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

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

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

计算增益

对于线性

nonlinearitygain
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模块文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值