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]+ϵ xE[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(16.5)2+(26.5)2++(126.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(1318.5)2+(1418.5)2++(2418.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.5930.4260.7401.3010.1351.0321.0100.1571.3230.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.5930.4260.7401.3010.1351.0321.0100.1571.3230.7180.4491.615
4. 应用可学习的仿射变换(可选)

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

  • NLP:
    在NLP领域中,最常见的单体对象就是word。常见的输入形状是[B,Seq_len,Word_dim],即batch_size,每个句子包含几个单词,每个单词的具体维度。所以我们在最后一个维度即单词维度进行归一化。
# 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:
    视觉也不用多说了,最多的就是在后三个维度(即完整的一张图像上)进行归一化。
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: 控制是否在推理时使用运行时统计量。

示例代码如下:

# 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),此时就是支持单个样本进行归一化的情况。

# 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:决定是否为每个通道学习仿射参数(缩放和偏移)。

示例代码:

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)

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

  • 14
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时光诺言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值