Batch Normalization
1.基本原理
现在一般采用批梯度下降方法对深度学习进行优化,这种方法把数据分为若干组,按组来更新参数,一组中的数据共同决定了本次梯度的方向,下降时减少了随机性。另一方面因为批的样本数与整个数据集相比小了很多,计算量也下降了很多。
Batch Normalization(简称BN)中的batch就是批量数据,即每一次优化时的样本数目,通常BN网络层用在卷积层后,用于重新调整数据分布。假设神经网络某层一个batch的输入为X=[x1,x2,…,xn],其中xi代表一个样本,n为batch size。
首先,我们需要求得mini-batch里元素的 均值:
接下来,求取mini-batch的 方差:
这样我们就可以对每个元素进行 归一化。
最后进行尺度缩放和偏移操作,这样可以变换回原始的分布,实现恒等变换,这样的目的是为了补偿网络的非线性表达能力,因为经过标准化之后,偏移量丢失。具体的表达如下,yi就是网络的最终输出。
假如gamma等于方差,beta等于均值,就实现了恒等变换。
从某种意义上来说,gamma和beta代表的其实是输入数据分布的方差和偏移。对于没有BN的网络,这两个值与前一层网络带来的非线性性质有关,而经过变换后,就跟前面一层无关,变成了当前层的一个学习参数,这更加有利于优化并且不会降低网络的能力。
对于CNN,BN的操作是在 各个特征维度之间单独进行,也就是说各个通道是分别进行Batch Normalization操作的。
如果输出的blob大小为(N,C,H,W),那么在每一层normalization就是基于N* H*W个数值进行求平均以及方差的操作,记住这里我们后面会进行比较。
2.BN带来的好处。
-
(1) 减轻了对参数初始化的依赖,这是利于调参的朋友们的。
-
(2) 训练更快,可以使用更高的学习率。
-
(3) BN一定程度上增加了泛化能力,dropout等技术可以去掉。
3.BN的缺陷
从上面可以看出,batch normalization依赖于batch的大小,当batch值很小时,计算的均值和方差不稳定。研究表明对于ResNet类模型在ImageNet数据集上,batch从16降低到8时开始有非常明显的性能下降,在训练过程中计算的均值和方差不准确,而在测试的时候使用的就是训练过程中保持下来的均值和方差。
这一个特性,导致batch normalization不适合以下的几种场景。
-
(1)batch非常小,比如训练资源有限无法应用较大的batch,也比如在线学习等使用单例进行模型参数更新的场景。
-
(2)rnn,因为它是一个动态的网络结构,同一个batch中训练实例有长有短,导致每一个时间步长必须维持各自的统计量,这使得BN并不能正确的使用。在rnn中,对bn进行改进也非常的困难。不过,困难并不意味着没人做,事实上现在仍然可以使用的,不过这超出了咱们初识境的学习范围。
4.BN的改进
针对BN依赖于batch的这个问题,BN的作者亲自现身提供了改进,即在原来的基础上增加了一个仿射变换。
其中参数r,d就是仿射变换参数,它们本身是通过如下的方式进行计算的
其中参数都是通过滑动平均的方法进行更新
所以r和d就是一个跟样本有关的参数,通过这样的变换来进行学习,这两个参数在训练的时候并不参与训练。
在实际使用的时候,先使用BN进行训练得到一个相对稳定的移动平均,网络迭代的后期再使用刚才的方法,称为Batch Renormalization,当然r和d的大小必须进行限制。
5.Batch Normalization的变种
Normalization思想非常简单,为深层网络的训练做出了很大贡献。因为有依赖于样本数目的缺陷,所以也被研究人员盯上进行改进。说的比较多的就是 Layer Normalization与Instance Normalization,Group Normalization 了。
前面说了Batch Normalization各个通道之间是独立进行计算,如果抛弃对batch的依赖,也就是每一个样本都单独进行normalization,同时各个通道都要用到,就得到了Layer Normalization。
跟Batch Normalization仅针对单个神经元不同,Layer Normalization考虑了神经网络中一层的神经元。如果输出的blob大小为(N,C,H,W),那么在每一层Layer Normalization就是基于CHW个数值进行求平均以及方差的操作。
Layer Normalization把每一层的特征通道一起用于归一化,如果每一个特征层单独进行归一化呢?也就是限制在某一个特征通道内,那就是instance normalization了。
如果输出的blob大小为(N,C,H,W),那么在每一层Instance Normalization就是基于H*W个数值进行求平均以及方差的操作。对于风格化类的图像应用,Instance Normalization通常能取得更好的结果,它的使用本来就是风格迁移应用中提出。
Group Normalization 是Layer Normalization和Instance Normalization 的中间体, Group Normalization将channel方向分group,然后对每个Group内做归一化,算其均值与方差。
如果输出的blob大小为(N,C,H,W),将通道C分为G个组,那么Group Normalization就是基于GHW个数值进行求平均以及方差的操作。我只想说,你们真会玩,要榨干所有可能性。
在Batch Normalization之外,有人提出了通用版本Generalized Batch Normalization,有人提出了硬件更加友好的L1-Norm Batch Normalization等,不再一一讲述。
另一方面,以上的Batch Normalization,Layer Normalization,Instance Normalization都是将规范化应用于输入数据x,Weight normalization则是对权重进行规范化,感兴趣的可以自行了解,使用比较少,也不在我们的讨论范围。
这么多的Normalization怎么使用呢?有一些基本的建议吧,不一定是正确答案。
-
(1) 正常的处理图片的CNN模型都应该使用Batch Normalization。只要保证batch size较大(不低于32),并且打乱了输入样本的顺序。如果batch太小,则优先用Group Normalization替代。
-
(2)对于RNN等时序模型,有时候同一个batch内部的训练实例长度不一(不同长度的句子),则不同的时态下需要保存不同的统计量,无法正确使用BN层,只能使用Layer Normalization。
-
(3) 对于图像生成以及风格迁移类应用,使用Instance Normalization更加合适。