Waar roep ik de functie BatchNormalization in Keras aan?

Als ik de BatchNormalization-functie in Keras wil gebruiken, moet ik deze dan in het begin maar één keer aanroepen?

Ik heb er deze documentatie voor gelezen: http://keras.io/layers/normalization/

Ik zie niet waar ik het moet noemen. Hieronder is mijn code die het probeert te gebruiken:

model = Sequential()
keras.layers.normalization.BatchNormalization(epsilon=1e-06, mode=0, momentum=0.9, weights=None)
model.add(Dense(64, input_dim=14, init='uniform'))
model.add(Activation('tanh'))
model.add(Dropout(0.5))
model.add(Dense(64, init='uniform'))
model.add(Activation('tanh'))
model.add(Dropout(0.5))
model.add(Dense(2, init='uniform'))
model.add(Activation('softmax'))
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='binary_crossentropy', optimizer=sgd)
model.fit(X_train, y_train, nb_epoch=20, batch_size=16, show_accuracy=True, validation_split=0.2, verbose = 2)

Ik vraag het, want als ik de code uitvoer met de tweede regel inclusief de batchnormalisatie en als ik de code zonder de tweede regel uitvoer, krijg ik vergelijkbare resultaten. Dus of ik roep de functie niet op de juiste plaats aan, of ik denk dat het niet zo’n groot verschil maakt.


Antwoord 1, autoriteit 100%

Om deze vraag wat gedetailleerder te beantwoorden, en zoals Pavel al zei, Batch Normalisatie is gewoon een andere laag, dus je kunt het als zodanig gebruiken om de gewenste netwerkarchitectuur te creëren.

Het algemene gebruiksscenario is om BN te gebruiken tussen de lineaire en niet-lineaire lagen in uw netwerk, omdat het de invoer naar uw activeringsfunctie normaliseert, zodat u gecentreerd bent in het lineaire gedeelte van de activeringsfunctie (zoals sigmoïd). Er is een kleine discussie over hier

In jouw geval hierboven kan dit er als volgt uitzien:


# import BatchNormalization
from keras.layers.normalization import BatchNormalization
# instantiate model
model = Sequential()
# we can think of this chunk as the input layer
model.add(Dense(64, input_dim=14, init='uniform'))
model.add(BatchNormalization())
model.add(Activation('tanh'))
model.add(Dropout(0.5))
# we can think of this chunk as the hidden layer    
model.add(Dense(64, init='uniform'))
model.add(BatchNormalization())
model.add(Activation('tanh'))
model.add(Dropout(0.5))
# we can think of this chunk as the output layer
model.add(Dense(2, init='uniform'))
model.add(BatchNormalization())
model.add(Activation('softmax'))
# setting up the optimization of our weights 
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='binary_crossentropy', optimizer=sgd)
# running the fitting
model.fit(X_train, y_train, nb_epoch=20, batch_size=16, show_accuracy=True, validation_split=0.2, verbose = 2)

Ik hoop dat dit de zaken wat meer verduidelijkt.


Antwoord 2, autoriteit 27%

Deze thread is misleidend. Ik heb geprobeerd commentaar te geven op het antwoord van Lucas Ramadan, maar ik heb nog niet de juiste rechten, dus plaats ik dit hier.

Batchnormalisatie werkt het beste na de activeringsfunctie, en hierof hieris waarom: het is ontwikkeld om interne covariabele verschuiving te voorkomen. Interne covariabele verschuiving treedt op wanneer de verdeling van de activeringenvan een laag aanzienlijk verschuift tijdens de training. Batch-normalisatie wordt gebruikt zodat de distributie van de inputs (en deze inputs zijn letterlijk het resultaat van een activeringsfunctie) naar een specifieke laag niet verandert in de tijd als gevolg van parameterupdates van elke batch (of op zijn minst laat veranderen op een voordelige manier). Het gebruikt batchstatistieken om de normalisatie uit te voeren en gebruikt vervolgens de batchnormalisatieparameters (gamma en bèta in de originele paper) “om ervoor te zorgen dat de transformatie die in het netwerk is ingevoegd de identiteitstransformatie kan vertegenwoordigen” (citaat uit originele paper). Maar het punt is dat we proberen de invoer naar een laag te normaliseren, dus het moet altijd direct voor de volgende laag in het netwerk gaan. Of dat na een activeringsfunctie is, hangt af van de betreffende architectuur.


Antwoord 3, autoriteit 20%

Deze thread heeft een behoorlijke discussie gevoerd over de vraag of BN moet worden toegepast vóór niet-lineariteit van de huidige laag of op de activeringen van de vorige laag.

Hoewel er geen juist antwoord is, zeggen de auteurs van Batch Normalization dat:
Het moet onmiddellijk vóór de niet-lineariteit van de huidige laag worden toegepast.De reden (geciteerd uit origineel papier) –

“We voegen de BN-transformatie toe direct voor de
niet-lineariteit, door x = Wu+b te normaliseren. We zouden kunnen hebben
heeft ook de laag-invoer u genormaliseerd, maar aangezien u waarschijnlijk is
de output van een andere niet-lineariteit, de vorm van zijn verdeling
zal waarschijnlijk veranderen tijdens de training, en beperkend
zijn eerste en tweede moment zouden de covariaat niet elimineren
verschuiving. Daarentegen heeft Wu + b meer kans om
een symmetrische, niet-dunne verdeling, dat is “meer Gaussiaans”
(Hyv¨arinen & Oja, 2000); normaliseren is waarschijnlijk
activaties produceren met een stabiele distributie.”


Antwoord 4, autoriteit 13%

Het is nu bijna een trend geworden om een ​​Conv2Dgevolgd door een ReLugevolgd door een BatchNormalization-laag te hebben. Dus verzon ik een kleine functie om ze allemaal tegelijk aan te roepen. Zorgt ervoor dat de modeldefinitie er een stuk schoner en gemakkelijker leesbaar uitziet.

def Conv2DReluBatchNorm(n_filter, w_filter, h_filter, inputs):
    return BatchNormalization()(Activation(activation='relu')(Convolution2D(n_filter, w_filter, h_filter, border_mode='same')(inputs)))

Antwoord 5, autoriteit 13%

Keras ondersteunt nu de optie use_bias=False, dus we kunnen wat rekenwerk besparen door te schrijven als

model.add(Dense(64, use_bias=False))
model.add(BatchNormalization(axis=bn_axis))
model.add(Activation('tanh'))

of

model.add(Convolution2D(64, 3, 3, use_bias=False))
model.add(BatchNormalization(axis=bn_axis))
model.add(Activation('relu'))

Antwoord 6, autoriteit 3%

Batchnormalisatie wordt gebruikt om zowel de invoerlaag als de verborgen lagen te normaliseren door het gemiddelde en de schaal van de activeringen aan te passen. Vanwege dit normaliserende effect met een extra laag in diepe neurale netwerken, kan het netwerk een hogere leersnelheid gebruiken zonder dat gradiënten verdwijnen of exploderen. Bovendien regulariseert batchnormalisatie het netwerk zodat het gemakkelijker te generaliseren is, en het is dus niet nodig om drop-out te gebruiken om overfitting tegen te gaan.

Direct na het berekenen van de lineaire functie met behulp van bijvoorbeeld de Dense() of Conv2D() in Keras, gebruiken we BatchNormalization() die de lineaire functie in een laag berekent en vervolgens voegen we de niet-lineariteit toe aan de laag met behulp van Activation( ).

from keras.layers.normalization import BatchNormalization
model = Sequential()
model.add(Dense(64, input_dim=14, init='uniform'))
model.add(BatchNormalization(epsilon=1e-06, mode=0, momentum=0.9, weights=None))
model.add(Activation('tanh'))
model.add(Dropout(0.5))
model.add(Dense(64, init='uniform'))
model.add(BatchNormalization(epsilon=1e-06, mode=0, momentum=0.9, weights=None))
model.add(Activation('tanh'))
model.add(Dropout(0.5))
model.add(Dense(2, init='uniform'))
model.add(BatchNormalization(epsilon=1e-06, mode=0, momentum=0.9, weights=None))
model.add(Activation('softmax'))
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='binary_crossentropy', optimizer=sgd)
model.fit(X_train, y_train, nb_epoch=20, batch_size=16, show_accuracy=True, 
validation_split=0.2, verbose = 2)

Hoe wordt batchnormalisatie toegepast?

Stel dat we a[l-1] hebben ingevoerd in een laag l. We hebben ook gewichten W[l] en bias-eenheid b[l] voor de laag l. Laat a[l] de activeringsvector zijn die wordt berekend (d.w.z. na het optellen van de niet-lineariteit) voor de laag l en z[l] de vector zijn voordat de niet-lineariteit wordt toegevoegd

  1. Met a[l-1] en W[l] kunnen we z[l] berekenen voor de laag l
  2. Meestal voegen we bij feed-forward propagatie een bias-eenheid toe aan de z[l] in dit stadium zoals deze z[l]+b[l], maar in Batch Normalization is deze stap van toevoeging van b[l] niet vereist en er wordt geen b[l] parameter gebruikt.
  3. Bereken z[l] middelen en trek deze af van elk element
  4. Verdeel (z[l] – gemiddelde) met behulp van standaarddeviatie. Noem het Z_temp[l]
  5. Definieer nu nieuwe parameters γ en β die de schaal van de verborgen laag als volgt zullen veranderen:

    z_norm[l] = γ.Z_temp[l] + β

In dit codefragment neemt de Dense() de a[l-1], gebruikt W[l] en berekent z[l]. Dan zal de directe BatchNormalization() de bovenstaande stappen uitvoeren om z_norm[l] te geven. En dan zal de onmiddellijke Activation() tanh(z_norm[l]) berekenen om a[l] te geven, d.w.z.

a[l] = tanh(z_norm[l])

Antwoord 7, autoriteit 2%

Het is een ander type laag, dus u moet het als een laag op een geschikte plaats van uw model toevoegen

model.add(keras.layers.normalization.BatchNormalization())

Bekijk hier een voorbeeld: https://github.com/fchollet /keras/blob/master/examples/kaggle_otto_nn.py


Antwoord 8

Nog een item toevoegen voor het debat over de vraag of batchnormalisatie moet worden aangeroepen voor of na de niet-lineaire activering:

In aanvulling op het originele artikel met batchnormalisatie vóór de activering, is Bengio’s boek Deep Learning, sectie 8.7.1geeft enige reden waarom het toepassen van batchnormalisatie na de activering (of direct voor de invoer naar de volgende laag) problemen kan veroorzaken:

Het is logisch dat we ons afvragen of we batchnormalisatie moeten toepassen op:
de ingang X, of naar de getransformeerde waarde XW+b. Ioffe en Szegedy (2015)
beveel het laatste aan. Meer specifiek moet XW+b worden vervangen door a
genormaliseerde versie van XW. De bias-term moet worden weggelaten omdat het
wordt overbodig met de βparameter toegepast door de batch
normalisatie herparametrisering. De invoer voor een laag is meestal de
uitvoer van een niet-lineaire activeringsfunctie zoals de gerectificeerde lineaire
functie in een vorige laag. De statistieken van de invoer zijn dus:
meer niet-Gaussiaans en minder vatbaar voor standaardisatie door lineaire
operaties.

Met andere woorden, als we een relu-activering gebruiken, worden alle negatieve waarden toegewezen aan nul. Dit zal waarschijnlijk resulteren in een gemiddelde waarde die al heel dicht bij nul ligt, maar de verdeling van de resterende gegevens zal sterk naar rechts scheef zijn. Proberen om die gegevens te normaliseren tot een mooie klokvormige curve zal waarschijnlijk niet de beste resultaten opleveren. Voor activeringen buiten de relu-familie is dit misschien niet zo’n groot probleem.

Houd er rekening mee dat er rapporten zijn van modellen die betere resultaten behalen bij het gebruik van batchnormalisatie na de activering, terwijl andere de beste resultaten behalen wanneer de batchnormalisatie vóór de activering wordt geplaatst. Het is waarschijnlijk het beste om uw model te testen met beide configuraties, en als batchnormalisatie na activering een significante vermindering van validatieverlies geeft, gebruik dan die configuratie.

Other episodes