BN:总的来说,BN通过将每一层网络的输入进行normalization,保证输入分布的均值与方差固定在一定范围内,减少了网络中的Internal Covariate Shift问题,并在一定程度上缓解了梯度消失,加速了模型收敛;并且BN使得网络对参数、激活函数更加具有鲁棒性,降低了神经网络模型训练和调参的复杂度;最后BN训练过程中由于使用mini-batch的mean/variance每次都不同,引入了随机噪声,在一定程度上对模型起到了正则化的效果。
Normalization
字面上意思就是标准化,也就是对输入的数据做标准化,可以用下面的公式表示(这里 代表输入数据, n代表训练集大小):
以上可以看出, 标准化以后的数据服从均值为0,方差为1的正态分布
为什么要进行Normalization?
在介绍BN之前,先说说为什么要进行Normalization
在神经网络中, 数据分布对训练会产生影响. 比如某个神经元 x 的值为1, 某个 Weights 的初始值为 0.1, 这样后一层神经元计算结果就是 Wx = 0.1; 又或者 x = 20, 这样 Wx 的结果就为 2. 现在还不能看出什么问题, 但是, 当我们加上一层激励函数, 激活这个 Wx 值的时候, 问题就来了. 如果使用 像 tanh 的激励函数, Wx 的激活值就变成了 ~0.1 和 ~1, 接近于 1 的部已经处在了 激励函数的饱和阶段, 也就是如果 x 无论再怎么扩大, tanh 激励函数输出值也还是接近1. 换句话说, 神经网络在初始阶段已经不对那些比较大的 x 特征范围 敏感了. 这样很糟糕, 想象我轻轻拍自己的感觉和重重打自己的感觉居然没什么差别, 这就证明我的感官系统失效了. 当然我们是可以用之前提到的对数据做 normalization 预处理, 使得输入的 x 变化范围不会太大, 让输入值经过激励函数的敏感部分. 但刚刚这个不敏感问题不仅仅发生在神经网络的输入层, 而且在隐藏层中也经常会发生.
Normalization的效果:
如上图,当没有进行normalizatin时,数据的分布是任意的,那么就会有大量的数据处在激活函数的敏感区域外, 对这样的数据分布进行激活后, 大部分的值都会变成1或-1,造成激活后的数据分布不均衡,而如果进行了Normallizatin, 那么相对来说数据的分布比较均衡,如下图所示:
一句话总结就是: 通过Normalization让数据的分布始终处在激活函数敏感的区域
BN的提出背景
https://zhuanlan.zhihu.com/p/34879333
Internal Covariate Shift
Covariate [kʌ'veərɪrt]
什么是Internal Covariate Shift:
在深层网络训练的过程中,由于网络中参数变化而引起内部结点数据分布发生变化的这一过程被称作Internal Covariate Shift。
带来了什么问题:
- 上层网络需要不停调整来适应输入数据分布的变化,导致网络学习速度的降低
- 网络的训练过程容易陷入梯度饱和区,减缓网络收敛速度
如何减缓Internal Covariate Shift:
(1)白化(PCA白化和ZCA白化):
- 使得输入特征分布具有相同的均值与方差
- 取出特征之间的相关性
- 通过白化操作,我们可以减缓ICS的问题,进而固定了每一层网络输入分布,加速网络训练过程的收敛
白化缺点:
- 白化过程计算成本太高,并且在每一轮训练中的每一层我们都需要做如此高成本计算的白化操作;
- 白化过程由于改变了网络每一层的分布,因而改变了网络层中本身数据的表达能力。底层网络学习到的参数信息会被白化操作丢失掉。
于是就提出了BN
什么是Batch Normalization
传统的Normalization使用的均值和方差是整个训练集的均值和方差, 并且只对输入层的数据做归一化, 而Batch Normalization按字面意思就是对每一批数据进行归一化, 同时会对每一层输入做归一化, 所以, 首先要将传统的标准化中的n改为m, m表示一个batch的大小,如下所示:
传统的Normalization直接使用了减均值除方差的方式来进行标准化, 但是, 这样一概而全的方法未必对所有数据来说就是最优的, 比如数据本身就不对称, 或者激活函数未必对方差为1的数据有最好的效果, 所以, BN的想法是在传统标准化之后再加上一个线性变换,如下所示:
其中, 和 是两个需要学习的参数, ** 可以看出, BN的本质就是利用参数优化来改变一下数据分布的方差大小和均值的位置. **
BN的优点
(1)BN使得网络中每层输入数据的分布相对稳定,加速模型学习速度
(2)BN使得模型对初始化方法和网络中的参数不那么敏感,简化调参过程,使得网络学习更加稳定
(3)BN允许网络使用饱和性激活函数(例如sigmoid,tanh等),缓解梯度消失问题
(4)BN具有一定的正则化效果
原因如下:
(1)BN使得网络中每层输入数据的分布相对稳定,加速模型学习速度
BN通过规范化与线性变换使得每一层网络的输入数据的均值与方差都在一定范围内,使得后一层网络不必不断去适应底层网络中输入的变化,从而实现了网络中层与层之间的解耦,更加有利于优化的过程,提高整个神经网络的学习速度。
(2)BN使得模型对初始化方法和网络中的参数不那么敏感,简化调参过程,使得网络学习更加稳定
在神经网络中,我们经常会谨慎地采用一些权重初始化方法(例如Xavier)或者合适的学习率来保证网络稳定训练。当学习率设置太高时,会使得参数更新步伐过大,容易出现震荡和不收敛...
https://zhuanlan.zhihu.com/p/34879333
(3)BN允许网络使用饱和性激活函数(例如sigmoid,tanh等),缓解梯度消失问题
在不使用BN层的时候,由于网络的深度与复杂性,很容易使得底层网络变化累积到上层网络中,导致模型的训练很容易进入到激活函数的梯度饱和区;通过normalize操作可以让激活函数的输入数据落在梯度非饱和区,缓解梯度消失的问题;另外通过自适应学习 与 又让数据保留更多的原始信息。
(4)BN具有一定的正则化效果
在Batch Normalization中,由于我们使用mini-batch的均值与方差作为对整体训练样本均值与方差的估计,尽管每一个batch中的数据都是从总体样本中抽样得到,但不同mini-batch的均值与方差会有所不同,这就为网络的学习过程中增加了随机噪音,与Dropout通过关闭神经元给网络训练带来噪音类似,在一定程度上对模型起到了正则化的效果。
另外,原作者也证明了网络加入BN后,可以丢弃Dropout,模型也同样具有很好的泛化效果。
BN的具体实现及其反向传播
//www.greatytc.com/p/4270f5acc066
https://zhuanlan.zhihu.com/p/27938792
在Caffe2实现中, BN层需要和Scale层配合使用, 其中, BN专门用于做归一化操作, 而后续的线性变换层, 会交给Scale层去做.
训练阶段:
在训练时利用当前batch的mean和variance来进行BN处理, 同时使用滑动平均的方式不断的更新global 的mean和variance, 并将其存储起来.
测试阶段:
在预测阶段, 直接使用模型存储好的均值和方差进行计算
使用BN时应注意的问题
- 训练/测试阶段的使用
在实际应用中, 均值和方差是通过滑动平均方法在训练数据集上得到的, 如果换了其他的任务或数据集, 建议先finetune之后再使用BN层存储的均值和方差. 同时, 注意训练时的均值和方差是来自于当前batch的.
- 隐藏层中BN的数据大小
在卷积网络隐藏层中, BN的大小不单单是batch, 而是batch和特征相应图大小的乘积. 也就是说, 在隐藏层, 层的输入是上一层的输出, 也就是上一层的神经元个数, 而对于上一层来说, 如果输出的特征相应图大小为 , 那么上一层的神经元个数就应该是 , 其中,b是指batch的大小