我在哪里可以在Keras中调用BatchNormalization函数?

如果我想在Keras中使用BatchNormalization函数,那么我只需要在开始时调用它一次吗?

我读了这个文档: http : //keras.io/layers/normalization/

我不明白我应该怎么称呼它。 下面是我的代码试图使用它:

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) 

我问,因为如果我运行包括批规范化的第二行的代码,如果我没有第二行运行代码,我得到类似的输出。 所以要么我没有在正确的地方调用函数,要么我认为这并没有太大的区别。

为了更详细地回答这个问题,正如Pavel所说,批量标准化只是另一个层次,所以你可以使用它来创build你想要的networking体系结构。

一般用例是在networking中的线性和非线性图层之间使用BN,因为它将input标准化为激活函数,使得激活函数的线性部分(如Sigmoid)居中。 这里有一个小的讨论

在你的情况上面,这可能看起来像:


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

希望这个更清楚一点。

Conv2D后跟一个ReLu然后是一个BatchNormalization层,现在几乎成为一种趋势。 所以我编了一个小函数来一次调用所有这些函数。 使模型定义看起来更清晰,更易于阅读。

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

Keras现在支持bias=False选项,所以我们可以通过写入来节省一些计算

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

要么

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

这个线程是误导。 试图评论卢卡斯斋月的答案,但我没有正确的特权,所以我只是把这个在这里。

批处理规范化在激活函数之后效果最好, 这里或这里是为什么:它是为防止内部协variables移位而开发的。 当一个层的激活分布在整个训练过程中发生显着变化时,发生内部协variables转移。 批处理标准化被使用,使得到特定层的input(并且这些input实际上是激活函数的结果)的分布不会随着时间而改变,这是由于来自每批的参数更新(或者至less允许它改变以有利的方式)。 它使用批量统计来进行归一化,然后使用批量归一化参数(原文中的gamma和beta)“来确保插入到networking中的变换可以代表身份变换”(引自原文)。 但重点是我们试图规范input到一个图层,所以它应该总是在networking的下一层之前。 激活function之后是否依赖于所讨论的体系结构。

这个线程有一个很大的争议,就是BN是应该在当前层的非线性之前还是之前层的激活之前应用的。

虽然没有正确的答案,批量标准化的作者说, 它应该被应用在当前层的非线性之前。 原因(引自原文) –

“我们在非线性之前加上BN变换,通过归一化x = Wu + b。我们也可以将层inputu归一化,但是由于u很可能是另一个非线性的输出,所以它的分布形状可能在训练和约束它的一阶和二阶矩都不能消除协variables;相反,Wu + b更可能具有对称的非稀疏分布,即“更高斯”(Hyv-arinen&Oja,2000) ;正常化可能会产生稳定分布的激活。“

这是另一种types的图层,因此您应该将其添加为模型的适当位置中的图层

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

在这里看一个例子: https : //github.com/fchollet/keras/blob/master/examples/kaggle_otto_nn.py

Interesting Posts