본문 바로가기
C.W.K.
Stream
Lesson 06 of 08 · published

평가지표와 평가

~12 min · metrics, accuracy, precision, recall, f1

Level 0텐서 탐구자
0 XP0/62 lessons0/13 achievements
0/120 XP to next level120 XP to go0% complete

손실은 기울기 신호고 평가지표는 성적표야

모델은 손실을 줄이도록 학습하지만 성능은 작업에 맞는 평가지표로 판단해. 둘은 같은 숫자가 아니며 그 차이를 아는 게 중요해.

분류 평가지표

  • 정확도: 전체 예측 중 맞힌 비율이야. 해석은 쉽지만 클래스가 불균형하면 실제 성능을 거의 보여 주지 못할 수 있어.
  • 정밀도 / 재현율 / F1: 정밀도는 양성이라고 예측한 것 중 실제 양성의 비율이고, 재현율은 실제 양성 중 찾아낸 비율이야. F1은 둘의 조화 평균이야.
  • Top-K 정확도: 정답 클래스가 확률이 높은 상위 K개 예측 안에 든 비율이야. ImageNet에서는 top-1과 top-5를 표준으로 사용해.
  • ROC AUC: 수신자 조작 특성 곡선 아래의 면적이야. 이진 분류기에 사용하며 특정 임곗값에 의존하지 않아.

회귀 평가지표

  • MAE / RMSE: 평균 절댓값 오차와 평균 제곱근 오차야. 둘 다 정답과 같은 단위로 해석할 수 있어.
  • : 모델이 설명한 분산의 비율이야.

평가지표는 검증 데이터에서 평가 모드와 inference_mode로 계산해

평가지표를 계산할 때 BatchNorm이나 드롭아웃 같은 학습 모드 동작이 결과를 오염해서는 안 되고, 쓰지도 않을 autograd 그래프를 만들 필요도 없어.

torchmetrics: 검증된 구현이 필요할 때

별도로 설치하는 torchmetrics 패키지는 흔한 평가지표의 검증된 구현을 제공해. 배치마다 값을 누적할 수 있는 스트리밍 방식도 포함돼. 정확도보다 복잡한 지표를 쓴다면 직접 구현하기보다 이 패키지에 기대는 게 좋아.

Code

정확도와 클래스별 정밀도/재현율: 손으로·python
import torch

def accuracy(logits, targets):
    return (logits.argmax(-1) == targets).float().mean().item()

def precision_recall_f1(logits, targets, num_classes):
    preds = logits.argmax(-1)
    out = {}
    for c in range(num_classes):
        tp = ((preds == c) & (targets == c)).sum().item()
        fp = ((preds == c) & (targets != c)).sum().item()
        fn = ((preds != c) & (targets == c)).sum().item()
        prec = tp / (tp + fp) if (tp + fp) else 0.0
        rec  = tp / (tp + fn) if (tp + fn) else 0.0
        f1 = 2 * prec * rec / (prec + rec) if (prec + rec) else 0.0
        out[c] = {'precision': prec, 'recall': rec, 'f1': f1}
    return out

logits = torch.randn(64, 5)
targets = torch.randint(0, 5, (64,))
print(f"acc: {accuracy(logits, targets):.3f}")
print(precision_recall_f1(logits, targets, 5))
완전한 평가 함수·python
import torch
import torch.nn as nn

def evaluate(model, val_loader, criterion, device):
    model.eval()
    total_loss = 0.0
    total_correct = 0
    total_samples = 0

    with torch.inference_mode():
        for x, y in val_loader:
            x, y = x.to(device), y.to(device)
            out = model(x)
            loss = criterion(out, y)

            total_loss += loss.item() * x.size(0)
            total_correct += (out.argmax(-1) == y).sum().item()
            total_samples += x.size(0)

    return total_loss / total_samples, total_correct / total_samples

# Usage
val_loss, val_acc = evaluate(model, val_loader, criterion, device)
print(f"val_loss={val_loss:.4f}  val_acc={val_acc:.4f}")
torchmetrics: 검증된 구현이 필요할 때·python
# pip install torchmetrics
import torch
from torchmetrics.classification import (
    MulticlassAccuracy, MulticlassF1Score, MulticlassConfusionMatrix
)

n_classes = 10
acc = MulticlassAccuracy(num_classes=n_classes, top_k=1)
acc5 = MulticlassAccuracy(num_classes=n_classes, top_k=5)
f1 = MulticlassF1Score(num_classes=n_classes, average='macro')
cm = MulticlassConfusionMatrix(num_classes=n_classes)

# Accumulate across batches
for x, y in val_loader:
    logits = model(x)
    acc.update(logits, y)
    acc5.update(logits, y)
    f1.update(logits, y)
    cm.update(logits, y)

print(f"top-1: {acc.compute():.4f}")
print(f"top-5: {acc5.compute():.4f}")
print(f"macro-F1: {f1.compute():.4f}")
print("Confusion matrix:")
print(cm.compute())

External links

Exercise

두 번째 코드 블록의 평가 함수가 혼동 행렬도 출력하도록 확장해 봐. torchmetrics.MulticlassConfusionMatrix를 사용해 5클래스 모델을 학습하고 행렬을 살펴봐. 대각선에 값이 몰리면 예측이 좋다는 뜻이고, 대각선 밖의 큰 값은 모델이 자주 혼동하는 클래스 쌍을 알려 줘.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.