注:本文翻译的原文为Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift中的BN理论知识(到3.1小节),同时会在翻译过程中加入一些自己的理解。目的是加深对提出BN的目的及其原理的理解。英语水平以及知识水平有待提高,有不足之处请大家提出来。
http://blog.csdn.net/linmingan/article/details/50780761
Abstract:当前神经网络层之前的神经网络层的参数变化,引起神经网络每一层输入数据的分布产生了变化,这使得训练一个深度神经网络(Deep Neural Networks)变得复杂。这样就要求使用更小的学习率,参数初始化也需要更为谨慎的设置。并且由于非线性饱和(注:如sigmoid激活函数的非线性饱和问题),训练一个深度神经网络会非常困难。我们称这个现象为:internal covariate shif;同时利用归一化层输入解决这个问题。我们将归一化层输入作为神经网络的结构,并且对每一个小批量训练数据执行这一操作。Batch Normalization(BN) 能使用更高的学习率,并且不需要过多的注重参数初始化问题。BN 的过程与正则化相似,在某些情况下可以去除Dropout。将BN应用到一个state-of-the-art的图片分类模型中时,使用BN只要1/14的训练次数就能够达到同样的精度。使用含有BN神经网络模型能提升现有最好的ImageNet分类结果:在top-5 验证集中达到4.9%的错误率(测试集为4.8%),超出了人类的分类精度。
1 Introduction
深度学习极大的促进了许多领域的发展,如视觉、语音以及其他领域。随机梯度下降法(SGD)已经证明能够有效的训练深度神经网络,并且在SGD中加入momentum和Adgrad变量也达到了最好的性能。SGD优化参数 θ θ 来最小化损失函数
θ=argminθ1N∑i=1Nl(Xi,θ) θ = a r g m i n θ 1 N ∑ i = 1 N l ( X i , θ )
,其中 X1…N X 1 … N 为训练数据集。在使用SGD时,每次迭代我们使用一个大小为 m m 的小批量数据X1…mX1…m 。通过计算 1m∂l(Xi,θ)∂θ 1 m ∂ l ( X i , θ ) ∂ θ
来逼近损失函数关于权值的梯度。在迭代过程中使用小批量数据相比使用一个样本有几个好处。首先,由小批量数据计算而来的损失函数梯度是由整个训练数据集的损失函数梯度的估计。并且随着小批量数据大小的增加,其性能会越好。其次,由于现代计算平台的并行性,小批量训练会比单个样例训练更高效。
尽管随机梯度下降法简单有效,但却需要谨慎的调整模型的参数,特别是在优化过程中加入学习率和参数初始化方式的选择。每一层的输入都会受之前所有层的参数影响,并且随着网络越深,即使参数的变化很小也为对每一层的输入产生很大的影响。这使得训练一个网络变得十分复杂。
神经网络层输入分布的改变,使得神经网络层必须不停的适应新的数据分布。当一个学习系统的输入数据分布产生变化,我们称这种现象为:Experience Covariate Shift. 解决这种现象的典型方法是领域适应。然而,Covariate Shift的概念的适用性能够从整个学习系统扩展到该系统的一部分,比如一个子网络或者其中的一层。考虑一个网络计算 l=F2(F1(u,θ1),θ2) l = F 2 ( F 1 ( u , θ 1 ) , θ 2 )
其中 F1 F 1 和 F2 F 2 是任意的变换函数。通过学习参数 θ1 θ 1 和 θ2 θ 2 来最小化 l l 。θ2θ2 的学习:如果 X=F1(u,θ1) X = F 1 ( u , θ 1 ) 为子网络的输入,那么 l=F2(X,θ2). l = F 2 ( X , θ 2 ) .
则 θ2 θ 2 的更新为 ( m m :批量数据的样本数;αα :学习率) θ2←θ2−αm∑i=1m∂F2(Xi,θ2)∂θ2 θ 2 ← θ 2 − α m ∑ i = 1 m ∂ F 2 ( X i , θ 2 ) ∂ θ 2
因此,输入数据分布相同这一特性,使得子网络更容易训练。这与训练数据和测试数据有相同的分布是相似的。因此保持 X X 的分布不变是有利的。这样,θ2θ2 就不需要为了弥补 X X 的分布的改变而重新进行调整。
保持一个子网络的输入数据分布不变,对该子网络以外的隐藏层也有积极的作用。考虑一层激活函数为sigmoid函数的神经网络层 z=g(Wu+b)z=g(Wu+b) ,其中 u u 为该层的输入,权值矩阵 WW 和偏置 b b 为该层需要学习的参数,g(x)=11+exp(−x)g(x)=11+exp(−x). 随着 |x| | x | 的增大, g′(x) g ′ ( x ) 趋向0 (因为 g(x)→1 g ( x ) → 1 )。这意味着在 x=Wu+b x = W u + b 的每一维中除了绝对值较小的,其他的流向 u u 的误差会消失,同时模型的训练变得很缓慢。而同时 xx 是由 W,b W , b 以及该层以下的全部神经网络层的参数决定的,所有在训练期间改变这些参数有可能使 x x 中许多维偏移到非线性饱和端,从而降低了收敛速度。并且这个影响会随着网络层数的增加而加剧。在实际中非线性饱和端问题以及梯度弥散问题经常用ReLU,合适的初始化以及较小的学习率。如果我们能够确保非线性输入的数据分布更稳当的话,那么出现非线性饱和端问题的概率则会更小,并且能够加速网络的训练。
我们称在训练深度神经网络的过程中,网络内部节点的分布发生变换这一现象为,Internal Covariate Shift.。而消除这个现象能够加速网络的训练。我们提出了Batch Normalization ,通过减少依赖参数缩放和初始化,进而缓解Internal Covariate Shift,并动态的加速深度神经网络的训练速度。BN 允许使用更高的学习率,而不会有发散的风险。进一步的,BN能够正则化模型,并且不需要Dropout。最后,BN能够使用s型激活函数,同时不会陷入饱和端。
在4.2小节我们将BN加入一个分类模型,该模型在ImageNet中的表现最好。结果显示BN只需要使用之前的7%训练数次,就能够达到该模型的分类精度,并且最终能够明显的提高分类精度。通过利用嵌有 BN 的已训练好的模型,我们获得top-5的错误率,这超出了在 ImageNet 的已知分类精度。
2 Towards Reducing Internal Covariate Shift
我们将 Internal Covariate Shift 定义为:在神经网络的训练过程中,由于参数改变,而引起的神经网络激活值分布的改变。我们通过缓解 Internal Covariate Shift 来提高训练。在训练的过程中保持神经网络层输入的分布不变,来提高训练数据。我们已经知道,在训练的过程中加入白化处理能,如0均值1方差化和去相关化,能够加速模型的收敛。当每一层的输入来自该层之前的神经网络层,对于每一层的输入来说很容易获得相同的白化。通过对每一层的输入进行白化处理,我们能够保持输入的分布,从而消除 Internal Covariate Shift 的病态影响。
我们可以在每一步的训练中白化激活值,也可以通过直接调整模型的结构或者依照激活值来修改优化函数的参数进行白化。然而,如果这些方法在优化步骤中执行,那么在更新参数的时候,必须先计算归一化后的激活值的误差,这降低了梯度下降法的效果。(个人理解:归一化不能在求的激活值之后进行,不然流到上一层参数的误差值会越来越小,从而影响模型的学习,也就是梯度弥散问题。)举个例子,考虑一层神经网络层, uu 为输入, b b 为偏置值。并且对该神经网络层的激活值减均值归一化:x̂ =x−E[x]x^=x−E[x],其中 x=u+b,χ={x1...N} x = u + b , χ = { x 1... N } 为由训练数据集生成的该神经网络层输入的一个集合(训练数据集 X X 前向传播到该层), E[x]=1N∑Ni=1xiE[x]=1N∑i=1Nxi。如果 b b 的梯度与 E[x]E[x] 无关,有 b←b+∇b,∇b∝−∂l/∂x̂ b ← b + ∇ b , ∇ b ∝ − ∂ l / ∂ x ^ 。则 u+(b+∇b)−E[u+(b+∇b)]=u+b−E[u+b](注:=x−E[x]) u + ( b + ∇ b ) − E [ u + ( b + ∇ b ) ] = u + b − E [ u + b ] ( 注 : = x − E [ x ] ) 。因此当归一化和参数 b b 的更新同时进行的时候,会使该神经网络层的输出没有变化,进一步的导致损失函数的值没有变化。随着训练的继续,bb 一直在增长而损失函数的值却一直不变。当归一化操作不仅中心化激活值,同时对其进行缩放,这个现象会更严重。在初步的实验中我们观察到,如果归一化参数不在梯度下降中计算的话,会使模型参数膨胀。
上述方法的问题在于,梯度下降没有考虑归一化的情况。为了处理该问题,我们要确保对于任何参数,神经网络都由期望分布产生激活值。这样就能使模型参数的损失函数梯度都把归一化的情况考虑进去。与之前的例子相同,向量 x x 为一层神经网络层的输入,χχ 为由训练数据集生成的该神经网络层输入的一个集合。那么归一化操作为 x̂ =Norm(x,χ) x ^ = N o r m ( x , χ )
该归一化操作不仅考虑了 x x ,同时还考虑了所有的训练样本 χχ 。如果 x x 是由其他层产生的,那么 χχ 中的所有样例都依赖于 θ θ 。对于反向传播算法,我们就需要计算 ∂Norm(x,χ)∂x和∂Norm(x,χ)∂χ; ∂ N o r m ( x , χ ) ∂ x 和 ∂ N o r m ( x , χ ) ∂ χ ;
如果忽略了后面那一项,就会出现之前描述的模型参数膨胀问题。根据这个框架,白化操作的计算量非常大。因为白化需要计算协方差矩阵 Cov[x]=Ex∈χ[xxT]−E[x]E[xT] C o v [ x ] = E x ∈ χ [ x x T ] − E [ x ] E [ x T ] 、协方差矩阵的负平方根来产生白化激活值 Cov[x]−1/2(x−E[x]) C o v [ x ] − 1 / 2 ( x − E [ x ] ) 以及归一化相对于的梯度。这就驱使我们寻找一种可微,并且在参数更新的时候不需要对整个训练数据集进行分析的神经网络层输入归一化方法。
前人的一些方法,如利用统计学计算单个训练样本,或者在用于图像处理的神经网络中,根据不同的局部区域选择不同的特征图。然而,由于去掉了激活值的绝对值缩放,而改变了网络的表征能力。我们希望通过同时考虑单个训练样本和整个训练样本集的统计信息来归一化激活值,从而在网络中保留更多的信息。
3 Normalization via Mini-Batch Statistics
因为对于每一层的输入进行白化花费较高,并且也不是处处可微,所有我们做了两个必要的简化。第一是,我们对标量特征进行单独的进行零均值一方差归一化,来代替白化同时对层的输入和输出同时进行归一化。对于有 d d 维输入 x=(x(1)...x(d))x=(x(1)...x(d)) 的神经网络层,我们将利用下试归一化每一维: x̂ (k)=x(k)−E[x(k)]Var[x(k)]‾‾‾‾‾‾‾‾√ x ^ ( k ) = x ( k ) − E [ x ( k ) ] V a r [ x ( k ) ]
上式中的期望和方差由训练数据集计算得到。根据 LeCun 的一篇论文,该归一化能够加速收敛,甚至是特征之间没有相关性。
简单的归一化神经网络层的输入,可能会改变该层的表征能力。例如,对 sigmoid 函数的输入进行归一化,会使归一化后的输入趋向 s 型函数的线性端。为了避免这样的情况出现,我们确保穿插在网络内部的变换能够表示同样的变换。为了达到这样的目的,我们对每一个激活值 x(k) x ( k ) 都引入一对参数 γ(k) γ ( k ) 和 β(k) β ( k ) ,这两个参数能够缩放和平移归一化后的输入: y(k)=γ(k)x̂ (k)+β(k). y ( k ) = γ ( k ) x ^ ( k ) + β ( k ) .
这两个参数与模型原始的参数一起学习,并恢复了模型的表征能力。当 γ(k)=Var[x(k)]‾‾‾‾‾‾‾‾√,β(k)=E[x(k)] γ ( k ) = V a r [ x ( k ) ] , β ( k ) = E [ x ( k ) ] 就能够求得原来的激活值。
神经网络的训练是基于整个训练数据集的,在batch的设置中,我们可以用整个训练数据集来归一化激活值。但是,当我们使用随机梯度下降法的时候这一选择是不实际的。因此我们做了第二个简化:在随机梯度下降中我们采用mini-batch的方式,这样我们就能够通过每个mini-batch为每个激活值计算出对应的均值和方差。通过这样的方式,归一化所需统计信息就能够完全被考虑到梯度下降中去。利用mini-batch就能计算每一维激活值的方差,而不是计算所有激活值的协方差矩阵。如果是计算协方差矩阵的话,batch的数量可能比激活值向量的大小还要小,这样就会产生奇异协方差矩阵。
假设有一个mini-batch B ,其大小为 m m 。因为是对激活值的每一维进行归一化,所有我们只考虑其中的一个激活值 x(k)x(k) ,同时在下文中忽略 k k 。那么在一个mini-batch中我们有 mm 个激活值, ={x1...m}. B = { x 1... m } .
x̂ 1...m x ^ 1... m 为归一化后的值,同时 y1...m y 1... m 为 x̂ 1...m x ^ 1... m 的线性变换。于是有BN变换: BNγ,β:x1...m→y1...m B N γ , β : x 1... m → y 1... m
算法1为BN变换,其中 ε ε 是一个常数(趋于0),为了保证计算方差时的稳定性。
BN变换能被加入网络中,并对任何的激活值执行BN变换。在等式 y=BNγ,β(x) y = B N γ , β ( x ) 中,我们引入了两个需要学习的参数 γ,β γ , β 。但需要注意的是,BN变换不仅仅与单个训练样本相关,也与mini-batch中的其他训练样本有关。由缩放和平移变换而来的 y y 作为下一层的输入。虽然归一化激活值 x̂ x^ 被包含在BN变换中,但确实非常重要的存在。由于mini-batch中的样本都来自同一个分布,因此在忽略 ε ε 的情况下, x̂ x ^ 中的每一个元素都为0均值1方差分布。即 ∑mi=1x̂ i=0,1m∑mi=1x̂ 2i=1 ∑ i = 1 m x ^ i = 0 , 1 m ∑ i = 1 m x ^ i 2 = 1 。每个 x̂ (k) x ^ ( k ) 可看做含有线性变换 y(k)=γ(k)x̂ (k)+β(k) y ( k ) = γ ( k ) x ^ ( k ) + β ( k ) 以及原始网络其他操作的子网络的输入。子网络的输入保持着相同的均值和方差,并允许归一化后不同的 x̂ (k) x ^ ( k ) 之间的联合概率分布在训练过程中可变。我们希望这一归一化能够加速子网的训练,并最终加速整个网络的训练。
在训练过程中我们需要计算流过BN变换的误差,同时也要计算BN变换中涉及到的参数的误差。利用链式规则:
∂l∂x̂ i=∂l∂yi⋅γ ∂ l ∂ x ^ i = ∂ l ∂ y i ⋅ γ
∂l∂σ2=∑i=1m∂l∂x̂ i⋅(xi−u)⋅−12(σ2+ε)−3/2 ∂ l ∂ σ B 2 = ∑ i = 1 m ∂ l ∂ x ^ i ⋅ ( x i − u B ) ⋅ − 1 2 ( σ B 2 + ε ) − 3 / 2
(个人理解: ∂l∂σ2=∑mi=1∂l∂x̂ i⋅∂x̂ i∂σ2 ∂ l ∂ σ B 2 = ∑ i = 1 m ∂ l ∂ x ^ i ⋅ ∂ x ^ i ∂ σ B 2 ,因为方差是由mini-batch中的每一个样本计算而来的,所有求方差的梯度时候必须考虑到所有的样本,即有前面的求和。) ∂l∂u=⎛⎝⎜⎜⎜∑i=1m∂l∂x̂ i⋅−1σ2+ε‾‾‾‾‾‾‾√⎞⎠⎟⎟⎟+∂l∂σ2⋅∑mi=1−2(xi−u)m ∂ l ∂ u B = ( ∑ i = 1 m ∂ l ∂ x ^ i ⋅ − 1 σ B 2 + ε ) + ∂ l ∂ σ B 2 ⋅ ∑ i = 1 m − 2 ( x i − u B ) m
(个人理解: ∂l∂u=(∑mi=1∂l∂x̂ i⋅∂x̂ i∂u)+∂l∂σ2⋅∂σ2∂u ∂ l ∂ u B = ( ∑ i = 1 m ∂ l ∂ x ^ i ⋅ ∂ x ^ i ∂ u B ) + ∂ l ∂ σ B 2 ⋅ ∂ σ B 2 ∂ u B ,因为均值是由mini-batch中的每一个样本计算而来的,所有求方差的梯度时候必须考虑到所有的样本,即有前面的求和;另外由于方差的计算需要用到均值也就有了加号后面的项。) ∂l∂xi=∂l∂x̂ i⋅1σ2+ε‾‾‾‾‾‾‾√+∂l∂σ2⋅2(xi−u)m+∂l∂u⋅1m ∂ l ∂ x i = ∂ l ∂ x ^ i ⋅ 1 σ B 2 + ε + ∂ l ∂ σ B 2 ⋅ 2 ( x i − u B ) m + ∂ l ∂ u B ⋅ 1 m
(个人理解: ∂l∂xi=∂l∂x̂ i⋅∂x̂ i∂xi+∂l∂σ2⋅∂σ2∂xi+∂l∂u⋅∂u∂xi ∂ l ∂ x i = ∂ l ∂ x ^ i ⋅ ∂ x ^ i ∂ x i + ∂ l ∂ σ B 2 ⋅ ∂ σ B 2 ∂ x i + ∂ l ∂ u B ⋅ ∂ u B ∂ x i ,因为 x̂ i x ^ i 、方差和均值均与 xi x i 有关,所以求其梯度时必须考虑上述三个变量。) ∂l∂γ=∑i=1m∂l∂yi⋅x̂ i ∂ l ∂ γ = ∑ i = 1 m ∂ l ∂ y i ⋅ x ^ i
∂l∂β=∑i=1m∂l∂yi ∂ l ∂ β = ∑ i = 1 m ∂ l ∂ y i
( γ,β γ , β 与偏置 b b <script type="math/tex" id="MathJax-Element-100">b</script> 相似。)
因此BN变换是将归一化激活值引入神经网络的一种可微变换。这确保了网络可训练性,以及神经网络层能够持续学习输入数据分布。从而能够减少Internal Covariate Shift发生,同时加速网络的训练。进一步的,将学习好的仿射变换应用到归一化激活值中,能够允许BN变换比表示同样的变换,进而保存神经网络的表征能力。
好了,关于BN的翻译先到此。原文后面的内容主要是针对CNN的BN使用,以及说明BN能够使用更高的学习率,可以去掉Dropout,能够正则化模型等等。作者也介绍了加速BN训练的一些小技巧。
最后说一下自己在BN的实验上的效果。在我自己关于语音处理的数据集中利用BN的分类正确率能提升到68%,而不用的时候只能53%。同时收敛速度非常快,原来需要200次迭代的训练,利用BN只需要20次。这在大数据集训练的时候大大减少了实验周期。