Batch Normalization


转载请标明出处:http://blog.csdn.net/wuzqChom/article/details/78024653


1. 背景

先来看看为什么要归一化操作吧。
归一化之前和归一化之后的代价函数示意图,左边的最归一化之前,右边为归一化之后,最中间的点为我们要优化的最优点(图片来自Andrew deeplearning.ai课程1.9 Normalizing inputs)。

这里写图片描述

我们可以看到,在归一化之前,不同的特征的取值范围可能有所不同,这样带来的不好的地方就是在进行梯度下降的时候,学习率不能够设置太大,否则会造成明显波动,导致长时间不能收敛的情况。但是经过归一化之后,无论我们从哪一个位置开始,都能够方便地找到最小值,这样就更加容易优化,从而加速我们的训练过程。

2. Covariate Shift

论文“Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift”关于“Covariate Shift”的定义如下:

We define Internal Covariate Shift as the change in the distribution of network activations due to the change in network parameters during training.

稍加解释,即分布的变化。怎么说呢?
假设我们现在已经使用黑猫的图片训练了一个分类器来识别猫的图片,但现在假如有一些白猫的图片,虽然都是猫,但是因为训练数据并没有白猫的图片,那么分类器大概率识别不出来,这就是分布的变化。也即Covariate Shift问题。

接下来来看看神经网络中的Covariate Shift问题吧。

首先,下图为一个神经网络,为了表(hua)示(tu)方便,没有全连接箭头来表示,记住层与层之前都是全连接即可,

这里写图片描述

接下来仅考虑第三个隐层:

这里写图片描述

现在假设前面的都固定,即当前的输入固定,那么我们这一层的目的就是学习 w 3 w_{3} w3 b 3 b_{3} b3使得预测的 y ^ \hat{y} y^和真实的 y y y越接近越好,但不幸的是,当前层的输入并不固定,它与之前的输入和前两个隐层的参数都有关,即当前层的输入在变,这可以近似认为输入数据的分布在变化,即上面说的Covariate Shift问题。
刚开始上帝为你关了一扇门,可是马上就会为你打开一扇窗。
BN(Batch Normalization)就是这一扇窗。

3. Batch Normalization

顾名思义,就是一个归一化的操作。如何做呢?
首先和归一化输入类似,先标准化:

μ = 1 m ∑ i Z i \mu=\frac{1}{m}\sum_iZ^{i} μ=m1iZi
δ 2 = 1 m ∑ i ( Z i − μ ) \delta^2=\frac{1}{m}\sum_i(Z^{i}-\mu) δ2=m1i(Ziμ)
z n o r m i = z i − μ δ 2 + ε z_{norm}^{i}=\frac{z^{i}-\mu}{\sqrt{\delta^2+\varepsilon}} znormi=δ2+ε ziμ

其中 ε \varepsilon ε是为了防止分布不为零的一个很小的数。 z n o r m i z_{norm}^{i} znormi为标准化后的隐层单元的值,但是这样的结果就是隐层单元的值都服从 μ = 0 \mu=0 μ=0 δ 2 = 1 \delta^2=1 δ2=1的标准高斯分布,这样的话我们每一层的输入都相当于来自同一个分布了吗?这样就解决第二部分提到的Covariate Shift问题了。为了能够更加第灵活,论文中还用了一个放大和平移的操作:

z ~ i = γ z n o r m i + β \tilde{z}^i=\gamma z_{norm}^{i}+\beta z~i=γznormi+β

γ = δ 2 + ε \gamma=\sqrt{\delta^2+\varepsilon} γ=δ2+ε β = μ \beta=\mu β=μ时, z ~ i = z i \tilde{z}^i=z^i z~i=zi,即为原始的激活函数的值。

ps:或许应该叫mini-batch normalization更为合适?因为 μ \mu μ δ 2 \delta^2 δ2都是由当前的mini-batch得到的。

公式就是这样,让我们从一个神经元来看看它是怎么操作的吧。

这里写图片描述

如上所示,一个神经元可以分为两个操作,第一步算出 z i z^i zi,第二步由算出 z i z^i zi经过激活函数之后的值 a i a^i ai
在添加了BN之后,这两个步骤之间会多一BN操作(当然你也可以认为添加了一层BN层):

这里写图片描述

中间的 z ~ i \tilde{z}^i z~i可由上面的公式得到。如果在隐层加了BN操作,那么每一个神经元的计算步骤都会按照上图步骤进行。

4. BN正则化

我们知道神经网络的正则化可以使用dropout和l2 norm,在Ng的神经网络调参课程3.6 Why does BN work 中提到的另外一点就是BN可以看成是这一种正则化。
因为每一次我们使用BN的时候,都仅仅是使用了当前的mini-batch的均值和方差。但是每一个mini-batch肯定会存在一些噪音,这就相当于在训练的时候为每一个隐层单元增加了一些噪音(试想Denoising Autoencoder不就是在训练的时候增加一些噪音来使得训练的模型更加鲁棒吗)
当mini-batch的越大,就相当于看的信息越完整,这个时候的噪音也就越小,正则化的效果也就会降低。

5. 预测阶段的BN

在训练的时候我们可以使用当前的mini-batch来计算 μ \mu μ δ 2 \delta^2 δ2,但是预测的时候我们只有一个样本,均值和方差对于一个样本毫无意义,那么应该怎么得到呢?
训练结束之后,网络中的参数就固定了,那么这个时候我们可以计算每一个mini-batch的均值 μ i \mu_i μi,最后要得到的均值就可以由这些mini-batch计算得到,可以简单的平均或者指数加权(Ng提到采用并没有什么太大的影响),方差也可以用同样的方式得到,那么我们就可以得到预测样本归一化后的值:

Z n o r m = Z − μ δ 2 Z_{norm}=\frac{Z-\mu}{\delta^2} Znorm=δ2Zμ

然后计算 z ~ i \tilde{z}^i z~i,再送入激活函数,进行后续的计算。

参考资料:

  1. Andrew Ng deeplearning.ai深度学习课程
  2. Ioffe S, Szegedy C. Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift[J]. 2015:448-456.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值