Layer Normalization

预备知识:Batch Normalization

1 Batch Normalization局限性

假设把中国的收入水平进行标准化(变成标准正态分布),这时中国高收入人群的收入值接近3,中收入人群的收入值接近0,低收入人群接近-3。不难发现,标准化后的相对大小是不变的,即中国富人的收入水平在标准化前和标准化后都比中国穷人高。把中国的收入水平看成一个分布的话,我们可以说一个分布在标准化后,分布内的样本还是可比较的

假设把中国和印度的收入水平分别进行标准化,这时中国和印度的中收入人群的收入值都为0,但是这两个0可比较吗?印度和中国的中等收入人群的收入相同吗?不难发现,中国和印度的收入水平在归一化后,两国间收入值已经失去了可比性。把中国和印度的收入水平各自看成一个分布的话,我们可以说,不同分布分别进行标准化后,分布间的数值不可比较

Batch Normalization就是把不同特征图的同一通道进行标准化,这就意味着:

  • 不同图片的的同一通道的相对关系是保留的,即不同图片的同一通道的特征是可以比较的
  • 同一图片的不同通道的特征则是失去了可比性

feature的每个通道都对应一种特征(如低维特征的颜色,纹理,亮度等,高维特征的人眼,鸟嘴特征等)。BatchNorm后不同图片的同一通道的特征是可比较的,或者说A图片的纹理特征和B图片的纹理特征是可比较的;而同一图片的不同特征则是失去了可比性,或者说A图片的纹理特征和亮度特征不可比较。
这其实是很好理解的,视觉的特征是比较客观的,一张图片是否有人跟一张图片是否有狗这两种特征是独立,即同一图片的不同特征是不需要可比性;而人这种特征模式的定义其实是网络通过比较很多有人的图片,没人的图片得出的,因此不同图片的同一特征需要具有可比性。也就是说BN在视觉领域是非常奏效的,因为其符合视觉特征图的内在特征。

但是在NLP领域呢?

比如说有个句子 ,“教练,我想打篮球!” 和 “老板,我要一打包子。”。通过比较两个句子中 “打” 的词义我们可以发现,词义并非客观存在的,而是由上下文的语义决定的。因此进行标准化时不应该破坏同一句子中不同词义向量的可比性,如果使用bn,就会破坏一个样本中特征之间的可比性,这是不对的,Layer Normalization可以解决这个问题

2 Layer Normalization

从上图可以看出Layer Norm是对每个样本进行标准化,而不是对所有样本的某一特征通道进行标准化,会保留同一句子不同单词之间的可比性,所以说Layer Norm更适合NLP任务。也就是说

  • 同一句子中词义向量(上图中的V1, V2, …, VL)的相对大小是保留的,或者也可以说LayerNorm不改变词义向量的方向,只改变它的模。
  • 不同句子的词义向量则是失去了可比性
  • nn.BatchNorm2d(num_features)中的num_features一般是输入数据的第2维(从1开始数)(也就是每个样本的通道数),BatchNorm中\(\gamma\)和\(\beta\)与num_features一致。在计算时,BN是把不同样本同一通道取出来,求平均值和方差的,然后对每个元素进行归一化,最后再乘以对应的γ 和β (每一通道共享)。BN共有num_features个mean和var,(假设输入数据的维度为(N,num_features, H, W))。
  • nn.LayerNorm(normalized_shape)中的normalized_shape是最后的几维LayerNorm中weight和bias的shape就是传入的normalized_shape(normalized_shape可以理解为每一个样本的形状)。而LN是把normalized_shape这几个轴的元素展平,都放在一起,取平均值和方差的.然后对每个元素进行归一化,最后再乘以对应的γ和β(每个元素不同)。LN共有N1*N2个mean和var,N1*N2*normalized_shape对γ和β(假设输入数据的维度为(N1,N2,normalized_shape),normalized_shape表示多个维度)

2.1 源码解析

pytorch官方文档对LayerNorm的解释:

结合具体例子来看

import torch 
import torch.nn as nn
a=torch.empty(2,2,3).random_(0,3)
print(a)
#[batch_size=2,seq_len=2,emb_size=3]

对于每一个样本,其shape为[2, 3],也就是上文中说的normalized_shape。对于上述例子,pytorch的LayerNorm是如何处理的呢?对于每一个样本,扁平化然后z-score标准化,然后处理回原来的形状

  • 扁平化

  • 求其均值为1,方差为0.816496580927726
  • z-score公式代入

  • reshape回原先的形状

这就是这个batch中第一个数据LayerNormalization的结果,第二个数据也是重复这个流程

我们使用pytorch验证一下

ln=nn.LayerNorm([2,3])#2,3表示最后两个维度的大小,即为上文中的normalized_shape
ln(a)

完全正确

 

如果我们的ln层定义为nn.LayerNorm(3),就不用展平了,直接对[1, 2, 0]   [0, 1, 2]……进行标准化即可

对于nn.LayerNorm([2,3]),认为最后两个维度为一个layer,整个batch会有6对\(\gamma\)和\(\beta\),2对mean和variance;对于nn.LayerNorm(3),认为最后一个维度是一个layer,整个batch会有3对\(\gamma\)和\(\beta\),有2×2对mean和variance。

2.2 NLP中Layer Norm如何实现?

假设一个一个batch有16个句子,每个句子经过padding之后统一到10个单词,每个单词的embedding是256维,故一个batch的维度就是[16, 10, 256]。

在对这个句子进行layer norm的时候,我们是nn.LayerNorm([10, 256])还是nn.LayerNorm(256)呢?

一般采用的是后者,即对每个单词embedding进行标准化,而不是对整个句子所有单词embedding向量展平再标准化,因为每个序列(每个样本)的单词个数不一样,但在代码实现的时候会进行padding,比如一个序列原始单词数为10个,另一个序列原始单词数是8,然后你统一padding成了10个单词,那如果按照相同维度,进行归一化,norm的信息就会被无意义的padding的embedding冲淡的!这显然是不合理的。

3 参考资料

  1. BatchNorm和LayerNorm——通俗易懂的理解

  2. 深入理解NLP中LayerNorm的原理以及LN的代码详解

  3. Pytorch归一化方法讲解与实战:BatchNormalization、LayerNormalization、nn.BatchNorm1d和LayerNorm()和F.normalize()

 

 

 

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇