1 导入
1.1 独立同分布
统计机器学习的经典假设:source domain和target domain的数据分布是一致的,也就是说,训练数据和测试数据满足独立同分布。这是通过训练的模型能在测试集上获得好的效果的前提。
1.2 Internal Covariate Shift
Covariate Shift:是机器学习的一个问题,同时迁移学习也会涉及到这个概念。假设x是属于特征空间的某一样本点,y是标签。covariate这个词,其实就是指这里的x,那么Covariate Shift可以直接根据字面意思去理解:样本点x的变化。
对于迁移学习的Covariate Shift的规范化描述:设源域(source domain)和目标域(target domain)的输入空间均为X, 输出空间均为Y. 源域的边际分布
如何解决Covariate Shift:其实就是重新给训练集中的数据赋予一个新的权重即Reweight操作,比方说对于样本xi,它在训练集中的分布是q(xi),在预测集中的真实分布是p(xi),那么它的新权重就是p(xi)/q(xi)。那么如何确定样本xi在训练集和测试集的真实分布呢?具体可以看基于样例的迁移学习——Covariate Shift——原始文章解读。
Internal Covariate Shift(ICS)描述:在BN的论文中,Covariate Shift指的是神经网络的输入X的分布老是变化,不符合独立同分布假设。而对于深度学习这种包含很多隐层的网络结构,每层的输出都是下一层的输入,在训练中,当梯度更新的时候,前一层的参数发生变化,使得前一层的输出发生变化,使得下一层的输入发生变化,这就意味着下一层的输入发生了Covariate Shift,这就是所谓的“Internal Covariate Shift”,Internal指的是深层网络的隐层,是发生在网络内部的事情,而不是Covariate Shift问题只发生在输入层。
Internal Covariate Shift带来的问题:(1)上层网络需要不停调整来适应输入数据分布的变化,导致网络学习速度的降低:梯度下降的过程会让每一层的参数发生变化,进而使得每一层的线性与非线性计算结果分布产生变化。后层网络就要不停地去适应这种分布变化,这个时候就会使得整个网络的学习速率过慢。(2)网络的训练过程容易陷入梯度饱和区,减缓网络收敛速度(我的理解:就是指梯度爆炸。同时我认为使用Sigmoid或者tanh这样的激活函数容易梯度爆炸的原因:该激活函数的非饱和区较小,且单调递增,且梯度高,因此迭代相乘几次后非常容易越过非线性区进入饱和区)。
Covariate Shift VS Internal Covariate Shift:关于Covariate Shift,知乎已经给出了不错的解释。但是针对Internal Covariate Shift,我们又被作者误导了。Covariate Shift ≠ Internal Covariate Shift,前者是迁移学习问题,后者是一个训练优化问题。正如知乎的层主所说的那样,各层添加零均值、单位方差的共轭分布,只针对数值,而不针对表征。实际上,如果把表征也”共荣化“,那就反而糟糕了。多层神经网络可以看作是一个迁移学习问题,层与层之间的抽象等级不同,比如学习一只猫,经过多层神经网络抽象后,就可以迁移分裂成多个机器学习问题:学习猫脸、学习猫腿、学习猫身、学习猫爪、学习猫尾。如果normalize之后,这五个部分的表征分布都变一样了,那么Deep Learning不是可以废掉了?所以说,normalize仅仅是数值层面的均衡化,以及表征层面的轻度破坏化。Internal Covariate Shift只针对数值偏移,而Covariate Shift才针对表征偏移。
2 BN的启发来源:白化
之前的研究表明如果在图像处理中对输入图像进行白化(Whiten)操作的话——所谓白化,就是对输入数据分布变换到0均值,单位方差的正态分布——那么神经网络会较快收敛,那么BN作者就开始推论了:图像是深度神经网络的输入层,做白化能加快收敛,那么其实对于深度网络来说,其中某个隐层的神经元是下一层的输入,意思是其实深度神经网络的每一个隐层都是输入层,不过是相对下一层来说而已,那么能不能对每个隐层都做白化呢?这就是启发BN产生的原初想法,而BN也确实就是这么做的,可以理解为对深层神经网络每个隐层神经元的激活值做简化版本的白化操作。
白化(Whitening)是机器学习里面常用的一种规范化数据分布的方法,主要是PCA白化与ZCA白化。白化是对输入数据分布进行变换,进而达到以下两个目的:(1)使得输入特征分布具有相同的均值与方差。其中PCA白化保证了所有特征分布均值为0,方差为1;而ZCA白化则保证了所有特征分布均值为0,方差相同。(2)去除特征之间的相关性。但现行的白化方法存在一些问题:(1)白化过程计算成本太高,并且在每一轮训练中的每一层我们都需要做如此高成本计算的白化操作。(2)白化过程由于改变了网络每一层的分布,因而改变了网络层中本身数据的表达能力。底层网络学习到的参数信息会被白化操作丢失掉。既然有了上面两个问题,那我们的解决思路就很简单,一方面,我们提出的normalization方法要能够简化计算过程;另一方面又需要经过规范化处理后让数据尽可能保留原始的表达能力。于是就有了简化+改进版的白化——Batch Normalization。
3 算法
3.1 思路
为了达到简化计算的目的,单独对每个特征进行标准化就可以了,让每个特征都有均值为0,方差为1的分布就OK。为了尽可能保留数据的原始表达能力,加个线性变换操作。BN是基于Mini-Batch的基础上计算的。
3.2 具体
这三步就是我们在刚刚一直说的标准化工序, 但是公式的后面还有一个反向操作, 将 normalize 后的数据再扩展和平移。原来这是为了让神经网络自己去学着使用和修改这个扩展参数 γ和平移参数 β, 这样神经网络就能自己慢慢琢磨出前面的标准化操作到底有没有起到优化的作用, 如果没有起到作用, 我就使用 γ和β来抵消一些 normalization 的操作,当γ² = σ²和β = μ时,可以实现等价变换(Identity Transform)并且保留了原始输入特征的分布信息。
注: 在进行normalization的过程中,由于我们的规范化操作会对减去均值,因此,偏置项b可以被忽略掉或可以被置为0,即:BN(Wμ+b) = BN(Wμ)
3.3 梯度下降公式
3.4 测试时
在测试时,可能需要测试的样本只有1个或者少数几个,此时用μ和σ可能是有偏估计。因此采用一个方法:u和σ被替换为训练阶段收集的运行均值这使得模型可以对单一样本评估,无须使用定义于整个小批量的u和σ。
4 总结
(1)能够减少Interal Covariate Shift的问题,从而减少train的时间,使得对于deep网络的训练更加可行。(BN后的模型每一轮训练收敛快,但每一轮的计算量大,有文章称使用Batch Normalization会带来30%额外的计算开销。)
我们可以看到,经过BN操作以后,权重的缩放值会被“抹去”,因此保证了输入数据分布稳定在一定范围内。另外,权重的缩放并不会影响到对 μ 的梯度计算;并且当权重越大时,即 a 越大,1/a 越小,也意味着权重 W 的梯度反而越小,这样BN就保证了梯度不会依赖于参数的scale,使得参数的更新处在更加稳定的状态。
因此,在使用Batch Normalization之后,抑制了参数微小变化随着网络层数加深被放大的问题,使得网络对参数大小的适应能力更强,此时我们可以设置较大的学习率而不用过于担心模型divergence的风险。
(3)对于参数的初始化影响更小:即使对于某组parameter同时乘以k倍后,最终的结果还是会keep不变的。
(4)能够减少overfitting问题的发生:
在Batch Normalization中,由于我们使用mini-batch的均值与方差作为对整体训练样本均值与方差的估计,尽管每一个batch中的数据都是从总体样本中抽样得到,但不同mini-batch的均值与方差会有所不同,这就为网络的学习过程中增加了随机噪音,与Dropout通过关闭神经元给网络训练带来噪音类似,在一定程度上对模型起到了正则化的效果。
另外,原作者通过也证明了网络加入BN后,可以丢弃Dropout,模型也同样具有很好的泛化效果。
5 试验
一个详细的试验在Batch Normalization原理与实战这篇博客里能看到。
6 参考:
Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift:
【机器学习】covariate shift现象的解释 - CSDN博客:https://blog.csdn.net/mao_xiao_feng/article/details/54317852
从Bayesian角度浅析Batch Normalization - 博客园:https://www.cnblogs.com/neopenx/p/5211969.html
Batch Normalization导读:https://zhuanlan.zhihu.com/p/38176412