손실 함수
Loss Function
모델 예측과 실제 값의 차이를 측정하는 함수. MSE, Cross-Entropy 등. 학습의 최적화 대상.
Loss Function
모델 예측과 실제 값의 차이를 측정하는 함수. MSE, Cross-Entropy 등. 학습의 최적화 대상.
손실 함수(Loss Function)는 모델의 예측값과 실제 정답 간의 차이를 수치화하는 함수입니다. 이 값이 작을수록 모델이 정답에 가깝게 예측하고 있다는 의미입니다. 머신러닝의 학습 과정은 결국 이 손실 함수를 최소화하는 파라미터를 찾는 최적화 문제입니다.
손실 함수는 문제 유형에 따라 다르게 선택합니다. 회귀 문제에서는 MSE(Mean Squared Error), MAE(Mean Absolute Error), Huber Loss 등을 사용합니다. 분류 문제에서는 Cross-Entropy Loss가 표준이며, 이진 분류에는 Binary Cross-Entropy, 다중 분류에는 Categorical Cross-Entropy를 사용합니다.
손실 함수의 특성이 학습에 큰 영향을 미칩니다. MSE는 큰 오차에 더 큰 페널티를 주어 이상치에 민감합니다. MAE는 모든 오차에 동일한 가중치를 주어 이상치에 강건합니다. Cross-Entropy는 확률 분포 간의 차이를 측정하며, 확률이 0에 가까운 잘못된 예측에 큰 페널티를 줍니다.
고급 손실 함수도 많이 활용됩니다. Focal Loss는 쉬운 샘플의 손실을 줄여 어려운 샘플에 집중합니다. Contrastive Loss와 Triplet Loss는 임베딩 학습에 사용됩니다. Dice Loss는 세그멘테이션에서 클래스 불균형 문제를 해결합니다. 실무에서는 여러 손실 함수를 가중합하여 사용하기도 합니다.
PyTorch에서 다양한 손실 함수 사용 및 커스텀 구현 예제입니다.
import torch
import torch.nn as nn
import torch.nn.functional as F
# ===== 회귀 손실 함수 =====
mse_loss = nn.MSELoss()
mae_loss = nn.L1Loss()
huber_loss = nn.HuberLoss(delta=1.0)
pred = torch.tensor([2.5, 0.0, 2.1, 7.8])
target = torch.tensor([3.0, -0.5, 2.0, 7.5])
print(f"MSE Loss: {mse_loss(pred, target):.4f}") # 0.1275
print(f"MAE Loss: {mae_loss(pred, target):.4f}") # 0.3250
# ===== 분류 손실 함수 =====
ce_loss = nn.CrossEntropyLoss()
bce_loss = nn.BCEWithLogitsLoss()
# 다중 분류: logits (B, C) vs labels (B,)
logits = torch.tensor([[2.0, 1.0, 0.1], [0.5, 2.5, 0.3]])
labels = torch.tensor([0, 1])
print(f"CrossEntropy: {ce_loss(logits, labels):.4f}")
# 이진 분류: logits (B,) vs labels (B,)
logits_binary = torch.tensor([0.9, -0.5, 0.3])
labels_binary = torch.tensor([1.0, 0.0, 1.0])
print(f"BCE: {bce_loss(logits_binary, labels_binary):.4f}")
# ===== Focal Loss 구현 =====
class FocalLoss(nn.Module):
def __init__(self, alpha=1, gamma=2):
super().__init__()
self.alpha = alpha
self.gamma = gamma
def forward(self, inputs, targets):
ce_loss = F.cross_entropy(inputs, targets, reduction='none')
pt = torch.exp(-ce_loss) # 정답 확률
focal_loss = self.alpha * (1 - pt) ** self.gamma * ce_loss
return focal_loss.mean()
# ===== Label Smoothing =====
ce_smooth = nn.CrossEntropyLoss(label_smoothing=0.1)
# ===== 가중 손실 함수 조합 =====
class CombinedLoss(nn.Module):
def __init__(self, alpha=0.5):
super().__init__()
self.alpha = alpha
self.ce = nn.CrossEntropyLoss()
self.dice = DiceLoss() # 커스텀 구현 필요
def forward(self, pred, target):
return self.alpha * self.ce(pred, target) + (1-self.alpha) * self.dice(pred, target)
| 손실 함수 | 적용 분야 | 장점 | 주의사항 |
|---|---|---|---|
| MSE (L2) | 회귀 | 수학적으로 다루기 쉬움 | 이상치에 민감 |
| MAE (L1) | 회귀 | 이상치에 강건 | 0에서 미분 불가 |
| Cross-Entropy | 분류 | 확률 해석 가능 | 클래스 불균형 취약 |
| Focal Loss | 객체 탐지 | 불균형 데이터에 효과적 | gamma 튜닝 필요 |
| Dice Loss | 세그멘테이션 | IoU 직접 최적화 | 배치 크기에 민감 |
"클래스 불균형이 심해서 Focal Loss로 바꿨더니 Minority Class의 Recall이 20% 올랐어요. gamma=2로 설정했습니다."
영어로는 "Switching to Focal Loss improved minority class recall by 20%"라고 표현합니다. "loss landscape", "loss curve", "training loss vs validation loss" 등의 용어도 자주 사용됩니다. 학습 과정에서는 "loss가 떨어지고 있다/정체됐다/발산했다"라고 표현합니다.