먼저 Entropy(엔트로피)부터 이해해야 합니다.
엔트로피는 불확실성을 측정하는 지표입니다.
상황 1: 동전 던지기 (앞면 50%, 뒷면 50%)
상황 2: 조작된 동전 (앞면 99%, 뒷면 1%)
H(P) = -Σ P(x) log P(x)
Cross Entropy는 두 확률 분포 간의 차이를 측정합니다.
H(P, Q) = -Σ P(x) log Q(x)
여기서:
이미지 하나가 실제로는 고양이입니다.
실제 정답 (One-hot encoding):
P = [1, 0, 0] # 고양이=1, 개=0, 새=0
모델의 예측 (Softmax 출력):
경우 A - 좋은 예측:
Q = [0.8, 0.15, 0.05] # 고양이 80% 확신
Cross Entropy 계산:
CE = -(1×log(0.8) + 0×log(0.15) + 0×log(0.05))
= -log(0.8)
≈ 0.223
경우 B - 나쁜 예측:
Q = [0.2, 0.6, 0.2] # 개를 60%로 잘못 예측
Cross Entropy 계산:
CE = -(1×log(0.2) + 0×log(0.6) + 0×log(0.2))
= -log(0.2)
≈ 1.609
결론: 예측이 나쁠수록 Cross Entropy 값이 커집니다! 🎯
스팸 메일 분류 같은 이진 분류에서는 간단한 형태를 사용합니다:
BCE = -[y log(ŷ) + (1-y) log(1-ŷ)]
이메일 1: 실제로 스팸 (y=1)
이메일 2: 실제로 스팸 (y=1)
MSE (평균 제곱 오차)를 분류에 사용하면:
Cross Entropy:
Cross Entropy를 최소화하는 것은 곧 Maximum Likelihood Estimation(MLE)과 동일합니다. 즉, 모델이 정답을 맞출 확률을 최대화하는 것입니다.
import torch
import torch.nn as nn
# 이진 분류 예시
bce_loss = nn.BCELoss()
# 실제 정답
target = torch.tensor([1.0, 0.0, 1.0, 0.0])
# 모델 예측 (시그모이드 출력)
prediction = torch.tensor([0.9, 0.2, 0.7, 0.3])
loss = bce_loss(prediction, target)
print(f"BCE Loss: {loss.item()}")
# 다중 클래스 분류 예시
ce_loss = nn.CrossEntropyLoss()
# 실제 정답 (클래스 인덱스)
target = torch.tensor([0, 2, 1])
# 모델의 로짓 출력 (Softmax 이전)
logits = torch.tensor([
[2.0, 0.5, 0.1], # 첫 번째 샘플
[0.1, 0.2, 2.5], # 두 번째 샘플
[0.3, 1.8, 0.2] # 세 번째 샘플
])
loss = ce_loss(logits, target)
print(f"CE Loss: {loss.item()}")
nn.CrossEntropyLoss()는 내부적으로 Softmax를 포함하므로, 모델의 마지막 레이어에서 Softmax를 적용하지 않아야 합니다Cross Entropy를 "모델이 얼마나 놀랐는가"로 이해할 수 있습니다. 정답이 고양이인데 모델이 고양이 확률을 0.01로 예측했다면, 모델은 매우 놀랄 것이고 손실이 큽니다. 반대로 0.99로 예측했다면 전혀 놀라지 않고 손실이 작습니다.