深度神经网络之激活函数

引言

神经网络中常见的非线性激活函数有三种,分别是sigmoid,tanh和relu函数,接下来从以下三点分别介绍三种激活函数。

  • 运算速度
  • 是否会梯度消失
  • 神经网络隐层的输出是否为zero-centered

首先先说明一下第三点中提到的zero-centered(以0为中心)大概是个什么意思。

zero-centered

zero-centered 这个字面意思是以0为中心,简单理解就是说神经网络每一层输出的数据都是有正有负,不是全为正或者全为负的。如果输出不符合这种规律的话,会导致网络的收敛速度变慢。那么为什么会变慢呢?
由于神经网络中的计算和更新方法是这样的:给定一个输入x,依次前向计算每一个隐层的输出,计算公式如下:
深度神经网络之激活函数_第1张图片
直到最后一层输出层,得到最终的y的结果,然后y和真实的标签比较,计算误差E,然后计算E对待更新的参数的偏导,最后根据反向传播算法中的梯度更新规则来更新每一个参数。
E对于参数的偏导和梯度更新规则分别如下:
深度神经网络之激活函数_第2张图片
激活函数是g函数,(式4)中等式右边第一项是(y - label),第二项就是激活函数求导,等式第三项就是x。
先来看第一种情况,网络的每一层输出恒为正值,即x恒为正值。如果激活函数求导恒为正值,(y - label)的值不定,那式4的偏导数将取决于(y - label),反向传播回去的梯度是恒为正或者恒为负。
再来看第二种情况,网络中的每一层输出恒为负,即x恒为负值。如果激活函数求导恒为正值,(y-label)值不定,那式4的偏导数将取决于(y - label),反向传播回去的梯度是恒为正或者恒为负。
如果网络的一批参数w=(w1,w2),网络的优化目标是要让w1一直增大,w2一直减小,然而反向传播回去的梯度恒为正或者恒为负,网络的收敛路线可能是锯齿状,这样网络的收敛速度会下降,很难达到收敛状态。
所以,网络中的每层输出的值符合zero-centered会有利于神经网络的训练和收敛。
有一种解决办法就是在每一层的输出上进行batch normalization操作,保证每一层的输出都是zero-centered。
接下来分别讨论三种激活函数。

sigmoid function

在这里插入图片描述
sigmoid函数形状是s形。这是深度学习领域开始时使用频率最高的激活函数,他将输出值压缩到0-1之间,函数曲线平滑便于求导。
它的曲线和它的导数曲线如下:
深度神经网络之激活函数_第3张图片
但是sigmoid函数有三大缺点:

  • 容易出现梯度消失
    从它的导数曲线可以看出,当x大于5或者小于-5的时候,它的梯度几乎为0;再加上它的导数最大值是0.25,也就是说没往回传一次梯度,梯度就要被压缩至少!!!至少四分之一,多往回传几层梯度,梯度一直被压缩,也很容易出现梯度为0的情况。传回来的梯度为0,根据参数更新规则(式5),参数基本不会有所更新,网络基本不会优化。
  • 网络中的输出的值不是zero-centered
    根据左边的函数曲线可以看出,它的输出恒为正值,也就是x恒为正值,而且它的导数曲线也恒为正值,所以说反向传播训练时,它的梯度符号一直不变,这样所有参数更新的时候会一直朝着正方向或者负方向更新,会走很多弯路,模型收敛的速度减慢。
  • 前向传播的时候幂运算比较耗时

tanh function

在这里插入图片描述
深度神经网络之激活函数_第4张图片
这个函数曲线同样也是s形,也是全区间可导的,把输出限制在[-1,1]。

  • 会出现梯度消失
    从右边的导数曲线可以看出,当x大于5或者小于-5的时候,梯度为0;而且它的导数数值在[0,1],这样每次回传梯度的时候,也会对上游的梯度进行压缩,极有可能出现梯度为0的情况。
  • 输出是zero-centered
    由于它的曲线输出范围是在[-1,1], 有正有负,尽管它的导数数值恒为正,最后的梯度数值有正有负,模型收敛的速度会快。
  • 幂运算耗时

relu function

这个函数是取最大值函数,尽管不是全区间可导的,但是可以取次梯度来计算。
在这里插入图片描述
深度神经网络之激活函数_第5张图片

  • 解决了梯度消失的问题(在正区间)
    在正区间,它的梯度保持在1上,所以梯度不管回传多少个隐层,都不会被压缩,所以不会出现梯度消失的问题。
  • 网络上每层输出不是zero-centered
    由于它的输出或者大于0或者等于0,所以梯度或者等于0或者是保持一致的符号,所以参数更新的路径也会呈现锯齿状,模型收敛的速度也会减慢。尽管如此他的收敛速度还是远远快于sigmoid和tanh。
  • 计算速度非常快,只需要判断输入是否大于0
    除此之外,relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。
    他还存在一个问题就是Dead ReLU Problem,这指的是某些神经元可能永远不会被激活,导致相应的参数永远不能被更新。有两个主要原因可能导致这种情况产生: (1) 非常不幸的参数初始化,这种情况比较少见 (2) 学习速率太高导致在训练过程中参数更新太大,不幸使网络进入这种状态。解决方法是可以采用Xavier初始化方法,以及避免将学习速率设置太大或使用adagrad等自动调节学习速率的算法。
    Relu目前是最常用的激活函数。

你可能感兴趣的:(神经网络,激活函数)