后台更新的内容在网站上不显示青岛网站优化公司
目录
1 固定值参数初始化
1.1 全零初始化
1.2 全1初始化
1.3 认识常数初始化
2 随机初始化
3 Vavier初始化
4 He初始化
5 总结
神经网络的参数初始化是训练深度学习模型的关键步骤之一。初始化参数(通常是权重和偏置)会对模型的训练速度、收敛性以及最终的性能产生重要影响。下面是关于神经网络参数初始化的一些常见方法及其相关知识点。
官方文档参考:torch.nn.init — PyTorch 2.7 documentation
1 固定值参数初始化
固定值初始化是指在神经网络训练开始时,将所有权重或偏置初始化为一个特定的常数值。这种初始化方法虽然简单,但在实际深度学习应用中通常并不推荐。
1.1 全零初始化
将神经网络中的所有权重参数初始化为0。
方法:将所有权重初始化为零。
缺点:导致对称性破坏,每个神经元在每一层中都会执行相同的计算,模型无法学习。
应用场景:通常不用来初始化权重,但可以用来初始化偏置。
对称性问题
-
现象:同一层的所有神经元具有完全相同的初始权重和偏置。
-
后果:
-
在反向传播时,所有神经元会收到相同的梯度,导致权重更新完全一致。
-
无论训练多久,同一层的神经元本质上会保持相同的功能(相当于“一个神经元”的多个副本),极大降低模型的表达能力。
-
代码演示:
import torch
import torch.nn as nndef test004():# 3. 全0参数初始化linear = nn.Linear(in_features=6, out_features=4)# 初始化权重参数nn.init.zeros_(linear.weight)# 打印权重参数print(linear.weight)if __name__ == "__main__":test004()
打印结果:
Parameter containing:
tensor([[0., 0., 0., 0., 0., 0.],[0., 0., 0., 0., 0., 0.],[0., 0., 0., 0., 0., 0.],[0., 0., 0., 0., 0., 0.]], requires_grad=True)
1.2 全1初始化
全1初始化会导致网络中每个神经元接收到相同的输入信号,进而输出相同的值,这就无法进行学习和收敛。所以全1初始化只是一个理论上的初始化方法,但在实际神经网络的训练中并不适用。
代码演示:
import torch
import torch.nn as nndef test003():# 3. 全1参数初始化linear = nn.Linear(in_features=6, out_features=4)# 初始化权重参数nn.init.ones_(linear.weight)# 打印权重参数print(linear.weight)if __name__ == "__main__":test003()
输出结果:
Parameter containing:
tensor([[1., 1., 1., 1., 1., 1.],[1., 1., 1., 1., 1., 1.],[1., 1., 1., 1., 1., 1.],[1., 1., 1., 1., 1., 1.]], requires_grad=True)
1.3 认识常数初始化
将所有参数初始化为某个非零的常数(如 0.1,-1 等)。虽然不同于全0和全1,但这种方法依然不能避免对称性破坏的问题。
import torch
import torch.nn as nndef test002():# 2. 固定值参数初始化linear = nn.Linear(in_features=6, out_features=4)# 初始化权重参数nn.init.constant_(linear.weight, 0.63)# 打印权重参数print(linear.weight)passif __name__ == "__main__":test002()
输出结果:
Parameter containing:
tensor([[0.6300, 0.6300, 0.6300, 0.6300, 0.6300, 0.6300],[0.6300, 0.6300, 0.6300, 0.6300, 0.6300, 0.6300],[0.6300, 0.6300, 0.6300, 0.6300, 0.6300, 0.6300],[0.6300, 0.6300, 0.6300, 0.6300, 0.6300, 0.6300]], requires_grad=True)
参考2:
import torch
import torch.nn as nndef test002():net = nn.Linear(2, 2, bias=True)# 假设一个数值x = torch.tensor([[0.1, 0.95]])# 初始化权重参数net.weight.data = torch.tensor([[0.1, 0.2], [0.3, 0.4]])# 输出什么:权重参数会转置output = net(x)print(output, net.bias)passif __name__ == "__main__":test002()
-
所有输入特征被同等对待
-
无法学习特征间的不同重要性
2 随机初始化
方法:将权重初始化为随机的小值,通常从正态分布或均匀分布中采样。
应用场景:这是最基本的初始化方法,通过随机初始化避免对称性破坏。
代码演示:随机分布之均匀初始化
import torch
import torch.nn as nndef test001():# 1. 均匀分布随机初始化linear = nn.Linear(in_features=6, out_features=4)# 初始化权重参数nn.init.uniform_(linear.weight)# 打印权重参数print(linear.weight)if __name__ == "__main__":test001()
打印结果:
Parameter containing:
tensor([[0.4080, 0.7444, 0.7616, 0.0565, 0.2589, 0.0562],[0.1485, 0.9544, 0.3323, 0.9802, 0.1847, 0.6254],[0.6256, 0.2047, 0.5049, 0.3547, 0.9279, 0.8045],[0.1994, 0.7670, 0.8306, 0.1364, 0.4395, 0.0412]], requires_grad=True)
代码演示:正态分布初始化
import torch
import torch.nn as nndef test005():# 5. 正太分布初始化linear = nn.Linear(in_features=6, out_features=4)# 初始化权重参数nn.init.normal_(linear.weight, mean=0, std=1)# 打印权重参数print(linear.weight)if __name__ == "__main__":test005()
打印结果:
Parameter containing:
tensor([[ 1.5321, 0.2394, 0.0622, 0.4482, 0.0757, -0.6056],[ 1.0632, 1.8069, 1.1189, 0.2448, 0.8095, -0.3486],[-0.8975, 1.8253, -0.9931, 0.7488, 0.2736, -1.3892],[-0.3752, 0.0500, -0.1723, -0.4370, -1.5334, -0.5393]],requires_grad=True)
3 Vavier初始化
前置知识:
均匀分布:
均匀分布的概率密度函数(PDF):
计算期望值(均值):
计算方差(二阶矩减去均值的平方):
先计算 :
代入方差公式:
Xavier 初始化(由 Xavier Glorot 在 2010 年提出)是一种自适应权重初始化方法,专门为解决神经网络训练初期的梯度消失或爆炸问题而设计。Xavier 初始化也叫做Glorot初始化。Xavier 初始化的核心思想是根据输入和输出的维度来初始化权重,使得每一层的输出的方差保持一致。具体来说,权重的初始化范围取决于前一层的神经元数量(输入维度)和当前层的神经元数量(输出维度)。
方法:根据输入和输出神经元的数量来选择权重的初始值。
数学原理:
(1) 前向传播的方差一致性
假设输入 x 的均值为 0,方差为 σ_x^2,权重 W的均值为 0,方差为 σ_W^2,则输出 z=Wx的方差为:
为了使 Var(z)=Var(x),需要:
(2) 反向传播的梯度方差一致性
在反向传播过程中,梯度 是通过链式法则计算得到的,其中 L 是损失函数,x 是输入,z 是输出。梯度
可以表示为:
假设 z=Wx,其中 W 是权重矩阵,那么 =W。因此,梯度
可以写为:
反向传播时梯度 的方差应与相同,因此:
其中 是输出维度(fan_out)。为了保持梯度的方差一致性,我们需要确保每个输入维度 nin 的梯度方差与输出维度 nout 的梯度方差相同。因此,我们需要将 W 的方差乘以 nout,以确保梯度的方差在反向传播过程中保持一致。
(3) 综合考虑
为了同时平衡前向传播和反向传播,Xavier 采用:
权重从以下分布中采样:
均匀分布:
在Xavier初始化中,我们选择和
,这样方差为:
正态分布:
其中 是当前层的输入神经元数量,
是输出神经元数量。
在前向传播中,输出的方差受 影响。在反向传播中,梯度的方差受
影响。
优点:平衡了输入和输出的方差,适合Sigmoid 和 Tanh 激活函数。
应用场景:常用于浅层网络或使用Sigmoid 、Tanh 激活函数的网络。
代码演示:
import torch
import torch.nn as nndef test007():# Xavier初始化:正态分布linear = nn.Linear(in_features=6, out_features=4)nn.init.xavier_normal_(linear.weight)print(linear.weight)# Xavier初始化:均匀分布linear = nn.Linear(in_features=6, out_features=4)nn.init.xavier_uniform_(linear.weight)print(linear.weight)if __name__ == "__main__":test007()
打印结果:
Parameter containing:
tensor([[-0.4838, 0.4121, -0.3171, -0.2214, -0.8666, -0.4340],[ 0.1059, 0.6740, -0.1025, -0.1006, 0.5757, -0.1117],[ 0.7467, -0.0554, -0.5593, -0.1513, -0.5867, -0.1564],[-0.1058, 0.5266, 0.0243, -0.5646, -0.4982, -0.1844]],requires_grad=True)
Parameter containing:
tensor([[-0.5263, 0.3455, 0.6449, 0.2807, -0.3698, -0.6890],[ 0.1578, -0.3161, -0.1910, -0.4318, -0.5760, 0.3746],[ 0.2017, -0.6320, -0.4060, 0.3903, 0.3103, -0.5881],[ 0.6212, 0.3077, 0.0783, -0.6187, 0.3109, -0.6060]],requires_grad=True)
4 He初始化
也叫kaiming 初始化。He 初始化的核心思想是调整权重的初始化范围,使得每一层的输出的方差保持一致。与 Xavier 初始化不同,He 初始化专门针对 ReLU 激活函数的特性进行了优化。
数学推导
(1) 前向传播的方差一致性
对于 ReLU 激活函数,输出的方差为:
(因为 ReLU 使一半神经元输出为 0,方差减半) 为使 Var(z)=Var(x),需:
(2) 反向传播的梯度一致性
类似地,反向传播时梯度方差需满足:
因此:
(3) 两种模式
-
fan_in
模式(默认):优先保证前向传播稳定,方差。
-
fan_out
模式:优先保证反向传播稳定,方差。
方法:专门为 ReLU 激活函数设计。权重从以下分布中采样:
均匀分布:
正态分布:
其中 是当前层的输入神经元数量。
优点:适用于ReLU 和 Leaky ReLU 激活函数。
应用场景:深度网络,尤其是使用 ReLU 激活函数时。
代码演示:
import torch
import torch.nn as nndef test006():# He初始化:正态分布linear = nn.Linear(in_features=6, out_features=4)nn.init.kaiming_normal_(linear.weight, nonlinearity="relu", mode='fan_in')print(linear.weight)# He初始化:均匀分布linear = nn.Linear(in_features=6, out_features=4)nn.init.kaiming_uniform_(linear.weight, nonlinearity="relu", mode='fan_out')print(linear.weight)if __name__ == "__main__":test006()
输出结果:
Parameter containing:
tensor([[ 1.4020, 0.2030, 0.3585, -0.7419, 0.6077, 0.0178],[-0.2860, -1.2135, 0.0773, -0.3750, -0.5725, 0.9756],[ 0.2938, -0.6159, -1.1721, 0.2093, 0.4212, 0.9079],[ 0.2050, 0.3866, -0.3129, -0.3009, -0.6659, -0.2261]],requires_grad=True)Parameter containing:
tensor([[-0.1924, -0.6155, -0.7438, -0.2796, -0.1671, -0.2979],[ 0.7609, 0.9836, -0.0961, 0.7139, -0.8044, -0.3827],[ 0.1416, 0.6636, 0.9539, 0.4735, -0.2384, -0.1330],[ 0.7254, -0.4056, -0.7621, -0.6139, -0.6093, -0.2577]],requires_grad=True)
5 总结
在使用Torch构建网络模型时,每个网络层的参数都有默认的初始化方法,同时还可以通过以上方法来对网络参数进行初始化。