神经网络权重初始化:正态分布 vs. Xavier初始化

1. 正态分布初始化(Normal Initialization)

原理

正态分布初始化(Normal Initialization)是一种简单的初始化方法,它假设神经网络的权重服从正态分布(高斯分布):
W ∼ N ( μ , σ 2 ) W \sim \mathcal{N}(\mu, \sigma^2) WN(μ,σ2)
其中:

  • μ 均值(通常设为 0 ) \mu均值(通常设为 0) μ均值(通常设为0
  • σ 是标准差(可以调整,例如 0.1 ) \sigma 是标准差(可以调整,例如 0.1) σ是标准差(可以调整,例如0.1
应用场景
  • 适用于线性模型(如 LightGCN、线性回归等),因为它们没有非线性激活函数,避免了梯度消失或爆炸问题。
  • 浅层网络中,正态分布初始化通常能提供合理的收敛性。
  • 用于嵌入向量(如推荐系统中的用户/物品嵌入)初始化,提供随机性。
PyTorch代码示例
import torch
import torch.nn as nn

# 创建一个 3x3 的权重矩阵
weights = torch.empty(3, 3)
nn.init.normal_(weights, mean=0, std=0.1)  # 使用均值 0,标准差 0.1 的正态分布初始化
print(weights)

可能输出:

tensor([[ 0.0564, -0.0342,  0.0971],
        [-0.0123,  0.0422, -0.0788],
        [ 0.0074, -0.0254,  0.0659]])

2. Xavier 初始化(Xavier Initialization / Glorot Initialization)

原理

Xavier 初始化是一种专门针对有非线性激活函数的神经网络的初始化方法。
它的目的是让前向传播和反向传播的方差保持稳定,避免梯度消失或爆炸。

权重 ( W ) 服从:
W ∼ U ( − 6 n in + n out , 6 n in + n out ) W \sim U\left(-\frac{\sqrt{6}}{\sqrt{n_{\text{in}} + n_{\text{out}}}}, \frac{\sqrt{6}}{\sqrt{n_{\text{in}} + n_{\text{out}}}}\right) WU(nin+nout 6 ,nin+nout 6 )
或:
W ∼ N ( 0 , 2 n in + n out ) W \sim \mathcal{N}\left(0, \frac{2}{n_{\text{in}} + n_{\text{out}}}\right) WN(0,nin+nout2)
其中:

  • n in 是上一层的神经元数量 n_{\text{in}} 是上一层的神经元数量 nin是上一层的神经元数量
  • n out 是下一层的神经元数量 n_{\text{out}} 是下一层的神经元数量 nout是下一层的神经元数量
  • U ( a , b ) 代表均匀分布 U(a, b)代表均匀分布 U(a,b)代表均匀分布
  • ( 0 , σ 2 ) 代表正态分布 (0, σ²)代表正态分布 N(0,σ2)代表正态分布
应用场景
  • 适用于深度神经网络(DNN)、MLP(多层感知机)、CNN(卷积神经网络),特别是有ReLU、Tanh、Sigmoid 这类激活函数的网络。
  • 通过缩放权重的初始值,让每一层的输入和输出保持方差一致,防止梯度消失/爆炸。
  • 对于深层网络比普通正态分布初始化更稳定。
PyTorch 代码示例
import torch
import torch.nn as nn

# 创建一个 3x3 的权重矩阵
weights = torch.empty(3, 3)
nn.init.xavier_uniform_(weights)  # Xavier 均匀分布初始化
print(weights)

可能输出:

tensor([[-0.4313,  0.2189, -0.3745],
        [ 0.3827,  0.0576, -0.1932],
        [-0.2154,  0.4018, -0.2498]])

如果想使用Xavier 正态分布(而不是均匀分布):

nn.init.xavier_normal_(weights)

正态分布初始化 vs. Xavier 初始化

方法 适用场景 优缺点
正态分布初始化 适用于浅层模型、线性模型、嵌入层 简单易用,但深层网络可能导致梯度消失/爆炸
Xavier 初始化 适用于DNN、CNN、MLP,特别是带非线性激活的网络 避免梯度消失/爆炸,适合深度网络

总结

  • 如果是浅层网络或者线性模型(如 LightGCN),用正态分布初始化
    nn.init.normal_(weights, mean=0, std=0.1)
    
  • 如果是深度网络(DNN、CNN),用 Xavier 初始化
    nn.init.xavier_uniform_(weights)
    
    nn.init.xavier_normal_(weights)
    
  • Xavier 初始化更适合带非线性激活函数的深度神经网络,而正态分布初始化更简单,但在深层网络中可能会导致训练不稳定。

你可能感兴趣的:(神经网络,人工智能,深度学习)