A 23.1. Confusion matrix és aggregálási
konvenció egységben a confusion matrixból kiindulva az accuracy,
precision és recall fogalmát építettük fel. Ott a döntési lépés adott
volt: az argmax kiválasztja a legnagyobb logithoz tartozó
osztályt. Most a döntés előtt álló valószínűségi kimenetet
vizsgáljuk: ha a modell azt mondja, hogy egy kép 0,9 valószínűséggel
vertical, két különböző kérdést tehetünk fel.
Osztályonként: azok között a képek között, amelyekre a
vertical osztály valószínűsége 0,9, tényleg kb. 90% a
vertical? A döntés konfidenciájára (top-label):
azok között a döntések között, amelyek legnagyobb valószínűsége 0,9
(bármelyik osztályra), kb. 90% helyes? A kettő nem ugyanaz, és mindkettő
ahhoz kell, hogy a 0,9 értéket valódi valószínűségként használhassuk. Ez
a kalibráció kérdése, és szorosan kapcsolódik ahhoz,
hogyan állítunk be egy döntési küszöböt egy költségérzékeny
alkalmazásban.
Előismeretként a 23.1. Confusion matrix és
aggregálási konvenció jelölését használjuk:
logitmátrix,
osztályindex-vektor. A [D07] dokumentáció szerint a PyTorch
CrossEntropyLoss logits bemenetet és int64
célindexet vár, a softmaxot pedig maga a loss számolja; mi itt a loss
definíciójához a softmax-kimenetet explicite is felírjuk. A 11.2. nn.Module és paraméterregisztráció tanulsága,
hogy a modell eval() módban, frissítés nélkül adja a
kiértékeléshez használt logitokat, és a 22.2.
Címkemegőrző transzformációk szerződése szerint a kalibráló
halmaznak ugyanazon a preprocessingen kell átmennie, mint a tanító
halmaznak.
Induló kérdés. Egy háromosztályos GlyphLab-modell a validációs halmazon minden mintához körüli maximális softmax-értéket rendel. Ebből következik-e, hogy az ilyen minták 80%-ában helyes az argmax-döntés? Ha nem, mit kell mérnünk, és hogyan javítható a hiba a logitok megváltoztatása nélkül?
Legyen a modell által adott logitmátrix. A softmax-kimenet
A döntés , mert a softmax rendezéstartó. A döntéshez tartozó konfidencia , a helyesség pedig .
Definíció (top-label kalibráció). Legyen a populációs eloszlásból vett pár, a modell döntése és a konfidenciája. A modell top-label kalibrált, ha
minden -re (a eloszlása szerint majdnem mindenütt).
Definíció (osztályonkénti kalibráció). A modell a
osztályra kalibrált, ha
minden
-re.
Ez más és erősebb állítás: a „0,9 valószínűséggel vertical”
mondat a vertical osztályra vonatkozik. Top-label
kalibráció mellett az egyes osztályok külön-külön lehetnek
kalibrálatlanok.
Mindkettő populációs, feltételes valószínűségi tulajdonság. Véges mintán még egy tökéletesen kalibrált modellnél sem kell a megfigyelt gyakoriságnak pontosan egyeznie a konfidenciával, és a feltételt folytonos -re közvetlenül nem is lehet mérni. Ezért binelt diagnosztikát használunk: a intervallumot diszjunkt binekre osztjuk, és binenként összevetjük az empirikus pontosságot és az átlagos konfidenciát:
ahol a nevezőben a bin elemszáma áll, és az üres bineket kihagyjuk. Ez a reliability diagram alapja. A binenkénti eltérés becslés: kis binben nagy a mintavételi szórása, a binelés pedig egy binen belül elrejtheti az ellentétes irányú eltéréseket (az egyik részen túl-, a másikon alulbiztos modell binátlaga lehet pontos). A binenkénti egyezés ezért nem a kalibráció definíciója, csak annak zajos, nem elégséges jele.
Log loss. A többosztályos negatív log-likelihood, más néven log loss:
A [D07] szerint ez éppen a PyTorch CrossEntropyLoss
default reduction="mean" viselkedése, ha a bemenet a
logitmátrix és a cél az int64 osztályindex. A log loss a
teljes valószínűségvektort bünteti, ezért a kalibrációt is méri: ha a
modell magabiztosan téved, a büntetés nagy.
Brier-pontszám (többosztályos). Legyen a one-hot célmátrix. A többosztályos Brier-pontszám
A tökéletes modellnél
;
a legrosszabb lehetséges érték
,
mert ha a modell egyetlen rossz osztályra ad 1 valószínűséget, akkor
.
(A bináris esetre a scikit-learn brier_score_loss a
értékkészletet dokumentálja; a [D15] oldal tartalmát a fejezet írásakor
még nem olvastuk végig, ezért a fenti többosztályos általánosítást saját
definícióként adjuk meg, és a kimondott határokat levezetésként
ellenőrizzük.)
Reliability diagram és ECE. A binelt konfidencia–pontosság párokat diagramon ábrázoljuk: minden binhez az átlagos konfidencia és a megfigyelt pontosság tartozik. Az expected calibration error a top-label kalibrációs eltérés binelt, mintavételi bizonytalansággal terhelt becslése:
A fenti képletekben a biteket például módon vehetjük fel. A binek száma és határai a mérési protokoll részei; más binelés más ECE-t ad.
Döntési küszöb és költség. Bináris vagy multilabel esetben a döntési szabály . A küszöböt gyakran költségmátrixszal indokoljuk. Ha a téves pozitív költsége , a téves negatívé , a helyes döntéseké 0, akkor az 1-osztály választásának várható költsége , a 0-osztályé . Az 1-es döntés optimális, ha
tehát az optimális küszöb . Ez a levezetés feltételezi, hogy a értéke kalibrált valószínűség; ha a modell nem kalibrált, akkor a költségküszöb nem az elvárt gyakoriságot adja.
A temperature scaling a logitokat egyetlen pozitív skalárral osztja, majd softmaxot számol. A hőmérséklettel skálázott valószínűség:
Lemma (a hőmérséklet hatása). Legyen véges logitvektor, a fenti eloszlás. Ekkor:
Bizonyítás. Az 1. állításhoz: miatt a leképezés szigorúan rendezéstartó, és az exponenciális függvény is szigorúan monoton; a pozitív normalizáló konstans nem változtat a sorrenden.
A 2. állításhoz: véges, ezért esetén , így minden -re, tehát
A 3. állításhoz legyen , és írjuk át:
Ha , akkor , ezért és . Ha , akkor a kitevő azonosan 0, tehát . Így a nevező határértéke az értékű osztályok száma, , a számláló pedig 1 a maximális, 0 a nem maximális osztályokra. Ebből a harmadik állítás következik.
A tehát kívül esik a paramétertartományon; a határérték a kemény argmax-eloszlás. A az identitás, élesíti, lapítja az eloszlást.
A validációs illesztés. A modell súlyait rögzítjük, és csak a skalárt hangoljuk a validációs halmazon a log loss minimalizálásával. Legyen a validációs logitmátrix és a cél . A célfüggvény
A optimalizálást a szerinti gradienssel is elvégezhetjük. Egyetlen mintára , ahol és . A logaritmus deriváltja:
A negatív előjel miatt a batchra átlagolt gradiens
A gradiens
-n
folytonos, de ebből nem következik numerikus
stabilitás:
esetén a
tényező nagy lehet. A gyakorlatban a CrossEntropyLoss
logitsbemenetét használjuk, és a pozitivitás biztosítására kereshetünk
paraméteren vagy korlátozott, pozitív rácson. A levezetés
alakellenőrzése:
skalár, a gradiens is skalár; a jobb oldal minden tagja logit
mértékegységű, osztva
-tel,
tehát
inverz dimenziójú, ahogy vártuk.
Oktatási kiindulópontként egy kis rács, például használható, de a rács nem garantálja az optimum pontos megtalálását; a keresés semmilyen modellparamétert nem érint. A választott nem változtatja az argmax-döntést, tehát az accuracy, a confusion matrix és a belőle számolt macro/micro metrikák változatlanok maradnak. Amit a hőmérséklet megváltoztat, az a log loss, a Brier-pontszám, az ECE és minden küszöb-alapú döntés konfidenciaértéke.
Heurisztika, nem tétel. A temperature scaling modern konvolúciós hálókon gyakran csökkenti az ECE-t, de ez empirikus megfigyelés, nem bizonyított garancia minden modellosztályra. A validációs optimum kiválasztása maga is mintavételi bizonytalanságnak kitett; a [S02] módszertani oldal az intervallumok feltételes, ismételt mintavételi értelmezését hangsúlyozza, ezért a mért ECE-csökkenést a validációs elemszám ismeretében, nem pedig egyetlen pontbecslésként kell kezelni.
Három minta, , célok , logitok:
A softmaxok rendre:
A log loss értékei: , , , az átlag . A harmadik minta magabiztos tévedés: a modell a 0 osztályt adja, pedig a cél 1.
Most : , így , és a harmadik minta vesztesége . Az első két mintán a loss javul (közel és ), de az átlag , tehát a rácsban a jobb, mert a téves minta túlzott élesítése drágább. Ez a kézi számpélda mutatja, hogy a kalibráló optimum nem automatikusan a legkisebb hőmérséklet.
Minimális ellenőrző kód float64 pontossággal:
import numpy as np
Z = np.array([[2.0,0.5,-0.5],[0.2,1.8,-0.3],[2.5,1.8,0.2]], dtype=np.float64)
y = np.array([0,1,1], dtype=np.int64)
def softmax(Z, T):
U = Z / T
U = U - U.max(axis=1, keepdims=True) # stabil logiteltolás
E = np.exp(U)
return E / E.sum(axis=1, keepdims=True)
for T in [0.5, 1.0, 2.0]:
P = softmax(Z, T)
loss = -np.mean(np.log(P[np.arange(len(y)), y]))
print(f"T={T:3.1f} loss={loss:.6f} P[2]={P[2].round(3)}")
# Várt kimenet (a fenti kézi számításból):
# T=0.5 loss=0.579231 P[2]=[0.796 0.196 0.008]
# T=1.0 loss=0.571774 P[2]=[0.626 0.311 0.063]
# T=2.0 loss=0.735268 P[2]=[0.495 0.349 0.157]A kód nem állítja, hogy futtattuk a kéziratban; az értékek a fenti
kézi számításból származnak, ezért # Várt kimenet jelölést
kaptak.
A labor a GlyphLab adatszerződésére épül. A protokoll rögzített, a teszt csak a legvégén, egyszer kerül kiértékelésre.
state_dict-jét és a GlyphLab metadata.csv
split oszlopát.# futtatási parancs: python n090_lab.py
import numpy as np
import torch
import csv
torch.manual_seed(20261020)
device = torch.device("cpu")
dtype = torch.float32
# A modellt a n080/n096-ból saját state_dict-ből töltjük; a betöltés helye projektfüggő.
# model = load_trained_model()
# model.load_state_dict(torch.load("model.pt", map_location=device))
# model.to(device).eval()
images = np.load("data/images.npy").astype(np.float32) # (360,1,24,24)
labels = np.load("data/labels.npy").astype(np.int64) # (360,)
with open("data/metadata.csv", newline="", encoding="utf-8") as f:
metadata = list(csv.DictReader(f))
val_idx = np.array([int(r["index"]) for r in metadata if r["split"] == "val"])
test_idx = np.array([int(r["index"]) for r in metadata if r["split"] == "test"])
assert len(val_idx) == len(test_idx) == 60
def gather_logits(model, X, batch=32):
model.eval()
outs = []
with torch.no_grad():
for i in range(0, len(X), batch):
xb = torch.from_numpy(X[i:i+batch]).to(dtype=torch.float32, device=device)
outs.append(model(xb).detach().cpu())
return torch.cat(outs, dim=0)
# Z_val = gather_logits(model, images[val_idx]) # (60,3)
# Z_test = gather_logits(model, images[test_idx]) # (60,3)
# y_val = torch.from_numpy(labels[val_idx])
# y_test = torch.from_numpy(labels[test_idx])
# temperature grid search
def nll_from_logits(Z, y):
# D07: CrossEntropyLoss logitsot vár, softmax nélkül; int64 cél.
return torch.nn.functional.cross_entropy(Z, y).item()
# ECE számítása: max softmax konfidencia és argmax accuracy binelése
def ece(Z, y, bins=(0.0,0.2,0.4,0.6,0.8,1.0)):
p = torch.softmax(Z, dim=1)
conf, pred = p.max(dim=1)
acc = (pred == y).float()
ece_val = 0.0
for lo, hi in zip(bins[:-1], bins[1:]):
mask = (conf >= lo) & (conf < hi + (1e-9 if hi == 1.0 else 0.0))
n = mask.sum().item()
if n > 0:
ece_val += (n/len(y)) * abs(conf[mask].mean().item() - acc[mask].mean().item())
return ece_val
# Példa a kézi 3 mintás adatra; nem GlyphLab-mérés.
Z_example = torch.tensor([[2.0,0.5,-0.5],[0.2,1.8,-0.3],[2.5,1.8,0.2]])
y_example = torch.tensor([0,1,1], dtype=torch.int64)
T_star = min([0.5,1.0,2.0], key=lambda T: nll_from_logits(Z_example/T, y_example))
print(f"T* a példán: {T_star}") # várt: 1.0 a 4. szakasz számításai alapján
print(f"ECE T=1 példán: {ece(Z_example, y_example):.4f}") # kézzel várható ~0.22A labor átadandó eredménye a validációs kalibrációs protokoll és a tesztkiértékelés. A fenti kódban a modellbetöltés és a metaadatokból kiválasztott 60-60 val/test index a GlyphLab splitjét jelöli; a futás e kéziratban nem elvégzett, ezért a nyomtatott értékek a 4. szakasz kézi példájából származó várt kimenetek. A tényleges futtatás után a naplóba rögzítendő a , a val és teszt log loss, Brier, ECE és accuracy, valamint a választott binhatárok.
Eredményértelmezés. Ha a teszt log loss -gal kisebb, mint -gyel, akkor a hőmérséklet-illesztés a validációról a tesztre általánosult. Ha az ECE is csökken, a kalibráció javult. A kísérleti állítás ezzel még mindig a GlyphLab három osztályára és a konkrét modellre vonatkozik, nem általános CNN-kalibrációs tétel.
F1 (fogalmi, nehézség 1). Definiálja a konfidencia-kalibrációt a binek nyelvén. Adjon ellenpéldát arra, hogy egy modell kalibrált, de haszontalan, és arra, hogy egy modell pontos, de nem kalibrált. Adja meg mindkét esetben a logitokat vagy valószínűségeket.
F2 (levezetési, nehézség 2). Legyen , . Számítsa ki a eloszlást és esetén, és vezesse le a határértéket. Igazolja, hogy a rendezés minden -ra változatlan.
F3 (implementációs, nehézség 2). Írjon teljes Python/PyTorch függvényt, amely adott logitmátrixon, célvektoron és -rácson visszaadja a legjobb -ot a log loss minimalizálásával. A függvény ne használjon külső adatot; a bemeneteket ellenőrizze. Tesztelje a 4. szakasz hárommintás példáján, és adja meg az elvárt -ot.
F4 (hibakeresési, nehézség 2). Az alábbi kódrészlet a kalibráló hőmérsékletet a teszt logitokon választja ki:
def bad_temperature(Z_test, y_test):
best = None
for T in [0.5, 0.75, 1.0, 1.25, 1.5, 2.0]:
loss = torch.nn.functional.cross_entropy(Z_test/T, y_test).item()
if best is None or loss < best[0]:
best = (loss, T)
return best[1]Mi a hiba, mi a következménye a tudományos állításra nézve, és hogyan kell javítani? Visszaellenőrzésként adja meg, melyik halmaznak kell megmaradnia érintetlennek.
F5 (kísérleti/transzfer, nehézség 3). Tervezzen kísérletet annak eldöntésére, hogy a temperature scaling javítja-e egy CNN log lossát egy új, kétosztályos feladaton, ahol a pozitív osztály ritka (prevalencia 10%). Adja meg a protokollt, a baseline-t, a metrikákat, a megfigyelési egységet, a szükséges split-felépítést és a következtetési korlátot. Indokolja, miért nem elég az accuracy, és miért kell a kalibráló halmazt a threshold-választástól is elkülöníteni.
F1. A top-label kalibráció definíciója a 2. szakaszban szerepel: ; a binelt diagnosztikában ennek jele, hogy a binekben az átlagos konfidencia közel van a megfigyelt pontossághoz. Kalibrált, de haszontalan: háromosztályos feladaton a konstans modell minden mintára. A konfidencia mindenütt, a pontosság is , tehát kalibrált, de a döntése véletlenszerű. Pontos, de nem kalibrált: kétosztályos, 100 mintás feladaton a modell 90 mintát helyesen osztályoz, de a 90 helyes mintához 0.99 konfidenciát, a 10 téveshez 0.51-et ad. Az accuracy 0.9, de a 0.99 konfidenciájú binben a pontosság 1.0, a 0.51-es binben 0.0; a modell nem kalibrált. A példa szándékosan szélsőséges, hogy a két fogalom elváljon.
F2. . : , , , összeg , tehát . : , kétszer, , összeg , tehát . A rendezés változatlan: a két maximális logitú osztály egyenlő valószínűségű, a harmadik kisebb. A határérték: a lemmában szereplő átírással , a két maximális osztály kitevője , a harmadiké , így a határeloszlás . A rendezés invarianciája onnan következik, hogy -val osztás és az exponenciális függvény is szigorúan monoton; a normalizáló konstans pozitív.
F3. A függvény PyTorchban:
import torch
def fit_temperature(Z: torch.Tensor, y: torch.Tensor,
grid=[0.5, 0.75, 1.0, 1.25, 1.5, 2.0]) -> float:
if Z.ndim != 2 or y.ndim != 1 or len(Z) != len(y):
raise ValueError("Z legyen (N,K), y legyen (N,)")
if torch.any(torch.tensor(grid) <= 0):
raise ValueError("A hőmérsékletrács elemei legyenek pozitívak")
Z = Z.to(dtype=torch.float64)
y = y.to(dtype=torch.int64)
best_T, best_loss = None, float("inf")
for T in grid:
loss = torch.nn.functional.cross_entropy(Z/T, y).item()
if loss < best_loss:
best_loss, best_T = loss, T
return best_T
Z = torch.tensor([[2.0,0.5,-0.5],[0.2,1.8,-0.3],[2.5,1.8,0.2]], dtype=torch.float64)
y = torch.tensor([0,1,1], dtype=torch.int64)
print(fit_temperature(Z, y)) # várt: 1.0, a 4. szakasz kézi számítása alapjánAlakellenőrzés:
alakja
,
a célé
;
a cross_entropy default mean redukció. A tolerancia a
rácsfelbontásból adódik: ha a rács például 0.05 lépésközű, a hiba a
hőmérsékletben legfeljebb 0.05. A függvény float64
bemenettel számol, mert a loss értéke kis különbségekre érzékeny.
F4. A hiba: a hőmérsékletet a teszt logitokon választja. A következmény: a teszt már nem érintetlen; a kiválasztása a teszt loss minimalizálásával teszt-adatszivárgás, és a jelentett teszt log loss optimistán torzított lesz. A javítás: a -rácsot kizárólag a validációs logitokon értékeljük, majd a kiválasztott -ot egyszer alkalmazzuk a tesztre. A visszaellenőrzés: a teszt halmaz semmilyen választási lépésben nem vett részt, tehát a teszt loss torzítatlan becslés marad.
F5. Protokoll: rögzített scene-szintű train/val/test split, a pozitív osztály aránya mindegyikben 10%. A modell betanítása után a validációs logitokon kiválasztása log loss szerint. Baseline: , azaz kalibrálás nélküli modell. Metrikák: log loss, Brier-pontszám, ECE, valamint a ritka osztályra recall és precision a , költségküszöbbel. Az accuracy a 90%-os prevalencia miatt csak a többségi osztályt tükrözné, ezért önmagában nem elég. Megfigyelési egység: scene, mert a két nézet nem független. A küszöböt a validációtól is el kell különíteni: ha a küszöböt ugyanazon a validáción hangolnánk, mint a -t, akkor a két választás kölcsönhatása miatt a teszt következtetés ismét torzulhat; célszerű a validációt két részre bontani, vagy a küszöböt a feladat kiírása előtt, költségarányokból rögzíteni. Korlát: a ritka osztály 10%-os prevalenciája miatt a binelt ECE-ben a magas konfidenciájú bitek elemszáma kicsi, ezért a becslés szórása nagy.
Tipikus tévedés: a maximális softmax-valószínűség garantált bizonytalansági vagy OOD-mérték. A softmax normalizálása miatt a csak a zárt osztályhalmazhoz viszonyított relatív konfidencia. Ha egy olyan mintát adunk a modellnek, amely egyik tanult osztályhoz sem hasonlít, a logitok lehetnek például ; ekkor a softmax , tehát a modell 0.525 konfidenciával dönt, noha a minta az eloszláson kívüli. A kalibráció sem oldja meg ezt: a kalibráció azt méri, hogy a tanult eloszláson a 0.525 körüli döntések milyen gyakran helyesek, nem azt, hogy a konkrét minta ismert-e. Az OOD-detektáláshoz külön pontszám, például a logitok energiája vagy egy sűrűségmodell szükséges; a -ot ilyenként használni hibás.
Önellenőrzés. (1) A hőmérséklet nem változtatja meg az argmax-ot; igaz-e -re is? Igen, mert . (2) A Brier-pontszám felső határa 2, nem 1; ellenőriztük a rossz osztályra tett 1 valószínűség esetével. (3) A validációs illesztés után a teszt log loss csökkenése akkor megbízható, ha a tesztet sem a választására, sem más hiperparaméter-hangolásra nem használtuk.
Visszahívás. A 22.2.
Címkemegőrző transzformációk címkemegőrző transzformációk egysége
rögzítette, hogy a validációs képeken nem alkalmazhatunk olyan
augmentációt, amely megváltoztatná a címkét; ugyanígy a kalibráló
halmaznak a teszt eloszlását kell reprezentálnia. A 11.2. nn.Module és paraméterregisztráció a
train()/eval() flag jelentését adta meg: a
logitgyűjtés alatt a modellnek eval() módban kell lennie,
különben a dropout vagy BatchNorm tanítási statisztikája torzítja a
kalibráló logitokat. A 19.2. MobileNet és inverted
residual inverted residual blokkjának fej-rétege előtt a logitok
skálája az utolsó lineáris rétegtől függ; a hőmérséklet-illesztést ezért
minden architektúrához külön kell elvégezni, és a
értéke nem vihető át automatikusan más modellre. Korábbi anyagból a 7.1. Entrópia, cross-entropy és KL entrópia/KL
fogalmai adják a log loss proper scoring tulajdonságának hátterét: mivel
és a KL nemnegatív, a várható log loss minimalizálója a valódi
eloszlás.
A logitok softmax-kimenete valószínűségvektor, de a döntési szabály és a kalibráció két külön értékelési réteg. A log loss és a többosztályos Brier-pontszám a teljes eloszlást bünteti; a reliability diagram és az ECE a konfidencia és a megfigyelt pontosság egyezését méri. A temperature scaling egyetlen skalárral osztja a logitokat, nem változtatja az argmaxot, de élesíti vagy lapítja az eloszlást; a határ az egyenletes, a a kemény max eloszlás. A validációs log loss-minimalizálással illeszthető, és a gradiensét explicite levezettük. A döntési küszöb a költségarányból adódóan , és csak kalibrált valószínűségek mellett értelmezhető költségoptimumként. A maximális softmax nem OOD-mérték.
A 23.3. Páros összehasonlítás és csoportszintű intervallum egységben a páros összehasonlítás és a csoportszintű intervallum következik: a GlyphLab scene-szintű függősége miatt a képenkénti konfidenciaintervallum nem elegendő, ezért a két modell vagy két döntési szabály közötti különbséget páros, scene-szintű újramintavétellel becsüljük.