激活函数——Sigmoid、tanh、ReLU、Leaky ReLU、ELU
1、神经网络为什么引入激活函数?
如果不引入激活函数,神经网络的每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合,与没有隐藏层的效果相当,这种情况就是最原始的感知机(Perceptron)。
因此,引入非线性函数作为激励函数,这样深层神经网络就有意义了(不再是输入的线性组合,可以逼近任意函数)。激活函数的作用就是为了增加神经网络模型的非线性。
2、Sigmoid函数
缺点:
*容易出现gradient vanishing
*函数输出并不是zero-centered
*幂运算相对来讲比较耗时
解释:
Gradient Vanishing
优化神经网络的方法是Back Propagation,即导数的后向传递:先计算输出层对应的loss,然后将loss以导数的形式不断向上一层网络传递,修正相应的参数,达到降低loss的目的。Sigmoid函数在深度网络中常常会导致导数逐渐变为0,使得参数无法被更新,神经网络无法被优化。原因在于两点:(1) 在上图中容易看出,当中较大或较小时,导数接近0,而后向传递的数学依据是微积分求导的链式法则,当前层的导数需要之前各层导数的乘积,几个小数的相乘,结果会很接近0 (2) Sigmoid导数的最大值是0.25,这意味着导数在每一层至少会被压缩为原来的1/4,通过两层后被变为1/16,…,通过10层后为1/1048576。请注意这里是“至少”,导数达到最大值这种情况还是很少见的。
输出不是zero-centered
Sigmoid函数的输出值恒大于0,这会导致模型训练的收敛速度变慢。举例来讲,如果所有均为正数或负数,那么其导数总是正数或负数,这会导致如下图红色箭头所示的阶梯式更新,这显然并非一个好的优化路径。深度学习往往需要大量时间来处理大量数据,模型的收敛速度是尤为重要的。所以,训练深度学习网络尽量使用zero-centered数据 (可以经过数据预处理实现) 和zero-centered输出。
3、tanh函数
解决了zero-centered的输出问题,然而,gradient vanishing的问题和幂运算的问题仍然存在。
4、ReLU函数
修正线性单元 Rectified linear unit,起源于神经科学的研究:2001年,Dayan、Abott从生物学角度模拟出了脑神经元接受信号更精确的激活模型。
- 解决了gradient vanishing问题 (在正区间)
- 计算速度非常快,只需要判断输入是否大于0
- 收敛速度远快于sigmoid和tanh
- 比 Sigmoid 更符合生物学神经激活机制,造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。
缺点:
- ReLU的输出不是zero-centered
- Dead ReLU Problem,指的是某些神经元可能永远不会被激活,导致相应的参数永远不能被更新。主要有两个原因: (1) 非常不幸的参数初始化,这种情况比较少见 (2) learning rate太高导致在训练过程中参数更新太大,不幸使网络进入这种状态。解决方法是可以采用Xavier初始化方法,以及避免将learning rate设置太大或使用adagrad等自动调节learning rate的算法。
5、Leaky ReLU函数
为解决Dead ReLU Problem,提出将ReLU的前半段设为非0。
6、ELU函数
- 不会有Deal ReLU问题
- 输出的均值接近0,zero-centered
- 计算量稍大
然而,Leaky ReLU和ELU,理论上虽然好于ReLU,但在实际使用中目前并没有证明总是优于ReLU。
总结:小型神经网络和二分类型的神经网络中使用Sigmoid比较多,如果神经网络层数很深,使用sigmoid则容易出现梯度消失的情况。
在这种情况下,建议使用ReLU函数,但是要注意初始化和learning rate的设置;可以尝试使用Leaky ReLU或ELU函数;不建议使用tanh,尤其是Sigmoid函数。
https://www.cnblogs.com/shixisheng/p/9562336.html
https://www.jianshu.com/p/338afb1389c9