Plast Batch Normalization Kerasa je pokvarjena PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Plast Normalizacije serije se razbije

POSODOBITEV: Na žalost moja zahteva za vlečenje za Keras, ki je spremenila vedenje sloja za normalizacijo serije, ni bila sprejeta. Podrobnosti si lahko preberete tukaj. Za tiste med vami, ki ste dovolj pogumni, da se ukvarjate z implementacijami po meri, lahko najdete kodo v moja podružnica. Morda ga bom vzdrževal in združil z najnovejšo stabilno različico Kerasa (2.1.6, 2.2.2 in 2.2.4), dokler ga uporabljam, vendar brez obljub.

Večina ljudi, ki delajo na področju poglobljenega učenja, ga je uporabljala ali slišala zanj Keras. Za tiste, ki še niste, je to odlična knjižnica, ki abstrahira temeljna ogrodja globokega učenja, kot so TensorFlow, Theano in CNTK, in zagotavlja API na visoki ravni za usposabljanje ANN. Je enostaven za uporabo, omogoča hitro izdelavo prototipov in ima prijazno aktivno skupnost. Že nekaj časa ga intenzivno uporabljam in občasno prispevam k projektu in ga vsekakor priporočam vsem, ki želijo delati na področju globokega učenja.

Čeprav mi je Keras olajšal življenje, me je precejkrat ugriznilo nenavadno vedenje sloja Batch Normalization. Njegovo privzeto vedenje se je sčasoma spremenilo, kljub temu pa še vedno povzroča težave mnogim uporabnikom in posledično obstaja več povezanih odprta vprašanja na Githubu. V tej objavi v spletnem dnevniku bom poskušal utemeljiti, zakaj Kerasov sloj BatchNormalization ne deluje dobro s Transfer Learning, zagotovil bom kodo, ki odpravlja težavo, in podal primere z rezultati obliž.

V spodnjih pododdelkih ponujam uvod o tem, kako se Transfer Learning uporablja pri poglobljenem učenju, kaj je plast paketne normalizacije, kako deluje learnining_phase in kako je Keras sčasoma spremenil vedenje BN. Če jih že poznate, lahko varno skočite neposredno na 2. razdelek.

1.1 Uporaba prenosnega učenja je ključnega pomena za poglobljeno učenje

Eden od razlogov, zakaj je bilo globoko učenje v preteklosti kritizirano, je, da zahteva preveč podatkov. To ni vedno res; obstaja več tehnik za reševanje te omejitve, ena od njih je Transfer Learning.

Predpostavimo, da delate na aplikaciji Computer Vision in želite zgraditi klasifikator, ki razlikuje mačke od psov. Za treniranje modela pravzaprav ne potrebujete milijonov slik mačk/psov. Namesto tega lahko uporabite vnaprej usposobljen klasifikator in natančno prilagodite zgornje konvolucije z manj podatkov. Ideja v ozadju je, da ker je bil predhodno usposobljen model prilagojen slikam, lahko spodnje konvolucije prepoznajo funkcije, kot so črte, robovi in ​​drugi uporabni vzorci, kar pomeni, da lahko njegove uteži uporabite kot dobre inicializacijske vrednosti ali delno znova usposobite omrežje s svojimi podatki .
Plast Batch Normalization Kerasa je pokvarjena PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.
Keras je opremljen z več vnaprej pripravljenimi modeli in preprostimi primeri za natančno nastavitev modelov. Več lahko preberete na Dokumentacija.

1.2 Kaj je plast paketne normalizacije?

Sloj normalizacije serije sta leta 2014 uvedla Ioffe in Szegedy. Rešuje problem izginjajočega gradienta s standardizacijo izhoda prejšnje plasti, pospešuje usposabljanje z zmanjšanjem števila zahtevanih iteracij in omogoča usposabljanje globljih nevronskih mrež. Točna razlaga, kako deluje, presega obseg te objave, vendar vas močno spodbujam, da preberete izvirni papir. Preveč poenostavljena razlaga je, da vnos spremeni lestvico tako, da odšteje njegovo povprečje in deli s standardnim odklonom; po potrebi se lahko tudi nauči razveljaviti transformacijo.
Plast Batch Normalization Kerasa je pokvarjena PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

1.3 Kaj je učna_faza v Kerasu?

Nekatere plasti delujejo drugače med načinom usposabljanja in sklepanja. Najpomembnejša primera sta sloja Batch Normalization in Dropout. V primeru BN med usposabljanjem uporabimo povprečje in varianco mini šarže za prerazporeditev vnosa. Po drugi strani pa med sklepanjem uporabljamo drseče povprečje in varianco, ki sta bili ocenjeni med treningom.

Keras ve, v katerem načinu teče, ker ima vgrajen mehanizem, imenovan učna_faza. Faza učenja nadzira, ali je omrežje v vlakovnem ali testnem načinu. Če ga uporabnik ne nastavi ročno, med fit() omrežje deluje z learning_phase=1 (način vlaka). Med ustvarjanjem napovedi (na primer, ko kličemo metodi predict() & evaluate() ali pri koraku preverjanja fit()) omrežje deluje z learning_phase=0 (testni način). Čeprav ni priporočljivo, lahko uporabnik tudi statično spremeni learning_phase na določeno vrednost, vendar se mora to zgoditi, preden je v graf dodan kateri koli model ali tenzor. Če je learning_phase nastavljen statično, bo Keras zaklenjen na kateri koli način, ki ga izbere uporabnik.

1.4 Kako je Keras sčasoma implementiral paketno normalizacijo?

Keras je večkrat spremenil vedenje paketne normalizacije, vendar se je zadnja pomembna posodobitev zgodila v Kerasu 2.1.3. Pred različico 2.1.3, ko je bila plast BN zamrznjena (trainable = False), je nenehno posodabljala svojo paketno statistiko, kar je uporabnikom povzročalo epske glavobole.

To ni bila le čudna politika, bila je pravzaprav napačna. Predstavljajte si, da obstaja plast BN med vijugami; če je plast zamrznjena, se na njej ne sme zgoditi nobenih sprememb. Če delno posodobimo njegove uteži in so zamrznjene tudi naslednje plasti, se nikoli ne bodo imele priložnosti prilagoditi posodobitvam statistike mini paketov, kar bo povzročilo večjo napako. K sreči od različice 2.1.3 naprej, ko je sloj BN zamrznjen, ne posodablja več svoje statistike. Toda ali je to dovolj? Ne, če uporabljate Transfer Learning.

Spodaj natančno opisujem, v čem je težava, in skiciram tehnično izvedbo za njeno rešitev. Ponujam tudi nekaj primerov, ki prikazujejo učinke na natančnost modela pred in po obliž se uporablja.

2.1 Tehnični opis problema

Težava s trenutno implementacijo Kerasa je, da ko je plast BN zamrznjena, še naprej uporablja statistiko mini paketov med usposabljanjem. Menim, da je boljši pristop, ko je BN zamrznjen, uporaba drseče sredine in variance, ki se ju je naučil med treningom. Zakaj? Iz istih razlogov, zakaj statistike mini serije ne bi smeli posodabljati, ko je plast zamrznjena: to lahko privede do slabih rezultatov, ker naslednje plasti niso pravilno usposobljene.

Predpostavimo, da gradite model računalniškega vida, vendar nimate dovolj podatkov, zato se odločite uporabiti enega od predhodno usposobljenih CNN-jev Keras in ga natančno prilagoditi. Na žalost s tem ne dobite nobenega zagotovila, da bosta povprečje in varianca vašega novega nabora podatkov znotraj plasti BN podobna tistima iz izvirnega nabora podatkov. Ne pozabite, da bo trenutno med usposabljanjem vaše omrežje vedno uporabljalo statistiko mini paketov, ne glede na to, ali je plast BN zamrznjena ali ne; tudi pri sklepanju boste uporabili predhodno naučeno statistiko zamrznjenih BN plasti. Posledično, če natančno prilagodite zgornje plasti, bodo njihove uteži prilagojene povprečju/varianci novo nabor podatkov. Kljub temu bodo med sklepanjem prejeli podatke, ki so skalirani drugače ker je povprečje/varianca izvirno nabor podatkov bo uporabljen.
Plast Batch Normalization Kerasa je pokvarjena PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.
Zgoraj nudim poenostavljeno (in nerealistično) arhitekturo za demonstracijske namene. Predpostavimo, da natančno prilagodimo model od konvolucije k+1 do vrha omrežja (desna stran), spodnji del (leva stran) pa ostane zamrznjen. Med vadbo bodo vse plasti BN od 1 do k uporabljale povprečje/varianco vaših podatkov o vadbi. To bo imelo negativne učinke na zamrznjene ReLU, če povprečje in varianca na vsakem BN nista blizu tistim, pridobljenim med predhodnim usposabljanjem. Prav tako bo povzročilo, da se preostalo omrežje (od CONV k+1 in pozneje) usposablja z vhodi, ki imajo drugačne lestvice v primerjavi s tem, kar bo prejelo med sklepanjem. Med usposabljanjem se lahko vaše omrežje prilagodi tem spremembam, kljub temu pa bo Keras v trenutku, ko preklopite v način predvidevanja, uporabil drugačno standardizacijsko statistiko, nekaj, kar bo pospešilo porazdelitev vnosov naslednjih plasti, kar vodi do slabih rezultatov.

2.2 Kako lahko ugotovite, ali ste prizadeti?

Eden od načinov za odkrivanje je, da statično nastavite fazo učenja Kerasa na 1 (način vlaka) in na 0 (testni način) ter v vsakem primeru ocenite svoj model. Če obstaja velika razlika v natančnosti istega nabora podatkov, težava vpliva na vas. Vredno je poudariti, da zaradi načina, kako je mehanizem learning_phase implementiran v Kerasu, običajno ni priporočljivo, da bi se z njim ukvarjali. Spremembe v fazi_učenja ne bodo vplivale na modele, ki so že prevedeni in uporabljeni; kot lahko vidite na primerih v naslednjih podrazdelkih, je najboljši način za to, da začnete s čisto sejo in spremenite learning_phase, preden je v grafu definiran kateri koli tenzor.

Drug način za odkrivanje težave med delom z binarnimi klasifikatorji je preverjanje točnosti in AUC. Če je natančnost blizu 50 %, vendar je AUC blizu 1 (in opazite tudi razlike med načinom vlak/preizkus na istem naboru podatkov), je verjetnost, da so verjetnosti izven lestvice zaradi statistike BN. Podobno lahko za regresijo uporabite MSE in Spearmanovo korelacijo, da jo zaznate.

2.3 Kako lahko to popravimo?

Menim, da je težavo mogoče odpraviti, če so zamrznjene plasti BN dejansko samo to: trajno zaklenjene v testnem načinu. Kar zadeva implementacijo, mora biti zastavica, ki jo je mogoče učiti, del računskega grafa, obnašanje BN pa mora biti odvisno ne samo od faze učenja, ampak tudi od vrednosti lastnosti, ki jo je mogoče učiti. Podrobnosti o moji izvedbi najdete na GitHub.

Z uporabo zgornjega popravka, ko je plast BN zamrznjena, ne bo več uporabljala statistike mini paketov, ampak bo uporabila tiste, pridobljene med usposabljanjem. Posledično ne bo odstopanja med načinoma usposabljanja in preizkusa, kar vodi do večje natančnosti. Očitno bo, ko plast BN ni zamrznjena, med usposabljanjem še naprej uporabljala statistiko mini serije.

2.4 Ocenjevanje učinkov obliža

Čeprav sem zgornjo implementacijo napisal pred kratkim, je ideja za njo močno preizkušena na težavah v resničnem svetu z uporabo različnih rešitev, ki imajo enak učinek. Na primer, neskladju med načinoma usposabljanja in testiranja se je mogoče izogniti tako, da omrežje razdelite na dva dela (zamrznjeno in nezamrznjeno) in izvedete predpomnjeno usposabljanje (enkrat posredujete podatke skozi zamrznjeni model in jih nato uporabite za usposabljanje nezamrznjenega omrežja). Kljub temu, ker "verjemite mi, to sem že naredil" običajno nima teže, spodaj podajam nekaj primerov, ki prikazujejo učinke nove implementacije v praksi.

Tukaj je nekaj pomembnih točk o poskusu:

  1. Uporabil bom majhno količino podatkov, da bom model namerno preveč prilagodil, model pa bom uril in validiral na istem naboru podatkov. S tem pričakujem skoraj popolno natančnost in enako zmogljivost na naboru podatkov o usposabljanju/validaciji.
  2. Če med validacijo dobim znatno nižjo natančnost istega nabora podatkov, bom imel jasen znak, da trenutna politika BN negativno vpliva na delovanje modela med sklepanjem.
  3. Kakršna koli predhodna obdelava bo potekala zunaj generatorjev. To je storjeno, da bi se izognili napaki, ki je bila uvedena v različici 2.1.5 (trenutno je popravljena v prihajajoči različici 2.1.6 in najnovejši glavni različici).
  4. Keras bomo prisilili, da bo med ocenjevanjem uporabljal različne faze učenja. Če opazimo razlike med navedeno natančnostjo, bomo vedeli, da veljavna politika BN vpliva na nas.

Koda za poskus je prikazana spodaj:

import numpy as np
from keras.datasets import cifar10
from scipy.misc import imresize

from keras.preprocessing.image import ImageDataGenerator
from keras.applications.resnet50 import ResNet50, preprocess_input
from keras.models import Model, load_model
from keras.layers import Dense, Flatten
from keras import backend as K


seed = 42
epochs = 10
records_per_class = 100

# We take only 2 classes from CIFAR10 and a very small sample to intentionally overfit the model.
# We will also use the same data for train/test and expect that Keras will give the same accuracy.
(x, y), _ = cifar10.load_data()

def filter_resize(category):
   # We do the preprocessing here instead in the Generator to get around a bug on Keras 2.1.5.
   return [preprocess_input(imresize(img, (224,224)).astype('float')) for img in x[y.flatten()==category][:records_per_class]]

x = np.stack(filter_resize(3)+filter_resize(5))
records_per_class = x.shape[0] // 2
y = np.array([[1,0]]*records_per_class + [[0,1]]*records_per_class)


# We will use a pre-trained model and finetune the top layers.
np.random.seed(seed)
base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
l = Flatten()(base_model.output)
predictions = Dense(2, activation='softmax')(l)
model = Model(inputs=base_model.input, outputs=predictions)

for layer in model.layers[:140]:
   layer.trainable = False

for layer in model.layers[140:]:
   layer.trainable = True

model.compile(optimizer='sgd', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit_generator(ImageDataGenerator().flow(x, y, seed=42), epochs=epochs, validation_data=ImageDataGenerator().flow(x, y, seed=42))

# Store the model on disk
model.save('tmp.h5')


# In every test we will clear the session and reload the model to force Learning_Phase values to change.
print('DYNAMIC LEARNING_PHASE')
K.clear_session()
model = load_model('tmp.h5')
# This accuracy should match exactly the one of the validation set on the last iteration.
print(model.evaluate_generator(ImageDataGenerator().flow(x, y, seed=42)))


print('STATIC LEARNING_PHASE = 0')
K.clear_session()
K.set_learning_phase(0)
model = load_model('tmp.h5')
# Again the accuracy should match the above.
print(model.evaluate_generator(ImageDataGenerator().flow(x, y, seed=42)))


print('STATIC LEARNING_PHASE = 1')
K.clear_session()
K.set_learning_phase(1)
model = load_model('tmp.h5')
# The accuracy will be close to the one of the training set on the last iteration.
print(model.evaluate_generator(ImageDataGenerator().flow(x, y, seed=42)))

Preverimo rezultate na Keras v2.1.5:

Epoch 1/10
1/7 [===>..........................] - ETA: 25s - loss: 0.8751 - acc: 0.5312
2/7 [=======>......................] - ETA: 11s - loss: 0.8594 - acc: 0.4531
3/7 [===========>..................] - ETA: 7s - loss: 0.8398 - acc: 0.4688 
4/7 [================>.............] - ETA: 4s - loss: 0.8467 - acc: 0.4844
5/7 [====================>.........] - ETA: 2s - loss: 0.7904 - acc: 0.5437
6/7 [========================>.....] - ETA: 1s - loss: 0.7593 - acc: 0.5625
7/7 [==============================] - 12s 2s/step - loss: 0.7536 - acc: 0.5744 - val_loss: 0.6526 - val_acc: 0.6650

Epoch 2/10
1/7 [===>..........................] - ETA: 4s - loss: 0.3881 - acc: 0.8125
2/7 [=======>......................] - ETA: 3s - loss: 0.3945 - acc: 0.7812
3/7 [===========>..................] - ETA: 2s - loss: 0.3956 - acc: 0.8229
4/7 [================>.............] - ETA: 1s - loss: 0.4223 - acc: 0.8047
5/7 [====================>.........] - ETA: 1s - loss: 0.4483 - acc: 0.7812
6/7 [========================>.....] - ETA: 0s - loss: 0.4325 - acc: 0.7917
7/7 [==============================] - 8s 1s/step - loss: 0.4095 - acc: 0.8089 - val_loss: 0.4722 - val_acc: 0.7700

Epoch 3/10
1/7 [===>..........................] - ETA: 4s - loss: 0.2246 - acc: 0.9375
2/7 [=======>......................] - ETA: 3s - loss: 0.2167 - acc: 0.9375
3/7 [===========>..................] - ETA: 2s - loss: 0.2260 - acc: 0.9479
4/7 [================>.............] - ETA: 2s - loss: 0.2179 - acc: 0.9375
5/7 [====================>.........] - ETA: 1s - loss: 0.2356 - acc: 0.9313
6/7 [========================>.....] - ETA: 0s - loss: 0.2392 - acc: 0.9427
7/7 [==============================] - 8s 1s/step - loss: 0.2288 - acc: 0.9456 - val_loss: 0.4282 - val_acc: 0.7800

Epoch 4/10
1/7 [===>..........................] - ETA: 4s - loss: 0.2183 - acc: 0.9688
2/7 [=======>......................] - ETA: 3s - loss: 0.1899 - acc: 0.9844
3/7 [===========>..................] - ETA: 2s - loss: 0.1887 - acc: 0.9792
4/7 [================>.............] - ETA: 1s - loss: 0.1995 - acc: 0.9531
5/7 [====================>.........] - ETA: 1s - loss: 0.1932 - acc: 0.9625
6/7 [========================>.....] - ETA: 0s - loss: 0.1819 - acc: 0.9688
7/7 [==============================] - 8s 1s/step - loss: 0.1743 - acc: 0.9747 - val_loss: 0.3778 - val_acc: 0.8400

Epoch 5/10
1/7 [===>..........................] - ETA: 3s - loss: 0.0973 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0828 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0851 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0897 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0928 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0936 - acc: 1.0000
7/7 [==============================] - 8s 1s/step - loss: 0.1337 - acc: 0.9838 - val_loss: 0.3916 - val_acc: 0.8100

Epoch 6/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0747 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0852 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0812 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0831 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0779 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0766 - acc: 1.0000
7/7 [==============================] - 8s 1s/step - loss: 0.0813 - acc: 1.0000 - val_loss: 0.3637 - val_acc: 0.8550

Epoch 7/10
1/7 [===>..........................] - ETA: 1s - loss: 0.2478 - acc: 0.8750
2/7 [=======>......................] - ETA: 2s - loss: 0.1966 - acc: 0.9375
3/7 [===========>..................] - ETA: 2s - loss: 0.1528 - acc: 0.9583
4/7 [================>.............] - ETA: 1s - loss: 0.1300 - acc: 0.9688
5/7 [====================>.........] - ETA: 1s - loss: 0.1193 - acc: 0.9750
6/7 [========================>.....] - ETA: 0s - loss: 0.1196 - acc: 0.9792
7/7 [==============================] - 8s 1s/step - loss: 0.1084 - acc: 0.9838 - val_loss: 0.3546 - val_acc: 0.8600

Epoch 8/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0539 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.0900 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0815 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0740 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0700 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0701 - acc: 1.0000
7/7 [==============================] - 8s 1s/step - loss: 0.0695 - acc: 1.0000 - val_loss: 0.3269 - val_acc: 0.8600

Epoch 9/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0306 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0377 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0898 - acc: 0.9583
4/7 [================>.............] - ETA: 1s - loss: 0.0773 - acc: 0.9688
5/7 [====================>.........] - ETA: 1s - loss: 0.0742 - acc: 0.9750
6/7 [========================>.....] - ETA: 0s - loss: 0.0708 - acc: 0.9792
7/7 [==============================] - 8s 1s/step - loss: 0.0659 - acc: 0.9838 - val_loss: 0.3604 - val_acc: 0.8600

Epoch 10/10
1/7 [===>..........................] - ETA: 3s - loss: 0.0354 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0381 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0354 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0828 - acc: 0.9688
5/7 [====================>.........] - ETA: 1s - loss: 0.0791 - acc: 0.9750
6/7 [========================>.....] - ETA: 0s - loss: 0.0794 - acc: 0.9792
7/7 [==============================] - 8s 1s/step - loss: 0.0704 - acc: 0.9838 - val_loss: 0.3615 - val_acc: 0.8600

DYNAMIC LEARNING_PHASE
[0.3614931714534759, 0.86]

STATIC LEARNING_PHASE = 0
[0.3614931714534759, 0.86]

STATIC LEARNING_PHASE = 1
[0.025861846953630446, 1.0]

Kot lahko vidimo zgoraj, se model med vadbo zelo dobro nauči podatkov in na vadbenem nizu doseže skoraj popolno natančnost. Kljub temu na koncu vsake iteracije, med vrednotenjem modela na istem naboru podatkov, dobimo pomembne razlike v izgubi in natančnosti. Upoštevajte, da tega ne bi smeli dobiti; namenoma smo preveč opremili model s specifičnim naborom podatkov in nabori podatkov za usposabljanje/validacijo so enaki.

Po končanem usposabljanju ovrednotimo model z uporabo 3 različnih konfiguracij faze učenja: dinamično, statično = 0 (testni način) in statično = 1 (način usposabljanja). Kot lahko vidimo, bosta prvi dve konfiguraciji zagotovili enake rezultate v smislu izgube in natančnosti, njuna vrednost pa se ujema s prijavljeno natančnostjo modela na validacijskem nizu v zadnji iteraciji. Kljub temu, ko preklopimo v način vadbe, opazimo veliko odstopanje (izboljšanje). Zakaj to? Kot smo že povedali, so uteži omrežja prilagojene tako, da pričakujejo, da bodo prejeli podatke, prilagojene povprečju/varianci podatkov o usposabljanju. Na žalost se ta statistika razlikuje od tiste, shranjene v slojih BN. Ker so bile plasti BN zamrznjene, ta statistika ni bila nikoli posodobljena. To neskladje med vrednostmi statistike BN vodi do poslabšanja točnosti med sklepanjem.

Poglejmo, kaj se zgodi, ko uporabimo obliž:

Epoch 1/10
1/7 [===>..........................] - ETA: 26s - loss: 0.9992 - acc: 0.4375
2/7 [=======>......................] - ETA: 12s - loss: 1.0534 - acc: 0.4375
3/7 [===========>..................] - ETA: 7s - loss: 1.0592 - acc: 0.4479 
4/7 [================>.............] - ETA: 4s - loss: 0.9618 - acc: 0.5000
5/7 [====================>.........] - ETA: 2s - loss: 0.8933 - acc: 0.5250
6/7 [========================>.....] - ETA: 1s - loss: 0.8638 - acc: 0.5417
7/7 [==============================] - 13s 2s/step - loss: 0.8357 - acc: 0.5570 - val_loss: 0.2414 - val_acc: 0.9450

Epoch 2/10
1/7 [===>..........................] - ETA: 4s - loss: 0.2331 - acc: 0.9688
2/7 [=======>......................] - ETA: 2s - loss: 0.3308 - acc: 0.8594
3/7 [===========>..................] - ETA: 2s - loss: 0.3986 - acc: 0.8125
4/7 [================>.............] - ETA: 1s - loss: 0.3721 - acc: 0.8281
5/7 [====================>.........] - ETA: 1s - loss: 0.3449 - acc: 0.8438
6/7 [========================>.....] - ETA: 0s - loss: 0.3168 - acc: 0.8646
7/7 [==============================] - 9s 1s/step - loss: 0.3165 - acc: 0.8633 - val_loss: 0.1167 - val_acc: 0.9950

Epoch 3/10
1/7 [===>..........................] - ETA: 1s - loss: 0.2457 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.2592 - acc: 0.9688
3/7 [===========>..................] - ETA: 2s - loss: 0.2173 - acc: 0.9688
4/7 [================>.............] - ETA: 1s - loss: 0.2122 - acc: 0.9688
5/7 [====================>.........] - ETA: 1s - loss: 0.2003 - acc: 0.9688
6/7 [========================>.....] - ETA: 0s - loss: 0.1896 - acc: 0.9740
7/7 [==============================] - 9s 1s/step - loss: 0.1835 - acc: 0.9773 - val_loss: 0.0678 - val_acc: 1.0000

Epoch 4/10
1/7 [===>..........................] - ETA: 1s - loss: 0.2051 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.1652 - acc: 0.9844
3/7 [===========>..................] - ETA: 2s - loss: 0.1423 - acc: 0.9896
4/7 [================>.............] - ETA: 1s - loss: 0.1289 - acc: 0.9922
5/7 [====================>.........] - ETA: 1s - loss: 0.1225 - acc: 0.9938
6/7 [========================>.....] - ETA: 0s - loss: 0.1149 - acc: 0.9948
7/7 [==============================] - 9s 1s/step - loss: 0.1060 - acc: 0.9955 - val_loss: 0.0455 - val_acc: 1.0000

Epoch 5/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0769 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.0846 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0797 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0736 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0914 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0858 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0808 - acc: 1.0000 - val_loss: 0.0346 - val_acc: 1.0000

Epoch 6/10
1/7 [===>..........................] - ETA: 1s - loss: 0.1267 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.1039 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0893 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0780 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0758 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0789 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0738 - acc: 1.0000 - val_loss: 0.0248 - val_acc: 1.0000

Epoch 7/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0344 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0385 - acc: 1.0000
3/7 [===========>..................] - ETA: 3s - loss: 0.0467 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0445 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0446 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0429 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0421 - acc: 1.0000 - val_loss: 0.0202 - val_acc: 1.0000

Epoch 8/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0319 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0300 - acc: 1.0000
3/7 [===========>..................] - ETA: 3s - loss: 0.0320 - acc: 1.0000
4/7 [================>.............] - ETA: 2s - loss: 0.0307 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0303 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0291 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0358 - acc: 1.0000 - val_loss: 0.0167 - val_acc: 1.0000

Epoch 9/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0246 - acc: 1.0000
2/7 [=======>......................] - ETA: 3s - loss: 0.0255 - acc: 1.0000
3/7 [===========>..................] - ETA: 3s - loss: 0.0258 - acc: 1.0000
4/7 [================>.............] - ETA: 2s - loss: 0.0250 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0252 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0260 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0327 - acc: 1.0000 - val_loss: 0.0143 - val_acc: 1.0000

Epoch 10/10
1/7 [===>..........................] - ETA: 4s - loss: 0.0251 - acc: 1.0000
2/7 [=======>......................] - ETA: 2s - loss: 0.0228 - acc: 1.0000
3/7 [===========>..................] - ETA: 2s - loss: 0.0217 - acc: 1.0000
4/7 [================>.............] - ETA: 1s - loss: 0.0249 - acc: 1.0000
5/7 [====================>.........] - ETA: 1s - loss: 0.0244 - acc: 1.0000
6/7 [========================>.....] - ETA: 0s - loss: 0.0239 - acc: 1.0000
7/7 [==============================] - 9s 1s/step - loss: 0.0290 - acc: 1.0000 - val_loss: 0.0127 - val_acc: 1.0000

DYNAMIC LEARNING_PHASE
[0.012697912137955427, 1.0]

STATIC LEARNING_PHASE = 0
[0.012697912137955427, 1.0]

STATIC LEARNING_PHASE = 1
[0.01744014158844948, 1.0]

Najprej opažamo, da mreža bistveno hitreje konvergira in dosega popolno natančnost. Vidimo tudi, da ni več neskladja v smislu natančnosti, ko preklapljamo med različnimi vrednostmi faze učenja.

2.5 Kako se popravek obnese na resničnem naboru podatkov?

Kako se torej popravek obnese pri bolj realističnem poskusu? Uporabimo Kerasov vnaprej usposobljen ResNet50 (prvotno primeren za imagenet), odstranimo zgornjo klasifikacijsko plast in jo natančno nastavimo z in brez popravka ter primerjamo rezultate. Za podatke bomo uporabili CIFAR10 (standardni train/test split, ki ga zagotavlja Keras) in spremenili velikost slik na 224×224, da bodo združljive z vhodno velikostjo ResNet50.

Izvedli bomo 10 epoh za usposabljanje najvišje klasifikacijske plasti z uporabo RSMprop in nato bomo izvedli še 5 za natančno nastavitev vsega po 139. plasti z uporabo SGD(lr=1e-4, momentum=0.9). Brez popravka naš model dosega natančnost 87.44 %. Z uporabo popravka dobimo natančnost 92.36%, skoraj 5 točk več.

2.6 Ali naj isti popravek uporabimo za druge plasti, kot je Dropout?

Paketna normalizacija ni edina plast, ki deluje drugače med načinoma vlaka in preskusnim načinom. Enak učinek imajo tudi Dropout in njegove različice. Ali naj uporabimo isti pravilnik za vse te plasti? Verjamem, da ne (čeprav bi rad slišal vaše misli o tem). Razlog je v tem, da se Dropout uporablja za preprečevanje prekomernega opremljanja, zato bi trajno zaklepanje v način predvidevanja med vadbo izničilo njegov namen. Kaj misliš?

Trdno sem prepričan, da je treba to neskladje rešiti v Kerasu. Videl sem še bolj globoke učinke (od 100-odstotne do 50-odstotne natančnosti) v aplikacijah v resničnem svetu, ki jih povzroča ta težava. jaz nameravate poslati že poslal a PR Kerasu s popravkom in upam, da bo sprejet.

Če vam je bila ta objava v spletnem dnevniku všeč, si vzemite trenutek in jo delite na Facebooku ali Twitterju. 🙂

Časovni žig:

Več od Datumbox