34.4 Teacher–student desztilláció

34.4.1 Cél, előismeret és induló kérdés

Ebben az alfejezetben egy már betanított, nagyobb „tanár” (teacher) háló viselkedését préseljük át egy kisebb „diák” (student) hálóba. A desztilláció lényege, hogy a diák nemcsak a merev osztálycímkét, hanem a tanár lágyított osztályeloszlását is megpróbálja utánozni. Előismeret: többosztályos cross-entropy és logit fogalma 7.2. Softmax és többosztályos cross-entropy, valamint a tanítási/kiértékelési mód megkülönböztetése 12.1. Tanítás, validáció és kiértékelési mód, 18.2. Batch normalization train és eval módban. Induló kérdés: ha egy 3 osztályos feladatban a címke 0, akkor a (1,0,0) cél miért hordoz kevesebb mintázatot a tanuló számára, mint egy (0.78, 0.15, 0.07) eloszlás?

34.4.2 Definíciók és tenzoralakok

Legyen a batch méret NN, az osztályok száma KK. A tanár logit kimenete

Zt∈ℝN×K, Z_t \in \mathbb{R}^{N\times K},

a diák logit kimenete

Zs∈ℝN×K. Z_s \in \mathbb{R}^{N\times K}.

A valódi osztálycímke y∈{0,…,K−1}Ny\in\{0,\ldots,K-1\}^N. A hőmérséklet (temperature) egy pozitív valós skalár, T>0T>0. A lágyított tanári cél (soft target) a soronkénti hőmérsékletes softmax:

qn,i=exp(Zt,n,i/T)∑j=1Kexp(Zt,n,j/T),q∈ℝN×K,∑iqn,i=1. q_{n,i} \;=\; \frac{\exp\!\left(Z_{t,n,i}/T\right)} {\sum_{j=1}^{K}\exp\!\left(Z_{t,n,j}/T\right)}, \qquad q\in\mathbb{R}^{N\times K},\quad \sum_i q_{n,i}=1.

A diák megfelelő eloszlása pp ugyanezzel a TT-vel:

pn,i=exp(Zs,n,i/T)∑j=1Kexp(Zs,n,j/T). p_{n,i} \;=\; \frac{\exp\!\left(Z_{s,n,i}/T\right)} {\sum_{j=1}^{K}\exp\!\left(Z_{s,n,j}/T\right)}.

A desztillációs loss a következő konvenciót követi:

ℒ(Zs;Zt,y,T,α)=αT2DKL(q∥p)+(1−α)CE(Zs,y), \mathcal{L}(Z_s; Z_t,y,T,\alpha) \;=\; \alpha\, T^2\, D_{KL}(q\,\|\,p) \;+\; (1-\alpha)\, \mathrm{CE}(Z_s,y), \tag{1}

ahol α∈[0,1]\alpha\in[0,1], és a két tag definíciója

DKL(q∥p)=1N∑n=1N∑i=1Kqn,ilogqn,ipn,i,CE(Zs,y)=−1N∑n=1Nlogexp(Zs,n,yn)∑jexp(Zs,n,j). D_{KL}(q\,\|\,p) = \frac1N\sum_{n=1}^{N}\sum_{i=1}^{K} q_{n,i}\log\frac{q_{n,i}}{p_{n,i}}, \qquad \mathrm{CE}(Z_s,y) = -\frac1N\sum_{n=1}^{N} \log \frac{\exp(Z_{s,n,y_n})}{\sum_j\exp(Z_{s,n,j})}.

Mindkét tag batch-átlag, tehát a loss egyetlen skalár. A CE\mathrm{CE} tag a PyTorch CrossEntropyLoss reduction='mean' konvenciójának felel meg logit bemenettel és int64 célindexszel. A KL tagban qq rögzített cél, pp a diák függvénye. Gyakori ekvivalens alternatíva a cross-entropy H(q,p)H(q,p) használata a KL helyett; a kettő gradiense a diák paramétereiben azonos, mert H(q,p)=DKL(q∥p)+H(q)H(q,p)=D_{KL}(q\|p)+H(q), és H(q)H(q) a diák paramétereitől független konstans. A loss értéke viszont eltér, ezért a naplózáskor meg kell nevezni, melyiket számoljuk.

A CE\mathrm{CE} tagot hard-label tagnak, a KL tagot soft-target tagnak nevezzük. A α\alpha a soft tag súlya; α=1\alpha=1 tisztán soft desztilláció, α=0\alpha=0 a szokásos felügyelt tanítás. A T=1T=1 esetén a soft tag a szokásos, nem lágyított softmaxeloszlások KL-divergenciája.

Teacher eval. A tanár súlyai a desztilláció során nem frissülnek. A soft célok előállításakor a tanárt eval() módba kell tenni, és torch.no_grad() alatt kell futtatni. Ez azért lényeges, mert dropout és BatchNorm esetén a train mód más kimenetet ad, mint az eval mód 18.2. Batch normalization train és eval módban; a soft céloknak azt az eloszlást kell reprezentálniuk, amelyet a tanár a kiértékeléskor produkál.

34.4.3 Levezetés: a hőmérsékletes cél alakja és a T2T^2 skálázás indoka

Először a gradiensről mondunk ki egy lemmát.

Lemma. Legyen q=softmax(a)q=\operatorname{softmax}(a) rögzített, p=softmax(b)p=\operatorname{softmax}(b), ahol a,b∈ℝKa,b\in\mathbb{R}^K. Ekkor

∇bDKL(q∥p)=p−q. \nabla_b D_{KL}(q\,\|\,p) \;=\; p-q.

Bizonyítás. A KL definíciójából

DKL(q∥p)=∑iqilogqi−∑iqilogpi. D_{KL}(q\,\|\,p) = \sum_i q_i\log q_i - \sum_i q_i\log p_i.

Az első tag bb-től független, ezért eltűnik a gradiensképzésnél. Marad a −∑iqilogpi-\sum_i q_i\log p_i tag. A softmax logaritmusának parciális deriváltja

∂logpi∂bj=δij−pj, \frac{\partial \log p_i}{\partial b_j} = \delta_{ij}-p_j,

ahol δij\delta_{ij} a Kronecker-delta. Ezt behelyettesítve

∂∂bj(−∑iqilogpi)=−∑iqi(δij−pj)=−qj+pj∑iqi=pj−qj, \frac{\partial}{\partial b_j} \left(-\sum_i q_i\log p_i\right) = -\sum_i q_i(\delta_{ij}-p_j) = -q_j + p_j\sum_i q_i = p_j-q_j,

mert ∑iqi=1\sum_i q_i=1. Ezzel a lemma bizonyítását befejeztük. ▫\square

Most helyettesítsük be a=Zt/Ta=Z_t/T és b=Zs/Tb=Z_s/T értékeket. Ekkor qq a tanári, pp a diákhőmérsékletes eloszlás. A láncszabály szerint, mivel ∂bi/∂Zs,i=1/T\partial b_i/\partial Z_{s,i}=1/T és a keresztderiváltak nullák,

∇ZsDKL(q∥p)=1T(p−q). \nabla_{Z_s} D_{KL}(q\,\|\,p) = \frac{1}{T}\,(p-q). \tag{2}

A (2) képlet a pontos, véges TT-re érvényes gradiens. A T2T^2-es szorzó nélkül a soft tag gradiense 1/T1/T-vel skálázódik. Miért éppen T2T^2 a szokásos kompenzáció? Ennek indoklása a nagy TT határesetből látható. Fejtsük sorba a hőmérsékleti softmaxot 1/T1/T szerint. Legyen z‾=1K∑jzj\bar z=\frac1K\sum_j z_j egy logitvektor átlaga. Ekkor

exp(zi/T)∑jexp(zj/T)=1K+zi−z‾KT+ri(T), \frac{\exp(z_i/T)}{\sum_j\exp(z_j/T)} = \frac{1}{K} + \frac{z_i-\bar z}{K\,T} + r_i(T),

ahol a maradéktag |ri(T)|≤C/T2|r_i(T)|\le C/T^2 valamilyen CC konstanssal, feltéve, hogy a logitok komponensei korlátosak. Így T→∞T\to\infty esetén

p−q=(Zs−Z‾s)−(Zt−Z‾t)KT+O(T−2), p-q = \frac{(Z_s-\bar Z_s)-(Z_t-\bar Z_t)}{K\,T} + O(T^{-2}),

ahol a kivonás és az átlag komponensenként értendő. Ezt (2)-be helyettesítve a skálázatlan KL gradiens aszimptotikus alakja

∇ZsDKL(q∥p)=(Zs−Z‾s)−(Zt−Z‾t)KT2+O(T−3). \nabla_{Z_s} D_{KL}(q\,\|\,p) = \frac{(Z_s-\bar Z_s)-(Z_t-\bar Z_t)}{K\,T^2} + O(T^{-3}).

A logit-térbeli gradiens nagyságrendje tehát 1/T21/T^2-tel csökken. Ha a soft tagot T2T^2-tel szorozzuk, akkor a gradiens

T2∇ZsDKL(q∥p)=T(p−q)→(Zs−Z‾s)−(Zt−Z‾t)K+O(T−1), T^2\,\nabla_{Z_s} D_{KL}(q\,\|\,p) = T(p-q) \;\to\; \frac{(Z_s-\bar Z_s)-(Z_t-\bar Z_t)}{K} + O(T^{-1}),

ami T→∞T\to\infty esetén már TT-független határértékhez tart. A T2T^2-es szorzó tehát azt biztosítja, hogy a hőmérséklet növelése ne hígítsa fel a soft tag tanító jelét. Pontosabban: az (1)-beli T2T^2 a loss értékét skálázza; a láncszabály miatt a gradiensre gyakorolt hatása ugyanez a T2T^2 szorzó. A fenti határérték-állítás aszimptotikus heurisztika, nem minden TT-re pontos egyenlőség; a véges TT-re érvényes igazság a (2) képlet. Ez a levezetés a saját konvenciónkra vonatkozik; az eredeti desztillációs javaslatban is hasonló skálázás szerepel [P26], de annak részletes szakaszát a kézirat írásakor nem áll módunkban teljes szövegként idézni.

34.4.4 Eredeti kézi kis példa

Legyen N=1N=1, K=3K=3, T=2T=2, α=0.7\alpha=0.7. A tanár logitja

Zt=(2.5,0.0,−0.5), Z_t=(2.5,\;0.0,\;-0.5),

a diák kezdeti logitja

Zs=(1.2,0.3,−0.9), Z_s=(1.2,\;0.3,\;-0.9),

és a valódi címke y=0y=0. Először a hőmérsékleti softmaxok. A tanári cél:

e2.5/2=e1.25≈3.4903,e0/2=1,e−0.5/2=e−0.25≈0.7788, \begin{aligned} e^{2.5/2}&=e^{1.25}\approx 3.4903,\\ e^{0/2}&=1,\\ e^{-0.5/2}&=e^{-0.25}\approx 0.7788, \end{aligned}

az összeg 5.26915.2691, így

q=(0.6624,0.1898,0.1478). q=(0.6624,\;0.1898,\;0.1478).

A diák hőmérsékleti eloszlása hasonlóan:

e1.2/2=e0.6≈1.8221,e0.3/2=e0.15≈1.1618,e−0.9/2=e−0.45≈0.6376, \begin{aligned} e^{1.2/2}&=e^{0.6}\approx 1.8221,\\ e^{0.3/2}&=e^{0.15}\approx 1.1618,\\ e^{-0.9/2}&=e^{-0.45}\approx 0.6376, \end{aligned}

az összeg 3.62153.6215, tehát

p=(0.5031,0.3208,0.1761). p=(0.5031,\;0.3208,\;0.1761).

A KL tag:

DKL(q∥p)≈0.6624ln0.66240.5031+0.1898ln0.18980.3208+0.1478ln0.14780.1761≈0.0567. D_{KL}(q\|p) \approx 0.6624\ln\frac{0.6624}{0.5031} + 0.1898\ln\frac{0.1898}{0.3208} + 0.1478\ln\frac{0.1478}{0.1761} \approx 0.0567.

A T2T^2-es szorzóval a soft tag 4⋅0.0567=0.22684\cdot 0.0567=0.2268. A hard-label tag a T=1T=1 softmaxból: softmax(Zs)=(0.6540,0.2659,0.0801)\operatorname{softmax}(Z_s)=(0.6540,0.2659,0.0801), így

CE(Zs,y)=−ln(0.6540)≈0.4247. \mathrm{CE}(Z_s,y)=-\ln(0.6540)\approx 0.4247.

A teljes loss:

ℒ=0.7⋅0.2268+0.3⋅0.4247≈0.2862. \mathcal L=0.7\cdot 0.2268+0.3\cdot 0.4247\approx 0.2862.

A gradiens ellenőrzéséhez használjuk a (2) képletet és a lemma bizonyítását. A soft tag T2T^2-es gradiensére

T(p−q)=2⋅(−0.1593,0.1310,0.0283)=(−0.3186,0.2620,0.0566). T(p-q) = 2\cdot(-0.1593,\;0.1310,\;0.0283) = (-0.3186,\;0.2620,\;0.0566).

A hard tag gradiense a szokásos softmax-cél különbség:

∇ZsCE=(0.6540,0.2659,0.0801)−(1,0,0)=(−0.3460,0.2659,0.0801). \nabla_{Z_s}\mathrm{CE} = (0.6540,\;0.2659,\;0.0801)-(1,0,0) = (-0.3460,\;0.2659,\;0.0801).

A teljes gradiens α\alpha-súlyozva:

∇Zsℒ≈0.7(−0.3186,0.2620,0.0566)+0.3(−0.3460,0.2659,0.0801)=(−0.3268,0.2632,0.0636). \nabla_{Z_s}\mathcal L \approx 0.7(-0.3186,0.2620,0.0566) + 0.3(-0.3460,0.2659,0.0801) = (-0.3268,\;0.2632,\;0.0636).

Az alábbi kód ugyanezt a veszteséget és gradienst számítja ki numerikusan; a kézirat írásakor ezt a kimenetet nem futtatott mérésként, hanem a fenti kézi számításból adódó várható értékként jelöljük.

# lab/n136_distill/soft_target_example.py
import torch
import torch.nn.functional as F

def distillation_loss(z_s, z_t, y, T, alpha):
    """
    z_s, z_t: (N, K) logit tensorok
    y:        (N,) int64 osztalyindex
    T:        pozitiv float
    alpha:    float [0,1], a soft tag sulya
    """
    q = torch.softmax(z_t / T, dim=1)
    log_p = torch.log_softmax(z_s / T, dim=1)
    kd = F.kl_div(log_p, q, reduction='batchmean')
    ce = F.cross_entropy(z_s, y, reduction='mean')
    return alpha * T * T * kd + (1.0 - alpha) * ce

torch.manual_seed(20261020)
z_t = torch.tensor([[2.5, 0.0, -0.5]], dtype=torch.float64)
z_s = torch.tensor([[1.2, 0.3, -0.9]], dtype=torch.float64, requires_grad=True)
y = torch.tensor([0], dtype=torch.int64)

loss = distillation_loss(z_s, z_t, y, T=2.0, alpha=0.7)
loss.backward()
print(f"loss={loss.item():.4f}")
print(f"grad={z_s.grad.detach().numpy()}")

A várt kimenet loss=0.2862 és grad=[[-0.3268, 0.2632, 0.0636]] körül, körülbelül 10−310^{-3} abszolút toleranciával, mert a kézi számítás négy tizedesjegyre kerekített.

34.4.5 Konkrét labor: azonos tesztprotokollú desztilláció a GlyphLabon

A következő mérési terv a GlyphLab adatszerződést használja. A tanár és a diák is ugyanazt a train/val/test felosztást kapja, és a modellválasztás kizárólag a clean validációs loss alapján történik, ahogyan azt 22.4. Augmentációs kísérlet és domainváltozás előírja. A kézirat írásakor ezt a kísérletet nem futtattuk, ezért alább csak a protokollt és a desztilláció-specifikus kódvázlatot adjuk meg; a kimeneti számok a fenti kézi példa ellenőrzésére szolgálnak.

Protokoll.

  1. Teacher tanítás. Egy kis CNN (például 2 konvolúciós réteg 8 és 16 csatornával, ReLU, maxpool, majd 64 egységes MLP-feijel) betanítása a data/images.npy train részén, 240 képen, seed 20261020, Adam, tanulási ráta 10−310^{-3}, batch 32, legfeljebb 20 epoch. A legjobb checkpointot a val loss választja ki.
  2. Soft cél cache. A legjobb teachert eval() módban, torch.no_grad() alatt futtatjuk a train és val képekre. A kapott N×3N\times 3 logit tenzort float32 tömbben elmentjük. A tanár a diák tanítása alatt nem fut újra.
  3. Student tanítás. Egy kisebb CNN (például 1 konvolúció 8 csatornával, 32 egységes MLP-feijel) tanítása ugyanazon a train spliten az (1) loss-szal, T=4T=4 és α=0.7\alpha=0.7 mellett. A val spliten a modellválasztáshoz a hard-label CE-t számoljuk, hogy a baseline-nal összehasonlítható legyen.
  4. Baseline. Ugyanez a student architektúra, ugyanaz a seed, epoch-szám, batch és optimizer, de α=0\alpha=0, azaz tiszta hard-label tanítás.
  5. Végső teszt. A legjobb val checkpointot egyszer futtatjuk a clean tesztre, majd a corrupted_test.npy halmazra. A két halmaz ugyanazon scene/view párokból áll, ezért a clean–corrupt pontosságkülönbség páros, jelenetszintű összehasonlítás 22.4. Augmentációs kísérlet és domainváltozás. A teachert is ugyanígy kiértékeljük összehasonlításként.
  6. Erőforrás-mérés. A futásidő mérésére a torch.utils.benchmark [D16] és a torch.profiler [D17] használható; a mérési környezetet, az eszközt és az egyes profilozási beállításokat minden futtatáskor a laborjelentésben kell rögzíteni.

A desztilláció-specifikus kódvázlat:

# lab/n136_distill/train_distill.py
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F

torch.manual_seed(20261020)
np.random.seed(20261020)

images = np.load("../data/images.npy")       # (360,1,24,24) float32
labels = np.load("../data/labels.npy")       # (360,) int64

# ... train/val/test indexek a metadata.csv split oszlopa alapjan ...

def make_soft_cache(teacher, split_images):
    teacher.eval()
    with torch.no_grad():
        # split_images: (M,1,24,24) float32 CPU tensor
        logits = teacher(split_images)       # (M,3)
    return logits.detach().cpu().float()     # soft target cache

def distillation_loss(z_s, z_t, y, T, alpha):
    q = torch.softmax(z_t / T, dim=1)
    log_p = torch.log_softmax(z_s / T, dim=1)
    kd = F.kl_div(log_p, q, reduction='batchmean')
    ce = F.cross_entropy(z_s, y, reduction='mean')
    return alpha * T * T * kd + (1.0 - alpha) * ce

# ... a tanitasi hurok a n044 szerinti szerkezetet koveti; a teacher
#     forwardja helyett a cache-bol toltjuk a z_t-t ...

Futtatási parancs a munkakönyvtárból:

cd lab/n136_distill
python train_distill.py --T 4 --alpha 0.7 --seed 20261020

Az átadandó eredmény: tanári és diák val pontosság, clean test pontosság, corrupt test pontosság, valamint a corrupt–clean páros különbség átlaga és szórása. Értelmezési korlát: a GlyphLab 24×24 pixeles procedurális adat, ezért az eredmény nem általánosít természetes képi feladatokra.

34.4.6 Feladatok

34.4.6.1 F1 fogalmi (nehézség 1)

Magyarázza el, miért nem azonos a desztilláció a label smoothinggal. Adjon egy K=3K=3 osztályú, N=1N=1 példát, amelyben a tanári soft cél q=(0.02,0.95,0.03)q=(0.02,0.95,0.03), a valódi címke y=1y=1, és mutassa meg, hogy a 0.10.1 egyenletes hátterű label smoothing cél ettől különbözik.

34.4.6.2 F2 levezetési (nehézség 2)

Bizonyítsa be a fenti lemma felhasználásával, hogy az (1) loss-ban a soft tag gradiensére

∇Zs(αT2DKL(q∥p))=αT(p−q) \nabla_{Z_s}\left(\alpha T^2 D_{KL}(q\|p)\right) = \alpha T(p-q)

teljesül. Ellenőrizze a képletet a kézi példa T=2T=2, α=0.7\alpha=0.7 adataira, és adja meg a kapott háromdimenziós gradiensvektort.

34.4.6.3 F3 implementációs (nehézség 2)

Implementálja a distillation_loss függvényt úgy, hogy ne használja a torch.nn.KLDivLoss osztályt, hanem a KL tagot a qlog(q/p)q\log(q/p) definícióból számolja. A függvény bemenete z_s, z_t, y, T, alpha; a kimenet skalár. Ellenőrizze a kézi példán: z_s, z_t, y, T=2.0, alpha=0.7 mellett a loss 0.2862±10−30.2862\pm 10^{-3}.

34.4.6.4 F4 hibakeresési (nehézség 3)

Az alábbi részlet hibásan állítja elő a soft célokat:

teacher.train()
with torch.no_grad():
    z_t = teacher(x_batch)          # (N,3)
q = torch.softmax(z_t / T, dim=1)   # soft target
# ... studenttanítási lépés ...
# a teacher súlyai nem frissülnek, de a BatchNorm statisztikája train módban

Nevezze meg a hiba okát, írja le a következményét a desztillált diák tanítására, javítsa a kódot, és adja meg, hogyan ellenőrizné a javítás helyességét.

34.4.6.5 F5 kísérlettervezési/transzfer (nehézség 3)

Tervezzen kísérletet, amely a GlyphLabon a hard-label baseline-t egy T=1T=1, T=4T=4 és T=8T=8 desztillált studenttel hasonlítja össze, mindegyiket 3 különböző seeddel. Adja meg a megfigyelési egységet, a splitet, a modellválasztási szabályt, a metrikát, a számítási és címkeköltség-keretet, valamint a következtetés érvényességi korlátját.

34.4.7 Megoldások és indoklás

34.4.7.1 F1 megoldása

A label smoothing a valódi one-hot cél eye_y helyett a

(1−ε)ey+εK−1(1−ey) (1-\varepsilon)e_y+\frac{\varepsilon}{K-1}(1-e_y)

eloszlást használja; ez a háttérosztályokat szimmetrikusan, egyenletesen tölti fel, és nem függ egyetlen tanár predikciójától sem. A desztilláció ezzel szemben egy konkrét tanár által számított qq eloszlást használ célként, amely tükrözheti a tanár osztályok közötti hasonlósági ítéletét. A megadott q=(0.02,0.95,0.03)q=(0.02,0.95,0.03) és ε=0.1\varepsilon=0.1 esetén a smoothing cél

(1−0.1)(0,1,0)+0.1⋅(0.5,0,0.5)=(0.05,0.9,0.05), (1-0.1)(0,1,0)+0.1\cdot(0.5,0,0.5) = (0.05,\;0.9,\;0.05),

amely különbözik a tanári qq-tól: a tanár a 2. osztályt kissé valószínűbbnek tartja a 0. osztálynál, míg a smoothing ezt a kettőt egyenlővé teszi.

34.4.7.2 F2 megoldása

A lemma szerint a KL gradiens a diák hőmérsékleti logitjaira ∇bDKL=p−q\nabla_b D_{KL}=p-q, ahol b=Zs/Tb=Z_s/T. A láncszabállyal

∇ZsDKL=1T(p−q). \nabla_{Z_s}D_{KL} = \frac{1}{T}(p-q).

A loss αT2\alpha T^2-szeres szorzót tartalmaz, ezért

∇Zs(αT2DKL)=αT(p−q). \nabla_{Z_s}\left(\alpha T^2 D_{KL}\right) = \alpha T(p-q).

A kézi példában p−q=(−0.1593,0.1310,0.0283)p-q=(-0.1593,0.1310,0.0283), így

αT(p−q)=0.7⋅2⋅(−0.1593,0.1310,0.0283)=(−0.2230,0.1834,0.0396). \alpha T(p-q) = 0.7\cdot 2\cdot(-0.1593,0.1310,0.0283) = (-0.2230,\;0.1834,\;0.0396).

34.4.7.3 F3 megoldása

# lab/n136_distill/manual_kd.py
import torch
import torch.nn.functional as F

def distillation_loss_manual(z_s, z_t, y, T, alpha):
    q = torch.softmax(z_t / T, dim=1)
    p = torch.softmax(z_s / T, dim=1)
    # numerikusan stabilabb: q*(log q - log p)
    kd = torch.sum(q * (torch.log(q + 1e-12) - torch.log(p + 1e-12)), dim=1).mean()
    ce = F.cross_entropy(z_s, y, reduction='mean')
    return alpha * T * T * kd + (1.0 - alpha) * ce

torch.manual_seed(20261020)
z_t = torch.tensor([[2.5, 0.0, -0.5]], dtype=torch.float64)
z_s = torch.tensor([[1.2, 0.3, -0.9]], dtype=torch.float64, requires_grad=True)
y = torch.tensor([0], dtype=torch.int64)
loss = distillation_loss_manual(z_s, z_t, y, T=2.0, alpha=0.7)
print(float(loss))

Az ellenőrzés: a kézi számítás 0.2862; a kódnak ezt kell visszaadnia 10−310^{-3} abszolút hibán belül. A 1e-12 hozzáadás csak az üres logaritmus elkerülésére szolgál; float64 bemenetnél a négy tizedesjegyre kerekített kézi értékhez képest a hiba O(10−4)O(10^{-4}).

34.4.7.4 F4 megoldása

Hiba oka: a tanárt train() módban hagytuk, ezért a BatchNorm rétegek a minibatch-átlagot és varianciát használják, nem a tanítás során gyűjtött running statisztikát. Ráadásul a no_grad csak a gradiens számítását kapcsolja ki, a BN training flagjét nem.

Következmény: a soft célok batch-függővé válnak; ugyanahhoz a képhez különböző minibatch-összetétel mellett más qq tartozhat. A diák inkonzisztens célokat kap, ami a desztillációs jelet zajossá és a kiértékelési viselkedéstől eltérővé teszi.

Javítás:

teacher.eval()
with torch.no_grad():
    z_t = teacher(x_batch)

Ellenőrzés: futtassuk a tanárt két különböző minibatch-be rendezett adaton; eval() módban a logitoknak batch-átrendezéstől függetlenül azonosnak kell lenniük, míg a hibás train() módban a BatchNorm miatt eltérhetnek.

34.4.7.5 F5 megoldása

Megfigyelési egység: a GlyphLab scene_id, mert a két nézet ugyanahhoz a jelenethez tartozik; a bootstrap és a páros összehasonlítás is jelenetszintű 22.4. Augmentációs kísérlet és domainváltozás. Split: a rögzített train/val/test osztás; a corrupt teszt csak a test scene párokra épül. Modellválasztás: minden seedhez a clean val loss minimumánál választunk best checkpointot; a tesztet csak ezután, egyszer értékeljük. Változó tényező: a soft tag hőmérséklete T∈{1,4,8}T\in\{1,4,8\}, rögzített α=0.7\alpha=0.7 mellett, plusz a α=0\alpha=0 baseline. Metrika: clean test accuracy, corrupt test accuracy, és a corrupt–clean páros különbség átlaga. Költségkeret: a tanár egyszer tanul meg, és minden diák-kísérlet ugyanannyi képcímkét használ; a számítási keret a diák forward/backward lépéseinek számával normalizálva azonos. Érvényességi korlát: a GlyphLab toy adat, ezért a TT sorrendből nem vonható le következtetés természetes képekre; a 3 seed csak a seed-szórás alsó becslését adja; a soft célokból nyert nyereség nem bizonyítja, hogy a diák a tanár minden hibaszeletét megőrzi.

34.4.8 Tipikus tévedés és ellenpélda

Gyakori tévedés, hogy a desztillált diák automatikusan megőrzi a tanár minden viselkedését, például a ritka osztályokon vagy a corrupt bemeneteken mutatott pontosságát. A desztillációs loss a soft célok átlagos KL-divergenciáját bünteti, de a diák kapacitása kisebb, és a loss nem tartalmaz szeletenkénti súlyozást. Ellenpélda: legyen egy háromosztályos feladat, amelyben az 1. osztály a gyakori, a 2. osztály pedig ritka, és a tanár a ritka osztályon 90%-os, a gyakorin 95%-os pontosságú. Ha a diák a soft célokat a gyakori osztályok mintáin jobban tudja csökkenteni, akkor előfordulhat, hogy a teljes KL alacsony marad, miközben a ritka osztály pontossága 70%-ra esik vissza. A desztilláció tehát nem helyettesíti a 33.4. Üzemeltetés, drift és késő címke alfejezetben bevezetett monitorozást és a hibaszelet-elemzést; az üzembe helyezés előtt a diákot ugyanazokkal a tesztekkel kell ellenőrizni, mint a tanárt.

34.4.9 Önellenőrzés és visszahívás

A definíciók ellenőrzése: a soft cél minden sora valószínűségeloszlás, nemnegatív és 11 összegű; a hard-label tag logit bemenetet vár, előtte nem végzünk softmaxot 7.2. Softmax és többosztályos cross-entropy. A KL csak akkor véges, ha qq supportja benne van pp supportjában; hőmérsékleti softmax esetén ez teljesül. A numerikus stabilitáshoz log_softmax használata indokolt, nem külön softmax majd log. A 34.3. Pruning és struktúra alfejezetből tudjuk, hogy a pruning után a ritka súlyok tényleges kihagyása külön lépés; a desztilláció a kisebb modell előállításának alternatív útja, és a kettő kombinálható, ha a prune-olt diákot ezután a soft célokkal finomhangoljuk. A 30.4. Önfelügyelt kísérlet korrekt összevetése költségkerete itt is érvényes: ha a tanári logitokat címkézetlen képekre is kiterjesztjük, akkor a címkeköltség és a teacher-forward költség külön sorban könyvelendő, hogy a hard-label baseline-nal való összehasonlítás fair maradjon. Végül a 22.4. Augmentációs kísérlet és domainváltozás szerint a corrupt tesztet csak a befagyasztott, legjobb val checkpointon értékeljük, és a clean–corrupt különbséget páros, jelenetszintű adatként kezeljük.

34.4.10 Rövid összefoglaló

A tudásdesztilláció egy kiértékelő módba kapcsolt, befagyasztott tanár lágyított osztályeloszlásait használja célként egy kisebb diák tanításához. Az (1) loss egy α\alpha súlyú soft KL tagból és egy (1−α)(1-\alpha) súlyú hard-label cross-entropy tagból áll. A soft tagban a tanári és diáklagitok egyaránt TT-vel osztottak; a lemma szerint a KL gradiens (p−q)/T(p-q)/T, ezért a T2T^2-es szorzó a nagy TT határesetben kompenzálja a logit-gradiens 1/T21/T^2-es csillapodását. A labor azonos tesztprotokollt ír elő a tanárra, diákra és hard-label baseline-ra, és a corrupt tesztet páros jelenetszintű adatként értékeli.

34.4.11 Következő alkalmazás

A 35.1. Saliency és Grad-CAM a Grad-CAM és a saliency-térképek alapjait tárgyalja. A desztillált diák kisebb paraméterszámú modellje alkalmas kiindulópont a magyarázatok sanity checkjéhez, mert a tanár-diák eltérések vizsgálata megmutathatja, mely bemeneti régiókban marad meg vagy vész el a tanári viselkedés.

34.4.12 Források