A Keras Batch Normalization rétege megszakadt a PlatoBlockchain Data Intelligence. Függőleges keresés. Ai.

A Keras Batch Normalization rétege megszakadt

FRISSÍTÉS: Sajnos a Kerashoz intézett Pull-Request, amely megváltoztatta a Batch Normalization réteg viselkedését, nem fogadták el. A részleteket olvashatod itt. Azok számára, akik elég bátrak ahhoz, hogy egyedi megvalósításokkal vacakoljanak, megtalálhatják a kódot az ágam. Lehet, hogy karbantartom és egyesítem a Keras legújabb stabil verziójával (2.1.6, 2.2.2 és a 2.2.4) amíg használom, de nem ígérem.

A Deep Learningben dolgozók többsége már használta vagy hallott róla Keras. Azok számára, akik még nem, ez egy nagyszerű könyvtár, amely kivonatolja a mögöttes mély tanulási keretrendszereket, például a TensorFlow-t, a Theano-t és a CNTK-t, és magas szintű API ANN-ok képzéséhez. Könnyen használható, gyors prototípuskészítést tesz lehetővé, és barátságos, aktív közösséggel rendelkezik. Jó ideje sokat használom, és rendszeresen hozzájárulok a projekthez, és határozottan ajánlom mindenkinek, aki a Deep Learningen szeretne dolgozni.

Annak ellenére, hogy a Keras megkönnyítette az életemet, elég sokszor megharapott a Batch Normalization réteg furcsa viselkedése. Alapértelmezett viselkedése változott az idők során, ennek ellenére sok felhasználónak továbbra is problémákat okoz, és ennek eredményeként számos kapcsolódó probléma nyitott kérdések a Githubon. Ebben a blogbejegyzésben megpróbálok egy esetet felépíteni arra, hogy a Keras BatchNormalization rétege miért nem működik jól a Transfer Learninggel, megadom a kódot, amely kijavítja a problémát, és példákat hozok a folt.

Az alábbi alfejezetekben bemutatom, hogyan használják a Transfer Learninget a Deep Learningben, mi az a Batch Normalization réteg, hogyan működik a learning_phase, és hogyan változtatta meg Keras a BN viselkedését az idők során. Ha ezeket már ismeri, nyugodtan ugorjon közvetlenül a 2. részre.

1.1 A Transzfertanulás használata kulcsfontosságú a mélytanuláshoz

A Deep Learning egyik oka a múltban az, hogy túl sok adatot igényel. Ez nem mindig igaz; Számos technika létezik ennek a korlátozásnak a kezelésére, ezek egyike a transzfertanulás.

Tételezzük fel, hogy egy Computer Vision alkalmazáson dolgozik, és olyan osztályozót szeretne létrehozni, amely megkülönbözteti a macskákat a kutyáktól. Valójában nincs szükség több millió macska/kutya képre a modell betanításához. Ehelyett használhat egy előre betanított osztályozót, és kevesebb adattal finomhangolhatja a felső konvolúciókat. A mögöttes ötlet az, hogy mivel az előre betanított modell illeszkedett a képekhez, az alsó konvolúciók képesek felismerni az olyan jellemzőket, mint a vonalak, élek és más hasznos minták, ami azt jelenti, hogy használhatja a súlyait vagy jó inicializálási értékekként, vagy részben áttanítja a hálózatot az adatokkal. .
A Keras Batch Normalization rétege megszakadt a PlatoBlockchain Data Intelligence. Függőleges keresés. Ai.
A Keras számos előre betanított modellt és könnyen használható példát kínál a modellek finomhangolására. Bővebben olvashatsz a dokumentáció.

1.2 Mi az a Batch Normalization réteg?

A Batch Normalization réteget 2014-ben vezette be az Ioffe és a Szegedy. Az eltűnő gradiens problémát az előző réteg kimenetének szabványosításával kezeli, a szükséges iterációk számának csökkentésével felgyorsítja a betanítást és lehetővé teszi a mélyebb neurális hálózatok betanítását. A működésének pontos elmagyarázása túlmutat e bejegyzés keretein, de határozottan ajánlom, hogy olvassa el a eredeti papír. Egy túlságosan leegyszerűsített magyarázat az, hogy átskálázza a bemenetet úgy, hogy kivonja annak átlagát és osztja a szórásával; azt is megtanulhatja, hogy szükség esetén visszavonja az átalakítást.
A Keras Batch Normalization rétege megszakadt a PlatoBlockchain Data Intelligence. Függőleges keresés. Ai.

1.3 Mi az a tanulási_fázis a Kerasban?

Egyes rétegek eltérően működnek a képzés és a következtetési mód során. A legfigyelemreméltóbb példák a Batch Normalization és a Dropout rétegek. A BN esetében a betanítás során a mini batch átlagát és szórását használjuk a bemenet átskálázására. Másrészt a következtetés során a képzés során becsült mozgóátlagot és szórást használjuk.

A Keras tudja, melyik üzemmódban fut, mert van egy beépített mechanizmusa, az úgynevezett tanulási_fázis. A tanulási fázis szabályozza, hogy a hálózat vonat vagy teszt üzemmódban van-e. Ha a felhasználó nem állítja be kézzel, a fit() alatt a hálózat a learning_phase=1 értékkel fut (train mode). Az előrejelzések előállítása közben (például amikor a predikció() & value() metódusokat hívjuk, vagy a fit() érvényesítési lépésénél) a hálózat a learning_phase=0 értékkel fut (teszt mód). Bár ez nem ajánlott, a felhasználó statikusan is módosíthatja a learning_phase értéket egy adott értékre, de ennek meg kell történnie, mielőtt bármilyen modellt vagy tenzort hozzáadna a grafikonhoz. Ha a tanulási_fázis statikusan van beállítva, a Keras a felhasználó által kiválasztott módhoz zárolva lesz.

1.4 Hogyan valósította meg a Keras a kötegelt normalizálást az idő múlásával?

A Keras többször módosította a Batch Normalization viselkedését, de a legutóbbi jelentős frissítés a Keras 2.1.3-ban történt. A v2.1.3 előtt, amikor a BN réteg lefagyott (tanítható = hamis), folyamatosan frissítette a kötegelt statisztikát, ami óriási fejtörést okozott a felhasználóknak.

Ez nem csak egy furcsa politika volt, hanem valójában téves. Képzeljük el, hogy egy BN réteg létezik a konvolúciók között; ha a réteg lefagyott, nem történhet változás rajta. Ha részben frissítjük a súlyait, és a következő rétegek is lefagynak, soha nem lesz lehetőségük alkalmazkodni a mini-batch statisztikák frissítéséhez, ami nagyobb hibát eredményez. Szerencsére a 2.1.3-as verziótól kezdve a BN réteg lefagyása után már nem frissíti a statisztikáját. De vajon ez elég? Nem, ha Transfer Learninget használ.

Az alábbiakban leírom, hogy pontosan mi a probléma, és felvázolom a megoldás technikai megvalósítását. Néhány példát is bemutatok a modell pontosságára gyakorolt ​​hatások bemutatására az előtt és után folt alkalmazzák.

2.1 A probléma műszaki leírása

A Keras jelenlegi implementációjával az a probléma, hogy amikor egy BN réteg lefagy, a képzés során továbbra is a mini-batch statisztikákat használja. Úgy gondolom, hogy jobb megközelítés a BN lefagyott állapotában az, ha az edzés során tanult mozgó átlagot és szórást használjuk. Miért? Ugyanazok az okok miatt, amelyek miatt a mini-kötegelt statisztikákat nem szabad frissíteni, amikor a réteg lefagy: ez gyenge eredményekhez vezethet, mivel a következő rétegek nincsenek megfelelően betanítva.

Tegyük fel, hogy Computer Vision modellt épít, de nincs elég adata, ezért úgy dönt, hogy a Keras egyik előre betanított CNN-jét használja, és finomhangolja azt. Sajnos ezzel nem kap garanciát arra, hogy az új adatkészlet átlaga és szórása a BN rétegeken belül hasonló lesz az eredeti adatkészletéhez. Ne feledje, hogy jelenleg a képzés során a hálózata mindig a mini-kötegelt statisztikákat fogja használni, vagy a BN réteg le van fagyva, vagy sem; a következtetés során is a lefagyasztott BN rétegek korábban tanult statisztikáit fogja használni. Ennek eredményeként, ha finomhangolja a felső rétegeket, a súlyuk a új adatkészlet. Ennek ellenére a következtetés során skálázott adatokat kapnak eltérően mert az átlag/szórás a eredeti adatkészlet kerül felhasználásra.
A Keras Batch Normalization rétege megszakadt a PlatoBlockchain Data Intelligence. Függőleges keresés. Ai.
Fent bemutatok egy leegyszerűsített (és irreális) architektúrát demonstrációs célokra. Tegyük fel, hogy a k+1 konvolúcióból felfelé finomhangoljuk a modellt a hálózat tetejéig (jobb oldal), és az alját (bal oldal) fagyasztva tartjuk. A képzés során az összes BN réteg 1-től k-ig az edzési adatok átlagát/varianciáját fogja használni. Ez negatív hatással lesz a lefagyott ReLU-kra, ha az egyes BN-ek átlaga és variancia nem közelíti meg az előképzés során tanultakat. Ezenkívül a hálózat többi részét (a CONV k+1-től és későbbitől kezdve) olyan bemenetekkel kell betanítani, amelyek eltérő léptékűek ahhoz képest, amit a következtetés során kap. A képzés során a hálózat képes alkalmazkodni ezekhez a változásokhoz, mindazonáltal abban a pillanatban, amikor előrejelzési módra vált, a Keras különböző szabványosítási statisztikákat fog használni, ami felgyorsítja a következő rétegek bemeneteinek elosztását, ami rossz eredményekhez vezet.

2.2 Hogyan észlelheti, ha érintett?

Az észlelés egyik módja az, hogy statikusan állítja be a Keras tanulási fázisát 1-re (tanulási mód) és 0-ra (teszt mód), és minden esetben értékeli a modellt. Ha ugyanabban az adatkészletben jelentős eltérések vannak a pontosságban, akkor Önt érinti a probléma. Érdemes kiemelni, hogy a Keras tanulási_fázisú mechanizmusának megvalósítása miatt jellemzően nem tanácsos ezzel foglalkozni. A tanulási_fázisban végrehajtott változtatások nem lesznek hatással a már összeállított és használt modellekre; Amint azt a következő alfejezetekben szereplő példák is láthatják, a legjobb módja ennek az, ha tiszta munkamenettel kezdjük, és megváltoztatjuk a learning_phase értéket, mielőtt bármely tenzort meghatároznánk a grafikonon.

A probléma észlelésének másik módja a bináris osztályozókkal végzett munka során a pontosság és az AUC ellenőrzése. Ha a pontosság közel 50%, de az AUC közel 1 (és ugyanabban az adatkészletben különbségeket figyel meg a vonat/teszt üzemmódok között), akkor előfordulhat, hogy a valószínűségek skálán kívül esnek a BN statisztikák miatt. Hasonlóképpen, a regresszióhoz használhatja az MSE és a Spearman-féle korrelációt a kimutatására.

2.3 Hogyan javíthatjuk?

Úgy gondolom, hogy a probléma megoldható, ha a lefagyott BN rétegek valójában csak ilyenek: tartósan zárolva teszt módban. Megvalósítási szempontból a betanítható jelzőnek a számítási gráf részének kell lennie, és a BN viselkedésének nemcsak a tanulási_fázistól kell függnie, hanem a betanítható tulajdonság értékétől is. Megvalósításom részleteit itt találod GitHub.

A fenti javítás alkalmazásával, amikor egy BN réteg lefagy, többé nem használja a mini-batch statisztikákat, hanem a képzés során tanultakat. Ennek eredményeként nem lesz eltérés az edzési és a tesztmódok között, ami nagyobb pontosságot eredményez. Nyilvánvalóan, ha a BN réteg nincs lefagyva, továbbra is használja a mini-batch statisztikákat a képzés során.

2.4 A tapasz hatásainak felmérése

Annak ellenére, hogy a fenti megvalósítást nemrég írtam, a mögötte meghúzódó ötletet alaposan tesztelték valós problémákon, különféle, azonos hatású megoldásokkal. Például a betanítási és a tesztelési módok közötti eltérés elkerülhető, ha a hálózatot két részre osztjuk (befagyasztott és feloldott), és gyorsítótárazott betanítást hajtunk végre (egyszer átengedjük az adatokat a lefagyott modellen, majd ezek segítségével betanítjuk a feloldott hálózatot). Mindazonáltal, mivel a „bízz bennem, én már csináltam ilyet” jellemzően súlytalan, az alábbiakban bemutatok néhány példát, amelyek bemutatják az új megvalósítás gyakorlati hatásait.

Íme néhány fontos szempont a kísérlettel kapcsolatban:

  1. Kis mennyiségű adatot fogok felhasználni a modell szándékos túlillesztésére, és ugyanazon az adatkészleten fogom betanítani és validálni a modellt. Ezáltal szinte tökéletes pontosságot és azonos teljesítményt várok el a vonat/ellenőrzési adatkészleten.
  2. Ha a validálás során lényegesen kisebb pontosságot kapok ugyanarra az adathalmazra, akkor egyértelműen jelezni fogom, hogy a jelenlegi BN házirend negatívan befolyásolja a modell teljesítményét a következtetés során.
  3. Minden előfeldolgozás a Generátorokon kívül történik. Ezzel a 2.1.5-ös verzióban (jelenleg a közelgő v2.1.6-on és a legújabb mesterverzión javítva) bevezetett hiba megkerülésére szolgál.
  4. Arra kényszerítjük a Kerast, hogy az értékelés során különböző tanulási fázisokat alkalmazzon. Ha különbségeket észlelünk a jelentett pontosság között, tudni fogjuk, hogy a jelenlegi BN-szabályzat érint bennünket.

A kísérlet kódja alább látható:

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

Nézzük meg a Keras v2.1.5 eredményeit:

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]

Mint fentebb láthattuk, a modell a képzés során nagyon jól megtanulja az adatokat, és a betanítási halmazon közel tökéletes pontosságot ér el. Még mindig minden iteráció végén, miközben a modellt ugyanazon az adatkészleten értékeljük, jelentős különbségeket kapunk a veszteségben és a pontosságban. Jegyezzük meg, hogy ezt nem kellene megkapnunk; szándékosan túlillesztettük a modellt az adott adatkészleten, és a betanítási/érvényesítési adatkészletek azonosak.

A képzés befejezése után 3 különböző tanulási fázis konfigurációval értékeljük a modellt: dinamikus, statikus = 0 (teszt mód) és statikus = 1 (képzési mód). Amint látjuk, az első két konfiguráció azonos eredményeket fog adni a veszteség és a pontosság tekintetében, és értékük megegyezik a modell jelentett pontosságával az utolsó iterációban az érvényesítési halmazban. Mindazonáltal, ha edzésmódra váltunk, hatalmas eltérést (javulást) figyelünk meg. Miért ez? Amint azt korábban említettük, a hálózat súlyait úgy hangolják, hogy a képzési adatok átlagával/varianciájával skálázott adatokat kapjanak. Sajnos ezek a statisztikák eltérnek a BN rétegekben tároltaktól. Mivel a BN rétegek lefagytak, ezeket a statisztikákat soha nem frissítették. Ez az eltérés a BN statisztika értékei között a következtetés során a pontosság romlásához vezet.

Lássuk, mi történik, ha alkalmazzuk a folt:

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]

Először is azt figyeljük meg, hogy a hálózat lényegesen gyorsabban konvergál és tökéletes pontosságot ér el. Azt is látjuk, hogy a pontosság tekintetében már nincs eltérés, amikor a különböző tanulási_fázis értékek között váltunk.

2.5 Hogyan működik a javítás valódi adatkészleten?

Tehát hogyan teljesít a javítás egy valósághűbb kísérletben? Használjuk a Keras előre betanított ResNet50-et (eredetileg illeszkedik az imagenetre), távolítsuk el a legfelső osztályozási réteget, és finomhangoljuk a javítással és anélkül, és hasonlítsuk össze az eredményeket. Az adatokhoz a CIFAR10-et (a Keras által biztosított szabványos vonat/teszt felosztás) fogjuk használni, és a képeket 224×224-re méretezzük át, hogy kompatibilisek legyenek a ResNet50 bemeneti méretével.

10 epochát végzünk a legfelső osztályozási réteg betanítására az RSMprop segítségével, majd további 5-öt, hogy mindent finomhangoljunk a 139. réteg után az SGD(lr=1e-4, momentum=0.9) használatával. Patch nélkül a modellünk 87.44%-os pontosságot ér el. A patch használatával 92.36%-os pontosságot kapunk, ami közel 5 ponttal magasabb.

2.6 Alkalmazzuk ugyanezt a javítást más rétegekre, például a Dropoutra?

A kötegelt normalizálás nem az egyetlen réteg, amely eltérően működik a vonat és a teszt üzemmódok között. A lemorzsolódás és változatai is hasonló hatást fejtenek ki. Ugyanazt a politikát kell alkalmaznunk ezekre a rétegekre? Nem hiszem el (bár szívesen hallanám ezzel kapcsolatos gondolatait). Ennek az az oka, hogy a Dropout-ot a túlillesztés elkerülésére használják, így ha edzés közben véglegesen előrejelzési módba zárnák, az elveszítené a célját. Mit gondolsz?

Erősen hiszek abban, hogy ezt az eltérést a Kerasban meg kell oldani. Még mélyebb hatásokat láttam (100%-tól egészen 50%-os pontosságig) a valós alkalmazásokban, amelyeket ez a probléma okozott. én tervezi küldeni már elküldte a PR Kerasnak a javítással és remélhetőleg elfogadják.

Ha tetszett ez a blogbejegyzés, kérlek, oszd meg Facebookon vagy Twitteren. 🙂

Időbélyeg:

Még több Datumbox