归一化的目的

归一化数据的目标,是为了让数据的分布变得更加符合期望,增强数据的表达能力。
在深度学习中,因为网络的层数非常多,如果数据分布在某一层开始有明显的偏移,随着网络的加深这一问题会加剧(这在BN的文章中被称之为internal covariate shift),进而导致模型优化的难度增加,甚至不能优化。所以,归一化就是要减缓这个问题。

Internal Covariate Shift

从论文的标题可以看到:BN 是用来减少 “Internal Covariate Shift” 来加速网络的训练。
那么,什么是 Internal Covariate Shift 呢?
论文指出:神经网络在更新参数后各层输入的分布会发生变化,从而给训练带来困难。这种现象被称为内部协变转移(Internal Covariate Shift,以下简称 ICS)。
更形象一点来说,如果网络在传播过程中,数据分布稍微发生些变化,便会不断累积从而产生梯度消失和梯度爆炸的问题。
ICS 会带来什么样的危害呢?主要有以下两点:

  • 首先,在训练过程中,每一层网路计算结果的分布都在发生变化,这使得后一层网络需要不停的适应这种分布变化,这便会降低网络的收敛速度;
  • 其次,在训练过程中,模型容易陷入激活函数的饱和区,导致梯度变小,降低参数的更新速度。

为了解决这个问题,我们会采用较小的学习率和特定的权重初始化(比如,前面介绍的初始化)。
但参数初始化的方式非常依赖激活函数,并不能给出通用的解决方案。

BN简介

参考:六问透彻理解BN(Batch Normalization)深度学习中 Batch Normalization为什么效果好? :::info 在CNN中,如resnet,BN层是直接加载卷积层后面的,再之后才是激活函数如relu。
一个新理解:bn可以调整数据分布,使得数据落在激活函数的非饱和区。 :::

  • BN层位于激活函数之前,它先对数据进行标准化,再进行缩放和平移
  • 标准化是防止数据达到饱和(即激活值分布在大部分都接近0或1),这样会使数据对激活函数不敏感

    • 如sigmoid那样的激活函数,在两端梯度会比较平,而网络越深,影响越大,而每一层的输入分布如果能比较稳定,就会比较好。在sigmoid的例子中,输入能比较集中在梯度较大的地方就比较好。

      上面这一条应该也是为何bn层放在激活函数之前的原因。

  • 缩放平移是为神经网络学会,在标准化效果好时,尽量不抵消标准化的作用,而在标准化效果不好时,尽量去抵消一部分标准化的效果,相当于让神经网络学会要不要标准化,如何折中选择。

  • 对于CNN,BN的操作是在各个特征维度之间单独进行,也就是说各个通道是分别进行Batch Normalization操作的。如果输出的blob大小为(N,C,H,W),那么在每一层normalization就是基于NHW个数值进行求平均以及方差的操作,记住这里我们后面会进行比较。

    作用

  1. 减轻了对参数初始化的依赖。
  2. 训练更快,可以使用更高的学习率。
  3. 一定程度了增加了泛化能力,dropou等技术可以去掉。
  • 其作用可以加快模型训练时的收敛速度,使得模型训练过程更加稳定,避免梯度爆炸或者梯度消失。并且起到一定的正则化作用,几乎代替了Dropout。

batch normalization - 图1

训练与推理阶段的不同

  • beta、gamma在训练状态下,是可训练参数,在推理状态下,直接加载训练好的数值。
  • moving_mean、moving_var在训练、推理中都是不可训练参数,只根据滑动平均计算公式更新数值,不会随着网络的训练BP而改变数值;在推理时,直接加载储存计算好的滑动平均之后的数值,作为推理时的均值和方差。

    BN为什么有效

  1. 主流观点,Batch Normalization调整了数据的分布,不考虑激活函数,它让每一层的输出归一化到了均值为0方差为1的分布,这保证了梯度的有效性,目前大部分资料都这样解释,比如BN的原始论文认为的缓解了Internal Covariate Shift(ICS)问题。
  2. 可以使用更大的学习率,文[2]指出BN有效是因为用上BN层之后可以使用更大的学习率,从而跳出不好的局部极值,增强泛化能力,在它们的研究中做了大量的实验来验证。
  3. 损失平面平滑。文[3]的研究提出,BN有效的根本原因不在于调整了分布,因为即使是在BN层后模拟ICS,也仍然可以取得好的结果。它们指出,BN有效的根本原因是平滑了损失平面。之前我们说过,Z-score标准化对于包括孤立点的分布可以进行更平滑的调整。

相关面试问题

  • BN层的可训练参数有多少个?c*2个

均值的计算,就是在一个批次内,将每个通道中的数字单独加起来,再除以 batch normalization - 图2 。举个例子:该批次内有10张图片,每张图片有三个通道RBG,每张图片的高、宽是H、W,那么均值就是计算10张图片R通道的像素数值总和除以batch normalization - 图3 ,再计算B通道全部像素值总和除以batch normalization - 图4,最后计算G通道的像素值总和除以batch normalization - 图5。方差的计算类似。
可训练参数 batch normalization - 图6 的维度等于张量的通道数,在上述例子中,RBG三个通道分别需要一个 batch normalization - 图7 和一个 batch normalization - 图8 ,所以 batch normalization - 图9 的维度等于3。

  • 输入的维度为[N,C,H,W],经过bn层,输出的维度是什么呢?
    • 输出的维度没有变化。如下为pytorch中实现。

batch normalization - 图10