Kerasin eränormalisointikerros on rikki PlatoBlockchain Data Intelligence. Pystysuuntainen haku. Ai.

Keras-erän normalisointikerros on rikki

PÄIVITYS: Valitettavasti Erään normalisointi -kerroksen käyttäytymistä muuttavaa Pull-pyyntöä Keralle ei hyväksytty. Voit lukea yksityiskohdat tätä. Niille teistä, jotka olette tarpeeksi rohkeita sietämään mukautettuja toteutuksia, löydät koodin täältä oksani. Voisin ylläpitää sitä ja yhdistää sen viimeisimpään vakaan Keras-version (2.1.6, 2.2.2 ja 2.2.4) niin kauan kuin käytän sitä, mutta en lupaa.

Suurin osa syväoppimisessa työskentelevistä on joko käyttänyt tai kuullut niistä Keras. Niille teistä, jotka eivät ole, se on loistava kirjasto, joka tiivistää taustalla olevat Deep Learning -kehykset, kuten TensorFlow, Theano ja CNTK, ja tarjoaa korkean tason API koulutukseen ANNs. Sitä on helppo käyttää, se mahdollistaa nopean prototyyppien luomisen ja sillä on ystävällinen ja aktiivinen yhteisö. Olen käyttänyt sitä voimakkaasti ja osallistunut projektiin säännöllisesti jo jonkin aikaa, ja suosittelen sitä ehdottomasti kaikille, jotka haluavat työskennellä syvän oppimisen parissa.

Vaikka Keras teki elämästäni helpompaa, erän normalisointikerroksen outo käyttäytyminen on minua usein purettu. Sen oletuskäyttäytyminen on muuttunut ajan myötä, silti se aiheuttaa edelleen ongelmia monille käyttäjille, ja seurauksena siihen liittyy useita liittyviä avoimet ongelmat Githubissa. Tässä blogiviestissä yritän luoda tapauksen, miksi Kerasin BatchNormalization-taso ei soi mukavasti Transfer Learning -sovelluksen kanssa, annan koodin, joka korjaa ongelman, ja annan esimerkkejä tuloksista lappu.

Annan alla olevissa osioissa johdannon siitä, kuinka siirto-opiskelua käytetään syvässä oppimisessa, mikä on Erän normalisointi -kerros, kuinka oppiminen_faasi toimii ja kuinka Keras muutti BN: n käyttäytymistä ajan myötä. Jos tiedät nämä jo, voit siirtyä turvallisesti suoraan kohtaan 2.

1.1 Siirto-oppimisen käyttö on välttämätöntä syvälle oppimiseksi

Yksi syy siihen, miksi syvää oppimista kritisoitiin aiemmin, on se, että se vaatii liian paljon tietoa. Tämä ei ole aina totta; tätä rajoitusta voidaan käsitellä monella tekniikalla, joista yksi on siirto-oppiminen.

Oletetaan, että työskentelet Computer Vision -sovelluksen parissa ja haluat rakentaa luokittelijan, joka erottaa kissat koirista. Sinun ei oikeastaan ​​tarvitse miljoonia kissan / koiran kuvia mallin kouluttamiseen. Sen sijaan voit käyttää esiohjattua luokittelijaa ja hienosäätää ylin konvoluutioita vähemmän dataa. Ajatuksena on, että koska ennalta koulutettu malli sopi kuviin, alakertapinnat tunnistavat piirteitä, kuten viivoja, reunoja ja muita hyödyllisiä kuvioita, mikä tarkoittaa, että voit käyttää sen painoja joko hyvinä alustusarvoina tai kouluttaa verkon osittain uudelleen tietosi kanssa .
Kerasin eränormalisointikerros on rikki PlatoBlockchain Data Intelligence. Pystysuuntainen haku. Ai.
Kerassa on useita valmiiksi koulutettuja malleja ja helppokäyttöisiä esimerkkejä mallien hienosäätöstä. Voit lukea lisää aiheesta dokumentointi.

1.2 Mikä on erän normalisointikerros?

Iffe ja Szegedy esittelivät vuonna 2014 erän normalisointikerroksen. Se korjaa häviävän kaltevuusongelman standardisoimalla edellisen kerroksen lähtö, se nopeuttaa harjoittelua vähentämällä tarvittavien iteraatioiden määrää ja mahdollistaa syvempien hermoverkkojen kouluttamisen. Tarkalleen selittäminen, miten se toimii, on tämän viestin ulkopuolella, mutta kannustan sinua lukemaan alkuperäinen paperi. Yli yksinkertaistettu selitys on, että se muuttaa mittaustulosta vähentämällä sen keskiarvo ja jakamalla sen normaalipoikkeamalla; se voi myös oppia kumoamaan muutoksen tarvittaessa.
Kerasin eränormalisointikerros on rikki PlatoBlockchain Data Intelligence. Pystysuuntainen haku. Ai.

1.3 Mikä on oppimisfaasi Kerassa?

Jotkut kerrokset toimivat eri tavalla harjoittelu- ja päättelytilan aikana. Merkittävimpiä esimerkkejä ovat erän normalisointi ja pudotuskerrokset. BN: n tapauksessa käytämme harjoituksen aikana minierän keskiarvoa ja varianssia syötteen mitoittamiseen. Toisaalta päättelyssä käytämme liikkuvaa keskiarvoa ja varianssia, joka arvioitiin harjoituksen aikana.

Keras tietää missä tilassa suorittaa, koska siinä on sisäänrakennettu mekanismi, jota kutsutaan oppimisvaihe. Oppimisvaihe ohjaa onko verkko junassa vai testitilassa. Jos käyttäjä ei ole asettanut sitä manuaalisesti, fit (): n aikana verkko toimii oppimisvaihe = 1 (juna-tila). Ennusteiden tuottamisen aikana (esimerkiksi kun kutsumme ennustamismenetelmiä () ja arviointimenetelmiä tai fit (): n validointivaiheessa) verkko toimii oppimisvaihe = 0 (testitila). Vaikka sitä ei suositella, käyttäjä pystyy myös muuttamaan staattisesti oppimisvaiheen tietyksi arvoksi, mutta tämän on tapahduttava ennen kuin malli tai tensori lisätään kaavioon. Jos oppimisvaihe asetetaan staattisesti, Keras lukitaan käyttäjän valitsemaan tilaan.

1.4 Kuinka Keras toteutti erän normalisoinnin ajan myötä?

Keras on muuttanut erän normalisoinnin käyttäytymistä useita kertoja, mutta viimeisin merkittävä päivitys tapahtui Keras 2.1.3: ssa. Ennen v2.1.3, kun BN-kerros oli jäädytetty (traine = False), se jatkoi erätilastojensa päivittämistä, mikä aiheutti käyttäjille eeppisiä päänsärkyjä.

Tämä ei ollut vain outoa politiikkaa, se oli todella väärässä. Kuvittele, että konvoluutioiden välillä on BN-kerros; Jos kerros jäätyy, siihen ei pitäisi tapahtua muutoksia. Jos päivitämme osittain sen painot ja myös seuraavat kerrokset jäädytetään, he eivät koskaan saa mahdollisuutta mukautua mini-erätilastojen päivityksiin, mikä johtaa suurempaan virheeseen. Onneksi versiosta 2.1.3 alkaen, kun BN-kerros on jäädytetty, se ei enää päivitä tilastojaan. Mutta riittääkö se? Ei, jos käytät Transfer Learning -sovellusta.

Seuraavassa kuvailen tarkalleen, mikä on ongelma, ja luonnostelen teknisen toteutuksen sen ratkaisemiseksi. Annan myös muutamia esimerkkejä vaikutuksista mallin tarkkuuteen ennen ja jälkeen lappu sovelletaan.

2.1 Ongelman tekninen kuvaus

Kerasin nykyisen toteutuksen ongelmana on, että kun BN-kerros jäätyy, se jatkaa minierätilastojen käyttöä harjoittelun aikana. Uskon, että parempi tapa lähestyä BN: tä on jäädytetyn liikkuvan keskiarvon ja varianssin käyttö. Miksi? Samoista syistä miksi pienerätilastoja ei pitäisi päivittää, kun kerros jäädytetään: se voi johtaa huonoihin tuloksiin, koska seuraavia kerroksia ei ole koulutettu oikein.

Oletetaan, että rakennat Computer Vision -mallia, mutta sinulla ei ole tarpeeksi tietoa, joten päätät käyttää yhtä Keran valmiiksi koulutetusta CNN: stä ja hienosäätää sitä. Valitettavasti tekemällä niin et saa takuita siitä, että uuden tietojoukon keskiarvo ja varianssi BN-kerrosten sisällä ovat samanlaiset kuin alkuperäisessä tietoaineistossa. Muista, että tällä hetkellä verkkoharjoituksen aikana verkko käyttää aina minierätilastoja joko BN-kerros on jäädytetty tai ei; päättelet myös, että käytät aiemmin opittuja tilastotietoja jäädytetyistä BN-kerroksista. Seurauksena on, että kun hienosäädät ylimpiä kerroksia, niiden painot säädetään arvojen keskiarvoon / varianssiin uusi aineisto. Siitä huolimatta päättelyn aikana he vastaanottavat dataa, joka skaalataan eri tavalla koska keskimääräinen / varianssi alkuperäinen tietojoukkoa käytetään.
Kerasin eränormalisointikerros on rikki PlatoBlockchain Data Intelligence. Pystysuuntainen haku. Ai.
Edellä annan yksinkertaistetun (ja epärealistisen) arkkitehtuurin esittelytarkoituksiin. Oletetaan, että hienosäätämme mallia Convolution k + 1: stä verkon yläosaan (oikea puoli) ja pidämme pohjaan (vasen puoli) jäädytettynä. Harjoituksen aikana kaikki BN-kerrokset välillä 1 - k käyttävät harjoitustietojesi keskiarvoa / varianssia. Tällä on kielteisiä vaikutuksia jäädytettyihin ReLU: iin, jos kunkin BN: n keskiarvo ja varianssi eivät ole lähellä ennakkoharjoituksen aikana oppittuja. Se aiheuttaa myös muun verkon (CONV k + 1: stä ja uudemmasta) koulutuksen tuloilla, joilla on eri asteikot verrattuna siihen, mitä vastaanotetaan päätelmän aikana. Harjoituksen aikana verkkoasi voi mukautua näihin muutoksiin. Siitä huolimatta, kun siirryt ennustustilaan, Keras käyttää erilaisia ​​standardointitilastoja, mikä nopeuttaa seuraavien kerrosten tulojen jakautumista, mikä johtaa huonoihin tuloksiin.

2.2 Kuinka voit havaita, onko sinulla vaikutusta?

Yksi tapa havaita se on asettaa staattisesti Keran oppimisvaiheeksi 1 (junatila) ja 0 (testitila) ja arvioida mallisi kussakin tapauksessa. Jos saman aineiston tarkkuudessa on merkittäviä eroja, ongelma vaikuttaa sinuun. On syytä huomauttaa, että koska oppimisfaasin mekanismi toteutetaan Kerasissa, sitä ei yleensä suositella sietämään sitä. Learning_phasen muutoksilla ei ole vaikutusta malleihin, jotka on jo koottu ja käytetty; kuten voit nähdä seuraavien alajaksojen esimerkeistä, paras tapa tehdä tämä on aloittaa puhtaalla istunnolla ja muuttaa oppimisfaasia ennen kuin jokin tenori määritetään kuvaajassa.

Toinen tapa havaita ongelma binaariluokittimien kanssa työskennellessä on tarkistaa tarkkuus ja AUC. Jos tarkkuus on lähellä 50%, mutta AUC on lähellä yhtä (ja myös havaitset eroja junan / testimoodin välillä samassa tietojoukossa), voi olla, että todennäköisyydet ovat mittakaavan ulkopuolella BN-tilastojen takia. Vastaavasti regressioksi voit käyttää MSE: tä ja Spearmanin korrelaatiota sen havaitsemiseen.

2.3 Kuinka voimme korjata sen?

Uskon, että ongelma voidaan korjata, jos jäädytetyt BN-kerrokset ovat oikeasti juuri niin: pysyvästi lukittu testitilaan. Toteutuksen kannalta, koulutettavan lipun on oltava osa laskennallista kuvaajaa, ja BN: n käyttäytymisen on oltava riippuvainen paitsi oppimisfaasista myös koulutettavan ominaisuuden arvosta. Löydät yksityiskohdat toteutuksestani osoitteessa Github.

Kun yllä olevaa korjausta käytetään, kun BN-kerros on jäädytetty, se ei enää käytä minerätilastoja, vaan käyttää harjoittelun aikana opittuja. Seurauksena on, että harjoittelu- ja testitilojen välillä ei ole eroa, mikä johtaa suurempaan tarkkuuteen. Ilmeisesti kun BN-kerros ei ole jäätynyt, se jatkaa minierätilastojen käyttöä harjoittelun aikana.

2.4 Laastarin vaikutusten arviointi

Vaikka kirjoitin yllä mainitun toteutuksen äskettäin, sen taustalla olevaa ideaa testataan voimakkaasti reaalimaailman ongelmissa käyttämällä erilaisia ​​kiertotapoja, joilla on sama vaikutus. Esimerkiksi koulutus- ja testaustilojen välinen ero voidaan välttää jakamalla verkko kahteen osaan (jäädytetty ja jäädytetty) ja suorittamalla välimuistissa harjoittelu (siirtämällä tietoja kerran jäädytetyn mallin läpi ja käyttämällä niitä sitten jäädyttämättömän verkon kouluttamiseen). Siitä huolimatta, että ”luota minuun, olen tehnyt tämän aiemmin” ei yleensä ole painoarvoa, alla annan muutamia esimerkkejä, jotka osoittavat uuden täytäntöönpanon vaikutukset käytännössä.

Tässä on muutama tärkeä kohta kokeilusta:

  1. Käytän pienen määrän tietoa tarkoituksellisesti liikaa mallia varten ja koulutan ja validoin mallin samassa tietojoukossa. Näin tekemällä odotan melkein täydellistä tarkkuutta ja identtistä suorituskykyä juna- / validointitiedostossa.
  2. Jos validoinnin aikana saan huomattavasti alhaisemman tarkkuuden samassa aineistossa, minulla on selkeä merkki siitä, että nykyinen BN-käytäntö vaikuttaa negatiivisesti mallin suorituskykyyn päätelmien aikana.
  3. Esikäsittely tapahtuu generaattorien ulkopuolella. Tämä tehdään kiertämään vika, joka otettiin käyttöön v2.1.5: ssä (tällä hetkellä korjattu tulevassa v2.1.6: ssä ja viimeisimmässä masterissa).
  4. Me pakotamme Keran käyttämään erilaisia ​​oppimisvaiheita arvioinnin aikana. Jos havaitsemme eroja ilmoitetun tarkkuuden välillä, tiedämme, että nykyinen BN-käytäntö vaikuttaa meihin.

Kokeen koodi näkyy alla:

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

Tarkistetaan tulokset Keras v2.1.5: llä:

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]

Kuten yllä näemme, malli oppii harjoittelun aikana erittäin hyvin tiedot ja saavuttaa harjoitusjoukolla lähes täydellisen tarkkuuden. Silti jokaisen iteraation lopussa, kun arvioimme mallia samassa tietojoukossa, saamme merkittäviä eroja häviöissä ja tarkkuudessa. Huomaa, että meidän ei pidä saada tätä; Olemme asettaneet tarkoituksellisesti mallin tietyssä tietojoukossa ja koulutus- / validointitiedot ovat identtisiä.

Harjoituksen päätyttyä arvioimme mallin käyttämällä 3 erilaista oppimisvaihekokoonpanoa: Dynaaminen, Staattinen = 0 (testitila) ja Staattinen = 1 (Harjoitustila). Kuten voimme nähdä, ensimmäiset kaksi kokoonpanoa tuottavat identtisiä tuloksia häviön ja tarkkuuden suhteen ja niiden arvo vastaa mallin ilmoitettua tarkkuutta viimeisessä iteraatiossa asetetussa validoinnissa. Siitä huolimatta, kun siirrymme harjoittelutilaan, havaitaan valtava ero (parannus). Miksi se niin? Kuten aiemmin sanoimme, verkon painot on viritetty odottaen vastaanottavan dataa, joka on skaalattu harjoitustietojen keskiarvon / varianssin mukaan. Valitettavasti nämä tilastot eroavat BN-kerroksiin tallennetuista tilastoista. Koska BN-kerrokset olivat jäätyneet, näitä tilastoja ei koskaan päivitetty. Tämä ero BN-tilastojen arvojen välillä johtaa tarkkuuden heikkenemiseen päätelmän aikana.

Katsotaanpa mitä tapahtuu, kun sovellamme lappu:

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]

Ensinnäkin huomaamme, että verkko lähenee huomattavasti nopeammin ja saavuttaa täydellisen tarkkuuden. Näemme myös, että tarkkuudessa ei enää ole eroa, kun siirrymme eri learning_phase-arvojen välillä.

2.5 Kuinka korjaustiedosto toimii oikeassa aineistossa?

Joten miten laastari toimii realistisemmassa kokeessa? Käytämme Keran ennalta koulutettua ResNet50: tä (sovittiin alun perin imagenetiin), poista ylin luokittelukerros ja hienosäädä sitä korjaustiedoston kanssa ja ilman sitä ja vertaile tuloksia. Tietoja varten käytämme CIFAR10: tä (Kerasin toimittama vakiojuna / testijako) ja koon kokoa muutetaan 224 × 224, jotta ne olisivat yhteensopivia ResNet50: n syöttökoon kanssa.

Teemme 10 aikajaksoa kouluttaaksesi ylin luokittelukerroksen käyttämällä RSMprop-ohjelmaa, ja sitten teemme vielä 5 viritämme kaiken hienosäätöön kaiken 139. kerroksen jälkeen käyttämällä SGD: tä (lr = 1e-4, vauhti = 0.9). Ilman laastaria mallimme tarkkuus on 87.44%. Korjausta käyttämällä saadaan tarkkuus 92.36%, melkein 5 pistettä korkeampi.

2.6 Pitäisikö meidän soveltaa samaa korjausta muihin kerroksiin, kuten Dropoutiin?

Erän normalisointi ei ole ainoa kerros, joka toimii eri tavalla juna- ja testimoodien välillä. Myös keskeyttämisellä ja sen muunnoksilla on sama vaikutus. Pitäisikö meidän soveltaa samaa politiikkaa kaikkiin näihin kerroksiin? En usko, että (vaikka haluaisin kuulla ajatuksesi tästä). Syynä on se, että keskeyttämistä käytetään välttämään liiallinen asettaminen, joten sen lukitseminen pysyvästi ennustusmoodiin harjoittelun aikana menettäisi tavoitteen. Mitä mieltä sinä olet?

Uskon vahvasti, että tämä ristiriita on ratkaistava Kerasissa. Olen nähnyt vielä syvällisempiä vaikutuksia (100%: sta 50%: n tarkkuudella) reaalimaailman sovelluksissa, joita tämä ongelma aiheuttaa. minä aikoo lähettää jo lähettänyt PR Kerasille korjauksella ja toivottavasti se hyväksytään.

Jos pidit tästä blogipostista, jaa hetki jakaa se Facebookissa tai Twitterissä. 🙂

Aikaleima:

Lisää aiheesta Datumbox