본문으로 건너뛰기

[메타코드 강의 후기] 딥러닝 Deep Learning | Loss Function, 최적화 (2)

LEGGO약 1 분DeepLearningPytorchCrossEntropyMSEADAMSGD메타코드메타코드mmetacodemetacodem

메타코드 강의: 딥러닝 입문 + Pytorch 실습 부트캠프로 이동open in new window
메타코드 강의: 딥러닝 입문 + Pytorch 실습 부트캠프로 이동

메타코드?

메타코드는 IT 대기업 현직자 + 서울대/카이스트 AI 박사 등 검증된 강사진들로 구성되어 있으며,

현직자 특강, 커리어 멘토링, 포트폴리오, 공모전, 채용정보 등 실제 취업에 도움이 될 수 있는 양질의 컨텐츠를 제공하고 있습니다.


Loss Function 실습

MSE Loss

일반적으로 회귀 작업에 사용되며, 예측 값과 실제 값 사이의 평균 제곱 차이를 최소화하는 것을 목표로 합니다.

import torch.nn as nn
import torch

mse_loss = nn.MSELoss()
pred = torch.randn(4, 10)
output = torch.randn(4, 10)
loss = mse_loss(pred, output)
print("MSE Loss:", loss)

# MSE Loss: tensor(2.0765)

Negative Log Likelihood (NLL) Loss

분류 문제에 사용되며, 특히 로그 소프트맥스와 함께 사용하여 올바른 클래스의 로그 확률을 측정하는 기준을 만듭니다. 소프트맥스 활성화 함수가 신경망에 포함될 때 주로 사용됩니다.

nn.LogSoftmax()와 torch.log(nn.Softmax())의 계산 결과는 같지만, softmax에 의한 결과는 수치적으로 불안정해서 NaN의 결과를 얻을 수 있기 때문에 NLL Loss에 직접적으로 사용될 수 없습니다.

m = nn.LogSoftmax(dim=1)
nll_loss = nn.NLLLoss()
pred = torch.randn([1, 5], requires_grad=True)
output = torch.tensor([1])  # 클래스 레이블
loss = nll_loss(m(pred), output)

print(torch.log(F.softmax(pred))) # 큰 텐서를 연산할때는 불안정해서 NaN 값 생성할 수도 있음.
print(m(pred))
print(nll_loss(m(pred), output))

# tensor([[-0.4442,  0.0901, -0.7359, -1.2302, -1.5951]], requires_grad=True)
# tensor([[-1.4411, -0.9068, -1.7328, -2.2271, -2.5920]], grad_fn=<LogBackward0>)
# tensor([[-1.4411, -0.9068, -1.7328, -2.2271, -2.5920]],
#        grad_fn=<LogSoftmaxBackward0>)
# tensor(0.9068, grad_fn=<NllLossBackward0>)
# <ipython-input-25-d4912cf100c6>:9: UserWarning: Implicit dimension choice for softmax has been deprecated. Change the call to include dim=X as an argument.
#   print(torch.log(F.softmax(pred)))

Cross Entropy Loss

nn.LogSoftmax()와 nn.NLLLoss()를 하나의 클래스로 결합합니다.

여러 클래스를 가진 분류 작업에 매우 유용합니다.

ce_loss = nn.CrossEntropyLoss()
pred = torch.randn(3, 5, requires_grad=True)
output = torch.tensor([0, 4, 0], dtype=torch.long)
loss = ce_loss(pred, output)
print("Cross Entropy Loss:", loss)

# Cross Entropy Loss: tensor(2.2137, grad_fn=<NllLossBackward>)

Optimization Techniques 실습

SGD (Stochastic Gradient Descent, 확률적 경사 하강법)에 대한 설명

SGD는 가장 널리 사용되는 최적화 알고리즘 중 하나로, 매개변수를 업데이트할 때 전체 데이터셋을 사용하는 대신 무작위로 선택된 일부 데이터만 사용하여 경사를 계산합니다.

이 접근 방식은 큰 데이터셋에서 효율적이며, 일반적으로 로컬 최소값에 갇힐 확률을 줄이는 데 도움이 됩니다.

장점:

  • 큰 데이터셋에 효과적입니다.
  • 매 업데이트가 빠르게 이루어집니다.

단점:

  • 미니 배치의 선택에 따라 학습 과정이 불안정할 수 있습니다.
  • 최적점에 수렴하는 속도가 느릴 수 있습니다.

ADAM (Adaptive Moment Estimation)에 대한 설명

ADAM은 SGD의 변형으로, 각 매개변수에 대해 학습률을 적응적으로 조정합니다.

이는 과거의 그라디언트의 제곱근을 평균내어 학습률을 조정함으로써, 희소한 그라디언트에 강인한 최적화 방식을 제공합니다.

ADAM은 RMSProp와 Momentum을 결합한 것으로, 학습 초기 단계에서 빠른 수렴을 도모하고 이후 안정적인 수렴을 유지하는 데 효과적입니다.

장점:

  • 소규모 데이터셋에서도 안정적인 학습이 가능합니다.
  • 각 매개변수에 대해 개별적으로 학습률을 조정함으로써, 다양한 데이터와 다른 매개변수에 잘 적응합니다.

단점:

  • SGD에 비해 계산 비용이 더 높습니다.
  • 특정 경우에 학습 초기에 너무 빨리 진행되어 최적해를 지나칠 수 있습니다.

라이브러리 임포트

import torch
import torch.nn as nn
import torch.optim as optim

모델 정의

class LinearRegressionModel(nn.Module):
    def __init__(self):
        super(LinearRegressionModel, self).__init__()
        self.linear = nn.Linear(1, 1)  # 단순 선형 회귀, 입력 차원 1, 출력 차원 1

    def forward(self, x):
        return self.linear(x)

데이터셋 생성

# 훈련 데이터
x_train = torch.rand(15, 1) * 5  # 0에서 5 사이의 무작위 수
y_train = 3 * x_train + torch.randn(15, 1)  # y = 3x + noise

모델 인스턴스화 및 손실 함수 정의

model = LinearRegressionModel()
criterion = nn.MSELoss()

SGD 설정

sgd_optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

ADAM 설정

adam_optimizer = optim.Adam(model.parameters(), lr=0.01)

훈련 루프 정의

def train(model, criterion, optimizer, x_train, y_train, epochs=100):
    model.train()
    for epoch in range(epochs):
        optimizer.zero_grad()  # 그라디언트를 0으로 초기화
        outputs = model(x_train)  # 모델 예측
        loss = criterion(outputs, y_train)  # 손실 계산
        loss.backward()  # 역전파
        optimizer.step()  # 모델 파라미터 업데이트

        if (epoch+1) % 10 == 0:
            print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')

SGD로 훈련

print("Training with SGD")
train(model, criterion, sgd_optimizer, x_train, y_train, epochs=100)

ADAM으로 훈련

# 모델 파라미터 초기화 (새로운 훈련을 위해)
model = LinearRegressionModel()
print("Training with ADAM")
train(model, criterion, adam_optimizer, x_train, y_train, epochs=100)

이 두 최적화 알고리즘은 각기 다른 특성과 장단점을 가지고 있어, 문제의 종류나 데이터의 크기, 학습의 목표에 따라 적절한 최적화 알고리즘을 선택하는 것이 중요합니다.


이런 분들께 추천합니다!


서포터즈 강의료 지원을 받아 작성하였습니다