
3.2 神经激活函数
取决于不同的架构和问题,人工神经网络中存在几种不同的神经激活函数。本节将讨论最常用的激活函数,因为这些函数决定了网络的架构和性能。线性激活函数和Sigmoid激活函数曾经在人工神经网络中使用较多,直到Hinton等人发明了修正线性单元(Rectified Linear Unit,ReLU),ReLU使人工神经网络的性能产生了翻天覆地的变化。
3.2.1 线性激活函数
线性激活函数神经元输出的是总输入对神经元的衰减,如图3-4所示。

图3-4 线性激活函数神经元
如果x是线性激活函数神经元的总输入,那么输出y如下所示。

3.2.2 Sigmoid激活函数
Sigmoid激活函数简称Sigmoid函数,也被称为S型函数。它可以将整个实数区间映射到(0,1)区间,因此经常被用来计算概率。它也是传统人工神经网络中经常被使用的一种激活函数。
Sigmoid函数的公式定义为

Sigmoid函数曲线如图3-5所示,其中,x的范围可以是正无穷到负无穷,但是对应y的范围为0~1,所以经过Sigmoid函数输出的值都会落在0~1的区间里,即Sigmoid函数能够把输入的值“压缩”到0~1。

图3-5 Sigmoid函数曲线
对于自然界中的各种复杂过程,输入与输出的关系通常是非线性的,因此,我们需要使用非线性激活函数通过神经网络来对它们建模。一个二元分类问题的神经网络,它的输出概率由Sigmoid神经元的输出给出,因为它的输出范围是0~1。输出概率可表示为

此处,x表示输出层中的Sigmoid神经元的总输入。
【例3-1】 利用Python绘制Sigmoid激活函数。

运行程序,效果如图3-6所示。

图3-6 Python绘制的Sigmoid激活函数
3.2.3 双曲正切激活函数
双曲正切激活函数(Hyperbolic Tangent Activation Function)又被称为tanh函数。它将整个实数区间映射到(-1,1),tanh函数也具有软饱和性。它的输出以0为中心,tanh函数的收敛速度比Sigmoid函数快。由于存在软饱和性,所以tanh函数也存在梯度消失的问题。
tanh函数的公式定义为

如图3-7所示,tanh函数输出值的范围是[-1,1]。

图3-7 tanh函数
值得注意的是,Sigmoid函数和tanh函数在一个小范围内是线性的,在此范围之外则输出趋于饱和。在饱和区间,激活函数(相对输入)的梯度非常小或趋于零,这意味着它们很容易产生梯度消失问题。之后可以看到,人工神经网络可以从反向传播方法学习,其中每一层的梯度由下一层激活函数的梯度决定,直到最终的输出层。因此,如果单元中的激活函数处于饱和区间,那么极少数的误差会被反向传播至之前的神经网络层。通过利用梯度,神经网络最小化预测误差来学习权重和偏置(W)。这意味着,如果梯度太小或趋于零,那么神经网络将无法有效地学习这些权重。
【例3-2】 利用Python绘制tanh函数。


运行程序,效果如图3-8所示。

图3-8 Python绘制的tanh函数
3.2.4 修正线性激活函数
当神经元的总输入大于零的时候,修正线性单元(ReLU)的输出是线性的;当总输入为负数时,输出为零。这个简单的激活函数为神经网络提供了非线性变换,同时,它为总输入提供了一个恒定的梯度。这个恒定的梯度可帮助人工神经网络避免其他激活函数(如Sigmoid函数和tanh函数)出现梯度消失问题。ReLU函数的输出为

ReLU函数如图3-9所示。

图3-9 ReLU函数
ReLU函数是目前比较火的一个激活函数,相比Sigmoid函数和tanh函数,它有以下优点:
(1)在输入为正数的时候,不存在梯度饱和问题。
(2)计算速度要快很多。ReLU函数只有线性关系,不管是前向传播还是反向传播,都比Sigmoid函数和tanh函数要快很多(Sigmoid函数和tanh函数要计算指数,计算速度会比较慢)。
当然,缺点也是有的:
(1)当输入是负数的时候,ReLU函数是完全不被激活的,这表明一旦输入负数,ReLU函数就会失效。这在前向传播过程中,还不算什么问题,因为有的区域是敏感的,有的区域是不敏感的。但是在反向传播过程中,输入负数,梯度就会完全到0,这个和Sigmoid函数、tanh函数有一样的问题。
(2)ReLU函数的输出要么是0,要么是正数,这也就是说,ReLU函数也不是以0为中心的函数。
【例3-3】 Python绘制ReLU函数。

运行程序,效果如图3-10所示。

图3-10 Python绘制的ReLU函数
3.2.5 PReLU激活函数
ReLU函数的一个缺点是它对负数输入的零梯度。这可能会降低训练的速度,尤其是在初始阶段。在这种情况下,带参数的修正线性单元(PReLU)激活函数(简称PReLU函数,见图3-11)会很有用,对于负数的输入,输出和梯度都不是零。PReLU函数为


图3-11 PReLU函数
PReLU函数是针对ReLU函数的一个改进函数,在负数区域内,PReLU函数有一个很小的斜率,这样也可以避免ReLU函数失效。相比ReLU函数,PReLU函数在负数区域内进行线性运算,斜率虽然小,但是不会趋于0。
在PReLU函数公式中,参数a一般取0~1的数,而且取值比较小,如零点零几。当a=0.01时,我们称PReLU函数为Leaky ReLU函数,是PReLU函数的一种特殊情况。
【例3-4】 利用Python绘制PReLU函数。


运行程序,效果如图3-12所示。

图3-12 Python绘制的PReLU函数
3.2.6 softmax激活函数
softmax激活函数常被用于多分类问题,其输出为不同类别的概率。假设我们需要处理一个包含n个类别的分类问题,那么所有类别的总输入可用下面的公式表示。

在这种情况下,可以通过softmax激活函数给出第k个类别的输出概率。

还有很多其他激活函数,通常是这些基本激活函数的变形形式。
softmax激活函数在机器学习中有非常广泛的应用,下面利用softmax激活函数对MNIST数据进行分类,演示softmax激活函数对分类的处理效果。
【例3-5】 对MNIST数据进行分类处理。

运行程序,输出如下:
