论文解析:Inception_V2(Batch Normalization)

740 阅读6分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Incepiont_V2(Batch Normalization)

痛点

 当我们使用SGD来更新神经网络的参数时,默认隐含着一个最基本的假设:minibatch上的数据分布和原始数据集中的数据分布是类似(一致)的,我们可以通过在minibatch上计算参数的梯度来更新网络对整个数据集的参数。那如果测试时数据的原始分布发生了较大的变化,那么训练所得的网络参数就会水土不服,面临covariate shift问题,需要通过domain adaptation来解决。而如果我们将整个神经网络的每一层都视为一个单独的存在,其训练和测试时输入的分布差异情况也会对其训练效率和最终表现有着较大影响,训练时由于输入的分布在不断变化,梯度的更新过于无序;测试时和训练时目标不一致,表现不佳。这种由于网络内部层输入分布发生变化造成的问题定义为 Internal covariate shift。作者提出了BN层来使得网络内每层的输入分布是固定的,给训练带来以下几项增益:

  1. 由于输入分布固定,减少了梯度消失也就是激活函数死区的可能,我们可以使用更大学习率来训练网络。
  2. 减少了对参数初始权重的依赖,不用怕梯度爆炸和消失
  3. 可以使用存在饱和区域的激活函数。

解决方案

 首先确定了我们的设计目标是希望网络内部每层的输入分布都应该是稳定的,而在LeCun之前的研究中论述过当网络的输入经过了白化,满足零均值、方差为1、去相关时,网络的训练收敛速度最快,因此我们希望设计一个模块使得每层网络的输入都应该是白化的。

原始白化

 首先考虑一下最原始的方案,如果我们只是要求网络的输入是白化的,直接对每层的输入数据进行归一化操作即可。但为此在前向传播时我们要计算整个训练集上的协方差矩阵,Cov[x]=Exχ[xxT]E[x]E[x]TCov[x]=E_{x\in \chi}[xx^T]-E[x]E[x]^T,这无疑是十分耗时的。而在反向传播时如果我们不考虑白化参数μ,σ2\mu,\sigma^2和输入的关系会可能使得网络的损失不变,而参数不断更新直到爆炸,举个例子:

假定某层网络的输入为μ\mu,输出为x=μ+bx=\mu+b,那么如果我们对其输出(下一层输入)进行零均值处理,得到x^=xE[x]\hat{x}=x-E[x]。而在反向传播时b=b+Δb,Δblossbb=b+\Delta b ,\Delta b \propto -\frac{\partial loss}{\partial b},如果我们忽略掉μ\mu对于b的依赖关系,那么Δb\Delta buu无关,则下一次前向传播时x^=u+b+ΔbE[u+b+Δb]=u+b+ΔbbΔbE[u]=u+bE[u+b]\hat{x}=u+b+\Delta b-E[u+b+\Delta b]=u+b+\Delta b-b-\Delta b-E[u]=u+b-E[u+b]和前一次别无二致,这就导致了网络输出不发生变化、损失不发生变化,而参数在不断更新。

那如果我们对白化的参数也考虑反向传播,就需要计算白化过程对训练集的偏导Norm(x,χ)χ\frac{\partial Norm(x,\chi)}{\chi},这更加的耗时耗力。 因此我们希望找到一个原始白化的改进方案,它要是可导的,简单的,不用对整个训练集进行。 ## Batch Normalization  作者对原始的白化操作做出了三个方面的改进:

  1. 针对协方差矩阵难以计算和求导的问题,将输入向量xx的每个特征xkx^{k}都认为是独立,单独求取方差和均值再归一化,xk^=xkE[xk]Var[xk]+ϵ\hat{x^k}=\frac{x^k-E[x^k]}{\sqrt{Var[x^k]+\epsilon}},分母上的附加项是为了避免分母为0 ,它应该是个极小值;
  2. 针对训练时采用SGD,不好对整个数据集求取相关统计量反向传播的问题,每个mini batch训练时的归一化统计量都是在mini batch上算得。
  3. 对于白化硬性改变了数据分布,可能减弱了网络的表达能力这一问题(如对sigmoid函数的输入归一化之后输入大集中在了线性区域),增加了两个可学习的参数,使得网络可以实现identity transform(就是输出等于输入),yk^=γkxk+βk\hat{y^k}=\gamma^k x^k+\beta^k.

最终得到了网络中的BN层

xk^=xkE[xk]Var[xk]yk^=γkxk^+βk\hat{x^k}=\frac{x^k-E[x^k]}{\sqrt{Var[x^k]}}\\ \hat{y^k}=\gamma^k \hat{x^k}+\beta^k

训练每个mini batch时的算法执行过程如下:

8.png

推断阶段

 可以看出训练阶段对于每一个样本来说,网络的输出都是会随着所在mini batch的变化而变化的。在推断阶段,我们希望结果是固定的,是只和当前输入样本有关的。因此推断时BN层的工作方式和训练时不同,此时的均值和方差都不再是对mini batch而言的,而是在训练集整体上得到的:

E[x]=EB[μB]Var[x]=mm1EB[σB2]E[x]=E_\mathcal{B}[\mu_\mathcal{B}]\\ Var[x]=\frac{m}{m-1}E_\mathcal{B}[\sigma_\mathcal{B}^2]

其中mm是mini batch的大小,对应的Var[x]Var[x]为数据集上方差的无偏估计。此时的BN层就退化成了一个线性变化层,由此得到训练测试时总的BN算法如下:

9.png

BN层细节

 BN层的作用是固定原始网络每层输入的分布,那么我们到底该在哪些原始层前加入BN层,对于原始每层的组合操作g(Wu+b)g(Wu+b)而言,是在输入时还是在线性操作后呢,作者给出的方案是在线性操作之后。依据是该层的输入是前一层的非线性输出,它的分布在训练过程中更加容易发生改变,对其一阶矩和二阶矩进行约束并不能减缓covariate shift问题。而wu+bwu+b则更可能接近于高斯,是对称的、非稀疏分布。(这里不是很理解后面的的解释,前面解释更容易发生改变倒是好理解,分布更加固定对输入更好)

 卷积操作时由于每个featuremap由一个卷积核得到(参数共享),此时在运行BN层时的mini batch就指的是其中所有样本空间层面对应同一个卷积点的值,假定feature map大小为p×qp\times q,则mini batch大小为mpqm\cdot p \cdot q

结果分析

 BN层的作用有

  1. 可以增大网络的学习率,因为不再轻易出现由于网络过深,极小量传播成了极大量,从而出现死区,梯度爆炸、梯度消失的问题。
  2. BN层作为网络正则,可以代替drop out层,由于某个样本在网络中的训练输出和所处的mini batch有关,相当于增加了网络的泛化能力,降低过拟合可能性,可以替代drop out.
  3. 可以使用带有死去的非线性激活函数,比如sigmoid。 前两者通过在ImageNet上实验证明是正确的,第三个结论的话也是对的,但是将Relu替换成Sigmoid也只是能用而已,并没有表现出更好的效果。

总结

 BN层就是为了使得网络内某些层的输入是固定分布的,更进一步考量到训练效率应该是零均值,方差为1的,由此引入白化操作。鉴于白化的复杂性和可能减弱层的表达能力,设计了scalar层面带可学习参数的BN。