Utvärdering av generativa modeller
Kunna använda FID, mänsklig bedömning och deras fallgropar.
Förkunskaper
- EGenerativa modeller — översiktkrävs
- EModellutvärderingkrävs
Intuition
Hur mäter man «bra bilder»? Det finns inget facit per bild — bara fördelningar att jämföra.
| Mått | Mäter | Missar |
|---|---|---|
| FID | avstånd mellan featurestatistik för äkta och genererade | mode collapse, minnesutantill, semantiska fel |
| Precision/recall (generativ) | precision = kvalitet, recall = täckning | kräver val av featurerum |
| CLIP-score | hur väl bilden matchar prompten | säger inget om bildkvalitet |
| Mänsklig parvis | faktisk preferens | dyrt, subjektivt, måste blindas |
FID ensam räcker aldrig. En modell som memorerat träningsbilder får utmärkt FID. En modell som tappat halva fördelningen kan också få hygglig FID om det den producerar är skarpt.
Formellt
FID antar att featurevektorerna (pool3 i Inception-v3) är normalfördelade och jämför medelvärde och kovarians:
Fallgropar som gör publicerade FID-tal svårjämförda:
- Stickprovsstorlek: FID är biased nedåt med fler samplar — 10 k och 50 k bilder ger olika tal för samma modell.
- Förbehandling: storleksändring och interpolationsmetod påverkar mätbart.
- Featurerum: Inception är tränat på ImageNet och passar dåligt för t.ex. medicinska bilder eller ansikten.
Precision och recall för generativa modeller (Kynkäänniemi m.fl. 2019) separerar de två felen: låg precision = fula/orimliga bilder, låg recall = hela lägen saknas. Det är precis den uppdelning FID saknar.
Memoreringstest som alltid bör köras: för varje genererad bild, hitta närmaste granne i träningsdatan (i featurerum) och titta manuellt på de närmaste hundra. En modell som reproducerar träningsdata är både ett kvalitets- och ett upphovsrättsproblem.
Kod
import numpy as np
from scipy import linalg
def fid(feat_akta: np.ndarray, feat_gen: np.ndarray) -> float:
mu_r, mu_g = feat_akta.mean(0), feat_gen.mean(0)
s_r, s_g = np.cov(feat_akta, rowvar=False), np.cov(feat_gen, rowvar=False)
covmean, _ = linalg.sqrtm(s_r @ s_g, disp=False)
if np.iscomplexobj(covmean):
covmean = covmean.real
return float(((mu_r - mu_g) ** 2).sum() + np.trace(s_r + s_g - 2 * covmean))
def narmaste_granne_check(feat_gen, feat_train, k=1):
"""Memoreringstest: hur nära ligger genererade bilder träningsdatan?"""
d = ((feat_gen[:, None, :] - feat_train[None, :, :]) ** 2).sum(-1)
narmast = np.sort(d, axis=1)[:, :k].mean(1)
return {"median_avstand": float(np.median(narmast)),
"misstankta": int((narmast < np.percentile(narmast, 1)).sum())}
# Rapportera alltid: FID (med n), precision, recall, CLIP-score vid text→bild,
# mänsklig parvis på ett stickprov, och memoreringskontrollen.
Behärskning innebär
- Använder FID och känner dess begränsningar
- Kompletterar med precision/recall och mänsklig bedömning
- Designar en utvärdering som fångar mode collapse
Logga in för att göra övningarna och bygga upp din behärskning.
Källor
- arXiv — GANs Trained by a Two Time-Scale Update Rule Converge to a Local Nash Equilibrium (FID) — arXiv (öppen åtkomst; licens per artikel)
- arXiv — Improved Precision and Recall Metric for Assessing Generative Models — arXiv (öppen åtkomst; licens per artikel)