🤖 AI/ML

Cross-Entropy

교차 엔트로피

분류 문제의 손실 함수. 예측 확률과 실제 분포의 차이 측정.

📖 상세 설명

Cross-Entropy(교차 엔트로피)는 두 확률 분포 사이의 차이를 측정하는 정보 이론의 개념입니다. 머신러닝에서는 모델이 예측한 확률 분포와 실제 정답 분포 간의 차이를 정량화하는 데 사용되며, 분류 문제에서 가장 널리 사용되는 손실 함수의 기반이 됩니다.

정보 이론의 창시자 Claude Shannon이 1948년 엔트로피 개념을 정립했고, 교차 엔트로피는 이후 두 분포 간의 "정보 차이"를 측정하는 방법으로 발전했습니다. 1990년대 이후 신경망 학습에 널리 적용되면서 딥러닝의 핵심 도구가 되었습니다.

수학적으로 교차 엔트로피 H(p,q)는 -sum(p(x) * log(q(x)))로 정의됩니다. 여기서 p는 실제 분포(정답), q는 예측 분포입니다. 예측이 정답과 일치할수록 값이 작아지고, 틀릴수록 커집니다. 로그 함수 특성상 확신 있게 틀린 예측(0.99 확률로 오답)에 큰 페널티를 부여합니다.

실무에서 교차 엔트로피는 이미지 분류, 자연어 처리의 다음 토큰 예측, 추천 시스템 등 거의 모든 분류 태스크에 사용됩니다. GPT 같은 언어 모델은 다음 토큰 예측의 교차 엔트로피를 최소화하는 방식으로 학습됩니다. 평균 교차 엔트로피를 perplexity(혼란도)로 변환하여 모델 성능을 비교하기도 합니다.

💻 코드 예제

import numpy as np
import torch
import torch.nn.functional as F

# NumPy로 직접 구현
def cross_entropy_numpy(y_true, y_pred, epsilon=1e-15):
    """
    y_true: 원-핫 인코딩된 실제 레이블 (batch_size, num_classes)
    y_pred: 예측 확률 분포 (batch_size, num_classes)
    """
    # 수치 안정성을 위해 클리핑
    y_pred = np.clip(y_pred, epsilon, 1 - epsilon)
    # 교차 엔트로피 계산
    ce = -np.sum(y_true * np.log(y_pred), axis=1)
    return np.mean(ce)

# 예제: 3개 클래스 분류
y_true = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])  # 정답
y_pred_good = np.array([[0.9, 0.05, 0.05], [0.1, 0.8, 0.1], [0.1, 0.1, 0.8]])  # 좋은 예측
y_pred_bad = np.array([[0.3, 0.4, 0.3], [0.4, 0.3, 0.3], [0.3, 0.3, 0.4]])   # 나쁜 예측

print(f"좋은 예측의 CE: {cross_entropy_numpy(y_true, y_pred_good):.4f}")  # ~0.18
print(f"나쁜 예측의 CE: {cross_entropy_numpy(y_true, y_pred_bad):.4f}")   # ~1.10

# PyTorch에서 사용
logits = torch.tensor([[2.0, 0.5, 0.3], [0.2, 2.5, 0.3], [0.1, 0.2, 2.8]])
targets = torch.tensor([0, 1, 2])  # 클래스 인덱스

# CrossEntropyLoss는 softmax + NLL을 결합
loss = F.cross_entropy(logits, targets)
print(f"\nPyTorch CE Loss: {loss.item():.4f}")

# Perplexity 변환 (언어 모델 평가 시 사용)
perplexity = torch.exp(loss)
print(f"Perplexity: {perplexity.item():.4f}")

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

모델 학습 회의에서

"학습 loss가 0.5에서 안 내려가는데, cross-entropy가 0.5면 perplexity가 약 1.65입니다. 3개 클래스 분류에서 랜덤 추측의 perplexity가 3이니까 학습은 되고 있는 거예요. 다만 클래스 불균형 문제가 있으면 weighted cross-entropy를 적용해보세요."

기술 면접에서

"분류에서 MSE 대신 cross-entropy를 쓰는 이유는 기울기 소실 문제 때문입니다. MSE의 미분값은 예측이 0이나 1에 가까우면 매우 작아지지만, cross-entropy는 틀린 정도에 비례하는 기울기를 유지합니다. 그래서 학습이 훨씬 빠르고 안정적입니다."

코드 리뷰에서

"여기서 softmax 먼저 적용하고 cross_entropy_loss에 넣으셨는데, PyTorch의 CrossEntropyLoss는 내부에서 log_softmax를 적용합니다. 두 번 softmax가 적용되면서 수치 불안정이 생길 수 있어요. logits를 직접 넣으세요."

⚠️ 흔한 실수 & 주의사항

1.
수치 불안정성 (log(0) 문제)

예측 확률이 0에 가까우면 log(0)으로 인해 -inf가 발생합니다. PyTorch의 내장 함수는 자동 처리하지만, 직접 구현 시 epsilon(예: 1e-15)을 더하거나 클리핑이 필수입니다.

2.
클래스 불균형 무시

1:100 비율의 불균형 데이터에서 기본 cross-entropy를 쓰면 다수 클래스만 예측하는 모델이 만들어집니다. class_weight 파라미터로 소수 클래스에 높은 가중치를 부여하거나 Focal Loss를 사용하세요.

3.
Binary vs Categorical 혼동

이진 분류에서 BCELoss(Binary Cross-Entropy)와 CrossEntropyLoss를 혼용하면 차원 오류가 발생합니다. 2개 클래스면 BCEWithLogitsLoss, 3개 이상이면 CrossEntropyLoss를 사용하세요.

🔗 관련 용어

📚 더 배우기