4.7 权重初始化方法

良好的模型权重初始化,有利于模型的训练,在torch.nn.init中提供了数十个初始化方法,本小节对它们进行介绍。

回顾上一小节中VGG的初始化代码,先总结出权重初始化的流程与步骤。

    for m in self.modules():
        if isinstance(m, nn.Conv2d):
            nn.init.kaiming_normal_(m.weight, mode="fan_out", nonlinearity="relu")
            if m.bias is not None:
                nn.init.constant_(m.bias, 0)
        elif isinstance(m, nn.BatchNorm2d):
            nn.init.constant_(m.weight, 1)
            nn.init.constant_(m.bias, 0)
        elif isinstance(m, nn.Linear):
            nn.init.normal_(m.weight, 0, 0.01)
            nn.init.constant_(m.bias, 0)

首先对每一个子module进行遍历,对不同的网络层进行设置对应的权重初始化方法,初始化方法采用的是nn.init.xxx函数。

接下来nn.init.xxx就是本节的主角,下面依次介绍nn.init.xxx函数。

主要分为三部分:

  1. Xavier 系列

  2. kaiming 系列

  3. 常数方法

Xavier 系列

  1. torch.nn.init.xavieruniform(tensor, gain=1.0)

xavier 初始化方法中服从均匀分布 U(-a,a) ,分布的参数 a = gain * sqrt(6/fan_in+fan_out),

这里有一个 gain,表示增益,其大小取决于激活函数的类型。本方法也称为 Glorot initialization。

  1. torch.nn.init.xaviernormal(tensor, gain=1.0)

xavier初始化方法中服从正态分布,

mean=0,std = gain * sqrt(2/fan_in + fan_out)

Xavier初始化方法的理论分析可见《Understanding the difficulty of training deep feedforward neural networks - Glorot, X. & Bengio, Y. (2010),》

Kaiming系列

​ 3.### torch.nn.init.kaiminguniform(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')

此为均匀分布,U~(-bound, bound), bound = sqrt(6/(1+a^2)*fan_in)

其中,a为激活函数的负半轴的斜率,relu是0

mode- 可选为fan_in 或 fan_out, fan_in使正向传播时,方差一致; fan_out使反向传播时,方差一致

nonlinearity- 可选 relu 和 leaky_relu ,默认值为 :leaky_relu

  1. torch.nn.init.kaimingnormal(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')

此为0均值的正态分布,N~ (0,std),其中std = sqrt(2/(1+a^2)*fan_in)

其中,a为激活函数的负半轴的斜率,relu是0

mode- 可选为fan_in 或 fan_out, fan_in使正向传播时,方差一致;fan_out使反向传播时,方差一致

nonlinearity- 可选 relu 和 leaky_relu ,默认值为: leaky_relu

Kaiming系列的初始化方法理论分析可参阅《Delving deep into rectifiers: Surpassing human-level performance on ImageNet classification - He, K. et al. (2015》

其它方法

  1. 均匀分布初始化

torch.nn.init.uniform_(tensor, a=0, b=1)

使值服从均匀分布U(a,b)

  1. 正态分布初始化

torch.nn.init.normal_(tensor, mean=0, std=1)

使值服从正态分布N(mean, std),默认值为0,1

  1. 常数初始化

torch.nn.init.constant_(tensor, val)

使值为常数val nn.init.constant_(w, 0.3)

  1. 单位矩阵初始化

torch.nn.init.eye_(tensor)

将二维tensor初始化为单位矩阵(the identity matrix)

  1. 正交初始化

torch.nn.init.orthogonal_(tensor, gain=1)

使得tensor是正交的,论文:Exact solutions to the nonlinear dynamics of learning in deep linear neural networks” - Saxe, A. et al. (2013)

  1. 稀疏初始化

torch.nn.init.sparse_(tensor, sparsity, std=0.01)

从正态分布N~(0. std)中进行稀疏化,使每一个column有一部分为0

sparsity- 每一个column稀疏的比例,即为0的比例

nn.init.sparse_(w, sparsity=0.1)

  1. 全零初始化

torch.nn.init.zeros_(tensor)

所有参数置零。

  1. 全1初始化

torch.nn.init.ones_(tensor)

所有参数置一。

  1. 狄拉克初始化

torch.nn.init.dirac_(tensor, groups=1)

采用狄拉克函数进行权重初始化,

  1. 增益计算

torch.nn.init.calculate_gain(nonlinearity, param=None)

返回各激活函数对应的增益值,该值用于调整权重初始化的方差。

nonlinearity gain
Linear / Identity 1
Conv{1,2,3}D 1
Sigmoid 1
Tanh 35
ReLU 2
Leaky Relu 1+negative_slope22
SELU 43

小结

本小节将torch.nn.init中包含的初始化方法进行了分类介绍,主要分为Xavier和Kaiming方法与其它常数方法,并且回顾了torchvision中如何对一个模型所有层进行权重初始化的流程,希望对大家有所帮助。

Copyright © TingsongYu 2021 all right reserved,powered by Gitbook文件修订时间: 2024年04月26日21:48:10

results matching ""

    No results matching ""