趋近智
批量归一化 (normalization)(BN)旨在处理深度学习 (deep learning)模型中的内部协变量偏移并稳定训练。其在常见深度学习框架中的实现利用了PyTorch和TensorFlow等框架提供的内置层。这些内置层能够处理前向传播、反向传播 (backpropagation)的复杂计算,以及推理 (inference)时所需的运行统计数据的跟踪。
批量归一化通常作为神经网络 (neural network)模型中的一个独立层添加。主要考量是根据BN层将接收的输入数据选择正确的维度,并决定相对于激活函数 (activation function)的放置位置。
大多数深度学习 (deep learning)库提供不同的BN变体:
(N, C) 或 (N, C, L),其中 N 为批量大小,C 为特征数量,L 为序列长度(可选)。归一化发生在每个特征 C 的批量维度上。(N, C, H, W),其中 C 为通道数,H 为高度,W 为宽度。归一化发生在每个通道 C 的批量、高度和宽度维度上。(N, C, D, H, W),其中 D 为深度。归一化发生在每个通道 C 的批量、深度、高度和宽度维度上。在PyTorch中,您可以轻松使用 torch.nn 模块添加批量归一化 (normalization)。让我们看看如何引入 BatchNorm1d 和 BatchNorm2d。
考虑一个简单的多层感知机(MLP)。您通常会在线性变换之后,激活函数 (activation function)之前应用 BatchNorm1d。
import torch
import torch.nn as nn
# 假设输入特征 = 784,隐藏单元 = 100,输出类别 = 10
input_features = 784
hidden_units = 100
output_classes = 10
model = nn.Sequential(
nn.Linear(input_features, hidden_units),
# 在线性层之后应用 BatchNorm1d
# num_features 应与上一层的输出大小匹配
nn.BatchNorm1d(num_features=hidden_units),
nn.ReLU(), # 在归一化之后应用激活
nn.Linear(hidden_units, output_classes)
# 注意:分类任务的最终输出层通常不使用BN或激活
)
print(model)
# 假数据使用示例
# 批量大小 N = 64
dummy_input = torch.randn(64, input_features)
output = model(dummy_input)
print("输出形状:", output.shape) # 预期: torch.Size([64, 10])
在CNN中,使用 BatchNorm2d,通常放置在卷积之后和激活之前。
import torch
import torch.nn as nn
# 假设输入图像:3通道,32x32像素
in_channels = 3
out_channels_conv1 = 16
out_channels_conv2 = 32
model_cnn = nn.Sequential(
# 卷积层 1
nn.Conv2d(in_channels=in_channels, out_channels=out_channels_conv1, kernel_size=3, padding=1),
# 在卷积之后应用 BatchNorm2d
# num_features 应与 Conv2d 的输出通道数匹配
nn.BatchNorm2d(num_features=out_channels_conv1),
nn.ReLU(), # 在归一化之后应用激活
nn.MaxPool2d(kernel_size=2, stride=2),
# 卷积层 2
nn.Conv2d(in_channels=out_channels_conv1, out_channels=out_channels_conv2, kernel_size=3, padding=1),
nn.BatchNorm2d(num_features=out_channels_conv2),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2)
# ... 后面可能跟着展平层和线性层
)
print(model_cnn)
# 假数据使用示例
# 批量大小 N = 16
dummy_input_cnn = torch.randn(16, in_channels, 32, 32)
output_cnn = model_cnn(dummy_input_cnn)
# 输出形状取决于层,这里是经过两个 2x2 最大池化后:
# H_out = 32 / 2 / 2 = 8
# W_out = 32 / 2 / 2 = 8
print("CNN 输出形状:", output_cnn.shape) # 预期: torch.Size([16, 32, 8, 8])
创建批量归一化 (normalization)层时,您会遇到几个参数:
num_features:这是最主要的参数。它指定被归一化维度的尺寸。对于 BatchNorm1d,它是特征数量 C。对于 BatchNorm2d,它是通道数 C。您必须根据前一层的输出形状正确设置此项。eps (epsilon):一个添加到归一化过程中分母(方差)上的小值 (): 这确保了数值稳定性,防止除以零,如果小批量方差非常接近零。一个典型的默认值是 1e-5。momentum:此参数控制运行平均值 () 和方差 () 估计值的更新规则,这些估计值用于评估/推理 (inference)阶段。更新通常是一个指数移动平均:
动量值越高,表示运行估计值越依赖于当前小批量 的统计数据。PyTorch中的默认值是 0.1。affine:一个布尔值(默认为 True)。如果设为 True,批量归一化层包含可学习的仿射变换参数:缩放 () 和平移 ()。这些参数在训练期间像其他网络权重 (weight)一样被学习。归一化步骤的输出如下:
保持 affine=True 允许网络在有利于学习的情况下潜在地取消归一化,从而给模型更大的灵活性。禁用它(affine=False)意味着 固定为1, 固定为0。track_running_stats:一个布尔值(默认为 True)。当为 True 时,层在训练期间保持均值和方差的运行估计值。这些运行估计值随后在评估期间用于归一化。如果设为 False,即使在评估期间,层也会使用当前小批量统计数据进行归一化,这通常不理想,除非用于特定的高级使用情形。一个常见的讨论点是批量归一化 (normalization)层应放置在激活函数(如ReLU)之前还是之后。
Linear/Conv -> BN -> Activation
Linear/Conv -> Activation -> BN
实践中,将BN放置在激活函数之前是更常见的惯例,并在许多有影响力的架构(如ResNets)中是标准做法。它通常会产生良好的结果。然而,像深度学习 (deep learning)架构设计的许多方面一样,最佳放置位置可能取决于具体任务,实验有时会显示出放置在激活函数之后也有益处。对于大多数目的,遵循传统的 Conv/Linear -> BN -> Activation 顺序是一个可靠的起点。
使用批量归一化 (normalization)最重要的实践方面之一是确保您的模型在训练和评估模式之间正确切换。
训练期间(PyTorch中为 model.train()):
track_running_stats=True,层会使用指定的 momentum 更新其均值和方差的运行估计值。affine=True,则 和 参数 (parameter)通过反向传播 (backpropagation)更新。评估/推理 (inference)期间(PyTorch中为 model.eval()):
这种切换对于在测试和部署期间获得一致且可复现的结果很有必要。未设置 model.eval() 可能导致在推理时使用批量统计数据,从而根据测试批量的组成出现潜在的不可预测行为。
import torch
import torch.nn as nn
# 假设一个带有 BN 的简单模型
model = nn.Sequential(
nn.Linear(10, 20),
nn.BatchNorm1d(20),
nn.ReLU()
)
# --- 训练阶段 ---
model.train() # 将模型设置为训练模式
print(f"模型在训练期间的模式:{'训练' if model.training else '评估'}")
# 前向传播使用小批量统计数据,更新运行统计数据
# --- 评估/推理阶段 ---
model.eval() # 将模型设置为评估模式
print(f"模型在评估期间的模式:{'训练' if model.training else '评估'}")
# 前向传播使用运行统计数据,不更新运行统计数据
# 用于演示的假输入
dummy_input = torch.randn(4, 10) # 批量大小 4
with torch.no_grad(): # 推理时禁用梯度计算
output_eval = model(dummy_input)
print("评估期间的输出形状:", output_eval.shape)
通过正确实现批量归一化层并管理它们的训练/评估状态,您可以利用它们的能力来稳定训练,允许更高的学习率,并加速深度学习 (deep learning)模型的收敛。
这部分内容有帮助吗?
BatchNorm1d 的官方文档,详细说明其用法、参数以及在训练和评估模式下的行为。此文档也适用于 BatchNorm2d 和 BatchNorm3d。© 2026 ApX Machine Learning用心打造