🤖 AI/ML

Loss Function

손실 함수

예측과 실제 차이 측정. MSE, Cross-Entropy. 최적화 대상.

📖 상세 설명

손실 함수(Loss Function)는 모델의 예측값과 실제 정답 간의 차이를 수치화하는 함수입니다. 머신러닝과 딥러닝에서 모델 학습의 목표는 이 손실 함수 값을 최소화하는 것이며, 최적화 알고리즘(SGD, Adam 등)이 이를 달성합니다.

손실 함수의 역사는 통계학의 최소제곱법(1805년, Legendre)까지 거슬러 올라갑니다. 현대 딥러닝에서는 문제 유형에 따라 다양한 손실 함수를 사용하며, 적절한 손실 함수 선택이 모델 성능에 결정적인 영향을 미칩니다.

회귀 문제에는 MSE(Mean Squared Error), MAE(Mean Absolute Error), Huber Loss를 사용합니다. 분류 문제에는 Cross-Entropy Loss, Binary Cross-Entropy, Focal Loss를 사용합니다. 손실 함수는 미분 가능해야 역전파(Backpropagation)로 학습할 수 있습니다.

실무에서 손실 함수는 모델 학습 모니터링의 핵심 지표입니다. 학습/검증 손실 그래프를 통해 과적합을 탐지하고, 다중 목표에는 여러 손실 함수를 가중 합산하여 사용합니다. 커스텀 손실 함수로 비즈니스 목표에 맞는 최적화도 가능합니다.

💻 코드 예제

import torch
import torch.nn as nn
import torch.nn.functional as F

# ===== 회귀 문제 손실 함수 =====
y_true = torch.tensor([3.0, -0.5, 2.0, 7.0])
y_pred = torch.tensor([2.5, 0.0, 2.0, 8.0])

# MSE: Mean Squared Error (평균 제곱 오차)
mse_loss = nn.MSELoss()
print(f"MSE Loss: {mse_loss(y_pred, y_true):.4f}")  # 0.3750

# MAE: Mean Absolute Error (평균 절대 오차)
mae_loss = nn.L1Loss()
print(f"MAE Loss: {mae_loss(y_pred, y_true):.4f}")  # 0.5000

# Huber Loss: MSE와 MAE의 장점 결합 (이상치에 강건)
huber_loss = nn.HuberLoss(delta=1.0)
print(f"Huber Loss: {huber_loss(y_pred, y_true):.4f}")

# ===== 분류 문제 손실 함수 =====
# 이진 분류
y_true_binary = torch.tensor([1.0, 0.0, 1.0, 0.0])
y_pred_logits = torch.tensor([0.9, -0.5, 0.8, -1.0])

bce_loss = nn.BCEWithLogitsLoss()
print(f"Binary CE Loss: {bce_loss(y_pred_logits, y_true_binary):.4f}")

# 다중 클래스 분류
y_true_class = torch.tensor([0, 2, 1])  # 클래스 인덱스
y_pred_logits = torch.tensor([
    [2.0, 0.5, 0.3],   # 클래스 0 예측
    [0.1, 0.2, 3.0],   # 클래스 2 예측
    [0.5, 2.5, 0.1]    # 클래스 1 예측
])

ce_loss = nn.CrossEntropyLoss()
print(f"Cross-Entropy Loss: {ce_loss(y_pred_logits, y_true_class):.4f}")

# ===== 커스텀 손실 함수 =====
class FocalLoss(nn.Module):
    """클래스 불균형 문제에 효과적인 Focal Loss"""
    def __init__(self, alpha=0.25, gamma=2.0):
        super().__init__()
        self.alpha = alpha
        self.gamma = gamma

    def forward(self, inputs, targets):
        bce = F.binary_cross_entropy_with_logits(inputs, targets, reduction='none')
        pt = torch.exp(-bce)
        focal_loss = self.alpha * (1 - pt) ** self.gamma * bce
        return focal_loss.mean()

focal = FocalLoss()
print(f"Focal Loss: {focal(y_pred_logits[:, 0], y_true_binary[:3]):.4f}")

🗣️ 실무에서 이렇게 말하세요

💬 회의에서
"학습 Loss가 에폭 10에서 0.5로 수렴했는데, 검증 Loss는 0.8에서 더 이상 내려가지 않습니다. 과적합 징후로 보여서 Early Stopping을 적용하거나 Dropout을 높여야 할 것 같습니다."
💬 면접에서
"분류 문제에 MSE 대신 Cross-Entropy를 쓰는 이유는 확률 분포 간의 차이를 더 잘 측정하기 때문입니다. MSE는 정답에 가까워질수록 그래디언트가 작아지지만, CE는 확률이 낮을 때 더 큰 페널티를 줘서 학습이 빠릅니다."
💬 기술 토론에서
"사기 탐지처럼 클래스 불균형이 심한 문제에는 Focal Loss를 쓰거나, 클래스 가중치를 주는 Weighted Cross-Entropy가 효과적입니다. gamma=2로 설정하면 쉬운 샘플의 영향을 줄이고 어려운 샘플에 집중합니다."

⚠️ 흔한 실수 & 주의사항

분류에 MSE 사용

분류 문제에 MSE를 쓰면 확률 출력이 [0,1] 범위를 벗어나고, 학습 속도도 느립니다. 분류에는 Cross-Entropy를 사용해야 합니다.

올바른 선택

회귀는 MSE/MAE, 분류는 CE를 기본으로 사용하세요. 이상치가 많으면 Huber Loss, 클래스 불균형에는 Focal Loss나 가중치 적용을 고려하세요.

🔗 관련 용어

📚 더 배우기