本文詳解深度學習中常見的歸一化方法。
【歸一化是將數據按比例縮放,使之落入一個特定的區間】
目錄
- 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=1m?xk(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=1n?xi? -
計算該樣本的方差 σ 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=1W?xc?(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)