关于网络权重初始化
1 前向,反向传播与梯度消失,梯度爆炸
神经网络的训练可以简化如下:
预处理(Scaling,…) -> 初始化网络weight与bias -> 前向传播(Forward Propagation)以获得网络输出 -> 根据输出计算损失函数获取当前损失 -> 利用链式法则进行反向传播(Back Propagation),逐层回传损失函数对当前参数梯度值,使用梯度下降更新参数 -> 重复前面步骤直至到达epoch或早停条件成立。
下面附上一张Medium上的网络前向及反向传播示意。
- 前向传播计算输出与损失函数
2. 反向传播更新参数
在反向传播中使用的梯度下降法更新参数的公 式见下:
W
(
t
+
1
)
=
W
(
t
)
−
η
d
J
d
W
W(t+1) = W(t) - \eta \frac{dJ}{dW}
W(t+1)=W(t)−ηdWdJ
式中
J
=
J
(
W
)
J=J(W)
J=J(W)即为损失函数,即通过链式法则得到的梯度对参数进行逐层更新。
反向传播:利用链式法则将梯度反向回传并逐层计算损失函数对当前层参数的梯度。反向传播中对某一个参数的梯度均为一串因子乘机,分别为:损失函数对网络输出偏导,激活函数偏导,线性组合偏导,激活函数偏导,线性组合偏导(即链式法则的展开)!此处借用一张分析(参考链接见最后),若C表示损失,z为线性组合输出(即激活层输入),a为激活层输出(即下个线性组合层输入):
可以看出,偏导的链式展开均为一串因子乘积,其中每一项均影响到结果。下面列出些许注意点:
- 全部权重偏导中都有共同项即损失函数对网络输出偏导(反向传播从最后一层往回传,一定会经过输出层);
- 每一次经过激活层就会有一个激活函数的偏导!如
σ
′
(
z
L
)
=
∂
a
L
∂
z
L
\sigma^{'}(z^L) = \frac{\partial{a^L}}{\partial{z^L}}
σ′(zL)=∂zL∂aL;
- 线性组合层的权重偏导只含有当前层输入作为因子项,如
a
L
−
1
a^{L-1}
aL−1;
- 每次经过一个线性组合层就有一个权重矩阵作为因子项,如
W
L
W^L
WL.
因此,它们中的任意一者若为0或接近于0,就会导致整个链为0,从而影响到最终的更新,我们称其为梯度消失。反正,若其中因子过大甚至为NaN,也会导致损失震荡发散,我们称其为梯度爆炸。
观察链式法则即可发现,梯度消失与梯度爆炸可能发生在训练的开始与途中!
2 激活函数对学习的影响
我们可以对比多种激活函数图像,见下图(原图链接在最后):
- 首先观察梯度消失倾向
- 可以看出来, S i g m o i d Sigmoid Sigmoid与 t a n h tanh tanh在远离原点正负向导数都几乎为0,此处我们称为其饱和区;一旦进入饱和区,由反向传播公式可以发现就很容易进入梯度消失导致无法学习更新!
- 其次, S i g m o i d Sigmoid Sigmoid的导数最大值出现在 x = 0 x=0 x=0处,然而此处的最大导数也仅为0.25!也就是说 S i g m o i d Sigmoid Sigmoid有很大的梯度消失倾向。
- 其次观察梯度爆炸倾向,可以看见 R e L u ReLu ReLu系在正方向导数均为1,有部分的梯度爆炸倾向。
根据情况修改非线性激活函数是很好的选择。
3 权重矩阵对学习的影响
我们先假设激活函数也为线性函数(如正区间
R
e
L
u
ReLu
ReLu),则能简化一个全神经网络如下:
假设权重矩阵均相同为 W W W,则前向与反向传播均涉及其与转置1的相乘,t层则相当于 W t W^t Wt,在这个基础上若对其进行特征值分解: W t = V ⋅ d i a g ( λ ) t ⋅ V − 1 W^t=V\cdot{diag(\lambda)^t}\cdot{V^{-1}} Wt=V⋅diag(λ)t⋅V−1,其中的 d i a g ( λ ) diag(\lambda) diag(λ)为特征值对角阵,可以发现,若特征值不在1附近时则会在t次后产生:1).大于1,产生梯度爆炸;2).小于1,产生梯度消失。
- 因此,网络初始化时的权重矩阵不应过小或过大以避免训练的初期产生梯度消失或爆炸!
4 不良初始化诱因
由前面内容,可以发现,不良初始化与初始权重矩阵关系。
- 权重矩阵过小:梯度消失;
- 权重矩阵过大:梯度爆炸;
- 权重矩阵全常数初始(所有权重W置同):考虑到前向传播公式 Z t + 1 = W t ⋅ x Z^{t+1} = W^t\cdot x Zt+1=Wt⋅x,会导致每层不同神经元的输入和输出相同,因此每层的反向传播更新仍旧相同,使得每层仅等价于一个神经元!!!
- 全零初始化
- :对于满足
σ
(
0
)
=
0
\sigma(0)=0
σ(0)=0的激活函数(如
R
e
L
u
ReLu
ReLu),会产生:初始态所有输入,输出都为0,反向传播梯度为0 ==> 权重一直为0不会更新!
- 对于不满足 σ ( 0 ) = 0 \sigma(0)=0 σ(0)=0的激活函数,会产生:初始激活曾的输入为0但输出不为0,反向传播导致每层权重的更新方向全相同!
- :对于满足
σ
(
0
)
=
0
\sigma(0)=0
σ(0)=0的激活函数(如
R
e
L
u
ReLu
ReLu),会产生:初始态所有输入,输出都为0,反向传播梯度为0 ==> 权重一直为0不会更新!
问题:如何进行良好的初始化?对于不同的激活函数,选择不同的初始化!
5 权重初始化的选择
初始化的重要点:
- 对权重W缺乏先验基础,所以应初始化在0附近,但需要有一定随机性,即 E ( W ) = 0 E(W)=0 E(W)=0;
- 为避免梯度消失和爆炸,权重不能过大过小,即方差 V a r ( W ) Var(W) Var(W)应在一定范围;
- 网络中的每一层输入都是上一层输出,为了保证学习,应使不同激活层输出的方差相同,即 V a r ( z i ) = V a r ( z i − 1 ) Var(z^i) = Var(z^{i-1}) Var(zi)=Var(zi−1),也就是,不同激活层的输入方差也应相同! – 所以批正规化BN比dropout啥的都管用
- 考虑到反向传播的连乘,为了防止梯度爆炸或消失,权重的数值范围(方差)需要考虑到前后双向!
权重初始化问题 -> 概率分布的参数设计问题!
因此,对于不同的激活函数,对应的初始化方法也被提出。
- tanh下的初始化:Lecun与Xavier;
- ReLu下的初始化:He Kaiming;
文章中主要观点及图出处如下:
网络初始化:From Medium
关于初始化:DeepGrid