本文详细介绍了Batch Normalization的实现和数学原理:
方法概述:Batch Normalization适用于4D输入(即小批量的2D输入加上通道维度),其基本公式为:
y = x − μ [ x ] V a r [ x ] + ϵ ⋅ γ + β y = \frac{x - \mu[x]}{\sqrt{\mathrm{Var}[x] + \epsilon}} \cdot \gamma + \beta y=Var[x]+ϵx−μ[x]⋅γ+β
其中, μ [ x ] \mu[x] μ[x]和 V a r [ x ] \mathrm{Var}[x] Var[x]分别是输入 x x x的均值和方差, ϵ \epsilon ϵ是为了数值稳定性而添加的小常数, γ \gamma γ和 β \beta β是可学习的参数。
参数设置:
训练与评估:在训练阶段,Batch Normalization计算当前批次的均值和方差,并使用这些统计量进行标准化;在评估阶段,使用训练期间获得的运行均值和方差。
实现示例:
m = nn.BatchNorm2d(100)
m = nn.BatchNorm2d(100, affine=False)[3]
input = torch.randn(20, 100, 35, 45)[4]
output = m(input)
我做了一个小实验
import torch
import torch.nn as nn
m = nn.BatchNorm2d(5, affine=False)
input = torch.randn(1, 5, 2, 2)
print('in',input)
output = m(input)
print('out',output)
结果如下
in tensor([[[[-0.9673, 1.8863],
[-1.4143, 0.0690]],
[[ 0.8643, -0.3151],
[ 0.8062, 0.8624]],
[[-0.0269, -1.8696],
[-0.1054, -0.7035]],
[[-0.9491, 0.8263],
[ 0.0069, 0.6058]],
[[-0.4429, 0.2575],
[ 0.0240, 1.4645]]]])
out tensor([[[[-0.6777, 1.5690],
[-1.0295, 0.1382]],
[[ 0.6166, -1.7301],
[ 0.5008, 0.6127]],
[[ 0.8812, -1.6192],
[ 0.7748, -0.0369]],
[[-1.5587, 1.0237],
[-0.1681, 0.7031]],
[[-1.0916, -0.0970],
[-0.4285, 1.6172]]]])
怎么计算的呢?一开始我以为是归一化到0-1之间,其实不是,根据公式计算。
BatchNorm2d的计算过程如下:
通道独立计算:对于输入张量的每个通道(共5个通道),分别计算该通道内所有元素的均值和方差。输入形状为(1,5,2,2),每个通道有4个元素(1×2×2)。
均值与方差计算:
μ = (所有元素之和) / 元素总数
σ² = (元素与均值的平方差之和) / 元素总数
(PyTorch默认使用无偏估计unbiased=False
,即分母为N,而非N-1)。标准化:对每个元素执行 (x - μ) / sqrt(σ² + eps)
,其中eps
是防止除以零的小常数(默认1e-5)。
仿射变换:当affine=True
时会应用可学习的γ和β参数,但此例中affine=False
,故跳过此步骤。
以第一个通道为例:
[-0.9673, 1.8863, -1.4143, 0.0690]
μ = (-0.9673 + 1.8863 -1.4143 +0.0690)/4 ≈ -0.1066
σ² = [(-0.9673+0.1066)² + (1.8863+0.1066)² + ... ] /4 ≈ 1.6133
σ ≈ sqrt(1.6133 + 1e-5) ≈ 1.2701
[-0.9673+0.1066]/1.2701 ≈ -0.6777
[1.8863+0.1066]/1.2701 ≈ 1.5690
[-0.6777, 1.5690, -1.0295, 0.1382]
,与用户输出一致。其他通道同理:
[0.6166, -1.7301, 0.5008, 0.6127]
也通过相同步骤得出。注意事项:
batch_size=1
时,方差计算可能不稳定(分母较小),但PyTorch仍按上述流程处理。track_running_stats=True
,当前批次的统计量不会更新running_mean
和running_var
(因为动量更新需要多个批次)。综上,输出结果是每个通道独立标准化后的值,无仿射变换,计算过程符合PyTorch的BatchNorm2d实现。
为了验证Batch Normalization的有效性,本文进行了多项实验:
实验结果表明,Batch Normalization显著提高了模型的训练速度和稳定性:
本文提出的Batch Normalization技术通过标准化深度网络的输入,显著加速了训练过程并提高了模型的稳定性。实验结果验证了Batch Normalization在多个深度学习任务中的有效性,未来的研究可以进一步探索其在其他类型模型中的应用和优化。