A 35.1. Saliency és Grad-CAM egységben definiáltuk a saliency-térképet és a Grad-CAM-et mint „a modell döntésére magyarázatot kínáló” vizualizációt. Ott a képlet megadja, mit rajzolunk. Most azt kérdezzük: honnan tudjuk, hogy a kirajzolt térkép egyáltalán a modelltől függ, nem pedig csak a kép statisztikai tulajdonságaitól? Ha egy módszer akkor is ugyanazt a „fontos területet” jelölné, amikor a modell súlyait véletlenre cseréljük, akkor a magyarázat nem a tanult modell magyarázata.
Előismeret. A 35.1. Saliency és Grad-CAM alfejezetből a bemeneti gradiens és a Grad-CAM súlyozási képlete szükséges. A 34.2. Kvantálás és hibatovábbterjedés arra figyelmeztetett, hogy a numerikus reprezentáció hibája különbözik a modellstruktúra hibájától; a mostani kontroll szintén különválasztja a mérési hibát a magyarázat tényleges modellfüggésétől. A 31.2. GAN mint minimax probléma alfejezetben láttuk, hogy egy optimum létezése nem garancia a véges tanítás konvergenciájára; hasonlóan, egy magyarázó képlet helyessége nem garancia arra, hogy a kimenet a tanult reprezentációt tükrözi. A 23.2. Kalibráció és döntési küszöb kalibrációs tanulsága pedig az, hogy egy számszerű kimenet (ott a softmax, itt a fontossági térkép) önmagában nem tekinthető evidenciának a mögöttes állításra.
Induló kérdés. Adott egy betanított GlyphLab-CNN, és legyen a Grad-CAM-je egy adott képen a kép felső sávjára koncentrált. Tegyük fel, hogy a modell súlyait véletlenre cseréljük, majd ugyanarra a képre újra kiszámítjuk a Grad-CAM-et. Ha a két térkép gyakorlatilag azonos, akkor megbízhatunk-e abban, hogy a magyarázat a tanult modell döntéséről szól?
Jelölések. Legyen a bemenet (a GlyphLab NCHW konvenciója; a batchdimenziót elhagyjuk), a modell logitokkal, paramétervektorral. Egy magyarázó módszer
nemnegatív fontossági térképet ad a célosztályra. A 35.1. Saliency és Grad-CAM alfejezetben tárgyalt Grad-CAM esetén rendszerint a modell által prediktált osztály; a randomizálási kísérletben rögzített, előre választott -t használunk, mert a véletlen súlyú modell predikciója nem hordoz tanult információt. A konkrét lehet a bemeneti gradiens nagysága vagy a Grad-CAM upsampling utáni térképe; a kontroll logikája mindkettőre azonos.
Parameter randomization (paraméter-randomizálás). A modell tanulható rétegét tetszőleges sorrendben indexeljük. A -edik szintű paraméter-randomizálás az réteg minden paraméterét a réteg inicializálási eloszlásából frissen húzott értékkel helyettesíti, a rétegek a betanított értékükön maradnak. A teljes randomizálásnál . A kontroll azt méri, hogy
hogyan változik függvényében, ahol egy hasonlósági metrika.
Label randomization (címkerandomizálás). A tanítóhalmaz címkéit a minták indexein végzett véletlen permutációval -re cseréljük, a képek változatlanok maradnak, majd a modellt a véletlen címkéken újratanítjuk. A permutáció az osztályok gyakoriságát megőrzi, de a képek és a tanító címkék közötti kapcsolatot véletlenszerűvé teszi. Ezzel szemben az osztályazonosítók globális átnevezése (, stb.) nem megfelelő kontroll, mert az eredeti célfüggvény információtartalmát változatlanul hagyja. A kérdés itt nem a betanított modell perturbálása, hanem hogy a tanító jel és a bemeneti képek közötti érdemi kapcsolat megváltoztatása módosítja-e a magyarázatot. A két randomizálás tehát két különböző függőséget tesztel:
| Randomizálás | Mit randomizálunk | Milyen függőséget vizsgál |
|---|---|---|
| Paraméter- | betanított súlyok | inference-kori paraméterfüggés |
| Címke- | tanító címkék | tanulási jel függése |
Saliency control. A kontroll egy modellmentes leképezés , például a Sobel-élkép vagy egy rögzített középpontú Gauss-súlyozás. A értéke nem változik, ha a modellt randomizáljuk. Ha a vizsgált magyarázat az eredeti modellhez képest nem mutat nagyobb modellérzékenységet, mint amennyit a modellmentes kontroll adatfüggése önmagában magyaráz, akkor a magyarázat modellhez kötött állítása nem támogatott.
Similarity limits. A hasonlósági metrika megválasztása maga is korlátozza a kontroll értelmezését. A könyv alapértelmezett metrikája a lapított, azonos méretűre interpolált térképek közötti Spearman-rangkoreláció:
A Spearman- invariáns a szigorúan monoton növekvő transzformációkra: ha , , akkor . Ezért a randomizálás okozta pusztán pozitív skálázást a rangkorreláció nem detektálja. A metrika globális: lokális eltolódások és a térkép invertálása (negatív ) csak korlátozottan jelenik meg. A kontrollt ezért mindig rögzített, indokolt metrika mellett kell jelenteni.
A sanity check logikai szerkezetét a következő állításban rögzítjük.
Állítás (a paraméter-randomizálás elutasítási logikája). Legyen magyarázó módszer, és tegyük fel, hogy modellfüggetlen: minden , minden bemenetre és rögzített osztályra
Ekkor tetszőleges paraméter-randomizálás után a Spearman- az eredeti és a randomizált magyarázat között determinisztikusan , feltéve, hogy a magyarázat nem konstans (nulla szórású) térkép.
Bizonyítás. A modellfüggetlenségi feltételt és a randomizált párra alkalmazva . A rangvektorok azonosak, tehát a Spearman- számlálójában a két azonos sorozat kovarianciája a szórással egyenlő, azaz . Ha a magyarázat konstans, a szórás nulla, és a nem definiált; ezt a kísérletben külön ki kell zárni, például szóráskontrollal.
A gyakorlati kontroll ezt a kontrapozíciót használja: ha a mért hasonlóság a randomizálás után szignifikánsan alá esik, akkor a modellfüggetlenség feltételezése megdől. A megfigyelés tehát cáfolhatja azt az állítást, hogy a magyarázat csak a bemenet statisztikájától függ. Azt viszont nem bizonyítja, hogy a megmaradó hasonlóság a „helyes” magyarázat, hogy a módszer a döntési mechanizmust hűen tükrözi, vagy hogy a küszöbértéke általános érvényű. Az alacsonyabb a randomizálás után a modellfüggőség egyik lehetséges jele, de önmagában nem elégséges bizonyíték arra, hogy a hőtérkép hű magyarázat, mert egy buta, de a súlyokat valamilyen nemlineáris módon felhasználó módszer is mutathat modellérzékenységet anélkül, hogy a döntéshez releváns régiókra mutatna.
Ugyanez a logika a címkerandomizálásra: ott a nullhipotézis az, hogy a magyarázat független a tanulási jel osztálytartalmától. Ha a véletlen címkén tanított modell magyarázata nem tér el szignifikánsan az igazi címkén tanítottétól, akkor ez a kontroll nem szolgáltatott bizonyítékot arra, hogy a módszer a tanult feladatfüggést jeleníti meg. Ebből a nemelutasításból viszont nem következik, hogy a magyarázat független a címkétől vagy hibás: a szignifikáns eltérés hiánya származhat alacsony statisztikai erőből (kevés kép, kevés ismétlés), és a választott hasonlósági mértékből is — a fejezet saját ellenpéldája szerint a Spearman- pozitív skálázásra érzéketlen, így egy modellfüggő módszer is adhat -et. Ilyenkor több kontrollt (paraméter- és címkerandomizálás együtt) és több metrikát (rangkorreláció mellett például a térképek szerkezeti hasonlósága vagy a legfontosabb pixelek átfedése) kell használni. De a címkerandomizálás sem bizonyítja a hűséget: az alacsony szintű képstatisztika (például élirány) véletlen címkék mellett is beépülhet az első konvolúciós rétegbe, ezért a ritkán esik nullára pusztán a címke miatt.
Legyen egy utolsó konvolúciós jellemzőtérkép két csatornával, , a logit pedig a csatornák lineáris kombinációja:
A betanított modell súlyai . A Grad-CAM súlyozása 35.1. Saliency és Grad-CAM szerint , azaz . Legyen
Ekkor a Grad-CAM aktiváció ReLU után:
A lapított vektor ; a rangok: , a két -as és átlaga , a -es . Tehát .
Most randomizáljuk a fej súlyait:
Az új súlyozás: , . A randomizált modell magyarázata:
A lapított vektor , rangjai . A két rangvektor átlaga egyaránt . A kovariancia:
A szórásnégyzetek: és , így
A randomizálás tehát a hasonlóságot -ről -ra csökkentette ezen a kézzel számolt példán. Ha viszont a randomizált súly az eredeti pozitív skalárszorosa lenne, mondjuk , akkor a rangok változatlanok maradnának, és lenne. Ez a fenti hasonlósági korlát konkrét illusztrációja.
A számítást ellenőrző minimális kód a
examples/n138_spearman_example.py munkakönyvtárból:
import numpy as np
def rank_average(v):
v = np.asarray(v, dtype=np.float64).ravel()
order = np.argsort(v, kind="mergesort")
ranks = np.empty_like(order, dtype=np.float64)
i, n = 0, v.size
while i < n:
j = i + 1
while j < n and v[order[j]] == v[order[i]]:
j += 1
ranks[order[i:j]] = (i + j - 1) / 2.0 + 1.0
i = j
return ranks
def spearman(a, b):
ra, rb = rank_average(a), rank_average(b)
if ra.std(ddof=0) == 0 or rb.std(ddof=0) == 0:
return float("nan")
return float(np.corrcoef(ra, rb)[0, 1])
A1 = np.array([[0., 2.], [1., 3.]], dtype=np.float64)
A2 = np.array([[3., 0.], [2., 1.]], dtype=np.float64)
w1 = np.ones((2, 2)); w2 = np.ones((2, 2))
L = w1.mean() * A1 + w2.mean() * A2
w1r = np.array([[-1., 1.], [2., 0.5]])
w2r = np.array([[1., 0.], [1., -1.]])
Lr = w1r.mean() * A1 + w2r.mean() * A2
print("rho(L, Lr) =", round(spearman(L, Lr), 6))
print("rho(L, 2*L) =", round(spearman(L, 2.0 * L), 6))Futtatás: python examples/n138_spearman_example.py. Az
elvárt kimenet
és
;
az utóbbi a monoton transzformációra való érzéketlenséget mutatja.
Az alábbi labor a GlyphLab-adat test részének első 20
képén paraméter-randomizálást végez. A kód a 24.4.
VI. ellenőrző pont: megbízható CNN-training labor modelljét és
checkpointját használja: a TinyCNN osztályt a
lab/n096_checkpoint.py modulból importálja (egyetlen
forráshely a tanítástól a Grad-CAM-ig), a checkpoint pedig a
lab/best.pt, amelyet a
cd lab && python n096_checkpoint.py futás ír. A
checkpoint kulcsai: model (a state_dict),
config (name=TinyCNN,
in_ch, num_classes, input_shape,
seed), epoch, val_loss,
val_acc, data_manifest,
parameter_count. Ha a checkpoint hiányzik, előbb a 24.4. VI. ellenőrző pont: megbízható CNN-training
labort kell lefuttatni. A Grad-CAM célrétege a features.3,
vagyis a TinyCNN második konvolúciója.
Input. data/images.npy float32, alak
(360,1,24,24); data/labels.npy int64;
data/metadata.csv split oszloppal; a checkpoint a fenti
szótár, a súlyok a model kulcs alatt. A kód CPU-n fut, seed
20261020, 30 ismétlés.
# lab/n138_sanity_check.py -- futtatás a lab/ könyvtárból, az n096 labor után:
# python n138_sanity_check.py --data data --checkpoint best.pt \
# --seed 20261020 --repeats 30 --max_images 20
import argparse, csv, json, math
from pathlib import Path
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from n096_checkpoint import TinyCNN # az n096 labor modellje és checkpointszerződése
def rank_average(v):
v = np.asarray(v, dtype=np.float64).ravel()
order = np.argsort(v, kind="mergesort")
ranks = np.empty_like(order, dtype=np.float64)
i, n = 0, v.size
while i < n:
j = i + 1
while j < n and v[order[j]] == v[order[i]]:
j += 1
ranks[order[i:j]] = (i + j - 1) / 2.0 + 1.0
i = j
return ranks
def spearman(a, b):
ra, rb = rank_average(a), rank_average(b)
if ra.std(ddof=0) == 0 or rb.std(ddof=0) == 0:
return float("nan")
return float(np.corrcoef(ra, rb)[0, 1])
def sobel_control(x_chw):
"""Sobel-gradiens nagysága egy (1,24,24) CHW képre; kimenet (24,24)."""
assert x_chw.ndim == 3 and x_chw.shape[0] == 1, x_chw.shape
x = x_chw[0]
kx = np.array([[-1., 0., 1.], [-2., 0., 2.], [-1., 0., 1.]])
ky = kx.T
pad = np.pad(x, 1, mode="reflect")
gx = np.zeros_like(x); gy = np.zeros_like(x)
for i in range(x.shape[0]):
for j in range(x.shape[1]):
gx[i, j] = (pad[i:i+3, j:j+3] * kx).sum()
gy[i, j] = (pad[i:i+3, j:j+3] * ky).sum()
mag = np.sqrt(gx**2 + gy**2)
return (mag - mag.min()) / (mag.max() - mag.min() + 1e-12)
def compute_gradcam(model, x, c, layer_name="features.3"):
model.eval(); model.zero_grad()
acts, grads = {}, {}
def fwd(m, i, o): acts[layer_name] = o
def bwd(m, gi, go): grads[layer_name] = go[0]
handles = []
for name, mod in model.named_modules():
if name == layer_name:
handles.append(mod.register_forward_hook(fwd))
handles.append(mod.register_full_backward_hook(bwd))
break
xx = x.clone().detach().requires_grad_(True)
logits = model(xx)
logits[0, c].backward()
A = acts[layer_name][0] # C x h x w
G = grads[layer_name][0] # C x h x w
alpha = G.mean(dim=(1, 2)) # C
L = torch.einsum("c,cuv->uv", alpha, A).relu()
L = (L - L.min()) / (L.max() - L.min() + 1e-12)
cam = F.interpolate(L[None, None], size=x.shape[-2:],
mode="bilinear", align_corners=False)[0, 0]
for h in handles: h.remove()
return cam.detach().cpu().numpy()
def randomize_parameters(model, seed, reset_bn_buffers=True):
"""Minden tanult paramétert a modul saját alapinicializálására állít vissza.
Conv/Linear: reset_parameters() (súly és fan-in alapú bias, pontosan a PyTorch
alapértelmezése szerint). BatchNorm: reset_parameters() a gamma/beta-t is
visszaállítja; a futó statisztikák (bufferek) visszaállítása külön döntés.
Visszaadja a randomizált paraméterek és bufferek nevét a naplóhoz."""
torch.manual_seed(seed)
touched = []
with torch.no_grad():
for name, mod in model.named_modules():
if isinstance(mod, (nn.Conv2d, nn.Linear)):
mod.reset_parameters()
touched += [f"{name}.{p}" for p, _ in mod.named_parameters(recurse=False)]
elif isinstance(mod, (nn.BatchNorm1d, nn.BatchNorm2d)):
running = (mod.running_mean.clone(), mod.running_var.clone())
mod.reset_parameters() # gamma=1, beta=0 és bufferek
touched += [f"{name}.weight", f"{name}.bias"]
if reset_bn_buffers:
touched += [f"{name}.running_mean", f"{name}.running_var"]
else: # bufferek megtartása, ha így döntünk
mod.running_mean.copy_(running[0]); mod.running_var.copy_(running[1])
return touched
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--data", type=Path, required=True)
ap.add_argument("--checkpoint", type=Path, required=True)
ap.add_argument("--seed", type=int, default=20261020)
ap.add_argument("--repeats", type=int, default=30)
ap.add_argument("--max_images", type=int, default=20)
args = ap.parse_args()
torch.manual_seed(args.seed); np.random.seed(args.seed)
device = torch.device("cpu")
images = np.load(args.data / "images.npy")
labels = np.load(args.data / "labels.npy")
with open(args.data / "metadata.csv", newline="", encoding="utf-8") as f:
idx = [int(r["index"]) for r in csv.DictReader(f) if r["split"] == "test"]
idx = idx[:args.max_images]
X = torch.from_numpy(images[idx]).float().to(device) # N,1,24,24
y = torch.from_numpy(labels[idx]).long()
base = TinyCNN()
state = torch.load(args.checkpoint, map_location="cpu", weights_only=True)
base.load_state_dict(state["model"] if isinstance(state, dict) and "model" in state else state)
base.to(device).eval()
base_cams = [compute_gradcam(base, X[i:i+1], int(y[i])) for i in range(len(X))]
controls = [sobel_control(images[idx[i]]) for i in range(len(X))] # (1,24,24) -> (24,24)
assert all(c.shape == (24, 24) for c in controls)
assert all(c.shape == (24, 24) for c in base_cams)
n_const = sum(1 for c in base_cams if c.std() == 0)
cont_rho = [spearman(base_cams[i], controls[i]) for i in range(len(X))]
rand_rhos, n_nan, n_all_nan = [], 0, 0
for rep in range(args.repeats):
m = TinyCNN(); m.load_state_dict(base.state_dict()); m.to(device).eval()
touched = randomize_parameters(m, args.seed + 1000 * rep)
if rep == 0:
print("randomizált:", ", ".join(touched))
assert set(touched) == {n for n, _ in m.named_parameters()} # minden tanult paraméter
vals = np.array([spearman(base_cams[i], compute_gradcam(m, X[i:i+1], int(y[i])))
for i in range(len(X))])
n_nan += int(np.isnan(vals).sum()) # konstans (pl. csupa nulla) randomizált térkép
if np.isnan(vals).all():
n_all_nan += 1 # az ismétlésnek nincs értelmezhető rho-ja
continue
rand_rhos.append(float(np.nanmean(vals)))
out = {
"seed": args.seed, "repeats": args.repeats, "n_images": len(X),
"control_sobel_rho_mean": float(np.nanmean(cont_rho)),
"randomized_rho_mean": float(np.nanmean(rand_rhos)),
"randomized_rho_median": float(np.nanmedian(rand_rhos)),
"randomized_rho_p05": float(np.nanpercentile(rand_rhos, 5)),
"randomized_rho_p95": float(np.nanpercentile(rand_rhos, 95)),
"excluded_constant_cams": n_const,
"randomized_constant_maps": n_nan,
"randomized_repeats_without_rho": n_all_nan,
"status": "completed",
}
print(json.dumps(out, indent=2, ensure_ascii=False))
if __name__ == "__main__":
main()Ellenőrzés és értelmezés. Először a
shape-ellenőrzést végezzük el: a Grad-CAM és a Sobel-kontroll egyaránt
(24,24) alakú. Másodszor a szóráskontrollt: ha egy
base_cams térkép szórása nulla, a megfelelő
-t
nan-ként kizárjuk, és a kizárások számát a jegyzőkönyvbe
írjuk. Az értelmezés két szám összevetése:
randomized_rho_mean és control_sobel_rho_mean.
Ha a randomizált modellek hasonlósága szignifikánsan alacsonyabb, mint a
Sobel-kontroll hasonlósága az eredeti magyarázathoz, és a randomizált
eloszlás 95%-os tartománya
alatt van, akkor a modellfüggetlenségi nullhipotézist elutasítjuk: a
magyarázat hordoz modellfüggő információt. Ha a randomizált
nem csökken a Sobel-kontroll szintje alá, a módszer ezen a kontrollon
nem mutat többet, mint egy modellmentes él-detektor. Futási
jegyzőkönyv. A 24.4. VI. ellenőrző pont:
megbízható CNN-training labor best.pt checkpointjával,
a fenti paranccsal, az eredeti GlyphLab-adaton (CPU, Python 3.12.3,
NumPy 2.3.5, PyTorch 2.14.1+cpu) két egymás utáni futás azonos eredményt
adott. A randomizált paraméterek naplója:
features.0.weight, features.0.bias,
features.3.weight, features.3.bias,
fc.weight, fc.bias, vagyis a modell minden
tanult paramétere (a TinyCNN-ben nincs BatchNorm).
Eredmények: control_sobel_rho_mean
,
randomized_rho_mean
(medián
,
5–95%-os tartomány
),
excluded_constant_cams
,
a 600 randomizált térképből 60 konstans (a ReLU utáni Grad-CAM csupa
nulla), és 1 ismétlésnek nincs értelmezhető
-ja.
Értelmezés: a randomizált modellek térképei az eredetivel gyengén
korrelálnak, és a 95%-os tartomány messze
alatt van, tehát a paraméter-randomizálási kontroll a magyarázat
modellfüggőségére utal. A Sobel-kontroll ezen az adaton nem élesebb
mérce: az eredeti Grad-CAM az él-térképpel is közel korrelálatlan
(),
a randomizált átlag pedig nem esik e szint alá; ebből a kontrollból
tehát nem következik, hogy a magyarázat „többet” mutat egy
él-detektornál, de az sem, hogy kevesebbet. A konstans randomizált
térképek aránya önmagában is jelentendő: a nan-ok kizárása
nélkül az átlag nem lenne számolható. Más könyvtárverzió vagy CPU
mellett az utolsó jegyek eltérhetnek; a saját futás JSON-ját kell
leadni.
F1 (fogalmi, nehézség 1). Definiálja a paraméter-randomizálást és a címkerandomizálást, és adja meg, melyik milyen függőséget tesztel. Miért nem helyettesíthető a két kontroll egymással? Átadandó: két-két mondat definíció és egy mondat indoklás.
F2 (levezetési, nehézség 2). A fenti kézi példa adataival vezesse le a Spearman- értékét az és térképekre, majd mutassa meg, hogy a térképre ugyanaz az érték adódik. Átadandó: a rangvektorok, a kovariancia és a két értéke.
F3 (implementációs, nehézség 2). Futtassa az
n138_sanity_check.py programot a saját checkpointtal,
seeddel 20261020, 30 ismétléssel. Ellenőrizze, hogy minden
Grad-CAM és Sobel-térkép alakja (24,24), és hogy a kizárt
konstans térképek száma nulla. Átadandó: a JSON-kimenet és az
ellenőrző shape-teszt utolsó sora.
F4 (hibakeresési, nehézség 2). Egy hallgató a
paraméter-randomizálásnál a Conv2d és Linear
rétegek súlyait újra inicializálja, de a BatchNorm2d
rétegek running_mean és running_var állapotát
változatlanul hagyja, majd model.eval() módban számít
Grad-CAM-et. Mi a hiba oka, mi a következménye a randomizált eloszlásra,
és mi a javítás? Átadandó: ok, következmény, javítás és egy
mini ellenőrzés.
F5 (kísérleti/transzfer, nehézség 3). Tervezze meg a címkerandomizálási kísérletet a GlyphLab-adaton: a tanító címkék permutációja, a train/val/test split érintetlenül hagyása, tanítási protokoll, baseline és kiértékelési metrika. Mi a fő érvényességi korlát? Átadandó: protokolltáblázat és a korlát indoklása.
F1. A paraméter-randomizálás a betanított modell rétegenkénti súlyait friss inicializálásra cseréli, és azt teszteli, hogy a magyarázat függ-e a tanult paraméterértékektől az inference során. A címkerandomizálás a tanító címkéket permutálja és újratanít, és azt teszteli, hogy a magyarázat a tanulási jel osztálytartalmától függ-e. A kettő nem cserélhető fel: egy módszer lehet érzékeny a betanított súlyokra, de lehet, hogy a súlyok a képstatisztikától, nem a címkéktől függenek; illetve a címkerandomizálás a tanítási folyamatot, nem az inference-kori paraméterfüggést vizsgálja.
F2. A rangvektorok a kézi példában: , . Átlaguk . A kovariancia , a szórásnégyzetek és , tehát . A térkép lapított vektora , rangjai szintén , mert a pozitív skalározással a rendezés nem változik, így . A szélsőeset-ellenőrzés: ha a két térkép konstans lenne, a nevezőben a szórás nulla lenne, és a nem definiált; ezért zárjuk ki a laborban a nulla szórást.
F3. A futtatás után a JSON-ben a
randomized_rho_mean és a
control_sobel_rho_mean összevetendő. Az elvárt
shape-ellenőrzés:
for i in range(len(idx)):
assert base_cams[i].shape == (24, 24)
assert sobel_control(images[idx[i]]).shape == (24, 24)Ha a randomizált 95%-os felső percentilise kisebb, mint a kontroll értéke, akkor a modellfüggőséget alátámasztja a kontroll; ha nem, a sanity check nem támogatja a magyarázat modellhez kötöttségét. A tolerancia itt nem lebegőpontos, hanem eloszlásalapú: a percentiliseket az ismétlésekből számítjuk, ezért a döntés a 30 ismétlés mintavételi bizonytalanságát is hordozza.
F4. Ok: a BatchNorm2d értékelő módban a
running_mean és running_var futó
statisztikákat használja, nem a minibatch statisztikát; a hallgató csak
a tanulható paramétereket randomizálta, a normalizálási állapot a régi
eloszlásra maradt kalibrálva. Következmény: a randomizált modell
továbbra is a betanított eloszlás skálázását alkalmazza, így a
magyarázat részben a régi modellhez hasonló marad, ami hamisan magas
értéket adhat. Javítás: a randomizáló függvénynek a BatchNorm rétegeken
reset_running_stats()-et kell hívnia, vagy a
running_mean-t nullára és a running_var-t
egyre kell állítania. Ellenőrzés: közvetlenül a
reset_running_stats() után, még újabb train
forward előtt a running_mean pontosan nulla és a
running_var pontosan egy. Mindkét puffer alakja
(C,); eval() módban a megfigyelések nem
módosítják őket.
F5. Protokoll: a train split 120 jelenetének osztálycímkéit rögzített, seedelt jelenetszintű permutációval keverjük, és a jelenet mindkét nézete ugyanazt a permutált címkét kapja; a val és test split érintetlen. A modellt ugyanazzal az architektúrával, optimizerrel, seeddel és epoch-számmal tanítjuk, mint a valódi címkés baseline-t. A metrika a Grad-CAM Spearman- a valódi és a véletlen címkés modell között a test-képeken, összevetve a Sobel-kontroll hasonlóságával. Fő korlát: az alacsony szintű képstatisztika véletlen címkék mellett is beépülhet a korai rétegekbe, ezért a nem várhatóan ; a kísérlet csak a tanult címkeinformációhoz kötött függést méri, nem a magyarázat abszolút hűségét. A scene-szintű függőség miatt a permutációt jelenetenként, a kiértékelést pedig a változatlan tesztjeleneteken végezzük; a páros nézeteket sem a permutációnál, sem a bizonytalanságbecslésnél nem tekintjük függetlennek.
Gyakori tévedés, hogy ha egy magyarázó módszer egy adathalmazon és architektúrán átmegy a sanity checken, akkor az minden magyarázatra és feladatra érvényes. Ez a következtetés érvénytelen. Ellenpélda: ugyanaz a Grad-CAM-implementáció a GlyphLab-CNN-en mutathat modellérzékenységet, míg egy pusztán lineáris pooling-fejjel képzett változaton a Spearman- randomizálás után is magas maradhat, mert a magyarázat ott gyakorlatilag a fix jellemzőtérkép skalározott másolata. A két eredmény közül egyik sem terjeszthető ki a másik architektúrára, és egyik sem mond semmit egy transzformer attention-térképéről. Az általánosítás csak új kontrollált kísérlettel igazolható.
Ellenőrizze, hogy a laborban a Grad-CAM célosztálya rögzített-e, a
randomizált modellek eval() módban futnak-e, és a konstans
térképeket a szóráskontroll kizárja-e. Ha a randomizált eloszlás 95%-os
tartománya tartalmazza az
-et,
akkor a modellfüggetlenség nullhipotézisét nem vethetjük el; ez nem a
módszer „jóságának” bizonyítéka, hanem a kontroll negatív eredménye.
Rövid visszahívás: a 31.2. GAN mint minimax probléma GAN-optimuma sem garantálta a véges tanítás konvergenciáját; itt a sanity check sem garantálja a magyarázat hűségét, csak egy cáfolható nullhipotézist tesztel. A 23.2. Kalibráció és döntési küszöb kalibrációs tanulsága szerint egy számszerű kimenet önmagában nem bizonytalansági garancia; itt egy hasonlósági érték önmagában nem hűséggarancia. A 34.2. Kvantálás és hibatovábbterjedés numerikus hibája pedig arra figyelmeztet, hogy a randomizálási kísérletben használt metrika megvalósításának saját numerikus hibája is ellenőrzést igényel.
A magyarázat sanity check azt a szükséges feltételt ellenőrzi, hogy a saliency- vagy Grad-CAM-térkép valóban a modelltől függjön. A paraméter-randomizálás a betanított súlyok, a címkerandomizálás a tanulási jel iránti érzékenységet teszteli. A kontroll logikai szerkezete kondicionális-negatív: a magas hasonlóság megőrzése modellfüggetlen módszernél elvileg determinisztikus lenne, ezért a randomizálás utáni erős csökkenés cáfolja a bemenetfüggetlen magyarázatot, de nem bizonyítja a hűséget. A Spearman- monoton transzformációkra érzéketlen, ezért a kontrollt fix metrika és modellmentes saliency control mellett, architektúránként külön kell jelenteni.
A 35.3. Perturbáció és adversarial példa egységben a perturbációs irányból vizsgáljuk ugyanezt a kérdést: az FGSM-alapú adversarial példa generálásának [D21] oktatóanyaga szerinti alapváltozatát a saját GlyphLab-modellre alkalmazzuk, és azt kérdezzük, hogyan változik a magyarázat, ha a bemenetet nem a súlyok, hanem egy kis, célzott perturbáció mentén módosítjuk. A most bevezetett hasonlósági metrikák és a randomizálási kontroll ott is a mérési protokoll részét képezik.