激活函数的作用
对于一个神经网络中的神经元(节点),需要根据输入计算这个神经元的输出(节点激活值)。以下图表示的这个神经元为例,计算它的输出包括两步
- 对输入值的线性加权,z=∑i=13wixi+bz=\sum_{i=1}^{3} w_{i} x_{i}+bz=∑i=13wixi+b;
- 对加权和 zzz 进行非线性变换,y=f(z)y=f(z)y=f(z)
这里 fff 是激活函数,一般为非线性函数。那么为什么一定要用非线性函数呢?原因在于如果使用了线性激活函数,无论这个神经网络有多深,得到的输出仍旧是输入的线性组合,这样的网络对于线性不可分的问题是没有作用的。
常用的激活函数
神经网络中常用的激活函数包括:sigmoid函数,tanh函数和ReLU函数。
1. sigmoid函数
Logistic中讲到过sigmoid函数
g(z)=11+e−zg(z)=\frac{1}{1+e^{-z}}g(z)=1+e−z1它能够将 (−∞,+∞)(-\infty,+\infty)(−∞,+∞) 中的值映射到 (0,1)(0,1)(0,1),函数图像如下

sigmoid函数还有一个很优秀的特性就是它的导函数,对它求导可以发现g′(z)=g(z)(1−g(z))g'(z)=g(z)(1-g(z))g′(z)=g(z)(1−g(z))这样在用梯度下降法求梯度就很容易,推导过程很简单,就不展开了。
优点有了,但是缺点同样也很明显。从导函数的函数式和sigmoid的函数图像也可以看出来,即当 zzz 很大( g(z)≈1g(z)\approx1g(z)≈1) 或者很小( g(z)≈0g(z)\approx0g(z)≈0) 的时候 g′(z)≈0g'(z)\approx0g′(z)≈0,这样在使用梯度下降法优化权重的时候由于梯度接近0,权重更新十分缓慢,称之为梯度消失。因此一般不在神经网络的隐层中使用sigmoid函数,但是对于二分类问题,将sigmoid用在输出层作为激活函数仍旧是一个不错的选择。
2. tanh函数
另一个和sigmoid函数很像的激活函数是tanh函数,它将 (−∞,+∞)(-\infty,+\infty)(−∞,+∞) 中的值映射到 (−1,1)(-1,1)(−1,1),函数式和函数图像如下g(z)=ez−e−zez+e−z g(z)=\frac{e^{z}-e^{-z}}{e^{z}+e^{-z}}g(z)=ez+e−zez−e−z

对tanh函数求导可以得到其导函数为g′(z)=1−g2(z) g'(z)=1-g^2(z)g′(z)=1−g2(z)
可以看到在是用梯度下降法的时候也是很容易求梯度的。吴恩达老师的深度学习课程视频里说到tanh函数大多数情况下性能会比sigmoid函数的性能好,Emmm至于为什么好的原因视频里没有讲到(可能是因为引入了负值之后放大了特征???)。但是,结合函数表达式和图像,以及导函数的表达式也可以看出使用tanh函数作为激活函数的时候同样存在梯度消失的问题。
3. ReLU函数
针对sigmoid函数和tanh函数求梯度时存在的梯度下降的问题,ReLU被提出。ReLU全称为非线性修正单元(Rectified Liner Unit),目前已经是机器学习和深度学习里非常受欢迎的一个函数,其表达式和图像如下g(z)=max(0,z)g(z)=max(0,z )g(z)=max(0,z)

ReLU在 z>0z>0z>0 时,输出与输入保持线性关系,因此梯度永远存在 g‘(z)=1g‘(z)=1g‘(z)=1,在 z<0z<0z<0 时梯度为零,然后 z>0z>0z>0 与 z<0z<0z<0 部分共同组成了非线性函数。RuLU函数在 z=0z=0z=0 时倒数是没有定义的,但是实际应用中,ReLU函数的输入(即前一层网络的线性加权和)为0的概率非常非常低,因此不同担心这一点,或者可以在程序中定义 z=0z=0z=0 时的导数值为0或1) 。
4. Leaky ReLU函数
Leaky ReLU是ReLU的改进版本,表达式和图像如下g(z)={0.001z,z<0z,z≥0g(z)=\left\{\begin{array}{c}{0.001 z, z<0} \\ {z \quad, z \geq 0}\end{array}\right.g(z)={0.001z,z<0z,z≥0

可以看到,在 z<0z<0z<0函数的斜率不再为0,而是一个很小的值,这样能保证在 z<0z<0z<0 时仍旧存在梯度。但是Leaky ReLU的使用频率却没有ReLU那么高,原因在于通常情况下有足够多的来保证 z>0z>0z>0 。
总结
上面介绍了神经网路中常用的激活函数,但是事实上,在神经网络中一般默认使用ReLU函数或者Leaky ReLU函数,因为它们的梯度优势会加快神经网络的训练速度。sigmoid函数一般仅仅用在二分类网络的输出层,其他情况下sigmoid函数都可以被性能更好的tanh函数代替。吴恩达老师在视频中给的建议是,如果不知道选择激活函数,那么直接使用ReLU函数就OK了!