NLP中 batch normalization与 layer normalization

NLP中 batch normalization与 layer normalization

BatchNormalization、LayerNormalization、InstanceNorm、GroupNorm、SwitchableNorm总结

对于batch normalization实际上有两种说法,一种是说BN能够解决“Internal Covariate Shift”这种问题。简单理解就是随着层数的增加,中间层的输出会发生“漂移”。另外一种说法是:BN能够解决梯度弥散。通过将输出进行适当的缩放,可以缓解梯度消失的状况。

那么NLP领域中,我们很少遇到BN,而出现了很多的LN,例如bert等模型都使用layer normalization。这是为什么呢?

这要了解BN与LN之间的主要区别。

主要区别在于 normalization的方向不同!

Batch 顾名思义是对一个batch进行操作。假设我们有 10行 3列 的数据,即我们的batchsize = 10,每一行数据有三个特征,假设这三个特征是【身高、体重、年龄】。那么BN是针对每一列(特征)进行缩放,例如算出【身高】的均值与方差,再对身高这一列的10个数据进行缩放。体重和年龄同理。这是一种“列缩放”。

而layer方向相反,它针对的是每一行进行缩放。即只看一笔数据,算出这笔所有特征的均值与方差再缩放。这是一种“行缩放”。

细心的你已经看出来,layer normalization 对所有的特征进行缩放,这显得很没道理。我们算出一行这【身高、体重、年龄】三个特征的均值方差并对其进行缩放,事实上会因为特征的量纲不同而产生很大的影响。但是BN则没有这个影响,因为BN是对一列进行缩放,一列的量纲单位都是相同的。

那么我们为什么还要使用LN呢?因为NLP领域中,LN更为合适。

如果我们将一批文本组成一个batch,那么BN的操作方向是,对每句话的第一个词进行操作。但语言文本的复杂性是很高的,任何一个词都有可能放在初始位置,且词序可能并不影响我们对句子的理解。而BN是针对每个位置进行缩放,这不符合NLP的规律。

而LN则是针对一句话进行缩放的,且LN一般用在第三维度,如[batchsize, seq_len, dims]中的dims,一般为词向量的维度,或者是RNN的输出维度等等,这一维度各个特征的量纲应该相同。因此也不会遇到上面因为特征的量纲不同而导致的缩放问题。
NLP中 batch normalization与 layer normalization
假如我们的词向量是100(如图是立方体的高),batchsize是64(立方体中的N)。

BN:固定每句话的第一个位置,则这个切片是 (64, 100)维的矩阵。

LN:固定一句话,则切片是(seq_len, 100)维。

但是,BN取出一条 (1,64)的向量(绿色剪头方向)并进行缩放,LN则是取出一条(1, 100)维(红色箭头)进行缩放。

总体来看:

BN (64,j, k)

j代表一句话的某一位置 0 ~ seq_len 左闭右开。

k代表embedding dim范围 0 ~ 100维左闭右开。

因此,对于BN而言,batchsize的大小会影响BN效果。

如果我们输入batchsize = 128,即 BN (128,j, k)

则BN取出一条 (1,128)的向量并进行缩放。

LN (i, j, 100)

i代表 batchsize的范围, 0~64 左闭右开。

j代表一句话的某一位置 0 ~ seq_len 左闭右开。

因此batchsize的大小不影响LN。

但是如果我们换成了glove300d,则会影响~