BN层的学习

   BN层,顾名思义嘛,就是归一化的作用,在深度学习里很常用,这里来简要梳理一下BN层的相关知识.

1 BN层引出的目的

   神经网络在进行训练时,主要是用来学习数据的分布规律,如果数据的训练部分和测试部分分布不一样,那么网络的泛化能力会变得非常差.而且对于训练的数据,每批分布也是不一样的,那么网络在迭代的过程中也要学习和适应不同的分布.这会大大降低网络的训练速度.此外,数据的分布对于激活函数来说也非常重要,有时数据分布范围太大不利于利用激活函数的非线性特性.一个例子如下图所示:

   可以看出,未进行归一化的数据可能很多部分位于该损失函数的饱和区,从而导致输出的结果非常接近,不利于网络的学习.

2 BN层的概念

   针对于归一化的问题,《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》提出可以在网络的每一层设立一个归一化层,对数据进行归一化处理,然后再送入下一层.BN层的前向传播过程如下所示(m表示mini batch大小):

   (4)式的输出结果就是BN层的输出结果.所以BN层实际学习的是缩放系数$\gamma$和偏移系数$\beta$,从而使网络去学习输出的特征分布.在实际测试中,我们只输入一个测试样本时,此时没有mini batch这个概念了,其他参数如均值和标准差都是固定不变的,即测试时均值和标准差的公式为:

   也就是说,测试时均值采用训练中u值的均值,标准差采用训练中标准差的无偏估计.所以最终测试时,BN使用的公式是:

   BN层置于激活函数的前面.在使用过程中,BN层的参数是针对整个特征图进行的,也就是说,BN层是求一个特征图所有神经元的均值和方差,对特征图的神经元做归一化.

3 BN层的实现

   tensorflow里使用BN层的api如下

1
def batch_normalization(x, mean, variance, offset, scale, variance_epsilon, name=None):

   x是输入,mean是均值,variance是方差,offset是偏移$\beta$(默认为0),scale是缩放系数$\gamma$(默认为1),variance_epsilon为$\epsilon$,调用这个api就可以输出BN后的结果.
另一个实现BN操作的api是tf.contrib.layers.batch_norm()函数,详情可见:https://www.tensorflow.org/api_docs/python/tf/contrib/layers/batch_norm

0%