Allen's 데이터 맛집
머신러닝의 손실 함수 본문
머신러닝과 기계학습에서 모델의 성능을 평가하고 최적화하는 데 중요한 역할을 하는 손실 함수(loss function)에 대해 알아보겠습니다. 손실 함수는 모델의 예측값과 실제값 간의 차이를 측정하여, 이 차이를 최소화하는 방향으로 모델을 학습시킵니다.
손실 함수란 무엇인가요?
손실 함수는 예측값과 실제값 사이의 차이를 측정하는 함수입니다. 손실 함수의 출력 값은 모델의 예측이 얼마나 잘못되었는지를 나타내며, 이 값을 최소화하는 것이 모델 학습의 목표입니다.
주요 손실 함수 소개
1. 평균 제곱 오차(MSELoss)
평균 제곱 오차는 예측값과 실제값 간의 차이를 제곱하여 평균을 구한 값입니다. 주로 회귀 분석에서 사용됩니다.
MSE = 1𝑛∑𝑖=1𝑛(𝑦𝑖−𝑦^𝑖)**2
장점: 계산이 간단하고, 큰 오차에 대해 민감합니다.
단점: 이상치(outlier)에 민감합니다.
import torch.nn as nn
mse_loss = nn.MSELoss()
2. 교차 엔트로피 손실(CrossEntropyLoss)
교차 엔트로피 손실은 분류 문제에서 주로 사용되며, 실제 클래스와 예측 확률 간의 차이를 측정합니다.
CrossEntropy=−∑𝑖=1𝑛𝑦𝑖log(𝑦^𝑖)
장점: 다중 클래스 분류 문제에 적합합니다.
단점: 예측 확률이 0 또는 1에 가까울 때 수치적으로 불안정할 수 있습니다.
cross_entropy_loss = nn.CrossEntropyLoss()
3. 이진 교차 엔트로피 손실(BCELoss)
이진 교차 엔트로피 손실은 이진 분류 문제에서 사용되며, 두 클래스 간의 예측 확률을 비교합니다.
BCE = −[𝑦log(𝑦^)+(1−𝑦)log(1−𝑦^)]
장점: 이진 분류 문제에 적합합니다.
단점: 예측 확률이 0 또는 1에 가까울 때 수치적으로 불안정할 수 있습니다.
bce_loss = nn.BCELoss()
4. 로짓과 함께 사용하는 이진 교차 엔트로피 손실(BCEWithLogitsLoss)
이 손실 함수는 BCELoss와 달리 로짓(logit)을 입력으로 받아 수치적 안정성을 높입니다.
BCEWithLogits=Sigmoid(𝑦^)+BCE
장점: 예측 확률을 직접 계산하지 않고도 안정적인 손실 값을 제공합니다.
단점: 다중 클래스 분류에는 적합하지 않습니다.
bce_with_logits_loss = nn.BCEWithLogitsLoss()
5. 음의 로그 우도 손실(NLLLoss)
음의 로그 우도 손실은 로그 소프트맥스(log-softmax)와 함께 사용되며, 다중 클래스 분류 문제에서 사용됩니다.
NLLLoss=−log(𝑃(true class))
장점: 로그 소프트맥스와 함께 사용하여 수치적 안정성을 높입니다.
단점: 예측 클래스의 확률만을 고려하므로, 다른 클래스의 예측 확률을 반영하지 않습니다.
nll_loss = nn.NLLLoss()
손실 함수의 선택 기준
손실 함수를 선택할 때는 다음과 같은 기준을 고려해야 합니다:
1. 문제 유형: 회귀 문제인지 분류 문제인지에 따라 적절한 손실 함수를 선택해야 합니다.
2. 데이터 특성: 데이터의 분포, 이상치의 존재 여부 등을 고려하여 손실 함수를 선택해야 합니다.
3. 모델 특성: 모델의 구조와 학습 과정에서의 수치적 안정성을 고려해야 합니다.
손실 함수의 구현 예제
[회귀 문제에서 MSELoss 사용 예제]
import torch
import torch.nn as nn
import torch.optim as optim
# 모델 정의
class LinearRegressionModel(nn.Module):
def __init__(self, input_dim, output_dim):
super(LinearRegressionModel, self).__init__()
self.linear = nn.Linear(input_dim, output_dim)
def forward(self, x):
return self.linear(x)
# 데이터 생성
x_train = torch.tensor([[1.0], [2.0], [3.0], [4.0]])
y_train = torch.tensor([[2.0], [4.0], [6.0], [8.0]])
# 모델 초기화
input_dim = 1
output_dim = 1
model = LinearRegressionModel(input_dim, output_dim)
# 손실 함수와 최적화 알고리즘 설정
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 모델 학습
num_epochs = 1000
for epoch in range(num_epochs):
# 순전파 계산
outputs = model(x_train)
loss = criterion(outputs, y_train)
# 역전파 및 최적화
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch+1) % 100 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
[분류 문제에서 CrossEntropyLoss 사용 예제]
import torch
import torch.nn as nn
import torch.optim as optim
# 모델 정의
class LogisticRegressionModel(nn.Module):
def __init__(self, input_dim, output_dim):
super(LogisticRegressionModel, self).__init__()
self.linear = nn.Linear(input_dim, output_dim)
def forward(self, x):
return self.linear(x)
# 데이터 생성
x_train = torch.tensor([[1.0, 2.0], [2.0, 3.0], [3.0, 4.0], [4.0, 5.0]])
y_train = torch.tensor([0, 1, 1, 0])
# 모델 초기화
input_dim = 2
output_dim = 2
model = LogisticRegressionModel(input_dim, output_dim)
# 손실 함수와 최적화 알고리즘 설정
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 모델 학습
num_epochs = 1000
for epoch in range(num_epochs):
# 순전파 계산
outputs = model(x_train)
loss = criterion(outputs, y_train)
# 역전파 및 최적화
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch+1) % 100 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
손실 함수는 머신러닝과 기계학습에서 모델의 성능을 평가하고 최적화하는 데 중요한 역할을 합니다. 다양한 손실 함수의 개념과 활용법을 이해하고, 적절한 손실 함수를 선택하여 모델의 성능을 최적화해보세요.