零基础理解批量归一化(batch normalization)

本文从最基础的部分讲起,并包含很多对理解过程中的问题的思考。最近深度学习入门,读文献常常很多不懂,批量归一化这部分很重要,学习中有很多思考,写出来与大家分享。其中的问题或理解的错误之处拜托大家批评指正。
(Batch Normalization: Acceleration Deep Network Training by Reducing Internal Covariate Shift 研读笔记)

什么是批量归一化?

深度神经网络的训练在训练时先前的层的权值参数改变会导致层间输入值的分布情况也随之改变,这就使神经网络的训练变得困难。也使我们只能使用较小的学习率、更谨慎的参数初始化,且训练非线性模型变得非常困难。
文章作者把这种现象称为内部协变量偏移。
而批量归一化便是作者为了解决这一问题而提出的方案:将层间输入值进行归一化。而“批量”则是因为归一化操作是对训练的小批量数据进行的。
批量归一化这一操作极大地提高了训练的学习率,也使初始化的参数可以不那么谨慎,是加速训练的好方法。
下面让我们来看看到底为什么会有协变量偏移问题,这一问题是如何影响神经网络的训练的,以及批量归一化是如何操作的,又是为什么可以提高学习率、加速训练的。

1.相关背景知识:深度学习

零基础理解批量归一化(batch normalization)_第1张图片

1.1 神经网络的结构

我们知道,神经网络是如图所示的结构,具有输入层、输出层以及中间的隐含层。我们以前馈神经网络为例,前馈网络的目标是近似某个函数 f* 。例如对于分类器,y = f*(x) 将输入x映射到一个类别y。前馈网络定义了一个映射 y = f(x ; θ \theta θ ),并且学习参数 θ \theta θ 的值,使它能够得到最佳的函数近似。
因为线性模型具有很大的局限性,为了扩展线性模型来表示非线性函数,我们考虑对输入x进行非线性变换 ϕ \phi ϕ ,再将线性模型作用于 ϕ \phi ϕ(x)。此时的 ϕ \phi ϕ 就定义了一个隐藏层。
那么如何选择映射 ϕ \phi ϕ ? 此前人们会使用通用的 ϕ \phi ϕ 或是相关领域专家去手动设计它。而深度学习的策略是去学习 ϕ \phi ϕ ,我们有一个模型 y = f(x ; θ \theta θ , ω \omega ω) = ϕ \phi ϕ (x ; θ \theta θ ) T )^{T} )T ω \omega ω 。可以看出我们有两个参数, 用于从一大类函数中学习 ϕ \phi ϕ 的参数 θ \theta θ ,以及用于将 ϕ \phi ϕ(x) 映射到所需的输出的参数 ω \omega ω

1.2 神经网络是如何训练的?

在神经网络的训练中,我们会先设定损失函数,这个损失函数表征预测结果和实际标注之间的差距,因此我们的训练过程就是寻找损失函数的最小值,我们知道最小值处肯定是梯度为零的,因此可以通过梯度方法如随机梯度下降法去寻找。

零基础理解批量归一化(batch normalization)_第2张图片
下面我们来看神经网络的训练过程。在训练多层神经网络的时候,简单感知机的训练方法不再适用,从而需要更加强大的算法——逆误差传播算法。
假设训练集D={(x1,y1),(x2,y2)…(xm,ym)}。且定义如上形式的多层前馈网络。其中,输入层的权重用ν表示,隐含层到输出层的权重用ω表示。那么第h个隐藏层的神经元的输入为:
α h = ∑ i = 1 d v i h x i \alpha_{h} = \sum_{i=1}^{d} v_{ih} x_{i} αh=i=1dvihxi

第j个输出层神经元的输入值为
β j = ∑ h = 1 q w h j b h \beta_{j} = \sum_{h=1}^{q} w_{hj} b_{h} βj=h=1qwhjbh

设输出神经元采用函数f(一般为relu或softmax函数),则神经网络对于(xk,yk)的训练结果输出为
y ^ j k = f ( β j ) \hat y_{j}^{k} = f(\beta_{j}) y^jk=f(βj)
训练的均方误差为
E k = 1 2 ∑ j = 1 l ( y ^ k j − y k j ) 2 E_{k} = \frac{1}{2} \sum_{j=1}^{l} (\hat y_{k}^{j} - y_{k}^{j})^2 Ek=21j=1l(y^kjykj)2
我们将该均方误差作为损失函数,参数更新公式为
v ← v + Δ v v \leftarrow v+ \Delta v vv+Δv
逆误差传播算法使用梯度下降策略,其参数调整方向为目标的负梯度方向。对于误差Ek、学习速率η,有:
Δ w h j = − η ∂ E k ∂ w h j \Delta w_{hj} = -\eta \frac{\partial E_{k}}{\partial w_{hj}} Δwhj=ηwhjEk
逆误差传播,顾名思义,其 ω h j ω_{hj} ωhj 先影响到了第j个输出层的神经元的输入值 β j β_{j} βj ,而后再传播影响到输出值,最后再影响到其误差 E k E_{k} Ek
总结:训练时先初始化权重等参数,然后一层层传递到最后,得到预测结果后,再去比较它与实际标注的差距(即损失函数),然后通过梯度下降策略去调整参数,再进行一次传播,经过多次训练,直到损失函数到达极小值。

2 什么是内部协变量偏移问题?

了解神经网络如何训练后,我们便可以更容易地去理解内部协变量偏移问题。在这里,协变量可以看作是输入变量。
我们可以看到训练过程中,层间的权重会不断改变和调整,而前面层权重参数的改变会影响后面层的输入,当网络的深度很大时,层间的关联性变得很高,前面层的一点改变积累到后面会是很大的影响。也就是经过前面层参数的改变,一层层积累下来,到某一层时的输入值与上一次训练(此次参数更新前)的输入值的分布情况可能会有很大的差距。
而一般的深度神经网络都要求输入变量在训练数据和测试数据上的分布是相似的,这是通过训练数据获得的模型能够在测试集获得好的效果的一个基本保障。当输入的分布在参数更新前后有较大改变时,网络要去不断的适应新的数据分布,进而使得训练变得异常困难,我们只能使用一个很小的学习速率和精调的初始化参数来解决这个问题。而且这个中间层的深度越大时,这种现象就越明显。由于是对层间数据的分析,也即是内部(internal),因此这种现象叫做内部协变量偏移(internal Covariate Shift)。

3 具体来看什么是批量归一化?

批量归一化通过归一化步骤使每层输入的均值和方差在训练中是确定的,缓解了内部协变量偏移问题,同时降低了梯度对参数的依赖,降低了梯度发散的几率,提高了学习率,也降低了对dropout的需求。另外由于可以防止网络陷入平缓区,也让我们可以使用平缓的非线性函数如softmax。
我们知道在进行训练时常常会对训练集的输入数据进行“白化”处理,即使数据均值为0,方差为1。这是针对输入到第一层也就是输入层的数据而进行的操作。这一操作可以加快训练的收敛速度。因此作者提出可以对内部每一层的输入数据都进行“白化”操作,应当也是对训练非常有利的。
由于对每层的输入值全体作“白化”操作计算量非常大,且不是处处可微的,作者做了两步简化。
首先是不再去把每层的特征输入和输出共同做白化,而是独立地对每个特征图去做。对于一层具有d维输入向量 x = ( x ( 1 ) x^{(1)} x(1) x ( d ) x^{(d)} x(d) ),将会对他的每一维去做归一化:
x ^ ( k ) = x ( k ) − E [ x ( k ) ] V a r [ x ( k ) ] \hat x^{(k)} = \frac{x^{(k)}-E[x^{(k)}]}{\sqrt {Var[x^{(k)}]}} x^(k)=Var[x(k)] x(k)E[x(k)]
其中期望和方差是训练数据集的期望和方差。
另外要注意由于直接将每层的输入归一化操作可能会降低网络的拟合、表示能力。例如将一个sigmoid函数前的输入值归一化后,均值为0方差为1,则数据如图主要集中在sigmoid函数中间那段近似线性的部分,非线性性大大降低。
零基础理解批量归一化(batch normalization)_第3张图片
因此作者对每一维的 x ( k ) x^{(k)} x(k) 引入一对参数 γ ( k ) \gamma^{(k)} γ(k) , β ( k ) \beta^{(k)} β(k) ,用于对标准化后的数据进行缩放(scale)和平移(shift),当参数分别初始化为 σ B \sigma_{B} σB μ B \mu_{B} μB (均值和方差)时,标准化的变量被还原为原来的值。
y ^ ( k ) = γ ( k ) x ^ ( k ) + β ( k ) \hat y^{(k)} = \gamma^{(k)} \hat x^{(k)}+\beta^{(k)} y^(k)=γ(k)x^(k)+β(k)
第二个简化是由于对整个数据进行计算是代价非常大的,且用随机梯度下降法时不现实,因为随机梯度下降是对小批量做的,因此我们也用小批量(mini-batch)去估计每个激活值的均值和方差。
下面我们看bn的算法:

零基础理解批量归一化(batch normalization)_第4张图片
其中 ϵ \epsilon ϵ 是一个很小的值,为了防止分母为零。我们来看批量归一化具体的步骤:

零基础理解批量归一化(batch normalization)_第5张图片
首先输入的数据是“白化”过的,输入到第一层也就是输入层中,如果没有批量归一化,它将直接乘上此处的权重参数、加上偏置项再通过一个ReLU函数后便作为下一层(隐藏层的第一层)的输入即 h 1 h_{1} h1 。现在我们加入批量归一化的操作,就是将乘完权重 W 后的数据 s 1 s_{1} s1 先减掉这一批量数据的均值和方差,得到 s 2 s_{2} s2 后再去进行缩放(乘以 γ \gamma γ) 和平移(加上 β \beta β)。得到 s 3 s_{3} s3 后再经过一个 ReLU 函数,再得到 h 1 h_{1} h1 作为下一层(隐藏层第一层)的输入。
此处要注意为什么做批量归一化前不需要加上原本的偏置参数 b h 1 b_{h1} bh1 ?这是因为减去第一层 batch 个数据的均值 μ B \mu_{B} μB 后, b h 1 b_{h1} bh1 的作用会被抵消掉,所以在使用 BN 的层中没必要加入偏置项,其平移的功能将由 β \beta β 来代替。
γ \gamma γ β \beta β 如何确定?这两个参数将和其他的权重参数等一起用梯度方法训练,最终得到使损失函数最小的值,这时候所有层间的输入值的分布是确定的,是任意的确定的均值和方差,由 γ \gamma γ β \beta β 决定的。

零基础理解批量归一化(batch normalization)_第6张图片
该图运用链式法则,关于相关的参数进行了微分,可以看出批量归一化的变换是可微的,我们用这些梯度关系去进行参数的训练。

3.1 为什么要“批量”?

在梯度下降法中我们便是对一个小批量(mini-batch)进行计算。一个小批量所计算的损失函数的梯度是对整个训练集的梯度的一个估计,它的质量会随批量的增大而提高。且对一个含量m的批量进行计算比对单次训练数据计算m次要高效的多。

3.2 批量归一化网络的训练和预测

BN算法在训练时的操作就如我们上面所说,首先提取每次迭代时的每个mini-batch 的平均值和方差进行归一化,再通过两个可学习的变量恢复要学习的特征。但是在实际应用时就没有mini-batch 了,那么BN算法怎样进行归一化呢?实际上在测试的过程中,BN算法的参数就已经固定好了,首先进行归一化时的平均值为:
E [ x ] = E B [ μ B ] E[x] = E_{B}[\mu_{B}] E[x]=EB[μB]
即为所有mini-batch 的平均值的平均值,而方差为:
V a r [ x ] = m m − 1 ⋅ E B [ σ B 2 ] Var[x] = \frac{m}{m-1}·E_B [\sigma_B^2] Var[x]=m1mEB[σB2]
即每个批次的方差的无偏估计。
最终BN算法的训练和测试的流程如下图所示:
零基础理解批量归一化(batch normalization)_第7张图片

3.3 对于卷积层的批量归一化

对于卷积层我们额外希望归一化操作可以适应卷积的特征,因此处于同一个特征图不同位置的不同元素被进行相同的归一化操作。我们把一个mini-batch中所有位置的激活值一起进行归一化,如第一个算法表Alg.1中的B,我们令他同时包括一个mini-batch中的元素值和空间位置信息,因此一个大小为m的mini-batch和大小为 p × q p \times q p×q 的特征图的有效大小为 m ′ = m ⋅ p × q m' = m·p \times q m=mp×q 。我们对每个特征图学习一对参数 γ ( k ) \gamma^{(k)} γ(k) β ( k ) \beta^{(k)} β(k) ,而不是对每个激活值。因此第二个算法图Alg.2也有相似的简化,在预测阶段批量归一化的变换对一个特征图中的每个激活值是相通的线性变换。

4 总结

批量归一化的优势:
  1. 通过对输入和中间网络层的输出进行标准化处理后,减少了内部层间输入分布的改变,使得大部分的数据都其处在非饱和区域,从而保证了梯度能够很好的回传,避免了梯度消失和梯度爆炸;
  2. 减少梯度对参数或其初始值尺度的依赖性,使得我们可以使用较大的学习速率对网络进行训练,从而加速网络的收敛,让模型变得更加健壮,鲁棒性更强;
  3. 增加了网络的独立性,使后面的神经元单元不过分依赖前面的神经元单元。所以,它也可以看作是一种归一化手段,提高了网络的泛化能力,使得我们可以减少或者取消 Dropout,优化网络结构。

5 参考

  1. Batch Normalization: Acceleration Deep Network Training by Reducing Internal Covariate Shift
  2. 《深度学习》
  3. CSDN博主「man_world」文章:批量标准化(BN)、实例标准化(IN)、特征标准化(FN)。原文链接:https://blog.csdn.net/mzpmzk/article/details/80043076
  4. CSDN博主 「lzsffuture」文章:深度学习 — 优化入门四(Batch Normalization(批量归一化)一) 原文链接:https://blog.csdn.net/weixin_42398658/article/details/84560411
  5. 简书 「养薛定谔的猫」文章:从零开始机器学习-17 神经网络的训练过程 原文链接:https://www.jianshu.com/p/cc440fb27874

你可能感兴趣的:(学习笔记)