深度学习——模型的初始化

模型初始化

在深度学习模型的训练中,权重的初始值极为重要。一个好的权重值,会使模型收敛速度提高,使模型准确率更精确。为了利于训练和减少收敛时间,我们需要对模型进行合理的初始化。PyTorch也在torch.nn.init中为我们提供了常用的初始化方法。 通过本次学习,你将学习到以下内容:
**·**常见的初始化函数
**·**初始化函数的使用

torch.nn.init内容

通过访问torch.nn.init的官方文档链接 ,我们发现torch.nn.init提供了以下初始化方法:
1.torch.nn.init.uniform_(tensor, a=0.0, b=1.0)
2.torch.nn.init.normal_(tensor, mean=0.0, std=1.0)
3.torch.nn.init.constant_(tensor, val)
4.torch.nn.init.ones_(tensor)
5.torch.nn.init.zeros_(tensor)
6.torch.nn.init.eye_(tensor)
7.torch.nn.init.dirac_(tensor, groups=1)
8.torch.nn.init.xavier_uniform_(tensor, gain=1.0)
9.torch.nn.init.xavier_normal_(tensor, gain=1.0)
10.torch.nn.init.kaiming_uniform_(tensor, a=0, mode=‘fan__in’, nonlinearity=‘leaky_relu’)
11.torch.nn.init.kaiming_normal_(tensor, a=0, mode=‘fan_in’, nonlinearity=‘leaky_relu’)
12.torch.nn.init.orthogonal_(tensor, gain=1)
13.torch.nn.init.sparse_(tensor, sparsity, std=0.01)
14.torch.nn.init.calculate_gain(nonlinearity, param=None)
我们可以发现这些函数除了calculate_gain,所有函数的后缀都带有下划线,意味着这些函数将会直接原地更改输入张量的值。

常见的初始化函数参数介绍及例子

1.torch.nn.init.uniform_(tensor, a=0.0,b=1.0)
参数介绍:

tensor:传入的tensor

a:均匀分布的下界,默认为0

b:均匀分布的上限,默认为1

#例子
w = torch.empty(3, 5)#返回填充有未初始化数据的张量
print(nn.init.uniform_(w))
'''输出结果为在0和1之间的3*5的tensor'''

在这里插入图片描述
2.torch.nn.init.normal_(tensor, mean=0.0, std=1.0)
参数介绍:

tensor:传入的tensor

a:正态分布的平均值,默认为0

b:正态分布的标准差,默认为1

#例子
w = torch.empty(3, 5)#返回填充有未初始化数据的张量
print(nn.init.normal_(w,mean=0.0,std=0.01))

输出结果:

tensor([[ 0.0091,  0.0007,  0.0094,  0.0044, -0.0025],
        [ 0.0072, -0.0100, -0.0076, -0.0090, -0.0010],
        [ 0.0155,  0.0131, -0.0094,  0.0115,  0.0056]])

torch.nn.init使用

我们通常会根据实际模型来使用torch.nn.init进行初始化,通常使用isinstance来进行判断模块属于什么类型。

import torch
import torch.nn as nn

conv = nn.Conv2d(1,3,3)
linear = nn.Linear(10,1)

isinstance(conv,nn.Conv2d) #输出结果为True
isinstance(linear,nn.Conv2d) #输出结果为False

对于不同的类型层,我们就可以设置不同的权值初始化的方法。

# 查看随机初始化的conv参数
print(conv.weight.data)
# 查看linear的参数
print(linear.weight.data)
#输出结果
tensor([[[[ 0.0503,  0.3219,  0.1713],
          [ 0.0245, -0.0674, -0.1320],
          [-0.3283, -0.0288,  0.0165]]],


        [[[-0.1239,  0.1486,  0.2322],
          [-0.0712,  0.2408, -0.3278],
          [ 0.0519,  0.1744, -0.0789]]],


        [[[ 0.1075,  0.3197,  0.2331],
          [ 0.3135, -0.0903,  0.1570],
          [-0.2024,  0.0870,  0.2645]]]])
tensor([[ 0.2414, -0.0159,  0.1235,  0.3005,  0.1137, -0.0574,  0.0590, -0.1375,
          0.2102,  0.1503]])
# 对conv进行kaiming初始化
torch.nn.init.kaiming_normal_(conv.weight.data)
print(conv.weight.data)
# 对linear进行常数初始化
torch.nn.init.constant_(linear.weight.data,0.3)
print(linear.weight.data)

输出结果:

#输出结果
tensor([[[[-0.4040, -0.9720, -0.5781],
          [-0.0445,  0.0511,  0.0119],
          [ 0.2158,  0.2108,  0.1139]]],


        [[[-0.3457, -0.0149,  0.1714],
          [ 1.4039,  0.8438,  0.0760],
          [ 0.4761,  0.0609,  0.0143]]],


        [[[-0.2765, -0.3612,  1.4848],
          [-0.3440, -0.0894,  0.5891],
          [ 0.4460, -0.9875, -0.5759]]]])
tensor([[0.3000, 0.3000, 0.3000, 0.3000, 0.3000, 0.3000, 0.3000, 0.3000, 0.3000,

初始化函数的封装

人们常常将各种初始化方法定义为一个initialize_weights()的函数并在模型初始后进行使用。

def initialize_weights(self):
    for m in self.modules():
        # 判断是否属于Conv2d
        if isinstance(m, nn.Conv2d):
            torch.nn.init.xavier_normal_(m.weight.data)
            # 判断是否有偏置
            if m.bias is not None:
                torch.nn.init.constant_(m.bias.data,0.3)
        elif isinstance(m, nn.Linear):
            torch.nn.init.normal_(m.weight.data, 0.1)
            if m.bias is not None:
                torch.nn.init.zeros_(m.bias.data)
        elif isinstance(m, nn.BatchNorm2d):
            m.weight.data.fill_(1) 
            m.bias.data.zeros_()

这段代码流程是遍历当前模型的每一层,如卷积层、全连接层、批量归一化层,然后判断各层属于什么类型,然后根据不同类型层,设定不同的权值初始化方法。我们可以通过下面的例程进行一个简短的演示:

# 模型的定义
class MLP(nn.Module):
  # 声明带有模型参数的层,这里声明了两个全连接层
  def __init__(self, **kwargs):
    # 调用MLP父类Block的构造函数来进行必要的初始化。这样在构造实例时还可以指定其他函数
    super(MLP, self).__init__(**kwargs)
    self.hidden = nn.Conv2d(1,1,3)
    self.act = nn.ReLU()
    self.output = nn.Linear(10,1)
    
   # 定义模型的前向计算,即如何根据输入x计算返回所需要的模型输出
  def forward(self, x):
    o = self.act(self.hidden(x))
    return self.output(o)

mlp = MLP()
print(list(mlp.parameters()))
print("-------初始化-------")

initialize_weights(mlp)
print(list(mlp.parameters()))

在这里插入图片描述

  • 8
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小白哒哒

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

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

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

打赏作者

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

抵扣说明:

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

余额充值