본문 바로가기

AI/AI 라이브러리

[Pytorch] 모델 매개변수 최적화하기

728x90
반응형

파이토치 한국사용자 모임의 글을 보면서 공부한 내용을 정리한 글입니다.

 

전전 포스트에서 우리는 모델의 Layer를 설정했었다.

이제 모델과 데이터가 준비되었으니 데이터에 매개변수를 최적화하여 모델을 학습, 검증, 테스트 할 차례이다.

 

모델 학습은 반복적이며 각 반복 단계에서 모델은 출력을 추측하고, 손실(Loss)를 계산하고, 매개변수에 대한 오류의 도함수(derivative)를 수집한 뒤, Gradient Descent를 사용하여 파라미터들을 Optimize 한다.

 

이제 코드를 보면서 알아보자.

 

데이터를 로드하고 기본 NN 모델을 만든다.

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor

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),
        )

    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits

model = NeuralNetwork()

 

 

Hyperparameter

하이퍼파라미터는 모델 최적화 과정을 제어할 수 있는 조절 가능한 매개변수 이다.

 

서로 다른 하이퍼파라미터 값은 모델의 학습과 수렴에 영향을 미칠 수 있다.

 

학습 과정에서 다음과 같은 하이퍼파라미터를 정의한다.

  • 에폭수(epoch) : 데이터셋을 반복하는 횟수
  • 배치크기(batch size) : 매개변수가 갱신되기 전 신경망을 통해 전파된 데이터 샘플의 수
  • 학습률(Learning Rate) : 각 배치/에폭에서 모델의 매개변수를 조절하는 비율, 값이 작을수록 학습속도가 느려짐, 값이 크면 학습 중 예측할 수 없는 동작이 발생할 수 있다.
learning_rate = 1e-3
batch_size = 64
epochs = 5

 

 

Optimization Loop

하이퍼파라미터 설정 후 최적화 단계를 통해 모델을 학습하고 최적화 한다.

 

최적화 단계의 각 반복을 에폭이라고 부른다.

 

하나의 에폭은 다음 두 부분으로 구성된다.

  1. 학습 단계(Train Loop) : 학습용 데이터셋을 반복하고 최적의 매개변수로 수렴
  2. 검증/테스트 단계(Validation/Test Loop) : 모델 성능이 개선되고 있는지를 확인하기 위해 테스트 데이터셋을 반복

 

 

Loss Function

신경망은 계산된 결과와 실제 값 사이의 틀린정도를 측정하며, 학습 중에 이 값을 최소화하려고 한다.

 

주어진 데이터 샘플을 입력으로 계산한 예측과 정답을 비교하여 loss를 계산한다.

 

손실함수는 여러가지가 존재하며 문제에 따라 다른 손실함수를 사용해야 한다.

 

일반적인 예시

  • 회귀 : nn.MSELoss() - 평균 제곱 오차(Mean Squere Error) 
  • 분류
    • nn.NLLLoss() - 음의 로그 우도(Negative Log Likelihood)
    • nn.LogSoftmaxnn.NLLLoss를 합친 nn.CrossEntropyLoss 

 

 

Optimizer

최적화는 각 학습 단계에서 모델의 오류를 줄이기 위해 모델의 매개변수를 조정하는 과정이다.

 

이 최적화를 진행하는 알고리즘은 수행되는 방식(ex. SGD: Stochastic Gradient Descent)을 정의한다.

 

모든 최적화 절차는 optimizer 객체에 캡슐화(encapsulate)된다.

 

최적화를 진행하는 알고리즘인 Optimizer는 여러가지가 존재한다.(ADAM, RMSProp 등)

 

최적화는 3가지 단계로 이루어진다.

  1. 옵티마이저 인스턴스.zero_grad()를 호출하여 모델 매개변수의 변화도를 재설정, 기본적으로 add되기 때문에 중복 계산을 막기위해 명시적으로 0으로 설정
  2. loss.backwards()를 호출하여 prediction loss를 back propagation한다. 각 매개변수에 대한 Loss의 변화도를 저장한다.
  3. 변화도를 계산한 후 옵티마이저 인스턴스.step()을 호출하여 역전파 단계에서 수집된 변화도로 매개변수를 조정한다.

 

 

Optimization

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 + 1) * 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")
# set
learning_rate = 1e-3
batch_size = 64
epochs = 5

loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

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!")

 

 

 

6. Optimization.ipynb

Colaboratory notebook

colab.research.google.com

 

728x90
반응형