Batch Normalization:Accelerating Deep Network Training by Reducing Internal Covariate Shift 论文笔记

0 摘要

    当前神经网络层之前的神经网络层的参数变化,会引起神经网络每一层输入数据的分布产生变化,这使得训练一个深度神经网络变得复杂。通过设置较小的学习率以及更谨慎的初始化参数减慢了训练,并且由于非线性饱和(注:如sigmoid激活函数的非线性饱和问题),训练一个深度神经网络会非常困难。这种现象被称为internal covariate shift。解决这个问题需要对输入进行标准化。本文的方法将标准化作为模型结构的一部分,并且对每一小批量数据执行标准化。BN有助于我们使用更高的学习率,并且不需要过多的注重参数初始化问题。BN 的过程与正则化相似,在某些情况下可以去除Dropout。将BN应用到一个state-of-the-art的图片分类模型中时,使用BN只要1/14的训练次数就能够达到同样的精度。使用含有BN神经网络模型能提升现有最好的ImageNet分类结果:在top-5 验证集中达到4.9%的错误率(测试集为4.8%),超出了人类的分类精度。 

1 介绍

深度学习在视觉、语音等诸多方面显著提高了现有技术的水平。随机梯度下降(SGD)已经被证明是训练深度网络的有效方式,并且已经使用诸如动量和Adagrad等SGD变种取得了最先进的性能。SGD优化网络参数θ来最小化损失函数

其中,X1...N是训练数据集,使用SGD,训练将逐步进行,在每一步中,我们考虑一个大小为m的小批量数据X1...m。通过计算

使用小批量数据来近似损失函数关于参数的梯度。使用小批量样本,而不是一次一个样本,在一些方面是有帮助的。首先,小批量数据的梯度是整个训练集上的梯度估计,其质量随批量的增加而改善。其次,现代计算平台的并行性,对一个批次的计算比单个样本计算m次效率更高。

虽然随机梯度是简单有效的,但它需要仔细调整模型的超参数,特别是优化中使用的学习速率以及模型参数的初始值。训练的复杂性在于每层的输入受到前面所有层的参数的影响——因此当网络变得更深时,网络参数的微小变化就会被放大。

层输入的分布变化是一个问题,因为这些层需要不断适应新的分布。当学习系统的输入分布发生变化时,会经历covariate shift然而covariate shift的概念的适用性能够从整个学习系统扩展到该系统的一部分,比如一个子网络或者其中的一层。考虑一个网络计算

F1和F2是任意变换,θ1和θ2是学习参数,用来最小化损失L。学习θ2可以看作将输入

送到子网络

  

则θ2的更新如下:(m是批量的样本数,α是学习率)

与输入为X的单独网络F2完全等价。输入数据分布相同这一特性,使得子网络更容易训练。这与训练数据和测试数据有相同的分布是相似的。因此保持X的分布不变是有利的。这样θ2就不需要为了弥补X的分布的改变而重新进行调整。 

保持一个子网络的输入数据分布不变,对该子网络以外的隐藏层也有积极的作用。考虑一层激活函数为sigmoid函数的神经网络层:

其中u为该层的输入,权重矩阵W和偏置b为该层需要学习的参数。当|x|增大的时候,趋向于0。

这意味着对于的每一维中除了绝对值较小的之外,其他的流向u的梯度会消失,同时模型的训练变得很缓慢。然而,由于xW,b和下面所有层的参数的影响,训练期间那些参数的改变可能会将x的许多维度移动到非线性的饱和状态并减慢收敛。这个影响随着网络深度的增加而放大。在实际中非线性饱和端问题以及梯度弥散问题经常用ReLU激活函数,并且配合合适的初始化以及较小的学习率的办法来解决。如果我们能够确保非线性输入的数据分布更稳当的话,那么出现非线性饱和端问题的概率则会更小,并且能够加速网络的训练。

我们称在训练深度神经网络的过程中,网络内部节点的分布发生变换这一现象为,Internal Covariate Shift.。而消除这个现象能够加速网络的训练。我们提出了Batch Normalization ,这样做可以显著加速深度神经网络的训练。它通过标准化步骤来实现,标准化步骤修正层输入的均值和方差。

BN的优点:

BN减少了梯度对参数尺度或者参数初始值尺度的依赖,这允许我们使用更高的学习率而没有发散的风险。

BN使模型正则化并减少了对Dropout的需求。

BN通过阻止网络陷入饱和模式让使用饱和非线性激活函数(sigmoid)成为可能。

2 减少internal covariate shift

    我们将inter covariate shift定义为:在神经网络的训练过程中,由于参数改变,而引起的神经网络激活值分布的改变。我们通过缓解inter covariate shift来提高训练。在训练的过程中保持神经网络层输入的分布不变,来提高训练速度。我们已经知道,在训练的过程中对网络的输入进行白化,网络的训练将会收敛得更快,即将输入的分布线性变换为具有零均值和单位方差的分布,并且去相关。每一层的输入来自该层之前的神经网络层,通过对每一层的输入进行白化处理,我们能够保持输入的分布,从而消除inter covariate shift的不良影响。 

    我们考虑在每个训练步骤或在某些间隔来白化激活值,通过直接修改网络或根据网络激活值来更改优化方法的参数进行白化。然而,如果这些方法在优化步骤中执行,那么在更新参数的时候,必须先计算标准化后的激活值的误差,这降低了梯度下降法的效果。(标准化不能在求的激活值之后进行,不然流到上一层参数的误差值会越来越小,从而影响模型的学习,也就是梯度弥散问题)举个例子,考虑一层神经网络层, u为输入,b为偏置值。并且对该神经网络的激活值减均值标准化
  
其中,


注:X是由训练数据集生成的该神经网络层输入的一个集合(训练数据集X前向传播到该层)。

如果梯度下降的步骤忽略E[x]对b的依赖,那么就有:

其中,

然后,

因此,当标准化和参数b的更新同时进行的时候,会使该神经网络层的输出没有变化,进一步的导致损失函数的值没有变化。随着训练的继续,b一直在增长而损失函数的值却一直不变。如果标准化参数在梯度下降步骤之外计算的话,会使模型参数爆炸。

    上述方法的问题是梯度下降优化没有考虑到标准化中发生的事实。为了解决这个问题,我们希望确保对于任何参数值,网络总是产生具有所需分布的激活值。与之前的例子相同,向量x为一层神经网络层的输入,X为由训练数据集生成的该神经网络层输入的一个集合。那么标准化可以写为变换:

该标准化操作不仅考虑了x,同时还考虑了所有训练样本X。对于反向传播,需要计算雅克比行列式

     

忽略后一项会导致上面描述的模型参数爆炸。根据这个框架,白化操作的计算量非常大。因为白化需要计算协方差矩阵

和协方差矩阵的负平方根来产生白化激活值

以及这些变换进行反向传播的偏导数。这促使我们寻求一种替代方案,寻求一种可微,并且在参数更新的时候不需要对整个训练数据集进行分析的神经网络层输入标准化方法。我们希望通过同时考虑单个训练样本和整个训练样本集的统计信息来标准化激活值,从而在网络中保留更多的信息。

3 mini-batch进行标准化

    因为对于每一层的输入进行白化花费较高,并且也不是处处可微,所有我们做了两个必要的简化。第一是,我们对标量特征进行单独的标准化,使其具有零均值和单位方差,来代替白化同时对层的输入和输出同时进行标准化。对于具有d维度的输入的神经网络层,利用下面的式子标准化每一维:

上式中的期望和方差由训练数据集计算得到。该标准化能够加速收敛。

    简单的标准化神经网络层的输入,可能会改变该层的表征能力。例如,对 sigmoid 函数的输入进行标准化,会使标准化后的输入整体处于 s 型函数的线性端(因为标准化后的值会很小,如果这个区域接近线性,显然不是我们想要的)。为了避免这样的情况出现,我们又加入了以下的变换,确保至少可以把数据还原为原数据。

新引入了两个参数,这两个参数是与模型原始的参数一起学习,并恢复了模型的表征能力。当满足下列条件时,

就能够求得原来的激活值。

神经网络的训练是基于整个训练数据集的,在batch的设置中,我们可以用整个训练数据集来标准化激活值。但是,当我们使用随机梯度下降法的时候这一选择是不实际的。因此我们做了第二个简化:在随机梯度下降中我们采用mini-batch的方式,这样我们就能够通过每个mini-batch为每个激活值计算出对应的均值和方差。通过这样的方式,标准化所需统计信息就能够完全被考虑到梯度下降中去。利用mini-batch就能计算每一维激活值的方差,而不是计算所有激活值的协方差矩阵。

假设由一个mini-batchB,其大小为m。因为是对激活值的每一维进行标准化,所以我们只考虑其中的一个激活值,为了清晰下文中忽略k。在小批量数据里我们有m个激活值

为标准化后的值,同时他们的线性变换为。于是有BN变换:

下图算法为BN变换,其中ε是一个趋于0的常数。

    BN变换可以添加到网络上来操纵任何激活。在公式中,参数γ和β需要进行学习。需要注意的是,BN变换不仅仅与单个训练样本相关,也与mini-batch中的其他训练样本有关。

    只要每个小批量的元素从相同的分布中进行采样,如果忽略ε,那么中的每个元素都是0均值,1方差的分布。所有的子网络输入都有固定的均值和方差。

  在训练过程中我们需要通过这个变换反向传播损失L的梯度,以及计算关于BN变换参数的梯度。我们使用的链式法则如下(简化之前)

  因此BN变换是将标准化激活值引入神经网络的一种可微变换。这确保了网络可训练性,以及神经网络层能够持续学习输入数据分布。从而能够减少inter covariate shift发生,同时加速网络的训练。此外,应用于这些标准化的激活上的学习到的仿射变换允许BN变换表示恒等变换并保留网络的能力。

3.1 BN的训练和预测

    任何以前接收x作为输入的层现在接收BN(x)作为输入。采用BN的模型可以使用批量梯度下降,或者用小批量数据(m>1)的随机梯度下降。依赖小批量数据的激活值的标准化可以有效地训练。一旦网络训练完成,我们使用总体统计来进行标准化,而不是小批量的数据统计。

跟训练过程中一样,如果忽略ε,这些标准化的激活具有相同的均值0和方差1.我们使用无偏方差估计

其中,期望是在大小为m的小批量训练数据上得到的,是其样本方差。由于均值和方差在预测时是固定的,因此标准化是应用到每一个激活上的简单线性变换。它可以进一步由缩放γ和平移β组成,以产生代替BN(x)的简单线性变换。

3.2 卷积网络的BN

    BN可以应用于网络的任何激活。

其中W和b是模型学习的参数,g(x)是非线性激活函数sigmoid或者ReLU。这个公式涵盖了全连接层和卷积层。我们在非线性之前通过x=Wu+b加入BN变换。我们也可以标准化层输入u。但是由于u可能是另一个非线性输出,它的分布形状可能在训练过程中改变,可能不能去除inter covariate shift。相比之下,Wu+b更可能具有对称,非稀疏分布,对其进行标准化可能产生具有稳定分布的激活。

    注意,由于我们对Wu+b进行标准化,偏置b可以忽略。因为它的效应将会被后面的去均值取消。偏置的作用会归到算法1的β。因此,z=g(Wu+b)被

替代。其中BN变换独立地应用到x=Wu的每一维。每一维具有单独的成对学习参数γ和β。


以下观点引用自:

原文地址http://blog.csdn.net/hjimce/article/details/50866313

作者:hjimce

BN算法(Batch Normalization)其强大之处如下:

(1)你可以选择比较大的初始学习率,让你的训练速度飙涨。以前还需要慢慢调整学习率,甚至在网络训练到一半的时候,还需要想着学习率进一步调小的比例选择多少比较合适,现在我们可以采用初始很大的学习率,然后学习率的衰减速度也很大,因为这个算法收敛很快。当然这个算法即使你选择了较小的学习率,也比以前的收敛速度快,因为它具有快速训练收敛的特性;

(2)你再也不用去理会过拟合中drop out、L2正则项参数的选择问题,采用BN算法后,你可以移除这两项了参数,或者可以选择更小的L2正则约束参数了,因为BN具有提高网络泛化能力的特性;

(3)再也不需要使用使用局部响应归一化层了(局部响应归一化是Alexnet网络用到的方法,搞视觉的估计比较熟悉),因为BN本身就是一个归一化网络层;

(4)可以把训练数据彻底打乱(防止每批训练的时候,某一个样本都经常被挑选到,文献说这个可以提高1%的精度,这句话我也是百思不得其解啊)。

开始讲解算法前,先来思考一个问题:我们知道在神经网络训练开始前,都要对输入数据做一个归一化处理,那么具体为什么需要归一化呢?归一化后有什么好处呢?原因在于神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;另外一方面,一旦每批训练数据的分布各不相同(batch 梯度下降),那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度,这也正是为什么我们需要对数据都要做一个归一化预处理的原因。

对于深度网络的训练是一个复杂的过程,只要网络的前面几层发生微小的改变,那么后面几层就会被累积放大下去。一旦网络某一层的输入数据的分布发生改变,那么这一层网络就需要去适应学习这个新的数据分布,所以如果训练过程中,训练数据的分布一直在发生变化,那么将会影响网络的训练速度。

我们知道网络一旦train起来,那么参数就要发生更新,除了输入层的数据外(因为输入层数据,我们已经人为的为每个样本归一化),后面网络每一层的输入数据分布是一直在发生变化的,因为在训练的时候,前面层训练参数的更新将导致后面层输入数据分布的变化。以网络第二层为例:网络的第二层输入,是由第一层的参数和input计算得到的,而第一层的参数在整个训练过程中一直在变化,因此必然会引起后面每一层输入数据分布的改变。我们把网络中间层在训练过程中,数据分布的改变称之为:“Internal  Covariate Shift”。Paper所提出的算法,就是要解决在训练过程中,中间层数据分布发生改变的情况,于是就有了Batch  Normalization,这个牛逼算法的诞生。

就像激活函数层、卷积层、全连接层、池化层一样,BN(Batch Normalization)也属于网络的一层。在前面我们提到网络除了输出层外,其它层因为低层网络在训练的时候更新了参数,而引起后面层输入数据分布的变化。这个时候我们可能就会想,如果在每一层输入的时候,再加个预处理操作那该有多好啊,比如网络第三层输入数据X3(X3表示网络第三层的输入数据)把它归一化至:均值0、方差为1,然后再输入第三层计算,这样我们就可以解决前面所提到的“Internal Covariate Shift”的问题了。

而事实上,paper的算法本质原理就是这样:在网络的每一层输入的时候,又插入了一个归一化层,也就是先做一个归一化处理,然后再进入网络的下一层。不过文献归一化层,可不像我们想象的那么简单,它是一个可学习、有参数的网络层。

经过前面简单介绍,这个时候可能我们会想当然的以为:好像很简单的样子,不就是在网络中间层数据做一个归一化处理嘛,这么简单的想法,为什么之前没人用呢?然而其实实现起来并不是那么简单的。 其实如果是仅仅使用上面的归一化公式,对网络某一层A的输出数据做归一化,然后送入网络下一层B,这样是会影响到本层网络A所学习到的特征的。打个比方,比如我网络中间某一层学习到特征数据本身就分布在S型激活函数的两侧,你强制把它给我归一化处理、标准差也限制在了1,把数据变换成分布于s函数的中间部分,这样就相当于我这一层网络所学习到的特征分布被你搞坏了,这可怎么办? 于是文献使出了一招惊天地泣鬼神的招式:变换重构,引入了可学习参数 γ、 β,这就是算法关键之处。 每一个神经元xk都会有一对这样的参数 γ、 β。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值