常见的几种 Normalization 算法
1. 为什么需要normalization
1.1 独立同分布与白化
机器学习界的炼丹师们最喜欢的数据有什么特点?窃以为,莫过于“独立同分布”了,即independent and identically distributed,简称为 i.i.d. 独立同分布并非所有机器学习模型的必然要求(比如 Naive Bayes 模型就建立在特征彼此独立的基础之上,而Logistic Regression 和 神经网络则在非独立的特征数据上依然可以训练出很好的模型),但独立同分布的数据可以简化常规机器学习模型的训练、提升机器学习模型的预测能力,已经是一个共识。
因此,在把数据喂给机器学习模型之前,“白化(whitening)”是一个重要的数据预处理步骤。白化一般包含两个目的:
(1)去除特征之间的相关性 —> 独立;
(2)使得所有特征具有相同的均值和方差 —> 同分布。
1.2 深度学习中的 Internal Covariate Shift,简称ICS
深度神经网络模型的训练为什么会很困难?其中一个重要的原因是,深度神经网络涉及到很多层的叠加,而每一层的参数更新会导致上层的输入数据分布发生变化,通过层层叠加,高层的输入分布变化会非常剧烈,这就使得高层需要不断去重新适应底层的参数更新。为了训好模型,我们需要非常谨慎地去设定学习率、初始化权重、以及尽可能细致的参数更新策略。
1.3 ICS 会导致什么问题?
简而言之,每个神经元的输入数据不再是“独立同分布”。
其一,上层参数需要不断适应新的输入数据分布,降低学习速度。
其二,下层输入的变化可能趋向于变大或者变小,导致上层落入饱和区,使得学习过早停止。
其三,每层的更新都会影响到其它层,因此每层的参数更新策略需要尽可能的谨慎。
1.4 normalization的目的
(1) 使得所有特征具有相同的均值和方差,使得每一层的数据具有相同的分布。即下一层的参数不用适应下一层输入的数据,而特意调整学习策略。
(2) 每一层的数据具有相同的分布后,网络得以加速收敛。
2. Normalization 的通用框架与基本思想
我们以神经网络中的一个普通神经元为例。神经元接收一组输入向量
通过某种运算后,输出一个标量值:
由于 ICS 问题的存在, 的分布可能相差很大。要解决独立同分布的问题,“理论正确”的方法就是对每一层的数据都进行白化操作。然而标准的白化操作代价高昂,特别是我们还希望白化操作是可微的,保证白化操作可以通过反向传播来更新梯度。
因此,以 BN 为代表的 Normalization 方法退而求其次,进行了简化的白化操作。基本思想是:在将 送给神经元之前,先对其做平移和伸缩变换, 将 的分布规范化成在固定区间范围的标准分布。
通用变换框架就如下所示:
我们来看看这个公式中的各个参数。
1) 是平移参数(shift parameter), 是缩放参数(scale parameter)。通过这两个参数进行 shift 和 scale 变换:
得到的数据符合均值为 0、方差为 1 的标准分布。
2) 是再平移参数(re-shift parameter), 是再缩放参数(re-scale parameter)。将 上一步得到的 进一步变换为:
最终得到的数据符合均值为 、方差为 的分布。
奇不奇怪?奇不奇怪?
说好的处理 ICS,第一步都已经得到了标准分布,第二步怎么又给变走了?
答案是——为了保证模型的表达能力不因为规范化而下降。
我们可以看到,第一步的变换将输入数据限制到了一个全局统一的确定范围(均值为 0、方差为 1)。下层神经元可能很努力地在学习,但不论其如何变化,其输出的结果在交给上层神经元进行处理之前,将被粗暴地重新调整到这一固定范围。
沮不沮丧?沮不沮丧?
难道我们底层神经元人民就在做无用功吗?
所以,为了尊重底层神经网络的学习结果,我们将规范化后的数据进行再平移和再缩放,使得每个神经元对应的输入范围是针对该神经元量身定制的一个确定范围(均值为 、方差为 )。rescale 和 reshift 的参数都是可学习的,这就使得 Normalization 层可以学习如何去尊重底层的学习结果。
除了充分利用底层学习的能力,另一方面的重要意义在于保证获得非线性的表达能力。Sigmoid 等激活函数在神经网络中有着重要作用,通过区分饱和区和非饱和区,使得神经网络的数据变换具有了非线性计算能力。而第一步的规范化会将几乎所有数据映射到激活函数的非饱和区(线性区),仅利用到了线性变化能力,从而降低了神经网络的表达能力。而进行再变换,则可以将数据从线性区变换到非线性区,恢复模型的表达能力。
那么问题又来了——
经过这么的变回来再变过去,会不会跟没变一样?
不会。因为,再变换引入的两个新参数 g 和 b,可以表示旧参数作为输入的同一族函数,但是新参数有不同的学习动态。在旧参数中, 的均值取决于下层神经网络的复杂关联;但在新参数中, 仅由 来确定,去除了与下层计算的密切耦合。新参数很容易通过梯度下降来学习,简化了神经网络的训练。
那么还有一个问题——
这样的 Normalization 离标准的白化还有多远?
标准白化操作的目的是“独立同分布”。独立就不说了,暂不考虑。变换为均值为 、方差为 的分布,也并不是严格的同分布,只是映射到了一个确定的区间范围而已。(所以,这个坑还有得研究呢!)
3. 主流 Normalization 方法梳理
在上一节中,我们提炼了 Normalization 的通用公式:
3.1 Batch Normalization —— 纵向规范化
Batch Normalization 于2015年由 Google 提出,开 Normalization 之先河。其规范化针对单个神经元进行,利用网络训练时一个 mini-batch 的数据来计算该神经元 的均值和方差,因而称为 Batch Normalization。
其中 是 mini-batch 的大小
按上图所示,相对于一层神经元的水平排列,BN 可以看做一种纵向的规范化。由于 BN 是针对单个维度定义的,因此标准公式中的计算均为 element-wise 的。
BN 独立地规范化每一个输入维度 ,但规范化的参数是一个 mini-batch 的一阶统计量和二阶统计量。这就要求 每一个 mini-batch 的统计量是整体统计量的近似估计,或者说每一个 mini-batch 彼此之间,以及和整体数据,都应该是近似同分布的。分布差距较小的 mini-batch 可以看做是为规范化操作和模型训练引入了噪声,可以增加模型的鲁棒性;但如果每个 mini-batch的原始分布差别很大,那么不同 mini-batch 的数据将会进行不一样的数据变换,这就增加了模型训练的难度。
因此,BN 比较适用的场景是:每个 mini-batch 比较大,数据分布比较接近。在进行训练之前,要做好充分的 shuffle. 否则效果会差很多。
3.2 Layer Normalization —— 横向规范化
层规范化就是针对 BN 的上述不足而提出的。与 BN 不同,LN 是一种横向的规范化,如图所示。它综合考虑一层所有维度的输入,计算该层的平均输入值和输入方差,然后用同一个规范化操作来转换各个维度的输入。
其中 枚举了该层所有的输入神经元。对应到标准公式中,四大参数 , , , 均为标量(BN中是向量),所有输入共享一个规范化变换。
4. BN和LN的区别、联系、优点和缺点
4.1 联系
1. 都是减均值和除以标准差
2. 将输入规范化到相同分布,加速网络收敛
4.2 区别
1. bn对每个维度采用该该维度下的均值和方差进行归一化。利用了整个批次大小,样本的时间长度和样本的宽求出了均值和方差,方差和均值的维度为[C]
2. ln是对所有维度都采用相同的均值和方差进行更新。利用了样本的词向量维度和样本的宽求出了均值和方差,方差和均值的维度为[B, S, 1],即每个样本采用自己的样本的均值和方差进行归一化
3. 基于1,2两点,可以理解为
a. 在bn时,所有维度下每个维度有一个独立的均值和方差
b. 在ln时,所有维度下只有1个均值和方差
4. 为什么称为layer normalization:bn是对每一层的单个通道分别进行归一化;ln是对每一层的所有通道统一进行归一化。
5. BN是对所有的Batch,所有的时间维度下,每一个特征通道利用进行单独的归一化(相同的特征通道利用相同的方差和均值进行归一化),LN是对每个Batch里面的每个时间序列单独进行归一化
4.3 优点
1. bn在适用与每个通道的特征不相似的情况下
2. ln不需要足够大的batch size就能估算均值和方差,也就是rnn和lstm
4.4 缺点
1. bn需要在足够大的batch size才能估算均值和方差
2. ln需要每个通道下的特征是相似的或者相关联的
5. 实现时注意的点
1. bn求出来的均值和方差的维度都是[1, 1, hidden_size]
2. ln求出来的均值和方差的维度都是[batch_size, seq_len, 1],因为每个样本中的sequence length长度不一样,所以求均值和方差时,不利用sequence这个维度