梯度消失与梯度爆炸
在训练模型的时候,会出现梯度很多为0或者为无穷(在不同的语言里表现不同)的情况。这个时间往往发生了梯度消失或梯度爆炸。梯度消失和梯度爆炸导致模型训练失败。因此我们需要了解其中的原因和解决办法。
1、梯度消失与梯度爆炸的原因
首先看一个简单的神经网络。这个神经网络只有三层,且每层都只有一个神经元。我们可以有 $f(x)=f_3(w3*f_2(w2*f_1(w1*x)))$
我们依次的对 w3, w2, w1等进行求导:
$\frac {\partial f_3}{w_3} = \frac {\partial f_3}{w_3}$
$\frac {\partial f_3}{w_2} = \frac {\partial f_3}{\partial f_2} * w3 * \frac{\partial f_2}{w_2}$
$\frac {\partial f_3}{w_1} = \frac {\partial f_3}{\partial f_2} * w3 * \frac{\partial f_2}{\partial f_1} * w_2 * \frac{\partial f_1}{w_1}$
这里看的出,随着深度的计算参数导数的计算中乘积因子越来越多。如果激活函数的导数很小的话,就会产生梯度消失。比如 sigmoid 函数,导数最大为1/4。为了让梯度整体不小,只能提高对应的 wi。而导数与 wi 也是相关的,所以选择如 sigmoid 的激活函数很容易出现梯度消失。
$f_{sigmoid}(wx+b)=\frac {1}{1+e^{-(wx+b)}}$
$\frac{f_{sigmoid}(wx+b)}{x} = f_{sigmoid}(wx+b)*(1-f_{sigmoid}(wx+b))*w$
当初始的权重 wi 比较大的时候(一般不是sigmoid 函数)会容易出现梯度爆炸。
2、梯度消失与梯度爆炸的解决办法
首先是选用更合适的激活函数,比如 Relu。
针对序列模型可以选用 LSTM,GRU 等。
使用 Batch Normalization 方法。