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

2024-09-02 22:52

本文主要是介绍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)

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

这篇关于Pytorch中不同的Norm归一化详细讲解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1131296

相关文章

Python中isinstance()函数原理解释及详细用法示例

《Python中isinstance()函数原理解释及详细用法示例》isinstance()是Python内置的一个非常有用的函数,用于检查一个对象是否属于指定的类型或类型元组中的某一个类型,它是Py... 目录python中isinstance()函数原理解释及详细用法指南一、isinstance()函数

Python的pandas库基础知识超详细教程

《Python的pandas库基础知识超详细教程》Pandas是Python数据处理核心库,提供Series和DataFrame结构,支持CSV/Excel/SQL等数据源导入及清洗、合并、统计等功能... 目录一、配置环境二、序列和数据表2.1 初始化2.2  获取数值2.3 获取索引2.4 索引取内容2

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

Python屏幕抓取和录制的详细代码示例

《Python屏幕抓取和录制的详细代码示例》随着现代计算机性能的提高和网络速度的加快,越来越多的用户需要对他们的屏幕进行录制,:本文主要介绍Python屏幕抓取和录制的相关资料,需要的朋友可以参考... 目录一、常用 python 屏幕抓取库二、pyautogui 截屏示例三、mss 高性能截图四、Pill

java时区时间转为UTC的代码示例和详细解释

《java时区时间转为UTC的代码示例和详细解释》作为一名经验丰富的开发者,我经常被问到如何将Java中的时间转换为UTC时间,:本文主要介绍java时区时间转为UTC的代码示例和详细解释,文中通... 目录前言步骤一:导入必要的Java包步骤二:获取指定时区的时间步骤三:将指定时区的时间转换为UTC时间步

Java中实现对象的拷贝案例讲解

《Java中实现对象的拷贝案例讲解》Java对象拷贝分为浅拷贝(复制值及引用地址)和深拷贝(递归复制所有引用对象),常用方法包括Object.clone()、序列化及JSON转换,需处理循环引用问题,... 目录对象的拷贝简介浅拷贝和深拷贝浅拷贝深拷贝深拷贝和循环引用总结对象的拷贝简介对象的拷贝,把一个

MySQL批量替换数据库字符集的实用方法(附详细代码)

《MySQL批量替换数据库字符集的实用方法(附详细代码)》当需要修改数据库编码和字符集时,通常需要对其下属的所有表及表中所有字段进行修改,下面:本文主要介绍MySQL批量替换数据库字符集的实用方法... 目录前言为什么要批量修改字符集?整体脚本脚本逻辑解析1. 设置目标参数2. 生成修改表默认字符集的语句3

MySQL使用EXISTS检查记录是否存在的详细过程

《MySQL使用EXISTS检查记录是否存在的详细过程》EXISTS是SQL中用于检查子查询是否返回至少一条记录的运算符,它通常用于测试是否存在满足特定条件的记录,从而在主查询中进行相应操作,本文给大... 目录基本语法示例数据库和表结构1. 使用 EXISTS 在 SELECT 语句中2. 使用 EXIS

Git打标签从本地创建到远端推送的详细流程

《Git打标签从本地创建到远端推送的详细流程》在软件开发中,Git标签(Tag)是为发布版本、标记里程碑量身定制的“快照锚点”,它能永久记录项目历史中的关键节点,然而,仅创建本地标签往往不够,如何将其... 目录一、标签的两种“形态”二、本地创建与查看1. 打附注标http://www.chinasem.cn

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具