Pytorch中不同的Norm归一化详细讲解

在做项目或者看论文时,总是能看到Norm这个关键的Layer,但是不同的Norm Layer具有不同的作用,准备好接招了吗?(本文结论全部根据pytorch官方文档得出,请放心食用)

一. LayerNorm

LayerNorm的公示如下:
y = x − E [ x ] Var ⁡ [ x ] + ϵ ∗ γ + β y=\frac{x-\mathrm{E}[x]}{\sqrt{\operatorname{Var}[x]+\epsilon}} * \gamma+\beta y=Var[x]+ϵ x−E[x]∗γ+β

Parameters(参数):

  • normalized_shape
  • eps(确保分母不为0)
  • elementwise_affine(布尔类型,是否要为每个元素添加一个可学习的仿射变换参数)
  • bias(布尔类型,在elementwise_affine为True时可选择为每个元素另外加上一个可学习的偏置项)

其中可变化的量即可学习的参数即 elementwise_affine涉及的权重以及bias。

归一化的维度是由normalized_shape 来决定的。假设输入的张量形状是[B,C,H,W],此时常见的normalized_shape 为[C,H,W]。换句话说,由于最后三个维度包含一张完整的图片信息,它会计算每个图片的 CxHxW 张量的均值和标准差,并进行归一化,使得这个张量在归一化后均值为 0,标准差为 1。

举个具体的例子来说明,假设输入张量 x 如下:
x = [ [ 1 2 3 4 5 6 7 8 9 10 11 12 ] [ 13 14 15 16 17 18 19 20 21 22 23 24 ] ] x=\left[\begin{array}{c}{\left[\begin{array}{cccc}1 & 2 & 3 & 4 \\5 & 6 & 7 & 8 \\9 & 10 & 11 & 12\end{array}\right]} \\{\left[\begin{array}{cccc}13 & 14 & 15 & 16 \\17 & 18 & 19 & 20 \\21 & 22 & 23 & 24\end{array}\right]}\end{array}\right] x= 159261037114812 131721141822151923162024

我们假设要对后两个维度进行归一化。
1. 计算均值
E [ x 1 ] = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 12 = 78 12 = 6.5 \mathrm{E}\left[x_{1}\right]=\frac{1+2+3+4+5+6+7+8+9+10+11+12}{12}=\frac{78}{12}=6.5 E[x1]=121+2+3+4+5+6+7+8+9+10+11+12=1278=6.5
E [ x 2 ] = 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 12 = 222 12 = 18.5 \mathrm{E}\left[x_{2}\right]=\frac{13+14+15+16+17+18+19+20+21+22+23+24}{12}=\frac{222}{12}=18.5 E[x2]=1213+14+15+16+17+18+19+20+21+22+23+24=12222=18.5
2. 对每个样本的二维切片计算方差。

第一个样本:
Var ⁡ [ x 1 ] = ( 1 − 6.5 ) 2 + ( 2 − 6.5 ) 2 + ⋯ + ( 12 − 6.5 ) 2 12 = 11.9167 \operatorname{Var}\left[x_{1}\right]=\frac{(1-6.5)^{2}+(2-6.5)^{2}+\cdots+(12-6.5)^{2}}{12}=11.9167 Var[x1]=12(1−6.5)2+(2−6.5)2+⋯+(12−6.5)2=11.9167

第二个样本:
Var ⁡ [ x 2 ] = ( 13 − 18.5 ) 2 + ( 14 − 18.5 ) 2 + ⋯ + ( 24 − 18.5 ) 2 12 = 11.9167 \operatorname{Var}\left[x_{2}\right]=\frac{(13-18.5)^{2}+(14-18.5)^{2}+\cdots+(24-18.5)^{2}}{12}=11.9167 Var[x2]=12(13−18.5)2+(14−18.5)2+⋯+(24−18.5)2=11.9167
3. 计算归一化后的值

方便起见,我们设定 ϵ=0:
y 1 = [ − 1.593 − 1.301 − 1.010 − 0.718 − 0.426 − 0.135 0.157 0.449 0.740 1.032 1.323 1.615 ] y_{1}=\left[\begin{array}{cccc}-1.593 & -1.301 & -1.010 & -0.718 \\-0.426 & -0.135 & 0.157 & 0.449 \\0.740 & 1.032 & 1.323 & 1.615\end{array}\right] y1= −1.593−0.4260.740−1.301−0.1351.032−1.0100.1571.323−0.7180.4491.615
y 2 = [ − 1.593 − 1.301 − 1.010 − 0.718 − 0.426 − 0.135 0.157 0.449 0.740 1.032 1.323 1.615 ] y_{2}=\left[\begin{array}{cccc}-1.593 & -1.301 & -1.010 & -0.718 \\-0.426 & -0.135 & 0.157 & 0.449 \\0.740 & 1.032 & 1.323 & 1.615\end{array}\right] y2= −1.593−0.4260.740−1.301−0.1351.032−1.0100.1571.323−0.7180.4491.615
4. 应用可学习的仿射变换(可选)

具体应用:

我们的核心目标是对一个完整对象利用LayerNorm,所以这是我们的第一目标。

  • NLP:
    在NLP领域中,最常见的单体对象就是word。常见的输入形状是[B,Seq_len,Word_dim],即batch_size,每个句子包含几个单词,每个单词的具体维度。所以我们在最后一个维度即单词维度进行归一化。
python 复制代码
# NLP Example
batch, sentence_length, embedding_dim = 20, 5, 10
embedding = torch.randn(batch, sentence_length, embedding_dim)
layer_norm = nn.LayerNorm(embedding_dim)
# Activate module
layer_norm(embedding)
  • CV:
    视觉也不用多说了,最多的就是在后三个维度(即完整的一张图像上)进行归一化。
python 复制代码
N, C, H, W = 20, 5, 10, 10
input = torch.randn(N, C, H, W)
# Normalize over the last three dimensions (i.e. the channel and spatial dimensions)
# as shown in the image below
layer_norm = nn.LayerNorm([C, H, W])
output = layer_norm(input)

二. BatchNorm2d

公式与LayerNorm完全相同。但是在代码中其操作的维度不一样。LayerNorm是对整张图像进行归一化(操作后三个维度),而BatchNorm2d则是对通道进行归一化,比如说我们有256张图片作为一个批次,每张图片有3个通道为R,G,B,那么在R通道在归一化需要使用这256张图片的R通道。(G,B通道同理)

Parameters(参数):

  • num_features:定义了通道数。
  • eps :用于数值稳定性。
  • momentum: 控制运行均值和方差的更新速度。
  • affine: 决定是否有可学习的缩放和偏移参数。
  • track_running_stats: 控制是否在推理时使用运行时统计量。

示例代码如下:

python 复制代码
# With Learnable Parameters
m = nn.BatchNorm2d(100)
# Without Learnable Parameters
m = nn.BatchNorm2d(100, affine=False)
input = torch.randn(20, 100, 35, 45)
output = m(input)

三. InstanceNorm2d

公式还是和上面的完全一样。InstanceNorm2d与BatchNorm2d非常相似,只不过InstanceNorm2d更进一步,它实现了单个样本单通道 的归一化。
Parameters(参数):

  • num_features 定义了通道数。
  • eps 用于防止数值不稳定。
  • momentum 控制 running_mean 和 running_var 的更新速度(如果track_running_stats=True)。
  • affine 决定是否有可学习的缩放和偏移参数。
  • track_running_stats 决定是否在推理时使用累计的均值和方差,还是每次使用当前样本的统计量。

示例代码如下:

输入:(B,C,H,W) or (C,H,W)

输出:(B,C,H,W) or (C,H,W) 形状不变,当B=1时即(C,H,W),此时就是支持单个样本进行归一化的情况。

python 复制代码
# Without Learnable Parameters
m = nn.InstanceNorm2d(100)
# With Learnable Parameters
m = nn.InstanceNorm2d(100, affine=True)
input = torch.randn(20, 100, 35, 45)
output = m(input)

四. GroupNorm

公式还是和上面三个一样。然而GroupNorm在Instance的基础上,可以将通道进行分组归一化。比如说一个样本共有8个通道,设置num_groups=2,那么1-4的channels,2-4的channels将被分组进行归一化。
Parameters(参数):

  • num_groups:定义了将通道分为多少组,每组内独立计算均值和方差。
  • num_channels:定义了输入数据的通道数,确保与 num_groups 匹配。
  • eps:防止除零错误的小值,确保计算稳定性。
  • affine:决定是否为每个通道学习仿射参数(缩放和偏移)。

示例代码:

python 复制代码
input = torch.randn(20, 6, 10, 10)
# Separate 6 channels into 3 groups
m = nn.GroupNorm(3, 6)
# Separate 6 channels into 6 groups (equivalent with InstanceNorm)
m = nn.GroupNorm(6, 6)
# Put all 6 channels into a single group (equivalent with LayerNorm)
m = nn.GroupNorm(1, 6)
# Activating the module
output = m(input)

纸上得来终觉浅,绝知此事要躬行!多分析源码,收获良多。

相关推荐
哭泣的眼泪4083 分钟前
解析粗糙度仪在工业制造及材料科学和建筑工程领域的重要性
python·算法·django·virtualenv·pygame
珠海新立电子科技有限公司30 分钟前
FPC柔性线路板与智能生活的融合
人工智能·生活·制造
湫ccc44 分钟前
《Python基础》之基本数据类型
开发语言·python
IT古董44 分钟前
【机器学习】机器学习中用到的高等数学知识-8. 图论 (Graph Theory)
人工智能·机器学习·图论
曼城周杰伦1 小时前
自然语言处理:第六十三章 阿里Qwen2 & 2.5系列
人工智能·阿里云·语言模型·自然语言处理·chatgpt·nlp·gpt-3
余炜yw2 小时前
【LSTM实战】跨越千年,赋诗成文:用LSTM重现唐诗的韵律与情感
人工智能·rnn·深度学习
drebander2 小时前
使用 Java Stream 优雅实现List 转化为Map<key,Map<key,value>>
java·python·list
莫叫石榴姐2 小时前
数据科学与SQL:组距分组分析 | 区间分布问题
大数据·人工智能·sql·深度学习·算法·机器学习·数据挖掘
威威猫的栗子2 小时前
Python Turtle召唤童年:喜羊羊与灰太狼之懒羊羊绘画
开发语言·python
如若1232 小时前
利用 `OpenCV` 和 `Matplotlib` 库进行图像读取、颜色空间转换、掩膜创建、颜色替换
人工智能·opencv·matplotlib