A 22.2. Címkemegőrző transzformációk egység azt vizsgálta, mely transzformáció őrzi meg a GlyphLab orientációs címkéjét. Most ugyanannak a tanulási szerződésnek a másik oldalát vizsgáljuk: mi történik, ha nem a transzformáció, hanem maga a címke hibás. A címkezaj nem javítható egyszerűen nagyobb kapacitású modellel, és nagyon különbözik a bemeneti képen megjelenő zajtól. A 21.3. Dropout, súlyregularizálás és augmentáció regularizáló eszközei, a 18.3. Pre-activation, kis batch és alternatív normalizálás normalizáló rétegei és a 10.3. Gradiensellenőrzés és numerikus hibamérce numerikus ellenőrzési protokollja mind feltételezték, hogy a tanulási cél érvényes; ezt a feltételt most fellazítjuk. Az induló kérdés: ha egy tanító képsorozat címkéinek egy része véletlenül másik osztályra mutat, mennyire torzul a clean validációra mért osztályozó, és mit tehetünk a kísérleti jegyzőkönyvben?
Előismeret: a többosztályos logit/cross-entropy szerződés (7.2. Softmax és többosztályos cross-entropy), a scene-szintű split és a train/val/test elkülönítés (22.1. Adateredet, címke és csoportos split), valamint a feltételes valószínűség és a teljes valószínűség tétele (5.1. Esemény, feltétel és véletlen változó). A labor továbbra is a helyi GlyphLab-adatokat használja, előtanított súly és GPU nélkül.
Legyen a képtér, az osztályindexek halmaza. A tiszta megfigyelés az pár; a tanulási mintában azonban gyakran a zajos érték áll rendelkezésre. A képek továbbra is alakúak, a célok , a zajos cél .
Definíció (címkezaj, label noise). A mintában szereplő címke címkezajos, ha nem determinisztikus függvénye a tiszta párnak, és a hiba a céloldalon következik be: . A domináns feltevés szerint érintetlen, és feltételesen független -től a értékére szorítkozva. A feltételt rövidítve: . Ez a klasszifikációcímkék tipikus elírás-, félreolvasás- vagy gépi átírási modellje.
Definíció (kovariáns zaj, covariate noise). A mintában a bemenet torzul: figyelhető meg, a cél változatlan. A feltételes függetlenségi feltevés . Példa: a GlyphLab két nézete ugyanahhoz a scene-hez és címkéhez tartozik, de a két kép véletlen szenzor- vagy megvilágítási zajjal tér el; ez nem címkezaj, hanem bemeneti zaj. A kettő következménye alapvetően eltér: a kovariáns zaj a döntési felületet a bemeneti térben mossa el, a címkezaj a cél kódolását.
Gyenge felügyelet (weak supervision). Olyan tanulási beállítás, ahol a címkék nem egyenként, emberi szakértő által ellenőrzöttek, hanem szabályokból, heurisztikákból, távoli forrásból vagy programozott annotációból származnak. A gyenge címke felfogható szisztematikus, nem feltétlenül sztochasztikus címkezajként; hibatulajdonságai nem cserélhetők fel a szimmetrikus véletlen zajéval.
Annotátorok közötti egyetértés (annotation agreement). Két vagy több annotátor döntésének egyezési mértéke; bináris esetben például Cohen-féle kappa, több annotátorra Fleiss-féle kappa. Az egyetértés a címkeminőség folyamatmutatója, nem a tiszta címke bizonyítéka: két annotátor szisztematikusan ugyanazt a hibát is elkövetheti. A review lépés a vitás vagy alacsony megbízhatóságú rekordok célzott átvizsgálása és javítása a modellválasztás előtt. A review során tilos a val/test címkék megváltoztatása a modell kimenetének ismeretében, mert az adaptív célmanipuláció.
Leakage (szivárgás). Bármely olyan út, amely a train folyamatot a val/test cél vagy a val/test megfigyelési egység azonosítójának tiltott ismeretéhez juttatja. A címkezajos kísérletben leakage, ha a zajszimulációhoz a val/test címkéket használjuk fel, vagy ha a zajos tanítóhalmazt a validáció hibája alapján utólag újracímkézzük. A split határai a zajmodell bevezetése után is érvényesek.
A laborban a zajt szabályozottan, szimulációval visszük be. A modellt formálisan definiáljuk, majd egy lemmában kiszámítjuk az osztályprior torzulását.
Definíció (szimulált címkezaj-modell). Legyen adott a zajátmenet-mátrix, ahol A zajos példa generálása: és feltesszük, hogy független minden mástól a értékére feltételesen. Az párok alkotják a tanító mintát; a tiszta legfeljebb az értékelésben jelenik meg, a tanításkor nem.
A leggyakoribb szimuláció a szimmetrikus zaj: adott teljes flip-ráta mellett minden osztály azonos eséllyel hibásodik, és a hibás címke egyenletesen választódik a többi osztály közül:
Lemma (a megfigyelt osztályprior torzulása). Legyen a tiszta prior , és a zaj a fenti feltételes függetlenséget teljesítő átmenetmátrixszal adott. Ekkor a megfigyelt osztálygyakoriság eloszlása
Bizonyítás. A teljes valószínűség tételét alkalmazzuk a értékeire: Az első egyenlőség a partíció, a második a feltételes valószínűség szorzatszabálya, a harmadik a definíció behelyettesítése.
Következmény (szimmetrikus zaj). A szimmetrikus zajra Ebből . Egyenletes priorra ( minden -re) a szimmetrikus zaj nem torzítja a marginális osztálygyakoriságot; más priorra azonban a ritka osztályok felé húz.
Ez a lemma világosan mutatja a címkezaj és a kovariáns zaj formális különbségét. A kovariáns zaj generatív modellje: Itt a cél a torzított bemenet ellenére is az eredeti posteriorból származik; a zaj a élen hat. A címkezajnál a zaj a élen hat, és érintetlen. A két generatív gráf tehát különböző faktorizációt ad: , illetve . A fontos következmény: véges mintán a címkezajos tanítás még akkor sem közelíti a tiszta Bayes-osztályozót, ha a modellkapacitás és a mintaméret nő, mert a cél maga torzult; a kovariáns zaj esetén a tiszta döntési szabály a torzított bemenetre alkalmazva értelmezhető, bár általában nem optimális.
Legyen , prior , szimmetrikus zaj . A zajátmenet-mátrix: A lemma alapján: A három érték összege . A ritka harmadik osztály gyakorisága nőtt (), a gyakori első osztályé csökkent ().
Ellenőrzésül a zajgenerálás minimális kódja:
import numpy as np
def symmetric_label_noise(labels, K, eps, rng):
"""labels: (N,) int; minden címkét eps eséllyel egyenletesen
kicserél a többi K-1 osztály valamelyikére."""
noisy = labels.copy()
flips = rng.random(len(labels)) < eps
for i in np.where(flips)[0]:
others = [j for j in range(K) if j != labels[i]]
noisy[i] = rng.choice(others)
return noisy
rng = np.random.default_rng(7)
y = np.array([0, 1, 2, 0, 1, 2, 0, 1, 2, 0])
y_t = symmetric_label_noise(y, 3, 0.2, rng)
print("clean:", y)
print("noisy:", y_t)
print("flip rate:", np.mean(y != y_t))Egy konkrét seed mellett a kimenet változhat; a lényegi ellenőrzés az, hogy a tesztpéldában a várható flip-ráta körül ingadozik, és a zajos címkék mindig közé esnek. A kód nem a tanítás, hanem a zajmodell elemi referenciaimplementációja.
Kérdés. Hogyan változik a clean validációra mért loss és accuracy, ha a train címkék hányadát szimmetrikusan kicseréljük?
Protokoll. Csak a data/metadata.csv
szerinti train split indexeire alkalmazunk zajt. A valid és test tiszta
marad. Minden
esetén új tanítást indítunk, rögzített seeddel. A modell kisméretű CNN,
3 kimeneti logittal; tanítás Adam-optimizálóval, cross-entropy
loss-szal, 20 epochig. A kiválasztáshoz nem használjuk a testet; a clean
validációs accuracy-t és loss-t jegyezzük fel.
Az alábbi kód a lab/n087_label_noise_lab.py
munkakönyvtárban futtatható:
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
import torch.optim as optim
SEED = 20261020
DEVICE = torch.device("cpu")
torch.manual_seed(SEED)
rng = np.random.default_rng(SEED)
images = np.load("data/images.npy") # (360,1,24,24) float32
labels = np.load("data/labels.npy") # (360,) int64
meta = pd.read_csv("data/metadata.csv")
train_idx = meta[meta.split == "train"].index.to_numpy()
val_idx = meta[meta.split == "val"].index.to_numpy()
K = 3
def symmetric_label_noise(y, eps, rng):
noisy = y.copy()
flips = rng.random(len(y)) < eps
for i in np.where(flips)[0]:
others = np.setdiff1d(np.arange(K), y[i])
noisy[i] = rng.choice(others)
return noisy
class SmallCNN(nn.Module):
def __init__(self):
super().__init__()
self.net = nn.Sequential(
nn.Conv2d(1, 8, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(8, 16, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Flatten(), nn.Linear(16*6*6, 32), nn.ReLU(),
nn.Linear(32, K)
)
def forward(self, x):
return self.net(x)
def run(eps):
y_train = symmetric_label_noise(labels[train_idx], eps, rng)
Xtr = torch.tensor(images[train_idx], dtype=torch.float32)
ytr = torch.tensor(y_train, dtype=torch.long)
Xva = torch.tensor(images[val_idx], dtype=torch.float32)
yva = torch.tensor(labels[val_idx], dtype=torch.long)
model = SmallCNN().to(DEVICE)
opt = optim.Adam(model.parameters(), lr=1e-3)
crit = nn.CrossEntropyLoss()
ds = torch.utils.data.TensorDataset(Xtr, ytr)
dl = torch.utils.data.DataLoader(ds, batch_size=32, shuffle=True)
for _ in range(20):
model.train()
for xb, yb in dl:
opt.zero_grad(); crit(model(xb), yb).backward(); opt.step()
model.eval()
with torch.no_grad():
val_loss = crit(model(Xva), yva).item()
val_acc = (model(Xva).argmax(1) == yva).float().mean().item()
return val_loss, val_acc
print("eps val_loss_clean val_acc_clean")
for eps in [0.0, 0.1, 0.2, 0.4]:
loss, acc = run(eps)
print(f"{eps:3.1f} {loss:9.4f} {acc:6.4f}")Futtatási parancs a lab könyvtárból:
python n087_label_noise_lab.py. A SmallCNN az
előző ellenőrzőpontokban használt kisméretű osztályozó adaptációja; a
torch.utils.data.TensorDataset használata a [D08]
dokumentáció szerinti, a futtatás környezeti PyTorch-verzióját a
jegyzőkönyvben ellenőrizni és rögzíteni kell. A seed, a dtype
(float32/int64) és a device rögzített. A
kimenetet itt nem mértük, ezért csak a modell alapján várt trendet
jelölhetjük:
eps val_loss_clean val_acc_clean
0.0 0.42 0.87 (jelölt szemléltetés)
0.1 0.65 0.79 (jelölt szemléltetés)
0.2 0.83 0.73 (jelölt szemléltetés)
0.4 1.05 0.58 (jelölt szemléltetés)
A számok nem futtatott mérés, csak a zajmodell alapján várható irány szemléltetése. A tényleges futásnál a pontos értéket seed-szórás is terheli; a clean validáció értelmezése feltételes, ismételt mintavételi konfidenciaintervallumot igényelne, ahogy az [S02] módszertani oldala is hangsúlyozza. Értelmezés: növekvő mellett a clean valid loss monoton nő, az accuracy csökken; a kis tartományban a zaj egy része implicit regularizációként is hathat, de ez nem garantált, és nem teszi a zajt tervezett eszközzé.
F1 fogalmi, nehézség 1. Hasonlítsa össze a címkezajt, a kovariáns zajt és a gyenge felügyeletet a generatív modell és a hibatípus szerint. Adj olyan GlyphLab-példát, ahol a két nézet különbsége kovariáns zaj, és olyan módosítást, amely címkezajt visz be anélkül, hogy a képet megváltoztatná. Elvárt átadandó eredmény: két formális szorzatfaktorizáció és egy-egy saját példa.
F2 levezetési, nehézség 2. Legyen , prior , szimmetrikus zaj . Számítsa ki a és feltételes valószínűségeket. Ellenőrizze, hogy az átmenetmátrix invertálható-e, és ebből visszanyerhető-e a tiszta prior a megfigyelt priorból. Elvárt eredmény: teljes levezetés, numerikus értékek, invertálhatósági indoklás, és annak megfogalmazása, miért nem állítja ez helyre a tiszta posteriort.
F3 implementációs, nehézség 2. Írjon függvényt
asymmetric_label_noise(labels, flip_pairs, probs, rng)
alakban, ahol flip_pairs explicit
párok listája, probs a megfelelő flip-valószínűség. A
függvény adja vissza a zajos címkéket és a tényleges flip-maszkot.
Tesztelje 1000 szintetikus címkén, hogy a flip-ráta a megadott
valószínűségek 0,02 abszolút tűrésén belül van. Elvárt eredmény: teljes
kód, teszt és tolerancia.
F4 hibakeresési, nehézség 2. Az alábbi kódrészlet a validációs címkéket is zajosítja, majd a kapott „clean accuracy”-t használja a legjobb epoch kiválasztásához. Azonosítsa a hibát, annak következményét a modellválasztásra, és adja meg a javított eljárást úgy, hogy a train zaj ráta , de a valid tiszta marad. Mutassa meg, milyen ellenőrzéssel bizonyítható, hogy a javítás valóban tiszta validációt mér. Elvárt eredmény: ok, következmény, javított kódrészlet, visszaellenőrzés.
F5 kísérleti/transzfer, nehézség 3. Tervezzen gyenge felügyeletű változatot a GlyphLab feladatra: az orientációt ne emberi címke, hanem képnyomaték-alapú heurisztika adja meg. Fogalmazzon meg protokollt, amely a clean train címkével tanított baseline-t hasonlítja a gyenge címkével tanított modellhez, scene-szintű bootstrap-tel az accuracy-különbségre. Milyen érvényességi korlát következik abból, hogy a gyenge címkék hibája várhatóan nem szimmetrikus? Elvárt eredmény: hipotézis, megfigyelési egység, baseline, metrika, érvényességi korlát.
F1 megoldás. A címkezaj generatív modellje
,
ahol a zaj a
élen hat, és
érintetlen. A kovariáns zaj modellje
,
ahol a zaj az
élen hat, és
érintetlen. A gyenge felügyelet determinisztikus vagy sztochasztikus
címkeképző szabályokból származó cél, amely formálisan a címkezaj egyik
speciális, gyakran szisztematikus esete; nem azonos a bemeneti
torzulással. GlyphLab-példa: a két nézet közötti pixelzaj kovariáns; ha
a data/labels.npy egy részét a szomszédos orientációra
írjuk át a képek módosítása nélkül, az címkezaj.
F2 megoldás. A 4. szakasz mátrixával , . A Bayes-szabály szerint A mátrix szimmetrikus és sajátértékei és kétszeres multiplicitással, azaz , tehát invertálható. Invertálásával visszaadja a tiszta priort, mert a marginalis eloszlásra . Ez azonban nem adja vissza a tiszta posteriort, mert a modell a zajos feltételes eloszlását tanulja, és a csak a marginális priorra alkalmazható; a posterior torzulását a és együttes inverziója kezelné, amihez ismert vagy becsült volta szükséges.
F3 megoldás.
def asymmetric_label_noise(labels, flip_pairs, probs, rng):
"""labels: (N,) int; flip_pairs: list of (from, to);
probs: azonos hosszú flip-valószínűségek."""
noisy = labels.copy()
mask = np.zeros(len(labels), dtype=bool)
for (src, dst), p in zip(flip_pairs, probs):
sel = (labels == src) & (rng.random(len(labels)) < p)
noisy[sel] = dst
mask[sel] = True
return noisy, mask
rng = np.random.default_rng(0)
y = rng.integers(0, 4, size=100000)
flip_pairs = [(0, 1), (2, 3)]
probs = [0.15, 0.25]
ny, mask = asymmetric_label_noise(y, flip_pairs, probs, rng)
# ellenőrzés
assert np.array_equal(mask, y != ny)
for (src, dst), p in zip(flip_pairs, probs):
rate = np.mean(mask[y == src])
assert abs(rate - p) < 0.01, (rate, p)
print("flip rates ok:", np.mean(mask))A teszt a megadott tűrésen belül ellenőrzi a valószínűséget; a
mask pontosan a megváltozott elemeket jelöli, így a
hibaarány mindig jól definiált.
F4 megoldás. Hiba: a validációs címkéket is
zajosítják (symmetric_label_noise(labels[val_idx], ...)),
ezért a kiválasztás nem a tiszta, hanem egy torzított validációs célra
optimalizál; a legjobb epoch kiválasztása a zajos validáció
zajmintázatához igazodik, és a jelentett „clean” accuracy valójában
zajos referencia. Következmény: a modellválasztás optimistán torzított,
és a záróteszt nem értelmezhető független mérésként. Javítás: a zajt
csak a train_idx indexekre alkalmazzuk,
val_idx és test_idx tiszta marad; a
validációhoz mindig labels[val_idx]-t használjuk.
Visszaellenőrzés:
-ra
a validációs loss pontosan megegyezik a zaj nélküli tanítás validációs
loss-ával, ha a seed és a modell azonos; továbbá a validációs címkék
np.unique-halmaza nem változik a zajparaméterrel.
F5 megoldás. Hipotézis: a gyenge, képnyomaték-alapú címkék rontják a clean validációs accuracy-t a clean annotációhoz képest, de a romlás mértéke függ attól, hogy a heurisztika mely osztályokat keveri. Megfigyelési egység: scene_id, mert a két nézet ugyanahhoz a jelenethez tartozik. Split: a meglévő train/val/test scene-szintű felosztás változatlan. Baseline: a clean train címkével tanított SmallCNN; a változó tényező a train célok forrása (clean vs. gyenge). Metrika: clean val accuracy, valamint a scene-szintű, osztályonkénti rétegzett bootstrapből számított 95%-os CI az accuracy-különbségre a [S02] feltételes, ismételt mintavételi értelmezése szerint. Érvényességi korlát: a gyenge címkék hibája valószínűleg aszimmetrikus, például a vertical és diagonal jellegű főtengelyek keverése gyakoribb, ezért a szimmetrikus zajra levezetett prior-képlet itt nem alkalmazható, és a kísérlet csak a GlyphLab adott heurisztikájára vonatkozik.
A leggyakoribb tévedés az, hogy a nagyobb háló „megtanulja figyelmen kívül hagyni” a rossz címkéket, ezért a címkezaj automatikusan eltűnik. Ez nem igaz: a cross-entropy cél éppen a zajos -t követi, és elegendő kapacitás mellett a háló a hibás címkéket is interpolálja. Ellenpélda számított 1D feladaton: legyen , , ha , különben ; a clean Bayes-accuracy 1. A train címkék 30%-át felforgatjuk. Egy -NN osztályozó kapacitása elegendő a train pontok tökéletes lejegyzéséhez: noisy train accuracy 1, clean train accuracy viszont várhatóan , és a clean test accuracy sem haladja meg tartósan ezt a szintet. A nagyobb kapacitású modell tehát pontosabban jegyzi meg a zajt, de nem állítja helyre a tiszta határt; a javulás csak akkor lehetséges, ha a zaj modelljét, tiszta mintát vagy erős regularizációt is beépítünk.
Önellenőrző kérdések: a zajátmenet-mátrix minden sora 1-re összegződik-e? A laborkódban a valid/test indexeket egyetlen zajfüggvény sem érinti? A lemmában a feltételes függetlenséget kimondtuk-e? A kovariáns zaj és címkezaj faktorizációja különbözik-e? Visszahívás: 21.3. Dropout, súlyregularizálás és augmentáció label smoothing-ja determinisztikusan keveri a célvektort, míg a címkezaj véletlenül, mintánként eltérően; a 18.3. Pre-activation, kis batch és alternatív normalizálás normalizáló rétegei az aktivációk skáláját kezelik, és nem korrigálják a cél hibáját; a 10.3. Gradiensellenőrzés és numerikus hibamérce numerikus ellenőrzés tanulsága szerint a zajszimulációt is seed-del és referenciaimplementációval kell reprodukálni.
A címkezaj a céloldali hiba: a zajos a átmenetmátrix szerint keletkezik, a bemenet érintetlen. A kovariáns zaj ezzel szemben az élen hat, a címke változatlan. A szimmetrikus zaj modelljében a megfigyelt prior az képlettel torzul; egyenletes priorra a marginális eloszlás változatlan. A labor a GlyphLab train részén szabályozott zajjal mutatja, hogy a clean validáció romlása növekvő -nel várható, de a tényleges mérés seed- és adatfüggő. A gyenge felügyelet, annotátor-egyezés és review az adatminőségi folyamat része, a leakage pedig a split tiszteletben tartásának követelménye.
A 22.4. Augmentációs kísérlet és domainváltozás egységben az augmentációs kísérletet és a domainváltást tárgyaljuk: ott a képi eloszlás megváltozását, nem a cél hibáját vizsgáljuk, és azt kérdezzük, hogyan lehet a GlyphLab-receptet más, még nem látott képi feltételre átvinni.