本文详解深度学习中常见的归一化方法。
【归一化是将数据按比例缩放,使之落入一个特定的区间】
目录
- 1. 批量归一化(Batch Normalization,BN)
- 1.1 数学原理
- 1.2 代码示例
- 2. 层归一化(Layer Normalization,LN)
- 2.2 代码示例
- 3. 实例归一化(Instance Normalization,IN)
- 3.1 数学原理
- 3.2 代码示例
1. 批量归一化(Batch Normalization,BN)
1.1 数学原理
对于一个包含 m m m个样本的小批量数据 x = { x ( 1 ) , x ( 2 ) , ⋯ , x ( m ) } x = \{x^{(1)}, x^{(2)}, \cdots, x^{(m)}\} x={x(1),x(2),⋯,x(m)}, 在第 k k k个特征维度上,批量归一化的步骤如下:
-
计算该维度上的均值 μ k \mu_k μk:
μ k = 1 m ∑ i = 1 m x k ( i ) \mu_k = \frac{1}{m}\sum_{i = 1}^{m}x^{(i)}_k μk=m1∑i=1mxk(i) -
计算该维度上的方差 σ k 2 \sigma^2_k σk2:
σ k 2 = 1 m ∑ i = 1 m ( x k ( i ) − μ k ) 2 \sigma^2_k = \frac{1}{m}\sum_{i = 1}^{m}(x^{(i)}_k - \mu_k)^2 σk2=m1∑i=1m(xk(i)−μk)2 -
对该维度上的每个样本进行归一化:
x ^ k ( i ) = x k ( i ) − μ k σ k 2 + ϵ \hat{x}^{(i)}_k = \frac{x^{(i)}_k - \mu_k}{\sqrt{\sigma^2_k + \epsilon}} x^k(i)=σk2+ϵxk(i)−μk
其中 ϵ 是一个很小的常数,用于防止分母为零
1.2 代码示例
在 PyTorch 中,可以使用torch.nn.BatchNorm2d
来实现批量归一化:
import torch
import torch.nn as nn# 定义一个批量归一化层,输入通道数为3
bn = nn.BatchNorm2d(3)# 模拟一个小批量的图像数据,形状为 (batch_size, channels, height, width)
x = torch.randn(16, 3, 32, 32)# 进行批量归一化
y = bn(x)
print(y.shape)
2. 层归一化(Layer Normalization,LN)
层归一化是对单个样本的所有特征维度进行归一化。对于一个样本 x = [ x 1 , x 2 , ⋯ , x n ] x = [x_1, x_2, \cdots, x_n] x=[x1,x2,⋯,xn], 其归一化步骤如下:
-
计算该样本的均值 μ \mu μ:
μ = 1 n ∑ i = 1 n x i \mu = \frac{1}{n}\sum_{i = 1}^{n}x_i μ=n1∑i=1nxi -
计算该样本的方差 σ 2 \sigma^2 σ2:
σ 2 = 1 n ∑ i = 1 n ( x i − μ ) 2 \sigma^2 = \frac{1}{n}\sum_{i = 1}^{n}(x_i - \mu)^2 σ2=n1∑i=1n(xi−μ)2 -
对该样本的每个特征进行归一化:
x ^ i = x i − μ σ 2 + ϵ \hat{x}_i = \frac{x_i - \mu}{\sqrt{\sigma^2 + \epsilon}} x^i=σ2+ϵxi−μ
2.2 代码示例
在 PyTorch 中,可以使用torch.nn.LayerNorm
来实现层归一化:
import torch
import torch.nn as nn# 定义一个层归一化层,归一化的维度为32
ln = nn.LayerNorm(32)# 模拟一个样本数据,形状为 (batch_size, sequence_length, features)
x = torch.randn(16, 10, 32)# 进行层归一化
y = ln(x)
print(y.shape)
3. 实例归一化(Instance Normalization,IN)
3.1 数学原理
实例归一化主要用于图像生成和风格迁移等任务,它是对每个样本的每个通道分别进行归一化。对于一个样本的第 c c c个通道的特征图 x c x_c xc, 其归一化步骤如下:
- 计算该通道的均值 μ c \mu_c μc:
μ c = 1 H × W ∑ i = 1 H ∑ j = 1 W x c ( i , j ) \mu_c = \frac{1}{H \times W}\sum_{i = 1}^{H}\sum_{j = 1}^{W}x_c(i, j) μc=H×W1∑i=1H∑j=1Wxc(i,j)
其中 H H H和 W W W 分别是特征图的高度和宽度。
-
计算该通道的方差 σ c 2 \sigma^2_c σc2:
σ c 2 = 1 H × W ∑ i = 1 H ∑ j = 1 W ( x c ( i , j ) − μ c ) 2 \sigma^2_c = \frac{1}{H \times W}\sum_{i = 1}^{H}\sum_{j = 1}^{W}(x_c(i, j) - \mu_c)^2 σc2=H×W1∑i=1H∑j=1W(xc(i,j)−μc)2 -
对该通道的每个像素进行归一化:
x ^ c ( i , j ) = x c ( i , j ) − μ c σ c 2 + ϵ \hat{x}_c(i, j) = \frac{x_c(i, j) - \mu_c}{\sqrt{\sigma^2_c + \epsilon}} x^c(i,j)=σc2+ϵxc(i,j)−μc
3.2 代码示例
在 PyTorch 中,可以使用torch.nn.InstanceNorm2d
来实现实例归一化:
import torch
import torch.nn as nn# 定义一个实例归一化层,输入通道数为3
in_layer = nn.InstanceNorm2d(3)# 模拟一个小批量的图像数据,形状为 (batch_size, channels, height, width)
x = torch.randn(16, 3, 32, 32)# 进行实例归一化
y = in_layer(x)
print(y.shape)