nn.BatchNorm 和nn.LayerNorm详解

本文深入解析了深度学习中两种重要的归一化技术——BatchNorm和LayerNorm。BatchNorm对每个批次的样本进行标准化,而LayerNorm则对每个样本的所有元素进行标准化。通过实例展示了这两种归一化方法在不同数据形状上的应用,并对比了它们在处理序列模型时的效果。理解这两者的区别对于优化神经网络性能至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BatchNorm和LayerNorm两者都是将张量的数据进行标准化的函数,区别在于BatchNorm是把一个batch里的所有样本作为元素做标准化,类似于我们统计学中讲的“组间”。layerNorm是把一个样本中所有数据作为元素做标准化,类似于统计学中的“组内”。下面直接举例说明。

首先我这里定义了一个shape为(2,3,2,2)的一个数据。对应(N,C,H,W)表示我这一堆数据中有2个样本,每个样本是一个通道数(channel)为3,长宽为2的图片。如下图。

#设置BatchNorm2d参数

bn=nn.BatchNorm2d(3) #注意参数必须和channel值相同。

print(bn(X)) #输入的X必须是4维的张量(N,C,H,W)

 

 

注意看,经过标准化处理后,第一张图片值全部为负,第二张全部为正,这是因为第二张图片设定的值大于第一张。所以这下我们可以理解了BatchNorm是把每一张图片(样本)当做一个元素,对这些元素做标准化处理。

同理可得BatchNorm1d   

定义一个shape为(2,3)的张量

 

#定义BatchNorm1d的参数
bn=nn.BatchNorm1d(3) # shape必须与channel值相同
print(bn(X)) #输入的X必须是二维或者三维张量(N,C)或者(N,C,L)

 

从输出结果可知,1d与2d的作用相同,只不过从2*2的图片变成了1*L长的序列。

下面来看LayerNorm 。

仍然使用最开始的(2,3,2,2)的数据 

#定义LayerNorm 
ln=nn.LayerNorm([3,2,2]) # 参数shape必须与每个图片的形状相同
print(ln(X)) 

 

 

这次可以看到每个样本中都是最后一个channel值为正,这是因为第三个通道的值大得多。

LayerNorm是对样本里所有值做标准化处理,而与另外一个样本无关,这是与BatchNorm的根本区别。

同理 BatchNorm和 LayerNorm还可以用在nlp的序列模型中

定义一个shape为(2,4,4)的序列

 

 

#定义BatchNorm和LayerNorm使其能用于nlp序列
bn=BatchNorm1d(4) #参数必须与序列的最后一个维度相同
ln=LayerNorm(4)#参数必须与序列的最后一个维度相同
print(bn(X))
print(ln(X))

LayerNorm结果

 

 

BatchNorm1d结果

 

 

# 整体网络架构 SignatureNet:整体网络结构,看起来像是基于ResNet的架构,但使用了CBAMBottleneck。包含初始的卷积层、BN、ReLU最大池化,然后是四个层(layer1到layer4),每个层由多个CBAMBottleneck组成。最后是自适应平均池化全连接层进行分类。 class SignatureNet(nn.Module): def __init__(self, num_classes=2, in_channels=3): super(SignatureNet, self).__init__() self.inplanes = 64 # 输入通道适配(支持灰度图) self.conv1 = nn.Conv2d(in_channels, 64, kernel_size=7, stride=2, padding=3, bias=False) # 将通道数转换为64通道 self.bn1 = nn.BatchNorm2d(64) # 一般这种Norm是为了稳定数据分布,使得训练稳定 self.relu = nn.ReLU(inplace=True) self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) # 使用CBAMBottleneck构建ResNet骨干 self.layer1 = self._make_layer(CBAMBottleneck, 64, 3) # 3个块,输出256通道。之后通道扩展:每层首块进行下采样通道扩展(64→256→512→1024→2048) self.layer2 = self._make_layer(CBAMBottleneck, 128, 4, stride=2) # 下采样,通过stride=2逐步缩小特征图尺寸(H/32, W/32) self.layer3 = self._make_layer(CBAMBottleneck, 256, 6, stride=2) # 深度配置:layer3包含6个块,加强深层特征提取能力 self.layer4 = self._make_layer(CBAMBottleneck, 512, 3, stride=2) # 保持高分辨率浅层特征(layer1不降采样),利于捕捉细节纹理 # 深层使用更多下采样,扩大感受野,捕获全局语义 # 分类头 self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) # 将比如2048 x 7 x 7的维度转换为 2048 x 1 x 1,2048是通道数,后面是特征图大小,pooling的目的是用特征向量代替图像的表达 self.fc = nn.Linear(512 * CBAMBottleneck.expansion, num_classes) # 作用:定义分类器(全连接层),将全局特征向量映射到类别概率空间。 我需要这个类的架构,你还要告诉我我应该重点介绍哪些部分,怎么介绍
最新发布
04-03
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值