17.2 AlexNet és a kísérleti kontextus

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

A 17.1. LeNet és a lokális megosztott reprezentáció egységben a LeNet-5 réteggráfját és a mai könyvtári változatok eltéréseit vizsgáltuk. Most az AlexNet következik: ez az a hálózat, amelynél a mély, nagy kapacitású CNN és a nagyméretű képi adat együttesen vált meghatározóvá. Előismeretként a 13.2. Konvolúció és cross-correlation konvolúciós jelölését, a 16.2. Pooling, downsampling és aliasing pooling definícióját és az 5.2. Várható érték, variancia és likelihood statisztikai gondolkodását idézzük vissza.

Induló kérdés: mit jelent pontosan az a gyakran idézett állítás, hogy az AlexNet „15,3%-os top-5 hibát ért el”, és miért nem lehet ezt a számot mai modellekkel közvetlenül összehasonlítani?

17.2.2 A P04 eredmény mint empirikus állítás

A [P04] tanulmányt a NeurIPS-proceedings PDF-jén ellenőriztük; az alábbi állítások helyét szakaszonként megadjuk. Az absztrakt szerint a szerzők egy mély konvolúciós hálózatot tanítottak az ImageNet ILSVRC-2012 verseny adatán, és a modell egy változata 15,3%-os top-5 teszthibát ért el, szemben a második legjobb nevezés 26,2%-ával. Az absztrakt emellett megadja a modell nagyságrendjét: körülbelül 60 millió tanulható paraméter, 650 000 neuron, öt konvolúciós réteg, amelyek egy részét max-pooling követi, valamint három teljesen összekötött réteg, végső 1000 kimenetes softmaxszal. A tanításhoz nem telítődő neuronokat és hatékony GPU-implementációt használtak; a túltanulás csökkentésére a teljesen összekötött rétegekben dropoutot alkalmaztak.

Ez az állítás típusa szerint empirikus állítás, nem matematikai tétel. Pontosan akkor értelmezhető, ha rögzítjük a feltételeket: adat, split, modellváltozat, betanítási eljárás és kiértékelési metrika. A 15,3% tehát az ILSVRC-2012 verseny adott tesztkészletén, a szerzők által beadott változatra vonatkozik. Nem azt jelenti, hogy bármely AlexNet-implementáció ma is 15,3%-ot érne el, és nem is azt, hogy a szám mai körülmények között reprodukálható eredmény lenne.

17.2.3 Az AlexNet rétegtáblája és bemeneti mérete

A történeti összefoglalók bemeneti mérete eltérhet: a 224-es és 227-es képméret mellett az első réteg térbeli mérete sem azonos. Az alábbi rétegtábla 227×227-es bemenetre, groups=1 kapcsolatokra készített didaktikai változat, nem az eredeti, két GPU közötti csoportos csatornakapcsolatok teljes rekonstrukciója. A konvolúció pontos kimeneti alakját ezért minden rétegnél a képletből számítjuk.

A 14.1. Stride, padding, dilation és outputméret alfejezetben ismertetett képlet szimmetrikus paddingre:

Hout=⌊H+2p−d(k−1)−1s⌋+1.H_{out}=\left\lfloor\frac{H+2p-d(k-1)-1}{s}\right\rfloor+1.

H=227H=227, p=0p=0, d=1d=1, k=11k=11, s=4s=4 esetén

Hout=⌊227−10−14⌋+1=⌊2164⌋+1=54+1=55.H_{out}=\left\lfloor\frac{227-10-1}{4}\right\rfloor+1 =\left\lfloor\frac{216}{4}\right\rfloor+1=54+1=55.

A 224224-es bemenetnél a hányados 213/4=53,25213/4=53{,}25, de a képletben alsó egészrész szerepel, így Hout=⌊53,25⌋+1=54H_{out}=\lfloor53{,}25\rfloor+1=54; a kimeneti méret tehát ebben az esetben is egész. A 227-es méret az 55×55-ös, a 224-es méret pedig az 54×54-es első jellemzőtérképet adja. A [P04] szövege 224×224×3224\times224\times3 bemenetet ír (3.5. szakasz, 4. o.), a 2. ábra viszont 55×55-ös első réteget mutat; a kettő padding nélkül nem fér össze, ezért a rekonstrukciók többsége 227-es bemenettel számol. A rétegtábla következetesen ezt a 227-es didaktikai változatot használja, és ezt az eltérést a forrás pontatlanságaként, nem a saját számítás hibájaként kezeljük.

Réteg Kimeneti alak (NCHW) Kernel/stride/pad Tanulható paraméter
input N×3×227×227N\times3\times227\times227 – –
conv1 N×96×55×55N\times96\times55\times55 11×11, s4, p0 34 944
pool1 N×96×27×27N\times96\times27\times27 3×3, s2 0
conv2 N×256×27×27N\times256\times27\times27 5×5, s1, p2 614 656
pool2 N×256×13×13N\times256\times13\times13 3×3, s2 0
conv3–5 lásd lent 3×3, s1, p1 lásd lent

A conv3, conv4 és conv5 rendre 384384, 384384 és 256256 kimeneti csatornával rendelkezik, mindegyik 13×1313\times13-as térbeli méreten marad. Paraméterszámuk:

Az utolsó pooling után 6×66\times6-os térbeli méret marad, amit három teljesen összekötött réteg követ: 9216→40969216\to4096, 4096→40964096\to4096 és 4096→10004096\to1000. A paraméterszámok rendre 3775283237\,752\,832, 1678131216\,781\,312 és 40970004\,097\,000. Az eredeti hálóban a conv2, conv4 és conv5 kernelei csak a saját GPU-juk térképeit látják: a [P04] 3.5. szakasza szerint a kernelméretek 5×5×485\times5\times48, 3×3×1923\times3\times192 és 3×3×1923\times3\times192, míg a conv3 (3×3×2563\times3\times256) és a teljesen összekötött rétegek minden előző térképhez kapcsolódnak. Ez groups=2 csoportos konvolúciónak felel meg: conv2 256⋅48⋅25+256=307456256\cdot48\cdot25+256=307\,456, conv4 384⋅192⋅9+384=663936384\cdot192\cdot9+384=663\,936, conv5 256⋅192⋅9+256=442624256\cdot192\cdot9+256=442\,624 paraméter. A fenti táblázat groups=1 értékeivel a teljes összeg 6237834462\,378\,344, a csoportos kötéssel 6096522460\,965\,224; ez utóbbi egyezik a cikk „60 million parameters” állításával (3.5. szakasz és összefoglaló).

A súlytenzor alakja minden konvolúciós rétegnél a JELOLESEK szerint K∈ℝCout×Cin×kh×kwK\in\mathbb R^{C_{out}\times C_{in}\times k_h\times k_w}, ahol CinC_{in} a bemeneti csatornák száma, CoutC_{out} a kimeneti csatornák száma. A bias minden kimeneti csatornához egy skalár.

17.2.4 ReLU: telítődés és tanítási sebesség

A [P04] „nem telítődő neuronokat” használ; a 3.1. szakasz szerint a konkrét aktiváció a ReLU, amelyet a 9.4. Aktivációk és gradiensáramlás egységben definiáltunk:

f(x)=max(0,x),f(x)=\max(0,x),

elemenként értelmezve, azaz tensor bemenetre is elemenként alkalmazzuk. A telítődő függvények, például a tanh\tanh vagy a szigmoid, a bemeneti tartomány szélein közelítőleg konstansok, így deriváltjuk nullához tart; a ReLU deriváltja x>0x>0-ra 11, x<0x<0-ra 00. A 00 pontban a klasszikus derivált nem létezik; a könyvtárak egy konvenciót választanak, például 00-t.

A nem telítődő tulajdonság heurisztikus előnye, hogy a pozitív tartományban a gradiens nem tűnik el. Ez nem globális konvergenciatétel, hanem empirikus megfigyelés: a [P04] 3.1. szakasza (3. o., 1. ábra) szerint egy négyrétegű konvolúciós háló a CIFAR-10-en ReLU-val hatszor gyorsabban érte el a 25%-os tanítási hibát, mint tanh-val. Ez egyetlen architektúrán és adatkészleten mért eredmény, nem általános törvény.

17.2.5 Dropout mint regularizáló zaj

A dropout a tanítás során minden előrecsatolt lépésben véletlenül nullázza a neuronok egy részét. Ha h∈ℝdh\in\mathbb R^d egy réteg aktivációja, akkor

h′i=mihi,mi∼Bernoulli(1−p),h'_i=m_i h_i,\qquad m_i\sim\mathrm{Bernoulli}(1-p),

ahol pp a kiejtési arány, és a mim_i maszkok függetlenek. A várható érték 𝔼[h′i]=(1−p)hi\mathbb E[h'_i]=(1-p)h_i, ezért a kiértékelés során a determinisztikus hálózatban vagy 1−p1-p-vel skálázunk, vagy az úgynevezett inverted dropout esetén már a tanítás alatt 11−p\frac{1}{1-p}-vel osztunk. A [P04] 4.2. szakasza (6. o.) szerint a dropoutot az első két teljesen összekötött rétegben alkalmazták p=0,5p=0{,}5 kiejtési valószínűséggel, és a teszteléskor minden neuront használtak, de a kimenetüket 0,50{,}5-tel szorozták. Ez tehát a klasszikus, nem inverted konvenció: a skálázás a kiértékeléskor történik.

17.2.6 Augmentation

Az adatkiegészítés olyan címkemegőrző transzformáció, amely a tanítóhalmazt bővíti. A [P04] 4.1. szakasza (5. o.) két formát ír le: véletlen 224×224224\times224-es kivágásokat és azok vízszintes tükörképeit a 256×256256\times256-os képekből (tesztkor az öt kivágás és tükörképeik átlagolt predikciójával), valamint az RGB-intenzitások megváltoztatását a tanítóhalmaz pixeleire számolt főkomponens-analízis (PCA) irányai mentén. Minden transzformációnál ellenőrizni kell, hogy az osztálycímke változatlan marad; ez a 22.2. Címkemegőrző transzformációk egységben részletesen visszatér majd. A GlyphLab adaton például a 90 fokos forgatás nem címkemegőrző, ahogy a kezdőlabor szerződése rögzíti.

17.2.7 GPU-kontextus

A [P04] kiemeli a hatékony GPU-implementációt. A korabeli gyakorlatban a hálózatot két GPU-ra osztották, és bizonyos rétegek csak a saját GPU-juk adatát látták, más rétegek pedig mindkét GPU kimenetét összekapcsolták. A [P04] 3.2. szakasza (3. o.) szerint a kernelek fele-fele az egyes GPU-kon van, és a GPU-k csak bizonyos rétegekben kommunikálnak: a 3. réteg kernelei a 2. réteg összes térképét látják, a 4. réteg kernelei viszont csak az azonos GPU-n lévő 3. rétegbeli térképeket; ugyanez érvényes az 5. rétegre. A mi laborunk kis CPU-s változatot használ, tehát a GPU-kontextust történeti körülményként kezeljük, nem reprodukciós követelményként.

17.2.8 Top-k metrika és kézi példa

Legyen Z∈ℝN×KZ\in\mathbb R^{N\times K} a logit mátrix, ahol NN a minták, KK az osztályok száma. A softmax soronként normalizál:

pn,i=exp(zn,i)∑j=1Kexp(zn,j).p_{n,i}=\frac{\exp(z_{n,i})}{\sum_{j=1}^K\exp(z_{n,j})}.

Mivel a softmax szigorúan monoton transzformáció, a legnagyobb valószínűségek indexsorrendje megegyezik a legnagyobb logitok sorrendjével; a top-k halmaz tehát számolható közvetlenül a logitokból is. A top-k pontosság:

topk_acc(Z,y)=1N∑n=1N𝟏{yn∈topk(pn)},\mathrm{topk\_acc}(Z,y)=\frac1N\sum_{n=1}^N \mathbf1\bigl\{y_n\in \mathrm{top}_k(p_n)\bigr\},

ahol topk(pn)\mathrm{top}_k(p_n) a pnp_n legnagyobb kk elemének indexhalmaza. A top-k hiba 1−topk_acc1-\mathrm{topk\_acc}.

Kézi példa. Legyen N=1N=1, K=10K=10 és a logit vektor

z=[0,1,2,0,−0,5,1,2,0,3,−1,0,0,8,0,05,1,5,−0,2].z=[0{,}1,\;2{,}0,\;{-0{,}5},\;1{,}2,\;0{,}3,\;{-1{,}0},\;0{,}8,\;0{,}05,\;1{,}5,\;{-0{,}2}].

A legnagyobb öt logit indexe sorrendben 11, 88, 33, 66, 44. Ha a valódi címke y=3y=3, akkor a minta top-3-ban helyes, top-2-ben hibás. A top-3 pontosság ezen az egy mintán 11, a top-2 pontosság 00. Ez mutatja, hogy a kk megváltoztatása önmagában más metrikát ad, még ugyanazon a modellen is.

17.2.9 Labor: rétegtábla-generáló és kísérleti terv

A labor célja, hogy a hallgató saját maga számolja ki a rétegtáblát. A következő szkriptben nincs véletlen szám, ezért seed nem szükséges; a számítás CPU-n, float32-ben is pontos, mert egész aritmetikát használ. A munkakönyvtár lab/n066/, a fájl alexnet_table.py.

import math

def conv_out(h, w, kh, kw, s, p):
    ho = math.floor((h + 2*p - kh) / s) + 1
    wo = math.floor((w + 2*p - kw) / s) + 1
    return ho, wo

def pool_out(h, w, k, s):
    ho = math.floor((h - k) / s) + 1
    wo = math.floor((w - k) / s) + 1
    return ho, wo

# Bemenet: 227x227x3, NCHW alakban csatorna elöl.
H, W = 227, 227
cin = 3

# conv1: 96 db 11x11 kernel, stride 4, padding 0
h, w = conv_out(H, W, 11, 11, 4, 0)
p1 = 96 * cin * 11 * 11 + 96
print(f"conv1: {96}x{h}x{w}, params={p1}")

# pool1: 3x3, stride 2
h, w = pool_out(h, w, 3, 2)
print(f"pool1: {96}x{h}x{w}")

# conv2: 256 db 5x5 kernel, stride 1, padding 2
h, w = conv_out(h, w, 5, 5, 1, 2)
p2 = 256 * 96 * 5 * 5 + 256
print(f"conv2: {256}x{h}x{w}, params={p2}")

# pool2: 3x3, stride 2
h, w = pool_out(h, w, 3, 2)
print(f"pool2: {256}x{h}x{w}")

# conv3, conv4, conv5: 3x3, stride 1, padding 1
for name, cout, cin_prev in [("conv3", 384, 256), ("conv4", 384, 384), ("conv5", 256, 384)]:
    h, w = conv_out(h, w, 3, 3, 1, 1)
    p = cout * cin_prev * 3 * 3 + cout
    print(f"{name}: {cout}x{h}x{w}, params={p}")

# pool3: 3x3, stride 2
h, w = pool_out(h, w, 3, 2)
print(f"pool3: {256}x{h}x{w}")

# FC rétegek
for name, cout, cin_prev in [("fc1", 4096, 256*h*w), ("fc2", 4096, 4096), ("fc3", 1000, 4096)]:
    p = cout * cin_prev + cout
    print(f"{name}: {cout}, params={p}")

A futtatási parancs: python lab/n066/alexnet_table.py. A fenti szövegben közölt táblázat a képletekből kézzel levezetett érték; a szkript lefuttatása a hallgató laborfeladata, és az értékeknek egyezniük kell a táblázattal.

A labor második része egy kis léptékű kísérleti terv egyetlen elem megváltoztatására. Kérdés: hogyan hat a dropout-arány a TinyAlexNet-Glyph validációs pontosságára? A terv az alábbi.

Ez a terv nem elvégzett futás, hanem protokolljavaslat; a hallgató az F5 feladatban bővíti.

17.2.10 Feladatok

F1 (fogalmi, nehézség 1). Definiálja a top-k pontosságot és a top-k hibát. Miért használta az ILSVRC-2012 verseny a top-5 hibát, és miben tér el a top-1 hibától? Adjon egy feltételt, amely mellett a kettő egybeesik.

F2 (levezetési, nehézség 2). A rétegtábla alapján vezesse le a conv2 réteg kimeneti térbeli méretét és paraméterszámát. Bemenet: 27×27×9627\times27\times96, kernel 5×55\times5, stride 1, padding 2, kimeneti csatorna 256. Ellenőrizze az NCHW alakokat.

F3 (implementációs, nehézség 2). Írjon NumPy-függvényt, amely adott logit mátrixból és int64 címkékből kiszámolja a top-k hibát. Tesztelje a Z=(1,20,32,50,11,80,9)Z=\begin{pmatrix}1{,}2&0{,}3&2{,}5\\0{,}1&1{,}8&0{,}9\end{pmatrix}, y=(2,0)y=(2,0), k=2k=2 bemeneten. Adja meg a várt kimenetet és a numerikus kontrollt.

F4 (hibakeresési, nehézség 2). Valaki a következő függvényt írta, de a visszatérési érték ellentmond a függvény nevének:

def topk_error_bad(logits, labels, k):
    p = np.exp(logits - logits.max(axis=1, keepdims=True))
    p /= p.sum(axis=1, keepdims=True)
    top = np.argsort(-p, axis=1)[:, :k]
    hit = np.any(top == labels[:, None], axis=1)
    return hit.mean()

Mi a hiba, mi a következménye egy összehasonlító kísérletben, és hogyan javítható? Ellenőrizze a javítást egy N=3N=3-as példán, ahol a pontosság 2/32/3.

F5 (kísérlettervezési, nehézség 3). Tervezzen kis CPU-s kísérletet a GlyphLab adaton, amely a ReLU és a tanh\tanh aktiváció hatását hasonlítja össze a TinyAlexNet-Glyph hálózatban. Adja meg a kérdést, a változó tényezőt, a rögzített beállításokat, a metrikát, a seedeket, a választási protokollt és a következtetési korlátot. A tervet ne futtassa le, de a futási parancsokat írja le.

17.2.11 Megoldások és indoklás

F1 megoldás. A top-k pontosság azon minták aránya, amelyeknél a valódi címke a legnagyobb kk predikált valószínűség indexei között szerepel; a top-k hiba ennek komplementere. Az ILSVRC-2012 verseny 1000 osztályt használt, amelyek között sok közeli kategória van, ezért a top-1 túl szigorú; a top-5 azt méri, hogy a modell a helyes osztályt legalább a legjobb öt javaslat között tartalmazza-e. A top-1 és top-5 hiba akkor esik egybe, ha minden mintára a valódi címke vagy mindig az első helyen van, vagy soha nincs az első ötben; tehát a köztes 22–55 helyezésű találatok hiányoznak.

F2 megoldás. A bemeneti térbeli méret 27×2727\times27, kernel 5×55\times5, stride 1, padding 2, dilation 1. A kimeneti méret:

Hout=⌊27+2⋅2−(5−1)−11⌋+1=⌊27+4−4−1⌋+1=27,H_{out}=\left\lfloor\frac{27+2\cdot2-(5-1)-1}{1}\right\rfloor+1 =\left\lfloor 27+4-4-1\right\rfloor+1=27,

és ugyanígy Wout=27W_{out}=27. A súly alakja 256×96×5×5256\times96\times5\times5, mert a bemeneti csatornák száma 96. A súlyparaméterek száma 256⋅96⋅25=614400256\cdot96\cdot25=614\,400, a bias további 256. Összesen 614656614\,656. Alakellenőrzés: a kimeneti tensor alakja N×256×27×27N\times256\times27\times27; a paraméterszám független az NN batchmérettől.

F3 megoldás. A függvény:

import numpy as np

def topk_error(logits, labels, k):
    # logits: (N, K) float32; labels: (N,) int64
    p = np.exp(logits - logits.max(axis=1, keepdims=True))
    p = p / p.sum(axis=1, keepdims=True)
    top = np.argsort(-p, axis=1)[:, :k]
    hit = np.any(top == labels[:, None], axis=1)
    return 1.0 - hit.mean()

Z = np.array([[1.2, 0.3, 2.5],
              [0.1, 1.8, 0.9]], dtype=np.float32)
y = np.array([2, 0], dtype=np.int64)
print(topk_error(Z, y, k=2))  # vart: 0.5

A várt kimenet 0,50{,}5. Az első sorban a legnagyobb két index [2,0][2,0], tartalmazza a 22-t; a második sorban [1,2][1,2], nem tartalmazza a 00-t. A softmax a max levonásával számolva numerikusan stabil; a -p negálás miatt az argsort csökkenő sorrendet ad. A float32 kerekítés itt nem változtatja a sorrendet, mert a logitok eltérése nagyobb, mint a gépi pontosság.

F4 megoldás. A hibás függvény hit.mean()-t ad vissza, ami a top-k pontosság, nem a hiba. Ha a hívó ezt hibaként ábrázolja, akkor a nagyobb értéket jobb modellnek értelmezi, ami éppen fordított következtetés. Javítás: a visszatérési érték legyen 1.0 - hit.mean(), vagy nevezzük át a függvényt topk_acc-nek. Ellenőrzés N=3N=3-mal: ha 22 minta találat, akkor a jó pontosság 2/3≈0,6672/3\approx0{,}667, a hiba 1/3≈0,3331/3\approx0{,}333; a hibás kód 0,6670{,}667-et ad, a javított 0,3330{,}333-at. A javított függvény az F3 példán is 0,50{,}5-öt ad, mert 1−0,5=0,51-0{,}5=0{,}5.

F5 megoldás. A kísérleti terv:

17.2.12 Gyakori tévedés és ellenpélda

A leggyakoribb tévedés a történeti top-5 számot mai modellek azonos körülményű összehasonlításának tekinteni. A 15,3% az ILSVRC-2012 tesztkészletére, a szerzők adott modellváltozatára és a verseny kiértékelési protokolljára vonatkozik. Ma sem az adat, sem a tesztkörnyezet, sem a modellimplementációk nem azonosak. Ellenpéldaként: ha valaki egy modern, előtanított modellt az ImageNet-2012 validációs készletének egy mai újraosztott részén értékel, akkor az eredmény nem vethető össze a P04 15,3%-ával pusztán azért, mert mindkettőt százalékban mérik. Az összehasonlítás csak akkor értelmes, ha a split, az előfeldolgozás, az értékelési metrika és a modellváltozat is azonos.

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

Önellenőrzési kérdés: a rétegtábla első konvolúciós rétegének kimeneti mérete 55×5555\times55; miért nem 54×5454\times54? Mert a képletbe H=227H=227 kerül, nem 224224. Ha a 224224-es bemenetet használnánk, akkor paddingre lenne szükség, vagy a bemeneti méretet kellene megváltoztatni. Visszahívás a 16.2. Pooling, downsampling és aliasing egységből: a pooling downsamplinget hajt végre, és a 3×33\times3, stride 2 ablak a 5555-ből 2727-et ad, mert ⌊(55−3)/2⌋+1=27\lfloor(55-3)/2\rfloor+1=27; a fázisfüggőség itt is jelen van.

17.2.14 Rövid összefoglaló

Az AlexNet a P04 tanulmányban bemutatott mély konvolúciós hálózat, amely az ILSVRC-2012 versenyen 15,3%-os top-5 teszthibát ért el. A szám empirikus állítás, nem matematikai tétel; az adathoz, a modellváltozathoz és a top-5 metrikához kötött. A hálózat öt konvolúciós és három teljesen összekötött rétegből áll; a rétegtábla levezetése a 227×227227\times227-es bemenettel konzisztens. A ReLU, a dropout, az augmentation és a GPU-implementáció a tanítás gyorsaságát és a túltanulás csökkentését szolgálta. A top-k pontosság definíciója a softmax utáni legnagyobb kk indexen alapul, és a kk megváltoztatása más metrikát ad.

17.2.15 Következő alkalmazás

A 17.3. VGG és kis kernelek kompozíciója egység a VGG hálózatot tárgyalja: ott a kis 3×33\times3-as kernelek kompozíciója váltja fel a nagy kerneleket, és a mélység növelése a paraméterszám tudatosabb szabályozásával társul.

17.2.16 Felhasznált források