本文主要详解两种神经网络初始化的方法及如何使用Pytorch实现网络初始化
Xavier 初始化
对于神经网络中的 l a y e r i layer \ i layer i,假设它的输入是 z i z^i zi, s i = z i W i + b i s^i=z^iW^i+b^i si=ziWi+bi,激活函数为 f f f,满足 f ′ ( 0 ) = 1 f'(0)=1 f′(0)=1,经过激活函数后的输出为 z i + 1 = f ( s i ) z^{i+1}=f(s^i) zi+1=f(si)
假设在初始化之后,处于激活函数的线性区域,即 z i + 1 = s i z^{i+1} = s^i zi+1=si,即 z i + 1 = z i W i + b i z^{i+1}=z^iW^i+b^i zi+1=ziWi+bi
因为 V a r [ X Y ] = E [ X 2 ] E [ Y 2 ] − E 2 [ X ] E 2 [ Y ] Var[XY]=E[X^2]E[Y^2]-E^2[X]E^2[Y] Var[XY]=E[X2]E[Y2]−E2[X]E2[Y],若 E [ X ] E[X] E[X]和 E [ Y ] E[Y] E[Y]都是0,那么 V a r [ X Y ] = V a r [ X ] V a r [ Y ] Var[XY]=Var[X]Var[Y] Var[XY]=Var[X]Var[Y]
在 W , Z , b W,Z,b W,Z,b独立同分布,且 E [ w ] E[w] E[w]和 E [ z ] E[z] E[z]为0的假设下,
所以 V a r [ z k i + 1 ] = V a r [ z i W k i + b k i ] = V a r [ z i W k i ] = V a r [ Σ j = 0 n i z j i w j k ] = n i V a r [ z j i ] V a r [ w j k ] Var[z^{i+1}_k] = Var[z^iW^i_k + b^i_k] = Var[z^iW^i_k]=Var[\Sigma^{n_i}_{j=0}z_j^iw_j^k]=n_iVar[z^i_j]Var[w_j^k] Var[zki+1]=Var[ziWki+bki]=Var[ziWki]=Var[Σj=0nizjiwjk]=niVar[zji]Var[wjk]
z k i + 1 z_{k}^{i+1} zki+1这里是 l a y e r i layer \ i layer i的第k个node的输出, z j i z_j^i zji为 l a y e r i − 1 layer \ i-1 layer i−1的第j个node的输出, w j k w_j^k wjk为 l a y e r i − 1 layer \ i-1 layer i−1与 l a y e r i layer\ i layer i第k个node的连接权重
我们希望的是在前向传播的时候满足 V a r [ z k i + 1 ] = V a r [ z j i ] Var[z^{i+1}_k]=Var[z^i_j] Var[zki+1]=Var[zji],即对于每一个结点,它的输出的方差都相同,所以需要满足 n i V a r [ w j k ] = 1 n_iVar[w_j^k]=1 niVar[wjk]=1,所以 w j k w_j^k wjk可以从方差为 1 n i \frac{1}{n_i} ni1的正态分布从采样得到
当我们用梯度反向传播的时候, ∂ L ∂ z i = ∂ L ∂ z i + 1 ( W i ) T \frac{\partial L}{\partial z_i} = \frac{\partial L}{\partial z_{i+1}}(W^i)^T ∂zi∂L=∂zi+1∂L(Wi)T,和前向传播时一样希望结点输出的方差都相同,只是这时候 w j k w_j^k wjk需要从方差为 1 n i + 1 \frac{1}{n_{i+1}} ni+11的正态分布中采样得到
所以按照上述思路,我们无法保证前后传播的方差都相同,所以选择 w j k w_j^k wjk从方差为 2 n i + n i + 1 \frac{2}{n_i+n_{i+1}} ni+ni+12的正态分布中采样得到,或者从 [ − 6 n i + n i + 1 , 6 n i + n i + 1 ] [-\frac{\sqrt{6}}{\sqrt{n_i+n_{i+1}}}, \frac{\sqrt{6}}{\sqrt{n_i+n_{i+1}}}] [−ni+ni+16,ni+ni+16]的均匀分布中得到(均匀分布的方差为 ( a − b ) 2 12 \frac{(a-b)^2}{12} 12(a−b)2,边界可以按此公式推导得到)
kaiming初始化
对于神经网络中的 l a y e r i layer \ i layer i,假设它的输入是 z i z^i zi, s i = z i W i + b i s^i=z^iW^i+b^i si=ziWi+bi,激活函数为 f f f, z i = f ( s i − 1 ) z^i = f(s^{i-1}) zi=f(si−1)
假设 b i = 0 b^i=0 bi=0,激活函数为ReLU,
和之前一样, V a r [ s k i ] = V a r [ z i W k i + b k i ] = V a r [ z i W k i ] = n i V a r [ z j i w j k ] = n i V a r [ w j k ] E [ ( z j i ) 2 ] Var[s^{i}_k] = Var[z^iW^i_k + b_k^i] = Var[z^iW^i_k]=n_iVar[z_j^iw_j^k]=n_iVar[w^k_j]E[(z_j^i)^2] Var[ski]=Var[ziWki+bki]=Var[ziWki]=niVar[zjiwjk]=niVar[wjk]E[(zji)2]
因为激活函数为ReLU,所以 E [ z j i ] E[z_j^i] E[zji]不为0,所以和上面的Xavier不同,假设 s j i − 1 s_j^{i-1} sji−1的分布均值为0,并且在0左右呈现一个对称的分布,因为负的部分被ReLU截掉了,所以 E [ ( z j i ) 2 ] = 1 2 V a r [ s j i − 1 ] E[(z_j^i)^2]=\frac{1}{2}Var[s_j^{i-1}] E[(zji)2]=21Var[sji−1]
可得 V a r [ s k i ] = 1 2 n i V a r [ w j k ] V a r [ s j i − 1 ] Var[s^{i}_k]=\frac{1}{2}n_iVar[w^k_j]Var[s_j^{i-1}] Var[ski]=21niVar[wjk]Var[sji−1],为了使 V a r [ s k i ] = V a r [ s j i − 1 ] Var[s^{i}_k]=Var[s^{i-1}_j] Var[ski]=Var[sji−1], w j k w_j^k wjk可以从方差为 2 n i \frac{2}{n_i} ni2的正态分布中采样得到
同理,考虑梯度反向传播的时候, w j k w_j^k wjk需要从方差为 2 n i + 1 \frac{2}{n_{i+1}} ni+12的正态分布中采样得到
论文中说不管按照正向传递考虑初始化还是反向传递考虑初始化都可以
Pytorch实现
import torch.nn as nn
# Xavier
l1 = nn.Linear(20, 32)
nn.init.xavier_uniform_(l1.weight)
# kaiming
l2 = nn.Linear(32, 64)
nn.init.kaiming_normal_(l2.weight, mode='fan_in', nonlinearity='relu')
参考资料:
https://zhuanlan.zhihu.com/p/64464584
https://blog.csdn.net/shuzfan/article/details/51338178