BN是由Google于2015年提出,这是一个深度神经网络训练的技巧,它不仅可以加快了模型的收敛速度,而且更重要的是在一定程度缓解了深层网络中“梯度弥散”的问题,从而使得训练深层网络模型更加容易和稳定。所以目前BN已经成为几乎所有卷积神经网络的标配技巧了。
从字面意思看来Batch Normalization(简称BN)就是对每一批数据进行归一化,确实如此,对于训练中某一个batch的数据{x1,x2,...,xn},注意这个数据是可以输入也可以是网络中间的某一层输出。在BN出现之前,我们的归一化操作一般都在数据输入层,对输入的数据进行求均值以及求方差做归一化,但是BN的出现打破了这一个规定,我们可以在网络中任意一层进行归一化处理,因为我们现在所用的优化方法大多都是min-batch SGD,所以我们的归一化操作就成为Batch Normalization。
我们为什么需要BN
我们知道网络一旦train起来,那么参数就要发生更新,除了输入层的数据外(因为输入层数据,我们已经人为的为每个样本归一化),后面网络每一层的输入数据分布是一直在发生变化的,因为在训练的时候,前面层训练参数的更新将导致后面层输入数据分布的变化。以网络第二层为例:网络的第二层输入,是由第一层的参数和input计算得到的,而第一层的参数在整个训练过程中一直在变化,因此必然会引起后面每一层输入数据分布的改变。我们把网络中间层在训练过程中,数据分布的改变称之为:“Internal Covariate Shift”。BN的提出,就是要解决在训练过程中,中间层数据分布发生改变的情况。
BN怎么做
如上图所示,BN步骤主要分为4步:
- 1、求每一个训练批次数据的均值
- 2、求每一个训练批次数据的方差
- 3、使用求得的均值和方差对该批次的训练数据做归一化。其中ε是为了避免除数为0时所使用的微小正数。
- 4、尺度变换和偏移:将乘以调整数值大小,再加上增加偏移后得到,这里的是尺度因子,是平移因子。这一步是BN的精髓,由于归一化后的基本会被限制在正态分布下,使得网络的表达能力下降。为解决该问题,我们引入两个新的参数:,。 和是在训练时网络自己学习得到的,如果,而,那么就会恢复到之前的原数据。
BN的优势
BN对神经网络训练可谓是有诸多优点,可以分成以下几个方面:
-
解决内部协变量偏移
(最近一篇论文否定了BN是改善内部协变量偏移的观点,参考论文How Does Batch Normalization Help Optimization?)
如果单单是做了减均值除方差归一化的操作,那么就会像图中这样子,把输入数据框定在以0为中心的一块区域,在这一区域内绝大多数激活函数都会有一个问题:函数梯度变化程线性增长,不能保证对数据的非线性变换,从而影响数据表征能力,降低神经网络的作用。
sigmoid函数是这样,其他主流的激活函数也一样,如图:
BN的本质就是利用优化变一下方差大小和均值位置,使得新的分布更切合数据的真实分布,保证模型的非线性表达能力。BN的极端的情况就是这两个参数等于mini-batch的均值和方差,那么经过batch normalization之后的数据和输入的数据分布基本保持一致。
-
使得梯度变平缓
我们知道,如果梯度变得平缓后就可以使用大的学习率(learning rate),从而使得学习速度变快加速收敛到最优点的时间。
-
优化激活函数
可以看到,同样的激活函数,在使用BN与不使用BN有着明显的差异(虚线代表没有使用,实线代表使用),使用BN后能在更短的时间达到较稳定的状态。
-
增强优化器作用
同样,在增强优化器功效方面BN也有一定的作用,比较典型的是sigmoid函数,在没有使用BN之前它的迭代是震荡的,不稳定的,在使用了BN之后有了非常明显的提升。
-
解决梯度弥散问题
拿sigmoid和relu来举例,如果没有使用BN的话,第一层与第二层蓝色的曲线相差会很大,但是使用了BN的黄色曲线相差的值其实并不是很多了。
-
使模型具有正则化效果
采用BN算法后可以选择更小的L2正则约束参数,因为BN本身具有提高网络泛化能力的特性。
总结
使用BN会有以下几个优点:
- 解决内部协变量偏移
- 使得梯度变平缓
- 优化激活函数
- 解决梯度弥散问题
- 使模型正则化具有正则化效果
(各大深度学习框架在搭建网络时需要指定BN层)