17.4 Architektúra összehasonlítása kontrollált keretben

17.4.1 1. Cél, előismeret és induló kérdés

A 17.3. VGG és kis kernelek kompozíciója egységben a 3×33\times3-as stack és az 5×55\times5-ös kernel recepciós mezőjét és paraméterszámát hasonlítottuk össze. Ott az volt a kérdés, hogy mit tud egy-egy rétegsorozat. Itt az következik, hogy mikor állíthatunk róluk valamit mért adatok alapján: két architektúra összehasonlítása csak akkor érdemi, ha a kísérleti keret izolálja az architektúra hatását a tréningrecept, az adat, a modellválasztási szabály és a véletlen hatásától. Előismeret: a 16.4. IV. ellenőrző pont: a CNN-operátor teljes megértése alfejezetben rögzített operátorspecifikáció, a 13.4. Határkezelés és frekvenciaintuíció alfejezetben tárgyalt padding, valamint az 5.4. Függő képek, seedek és resampling alfejezetből a seed-ismétlés és a megfigyelési egység fogalma. Induló kérdés: ha az A modellt három seeddel, húsz epochig, a B modellt tíz seeddel, ötven epochig tanítjuk, és B jobb lesz, mit tudunk az architektúráról?

17.4.2 2. Fair comparison, baseline és a kontrollváltozók

Definíció (fair comparison). Legyen DD rögzített adathalmaz, MM rögzített metrika, TT a vizsgált tényező (például az architektúra), VV pedig az összes többi ismert befolyásoló tényező együttese: adatfelosztás, preprocessing, loss, optimalizáló, learning rate, epoch- vagy early-stopping-szabály, batchméret, seed-készlet és a hiperparaméter-keresés protokollja. A T1T_1 és T2T_2 beállítás összevetése fair DD-n, ha (i) VV mindkét karra azonos szabály szerint rögzített; (ii) a modellválasztás a validációs halmazon, a végső MM kiértékelés pedig a teszt halmazon, a választás után történik; (iii) az erőforrás-költségek közül az egyezik, amelyet a kutatási kérdés kontrollálni akar. A baseline egy előre rögzített referencia-beállítás, amelyhez képest a változtatás hatását mérjük; baseline nélkül a „jobb” szó nem rendelhető méréshez.

A definíció szándékosan nem írja elő, hogy mindig minden költség egyezzen. Az, hogy mit kell egyeztetni, a kérdésből következik. Például ha a kérdés az, hogy adott paraméterköltség mellett a mélység vagy a kernelszélesség hasznos-e, akkor a paraméterszám egyezzen; ha az, hogy adott epochszám mellett melyik tanul gyorsabban, akkor a számítási keret egyezzen; ha az, hogy melyik recept a jobb, akkor az architektúra legyen közös, és a recept változzon.

17.4.3 3. Lemma: mely költségnek kell egyeznie?

Jelölje Y(A,R,D,S)Y(A,R,D,S) a mért teljesítményt, ahol AA az architektúra, RR a tréningrecept, DD az adat és SS a seed-ek halmaza. Az alábbi lemmában a kontrollkészletet a kutatási kérdésből vezetjük le.

Lemma (kontrollkészlet a kérdésből). Legyen DD és az SS-en vett átlagolási szabály rögzített. Ekkor:

  1. Ha a kérdés az AA hatása, akkor a Y(A1,R1)−Y(A2,R2)Y(A_1,R_1)-Y(A_2,R_2) különbség csak akkor tekinthető AA-hatásnak, ha R1=R2R_1=R_2, és a modellválasztási szabály is azonos.
  2. Ha a kérdés „azonos paraméterkeret mellett melyik struktúra jobb?”, akkor a Θ(A)\Theta(A) paraméterszámokra |Θ(A1)−Θ(A2)|/max(Θ(A1),Θ(A2))≤ε|\Theta(A_1)-\Theta(A_2)|/\max(\Theta(A_1),\Theta(A_2))\le\varepsilon szükséges előre rögzített ε\varepsilon mellett.
  3. Ha a kérdés „azonos képzési számítás mellett”, akkor az epochonkénti szorzás–összeadás műveletek (MAC) számának kell egyeznie; ha „azonos csúcsmemória mellett”, akkor a csúcs-aktivációmemóriának; ha „receptérzékenység”, akkor A1=A2A_1=A_2-nek kell teljesülnie.

Bizonyítás. Az (1) állítás egy azonosságból következik. Írjuk fel a mért különbséget:

Y(A1,R1)−Y(A2,R2)=[Y(A1,R1)−Y(A2,R1)]+[Y(A2,R1)−Y(A2,R2)].Y(A_1,R_1)-Y(A_2,R_2)=[Y(A_1,R_1)-Y(A_2,R_1)]+[Y(A_2,R_1)-Y(A_2,R_2)].

Az első tag a recept rögzítése melletti architektúra-különbség, a második a recept hatása rögzített A2A_2 mellett. Ha R1≠R2R_1\ne R_2, akkor a második tag általában nem nulla, tehát a teljes különbség nem azonosítható az első taggal. Mivel a két tag egyetlen mért különbségből nem szeparálható, a tisztán AA-ra vonatkozó következtetéshez R1=R2R_1=R_2 szükséges.

A (2)–(3) állításokhoz elég megmutatni, hogy eltérő költség mellett a sorrend megfordulhat. Legyen TT a vizsgált struktúratényező, Θ\Theta a paraméterkeret, és tegyük fel, hogy a várható teljesítmény Y(T,Θ)=TΘY(T,\Theta)=T\Theta alakú. Az (T1,Θ1)=(2,1)(T_1,\Theta_1)=(2,1) és (T2,Θ2)=(1,3)(T_2,\Theta_2)=(1,3) beállításokra Y1=2<3=Y2Y_1=2<3=Y_2, tehát a nyers összehasonlítás T2T_2-t hozná ki jobbnak. Rögzített Θ=1\Theta=1 mellett viszont T1>T2T_1>T_2. A Θ\Theta tehát konfundáló tényező; az izolált TT-hatáshoz a Θ\Theta-t kontrollálni kell. Ugyanez az érvelés szó szerint átvihető a MAC- vagy memóriakeretre. ▫\square

A lemma azt mondja ki, hogy melyik költségnek kell egyeznie, nem azt, hogy bármely egyezés garantálja a helyes következtetést. Az egyezés szükséges feltétel; a véletlen bizonytalanságot emellett seed-ismétléssel kell becsülni.

17.4.4 4. Kézi példa: MiniDeep3 és MiniWide5 paraméterkerete

A laborhoz két kis adaptációt definiálunk a GlyphLab 24×2424\times24-es, egycsatornás képeire. Ezek nem az eredeti LeNet, AlexNet vagy VGG másolatai, hanem a 17.3. VGG és kis kernelek kompozíciója alfejezetben vizsgált 3×33\times3-stack kontra 5×55\times5-kernel elv dokumentált mini-adaptációi.

MiniDeep3. A features blokk: Conv(1,8,3,pad=1), ReLU, Conv(8,8,3,pad=1), ReLU, MaxPool(2); Conv(8,16,3,pad=1), ReLU, Conv(16,16,3,pad=1), ReLU, MaxPool(2). A fej: AdaptiveAvgPool2d(1), Flatten, Linear(16,3). A bias-tagokkal együtt a paraméterszám:

ΘD3=(1⋅8⋅9+8)+(8⋅8⋅9+8)+(8⋅16⋅9+16)+(16⋅16⋅9+16)+(16⋅3+3)=80+584+1168+2320+51=4203.\Theta_{\mathrm{D3}}=(1\cdot 8\cdot 9+8)+(8\cdot 8\cdot 9+8)+(8\cdot 16\cdot 9+16)+(16\cdot 16\cdot 9+16)+(16\cdot 3+3)=80+584+1168+2320+51=4203.

MiniWide5. Conv(1,10,5,pad=2), ReLU, MaxPool(2); Conv(10,16,5,pad=2), ReLU, MaxPool(2); ugyanaz a fej. A paraméterszám:

ΘW5=(1⋅10⋅25+10)+(10⋅16⋅25+16)+(16⋅3+3)=260+4016+51=4327.\Theta_{\mathrm{W5}}=(1\cdot 10\cdot 25+10)+(10\cdot 16\cdot 25+16)+(16\cdot 3+3)=260+4016+51=4327.

A relatív eltérés 124/4327≈2,9%124/4327\approx 2{,}9\%, tehát a két modell az ε=0,05\varepsilon=0{,}05 paraméterkeret-tűrésen belül van. A MAC-ok ezzel szemben eltérnek: a MiniDeep3 négy konvolúciója 8⋅1⋅9⋅242+8⋅8⋅9⋅242+16⋅8⋅9⋅122+16⋅16⋅9⋅122=8709128\cdot1\cdot9\cdot24^2+8\cdot8\cdot9\cdot24^2+16\cdot8\cdot9\cdot12^2+16\cdot16\cdot9\cdot12^2=870\ 912 MAC, a MiniWide5 két konvolúciója 10⋅1⋅25⋅242+16⋅10⋅25⋅122=72000010\cdot1\cdot25\cdot24^2+16\cdot10\cdot25\cdot12^2=720\ 000 MAC. Ezért az alábbi labor kutatási kérdése paraméterkeretre vonatkozik, és a MAC-eltérést dokumentált másodlagos tényezőként, nem kontrollálatlan zavaróként kezeljük.

17.4.5 5. Labor: kontrollált kétmodelles összevetés GlyphLabon

Protokoll. Kérdés: a GlyphLab orientáció-feladatán, közel azonos paraméterszám mellett, a 3×33\times3-as mély stack vagy az 5×55\times5-ös széles, sekély változat ér el jobb általánosítást? Hipotézis: a mély stack a 17.3. VGG és kis kernelek kompozíciója alfejezetben tárgyalt nemlinearitás-többlet miatt nem rosszabb; ez azonban nem előre garantált győzelem. Adat: data/images.npy, data/labels.npy, data/metadata.csv, data/corrupted_test.npy; a split a metadata split oszlopából. Megfigyelési egység: scene_id; a split jelenetszintű, tehát egy jelenet két nézete nem kerül különböző splitbe. Változó tényező: architektúra (MiniDeep3 vagy MiniWide5). Rögzített tényezők: AdamW lr 10−310^{-3}, weight decay 10−410^{-4}, batch 32, legfeljebb 20 epoch, early stopping 5 türelmi epochhal a validációs lossra, loss CrossEntropyLoss logitsból, CPU float32, seed-készlet {0,1,2}\{0,1,2\} mindkét modellre. Modellválasztás: a három seed átlagos validációs lossza alapján választjuk ki a győztest; a tesztet csak ezután, mindkét modellre kiértékeljük, de a fő következtetést a győztesre fogalmazzuk. A corrupt teszt páros a clean testtel: ugyanaz a 60 jelenet/nézet sorrend, ezért a két accuracy különbsége páros összehasonlítás.

Szkript. Munkakönyvtár: lab/n068/. A kód a GlyphLab fájljait a ../data/ alól olvassa. Ez a kód a hallgató által futtatandó laborterv; a kézirat megírásakor nem lett futtatva, ezért az alatta álló JSON-séma nem mért eredmény.

# lab/n068/train_compare.py
import json, argparse
import numpy as np
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset

def set_seed(seed):
    torch.manual_seed(seed); np.random.seed(seed)

class MiniDeep3(nn.Module):
    def __init__(self):
        super().__init__()
        self.features = nn.Sequential(
            nn.Conv2d(1,8,3,padding=1), nn.ReLU(),
            nn.Conv2d(8,8,3,padding=1), nn.ReLU(), nn.MaxPool2d(2),
            nn.Conv2d(8,16,3,padding=1), nn.ReLU(),
            nn.Conv2d(16,16,3,padding=1), nn.ReLU(), nn.MaxPool2d(2))
        self.head = nn.Sequential(nn.AdaptiveAvgPool2d(1), nn.Flatten(), nn.Linear(16,3))
    def forward(self, x):
        return self.head(self.features(x))

class MiniWide5(nn.Module):
    def __init__(self):
        super().__init__()
        self.features = nn.Sequential(
            nn.Conv2d(1,10,5,padding=2), nn.ReLU(), nn.MaxPool2d(2),
            nn.Conv2d(10,16,5,padding=2), nn.ReLU(), nn.MaxPool2d(2))
        self.head = nn.Sequential(nn.AdaptiveAvgPool2d(1), nn.Flatten(), nn.Linear(16,3))
    def forward(self, x):
        return self.head(self.features(x))

def param_count(model):
    return sum(p.numel() for p in model.parameters())

def evaluate(model, loader):
    model.eval()
    correct = total = 0
    with torch.no_grad():
        for x, y in loader:
            pred = model(x).argmax(dim=1)
            correct += (pred == y).sum().item(); total += y.numel()
    return correct / total

def fit(model, train_loader, val_loader, max_epochs=20, patience=5):
    opt = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=1e-4)
    loss_fn = nn.CrossEntropyLoss()
    best_loss, best_state, waited = float("inf"), None, 0
    for epoch in range(max_epochs):
        model.train()
        for x, y in train_loader:
            opt.zero_grad(); loss = loss_fn(model(x), y); loss.backward(); opt.step()
        model.eval(); val_loss = 0.0; count = 0
        with torch.no_grad():
            for x, y in val_loader:
                val_loss += loss_fn(model(x), y).item() * y.numel(); count += y.numel()
        val_loss /= count
        if val_loss < best_loss - 1e-6:
            best_loss, best_state, waited = val_loss, {k: v.clone() for k, v in model.state_dict().items()}, 0
        else:
            waited += 1
            if waited >= patience:
                break
    model.load_state_dict(best_state)
    return best_loss

def main(seeds, out_path):
    data_dir = "../data"
    X = np.load(f"{data_dir}/images.npy").astype(np.float32)
    y = np.load(f"{data_dir}/labels.npy").astype(np.int64)
    corrupt = np.load(f"{data_dir}/corrupted_test.npy").astype(np.float32)
    import pandas as pd
    meta = pd.read_csv(f"{data_dir}/metadata.csv")
    tr_idx = meta.index[meta.split == "train"].to_numpy()
    va_idx = meta.index[meta.split == "val"].to_numpy()
    te_idx = meta.index[meta.split == "test"].to_numpy()
    Xtr = torch.from_numpy(X[tr_idx]); ytr = torch.from_numpy(y[tr_idx])
    Xva = torch.from_numpy(X[va_idx]); yva = torch.from_numpy(y[va_idx])
    Xte = torch.from_numpy(X[te_idx]); yte = torch.from_numpy(y[te_idx])
    Xco = torch.from_numpy(corrupt)  # sorrend = metadata test sorrend
    results = {}
    for name, build in [("MiniDeep3", MiniDeep3), ("MiniWide5", MiniWide5)]:
        results[name] = {"params": param_count(build()), "val_loss": [],
                         "val_acc": [], "test_acc": [], "corrupt_acc": []}
        for seed in seeds:
            set_seed(seed)
            gen = torch.Generator().manual_seed(seed)
            train_dl = DataLoader(TensorDataset(Xtr, ytr), batch_size=32, shuffle=True, generator=gen)
            val_dl = DataLoader(TensorDataset(Xva, yva), batch_size=64)
            test_dl = DataLoader(TensorDataset(Xte, yte), batch_size=64)
            corrupt_dl = DataLoader(TensorDataset(Xco, yte), batch_size=64)
            model = build()
            val_loss = fit(model, train_dl, val_dl)
            results[name]["val_loss"].append(val_loss)
            results[name]["val_acc"].append(evaluate(model, val_dl))
            results[name]["test_acc"].append(evaluate(model, test_dl))
            results[name]["corrupt_acc"].append(evaluate(model, corrupt_dl))
    with open(out_path, "w", encoding="utf-8") as f:
        json.dump(results, f, indent=2, default=float)

if __name__ == "__main__":
    ap = argparse.ArgumentParser()
    ap.add_argument("--seeds", nargs="+", type=int, default=[0,1,2])
    ap.add_argument("--out", default="results_n068.json")
    args = ap.parse_args()
    main(args.seeds, args.out)

Futtatási parancs: python train_compare.py --seeds 0 1 2 --out results_n068.json.

Átadandó eredmény. A JSON mindkét modellre tartalmazza a paraméterszámot (számított érték: 4203 és 4327), továbbá seedenként a val_loss, val_acc, test_acc és corrupt_acc nyers listáit. A kiértékelés során a hallgató közli a három seed átlagát és terjedelmét, a győztes kiválasztását a validációs lossz alapján, valamint a corrupt-clean páros 6060-képes eltérését. A kézirat e szakasza nem állít mért számokat; a fenti JSON-séma a futtatás előtti szerződés.

17.4.6 6. Feladatok

1. (F1, fogalmi, nehézség 1). Definiálja a fair comparison fogalmát, és adjon konkrét példát arra, hogyan torzít a keresési költség eltérése. Átadandó: legfeljebb hatmondatos definíció, valamint egy olyan elképzelt eredmény, amelyben az egyik modellre tíz, a másikra száz konfigurációt kerestek.

2. (F2, levezetési, nehézség 2). Vezesse le a MiniWide5 MAC-számát a 24×2424\times24-es bemenetre, és határozza meg, hogy a paraméterkeret-egyezés mellett milyen másodlagos költség marad nyitva. Átadandó: lépésenkénti számítás shape-ekkel és a végső 720000720\ 000 érték.

3. (F3, implementációs, nehézség 2). Írjon olyan param_count_bias függvényt, amely egy nn.Module paramétereinek számát bias nélkül és bias-szal együtt adja vissza. Ellenőrizze a MiniDeep3-ra, hogy bias nélkül 41494149, bias-szal 42034203. Átadandó: futtatható kód és a két ellenőrző érték.

4. (F4, hibakeresési, nehézség 2). A labor egy változata a corrupt kiértékeléshez a test_dl-hez hasonlóan shuffle=True értéket állít be a corrupt DataLoaderre. Mi a hiba, mi a következménye, és mi a javítás ellenőrzése? Átadandó: a hiba pontos lokalizálása, a párosítás sérülésének magyarázata és a javított kódsor.

5. (F5, kísérleti/transzfer, nehézség 3). Tervezzen fair összevetést a GlyphLabon egy harmadik változat, a MiniDeep3-memory bevezetésére, amelynek csatornaszáma a középső blokkban 16-ról 24-re nő. Adja meg: kérdés, költségkontroll, baseline, seed- és választási szabály, valamint a következtetés érvényességi korlátja. Átadandó: protokollterv szövegesen, az 5.4. Függő képek, seedek és resampling alfejezetben tanult seed-adat elkülönítés alkalmazásával.

17.4.7 7. Megoldások és indoklás

1. megoldás. A fair comparison olyan összevetés, amelyben a vizsgált tényezőn kívül minden ismert befolyásoló tényezőt azonos szabály rögzít, a modellválasztás validációs halmazon történik, a tesztet pedig a választás után használjuk. A keresési költség eltérésére példa: az A modellhez egyetlen lr-t próbálunk, a B modellhez tíz lr-jelöltet, és a legjobbat jelentjük. Ha B nyer, nem tudjuk, hogy az architektúra vagy a nagyobb keresési költség miatt; a teszt többszöri használata ráadásul a kiválasztott konfigurációt optimistán torzítja. A korrekt keret mindkét modellre azonos keresési rácsot és azonos választási szabályt ír elő.

2. megoldás. Az első konvolúció bemenete N×1×24×24N\times1\times24\times24, kimenete N×10×24×24N\times10\times24\times24 a padding=2 miatt. A MAC-ok száma kimeneti elemenként és csatornánként Cinkhkw=1⋅25C_{in}k_hk_w=1\cdot25. Összesen 10⋅1⋅25⋅24⋅24=14400010\cdot1\cdot25\cdot24\cdot24=144\ 000. A MaxPool után a második konvolúció bemenete N×10×12×12N\times10\times12\times12, kimenete N×16×12×12N\times16\times12\times12. A MAC-ok: 16⋅10⋅25⋅12⋅12=57600016\cdot10\cdot25\cdot12\cdot12=576\ 000. Összeg: 720000720\ 000. A lemmából következik, hogy mivel a kérdés paraméterkeretre vonatkozott, a MAC-különbség dokumentált másodlagos költség; ha a kérdés számítási keretre váltana, a MiniWide5 számítási fölénye önmagában is magyarázhatná az eltérést, ezért a csatornaszámot újra kellene hangolni.

3. megoldás. A függvény a p.dim() vizsgálatával választja szét a bias-t, mert a konvolúciós és lineáris réteg bias-e egydimenziós; általánosabb heurisztika a name és a p.ndim == 1 kombinációja.

def param_count_bias(model):
    total = bias = 0
    for name, p in model.named_parameters():
        total += p.numel()
        if name.endswith("bias"):
            bias += p.numel()
    return total - bias, bias

A MiniDeep3 esetében a bias-tagok: 8+8+16+16+3=518+8+16+16+3=51, így az összeg 42034203 és a bias nélküli rész 4203−51=41524203-51=4152. Az ellenőrző érték a feladat szövegében 41494149 volt? A kézi számítás szerint a négy konvolúció bias-e 8+8+16+16=488+8+16+16=48, a lineárisé 33, tehát bias nélkül 4203−51=41524203-51=4152. A feladat 4149 értéke tehát hibás; a helyes válasz 41524152, és a feladatkiírást ennek megfelelően kell javítani: a megoldás ellenőrzése assert param_count_bias(MiniDeep3())[0] == 4152 és [1] == 51. Ez a korrekció maga is tanulság: az ellenőrző számokat nem szabad levezetés nélkül átvenni.

4. megoldás. A hiba a corrupt DataLoader shuffle=True beállításában van. A corrupted_test.npy sorrendje a metadata test sorainak sorrendjét követi, és a hozzá tartozó yte ugyanebben a sorrendben van. A keverés a képeket és a címkéket ugyan együtt keveri, tehát az accuracy önmagában nem romlik el; a probléma a clean testtel való páros összehasonlításban van, mert a corrupt és clean eredmények képszintű különbsége nem ugyanazon sorrendhez tartozik, így a páros különbség szórása torzul. A javítás: DataLoader(TensorDataset(Xco, yte), batch_size=64) keverés nélkül, és a clean test DataLoadert is shuffle=False értékkel kiértékelni. Az ellenőrzés: egy rögzített batch első képének corrupt és clean változata ugyanahhoz a metadata indexhez tartozzon.

5. megoldás. A MiniDeep3-memory bevezetésekor a kérdés az, hogy a középső csatornaszám növelése javítja-e az általánosítást a paraméterkeret rögzítése mellett. A költségkontrollhoz előbb ki kell számítani az új paraméterszámot: a Conv(8,24,3) és Conv(24,24,3) blokk paraméterei 8⋅24⋅9+24+24⋅24⋅9+24=1752+5208=69608\cdot24\cdot9+24+24\cdot24\cdot9+24=1752+5208=6960, a korábbi középső blokk 1168+2320=34881168+2320=3488, tehát a növekmény 34723472; a paraméterkeret-egyezéshez csökkenteni kell például az első blokk csatornaszámát, vagy explicite a „paraméterkeret közel azonos” helyett a kérdést „adott memória-keretre” kell átfogalmazni. A baseline a MiniDeep3; a seed-ismétlés ugyanazt a {0,1,2}\{0,1,2\} készletet használja mindkét modellre, így a seed-hatás párosítható, míg a seed-készlet terjedelme az algoritmus bizonytalanságát, nem az adatminta bizonytalanságát becsli. A választás a három seed átlagos validációs lossza; a tesztet csak ezután értékeljük. Korlát: a GlyphLab eredmény nem általánosítható természetes képekre, és a jelenetszintű függés miatt képszintű konfidenciaintervallumot nem szabad jelenet-függetleníként értelmezni.

17.4.8 8. Gyakori tévedés és ellenpélda

A leggyakoribb hiba, hogy a mérési különbséget automatikusan az architektúrának tulajdonítjuk, noha közben a tréningrecept is változott. Ellenpélda: az A modellt lr 10−310^{-3}-mal, a B modellt lr 10−210^{-2}-mal tanítva A validációs pontossága 0,850{,}85, B-é 0,800{,}80. Ha ebből azt állítjuk, hogy A architektúrája jobb, az állítás nem következik az adatból. Egy további futtatás B-t lr 10−310^{-3}-mal tanítva 0,880{,}88-at adhat; a recept megváltoztatása megfordítja a sorrendet. A helyes keret vagy rögzíti az lr-t, vagy mindkét modellre ugyanazt a keresési protokollt futtatja, és a választott lr-t a validációs halmazon választja, a tesztet pedig a választás után használja. A kevés seed hasonlóan félrevezető: egyetlen seed két modellje közötti különbség lehet pusztán a tanítási zaj; az 5.4. Függő képek, seedek és resampling alfejezetben tárgyalt módon a seed-ismétlés az algoritmus bizonytalanságát becsli.

17.4.9 9. Önellenőrzés és visszahívás

Ellenőrző kérdések: (1) Kijelenthetem-e, hogy a labor győztese jobb architektúra, ha a paraméterszámok 4203 és 4327? Igen, ha a protokoll a paraméterkeretet rögzítette, de a MAC-eltérést jelenteni kell mint korlátot. (2) Használtam-e a tesztet a modellválasztás előtt? A szkript nem; a test_dl és corrupt_dl csak a fit után, a legjobb checkpoint betöltése után fut. (3) A corrupt–clean különbség páros? Igen, mert a corrupt sorrendje megegyezik a metadata test sorrenddel, és a DataLoaderek nem kevernek. Visszahívás a 13.4. Határkezelés és frekvenciaintuíció alfejezetből: a padding=2 az 5×55\times5-ös kernelnél, a padding=1 a 3×33\times3-asnál őrzi meg a térbeli méretet. A 16.4. IV. ellenőrző pont: a CNN-operátor teljes megértése alfejezetből: a Conv2d keresztkorrelációt számol, ezért a paraméterszámban a kernel elemszáma CinkhkwC_{in}k_hk_w, nem pedig egy megfordított kernel másik mennyisége.

17.4.10 Rövid összefoglaló

A fair comparison olyan kísérleti keret, amelyben a vizsgált tényezőn kívül minden ismert befolyásoló tényezőt rögzítünk, a modellt validációs halmazon választjuk, a tesztet pedig a választás után használjuk. A lemma szerint az egyeztetendő költséget a kutatási kérdés határozza meg: paraméterkerethez paraméterszám, számítási kerethez MAC, memóriakerethez aktivációcsúcs, receptérzékenységhez közös architektúra kell. A MiniDeep3 és MiniWide5 paraméterszáma 4203 és 4327, tehát közel azonos keretbe esik; a labor ugyanazt a receptet, seed-készletet és választási szabályt alkalmazza. Az eltérő keresési költség vagy kevés seed nem izolálja az architektúra hatását.

17.4.11 Következő alkalmazás

A 18.1. Reziduális blokk és identitásút a reziduális blokkot vezeti be. Az ottani y=F(x)+xy=F(x)+x rövidítéshez tartozó ablatív vizsgálathoz ugyanez a kontrollkeret szükséges: az identitásút elhagyása és megtartása között csak akkor mérhető a blokk hatása, ha a paraméterszám-, MAC- és seed-protokollt előre rögzítjük.

17.4.12 Felhasznált források