バッチ正規化は、アクティベーションの平均とスケーリングを調整することにより、入力レイヤーと非表示レイヤーを正規化するために使用されます。ディープニューラルネットワークの追加レイヤーによるこの正規化効果により、ネットワークは勾配を消失または爆発させることなく、より高い学習率を使用できます。さらに、バッチ正規化によりネットワークが正規化され、一般化が容易になるため、ドロップアウトを使用して過剰適合を緩和する必要がありません。
KerasのDense()またはConv2D()などを使用して線形関数を計算した直後に、レイヤーの線形関数を計算するBatchNormalization()を使用し、次に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)
バッチ正規化はどのように適用されますか?
レイヤーlにa [l-1]を入力したとします。また、レイヤーlには重みW [l]とバイアス単位b [l]があります。a [l]をレイヤーlに対して計算された(つまり、非線形性を追加した後の)アクティベーションベクトルとし、z [l]を非線形性を追加する前のベクトルとします。
- a [l-1]とW [l]を使用して、レイヤーlのz [l]を計算できます
- 通常、フィードフォワード伝播では、この段階でz [l] + b [l]のようにz [l]にバイアス単位を追加しますが、バッチ正規化では、b [l]を追加するこの手順は不要であり、 b [l]パラメータが使用されます。
- z [l]平均を計算し、それを各要素から減算します
- 標準偏差を使用して(z [l]-平均)を割ります。それをZ_temp [l]と呼びます
次に、次のように非表示レイヤーのスケールを変更する新しいパラメーターγとβを定義します。
z_norm [l] =γ.Z_temp[l] +β
このコードの抜粋では、Dense()はa [l-1]を取得し、W [l]を使用してz [l]を計算します。次に、即時のBatchNormalization()は上記の手順を実行してz_norm [l]を提供します。そして、即時のActivation()はtanh(z_norm [l])を計算してa [l]を与えます。すなわち
a[l] = tanh(z_norm[l])