PyTorch 学习 -5- 模型初始化

2023-07-24 18:18:48 浏览数 (2)

在深度学习模型的训练中,权重的初始值极为重要。一个好的初始值,会使模型收敛速度提高,使模型准确率更精确, 本文介绍 Pytorch 的模型初始化 。

参考 深入浅出PyTorch ,系统补齐基础知识。

本节目录

  • 常见的初始化函数
  • 初始化函数的使用

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) 关于计算增益如下表:

nonlinearity

gain

Linear/Identity

1

Conv{1,2,3}D

1

Sigmod

1

Tanh

5/3

ReLU

sqrt(2)

Leaky Relu

sqrt(2/1 neg_slop^2)

我们可以发现这些函数除了calculate_gain,所有函数的后缀都带有下划线,意味着这些函数将会直接原地更改输入张量的值。

torch.nn.init使用

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

12345678910

import torchimport torch.nn as nnconv = nn.Conv2d(1,3,3)linear = nn.Linear(10,1)isinstance(conv,nn.Conv2d) # 判断conv是否是nn.Conv2d类型isinstance(linear,nn.Conv2d) # 判断linear是否是nn.Conv2d类型TrueFalse

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

12345678910111213141516171819202122232425262728293031

查看随机初始化的conv参数conv.weight.data# 查看linear的参数linear.weight.datatensor([[[ 0.1174, 0.1071, 0.2977, -0.2634, -0.0583, -0.2465, 0.1726, -0.0452, -0.2354]], [[ 0.1382, 0.1853, -0.1515, 0.0561, 0.2798, -0.2488, -0.1288, 0.0031, 0.2826]], [[ 0.2655, 0.2566, -0.1276, 0.1905, -0.1308, 0.2933, 0.0557, -0.1880, 0.0669]]])tensor([-0.0089, 0.1186, 0.1213, -0.2569, 0.1381, 0.3125, 0.1118, -0.0063, -0.2330, 0.1956])# 对conv进行kaiming初始化torch.nn.init.kaiming_normal_(conv.weight.data)conv.weight.data# 对linear进行常数初始化torch.nn.init.constant_(linear.weight.data,0.3)linear.weight.datatensor([[[ 0.3249, -0.0500, 0.6703, -0.3561, 0.0946, 0.4380, -0.9426, 0.9116, 0.4374]], [[ 0.6727, 0.9885, 0.1635, 0.7218, -1.2841, -0.2970, -0.9128, -0.1134, -0.3846]], [[ 0.2018, 0.4668, -0.0937, -0.2701, -0.3073, 0.6686, -0.3269, -0.0094, 0.3246]]])tensor([0.3000, 0.3000, 0.3000, 0.3000, 0.3000, 0.3000, 0.3000, 0.3000, 0.3000,0.3000])

初始化函数的封装

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

123456789101112131415

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_()

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

123456789101112131415161718192021222324252627282930313233343536373839404142

模型的定义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()))[Parameter containing:tensor([[[ 0.2103, -0.1679, 0.1757, -0.0647, -0.0136, -0.0410, 0.1371, -0.1738, -0.0850]]], requires_grad=True), Parameter containing:tensor(0.2507, requires_grad=True), Parameter containing:tensor([ 0.2790, -0.1247, 0.2762, 0.1149, -0.2121, -0.3022, -0.1859, 0.2983, -0.0757, -0.2868], requires_grad=True), Parameter containing:tensor(-0.0905, requires_grad=True)]"-------初始化-------"[Parameter containing: tensor([[[-0.3196, -0.0204, -0.5784, 0.2660, 0.2242, -0.4198, -0.0952, 0.6033, -0.8108]]], requires_grad=True), Parameter containing: tensor(0.3000, requires_grad=True), Parameter containing: tensor([ 0.7542, 0.5796, 2.2963, -0.1814, -0.9627, 1.9044, 0.4763, 1.2077, 0.8583, 1.9494], requires_grad=True), Parameter containing: tensor(0., requires_grad=True)]

参考资料

  • https://datawhalechina.github.io/thorough-pytorch/第三章/3.5 模型初始化.html

文章链接: https://cloud.tencent.com/developer/article/2304595

0 人点赞