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?
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.
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:
, , , , esetén
A -es bemenetnél a hányados , de a képletben alsó egészrész szerepel, így ; 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 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 | – | – | |
| conv1 | 11×11, s4, p0 | 34 944 | |
| pool1 | 3×3, s2 | 0 | |
| conv2 | 5×5, s1, p2 | 614 656 | |
| pool2 | 3×3, s2 | 0 | |
| conv3–5 | lásd lent | 3×3, s1, p1 | lásd lent |
A conv3, conv4 és conv5 rendre , és kimeneti csatornával rendelkezik, mindegyik -as térbeli méreten marad. Paraméterszámuk:
Az utolsó pooling után
-os
térbeli méret marad, amit három teljesen összekötött réteg követ:
,
és
.
A paraméterszámok rendre
,
és
.
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
,
és
,
míg a conv3
()
é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
,
conv4
,
conv5
paraméter. A fenti táblázat groups=1 értékeivel a teljes
összeg
,
a csoportos kötéssel
;
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 , ahol a bemeneti csatornák száma, a kimeneti csatornák száma. A bias minden kimeneti csatornához egy skalár.
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:
elemenként értelmezve, azaz tensor bemenetre is elemenként alkalmazzuk. A telítődő függvények, például a vagy a szigmoid, a bemeneti tartomány szélein közelítőleg konstansok, így deriváltjuk nullához tart; a ReLU deriváltja -ra , -ra . A pontban a klasszikus derivált nem létezik; a könyvtárak egy konvenciót választanak, például -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.
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 egy réteg aktivációja, akkor
ahol a kiejtési arány, és a maszkok függetlenek. A várható érték , ezért a kiértékelés során a determinisztikus hálózatban vagy -vel skálázunk, vagy az úgynevezett inverted dropout esetén már a tanítás alatt -vel osztunk. A [P04] 4.2. szakasza (6. o.) szerint a dropoutot az első két teljesen összekötött rétegben alkalmazták kiejtési valószínűséggel, és a teszteléskor minden neuront használtak, de a kimenetüket -tel szorozták. Ez tehát a klasszikus, nem inverted konvenció: a skálázás a kiértékeléskor történik.
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 -es kivágásokat és azok vízszintes tükörképeit a -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.
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.
Legyen a logit mátrix, ahol a minták, az osztályok száma. A softmax soronként normalizál:
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:
ahol a legnagyobb elemének indexhalmaza. A top-k hiba .
Kézi példa. Legyen , és a logit vektor
A legnagyobb öt logit indexe sorrendben , , , , . Ha a valódi címke , akkor a minta top-3-ban helyes, top-2-ben hibás. A top-3 pontosság ezen az egy mintán , a top-2 pontosság . Ez mutatja, hogy a megváltoztatása önmagában más metrikát ad, még ugyanazon a modellen is.
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.
scene_id.Ez a terv nem elvégzett futás, hanem protokolljavaslat; a hallgató az F5 feladatban bővíti.
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: , kernel , 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 , , 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 -as példán, ahol a pontosság .
F5 (kísérlettervezési, nehézség 3). Tervezzen kis CPU-s kísérletet a GlyphLab adaton, amely a ReLU és a 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.
F1 megoldás. A top-k pontosság azon minták aránya, amelyeknél a valódi címke a legnagyobb 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 – helyezésű találatok hiányoznak.
F2 megoldás. A bemeneti térbeli méret , kernel , stride 1, padding 2, dilation 1. A kimeneti méret:
és ugyanígy . A súly alakja , mert a bemeneti csatornák száma 96. A súlyparaméterek száma , a bias további 256. Összesen . Alakellenőrzés: a kimeneti tensor alakja ; a paraméterszám független az 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.5A várt kimenet
.
Az első sorban a legnagyobb két index
,
tartalmazza a
-t;
a második sorban
,
nem tartalmazza a
-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
-mal:
ha
minta találat, akkor a jó pontosság
,
a hiba
;
a hibás kód
-et
ad, a javított
-at.
A javított függvény az F3 példán is
-öt
ad, mert
.
F5 megoldás. A kísérleti terv:
python lab/n066/train_ablation.py --act relu és
--act tanh.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.
Önellenőrzési kérdés: a rétegtábla első konvolúciós rétegének kimeneti mérete ; miért nem ? Mert a képletbe kerül, nem . Ha a -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 , stride 2 ablak a -ből -et ad, mert ; a fázisfüggőség itt is jelen van.
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 -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 indexen alapul, és a megváltoztatása más metrikát ad.
A 17.3. VGG és kis kernelek kompozíciója egység a VGG hálózatot tárgyalja: ott a kis -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.