神经网络学习是非凸优化问题,使用梯度下降法进行网络参数优化时,参数的初始化选值至关重要。
参数初始化的分类:
随机初始化, 预训练初始化,固定值初始化
- 随机初始化:最常用的参数初始化策略,通过一个随机采样函数来生成每个参数的初始值。
- 预训练初始化:一种在实践中经常使用的初始化策略,如果目标任务的训练数据不足,可以使用一个已经在大规模数据上训练过的模型作为参数初始值。预训练模型在目标任务上的学习过程也称为精调Fine-Tuning。
- 固定值初始化:对于神经网络中的某些重要参数,可以根据先验知识来初始化。比如对于使用ReLU激活函数的全连接层,其偏置通常可以设为比较小的正数(比如0.01),从而确保这一层的神经元的梯度不为0,避免死亡ReLU现象。
比较
| 初始化方法 | 核心原理 | 典型应用场景 | 主要优点 | 主要缺点 |
|---|---|---|---|---|
| 随机初始化 | 基于概率分布(如均匀分布、正态分布)随机生成权重参数 | 常规神经网络训练、无预训练模型可用时 | 实现简单,打破神经元对称性 | 可能陷入局部最优,需调参确定分布范围 |
| 预训练初始化 | 使用预训练模型的权重参数初始化新模型,通常结合迁移学习 | 小数据集场景、相似任务迁移、模型微调 | 加速收敛,利用预训练知识提升性能 | 依赖预训练模型可用性,可能需调整结构 |
| 固定值初始化 | 将所有权重参数设为相同的固定常数(如 0、0.1 等) | 特定研究场景、偏置项初始化 | 操作简单,便于复现实验 | 易导致神经元输出相同,引发对称性问题 |
在图像分类等自己的任务中,通常使用预训练初始化。
![]()
随机初始化
基于固定方差的参数初始化
基于固定方差的参数初始化:高斯分布初始化、均匀分布初始化
从一个固定均值(通常为 0)和方差σ2的分布中采样来生成参数的初始值

基于方差缩放的参数初始化
始化一个深度网络时,为了缓解梯度消失或爆炸问题,我们尽可能保持每个神经元的输入和输出的方差一致,根据神经元的连接数量来自适应地调整初始化分布的方差,这类方法称为方差缩放(Variance Scaling)。
基于方差缩放的参数初始化:Xavier初始化、He初始化
Xavier初始化
根据每层的神经元数量来自动计算初始化参数方差
模型构建
根据

MLP算子(全连接神经网络)
init_fn_name指定参数初始化的方法:normal或uniform,都不指定默认方差为1
class MLP(nn.Layer):
def __init__(self, layers_size, init_fn_name, init_fn, act_fn):
"""
多层网络初始化
输入:
- layers_size: 每层神经元的数量
- init_fn_name: 网络中参数初始化方法,可以为 'normal'或'uniform'
- init_fn: 函数,用来计算高斯分布标准差或均匀分布r值
- act_fn: 激活函数
"""
super(MLP, self).__init__()
self.linear = nn.Sequential()
self.num_layers = len(layers_size) - 1
for i in range(self.num_layers):
input_size, output_size = layers_size[i], layers_size[i + 1]
if init_fn_name == 'normal':
# Xavier高斯分布初始化,计算方差
self.linear.add_sublayer(str(i), nn.Linear(input_size, output_size,
weight_attr=nn.initializer.Normal(mean=0, std=init_fn(input_size, output_size))))
elif init_fn_name == 'uniform':
r = init_fn(input_size, output_size)
self.linear.add_sublayer(str(i), nn.Linear(input_size, output_size, weight_attr=nn.initializer.Uniform(low=-r, high=r)))
else:
self.linear.add_sublayer(str(i), nn.Linear(input_size, output_size, weight_attr=nn.initializer.Normal()))
self.act_fn = act_fn()
self.z = {}
def __call__(self, X):
return self.forward(X)
def forward(self, X):
"""
前向计算
"""
y = X
for num_layer in range(self.num_layers):
y = self.linear[num_layer](y)
if num_layer != self.num_layers - 1:
y = self.act_fn(y)
self.z[num_layer] = y
return y
Xavier高斯分布
指定五层网络,指定参数初始化方法是normal

目的:尽量保证输入输出的方差一致

Xavier均匀分布
根据




对比是否使用Xavier初始化其收敛性

结果
明显看出xavier的收敛性更好。


&spm=1001.2101.3001.5002&articleId=148806840&d=1&t=3&u=708fd7a57565448c8a3b8dc3653e49f4)
1564

被折叠的 条评论
为什么被折叠?



