Batch Normalization论文笔记

    论文:Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift. Sergey Ioffe, Christian Szegedy

素质三连

1.论文贡献

提出Batch Normalization,消除了Internal covariate shift的影响,加快了网络的收敛速度。

2.实验结果

在GoogLeNet中加入BN,达到原模型的精度少了14trainning steps。在imagenet上达到4.9%的top-5错误率,超越人类水平。

3.存在的问题

稍微多了一点点计算量。

模型提出

Internal Covariate Shift

    随机梯度下降(SGD)的目标是最小化损失函数:

1.png

    上式中的X1…XN是分别是大小为m的mini-batch,mini-batch用来估计损失函数对参数的梯度:

2.png

    使用mini-batch的优点:

    A.如果一次计算整个训练集的梯度,其计算量无法接受。因此使用mini-batch的梯度用来估计整个训练集的梯度,而且mini-batch的越大越能代表训练集。

    B.当前的计算机硬件都可以并行计算,因此使用大小为m的mini-batch要比单独m个样本计算要高效。

    使用sgd训练时需要仔细调整模型的超参数,尤其是学习率和参数的初始化。神经网络每一层的输入受前面所有层影响,随着网络变得更深,参数的微小变化会被放大,这使得训练变得更加复杂。网络层的输入数据分布变化会带来问题:层需要不断适应新的分布。当一个学习系统的输入分布变化时,被称为covariate shift,通常采用域适应[论文:A literature survey on domain adaptation of statistical classifiers]来解决这个问题。

    考虑网络计算:

3.png

    设F1、F2是激活函数,theta1、theta2是参数,L是损失函数。令x=F1(u,theta1),则L=F2(x, theta2),则theta2的参数更新为:

4.png

    m是batch_size,alpha是学习率。像上面的例子中,theta2不得不重新适应x分布的改变。但如果我们将每层的输入分布固定,不仅有利于当前层的训练,而且对后面层也是有益的。

    作者把训练过程中,深层网络内部节点分布的变化称为内部协变量移位(internal covariate shift)


Batch Normalization的优点

    论文提出Batch Normalization来解决internal covariate shift,还附带很多好处:

    1.BN可以减少internal covariate shift,使得模型的训练大大加速。

    2.BN归一化输入batch到固定的均值和方差,BN还有利于网络中梯度的流动,它减小了梯度对参数和初始值的依赖。

    3.BN让我们可以使用更高的学习率,而不同担心网络会发散。

    4.BN可以作为正则化器,减小dropout的使用。

    5.BN的加入,让模型可以使用饱和非线性函数。


白化减小Internal Covariate Shift

    总所周知,如果输入数据白化后网络能收敛的更快。白化:将数据线性变换为均值为0,方差为1,去相关的数据。而Internal Covariate Shift定义为由于网络参数变化引起的网络激活值分布的改变。那么如果可以对每一层的输入进行白化,这样就固定每层的输入数据分布,从而减小internal covariate shift。

    而要对每层的输入进行白化,要么直接修改网络,要么根据网络激活值改变优化算法的参数。这些修改如果和参数优化步骤穿插在一起,那么sgd会尝试以一种需要更新归一化的方式更新参数,这样就减小了sgd的作用。举个例子:

    u是输入数据,需要优化的参数是b,x=u+b,x通过减去均值来归一化,且E(x)是batch x的均值。如果梯度下降时无视E(x)对b的依赖,则进行参数更新:

5.png

    那么当下一个batch输入时:

6.png

    可以看到,层的输出值没变,那么loss也不变,也就是说整个网络没有被优化。随着训练的进行,b会增加逐渐到inf,但是loss仍然不会减少。出现这个问题的原因是梯度下降没有考虑到归一化,为了解决这个问题,我们希望确保对于任何参数值,网络总是生成具有所需分布的激活。

    令x为当前层输入,chi是数据集所有的数据,归一化可以写作:x_=Norm(x, chi)。也就是说归一化后的数据不仅依赖于当前输入,而且依赖所有的数据。反向传播时,需要计算雅可比矩阵:

8.png

    忽略上面的右项将导致前面的参数爆炸问题,但是使用上面的公式计算代价是昂贵的,需要计算协方差矩阵和它的逆矩阵平方根:

9.png10.png

    以及这些变换的导数。需要找一个替代的方式执行输入归一化,要求可微而且不需要计算整个训练集。


使用BN代替白化

    每一层全白化台昂贵了而且不可微,因此需要进行两个简化:

1.首先,不需要对层输入和输出的特征进行联合白化,而是通过使其均值为0,方差为1来独立地对每个标量特征进行归一化。x为输入,则归一化为:

11.png

    这样的归一化可以加快网络的收敛速度,但这么简单的归一化可能会改变网络层的表示。比如:对一个sigmoid激活函数的输入进行归一化会将其约束到非线性的线性状态。为了解决这个问题,需要保证the transformation inserted in the network can represent the identity transform。 因此引入了两个参数lambda和beta,为缩放参数和平移参数,公式如下:

12.png

    这两个参数和网络一起学习,用于恢复网络的表示能力。

    而当13.png14.png时,上式等价于无参数归一化的情况。

2.在1.中提到,每个训练步基于整个数据集,即使用整个数据集归一化激活,这是不切实际的。因此做第二个简化:因为使用sgd优化,因此使用每个mini-batch产生整体均值和方差的估计。注意mini-batches计算每一维的方差而不是联合协方差;在联合的情况下,将需要正则化,因为小批处理的大小可能小于正在漂白的激活数,从而导致奇异协方差矩阵。

    上面1.和2.就是BN算法,具体过程如下:

15.png

    其中加上一个很小的系数是防止方差为0。

    BN变换并不是独立地处理每个训练样本,相反BN变换依赖mini-batch中的其它样本。上面的步骤中经过归一化后的batch是均值为0方差为1的数据(忽略那个小常量)。后面再接一个缩放和平移的线性变换层,以保证网络的分布不变。尽管这些经过BN层的数据分布在训练期间还是会被改变,但是我们期望归一化的引入能加入网络的收敛。

    反向传播更新参数:

16.png16.png

    从上面可以看到,BN变换是可微的。这确保了训练时,网络层可以继续学习输入分布,从而减少internal covariate shift,加速网络的训练。此外,可学习的仿射变换应用在归一化激活函数允许BN变换表示恒等变换,保留了网络的容量。


在网络中使用BN

    在网络中激活函数的前使用BN层。激活的归一化在训练时是有效的,但是推断时既无必要也不可行。推断时我们希望输出仅仅依赖于输入。所以,推断时,我们使用如下的归一化:

17.png

    上式的均值是训练过程中mini-batches的均值的均值,方差来源如下,使用无偏估计:

18.png

    公式中的均值是训练过程中所有mini-batches的方差的均值。由于在推理过程中均值和方差是固定的,因此BN只是对每个激活应用一个线性变换。因此可以进一步简单,用一个线性变换代替BN。

    下面是训练一个BN网络的流程:

19.png


在卷积神经网络中使用BN

    设某层神经网络可表示为:z=g(Wu+b),其中W是参数,u是输入,b是偏置,g(x)是非线性激活函数。我们可以应用BN变换在里面,其中b可以去掉 因为后面归一化会减掉,因此得公式:z=g(BN(Wu))

    对于卷积层,我们还希望BN遵循卷积的特性:在不同的位置,相同feature map的不同元素就会以相同的方式归一化。

20.png


发现使用BN后学习率可以放大

    在传统的深度学习网络中,太高的学习率会导致梯度消失或梯度爆炸,或陷入局部最小值。使用BN层,可以防止参数的微小变化在深层网络被放大。BN层也使得训练对参数的scale更有弹性。一般来说,越大的学习率,参数的scale越大,使得反向传播的梯度变大导致梯度爆炸。然而使用BN之后,反向传播的梯度不受参数scale的影响。对于一个scalar a:BN(Wu)=BN((aW)u),对该式求梯度:

21.png

    scale不影响层的雅可比矩阵,也不影响梯度传播。而且,权值越大,梯度越小,BN可以稳定参数的增长。我们进一步推测,BN可能导致层雅可比矩阵的奇异值接近1,这对训练是有益的。


发现BN有正则化作用

    作者发现使用BN后,Dropout可以去掉。


实验

对比实验

    为了验证internal covariate shift对训练的影响,以及BN层的效果,作者使用一个简单的网络在MNIST数据集上训练,模型细节为:28x28的输入,三层100个激活的全连接隐层,使用sigmoid激活函数,使用高斯随机初始化权重。输出10个分类,使用交叉熵损失。训练50000步,batch_size=60。设置添加了BN的对照组,下面展示测试结果:

22.png

    上图a显示bn能加快收敛速度,图bc显示:对于每个网络的最后一个隐层的一个典型激活,我们展示了它的分布是如何演变的。原始网络中分布的均值和方差随时间变化很大,这使后续层的训练变得复杂。相比之下,随训练的进行,批处理规范化网络中的分布更加稳定,这有助于训练的进行。


GoogLeNet加入BN

    作者在Inception网络、ImageNet上进行对比测试。使用的架构如下:

23.png

    网络使用带动量的SGD训练,batch_size=32。    

    跟原来的Inception相比,不同的地方在于原来的5x5卷积核被替换为两个3x3卷积串联,这一点参考了VGGNet。除此之外,还对网络进行了如下改进:

增加BN层

增加学习率

移除dropout

减小L2增加化衰减,原来的系数除以5

加快学习率衰减,比从前快6倍。

去除LRN层

更加测底的shuffle。使用within-shard shuffe,防止相同的样本出现在同一个mini-batch。这符合BN作为一个正则化器的观点: the randomization inherent in our method should be most beneficial when it affects an example differently each time it is seen (这句没看懂)

减小光度失真。因为BN的网络训练速度更快,观察每个训练样本的次数更少,所以我们让训练器通过较少的失真来关注更多的“真实”图像。

    最后模型在LSVRC2012上训练和测试。设置了如下对照组:

Inception:未加BN的Inception ,学习率:0.0015

BN-Baseline: 在Inception的每个激活函数前加入BN

BN-x5:在Inception的每个激活函数前加入BN,而且像上面说的一样修改一些地方。学习率为0.0075

BN-x30:跟BN-x5差不多,但是学习率为0.045

BN-x5-Sigmoid:跟BN-x5差不多,但是使用Sigmoid替代ReLU。

    下图是训练结果:

24.png

25.png

    由上可知,加入BN会大幅加快收敛速度,有趣的是,学习率太大反而会减慢收敛速度,但是能达到更高的精度。上面还设置了sigmoid替换relu的对照组,用于测试internal covariate shift是否有所改善,结果是大大消除了ICS。


使用集成模型

26.png

    集成模型达到SOTA。




上一篇:

首页 所有文章 机器人 计算机视觉 自然语言处理 机器学习 编程随笔 关于