归一化

为什么使用归一化

如果输入有多个 feature,且它们的数值范围有很大差异,这样训练时学习率就不能设置得太大,以免大幅调参引发越界。反之,如果各个 feature 有相同的均值和方差,则可使用更高的学习率,使收敛更快。归一化解决了梯度爆炸和梯度消失的问题,使构建更深层的网络成为可能,还避免了梯度爆炸和梯度消失

使用模型时需要保证训练数据和测试数据同分布。在机器学习中往往对输入数据进行归一化处理,在深度学习中则常对网络的每一层都做归一化处理,以保证每次处理的数据分布一致。这也使得层与层之间更加独立,依赖更小。Batch-Normalize(BN)论文中描述:加入 BN 方法后,模型训练提速 14 倍,且精度也有所提升。

Convariate shift(漂移)问题

从原理上看,归一化缓解了内部协变量的移位问题,即漂移问题。深度神经网络中每一层输入都依赖之前层的输出,在训练的不同阶段,前层输出的分布也不相同。调参幅度越大越可能使分布变化,因此,只能使用较小的学习率,这样又使得收敛变慢。

由调参引发的内部数据分布变化的问题叫做内部协变量的移位问题,也被称作漂移问题。归一化方法可以有效地缓解该问题,它将特定特征的数据表示为均值为0,标准差为1的数据。其物理意义是把数据集映射到原点周围,除了缩放(除标准差)和平移(减均值),一般工具库提供的归一化函数包括 affine 参数实现仿射变换。其公式如下:

其中 x 为归一化层的输入,y 为归一化层的输出,E[x] 是均值,Var[x] 是方差,weight(γ) 和 bias(β) 是模型的参数,通过训练求得,用于实现仿射变换。ε(eps) 是个很小的数用于防止分母为 0。在γ为标准差,β为均值的情况下,上述公式未对 x 进行变换,而这两个参数通过训练求得,可以说在多大程度上进行归一化由模型训练决定。

常用的归一化方法

Batch-Normalize(BN)

Batch-Normalize 最早提出,也是最常用的归一化方法,其原理已经在前面介绍。在图像处理时,它在 batch 上,对 NHW 做归一化。它的缺陷是在 batch size 较小的情况下效果不好,而目标检测或者在图片分辨率较大的情况下,又只能使用较小的 batch size。

理论上,上述公式应该对整个训练集计算均值和方差,而实际操作中,每一次只对一个 batch 中的数据计算统计量(均值/方差),由此引起了噪声,这种噪声类似于 Dropout,因此有时 BN 也能部分实现 Dropout 的功能,降低模型对某些连接的依赖性,提高模型的泛化能力。但是当 batch size 很小时,归一化引入了太多的噪声,导致模型效果变差。为解决这一问题,开发者在 BN 基础上提出了更多的归一化算法。

Layer-Normalize(LN)

基于 BN,在通道方向上,对 CHW 归一化。常用于 RNN 任务,但在机器视觉方面达不到 BN 的精度。

Instance-Normalize(IN)

基于 BN,在图像像素上,对 HW 做归一化,常用于迁移学习,风格转换,在机器视觉方面达不到 BN 的精度。

Group-Normalize(GN)

基于 BN,GroupNorm 将 channel 分组,计算每一组数据的统计值做归一化处理,解决了 BN 在 batchSize 较小的情况下引入大量噪声的问题。

Switchable-Normalize(SN)

将 BN、LN、IN 结合,赋予权重,让网络自己去学习归一化层应该使用什么方法。

SN 结合了 BN、LN、IN 几种方法,可用于不同任务及不同场景,SN 计算了 BN,LN,IN 三种统计量,然后对统计量加权(权值通过 softmax 计算),最终计算出归一化值。通过训练动态调节权值,使模型具有更强的鲁棒性,以适应各种场景。

测试阶段的归一化

需要注意的是训练集和测试集需要使用同样的归一化方法。以 BN 为例,训练时,用当前 batch 中的所有数据计算均值和方差(一般包含 32,64,128 个样本)。在预测时,如果只对单个样本做预测,只计算单个样本的统计值会产生偏差。可使用如下几种解决方法:

  • 使用整个训练集的数据计算统计值。
  • 从训练集中随机抽取一批数据计算统计值。
  • 记录训练阶段计算的统计值,使用指数加权平均法计算训练阶段的统计值。

一般深度学习框架(如 Pytorch)都提供默认的处理方法,如无特殊情况,不用自己写程序实现。