摘要 Abstract
训练深度神经网络的复杂性在于,每层输入的分布在训练过程中会发生变化,因为前面的层的参数会发生变化。通过要求较低的学习率和仔细的参数初始化减慢了训练,并且使具有饱和非线性的模型训练起来非常困难。我们将这种现象称为 Internal Covariate Shift ,并通过标准化层输入来解决这个问题。我们的方法力图使标准化成为模型架构的一部分,并为每个训练小批量数据执行标准化。 Batch Normalization 使我们能够使用更高的学习率,并且不用太注意初始化。它也作为一个正则化项,在某些情况下不需要Dropout。将批量标准化应用到最先进的图像分类模型上, Batch Normalization 在取得相同的精度的情况下,减少了14倍的训练步骤,并以显著的差距击败了原始模型。使用 Batch Normalization 网络的组合,我们改进了在ImageNet分类上公布的最佳结果:达到了4.9% top-5的验证误差(和4.8%测试误差),超过了人类评估者的准确性。
介绍 Introduction
在这一部分,首先作者介绍了一下SGD,也就是我们常说的随机梯度下降算法。随机梯度下降(SGD)已经被证明是训练深度网络的有效方式,并且随之也出现了动量法和Adagrad等优化算法。SGD优化网络参数Θ \ThetaΘ,以最小化损失
在训练过程中,我们还通常是一个个mini-batch进行训练的,也就是使用小批量的样本,使用小批量数据来近似损失函数关于参数的梯度
使用小批量样本m mm有帮助的
mini-batch的梯度损失是训练集的梯度估计,并且样本越大越准确,我觉得这一部分类似于大数定律。
由于现代计算平台提供的并行性,对一个批次m mm的计算比单个样本计算m mm次效率更高。计算效率会更高
虽然随机梯度是简单有效的,但它需要仔细调整模型的超参数,特别是优化中使用的学习速率以及模型参数的初始值。训练的复杂性在于每层的输入受到前面所有层的参数的影响——因此当网络变得更深时,网络参数的微小变化就会被放大。
对于神经网络来说,每一层输入的分布变化是一个问题,因为这些层需要不断适应新的分布。当学习系统的输入分布发生变化时,据说会经历 Internal Covariate Shift (Shimodaira,2000),这通常是通过域适应(Jiang,2008)来处理的。
这里可能就出现一个词,也就是 Internal Covariate Shift ,这个词在我们的题目也出现了Internal Covariate Shift,这也被称为ICS问题,我觉得我们可以先浅显理解一下:如果训练数据经过网络的每一层后其分布都发生了变化,会极大的降低优化的效率。
接着作者举了一个子网络的例子,旨在说明,如果输入分布相同,对于我们的网络来说,可以减少更多的时间,也可以不用去修改过多的参数。
除此之外,固定分布的输入对我们的网络也是有积极的影响的。比如考虑sigmoid函数,对于这个激活函数来说,我们很多论文都提到过,随着∣ x ∣的增加,我们梯度会趋近于0,这意味着对于我们的神经网络来说,除了一开始的具有小的绝对值的输入之外,后面很多的梯度都会消失,会减小我们的训练速度,缓慢收敛。并且这种情况在深层网络中更为明显,这也就是我们常说的梯度消失。在实践中,提出了一个ReLU函数, ReLU = max(0,x),这个函数就不那么容易出现饱和问题,同时我们也可以调整小的学习率和仔细初始化来解决这个饱和问题,使得我们的优化器不太可能陷入饱和状态,从而加速训练。
作者把训练过程中深度网络内部节点分布变化称为 Internal Convariate Shift,如果解决掉他可以加快我们的训练,所以作者就提出了一个机制,也就是 Batch Normalization ,它是减少 Internal Covariate Shift 的一个步骤,这样做可以显著加速深度神经网络的训练。它通过标准化步骤来实现,标准化步骤修正了层输入的均值和方差。标准化减少了梯度对参数或它们的初始值尺度上的依赖,对通过网络的梯度流动有有益的影响。这允许我们使用更高的学习率而没有发散的风险。此外, Batch Normalization 使模型正则化并减少了对Dropout(Srivastava et al., 2014)的需求。最后, Batch Normalization 通过阻止网络陷入饱和模式让使用饱和非线性成为可能,比如我们可以用sigmoid函数等等
总结一下
保持各层输入的均值和方差稳定,来减弱 internal covariate shift
让梯度受参数及其初值的减小
算作正则项,减少对Dropout的依赖
让卡在饱和区域的概率降低,以便可以使用 saturating nonlinearities
并且在ImageNet的实验中,已经证明了BN层的优化效果是非常好的,改进了当时的最佳结果。
减少 Internal Covariate Shift Towards Reducing Internal Covariate Shift
由于训练过程中网络参数的变化,我们将 Internal Covariate Shift 定义为网络激活分布的变化。我们固定层输入x的数据分布,希望能够提高训练的速度。众所周知(LeCun et al., 1998b; Wiesler & Ney, 2011)如果对网络的输入进行白化,网络训练将会收敛的更快——即输入线性变换为具有零均值和单位方差,并去相关。当每一层观察下面的层产生的输入时,实现每一层输入进行相同的白化将是有利的。通过白化每一层的输入,我们将采取措施实现输入的固定分布,消除 Internal Covariate Shift 的不良影响。
这里面出现了一个词 白化,可能会有一点点陌生,虽然他可能不是很重要,但是我还是查了维基百科等等去寻找他的解释,比较的简单来说,通过白化后,数据不具有相关性,并且具有相同的方差1,均值为0,协方差矩阵为对角矩阵。
这里我们可能需要区分一下几个概念
标准化:均值为0,方差为1,不考虑相关性
去相关化:仅使变量不相关,不考虑方差
有色变换:将白色随机变量转换为指定协方差矩阵的随机向量
白化是不同的,这里有张图,可以表示一下
在很多的程序中,可以我们的白化实现会通过,PCA+归一化,这样子我们的数据既不相关,并且方差为1,均值为0
数据相关经常用协方差矩阵来表示,如果一个分布在给定正交基是各项独立,互不相关的话,那么协方差矩阵就是对角矩阵。因为每一个维度只与自己相关(对角线),与其他的维度都为0,所以协方差矩阵为对角矩阵。
参考
Whitening transformation - Wikipedia
白噪声 - 维基百科,自由的百科全书 (wikipedia.org)
解释完白化,接着就继续读论文吧。
作者接着考虑在每个训练步骤或在某些间隔来白化激活值,通过直接修改网络或根据网络激活值来更改优化方法的参数*(Wiesler et al., 2014; Raiko et al., 2012; Povey et al., 2014; Desjardins & Kavukcuoglu)*。然而,如果这些修改分散在优化步骤中,那么梯度下降步骤可能会试图以要求标准化进行更新的方式来更新参数,这会降低梯度下降步骤的影响。
这里举了一个例子,比如考虑一个层,他的输入u 加上学习到的偏置b ,通过减去在训练集上计算的激活值的均值对结果进行归一化:
是训练集上x 值的集合,。如果梯度下降步骤忽略了E [ x ] 对b 的依赖,那它将更新b ← b + Δ b 其中Δ b ∝ − ∂ ℓ / ∂ x ,然后
这个公式成立的原因是E [ x ] 和b 没什么关系,所以E [ Δ b ] = Δ 。因此,结合b bb的更新和接下来标准化中的改变会导致层的输出没有变化,从而导致损失没有变化。随着训练的继续,b bb将无限增长而损失保持不变。如果标准化不仅中心化而且缩放了激活值,问题会变得更糟糕。并且作者在最初的实验也发现了这一点,当标准化参数在梯度下降步骤之外计算时,模型会爆炸。
上述方法的问题就是梯度下降优化的时候,没有考虑标准化,为了解决这个问题呢,我们希望对于任何参数值,网络总是产生具有所需分布的激活值。这样做能更好的解释标准化和对模型参数Θ 的依赖。
设x 为层的输入,将其看作向量,X ^ 是输入在训练集上的集合。标准化可以写为变换
它不仅仅依赖于给定的训练样本x , 并且也依赖于所有的样本X ^如果他们是由另一层生成的,还都依赖于Θ 。对于反向传播,我们就需要计算雅可比行列式
在这个框架中,输入是昂贵的,或者可以理解为耗费的计算资源是比较大的,因为它要求计算协方差矩阵和他的平方根的倒数,从而生成白化的激活和这些变换进行反向传播的偏导数。所以促使着我们寻找另一种替代的防范,可以以微分的方式进行输入标准化,并且在每次参数更新后不需要对整个训练集进行分析。并且我们希望通过对相对于整个训练数据统计信息的单个训练样本的激活值进行归一化来保留网络的信息。
通过Mini-Batch 统计标准化 Normalization via Mini-Batch Statistics
如果对于每一层都进行白化的代价是很昂贵的,并且也不是处处可微的,所以呢,对此相处了两个必要的简化
首先,我们可以单独标准化标量特征,使其均值为0,方差为1,而不用总体白化。
可以用标准化,用以下公式对每一维进行标准化,其中期望和方差在整个训练集上计算。
有相关证明,这种方法虽然每一去相关,但是还是加快了收敛
考虑到如果标准化每一个输入有可能会改变层原有的表示,例如,标准化sigmoid的输入会将它们约束到非线性的线性状态。为了解决这个问题,我们希望确保插入网络的变化可以表示恒等变化。所以对每一个激活值x ( k ) x^{(k)}x
(k)
来说,引入了一对参数γ ( k ) , β ( k ) ,会对我们的标准化后的值进行一个移动和缩放
这两个参数与网络的参数一起学习而来的,用于恢复网络原有的表示能力。实际上,如果我们通过设置得到的我们就能得到原始值,这是最优的结果。
每个训练步骤的批处理设置是基于整个训练集的,我们将使用整个训练集来标准化激活值。然而,当使用随机优化时,这是不切实际的。所以在这里,我们用了第二个简化,在我们的训练都是通过Mini-batch的,那我们就每个batch产生平均值和方差的估计。这样就有利于我们进行反向传播。
举个例子,考虑一个大小为 m mm 的小批量数据 B \mathcal{B}B 。由于标准化被单独地应用于每一个激活, 所以让我们集中在一个特定的激活在小批量数据里我们有这个激活的 m 个值,
设标准化值为 x ^ 1 … m ,它们的线性变换为 y 1 … m 。我们把变换
这就是Batch Normalizing Transform,在论文中,也给出了算法Algorithm 1,其中的 ϵ \epsilonϵ 是一个常量,是加到方差中防止分母为0的出现
BN层是可以加入到任何网络中来处理激活的,在公式 y = B N γ , β ( x ) 中,我们指参数 γ 和 β 需要进行学习,但应该注意到在每一个训练样本中BN变换不单独处理激活。相反, B N γ , β ( x ) 取决于训练样本和小批量数据中的其它样本。
在训练过程中我们需要通过这个变换反向传播损失ℓ \ellℓ的梯度,以及计算关于BN变换参数的梯度。我们使用的链式法则如下
以上都是一些比较简单的公式,我自己已经推过了,可能比较麻烦的就是第三个,我们要知道方差和均值都是和x有关的,所以求偏导的时候也要多考虑一下
因此,BN变换是将标准化激活引入到网络中的可微变换。这确保了在模型训练时,层可以继续学习输入分布,表现出更少的内部协变量转移,从而加快训练。此外,应用于这些标准化的激活上的学习到的仿射变换允许BN变换表示恒等变换并保留网络的能力。
3.1 BN 的训练和推断 Training and Inference with Batch-Normalized Networks
为了去Batch Normalize一个网络,我们首先插入前面的BN的变换。所以现在以前接收 x xx 输入的层现在都接收 B N ( x )作为输入。我们可以采用SGD来进行训练(记住batch m >1),也可以用其他算法比如Adagrad等优化算法。在训练过程中,我们的标准化是基于mini-batch的,因为这样能够有效的训练,但是在推断过程中,这是不需要也不必要的。因为我们更希望输出只确定性的取决于输入,所以当网络完成训练,就使用总体统计来进行一个标准化,而不是小批量的数据
如果说忽略掉 ϵ \epsilonϵ ,我们得到标准化后的激活值具有相同的均值0和方差1。我们使用无偏方差估计,其中期望是在大小为m mm的小批量训练数据上得到的,方差也是。我们的方差和均值在推断的时候已经是固定了的,因此这时候标准化只是一个简单的线性变换。
论文中的算法2总结了训练BN网络的过程
在每次做Mini-Batch训练时,都会有那个Mini-Batch里m个训练实例获得的均值和方差,现在要全局统计量,只要把每个Mini-Batch的均值和方差统计量记住,然后对这些均值和方差求其对应的数学期望即可得出全局统计量,注意这里标准差使用的期望是其无偏估计:
就这样我们在推断的时候可以得到我们均值和方差,有了均值和方差,每个隐层神经元也已经有对应训练好的Scaling参数和Shift参数,就可以在推导的时候对每个神经元的激活数据计算NB进行变换了,在推理过程中进行BN采取如下方式:
这个公式其实和训练时
是等价的,通过简单的合并计算推导就可以得出这个结论。那为什么会写成这样呢,在我看了一些参考来说,其实作者这样写是因为在推断的时候,对于每一个隐藏层来说
这两个值都是固定值,这样这两个值可以事先算好存起来,在推理的时候直接用就行了,这样比原始的公式每一步骤都现算少了除法的运算过程,可能乍一看也没少多少计算量,但是如果隐层节点个数多的话节省的计算量就比较多了。
3.2 BN 卷积神经网络 Batch-Normalized Convolutional Networks
BN可以应用于网络的任何激活集合。论文中主要是仿射变换和非线性的变化:
W 和 b 都是模型学习的参数的,g gg 是非线性的比如ReLU或 sigmoid。这个公式涵盖了全连接层和卷积层,我们在激活之前经过BN层,由于我们对 W u+b进行标准化,偏置 b bb 可以忽略,因为它的效应将会被后面的中心化忽略 (偏置的作用会归入到算法1的 β \betaβ )。因此, z = g ( W u + b ) 会被
替代,并且BN变化独立的应用在每一维中,每一维都有独立的学习参数γ ( k ) , β ( k )
除此之外,我们希望对于卷积层,标准化后还是遵循卷积的特性——对同一特征映射的不同元素,在不同的位置,以相同的方式进行标准化。这里的BN作用在特征图上,而不是激活函数上。
这里穿插一下为什么可以去掉偏置层的原因,我们可以做一个较为简单的推导,因为加了偏置层b后结果是一样
首先来说
经过推导后,我们会发现其实偏置是没有必要的。
3.3 BN 允许更高的学习率 Batch Normalization enables higher learning rates
在传统的方法中,高的学习率会导致梯度消失或者爆炸,或者有可能陷入了局部最小值。而BN的出现,使得数据通过网络进行传播的时候它可以防止层参数的微小变化被放大。例如,这使sigmoid非线性更容易保持在它们的非饱和状态,这对训练深度sigmoid网络至关重要,但在传统上很难实现。
而BN使得对训练的参数更有弹性。一般来说,大学习率会增加学习参数的缩放,这样会导致在反向传播中放大梯度并导致模型爆炸。然而,通过BN通过层的反向传播不受参数缩放的影响。并且,对于标量a
因此
因此标量不影响层的Jacobian行列式, 从而不影响梯度传播。此外, 更大的权重会导致更小的梯度, 并且BN会稳定参数的增长
3.4 BN 正则化模型 Batch Normalization regularizes the model
在使用BN进行训练的时候,我们会发现一个训练实例是和同一个batch的训练实例相结合的,并且训练网络不会给确定的实例一个确定的值,在实验中,我们发现这种情况提高了模型的泛化能力。在之前的Dropout通常可以用来减小过拟合,在BN也有类似的结果,可以较好的防止过拟合。
实验 Experiments
随时间激活 Activations over time
作者为了去验证BN在训练时可以用来对抗Internal covariate shift,然后MNIST手写数据集中进行了一个实验。用了一个很简单的网络,只有三个全连接层,每层有100个激活,激活函数利用 sigmoid 函数,并且初始化权重为随机小高斯值。并且最后一层为全连接层,也就是分类层,分为10类,loss为交叉熵。作者训练此网络训练了50000次,batch设为60,并且在每个隐藏层之间都加入BN层。
下图反应了一下有无BN层的准确率,我们会发现有BN层的网络的准确率会更高。
为了寻找原因,在图(b,c)中,作者研究了两个网络中,最后一个影藏层的激活值,我们会发现,没有用BN的波动比较大,使得训练的难度被加大。
所以相比之下,BN网络中的数据分布更加稳定,更加有助于训练。
ImagetNet 分类 ImageNet Classification
这里简单的介绍了一下,作者希望用BN进行来训练,在这里选取了Inception 来进行一个训练,也就是我们说的GooLeNet。但是与传统的不同,首先主要区别是5×5卷积层被两个连续的3x3卷积层替换,最多可以有128个滤波器。并且在后面对这个Inception进行了添加了BN层。如果我没有记错,这就是后面的Inception v2
加速 BN 网络 Accelerating BN Networks
由于简单的添加BN层不能完全体现BN的优势,所以作者还对网络和一些训练超参数进行了一些改变
增加学习率(Increase learning rate):在BN中,可以提高学习率并且没有任何副作用
去掉Dropout(Remove Dropout):在实验中发现,去掉Dropout能得到更高的准确率,并且也能达到正则化的效果
减小 L 2 中的正则化(Reduce the L 2weight regularization):虽然这个正则化是为了控制过拟合,但是去掉以后,损失的权重减小了五倍,也提高了准确率,所以是有利的。
加速学习率衰减(Accelerate the learning rate decay):在训练Inception时,学习率呈指数衰减。因为我们的网络训练速度比Inception更快,所以我们将学习速度降低加快6倍
删除局部响应化(Remove Local Response Normalization):虽然在Inception和很多网络都有用,但是在BN中是没有必要的
更彻底打乱训练样本(Shuffle training examples more thorouthly):更彻底打乱,可以防止同一个例子一起出现在小批量数据中,这导致验证准确率提高了约1%。
减少光照扭曲(Remover the photometric distortions):(这个不知道怎么解释比较好)
单网络分类 Single-Network Classification
我们评估了下面的网络,所有的网络都在LSVRC2012训练数据上训练,并在验证数据上测试:
Inception:在开头描述的网络,以0.0015的初始学习率进行训练。
BN-Baseline:每个非线性之前加上批标准化,其它的与Inception一样。
BN-x5:带有批标准化的Inception,初始学习率增加5倍到了0.0075。原始Inception增加同样的学习率会使模型参数达到机器无限大。
BN-x30:类似于BN-x5,但初始学习率为0.045(Inception学习率的30倍)。
BN-5-Sigmoid:类似于BN-x5,但使用sigmoid非线性来代替ReLU。我们也尝试训练带有sigmoid的原始Inception,但模型保持在相当于机会的准确率。
得到下图的结果
从结果我们可以看出,我们的BN-Baseline只用了一半的训练就达到了正常Inception的准确率。并且其他带有BN层的网络也显著提高了训练速度和学习率。
这里有个点很有趣,或者说作者也无法解释,我们提高学习率使得BN-x30一开始的训练比较慢,但是居然使他能够达到更高的准确率。
并且我们从BN-x5-Sigmoid中可以证明BN可以减少Interal Covariate Shift,用了BN,就算是sigmoid也可以达到一个69.8%的准确率,但是如果不是的话,都打不到1/1000的准确率。
组合分类 Ensemble Classification
作者修改后的组合模型提高了当时ImageNet以前的最佳结果,并且根据(Russakovsky等,2014)这超过了人类评估者的评估准确率(95%)。
对于我们的组合模型,我们使用了6个网络。每个都是基于BN-x30的,进行了以下一些修改:增加卷积层中的初始重量;使用Dropout(丢弃概率为5%或10%,而原始Inception为40%);模型最后的隐藏层使用非卷积批标准化。组合预测的结果是基于组成网络的预测类概率的算术平均。
BN-Inception组合在验证集的5万张图像上取得了4.9% top-5
的错误率。
论文总结 Conclusion
我们提出了一个新的机制,大大加快了深度网络的训练。它是基于 Internal Covariate Shift ,这会使得机器学习系统训练复杂化,并且也可以适用于很多的神经网络,并且从网络的内部激活中去除它可能有助于训练。BN每个激活只增加了两个额外的参数,这样做可以保持网络的表示能力。我们提出了一个算法,其用于构建,训练和执行推断BN网络。所得到的网络可以用饱和非线性进行训练,能更容忍增加的训练率,并且通常不需要Dropout来进行正则化。
作者提到了,为了BN会用到循环神经网络之中,也就是RNN,因为其中的 Internal Covariate Shift 和梯度消失或爆炸可能特别严重,这将使我们能够更彻底地测试假设标准化改善了梯度传播。并且探索是否有助于传统意义上的域自适应——即网络执行BN是否能够更容易泛化到新的数据分布,也许仅仅是对总体均值和方差的重新计算。最后,作者很谦虚的说,可能这个算法还需要进行更多的改进和应用。
个人总结
所以总结一下BN的好处
不仅仅提高了训练的速度,同时也使得收敛速度大大加快。
使得调参变得更简单了,比如说可以使用更高的学习率,更简单的初始化
提高了模型的泛化能力,类似与Dropout的效果,可以防止过拟合。
在使用BN的时候,也需要注意几个点
batch size尽可能设置大点,设置小后表现可能没那么好,设置的越大求的均值和方差越接近整个训练集的均值和方差。这个我觉得可以利用大数定律来进行一个证明。
我们的BN层可以放在卷积层(Conv)和激活层(如ReLU)之间,并且我们的卷积层可以去掉bias,因为是没有用的,在前面也已经推导过的。
BN和dropout不要同时用,BN和Dropout单独使用都能减少过拟合并加速训练速度,但如果一起使用的话并不会产生1+1>2的效果,相反可能会得到比单独使用更差的效果。详细可以看论文Understanding the Disharmony between Dropout and Batch Normalization by Variance Shift,并且有时候,用BN比Dropout更好,比如Don’t Use Dropout in Convolutional Networks - KDnuggets有提到。