A 7.2. Softmax és többosztályos cross-entropy egységben a többosztályos célhoz tartozó softmax–cross-entropy párt vezettük be. Nem minden osztályozási feladat ilyen: egyetlen képhez tartozhat egyszerre több címke is, egyetlen bináris döntéshez pedig nincs szükség osztály logitjára. Emellett a neurális háló kimenete nem mindig osztálycímke: regressziós cél esetén valós számot jósolunk, amelyhez más veszteség illik. Ebben az alfejezetben a bináris, multilabel és regressziós célokhoz tartozó outputaktivációt és loss-szerződést építjük fel.
Előismeret: logit fogalma, softmax és természetes logaritmus (7.2. Softmax és többosztályos cross-entropy); batchgradiens és átlagolási konvenció (6.3. Sztochasztikus és minibatch gradiens); legkisebb négyzetek alapgondolata (3.3. Vetítés, legkisebb négyzetek és kondicionáltság). Programozói eszközként elég egy NumPy- vagy PyTorch-alapú tenzorkörnyezet.
Induló kérdés: egy modell három lehetséges betegség egyidejű jelenlétét becsli egy röntgenfelvételen. Miért nem elegendő a három kimenetű softmax, ha egy betegnek egyszerre két betegsége is lehet? Erre a kérdésre a multilabel szerződés ad pontos választ.
Logit. A neurális háló végső affin rétegének aktiváció előtti kimenete a logit. Egy elemű minibatch esetén a logitokat jelöli, ahol az osztályok vagy célváltozók száma. A logit nem valószínűség: lehet negatív, nulla vagy tetszőlegesen nagy.
Bináris cél és sigmoid. Bináris osztályozásban minden megfigyeléshez egyetlen cél tartozik. A modell egyetlen logitot ad, amelyből a
szigmoid aktiváció -beli becsült pozitív valószínűséget készít. Batchelt alakban: (vagy PyTorch-ban ) és ; a cél float32, mert a veszteségfüggvény valós célokkal dolgozik.
BCEWithLogits. A bináris cross-entropy logitbemenettel egy megfigyelésre:
Batchelt mean reduction esetén
;
sum reduction esetén az összeget jelöljük külön. A PyTorch
BCEWithLogitsLoss ezt a formulát számítja numerikusan
stabil módon, tehát a bemenete logit, nem szigmoidált érték. A szigmoid
és a BCE különválasztása
(
majd BCELoss) numerikusan kevésbé stabil, mert a logaritmus
alá kerülhet nagyon kicsi pozitív szám.
Multilabel cél. Multilabel osztályozásban minden megfigyeléshez egy float32 célmátrix tartozik: , ha az -edik példának a -adik címke jelen van. A modell logitmátrixot ad, és minden párra külön bináris BCE-t számítunk:
a reduction='mean' konvenció szerint. Fontos: itt nincs
softmax a
dimenzió mentén, mert az osztályok nem zárják ki egymást.
Regressziós cél és MSE. Ha a cél valós vektor , a modell kimenetet ad aktiváció nélkül, és a veszteség az átlagos négyzetes hiba:
ahol a reduction='mean' PyTorch-konvenció a batch és a
kimeneti dimenzió összes elemén átlagol. A mintánkénti négyzetes normák
-es
átlaga ettől
-szoros
tényezővel különbözik; a kettőt nem szabad azonosnak tekinteni. A
skalárkimenetű
()
esetben a képletek megegyeznek.
Class weights. Kiegyensúlyozatlan célok esetén a
veszteséghez súlyok adhatók. Bináris BCE esetén a
pos_weight paraméterrel a pozitív osztály tagját
súllyal szorozzuk:
Multilabel esetén osztályonkénti
súlyokat használhatunk; többosztályos cross-entropy esetén a
weight paraméter a
tagot súlyozza. A súlyozás nem változtatja meg a target dype-ot vagy
alakot.
Legyen , ahol rögzített és . Ekkor
Bizonyítás. A szigmoid deriváltja , amit a hányadosszabályból vagy a logisztikus differenciálegyenletből kapunk. A láncszabállyal:
és
Összeadva:
Ez a kifejezés esetén , tehát negatív, amikor a modell a pozitív osztályhoz tartozó becslése kicsi; ilyenkor a gradiens a logit növelése felé mutat. esetén , ami csökkenti a logitot, ha a modell tévesen magas valószínűséget ad. A batchelt mean derivált a 4.3. Jacobi-mátrix, láncszabály és VJP alfejezetbeli VJP-konvenció miatt alakú.
Tegyük fel, hogy a cél a modell kimenetének és egy additív zajnak az összege:
ahol ismert, rögzített variancia. A feltételes likelihood sűrűsége:
A negatív log-likelihood (NLL) egy megfigyelésre:
A paramétereitől független konstans tagot elhagyva a minimalizálandó cél az
kifejezés. Mivel rögzített, az négyzetes hiba minimalizálása ekvivalens az NLL minimalizálásával: a pozitív skálázás nem változtatja meg az optimum helyét. Ez az ekvivalencia azonban csak a fenti Gauss-feltevés mellett érvényes. Ha -et is becsülni kell, vagy a zaj nem additív Gauss, az MSE már nem indukál ugyanolyan likelihood-feladatot; például heteroszkedasztikus zajnál külön varianciamodellt kell becsülni.
Legyen egy bináris megfigyelés logitja és célja . Ekkor , a BCE veszteség
A gradiens a fenti tétel szerint .
Multilabel esetben legyen , és . A két elem BCE-je:
A reduction='mean' veszteség
.
Regressziós példa: , , . A négyzetes hibák: , , az átlag .
A labor három eltérő célszerződést ellenőriz shape- és dtype-szempontból. Az alábbi tábla az érvényes konfigurációkat foglalja össze:
| Feladat | Logit alak | Target alak | Target dtype | Loss |
|---|---|---|---|---|
| Bináris | vagy | a logittal pontosan azonos alak | float32 | BCEWithLogitsLoss |
| Multilabel | float32 | BCEWithLogitsLoss |
||
| Regresszió | float32 | MSELoss |
Hibás példák és javításuk:
Hiba: többosztályos one-hot cél
float32 alakkal
a BCEWithLogitsLoss-nak adva, a modell
logitot ad. Következmény: a könyvtár ezt multilabelként
értelmezi; minden osztályt függetlenül kezel, nincs softmax
normalizálás, ezért a modell helytelen szerződést tanul.
Javítás: ha a cél egyetlen kizárólagos osztály,
használjunk CrossEntropyLoss-t int64 célindexszel.
Hiba: bináris BCE-nek int64 target.
Következmény: dtype-hiba vagy csendes átkonvertálási
kísérlet; a BCE a célokat valósnak feltételezi.
Javítás: y.to(torch.float32).
Hiba: regressziós MSELoss-nak
int64 target. Következmény: a veszteség
nem tudja a gradienst visszavezetni a targetre (nem is kell), de az
input-típus-ellenőrzés hibát adhat. Javítás: a target
legyen float32.
Az alábbi kód a fenti ellenőrzést futtatja; a kimeneti értékek számított példák, a kódot a laborban külön futtatni kell:
# labor/n027_shape_check.py
import torch
torch.manual_seed(20261020)
device = torch.device("cpu")
dtype = torch.float32
# Bináris: N=2
z_bin = torch.zeros(2, 1, device=device, dtype=dtype)
y_bin = torch.tensor([[1.0], [0.0]], device=device, dtype=dtype)
loss_bin = torch.nn.functional.binary_cross_entropy_with_logits(z_bin, y_bin)
print("bináris loss, N=2:", loss_bin.item()) # számított példa: 0.6931
# Multilabel: N=1, K=2
z_ml = torch.tensor([[1.0, -2.0]], device=device, dtype=dtype)
y_ml = torch.tensor([[1.0, 0.0]], device=device, dtype=dtype)
loss_ml = torch.nn.functional.binary_cross_entropy_with_logits(z_ml, y_ml)
print("multilabel loss, N=1, K=2:", loss_ml.item()) # számított: 0.2201
# Regresszió: N=1, d_out=2
z_reg = torch.tensor([[1.5, 4.5]], device=device, dtype=dtype)
y_reg = torch.tensor([[2.0, 4.0]], device=device, dtype=dtype)
loss_reg = torch.nn.functional.mse_loss(z_reg, y_reg)
print("MSE loss, N=1, d_out=2:", loss_reg.item()) # számított: 0.25A kimeneti értékek a kézi példából következnek; toleranciaként
abszolút eltérés használható a print-elt értékek
ellenőrzéséhez. A seed itt nem befolyásolja a veszteségeket, mert nincs
véletlen mintavétel; a protokoll-egységesség miatt mégis rögzítjük.
F1 (fogalmi, nehézség 1). Egy dokumentumhoz egyszerre több témacímke is tartozhat a halmazból. Miért nem helyes egy háromkimenetű softmaxot használni? Adjunk egy konkrét célt, amelyet semmilyen softmax-kimenet nem tud pontosan előállítani, és indokoljuk.
F2 (levezetési, nehézség 2). Vezessük le a BCE logitgradiensét esetén közvetlenül a logisztikus függvény deriváltjának felhasználásával, majd számítsuk ki esetén a gradiens értékét három tizedesjegy pontossággal.
F3 (implementációs, nehézség 2). Írjunk
NumPy-függvényt bce_with_logits(z, y) néven, amely stabilan
számítja a BCE-t az
azonosság alapján, ahol . Ellenőrizzük a fenti azonosságot levezetéssel, és a függvényt a és eseteken; adjunk toleranciát is.
F4 (hibakeresési, nehézség 2). Az alábbi kód egy háromosztályos probléma céljait készíti elő:
N, K = 4, 3
logits = torch.randn(N, K, device="cpu", dtype=torch.float32)
target_onehot = torch.zeros(N, K, device="cpu", dtype=torch.float32)
target_onehot.scatter_(1, torch.randint(0, K, (N, 1), device="cpu"), 1.0)
loss = torch.nn.functional.binary_cross_entropy_with_logits(logits, target_onehot)Mi a szerződési hiba? Milyen matematikai következménye van a predikcióra nézve? Javítsuk a kódot úgy, hogy valódi többosztályos célt használjon, és adjuk meg a helyes target dype-ot.
F5 (kísérleti/transzfer, nehézség 3). Tervezzünk kis
kísérletet egy kiegyensúlyozatlan multilabel osztályozási feladatra,
ahol a pozitív címkék aránya osztályonként
,
és
.
Hasonlítsuk össze a súlyozatlan BCE-t és a pos_weight-et
(vagy osztálysúlyt) használó változatot. Adjunk protokollt: megfigyelési
egység, split, baseline, változó tényező, metrika, kiértékelési korlát.
Nem kell előre megjósolni a győztest.
F1 megoldás. A softmax egy diszkrét eloszlást ad, amelynek komponensei nemnegatívak és összegük . Egy többcímkés cél viszont tetszőleges csúcshalmazt megenged; az vektor összege , tehát nem lehet eloszlás. Pontosabban, ha , akkor , ezért és egyszerre nem teljesülhet. A helyes szerződés: darab független szigmoid kimenet, például , és multilabel BCE.
F2 megoldás. Az esetben . A szigmoid deriváltja , így a láncszabállyal
esetén , tehát a gradiens , három tizedesjegyre . A negatív előjel várható: a cél pozitív, a modell becslése nagyon kicsi, ezért a logitot növelni kell.
F3 megoldás. Az azonosság: . Mivel , kapjuk, hogy . Így
Ezért esetén a BCE ; esetén a BCE . A kettőt egységesen az alak adja, ugyanis -nál , -nél pedig . Az utóbbi: , ami valóban . Tehát az azonosság helyes.
import numpy as np
def softplus(z):
# logaddexp stabilan, elágazások túlcsorduló előértékelése nélkül
return np.logaddexp(0.0, z)
def bce_with_logits(z, y):
# z, y: float64 tömbök; y elemei {0,1}
return softplus(z) - y * z
# Ellenőrzés
for z, y in [(0.0, 1.0), (1.0, 0.0)]:
val = bce_with_logits(np.array(z), np.array(y))
print(z, y, val) # 0.0 1.0 0.69314718; 1.0 0.0 0.31326169Tolerancia: a referenciaértékekhez képest
és
.
A float64 használata a numerikus ellenőrzéshez ajánlott; a
tanítási főút ettől függetlenül float32 maradhat.
F4 megoldás. A hiba: a one-hot cél
BCEWithLogitsLoss-szal párosul, amely minden osztályt külön
bináris problémaként kezel. A modell
logitot ad, de nem normalizálja őket softmaxszal, így a predikált
osztályok valószínűségei nem összegződnek
-re,
és a kizárólagosság nem érvényesül. A matematikai következmény: a
tanulási cél nem a helyes diszkrét eloszlást közelíti. Javítás:
CrossEntropyLoss int64 indexekkel:
target_class = torch.randint(0, K, (N,), device="cpu") # int64
loss = torch.nn.functional.cross_entropy(logits, target_class)Ekkor a logits shape
,
a target shape
int64, és a softmax a loss belsejében történik.
F5 megoldásminta (nyitott). Egy lehetséges terv: a
GlyphLab-hoz hasonló kis szintetikus multilabel adat, ahol
független jelenet, minden jelenethez három bináris címke tartozik, a
pozitív arányok
,
,
.
A független mintavételi egység a scene_id. Rögzített,
címkénként rétegzett train/val/test split
arányban. Baseline: súlyozatlan BCEWithLogitsLoss, a
változat: pos_weight minden osztályhoz az inverz gyakoriság
arányában, vagy osztályonkénti weight. A kísérlet változója
csak a veszteségsúlyozás; a modell, az initializálás, az optimizáló, az
epochszám és a seed rögzített. Metrika: per-osztály és mikro-átlagolt
ROC-AUC/F1 a test spliten, az osztályaránytól független küszöbbel;
emellett a becsült pozitív gyakoriság eltérése. Korlát: a kis
szintetikus adat nem általánosít valós klinikai feladatra; a
pos_weight javíthatja a ritka osztályok visszahívását, de
ronthatja a globális F1-et, ezért nem állítunk előre győztest; legalább
három seed ismétlése szükséges a bizonytalansághoz.
A leggyakoribb szerződési hiba a többosztályos one-of-K cél és a
multilabel cél felcserélése. Tekintsük a
esetet és egy olyan kérdést, ahol egy dokumentum egyszerre „matematika”
és „programozás” címkéjű. A cél
.
A softmax-kimenet
elemei nemnegatívak és
,
ezért
és
egyszerre lehetetlen. Ha a hálót CrossEntropyLoss-szal
tanítjuk, az
cél int64 indexként nem is értelmezhető, mert egyetlen osztályindexet
vár. Ha viszont one-hot float célként a BCE-hez adjuk, a könyvtár nem
hibázik dtype miatt, de szemantikailag rossz célt tanít. Az ellenpélda
tehát azt mutatja, hogy a shape egyezése önmagában nem garantálja a
helyes szerződést; a célstruktúra matematikai jelentése dönt.
Önellenőrzés: tudjuk-e a BCE gradienst batchelt mean esetén felírni alakban? Meg tudjuk-e mondani, miért nem kapunk softmaxot a multilabel BCE-ben? El tudjuk-e választani az MSE optimumát a Gauss-variancia skálázásától?
Visszahívás: a logit gradiense a 7.2. Softmax és többosztályos cross-entropy alfejezetbeli softmax esetben volt; ezt a BCE gradiense egészíti ki, és mindkettő a logit bemenetű, numerikusan stabil lossok közös tulajdonsága. A mean/sum reduction különbsége a 6.3. Sztochasztikus és minibatch gradiens alfejezetben tárgyalt batch-átlagozáshoz kapcsolódik; a reguláris tagoknál ugyanez a pontos skála megadásának kötelezettsége. Az MSE pedig a 3.3. Vetítés, legkisebb négyzetek és kondicionáltság alfejezetbeli legkisebb négyzetek elvének neurális megfelelője.
A bináris cél logitból szigmoiddal alakul valószínűséggé, a BCEWithLogits pedig numerikusan stabil formulát ad; gradiense . Multilabel cél esetén célbithez független szigmoid tartozik, nincs softmax, a célmátrix float32. Regressziós cél aktiváció nélküli logitot használ, és MSE-vel tanul; ez rögzített varianciájú additív Gauss-zaj mellett ekvivalens a negatív log-likelihood minimalizálásával. A class weight a ritka célokra ad kontrollt, de nem változtatja meg a target alakját vagy dtype-ját. A labor shape- és dtype-táblája a három szerződést ellenőrzi.
A 7.4. Numerikus stabilitás és jelentésmegőrző implementáció egységben a numerikus stabilitást és a jelentésmegőrző implementációt általánosítjuk: a log-softmax, a BCE és az MSE implementációs trükkjei után megvizsgáljuk, hogyan őrizhető meg a matematikai jelentés lebegőpontos környezetben.