归一化的目的
归一化数据的目标,是为了让数据的分布变得更加符合期望,增强数据的表达能力。
在深度学习中,因为网络的层数非常多,如果数据分布在某一层开始有明显的偏移,随着网络的加深这一问题会加剧(这在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层放在激活函数之前的原因。
- 如sigmoid那样的激活函数,在两端梯度会比较平,而网络越深,影响越大,而每一层的输入分布如果能比较稳定,就会比较好。在sigmoid的例子中,输入能比较集中在梯度较大的地方就比较好。
缩放平移是为神经网络学会,在标准化效果好时,尽量不抵消标准化的作用,而在标准化效果不好时,尽量去抵消一部分标准化的效果,相当于让神经网络学会要不要标准化,如何折中选择。
- 对于CNN,BN的操作是在各个特征维度之间单独进行,也就是说各个通道是分别进行Batch Normalization操作的。如果输出的blob大小为(N,C,H,W),那么在每一层normalization就是基于NHW个数值进行求平均以及方差的操作,记住这里我们后面会进行比较。
作用
- 减轻了对参数初始化的依赖。
- 训练更快,可以使用更高的学习率。
- 一定程度了增加了泛化能力,dropou等技术可以去掉。
- 其作用可以加快模型训练时的收敛速度,使得模型训练过程更加稳定,避免梯度爆炸或者梯度消失。并且起到一定的正则化作用,几乎代替了Dropout。
训练与推理阶段的不同
- beta、gamma在训练状态下,是可训练参数,在推理状态下,直接加载训练好的数值。
- moving_mean、moving_var在训练、推理中都是不可训练参数,只根据滑动平均计算公式更新数值,不会随着网络的训练BP而改变数值;在推理时,直接加载储存计算好的滑动平均之后的数值,作为推理时的均值和方差。
BN为什么有效
- 主流观点,Batch Normalization调整了数据的分布,不考虑激活函数,它让每一层的输出归一化到了均值为0方差为1的分布,这保证了梯度的有效性,目前大部分资料都这样解释,比如BN的原始论文认为的缓解了Internal Covariate Shift(ICS)问题。
- 可以使用更大的学习率,文[2]指出BN有效是因为用上BN层之后可以使用更大的学习率,从而跳出不好的局部极值,增强泛化能力,在它们的研究中做了大量的实验来验证。
- 损失平面平滑。文[3]的研究提出,BN有效的根本原因不在于调整了分布,因为即使是在BN层后模拟ICS,也仍然可以取得好的结果。它们指出,BN有效的根本原因是平滑了损失平面。之前我们说过,Z-score标准化对于包括孤立点的分布可以进行更平滑的调整。
相关面试问题
- BN层的可训练参数有多少个?c*2个
均值的计算,就是在一个批次内,将每个通道中的数字单独加起来,再除以 。举个例子:该批次内有10张图片,每张图片有三个通道RBG,每张图片的高、宽是H、W,那么均值就是计算10张图片R通道的像素数值总和除以 ,再计算B通道全部像素值总和除以,最后计算G通道的像素值总和除以。方差的计算类似。
可训练参数 的维度等于张量的通道数,在上述例子中,RBG三个通道分别需要一个 和一个 ,所以 的维度等于3。
- 输入的维度为[N,C,H,W],经过bn层,输出的维度是什么呢?
- 输出的维度没有变化。如下为pytorch中实现。