2021年1月7日 / 133次阅读 / Last Modified 2021年1月7日
神经网络
深度神经网络DNN在训练的时候,会存在两个潜在的与不稳定的梯度有关的问题:(1)梯度消失(vanishing gradient);(2)梯度爆炸(exploding gradient)。
梯度消失,会导致DNN中,前面的层(从左到右)学习缓慢,甚至停止学习。梯度爆炸,会让学习完全无效,会让网络中对应的weights和bias更新到一个荒谬的值,可能还不如不要更新。
我们先从数学上来研究一下为什么会出现这样的情况:
上图是一个简化后的示例。
假设这个神经网络,从输入到输出,每一层都只有一个神经元,那么对于b1的偏导数公式,就是如图中所示。经过层层后向传导计算,在传导过程中,要不断地乘以连接权重w,不断地乘以神经元激活函数针对z(weighted input,wa+b)的导数。
上式是极度简化后的,只是为了说明问题。正常的网络,计算b1的偏导数,是整个后向传播所有连接计算的求和。(为什么是求和?因为最后计算cost,就是计算vector的长度平方)
貌似现在这个问题在MLP网络中更容易出现。
初始化神经网络的weights和bias时,一般都是np.random.randn,即N(0,1),就是所有的w和b在一起,符合mean=0,var=1的normal distribution。大部分的w和b在-1到1之间。
如果激活函数使用经典的sigmoid,这个函数有个特点,它的导数最大值才0.25:
这样,一层层往后计算的过程中,得到的值就越来越小,这就是梯度消失的原因!
使用其它激活函数可以改善梯度消失的问题,但不能更本解决,如何w和b依然悬而未决。
梯度不能太大,正如Learning Rate也不能太大一样,可能出现overshooting或者梯度爆炸。
我们还是要回到上文的那个数学公式上来分析。很明显,如果w和b的初始值就很大,就直接梯度爆炸了。
以上分析可以看出,不管是更换激活函数,或者在N(0,1)范围内初始化w和b,都不能根本上解决问题。下面只是记录一下现在业界的方案,还未深入研究:
-- EOF --
本文链接:https://www.pynote.net/archives/3094
前一篇:为什么Learning Rate不能很大?
后一篇:神经元激活函数
©Copyright 麦新杰 Since 2019 Python笔记