pytorch参数初始化方法

本文详细介绍了深度学习模型的初始化方法,包括单层和多层网络的初始化方式,如使用apply函数和在_init_函数中进行初始化。同时,文章列举了多种参数初始化策略,如均匀分布、正态分布、常数分布、单位分布、Dirac函数、Xavier和Kaiming初始化等,这些策略旨在解决梯度消失和爆炸问题,保持网络的训练效果。
摘要由CSDN通过智能技术生成

1、初始化方式

单层网络初始化方式

在创建model后直接调用torch.nn.init里的初始化函数。

conv = torch.nn.Conv2d(3, 64, kernel_size = 3, stride = 1, padding = 1)
torch.nn.init.xavier_uniform_(conv.weight)
torch.nn.init.xavier_uniform_(conv.bias, 0)

多层网络初始化方式

(1). 使用apply函数,在_init_函数中用self.modules()进行初始化

先定义初始化模型方法,运用apply()调用weight_init函数.

class Net(nn.Module):
 
    def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
        super().__init__()
 
        self.layer = nn.Sequential(
            nn.Linear(in_dim, n_hidden_1), 
            nn.ReLU(True),
            nn.Linear(n_hidden_1, n_hidden_2),
            nn.ReLU(True),
            nn.Linear(n_hidden_2, out_dim)
             )    
    def forward(self, x):
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        return x
 
 # 1. 根据网络层的不同定义不同的初始化方式     
def weight_init(m):
    if isinstance(m, nn.Linear):
        nn.init.xavier_normal_(m.weight)
        nn.init.constant_(m.bias, 0)
    # 也可以判断是否为conv2d,使用相应的初始化方式 
    elif isinstance(m, nn.Conv2d):
        nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
     # 是否为批归一化层
    elif isinstance(m, nn.BatchNorm2d):
        nn.init.constant_(m.weight, 1)
        nn.init.constant_(m.bias, 0)
 
# 2. 初始化网络结构        
model = Net(in_dim, n_hidden_1, n_hidden_2, out_dim)
 
# 3. 将weight_init应用在子模块上
model.apply(weight_init)
#torch中的apply函数通过可以不断遍历model的各个模块,并将weight_init函数应用在这些Module上

(2)定义在模型中,利用self.modules()来进行循环(推荐)

class Net(nn.Module):
 
    def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
        super().__init__()
        self.layer = nn.Sequential(
            nn.Linear(in_dim, n_hidden_1), 
            nn.ReLU(True),
            nn.Linear(n_hidden_1, n_hidden_2),
            nn.ReLU(True),
            nn.Linear(n_hidden_2, out_dim)
             )    
 
       for m in self.modules():
             if isinstance(m, nn.Conv2d):
                 nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
             elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
                 nn.init.constant_(m.weight, 1)
                 nn.init.constant_(m.bias, 0)
 
    def forward(self, x):
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        return x
 

2、几种常见的参数初始化方式

1、init.uniform均匀分布

init.uniform(tensor, a=0, b=1)
nn.init.uniform(w)

从均匀分布 U ( a , b )中生成值,填充输入的张量或变量

  • tensor - n维的torch.Tensor
  • a - 均匀分布的下界
  • b - 均匀分布的上界

2、nn.init.normal 正太分布

nn.init.normal(tensor, mean=0, std=1)
nn.init.normal(w)

从给定均值和标准差的正态分布N(mean,std)中生成值,填充输入的张量或变量

  •     tensor – n维的torch.Tensor
  •     mean – 正态分布的均值
  •     std – 正态分布的标准差

3、nn.init.constant常数分布

nn.init.constant(tensor, val)
nn.init.constant(w)

用val的值填充输入的张量或变量

  • tensor – n维的torch.Tensor 或 autograd.Variable
  • val – 用来填充张量的值

4、nn.init.eye 单位分布

nn.init.eye(tensor)
nn.init.eye(w)

用单位矩阵来填充2维输入张量或变量。在线性层尽可能多的保存输入特性

  • tensor – 2维的torch.Tensor 或 autograd.Variable

5、nn.init.dirac

nn.init.dirac(tensor)
nn.init.dirac(w)

用Dirac δ  函数来填充{3, 4, 5}维输入张量或变量。在卷积层尽可能多的保存输入通道特性

  •     tensor – {3, 4, 5}维的torch.Tensor 或 autograd.Variable
     

6、 nn.init.xavier_uniform

基本思想是维持输入和输出的方差一致,避免了所有的输出值都为0, 使用于任何激活函数,但是Xavier初始化在tanh中表现的很好, 在relu中表现很差

nn.init.xavier_uniform(tensor, gain=1)
nn.init.xavier_uniform(w, gain=math.sqrt(2.0))

用一个均匀分布生成值,填充输入的张量或变量。结果张量中的值采样自U(-a, a)

  •     tensor – n维的torch.Tensor
  •     gain - 可选的缩放因子

7、nn.init.xavier_normal

针对Xavier在relu表现不佳被提出。基本思想仍然从“输入输出方差一致性”角度出发,在Relu网络中, 假设每一层有一半的神经元被激活,另一半为0。一般在使用Relu的网络中推荐使用这种初始化方式。

nn.init.xavier_normal(tensor, gain=1)
nn.init.xavier_normal(w)

 用一个正态分布生成值,填充输入的张量或变量。结果张量中的值采样自均值为0的正态分布。

  • tensor – n维的torch.Tensor
  • gain - 可选的缩放因子

8、nn.init.kaiming_uniform

nn.init.kaiming_uniform(tensor, a=0, mode='fan_in',nonlinearity='leaky_relu')
nn.init.kaiming_uniform(w, mode='fan_in')

 用一个均匀分布生成值,填充输入的张量或变量。结果张量中的值采样自U(-bound, bound)

  • tensor ,n维的torch.Tensor或autograd.Variable
  • a -这层之后使用的rectifier的斜率系数(ReLU的默认值为0)
  • mode -可以为“fan_in”(默认)或 “fan_out”
  • “fan_in”保留前向传播时权值方差的量级
  • “fan_out”保留反向传播时的量级
  • nonlinearity=‘leaky_relu’ 非线性函数 建议“relu”或“leaky_relu”(默认值)使用。
     

 9、nn.init.kaiming_normal

nn.init.kaiming_normal(tensor, a=0, mode='fan_in')
nn.init.kaiming_normal(w, mode='fan_out')

用一个正态分布生成值,填充输入的张量或变量。结果张量中的值采样自均值为0的正态分布.

  • tensor – n维的torch.Tensor或 autograd.Variable
  • a -这层之后使用的rectifier的斜率系数(ReLU的默认值为0)
  • mode -可以为“fan_in”(默认)或 “fan_out”
  • “fan_in”保留前向传播时权值方差的量级
  • “fan_out”保留反向传播时的量级

 10、nn.init.orthogonal正交矩阵初始化

主要是解决神经网络中出现的梯度消失和梯度爆炸等问题,是RNN中常用的初始化方法

nn.init.orthogonal(tensor, gain=1)
nn.init.orthogonal(w)

用正交矩阵填充输入的张量或变量。输入张量必须至少是2维的,对于更高维度的张量,超出的维度会被展平,视作行等于第一个维度,列等于稀疏矩阵乘积的2维表示【其中非零元素生成自均值为0,标准差为std的正态分布】

  •     tensor – n维的torch.Tensor 或 autograd.Variable,其中n>=2
  •     gain -可选

11、nn.init.sparse稀疏矩阵

nn.init.sparse(tensor, sparsity, std=0.01)
# 非零元素采用正态分布 N(0, 0.01) 初始化.
nn.init.sparse(w, sparsity=0.1)

将2维的输入张量或变量当做 稀疏矩阵填充,其中非零元素根据一个均值为0,标准差为std的正态分布生成。

  •     tensor – n维的torch.Tensor或autograd.Variable
  •     sparsity - 每列中需要被设置成零的元素比例
  •     std - 用于生成非零值的正态分布的标准差
  • 16
    点赞
  • 99
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只小小的土拨鼠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值