相关文章
Pytorch学习笔记(一):torch.cat()模块的详解
Pytorch学习笔记(二):nn.Conv2d()函数详解
Pytorch学习笔记(三):nn.BatchNorm2d()函数详解
Pytorch学习笔记(四):nn.MaxPool2d()函数详解
Pytorch学习笔记(五):nn.AdaptiveAvgPool2d()函数详解
Pytorch学习笔记(六):view()和nn.Linear()函数详解
Pytorch学习笔记(七):F.softmax()和F.log_softmax函数详解
✅💖⚠️▶️➡️🌿🍀🍄🌟⭐❄️✅💖⚠️▶️➡️🌿🍀🍄🌟⭐❄️✅💖⚠️▶️➡️🌿🍀🍄🌟⭐❄️✅💖⚠️
1. 函数语法格式和作用▶️
在深度学习的卷积神经网络(CNN)架构中,torch.nn.BatchNorm2d
扮演着至关重要的角色。在卷积层之后,总会添加 BatchNorm2d
对数据进行归一化处理。这一操作有着深远的意义和影响。
在神经网络的训练过程中,数据的分布会随着网络层的传递而发生变化,这种现象被称为 “内部协变量偏移”。当数据在经过卷积层后,其数值范围可能会出现较大的波动。如果这些数据在进入激活函数(如 ReLU)之前没有得到有效的处理,过大的数据值可能会导致激活函数的输出饱和,使得神经元的梯度变得极小,从而导致网络学习速度变慢,甚至出现梯度消失的问题,严重影响网络性能的稳定性。
而 BatchNorm2d
的作用就在于通过对每个小批量数据进行归一化处理,将数据的均值和方差调整到一个相对稳定的范围。具体来说,它会对每个特征维度分别计算均值和方差,并将数据归一化到均值为 0、方差为 1 的分布。这样一来,无论输入数据的初始分布如何,经过 BatchNorm2d
处理后的数据都具有相似的统计特性,从而减少了内部协变量偏移的影响。这不仅有助于加快网络的收敛速度,还能使网络在训练过程中更加稳定,降低了因数据波动过大而导致的模型性能下降的风险。
torch.nn.BatchNorm2d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
2. 参数解释▶️
-
num_features:这是一个关键参数,用于指定输入数据中的特征数量。在卷积神经网络中,输入数据的形状通常为
batch_size×num_features×height×width
,其中num_features
表示每个样本在空间维度(height
和width
)上的特征通道数。例如,对于 RGB 图像,在经过一些卷积层处理后,num_features
可能表示卷积层输出的特征图通道数。这个参数决定了BatchNorm2d
层需要对多少个特征维度进行归一化操作。不同的特征维度会有各自独立的均值和方差计算,以及后续的参数调整。 -
eps:它是在分母中添加的一个极小的值,默认设置为
1e-5
。在归一化计算过程中,需要计算方差并将其作为分母进行除法运算。为了避免分母为零的情况(尤其是在方差接近零的极端情况下),从而确保计算的稳定性,就引入了eps
。这个微小的常数可以防止在计算归一化值时出现除零错误,保证了整个归一化过程的数值稳定性。即使方差非常小,加上eps
后也能得到一个非零的分母,使得计算能够顺利进行。 -
momentum:这是一个用于在运行过程中估计均值和方差的参数。它类似于随机梯度下降(SGD)中的动量系数,起到了稳定估计过程的作用。在训练过程中,
BatchNorm2d
层需要不断地更新每个特征维度的均值和方差。momentum
控制了新的统计量(当前小批量数据的均值和方差)与之前估计值之间的融合比例。具体来说,新的均值和方差估计值是当前小批量数据的统计量与之前估计值的加权平均,其中momentum
决定了之前估计值的权重,而1 - momentum
则是当前小批量数据统计量的权重。较大的momentum
值会使估计值更依赖于之前的统计信息,变化相对缓慢,适合在数据分布较为稳定的情况下使用;较小的momentum
值则会更注重当前小批量数据的统计信息,能够更快地适应数据分布的变化。 -
affine:这是一个布尔值参数,当设置为
true
时,BatchNorm2d
层会引入两个可学习的参数矩阵gamma
和beta
。gamma
和beta
分别用于对归一化后的数据进行缩放和平移操作。gamma
是一个形状为(num_features,)
的缩放系数向量,它可以对每个特征维度进行独立的缩放,用于调整数据的幅度;beta
是一个形状同样为(num_features,)
的偏移系数向量,用于对每个特征维度进行独立的偏移,调整数据的位置。通过学习这两个参数矩阵,BatchNorm2d
层可以在归一化的基础上,进一步对数据进行个性化的调整,使得模型能够更好地适应不同的数据集和任务需求。如果affine
设置为false
,则BatchNorm2d
层仅进行归一化操作,不引入可学习的缩放和平移参数。 -
track_running_stats:这是一个布尔值参数,默认值为
true
。当设置为true
时,BatchNorm2d
层会在训练过程中跟踪并记录每个特征维度的运行均值和方差。这些运行统计量是基于所有已处理的小批量数据计算得到的,会随着训练的进行不断更新。在测试阶段,模型会使用这些运行统计量来对输入数据进行归一化,而不是使用当前测试数据的统计量。这样做的目的是为了在测试时能够提供稳定的归一化结果,避免因测试数据的小批量特性导致的统计波动。当设置为false
时,在训练和测试阶段都会使用当前数据的统计量进行归一化。
通过对这些参数的深入理解和合理调整,开发者可以充分发挥 torch.nn.BatchNorm2d
的优势,优化卷积神经网络的性能和稳定性,提高模型在各种任务中的表现。
3.具体代码▶️
这段 Python 代码主要展示了如何在 PyTorch 中使用 nn.BatchNorm2d
进行批归一化操作,并对比了 affine
参数为 True
和 False
时的不同效果。以下是对代码的详细分析:
1. 编码声明与库导入
# encoding:utf-8
import torch
import torch.nn as nn
# encoding:utf-8
:这行代码指定了文件的编码格式为 UTF - 8,确保代码中可以正确处理中文字符等非 ASCII 字符(虽然本代码中未涉及)。import torch
和import torch.nn as nn
:导入 PyTorch 库及其神经网络模块。torch
是 PyTorch 的核心库,提供了张量操作等基础功能;nn
是 PyTorch 中用于构建神经网络的高级接口。
2. 批归一化层的实例化
m = nn.BatchNorm2d(3) # affine参数设为True表示weight和bias将被使用
m1 = nn.BatchNorm2d(3, affine=False) # affine参数设为True表示weight和bias将被使用
m = nn.BatchNorm2d(3)
:创建一个nn.BatchNorm2d
实例m
,num_features
参数设置为 3。这意味着该批归一化层将对输入数据中每个样本的 3 个特征通道进行归一化操作。默认情况下,affine=True
,这表示该层将包含可学习的权重参数weight
和偏置参数bias
。m1 = nn.BatchNorm2d(3, affine=False)
:创建另一个nn.BatchNorm2d
实例m1
,同样num_features
为 3,但affine=False
,这意味着该层不会包含可学习的权重和偏置参数,仅进行归一化操作。
3. 输入数据的生成
input = torch.randn(2, 3, 2, 3)
- 使用
torch.randn
函数生成一个形状为(2, 3, 2, 3)
的随机张量input
。这个张量表示输入数据,其中:- 第一个维度
2
表示 batch size,即一次处理的样本数量。 - 第二个维度
3
对应于nn.BatchNorm2d
中的num_features
,表示每个样本的特征通道数。 - 第三和第四个维度
2
和3
分别表示特征图的高度和宽度。
- 第一个维度
4. 批归一化操作与输出
output = m(input)
output1 = m1(input)
output = m(input)
:将输入数据input
传入m
实例进行批归一化操作,由于m
的affine=True
,操作过程中会使用可学习的权重和偏置参数对归一化后的数据进行缩放和平移。output1 = m1(input)
:将相同的输入数据input
传入m1
实例进行批归一化操作,由于m1
的affine=False
,操作仅进行归一化,不进行额外的缩放和平移。
5. 结果输出与分析
print('"""affine=True"""')
print(input)
print(m.weight)
print(m.bias)
print(output)
print(output.size())
print('"""affine=False"""')
print(output1)
print(output1.size())
- 首先输出
'"""affine=True"""'
,作为标记,表明接下来的输出是affine=True
时的情况。- 打印
input
,展示输入数据的具体值。 - 打印
m.weight
,这是m
实例中可学习的权重参数,初始值为全 1 的张量,并且requires_grad=True
表示该参数在训练过程中会计算梯度以进行更新。 - 打印
m.bias
,这是m
实例中可学习的偏置参数,初始值为全 0 的张量,同样requires_grad=True
。 - 打印
output
,展示经过m
批归一化后的输出数据。 - 打印
output.size()
,显示输出数据的形状,与输入数据形状相同,都是(2, 3, 2, 3)
,说明批归一化操作不改变数据的形状。
- 打印
- 接着输出
'"""affine=False"""'
,标记接下来的输出是affine=False
时的情况。- 打印
output1
,展示经过m1
批归一化后的输出数据。 - 打印
output1.size()
,显示其形状也是(2, 3, 2, 3)
。
- 打印
通过对比 output
和 output1
,可以发现当 affine=False
时,批归一化操作仅对数据进行了归一化,而当 affine=True
时,除了归一化,还使用了可学习的权重和偏置对数据进行了进一步的调整,使得输出结果在数值上有所不同。
6. 总结
这段代码通过简单的示例,清晰地展示了 nn.BatchNorm2d
层的基本使用方法以及 affine
参数对批归一化操作结果的影响。在实际的神经网络训练中,合理使用批归一化可以加速模型收敛、提高模型的稳定性和泛化能力。
✅💖⚠️▶️➡️🌿🍀🍄🌟⭐❄️✅💖⚠️▶️➡️🌿🍀🍄🌟⭐❄️✅💖⚠️▶️➡️🌿🍀🍄🌟⭐❄️✅💖⚠️