梯度消失和梯度爆炸的原因和解决方案
产生消失的梯度问题的原因
注:实际上就是梯度计算过程中,w值和**函数的导数值相乘大于1或者小于1的问题,如果是大于1,那么经历过很多个隐藏层梯度就会越来越大,即梯度爆炸,如果是小于1当然就是梯度消失啦!!!
所以w初始化大,w值和**函数的导数值相乘可能越来越大,造成梯度爆炸。
所以w初始化小,w值和**函数的导数值相乘可能越来越小,造成梯度消失。
sigmoid的导数的最大值就很小,每一层的sigmoid的输入越大,造成的最后算出的sigmoid的梯度就变得很小。
以这样的网络为例:
表示误差
表示e的经过sigmoid之后输入的结果,就是e现在的值,第3层的第1个神经元。
表示 e的没有经过sigmoid之后的输入,不是e的值。
从这里还看不出来下面的权值乘以sigmoid对于z的偏导的形式,这是因为此神经元的梯度的计算只可能会用到后面神经元的权值,这个是最后一层的权值,所以看不出来。
这里就能看出来了,计算的时候使用了
(前面一个sigmoid对后面一个神经元的a之前的z的偏导)和
(后面一个神经元对后后面一个神经元的权值!)
然而对于最后一层的神经元,因为没有后后面一个神经元,所以看不出来乘以权值的形式、。。。唉,在这里纠结了很久
https://blog.****.net/zxyhhjs2017/article/details/79139255
先看一个极简单的深度神经网络:每一层都只有一个单一的神经元。如下图:
代价函数C对偏置b1的偏导数的结果计算如下:
先看一下sigmoid 函数的图像:、
下面是导数的图像:
该导数在σ′(0) = 1/4时达到最高。现在,如果我们使用标准方法来初始化网络中的权重,那么会使用一个均值为0 标准差为1 的高斯分布。因此所有的权重通常会满足|wj|<1。从而有wjσ′(zj) < 1/4。
这其实就是消失的梯度出现的本质原因了。
可以考虑将权重初始化大一点的值,但这可能又会造成激增的梯度问题。
根本的问题其实并非是消失的梯度问题或者激增的梯度问题,而是在前面的层上的梯度是来自后面的层上项的乘积。所以神经网络非常不稳定。唯一可能的情况是以上的连续乘积刚好平衡大约等于1,但是这种几率非常小。
所以只要是sigmoid函数的神经网络都会造成梯度更新的时候极其不稳定,产生梯度消失或者激增问题。
解决梯度消失问题
使用ReLU。
使用ReLU 函数时:gradient = 0 (if x < 0), gradient = 1 (x > 0)。不会产生梯度消失问题。、
注:实际上就是梯度计算过程中,w值和**函数的导数值相乘大于1或者小于1的问题,如果是大于1,那么经历过很多个隐藏层梯度就会越来越大,即梯度爆炸,如果是小于1当然就是梯度消失啦。
转载:https://www.cnblogs.com/tsiangleo/p/6151560.html
relu和leaky reluqing请见:
https://blog.****.net/sinat_33027857/article/details/80192789
Relu 及 leakyRelu是深度学习中常用的**函数,看了几篇博客后,做一个小的总结。
1. Relu:
数学表达式:a = max(0, z)
函数图像为:
优点:由上图可以看出,Relu得到的SGD的收敛速度较快
缺点:训练的时候很容易‘die'了,对于小于0的值,这个神经元的梯度永远都会是0,在实际操错中,如果learning rate很大,很可能网络中较多的神经元都'dead'了,即使是较小的learning rate,这种情况也很有可能发生。
为了解决以上的问题,提出了leakyRelu**函数:
2. leakyRelu:
数学表达式:y = max(0, x) + leak*min(0,x) (leak是一个很小的常数,这样保留了一些负轴的值,使得负轴的信息不会全部丢失)
leakyRelu的图像:
3. 在tf中的实现:
Relu在tf中有官方的实现,可以直接调用函数 tf.nn.relu( features, name= None )
leakyRelu的简单实现可以这么写: tf.maximum(leak * x, x),
比较高效的写法为: