Kerase partii normaliseerimise kiht on katki PlatoBlockchain Data Intelligence. Vertikaalne otsing. Ai.

Kerase partii normaliseerimise kiht on katki

VÄRSKENDUS: Kahjuks ei aktsepteeritud minu Kerasele saadetud tõmbetaotlust, mis muutis partii normaliseerimise kihi käitumist. Saate lugeda üksikasju siin. Need, kes on piisavalt julged kohandatud rakendustega segamini ajada, leiate koodi siit minu haru. Võin selle säilitada ja ühendada Kerase uusima stabiilse versiooniga (2.1.6, 2.2.2 ja 2.2.4) nii kaua, kuni ma seda kasutan, kuid ei luba.

Enamik inimesi, kes töötavad süvaõppes, on seda kas kasutanud või sellest kuulnud Keras. Neile, kes pole seda teinud, on see suurepärane raamatukogu, mis võtab kokku aluseks olevad süvaõppe raamistikud, nagu TensorFlow, Theano ja CNTK, ning pakub kõrgetasemeline API ANNide koolitamiseks. Seda on lihtne kasutada, see võimaldab kiiret prototüüpimist ja sellel on sõbralik aktiivne kogukond. Olen seda aktiivselt kasutanud ja projektis perioodiliselt panustanud juba mõnda aega ning soovitan seda kindlasti kõigile, kes soovivad süvaõppega tegeleda.

Kuigi Keras muutis mu elu lihtsamaks, on mind päris mitu korda hammustanud partii normaliseerimise kihi veider käitumine. Selle vaikekäitumine on aja jooksul muutunud, kuid siiski põhjustab see paljudele kasutajatele probleeme ja seetõttu on sellega seotud mitu lahtised küsimused Githubis. Selles ajaveebipostituses püüan luua juhtumi, miks Kerase BatchNormalization kiht ei mängi Transfer Learningiga kenasti, annan koodi, mis probleemi parandab, ja toon näiteid selle tulemuste kohta. plaaster.

Allolevates alajaotistes annan sissejuhatuse selle kohta, kuidas ülekandeõpet kasutatakse süvaõppes, mis on partii normaliseerimise kiht, kuidas õppimise_faas töötab ja kuidas Keras BN-i käitumist aja jooksul muutis. Kui te neid juba teate, võite julgelt otse 2. jaotisesse hüpata.

1.1 Transfer Learning kasutamine on süvaõppe jaoks ülioluline

Üks põhjusi, miks Deep Learningut varem kritiseeriti, on see, et see nõuab liiga palju andmeid. See ei ole alati tõsi; selle piiranguga toimetulemiseks on mitu tehnikat, millest üks on ülekandeõpe.

Oletame, et töötate arvutinägemise rakenduse kallal ja soovite luua klassifikaatori, mis eristab kasse koertest. Modelli koolitamiseks pole tegelikult vaja miljoneid kassi/koera pilte. Selle asemel saate kasutada eelkoolitatud klassifikaatorit ja peenhäälestada parimaid keerdkäike vähemate andmetega. Selle idee seisneb selles, et kuna eelkoolitatud mudel sobis piltidele, suudavad alumised keerdud ära tunda selliseid funktsioone nagu jooned, servad ja muud kasulikud mustrid, mis tähendab, et saate selle kaalusid kasutada kas heade lähtestamisväärtustena või oma andmetega võrku osaliselt ümber õpetada. .
Kerase partii normaliseerimise kiht on katki PlatoBlockchain Data Intelligence. Vertikaalne otsing. Ai.
Kerasega on kaasas mitu eelkoolitatud mudelit ja hõlpsasti kasutatavaid näiteid mudelite peenhäälestamiseks. Lisateavet saate lugeda dokumentatsioon.

1.2 Mis on partii normaliseerimise kiht?

Partii normaliseerimise kihi võtsid 2014. aastal kasutusele Ioffe ja Szegedy. See lahendab kaduva gradiendi probleemi, standardiseerides eelmise kihi väljundi, kiirendab koolitust, vähendades vajalike iteratsioonide arvu ja võimaldab treenida sügavamaid närvivõrke. Selle töö täpse selgitamine ei kuulu selle postituse ulatusse, kuid soovitan teil tungivalt seda lugeda originaalpaber. Liiga lihtsustatud seletus on see, et see muudab sisendit, lahutades selle keskmise ja jagades selle standardhälbega; see võib ka õppida vajaduse korral teisendust tagasi võtma.
Kerase partii normaliseerimise kiht on katki PlatoBlockchain Data Intelligence. Vertikaalne otsing. Ai.

1.3 Mis on Keras õppimise_faas?

Mõned kihid töötavad treeningu ja järeldusrežiimi ajal erinevalt. Kõige tähelepanuväärsemad näited on partii normaliseerimine ja väljalangemise kihid. BN-i puhul kasutame koolituse ajal sisendi muutmiseks minipartii keskmist ja dispersiooni. Teisest küljest kasutame järelduste tegemisel libisevat keskmist ja dispersiooni, mida hinnati treeningu ajal.

Keras teab, millises režiimis töötada, sest sellel on sisseehitatud mehhanism nimega õppimise_faas. Õppimise faas kontrollib, kas võrk on rongi- või katserežiimis. Kui kasutaja ei ole seda käsitsi määranud, töötab võrk fit() ajal parameetriga learning_phase=1 (treenirežiim). Prognooside loomisel (näiteks kui kutsume meetodeid ennustama() & hindama() või sobivuse () valideerimisetapis) töötab võrk õppimise_faasiga = 0 (testimisrežiim). Kuigi see pole soovitatav, saab kasutaja ka staatiliselt muuta õppimisfaasi konkreetseks väärtuseks, kuid see peab juhtuma enne, kui graafikule lisatakse mõni mudel või tensor. Kui õppefaas on staatiliselt määratud, lukustatakse Keras kasutaja valitud režiimile.

1.4 Kuidas Keras aja jooksul partii normaliseerimist rakendas?

Keras on mitu korda muutnud partii normaliseerimise käitumist, kuid viimane oluline värskendus leidis aset Kerase versioonis 2.1.3. Enne versiooni 2.1.3, kui BN-kiht külmutati (koolitatav = vale), värskendas see pidevalt oma partiitatistikat, mis põhjustas selle kasutajatele eepilist peavalu.

See ei olnud lihtsalt veider poliitika, see oli tegelikult vale. Kujutage ette, et keerdude vahel eksisteerib BN kiht; kui kiht on külmunud, ei tohiks selles muutusi juhtuda. Kui värskendame osaliselt selle kaalusid ja ka järgmised kihid külmutatakse, ei saa nad kunagi kohaneda minipartii statistika värskendustega, mis põhjustavad suuremat viga. Õnneks alates versioonist 2.1.3, kui BN-kiht on külmutatud, ei värskenda see enam oma statistikat. Aga kas sellest piisab? Mitte, kui kasutate ülekandeõpet.

Allpool kirjeldan täpselt, milles probleem on ja visandan selle lahendamise tehnilise teostuse. Toon ka mõned näited, et näidata mõju mudeli täpsusele enne ja pärast plaaster rakendatakse.

2.1 Probleemi tehniline kirjeldus

Kerase praeguse juurutamise probleem seisneb selles, et kui BN-kiht on külmutatud, jätkab see treeningu ajal minipartii statistika kasutamist. Usun, et parem lähenemine BN-i külmutamisel on kasutada treeningu ajal õpitud liikuvat keskmist ja dispersiooni. Miks? Samadel põhjustel, miks minipartii statistikat ei tohiks värskendada, kui kiht on külmunud: see võib põhjustada kehvad tulemused, kuna järgmisi kihte ei treenita korralikult.

Oletame, et loote Computer Visioni mudelit, kuid teil pole piisavalt andmeid, mistõttu otsustate kasutada mõnda Kerase eelkoolitatud CNN-i ja seda peenhäälestada. Kahjuks ei saa te seda tehes garantiid, et teie uue andmestiku keskmine ja dispersioon BN-kihtides on sarnased algse andmekogumi omadega. Pidage meeles, et praegu kasutab teie võrk treeningu ajal alati minipartii statistikat, kas BN-kiht on külmutatud või mitte; ka järeldamisel kasutate eelnevalt õpitud külmutatud BN-kihtide statistikat. Selle tulemusel kohandatakse ülemiste kihtide peenhäälestamisel nende kaal vastavalt kihi keskmisele/variatsioonile. uus andmestik. Sellest hoolimata saavad nad järelduste tegemise ajal andmeid, mis on skaleeritud erinevalt sest keskmine/variatsioon originaal kasutatakse andmestikku.
Kerase partii normaliseerimise kiht on katki PlatoBlockchain Data Intelligence. Vertikaalne otsing. Ai.
Eespool pakun demonstratsiooni eesmärgil lihtsustatud (ja ebareaalset) arhitektuuri. Oletame, et peenhäälestame mudelit konvolutsioonist k+1 kuni võrgu ülaosani (parem pool) ja hoiame allserva (vasak pool) külmutatuna. Treeningu ajal kasutavad kõik BN-kihid vahemikus 1 kuni k teie treeningandmete keskmist/variatsiooni. Sellel on külmutatud ReLU-dele negatiivne mõju, kui iga BN-i keskmine ja dispersioon ei ole lähedased eelkoolituse ajal õpitutele. Samuti õpetatakse ülejäänud võrku (alates CONV k+1 ja uuemad) sisenditega, mille skaala on erinev võrreldes sellega, mis järeldamise ajal vastu võetakse. Treeningu ajal suudab teie võrk nende muutustega kohaneda, kuid ennustusrežiimile üleminekul kasutab Keras erinevat standardimisstatistikat, mis kiirendab järgmiste kihtide sisendite jaotamist, mis toob kaasa kehvad tulemused.

2.2 Kuidas saate tuvastada, kas olete mõjutatud?

Üks võimalus selle tuvastamiseks on seada Kerase õppimisfaasi staatiliselt 1-le (treeningrežiim) ja 0-le (testrežiim) ning hinnata igal juhul oma mudelit. Kui sama andmestiku täpsuses on märkimisväärne erinevus, mõjutab probleem teid. Tasub märkida, et õppefaasi mehhanismi Keras rakendamisviisi tõttu ei soovitata tavaliselt sellega jamada. Õppimisfaasi muudatused ei mõjuta mudeleid, mis on juba koostatud ja kasutatud; nagu näete järgmiste alajaotiste näidetes, on parim viis selleks alustada puhta seansiga ja muuta õppimisfaasi enne, kui graafikus on defineeritud mis tahes tensor.

Teine võimalus binaarsete klassifikaatoritega töötamise ajal probleemi tuvastamiseks on kontrollida täpsust ja AUC-d. Kui täpsus on 50% lähedal, kuid AUC on 1-le lähedane (ja märkate ka erinevusi sama andmestiku rongi-/katserežiimide vahel), võib juhtuda, et tõenäosused on BN-i statistika tõttu skaalast väljas. Samamoodi saate regressiooni tuvastamiseks kasutada MSE ja Spearmani korrelatsiooni.

2.3 Kuidas seda parandada?

Usun, et probleemi saab parandada, kui külmutatud BN-kihid on tegelikult just sellised: püsivalt testrežiimis lukustatud. Rakendamisel peab treenitav lipp olema arvutusgraafiku osa ja BN-i käitumine peab sõltuma mitte ainult õppimisfaasist, vaid ka treenitava omaduse väärtusest. Minu rakendamise üksikasjad leiate aadressilt Github.

Ülaltoodud paranduse rakendamisel ei kasuta BN-kihi külmutamisel enam minipartii statistikat, vaid kasutab koolituse käigus õpitut. Selle tulemusena ei esine lahknevusi treening- ja testirežiimide vahel, mis suurendab täpsust. Ilmselgelt, kui BN-kiht pole külmunud, jätkab see treeningu ajal minipartii statistika kasutamist.

2.4 Plaastri mõju hindamine

Kuigi ma kirjutasin ülaltoodud teostuse hiljuti, on selle idee põhjalikult testitud reaalsete probleemide puhul, kasutades erinevaid sama mõjuga lahendusi. Näiteks lahknevusi koolitus- ja testimisrežiimide vahel saab vältida, jagades võrgu kaheks osaks (külmutatud ja külmutamata) ja sooritades vahemällu salvestatud koolituse (andmed ühe korra läbi külmutatud mudeli ja seejärel nende abil külmutamata võrgu treenimiseks). Sellegipoolest, kuna "usalda mind, ma olen seda varem teinud" ei oma tavaliselt mingit kaalu, toon allpool mõned näited, mis näitavad uue rakenduse mõju praktikas.

Siin on mõned olulised punktid katse kohta:

  1. Kasutan väikest kogust andmeid, et mudelit tahtlikult üle sobitada, ning treenin ja valideerin mudeli samas andmekogumis. Seda tehes eeldan rongi/valideerimisandmestiku peaaegu täiuslikku täpsust ja identset jõudlust.
  2. Kui valideerimise käigus saan sama andmestiku puhul oluliselt madalama täpsuse, on mul selge märge, et praegune BN-poliitika mõjutab mudeli toimivust järelduse tegemisel negatiivselt.
  3. Igasugune eeltöötlus toimub väljaspool generaatoreid. Seda tehakse versioonis 2.1.5 (praegu parandatud eelseisval versioonil 2.1.6 ja uusimal masteril) kasutusele võetud vea ümberlülitamiseks.
  4. Sunnime Kerast hindamisel kasutama erinevaid õppefaase. Kui märkame erinevusi teatatud täpsuse vahel, teame, et praegune BN-poliitika meid mõjutab.

Katse kood on näidatud allpool:

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)))

Kontrollime Kerase v2.1.5 tulemusi:

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]

Nagu ülalt näha, õpib mudel koolituse ajal andmeid väga hästi ja saavutab treeningkomplektil peaaegu täiusliku täpsuse. Iga iteratsiooni lõpus, samal andmestikul mudelit hinnates, saame märkimisväärseid erinevusi kadude ja täpsuse osas. Pange tähele, et me ei peaks seda saama; oleme konkreetse andmekogumi mudelit tahtlikult üle kohandanud ja koolituse/valideerimise andmekogumid on identsed.

Pärast koolituse lõppu hindame mudelit kolme erineva õppimisfaasi konfiguratsiooni abil: dünaamiline, staatiline = 3 (testrežiim) ja staatiline = 0 (treeningrežiim). Nagu näeme, annavad kaks esimest konfiguratsiooni identsed tulemused kaotuse ja täpsuse osas ning nende väärtus vastab mudeli teatatud täpsusele viimases iteratsioonis valideerimiskomplektis. Sellegipoolest täheldame treeningrežiimile üleminekul tohutut lahknevust (paranemist). Miks see? Nagu me varem ütlesime, häälestatakse võrgu kaalud, eeldades, et saadakse andmeid, mis on skaleeritud treeningandmete keskmise / dispersiooniga. Kahjuks erineb see statistika BN-kihtides talletatust. Kuna BN-i kihid olid külmutatud, ei värskendatud seda statistikat kunagi. See lahknevus BN-i statistika väärtuste vahel põhjustab järelduse täpsuse halvenemist.

Vaatame, mis juhtub pärast selle rakendamist plaaster:

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]

Esiteks jälgime, et võrk koondub oluliselt kiiremini ja saavutab täiusliku täpsuse. Samuti näeme, et täpsuse osas pole enam lahknevusi, kui vahetame erinevate õppimisfaasi väärtuste vahel.

2.5 Kuidas plaaster reaalses andmekogumis toimib?

Niisiis, kuidas toimib plaaster realistlikumas katses? Kasutame Kerase eelkoolitatud ResNet50 (sobib algselt imagenet’i), eemaldame pealmise klassifikatsioonikihi ja timmime seda plaastriga ja ilma ning võrdleme tulemusi. Andmete jaoks kasutame CIFAR10 (Kerase pakutav standardne rongi/testi jaotus) ja muudame piltide suuruse 224 × 224, et need ühilduksid ResNet50 sisendi suurusega.

Teeme 10 epohhi, et treenida RSMpropi abil ülemist klassifikatsioonikihti ja seejärel veel 5, et kõik pärast 139. kihti SGD(lr=1e-4, momentum=0.9) abil peenhäälestada. Ilma plaastrita saavutab meie mudeli täpsus 87.44%. Plaastrit kasutades saame täpsuseks 92.36%, ligi 5 punkti kõrgemaks.

2.6 Kas peaksime sama paranduse rakendama ka teistele kihtidele, näiteks Dropout?

Partii normaliseerimine ei ole ainus kiht, mis töötab rongi- ja katserežiimide vahel erinevalt. Sama mõju on ka väljalangemisel ja selle variantidel. Kas peaksime rakendama sama poliitikat kõikidele nendele kihtidele? Ma ei usu, et mitte (kuigi mulle meeldiks kuulda teie mõtteid selle kohta). Põhjus on selles, et Dropouti kasutatakse ülepaigutamise vältimiseks, mistõttu selle lõplikult ennustusrežiimi lukustamine treeningu ajal kaotaks selle eesmärgi. Mida sa arvad?

Usun kindlalt, et see ebakõla tuleb Keras lahendada. Olen näinud selle probleemi põhjustatud tegelikes rakendustes veelgi sügavamaid mõjusid (100% kuni 50% täpsuseni). I plaan saata juba saadetud a PR parandusega Kerasse ja loodetavasti võetakse see vastu.

Kui teile meeldis see ajaveebipostitus, võtke hetk ja jagage seda Facebookis või Twitteris. 🙂

Ajatempel:

Veel alates Datumbox