神经网络中的权重初始化方式和pytorch应用

文章目录

    • 计算增益
    • 常数初始化
    • 均匀分布初始化
    • 正态分布初始化
    • Xavier初始化
      • 均匀分布(glorot初始化)
      • 正态分布
    • Kaiming初始化
      • 均匀分布
      • 正态分布
    • 具体应用
    • 一些问答或tips

深度学习模型中的权重初始化对模型的训练效果有很大的影响,对预训练模型的研究就是为了在大模型上先训练出较好的权重,然后再放到不同的小任务上微调。

对于不加载预训练的模型,仍然可以通过定义模型权重初始化的方式来使得模型获得较好的效果,以下介绍不同的权重初始化方法、适用场景及效果。

计算增益

对于线性

nonlinearity gain
Linear / Identity 1 1 1
Conv{1,2,3}D 1 1 1
Sigmoid 1 1 1
Tanh 5 3 \frac{5}{3} 35
ReLU 2 \sqrt{2} 2
Leaky Relu 2 1 + negative_slope 2 \sqrt{\frac{2}{1 + \text{negative\_slope}^2}} 1+negative_slope22
SELU 3 4 \frac{3}{4} 43

常数初始化

torch.nn.init.constant_(tensor, val)
按照常数val初始化tensor。

特别的,val为0和1分别有torch.nn.init.zeros_(tensor)torch.nn.init.ones_(tensor)

均匀分布初始化

torch.nn.init.uniform_(tensor, a=0.0, b=1.0)
按照 U ( a , b ) U(a,b) U(a,b)的均匀分布初始化tensor。

正态分布初始化

torch.nn.init.normal_(tensor, mean=0.0, std=1.0)
按照 N ( m e a n , s t d 2 ) N(mean,std^2) N(mean,std2)的均匀分布初始化tensor。

Xavier初始化

均匀分布(glorot初始化)

torch.nn.init.xavier_uniform_(tensor, gain=1.0)
按照 U ( − a , a ) U(-a,a) U(a,a)的均匀分布初始化tensor,其中
a = g a i n × 6 f a n _ i n + f a n _ o u t a = gain \times \sqrt{\frac{6}{fan\_in + fan\_out}} a=gain×fan_in+fan_out6

正态分布

torch.nn.init.xavier_normal_(tensor, gain=1.0)

按照 N ( 0 , s t d 2 ) N(0,std^2) N(0,std2)的均匀分布初始化tensor,其中
s t d = g a i n × 2 f a n _ i n + f a n _ o u t std = gain \times \sqrt{\frac{2}{fan\_in + fan\_out}} std=gain×fan_in+fan_out2

Kaiming初始化

均匀分布

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

按照 U ( − a , a ) U(-a,a) U(a,a)的均匀分布初始化tensor,其中
a = g a i n × 3 f a n _ m o d e a = gain \times \sqrt{\frac{3}{fan\_mode}} a=gain×fan_mode3

正态分布

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

按照 N ( 0 , s t d 2 ) N(0,std^2) N(0,std2)的均匀分布初始化tensor,其中
s t d = g a i n f a n _ m o d e std = \sqrt{\frac{gain}{fan\_mode}} std=fan_modegain

具体应用

在pytorch中的torch.nn.init模块中有多种初始化的方法,可以显式地定义,以下是一个例子:

 def init_weights(self):
     for m in self.modules():
         if isinstance(m, GCNConv):
             m.weight.data = init.xavier_uniform(
                 m.weight.data, gain=torch.nn.init.calculate_gain("relu")
             )
             if m.bias is not None:
                 m.bias.data = init.constant(m.bias.data, 0.0)

这个函数是模型类的成员函数,它表示的是检索这个类中的所有模块,如果有GCNConv类的话,就将对应的weights用xavier均匀分布的方法初始化,如果有bias的话用常数来初始化bias,在对象初始化的时候调用self.init_weights();就可以了。

一些问答或tips

1. How to use torch.nn.init.calculate_gain?
2. How to Initialize Weights in PyTorch
3. Weight Initialization Techniques in Neural Networks
4. 网络权重初始化方法总结(上):梯度消失、梯度爆炸与不良的初始化
5. 网络权重初始化方法总结(下):Lecun、Xavier与He Kaiming
6.pytorch-nn.init模块文档

你可能感兴趣的:(深度学习实践,python,pytorch,深度学习,神经网络,人工智能)