前言
我们知道在神经网络训练开始前,都要对输入数据做一个归一化处理,那么为什么需要归一化呢?原因就在于神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;另外一方面,一旦每批训练数据的分布各不相同,那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度。
对于深度神经网络的训练是一个复杂的过程,只要网络的前面几层发生微小的改变,那么后面几层就会被累积放大下去。一旦网络某一层的输入数据的分布发生改变,那么这一层网络就需要去适应学习这个新的数据分布,所以如果训练过程中,训练数据的分布一直在发生变化,那么将会影响网络的训练速度。
网络一旦训练起来,参数就要发生更新,除了输入层的数据外(因为输入层数据已经被人为地进行归一化了),后面网络每一层的输入数据分布是一直在发生变化的,因为在训练时前面层训练参数的更新将导致后面层输入数据分布的变化。举个例子,网络的第二层输入是由第一层的参数和input计算得到的,而第一层的参数在整个训练过程中一直在变化,因此必然会引起后面每一层输入数据分布的改变。我们把网络中间层在训练过程中,数据分布的改变称之为“Internal Covariate Shift”。为了解决在训练过程中,中间层数据分布发生改变的情况,Batch Normalization诞生了。
BN层
就像激活层、卷积层、全连接层、池化层一样,BN层也属于网络的一层。在前面我们提到网络除了输出层外,其它层因为低层网络在训练的时候更新了参数,而引起后面层输入数据分布的变化。这个时候我们就会想,如果在每一层输入的时候,再加个预处理操作那该有多好啊,比如说归一化一下,这样我们就可以解决前面所提的“Internal Covariate Shift”的问题了。
而事实上,paper的算法本质原理就是这样:在网络的每一层输入的时候,又插入了一个归一化层,也就是先做一个归一化处理,然后再进入网络的下一层。不过这里的归一化层,可不像我们想象的那么简单,它是一个可学习、有参数的网络层。
其中,
标准差归一化结果,即
、
为学习参数。
参考文献https://arxiv.org/abs/1502.03167arxiv.org标准化层 Normalization - Keras 中文文档keras.io