.box_article .article_cont p code
작성자: 13기 김현지
Pytorch로 신경망 모델 정의하고 사용하기
Reference:
Contents
FashionMNST 데이터셋의 이미지들을 분류하는 신경망을 구성해보자.
import os
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
가능한 경우 GPU와 같은 하드웨어 가속기에서 모델을 학습하려고 한다. torch.cuda를 사용할 수 있는지 확인하고 그렇지 않으면 CPU를 계속 사용한다.
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print('Using {} device'.format(device))
신경망 모델을 nn.Module의 하위클래스로 정의하고, __init__에서 신경망 계층들을 초기화한다. nn.Module을 상속받은 모든 클래스는 forward 메소드에서 입력 데이터에 대한 연산들을 구현한다.
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, 512),
nn.ReLU(),
nn.Linear(512, 512),
nn.ReLU(),
nn.Linear(512, 10),
nn.ReLU()
)
def forward(self, x):
x = self.flatten(x)
logits = self.linear_relu_stack(x)
return logits
model = NeuralNetwork().to(device)
PyTorch 모델로 쓰기 위해서는 다음 두가지 조건을 따라야 한다. 내장된 모델(nn.Linear등)도 이를 만족한다.
1. torch.nn.Moduled을 상속해야 한다.
2. __init()__과 forward()를 오버라이드(override)해야 한다.
PyTorch의 nn라이브러리는 Neural Network의 모든 것을 포괄하는 모든 신경망 모델의 Base Class이다. 다른 말로, 모든 신경망 모델읜 nn.Module의 subclass라고 할 수 있다.
nn.Module을 상속한 subclass가 신경망 모델로 사용되기 위해서는 앞서 소개한 두 메서드를 override해야 한다.
아주 많다! 아래 참고하기~
https://pytorch.org/docs/stable/nn.html#module
모델과 데이터가 준비되었으면, 데이터에 매개변수를 최적화하여 모델을 학습하고, 검증하고, 테스트할 차례이다. 모델을 학습하는 과정은 반복을 거친다. 에폭(epoch)이라고 부르는 각 반복 단계에서 모델을 출력을 추측하고, 추측과 정답 사이의 오류(손실)를 계산하고, 매개변수에 대한 오류의 도함수를 수집한 뒤, 경사하강법을 사용하여 파라미터들을 최적화한다.
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambda
training_data = datasets.FashionMNIST(
root="data",
train=True,
download=True,
transform=ToTensor()
)
test_data = datasets.FashionMNIST(
root="data",
train=False,
download=True,
transform=ToTensor()
)
train_dataloader = DataLoader(training_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)
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, 512),
nn.ReLU(),
nn.Linear(512, 512),
nn.ReLU(),
nn.Linear(512, 10),
nn.ReLU()
)
def forward(self, x):
x = self.flatten(x)
logits = self.linear_relu_stack(x)
return logits
model = NeuralNetwork()
하이퍼파라미터는 모델 최적화 과정을 제어할 수 있는 조절 가능한 매개변수이다.
학습 시에는 다음과 같은 하이퍼파라미터를 정의한다.
하이퍼파라미터를 설정한 뒤에는 최적화 단계를 통해 모델을 학습하고 최적화할 수 있다. 최적화 단계의 각 반복(iteration)을 에폭이라고 부른다.
하나의 에폭은 다음 두 부분으로 구성된다.
일반적인 손실함수에는 회귀 문제에 사용하는 nn.MSELoss나 분류에 사용하는 nn.NLLLoss, 그리고 nn.CrossEntropyLoss등이 있다.
# 손실 함수 초기화
loss_fn = nn.CrossEntropyLoss()
학습하려는 모델의 매개변수와 학습률(learning rate) 하이퍼파라미터를 등록하여 옵티마이저를 초기화한다.
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
최적화 코드를 반복하여 수행하는 train_loop와 테스트 데이터로 모델의 성능을 측정하는 test_loop가 정의되었다.
def train_loop(dataloader, model, loss_fn, optimizer):
size = len(dataloader.dataset)
for batch, (X, y) in enumerate(dataloader):
# 예측(prediction)과 손실(loss) 계산
pred = model(X)
loss = loss_fn(pred, y)
# 역전파
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_loop(dataloader, model, loss_fn):
size = len(dataloader.dataset)
num_batches = len(dataloader)
test_loss, correct = 0, 0
with torch.no_grad():
for X, y in dataloader:
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")
손실 함수와 옵티마이저를 초기화하고 train_loop와 test_loop에 전달한다. 모델의 성능 향상을 알아보기 위해 자유롭게 에폭(epoch) 수를 증가시켜 볼 수 있다.
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
epochs = 10
for t in range(epochs):
print(f"Epoch {t+1}\n-------------------------------")
train_loop(train_dataloader, model, loss_fn, optimizer)
test_loop(test_dataloader, model, loss_fn)
print("Done!")
import torch
import torch.onnx as onnx
import torchvision.models as models
PyTorch 모델은 학습한 매개변수를 state_dict라고 불리는 내부 상태 사전(internal state dictionary)에 저장한다. 이 상태 값들은 torch.save 메서드를 사용하여 저장(persist)할 수 있다.
model = models.vgg16(pretrained=True)
torch.save(model.state_dict(), 'model_weights.pth')
모델 가중치를 불러오기 위해서는, 먼저 동일한 모델의 인스턴스(instance)를 생성한 다음에 load_state_dict() 메서드를 사용하여 매개변수들을 불러온다.
model = models.vgg16() # 기본 가중치를 불러오지 않으므로 pretrained=True를 지정하지 않는다.
model.load_state_dict(torch.load('model_weights.pth'))
model.eval()
모델의 가중치를 불러올 때, 신경망의 구조를 정의하기 위해 모델의 클래스를 먼저 생성(instantiate)해야 했다. 이 클래스의 구조를 모델과 함께 저장하고 싶으면, (model.state_dict()가 아닌) model을 저장 함수에 전달한다.
torch.save(model, 'model.pth')
다음과 같이 모델을 불러올 수 있다.
model = torch.load('model.pth')
[알쓸쿠잡] PyTorch 사용법1 - 기본&데이터셋 (0) | 2021.11.24 |
---|
댓글 영역