본문 바로가기
딥러닝\머신러닝

[딥러닝공부] Model의 기본 - pytorch

by 인포메틱스 2022. 5. 17.
반응형

저번 포스팅에 이어서 pytorch에서는 model을 어떻게 제작을 하는지 공유드리고자 합니다.

 

포스팅 내용이 괜찮았다면 주변 광고 클릭 몇번 눌러주시면 감사하겠습니다.

 

pytorch는 tensorflow와 같이 python에서 Deep learning할때 필수적으로 사용되는 양대산맥이라고 할 수가 있습니다.

 

뭐 들리는 소문으로는 Tensorflow보다는 Pytorch가 좀 더 최근 트렌드에서 선호된다는 말을 들었던것 같습니다(그러나 모델 제작 정보는 tensorflow가 아직까지는 더 많은 것 같습니다.).

 

pytorch의 경우 기본적인 model의 틀이 tensorflow의 GradientTape를 사용하는 방법과 유사하다고 생각될 수 있습니다(GradientTape와 같이 loss들을 업데이트 해주는 부분이 있습니다.)

 

예시로 보여드릴 모델의 경우 tensorflow와 마찬가지로 mnist데이터를 이용하여 분석하는 모델을 만들어보겠습니다(뭐 mnist관련 모델의 경우 구글에 수도 없이 많긴합니다.).

 

1. pytorch model를 제작하기 위한 mnist 데이터 다운로드

 

# import basic module 
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor,Lambda, Compose
import matplotlib.pyplot as plt
import numpy as np

# train set
training_data=datasets.MNIST(
	root='data',
    train=True,
    download=True,
    trainsform=ToTensor(),
    )
# test set
test_data=datasets.MNIST(
	root='data',
    train=False,
    download=True,
    transform=ToTensor(),
    )

batch_size = 64

train_dataloader = DataLoader(training_data, batch_size = batch_size)
test_dataloader = DataLoader(test_data,batch_size=batch_size)
# 데이터 확인용
for X, y in test_dataloader:
	print('Shape of X[N,C,H,W] : ' X.shape) # N = 개수 , C = channel, H = Height, W = Width
    print('Shape of y : ', y.shape)
    break

 

 pytorch에서는 tensorflow와는 다르게 device를 지정해줘야 합니다. 그리고 계산될 부분을 device에다 추가해줘야지 계산이 됩니다(나중에 따라 하시다 보면 나옵니다.).

 

# cuda가 있으면 cuda로 사용이 되고, 아니면 cpu가 됨
device = 'cuda' if torch.cuda.is_available() else 'cpu'

 

 

2. pytorch의 기본 모델

 

가장 기본적인 모델을 만들기 위해서는 tensorflow처럼 class를 제작해야합니다(Model class Subclassing방법!).

 

# pytorch model
class NeuralNetwork(nn.Module):
	def __init__(self):
        	super(NeuralNetwork, self).__init__()
                self.flatten = nn.Flatten()
                self.linear_relu_stack = nn.Sequential(
                		nn.Linear(28*28, 128),
                        nn.ReLu(),
                        nn.Dropout(0.2),
                        nn.Linear(128,10)
                )
	def forward(self, x):
        	x = self.flatten(x)
                logits = self.linear_relu_stack(x)
                return logits

model = NeuralNetwork().device(device)
print(model)

 

위와 유사하게 tensorflow에서는 다음과 같이 제작이 되었습니다.

 

# tensorflow - model (class subclassing)
from tensorflow import keras
class SubClassModel(keras.Model):
	def __init__(self):
    		super(SubClassModel, self).__init__()
            	self.flatten = tf.keras.layers.Flatten(input_shape = (28,28))
    	    	self.dense1 = tf.keras.layers.Dense(128, activation = 'relu')
    	    	self.drop = tf.keras.layers.Dropout(0.2)
    	    	self.dense2 = tf.keras.layers.Dense(10, activation = 'softmax')
	def call(self, x, training = False):
		x=self.flatten(x)
    	    	x=self.dense1(x)
    	    	x=self.drop(x)
            	return self.dense2(x)

 

3. train, test 진행하기

 

train, test 또한 def 기능을 이용하여 train을 시킬 수가 있습니다.

 

def train(dataloader, model, loss_fn, optimizer):
	size = len(dataloader.dataset)
    for batch, (X, y) in enumerate(dataloader):
    	X, y = X.to(device), y.to(device) # 아까 이야기한 device에다 추가! cuda에 추가!
        # 모델 계산 및 loss(에러) 계산
        pred = model(X)
        loss=loss_fn(pred,y)
        # backpropogation
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        if batch% 100 == 0:
		loss, current = loss.item(), batch * len(X)
		print(f'loss : {loss : >7f} [{current : >5d}/{size : >5d}]')
        
        
def test(dataloader, model, loss_fn):
	size = len(dataloader.dataset)
	num_batches = len(dataloader)
	model.eval()
	test_loss, correct = 0, 0
	with torch.no_grad(): # no grad 기능은 test로서 모델에 업데이트가 안됨을 위해서임
		for X, y in dataloader:
			X, y = X.to(device), y.to(device)
			pred = model(X)
			test_loss += loss_fn(pred,y),item()
			correct += (pred.argmax(1)==y).type(torch.float).sum().item()
            
	test_loss /= num_batches
	correct /= size
	print(f'Test Error : \n Accuracy : {(100*correct) : >0.1f}%, Avg loss: {test_loss : >8f}\n')

 

4. model 돌리기

 

모델을 돌리기 전에 loss 와 optimizer를 불러봐야 합니다.

 

# loss, optimzer function 가져오기
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameter(),lr=1e-03)

그리고 실제로 돌리기 위해서 다음과 같이 해주시면 됩니다.

 

epochs = 10 # 데이터를 10번 반복하겠다.

for t in len(epochs):
	print(f'Epoch {t+1}\n -----------------')
	train(train_dataloader, model, loss_fn, optimizer)
	test(test_dataloader, model, loss_fn)

 

한번의 epoch이 돌아가면서 train에 대해 돌아가면서 model을 업데이트해줍니다. 그리고 test의 경우 train에서 나온 모델이 얼마나 잘 나왔는지 확인용이고, loss의 업데이트는 절대로 하지 않습니다.

 

만약 하게 만든 모델의 경우 전체 데이터에 대한 모델이기 때문에 overfitting이 될 확률이 있습니다.

 


 

저도 지금 딥러닝을 처음부터 배우는 중이고 포스팅 한 부분을 계속적으로 따라해보고 있습니다.

 

그리고 다양한 강의를 보면서 정말 다양한 방식으로 모델을 만들더라구요.

 

또한 어떠한 강의에서는 캐글같은 곳에서 대부분 상위권 사람들의 경우 자기 자신만의 형식의 모델이 있다고 합니다.

 

매번 새로운 데이터에 약간만 데이터만 변경만 해주면 알아서 돌아가게 만들어 놓는경우가 많다고 하더라구요.

 

 그렇기 때문에 위와 같은 기본적인 Tutorial의 경우 참고삼아 다양하게 공부하고 새롭게 모델을 만들어 낼수가 있어야 한다고 생각합니다.

 

앞으로도 다양하게 강의를 듣고 정리해서 포스팅하도록 하겠습니다.

 

도움이 되셧다면 주변 광고 클릭해주시면 도움이 될 것 같습니다. 감사합니다.

728x90
반응형

댓글