深度学习之参数初始化策略
为什么需要参数初始化策略
目的
为了让神经网络在训练过程中学习到有用的信息,需要参数更新时的梯度不为0。在一般的全连接网络中,参数更新的梯度和反向传播得到的状态梯度以及输入激活值有关。那么参数初始化应该满足以下两个条件:
1. 初始化必要条件一:各层激活值不会出现饱和现象(对于sigmoid,tanh);
2. 初始化必要条件二:各层激活值不为0。
全零初始化存在的问题
全零初始化方法在前向传播过程中会使得隐层神经元的激活值均未0,在反向过程中根据BP公式,不同维度的参数会得到相同的更新。
需要破坏这种“对称性”。
激活函数输入值的方差
从上述推导可以看出,神经元输出的方差会随着神经元数量的增大而变多。
标准初始化
标准初始化方法通过对方差乘以一个系数确保每层神经元的输出具有相同的方差,提高训练收敛速度。
标准均匀初始化方法保证了激活函数的输入值的均值为0,方差为常量 <nobr> 13 </nobr>,和网络的层数和神经元的数量无关。对于sigmoid激活函数来说,可以确保自变量处于有梯度的范围内。
但是注意对于 <nobr> sigmoid </nobr>函数,其输出是大于零的,这违反了上面推导中关于 <nobr> E(xi)=0 </nobr>的假设。综上,标准初始化方法更适用于 <nobr> tanh </nobr>激活函数。
标准正态初始化方法保证激活函数的输入均值为,方差为1。
对于含有 <nobr> nin </nobr>个输入和 <nobr> nout </nobr>个输出的全连接层,
- standard_normal
<nobr> Wi,j∼N(0,1nin√) </nobr> - standard_uniform
<nobr> Wi,j∼U(−1nin√,1nin√) </nobr>
Xavier初始化(glorot初始化)
glorot认为优秀的初始化应该使得各层的激活值和状态梯度的方差在传播过程中的方差保持一致。
glorot假设DNN使用激活值关于0对称且在0处梯度为1的激活函数(如tanh)。
记
<nobr> si=ziWi+bi </nobr>, <nobr> zi+1=f(si) </nobr>
有
<nobr> ∂Cost∂sik=∂Cost∂si+1Wi+1kf′(sik)..............(2) </nobr>
<nobr> ∂Cost∂wil,k=∂Cost∂sikzil..............(3) </nobr>
根据之前的假设
<nobr> f′(sik)≈1..............(4) </nobr>,
<nobr> Var[zi]=Var[x]∏i−1i′=0ni′Var[Wi′]..............(5) </nobr>
为了满足之前的假设,即
综合以上两个要求,
Xavier初始化要求神经元的权重的方差 <nobr> Var(w)=2nin+nout </nobr>
- xavier_normal
<nobr> Wi,j∼N(0,2nin+nout−−−−−−√) </nobr> - xavier_uniform
<nobr> Wi,j∼U(−6nin+nout−−−−−−√,6nin+nout−−−−−−√) </nobr>
该方法有一定限制,其推导过程假设激活函数在零点附近接近线性函数,且激活值关于0对称。
sigmoid函数和relu函数不满足这些假设。
在tensorflow中,
w = tf.get_variable("w",shape[100,10],initializer=tf.contrib.layers.xavier_initializer())
He初始化
- he_normal
<nobr> Wi,j∼N(0,2nin−−−√) </nobr> - he_uniform
<nobr> Wi,j∼U(−6nin−−−√,6nin−−−√) </nobr>
ReLU建议使用。