本文主要详解两种神经网络初始化的方法及如何使用Pytorch实现网络初始化
Xavier 初始化
对于神经网络中的layer ilayer \ ilayer i,假设它的输入是ziz^izi,si=ziWi+bis^i=z^iW^i+b^isi=ziWi+bi,激活函数为fff,满足f′(0)=1f'(0)=1f′(0)=1,经过激活函数后的输出为zi+1=f(si)z^{i+1}=f(s^i)zi+1=f(si)
假设在初始化之后,处于激活函数的线性区域,即zi+1=siz^{i+1} = s^izi+1=si,即zi+1=ziWi+biz^{i+1}=z^iW^i+b^izi+1=ziWi+bi
因为Var[XY]=E[X2]E[Y2]−E2[X]E2[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,那么Var[XY]=Var[X]Var[Y]Var[XY]=Var[X]Var[Y]Var[XY]=Var[X]Var[Y]
在W,Z,bW,Z,bW,Z,b独立同分布,且E[w]E[w]E[w]和E[z]E[z]E[z]为0的假设下,
所以Var[zki+1]=Var[ziWki+bki]=Var[ziWki]=Var[Σj=0nizjiwjk]=niVar[zji]Var[wjk]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]
zki+1z_{k}^{i+1}zki+1这里是layer ilayer \ ilayer i的第k个node的输出,zjiz_j^izji为layer i−1layer \ i-1layer i−1的第j个node的输出,wjkw_j^kwjk为layer i−1layer \ i-1layer i−1与layer ilayer\ ilayer i第k个node的连接权重
我们希望的是在前向传播的时候满足Var[zki+1]=Var[zji]Var[z^{i+1}_k]=Var[z^i_j]Var[zki+1]=Var[zji],即对于每一个结点,它的输出的方差都相同,所以需要满足niVar[wjk]=1n_iVar[w_j^k]=1niVar[wjk]=1,所以wjkw_j^kwjk可以从方差为1ni\frac{1}{n_i}ni1的正态分布从采样得到
当我们用梯度反向传播的时候,∂L∂zi=∂L∂zi+1(Wi)T\frac{\partial L}{\partial z_i} = \frac{\partial L}{\partial z_{i+1}}(W^i)^T∂zi∂L=∂zi+1∂L(Wi)T,和前向传播时一样希望结点输出的方差都相同,只是这时候wjkw_j^kwjk需要从方差为1ni+1\frac{1}{n_{i+1}}ni+11的正态分布中采样得到
所以按照上述思路,我们无法保证前后传播的方差都相同,所以选择wjkw_j^kwjk从方差为2ni+ni+1\frac{2}{n_i+n_{i+1}}ni+ni+12的正态分布中采样得到,或者从[−6ni+ni+1,6ni+ni+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)212\frac{(a-b)^2}{12}12(a−b)2,边界可以按此公式推导得到)
kaiming初始化
对于神经网络中的layer ilayer \ ilayer i,假设它的输入是ziz^izi,si=ziWi+bis^i=z^iW^i+b^isi=ziWi+bi,激活函数为fff,zi=f(si−1)z^i = f(s^{i-1})zi=f(si−1)
假设bi=0b^i=0bi=0,激活函数为ReLU,
和之前一样,Var[ski]=Var[ziWki+bki]=Var[ziWki]=niVar[zjiwjk]=niVar[wjk]E[(zji)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[zji]E[z_j^i]E[zji]不为0,所以和上面的Xavier不同,假设sji−1s_j^{i-1}sji−1的分布均值为0,并且在0左右呈现一个对称的分布,因为负的部分被ReLU截掉了,所以E[(zji)2]=12Var[sji−1]E[(z_j^i)^2]=\frac{1}{2}Var[s_j^{i-1}]E[(zji)2]=21Var[sji−1]
可得Var[ski]=12niVar[wjk]Var[sji−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],为了使Var[ski]=Var[sji−1]Var[s^{i}_k]=Var[s^{i-1}_j]Var[ski]=Var[sji−1],wjkw_j^kwjk可以从方差为2ni\frac{2}{n_i}ni2的正态分布中采样得到
同理,考虑梯度反向传播的时候,wjkw_j^kwjk需要从方差为2ni+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.youkuaiyun.com/shuzfan/article/details/51338178