神经网络权重初始化:正态分布 vs. Xavier初始化
Xavier 初始化是一种专门针对。是标准差(可以调整,例如。的神经网络的初始化方法。,避免梯度消失或爆炸。是上一层的神经元数量。是下一层的神经元数量。
·
1. 正态分布初始化(Normal Initialization)
原理
正态分布初始化(Normal Initialization)是一种简单的初始化方法,它假设神经网络的权重服从正态分布(高斯分布):
W∼N(μ,σ2) W \sim \mathcal{N}(\mu, \sigma^2) W∼N(μ,σ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(−6nin+nout,6nin+nout) 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) W∼U(−nin+nout6,nin+nout6)
或:
W∼N(0,2nin+nout) W \sim \mathcal{N}\left(0, \frac{2}{n_{\text{in}} + n_{\text{out}}}\right) W∼N(0,nin+nout2)
其中:
- nin是上一层的神经元数量n_{\text{in}} 是上一层的神经元数量nin是上一层的神经元数量
- nout是下一层的神经元数量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 初始化更适合带非线性激活函数的深度神经网络,而正态分布初始化更简单,但在深层网络中可能会导致训练不稳定。
更多推荐
所有评论(0)