18.4 Reziduális blokk ablatív vizsgálata

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

A 18.1. Reziduális blokk és identitásút alfejezetben levezettük a reziduális blokk y=F(x)+xy=F(x)+x rövidítését, a 18.3. Pre-activation, kis batch és alternatív normalizálás alfejezetben pedig a normalizáló rétegek tengelyválasztását és a pre-aktivációs elrendezést. Ebben az egységben azt a kérdést tesszük mérhetővé, amelyet a képlet önmagában nem dönt el: vajon a skip kapcsolat ténylegesen mérhető taníthatósági előnyt ad-e egy kis, ellenőrzött feladaton, vagy csak az adott recept szerencséje? Az ehhez szükséges eszköz az ablatív vizsgálat.

Előismeret: a 17.4. Architektúra összehasonlítása kontrollált keretben alfejezetből a kontrollált összehasonlítás kerete, a 6.4. Momentum és adaptív optimizálók alfejezetből az AdamW frissítési szabálya, a 18.3. Pre-activation, kis batch és alternatív normalizálás alfejezetből a BatchNorm train/eval viselkedése és a blokkok sorrendje. Induló becslés: ha a plain háló minden rétege kicsiny Jacobi-normával továbbítja a hibát, a korai rétegek gradiense eltűnik; a reziduális út ezt a szorzást megkerüli. A kérdés az, hogy ez a lokális érvelés a tényleges tanítási görbén is látszik-e.

18.4.2 Ablatív vizsgálat, matched recipe és az izoláló kontroll

Definíció (abláció). Az ablatív vizsgálat (ablation study) olyan kísérlet, amelyben egy architektúra vagy tanítási recept egyetlen komponensét távolítjuk el vagy cseréljük ki, a többi döntést változatlanul hagyva, és a változatokat ugyanazon a protokollon mérjük össze.

Definíció (matched recipe). A matched recipe olyan kontroll, amelyben a vizsgált tényezőn kívül minden tanítási döntés azonos: ugyanaz az adat és split, súlyinicializálás, seed-készlet, optimizer és súlycsökkentés, tanulási ráta és ütemezés, batchméret, epochszám, checkpoint-választási szabály és végső tesztelési eljárás. A 17.4. Architektúra összehasonlítása kontrollált keretben ottani lemmájának közvetlen alkalmazásaként a költségkeretet a kutatási kérdéshez kell igazítani: mivel a shortcut paramétermentes összeadás, a paraméterkeret itt automatikusan egyezik; emellett a számítási keret (MAC) is közel azonos, mert az összeadás elhanyagolható a konvolúciók mellett.

A vizsgált faktor tehát egy bináris változó:

S∈{plain,residual}.S \in \{\mathrm{plain}, \mathrm{residual}\}.

A plain blokk

BP(x;W)=F(x;W),B_P(x;W)=F(x;W),

a reziduális blokk pedig

BR(x;W)=F(x;W)+x,B_R(x;W)=F(x;W)+x,

ahol x∈ℝC×H×Wx\in\mathbb R^{C\times H\times W} a blokk bemeneti aktivációja, WW a blokk konvolúciós és normalizációs paramétereit tartalmazza, és a feltételek biztosítják, hogy az összeadás definiált legyen. A GlyphLab-hálóban a térbeli méret és a csatornaszám blokkon belül állandó, ezért az identitás-shortcut közvetlenül használható; vetítő-shortcutra most nincs szükség.

A kísérleti egység a GlyphLab scene_id-ja: egy jelenet két nézete ugyanabba a splitbe kerül, a bootstrap és az aggregálás ezért scene-szintű (5.4. Függő képek, seedek és resampling). A splitet a szerződés rögzíti: 120/30/30 jelenet train/val/test, osztályonként kiegyenlítve.

18.4.3 Hipotézis és a gradiensnorma levezetése

A kísérlet előtt rögzítjük a cáfolható hipotéziseket:

A H1 egy lokális lineáris modellből vezethető le. Legyen a háló mélysége TT, a blokk kimenete hl=Bl(hl−1)h_l=B_l(h_{l-1}), a skalár veszteség LL gradiense pedig gl=∇hlLg_l=\nabla_{h_l}L, amelynek alakja megegyezik hlh_l alakjával. A láncszabály szerint

gl−1=JBl(hl−1)⊤gl,g_{l-1}=J_{B_l}(h_{l-1})^\top g_l,

ahol JBlJ_{B_l} a blokk Jacobi-mátrixa. A plain blokkra JBl=JFlJ_{B_l}=J_{F_l}. Olyan pontokban, ahol a ReLU-k aktív mintázata rögzített, a blokk lokálisan affin leképezés; a konvolúció linearitása (15.1. Súly- és biasgradiens) miatt a Jacobi-norma a súlyokból számítható, de ehhez most elég annyi, hogy létezik ρ∈[0,1)\rho\in[0,1) felső korlát minden rétegre.

Lemma (eltűnő gradiens a plain láncban, lokális lineáris közelítés). Ha minden l=1,…,Tl=1,\dots,T rétegre ∥JFl(hl−1)⊤∥2≤ρ<1\|J_{F_l}(h_{l-1})^\top\|_2\le\rho<1, akkor a plain hálóra

∥g0∥2≤ρT∥gT∥2.\|g_0\|_2\le\rho^T\|g_T\|_2.

Bizonyítás. Indukcióval: ∥gl−1∥2=∥JFl⊤gl∥2≤ρ∥gl∥2\|g_{l-1}\|_2=\|J_{F_l}^\top g_l\|_2\le\rho\|g_l\|_2, amit TT-szer alkalmazva kapjuk az állítást. ▫\square

A reziduális blokkra BR(h)=h+F(h;W)B_R(h)=h+F(h;W), ezért differenciálható pontban

JBR(h)=I+JF(h),J_{B_R}(h)=I+J_F(h),

tehát a backward lépés

gl−1=gl+JF(hl−1)⊤gl.g_{l-1}=g_l+J_F(h_{l-1})^\top g_l.

Az upstream gradiens glg_l tehát változatlanul megjelenik a kimenő gradiensben: az identitásút minden blokkban hozzáadja a head felől érkező hibát. A teljes szorzat

g0=(∏l=1T(I+Al⊤))gT,Al=JFl(hl−1),g_0=\left(\prod_{l=1}^{T}(I+A_l^\top)\right)g_T,\qquad A_l=J_{F_l}(h_{l-1}),

ahol a szorzat minden tagja tartalmazza az II összeadandót. Ha ∥Al⊤∥2≤ρ<1\|A_l^\top\|_2\le\rho<1, akkor ez a szorzat I+∑lAl⊤+O(ρ2)I+\sum_l A_l^\top+O(\rho^2) alakú; a head-gradiens nem kényszerül kizárólag kicsiny Jacobi-tényezőkön áthaladni. Ez azonban nem ad a reziduális normára erős alsó korlátot, mert a tagok elvben kiolthatják egymást. Az állítás státusza: lokális lineáris közelítésből levezetett heurisztikus mechanizmus, nem globális konvergencia- vagy optimalizálási tétel. A H1 mérési célja éppen az, hogy ezt a mechanizmust empirikusan ellenőrizze, nem pedig az, hogy általános tételként igazolja.

18.4.4 Számított kis példa

Legyen T=2T=2, skalár közelítésben Fl(h)=alhF_l(h)=a_l h differenciálható pontban, a1=a2=0.2a_1=a_2=0.2, és a head-gradiens g2=1g_2=1. A plain láncra

g0=a1a2g2=0.04,g_0=a_1a_2\,g_2=0.04,

a reziduálisra

g1=(1+a2)g2=1.2,g0=(1+a1)g1=1.44.g_1=(1+a_2)g_2=1.2,\qquad g_0=(1+a_1)g_1=1.44.

Ugyanazokkal a blokkparaméterekkel a korai réteg gradiense a reziduális esetben több mint harmincszorosa a plain értéknek. A példa a lemmát illusztrálja, de nem helyettesíti: valódi hálóban a ReLU-k aktív mintázata lépésenként változik, és a Jacobi-norma ρ<1\rho<1 feltételét nem ellenőriztük.

18.4.5 A labor: plain és reziduális háló azonos recepttel

A labor a GlyphLab háromosztályos orientációfeladatát használja (13.1. Kép mint diszkrét többcsatornás jel, 25.1. Teljes képosztályozó adatfolyam). A bemenet float32 NCHW X∈ℝN×1×24×24X\in\mathbb R^{N\times1\times24\times24}, a cél int64 y∈{0,1,2}Ny\in\{0,1,2\}^N; a modell logitsot ad, CrossEntropyLoss előtt nincs softmax ([D07]).

Protokoll (a futás előtt rögzítendő). Változó faktor: SS. Rögzített: GlyphLab split, seedek {0,1,2}\{0,1,2\}, AdamW lr=10−3\mathrm{lr}=10^{-3}, weight_decay=10−4\mathrm{weight\_decay}=10^{-4} (6.4. Momentum és adaptív optimizálók), batch 64, 40 epoch, best checkpoint = legkisebb val loss, a teszt csak a checkpoint kiválasztása után, a clean és corrupt párosítás szerint a 38.3. Végső teszt és páros korrupció alfejezethez hasonlóan. A BatchNorm train alatt batch-statisztikát, eval alatt futó buffert használ; a mérést model.eval() módban végezzük ([D12]).

Az architektúra: stem Conv(1→161\to16, k=3k=3, pad=1), öt blokk, head AdaptiveAvgPool2d(1) és Linear(16→316\to3). Minden blokk két Conv(16→1616\to16, k=3k=3, pad=1, bias=False) réteget, két BatchNorm2d(16) réteget és ReLU-kat tartalmaz; a reziduális változat a második BN után hozzáadja a bemenetet, majd ReLU következik (poszt-aktivációs blokk a 18.3. Pre-activation, kis batch és alternatív normalizálás jelölésével). A paraméterszám mindkét változatra:

Rész Számítás Paraméter
Stem Conv 1⋅16⋅9+161\cdot16\cdot9+16 160
Egy blokk 2⋅(16⋅16⋅9)+2⋅162\cdot(16\cdot16\cdot9)+2\cdot16 4640
Head Linear 16⋅3+316\cdot3+3 51
Öt blokkal összesen 160+5⋅4640+51160+5\cdot4640+51 23 411

A labor kódja a lab/ munkakönyvtárban:

# lab/n072_resablation.py
# Futtatás: python lab/n072_resablation.py --data data --epochs 40 --seeds 0 1 2
import argparse, json, pathlib
import numpy as np
import torch
import torch.nn as nn

def make_block(ch, residual):
    class Block(nn.Module):
        def __init__(self):
            super().__init__()
            self.conv1 = nn.Conv2d(ch, ch, 3, padding=1, bias=False)
            self.bn1 = nn.BatchNorm2d(ch)
            self.conv2 = nn.Conv2d(ch, ch, 3, padding=1, bias=False)
            self.bn2 = nn.BatchNorm2d(ch)
            self.residual = residual
        def forward(self, x):
            h = self.bn1(self.conv1(x)).relu()
            h = self.bn2(self.conv2(h))
            if self.residual:
                h = h + x
            return h.relu()
    return Block()

class Net(nn.Module):
    def __init__(self, blocks=5, ch=16, residual=True, num_classes=3):
        super().__init__()
        self.stem = nn.Conv2d(1, ch, 3, padding=1)
        self.blocks = nn.Sequential(*[make_block(ch, residual) for _ in range(blocks)])
        self.head = nn.Sequential(
            nn.AdaptiveAvgPool2d(1), nn.Flatten(), nn.Linear(ch, num_classes))
    def forward(self, x):
        return self.head(self.blocks(self.stem(x).relu()))

def grad_norm(modules):
    sq = 0.0
    for m in modules:
        for p in m.parameters():
            if p.grad is not None:
                sq += p.grad.detach().float().pow(2).sum().item()
    return float(np.sqrt(sq))

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--data", type=pathlib.Path, default="data")
    ap.add_argument("--epochs", type=int, default=40)
    ap.add_argument("--seeds", nargs="+", type=int, default=[0, 1, 2])
    ap.add_argument("--device", default="cpu")
    args = ap.parse_args()

    torch.manual_seed(20261020)  # adatbetöltés determinizmusa
    imgs = np.load(args.data / "images.npy").astype(np.float32)
    labels = np.load(args.data / "labels.npy").astype(np.int64)
    meta = np.genfromtxt(args.data / "metadata.csv", delimiter=",", dtype=None,
                         names=True, encoding="utf-8")
    split = meta["split"]
    X = torch.from_numpy(imgs)
    y = torch.from_numpy(labels)
    device = torch.device(args.device)
    loss_fn = nn.CrossEntropyLoss()
    report = {}

    for seed in args.seeds:
        torch.manual_seed(seed)
        train_idx = [i for i, s in enumerate(split) if s == "train"]
        val_idx = [i for i, s in enumerate(split) if s == "val"]
        # egyszerű batch-képzés görgetéssel, a labban saját DataLoader is használható
        history = []
        for residual in (False, True):
            model = Net(residual=residual).to(device)
            opt = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=1e-4)
            best_val = float("inf")
            for ep in range(args.epochs):
                model.train()
                order = torch.randperm(len(train_idx))
                for st in range(0, len(train_idx), 64):
                    idx = order[st:st+64]
                    xb, yb = X[train_idx[idx]].to(device), y[train_idx[idx]].to(device)
                    opt.zero_grad()
                    loss = loss_fn(model(xb), yb)
                    loss.backward()
                    if ep == 0 and st == 0:
                        g0 = grad_norm([model.stem, model.blocks[0]])
                        gL = grad_norm([model.blocks[-1], model.head])
                        history.append({"step": 0, "stem_first_block_norm": g0,
                                        "last_block_head_norm": gL})
                    opt.step()
                model.eval()
                with torch.no_grad():
                    xv, yv = X[val_idx].to(device), y[val_idx].to(device)
                    val_loss = loss_fn(model(xv), yv).item()
                if val_loss < best_val:
                    best_val = val_loss
            report[f"seed{seed}_{'residual' if residual else 'plain'}"] = {
                "best_val_loss": best_val, "first_step_norms": history}
    out = args.data.parent / "n072_report.json"
    out.write_text(json.dumps(report, indent=2))
    print(out)

if __name__ == "__main__":
    main()

A kód szándékosan minimális: a DataLoader bevezetése és a legjobb checkpoint tényleges mentése, valamint a tesztkiértékelés a 11.4. Egy teljes PyTorch tanítási iteráció és 12.2. Checkpoint és folytathatóság receptjét követi. A labor átadandó eredménye: a n072_report.json nyers epochonkénti és lépésenkénti adatai, valamint a tesztkiértékelés a kiválasztott checkpointokon. Az alábbi mezők szemléltető adatok, nem mérési jegyzőkönyv:

{"seed0_plain": {"best_val_loss": 0.41, "first_step_norms":
  [{"step": 0, "stem_first_block_norm": 0.017, "last_block_head_norm": 5.2}]},
 "seed0_residual": {"best_val_loss": 0.28, "first_step_norms":
  [{"step": 0, "stem_first_block_norm": 0.17, "last_block_head_norm": 5.1}]}}

A tényleges futást a tanulói környezetben kell elvégezni; az itt megadott számok nem tekinthetők mért eredménynek.

18.4.6 Értelmezés, negatív eredmény és érvényességi határ

Az értékelés három szinten történik. (1) A H1-et a stem_first_block_norm mezők arányával ellenőrizzük; a várakozás a szemléltetett irány, de a mérés lehet ellentétes is. (2) A H2-höz a seedek feletti best-val-loss eloszlást hasonlítjuk össze, nem a legjobb seedet válogatjuk. (3) A végső tesztkiértékelés után közöljük a clean teszt pontosságát és szükség esetén a corrupt páros különbséget.

A negatív eredmény kifejezetten megengedett: ha a GlyphLab feladat 24×24 pixelen öt blokkal is könnyű, a két változat val lossza nem különül el. Ez nem cáfolja a [P06] nagyléptékű eredményét, és nem igazolja, hogy a skip minden feladaton hasznos; mindössze annyit állít, hogy ezen az adaton, ezzel a recepttel a különbség nem kimutatható. A következtetés érvényességi köre ezért a protokollal együtt rögzített: GlyphLab, 360 kép, 23 411 paraméter, CPU, három seed.

18.4.7 Gyakori tévedés

A leggyakoribb hiba az, hogy a kis ablatív kísérlet eredményét az eredeti ResNet-publikáció reprodukciójaként vagy általános architektúraigazságként olvassuk. A [P06] olvasott 3.1–3.2 szakasza a y=F(x)+xy=F(x)+x blokkot definiálja; a cikk állításai azonban ImageNet/COCO léptékű, nagyságrendekkel nagyobb hálókra és adatokra vonatkoznak. Ellenpélda: ha a fenti laborban a plain háló véletlenül jobb val losszt ér el, az nem azt jelenti, hogy „a skip kapcsolat hibás”, hanem hogy a mérési környezetben a H2 nem igazolódott. A skála és az adat különbözősége miatt a két állítás nem ütközik.

18.4.8 Feladatok

F1 (fogalmi, nehézség 1). Magyarázza el, miért nem ablatív vizsgálat, ha a plain hálót lr=10−3\mathrm{lr}=10^{-3}-mal, a reziduálist pedig lr=10−2\mathrm{lr}=10^{-2}-szal tanítjuk, és közben azt állítjuk, hogy a skip gyorsította a tanulást. Adjon egy olyan ellenőrzést, amely ezt a hibát kizárja.

F2 (levezetési, nehézség 2). Számítsa ki a fenti labor hálójának paraméterszámát, és igazolja, hogy a plain és reziduális változat paraméterkerete egyezik. Ezután a skalár példában a1=a2=0.5a_1=a_2=0.5 mellett adja meg a plain és a reziduális g0g_0 értékét, és ellenőrizze a lemma exponenciális becslését.

F3 (implementációs, nehézség 2). Írjon egy norm_probe függvényt, amely egy Net modellen az első forward-backward lépés után visszaadja a stem, az első blokk, az utolsó blokk és a head gradiensnormáit. Az input alakja (2,1,24,24)(2,1,24,24) legyen, dtype float32, device CPU; a függvény a modell paraméterein iterál, és None gradiensre 00-t ad.

F4 (hibakeresési, nehézség 2). A laborváltozat korai verziója a --residual kapcsolót beolvasta, de a Net(residual=False) hívás helyett mindig Net(residual=True)-ot konstruált. Mi a hiba következménye a H2 kiértékelésére, és milyen naplóbejegyzéssel lehet ezt a hiba detektálása után visszamenőleg kimutatni?

F5 (kísérleti/transzfer, nehézség 3). Tervezzen depth-sweep kísérletet 3, 5 és 7 blokkal annak eldöntésére, hogy a skip előnye a mélységgel nő-e a GlyphLabon. Adja meg a nullhipotézist, a rögzített erőforráskeretet, a metrikát, a seed- és scene-szintű kiértékelést, valamint a következtetés legalább egy érvényességi korlátját.

18.4.9 Megoldások és indoklás

F1 megoldás. Az eltérő tanulási ráta két faktor együttes változtatása, ezért a mért különbséget nem lehet kizárólag a skipnek tulajdonítani. Az ellenőrzés: ugyanazt a seed-készletet és AdamW konfigurációt mindkét ágon futtatjuk, a kód pedig a manifestbe írja az lr, a residual és a modell-paraméterszám értékét; a manifestet a kiértékelés előtt összevetjük.

F2 megoldás. A stem: 1⋅16⋅9+16=1601\cdot16\cdot9+16=160. Egy blokkban a Conv bias=False, ezért 16⋅16⋅9=230416\cdot16\cdot9=2304 súlyonként, két konvolúció 46084608; a két BatchNorm2d γ,β\gamma,\beta párja 2⋅16=322\cdot16=32; összesen blokkonként 46404640. Öt blokk 2320023200, a head 16⋅3+3=5116\cdot3+3=51. Összesen 160+23200+51=23411160+23200+51=23411. A shortcut add-nak nincs paramétere, tehát a budget egyezik. A skalár példában plain: g0=0.52=0.25g_0=0.5^2=0.25; reziduális: g0=(1.5)2=2.25g_0=(1.5)^2=2.25. A lemma a plain esetre ρ=0.5\rho=0.5, ρ2=0.25\rho^2=0.25, az egyenlőség teljesül, mert a példa lineáris.

F3 megoldás.

def norm_probe(model, xb, yb):
    loss_fn = torch.nn.CrossEntropyLoss()
    model.train()
    opt = torch.optim.AdamW(model.parameters(), lr=1e-3)
    opt.zero_grad()
    loss_fn(model(xb), yb).backward()

    def norm(modules):
        s = 0.0
        for m in modules:
            for p in m.parameters():
                if p.grad is not None:
                    s += p.grad.detach().pow(2).sum().item()
        return s ** 0.5
    return {
        "stem": norm([model.stem]),
        "first_block": norm([model.blocks[0]]),
        "last_block": norm([model.blocks[-1]]),
        "head": norm([model.head]),
    }

x = torch.randn(2, 1, 24, 24, dtype=torch.float32, device=torch.device("cpu"))
y = torch.tensor([0, 1], dtype=torch.int64)
model = Net(residual=True)
print(norm_probe(model, x, y))

Alakellenőrzés: a bemenet NCHW (2,1,24,24)(2,1,24,24); a head logitja (2,3)(2,3), a CrossEntropyLoss int64 célt vár. A kimeneti gradiensek skalárok, így a visszaadott értékek mindig nemnegatív valós számok.

F4 megoldás. Ha mindkét ág reziduális, a H2 összehasonlítás triviálisan azonos eloszlást mér, és a plain-ként naplózott eredmény valójában a reziduális modellé. A naplójavítás: a konstrukciókor a config JSON-ba be kell írni a residual kapcsoló tényleges értékét, és minden futás elején kiírni a modell state_dict kulcsainak számát és a blokkok Block.residual attribútumait. Visszaellenőrzés: ha a konfiguráció residual=false, de a blokkok attribútuma True, a hiba egyértelműen kimutatható a regenerált manifestből.

F5 megoldás. Nullhipotézis: a skip nélküli és a skipes háló best-val-loss különbsége nem változik a blokkszám függvényében. Rögzített keret: C=16C=16 csatorna, AdamW lr=10−3\mathrm{lr}=10^{-3}, három seed, 40 epoch, batch 64; a paraméterszám a mélységgel nő, ezért a kérdéshez a mélységi keret a releváns, és a MAC-értéket blokkonként expliciten naplózni kell. Metrika: a seedekre átlagolt best-val-loss különbség és a clean test accuracy; a bizonytalanság scene-szintű bootstrap CI a val predikciókra. A tesztet csak a három mélység és a két skip-változat best checkpointjainak kiválasztása után értékeljük. Érvényességi korlát: a GlyphLab kis mérete miatt a 7 blokkos háló is csak 32 ezer paraméteres marad, így az eredmény nem vihető át mély ImageNet-osztályú hálókra.

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

A képletekben az indexhatárok ellenőrizve: l=1,…,Tl=1,\dots,T, gTg_T a head felől érkező gradiens. Az add a reziduális blokkban csak akkor definiált, ha a csatorna- és térbeli alak egyezik; a laborban a stride 1 és a pad 1 ezt biztosítja. A plain és reziduális paraméterszám levezetése a bias=False konvenciót követi; a BN paraméterei mindkét ágban azonosak. A gradiensnormák a paraméterek L2-normái, a reduction sum a paraméterek négyzetösszege felett; a loss átlagolása a batchre vonatkozik, a gradiensnorma mérése ebből a skálából származó torzítást hordozhat, ezért a labornak azonos batchméretet kell használnia. Visszahívás a 17.4. Architektúra összehasonlítása kontrollált keretben alfejezetből: az egyeztetendő keretet a kérdéshez választjuk; a 18.3. Pre-activation, kis batch és alternatív normalizálás alfejezetből: a pre-aktivációs blokk a shortcutra nem tesz normalizálást; a 6.4. Momentum és adaptív optimizálók alfejezetből: az AdamW súlycsökkentése decoupled, ezért az L2-tagot nem a lossba írjuk.

18.4.11 Rövid összefoglaló

Az ablatív vizsgálat egyetlen tényezőt változtat, a matched recipe minden más döntést rögzít: adat, split, seed, optimizer, ütemezés, checkpoint- és tesztszabály. A skip kapcsolat hatását a plain BP(x;W)=F(x;W)B_P(x;W)=F(x;W) és a reziduális BR(x;W)=F(x;W)+xB_R(x;W)=F(x;W)+x blokk azonos paraméterkeretű összehasonlításával izoláljuk. A backward levezetés szerint a plain lánc a Jacobi-normák szorzatával skáláz, a reziduális láncban az identitás az upstream gradienst változatlanul továbbítja. A labor ötblokkos GlyphLab-hálón méri a best-val-loss eloszlást és az első lépés gradiensnormáit; a mérési állítás érvényessége erre a kis környezetre korlátozódik, és a negatív eredmény is közölhető.

18.4.12 Következő alkalmazás

A 19.1. Depthwise separable és pointwise réteg a depthwise separable konvolúciót vezeti be: ott ismét ablációval választjuk szét a spatial és a pointwise rész hatását, és a most bevezetett matched-recipe naplózást használjuk a paraméter/MAC-keret igazolására.

18.4.13 Felhasznált források