前言

本文是对神经网络中常见的激活函数的一个总结,我会介绍各种激活函数的基本形式和优缺点等。

什么是激活函数

  激活函数可以说是神经网络的基础,假设默认你已经了解过神经网络的基础结构,那么在神经网络中,输入层与隐含层或者隐含层与隐含层之间都会存在激活函数,其最主要的功能就是向神经网络中引入非线性因素。

1.Sigmiod函数

  Sigmoid型函数是一类S型曲线函数,也叫两端饱和函数,又称Logistic函数,逻辑回归其实就是单层的神经元模型,它可以很好的解决二分类问题,例如01输出。在神经网络结构中,Sigmoid是一个非常常见的激活函数,先来看一下它的图像

在这里插入图片描述


Sigmoid函数的值域是0到1,其梯度的值域是0到0.25。并且Sigmoid函数存在明显的两端饱和现象。由此可以得出Sigmoid函数的使用条件及其优缺点。

Sigmoid函数的特点

  1. 函数的输出范围是0到1,对每个神经元的输出进行了归一化;
  2. 用于将预测概率作为输出的模型,因为概率的取值是0到1,正好和Sigmoid的值域相等;
  3. 函数可微,能够适用于神经网络中的误差反向传播;

Sigmoid函数的缺点

  1. 梯度消失问题,假如神经网络的传输值变为较大的正数或者较小的负数,那么此时Sigmoid的梯度将会非常小,可想而知,在多层神经网络的误差传播过程中,如果上述情况多次出现,最后传播的梯度可能就等于0,网络也就无法学习,所以在深度学习中是很少使用Sigmoid作为激活函数的。
  2. 计算费时,Sigmoid函数本身自带幂计算,在大规模计算过程中,会很影响计算速率。
  3. 不以0为中心,会导致学习效率下降,原因放在附录。

可以看到,虽然Sigmoid能将值域固定在0到1之间,并且能够很好处理概率分类问题,但是Sigmoid不适合在多层神经网络中进行传播,一般来说,Sigmoid函数都会放在分类问题的最后一层。

2.Tanh函数

  Tanh函数也是一种常见的Sigmoid函数,它是对Sigmoid函数的一中改进,但是并不能从根本上解决Sigmiod函数来带的梯度消失问题。Tanh函数的定义如下:

图像如下:
在这里插入图片描述
  从图像可以看出,Tanh与Sigmoid最大的区别就是输出的值域发生了变化,Tanh的值域变为-1到1,但是其是关于中心0点对称,这很好的解决了Sigmoid传播低效的问题。但是输出却不能表达概率值,而且Tanh不能有效解决梯度消失问题,因为其仍然是一个两端饱和图像。
Tanh函数的特点

  1. Tanh解决了Sigmoid函数不以0点位中心的问题,在更新参数上要比Sigmoid函数要好;
  2. Tanh并没有解决梯度消失问题,在饱和时(x很大或者x很小时)也会出现梯度等于0的现象;
  3. Tanh函数的值域是-1到1,无法表示概率的输出,所以在神经网络分类问题上,可以将Tanh函数放在隐含层的传输中,在最后一层使用Sigmoid函数表示概率的输出。

总的来说,Tanh并没有从根本问题上来改进Sigmoid函数。

3.ReLU函数

  ReLU的提出就是为了解决梯度消失问题,其全名为修正线性单元,也是目前深度神经网络使用最多的激活函数,定义为:


下面是ReLU的函数图像:
在这里插入图片描述
可以看到,ReLU函数非常简单,它能作为激活函数肯定有很多特点,下面总结:

ReLU函数的特点分析

  1. 当输入为正时,导数为1,一定程度上改善了梯度消失问题,加速梯度下降的收敛速度;
  2. 计算速度快得多,ReLU只是很简单的线性表示,要么1要么0,所以不会出现很复杂的计算;
  3. 可能会出现神经元死亡现象,如果参数在一次不恰当的更新后,第一个隐含层中的某个ReLU神经元在所有的训练数据上都不能被激活,那么这个神经元自身参数的梯度就永远都会是0,在以后的训练过程中永远都不会被激活,这种现象叫做死亡ReLU问题。
  4. ReLU不是以0为中心,所以和Sigmoid激活函数类似,会影响梯度下降的效率;

  可以看到没有一个激活函数是完美的,各自都有各自的缺点,例如Sigmoid和Tanh可能会出现梯度消失,ReLU和Sigmoid不是以0为中心,会影响梯度下降的速度,Tanh计算复杂等等,这些各种各样的问题说明,在选择合适的激活函数时没有一个固定的答案,要看你的需求来确定合适的激活函数。

4.LReLU

LReLU全名Leaky ReLU,又称带泄露的ReLU,是ReLU函数的一个改进,具体如下:


其中 γ 是一个很小的常数,例如可以取0.01。下面是图像:
在这里插入图片描述
LReLU不但继承了ReLU的所有优点,还解决了ReLU出现神经元死亡的问题。

5.PReLU

  PReLU与LReLU函数非常相似,只不过LReLU使用的参数在全局训练过程中不改变,而PReLU的 γ 是学习的,即动态的,对于每一个不同的神经元,都有一个对应的 γ
  当 γ = 0 ,PReLU就变成了ReLU;当 γ 为一个很小的参数,PReLU就变成了LReLU,由于PReLU允许不同的神经元具有不同的参数,所以一般情况下,PReLU的效果是比较好的。学习PReLU可以看成LReLU。

LReLu、PReLu和ReLU的对比

  1. LReLU和PReLU通过把 x 的非常小的线性分量分给负输入来调整负值的零梯度问题;
  2. 前者有助于扩大ReLU函数的范围,通常参数 γ 的取值为0.01左右;
  3. LReLU和PReLU函数的值域是负无穷到正无穷;

要注意,尽管从理论上来看,LReLU和PReLU要比ReLU要好,但是事实如何,还是需要实验。

6.ELU

一个优秀的激活函数,应该尽量要满足下面两个条件:

  • 输出的分布是零均值的,可以加快训练速度。
  • 激活函数是单侧饱和的,可以更好的收敛。

为什么单侧饱和要更好
  神经元本质就是一种类似开关的东西,当输入的值大于阈值0,神经元被激活,当输入的值小于阈值0,神经元被抑制,这种神经元应该更符合实际,例如输入两个值:10与5,明显10要比5大,带来的信号增强也是10更明显,但是输入两个值-10与-5,这两个值本身就没有可比性,因为当输入小于0时,神经元都没有反应(处于抑制状态),更别说兴奋状态谁大谁小了。所以当输入值小于0时,这个时候让函数趋于饱和(即梯度等于0),应该是最理想的激活函数。
  单侧饱和还能使得神经元对于噪声干扰更具鲁棒性。假设一个双侧都不饱和的神经元,正侧的不饱和导致神经元正值的取值各不相同,这是我们所希望的,因为正值的大小代表了检测特征信号的强弱。但负值的大小引入了背景噪声或者其他特征的信息,这会给后续的神经元带来无用的干扰信息;且可能导致神经元之间的相关性,相关性(重复信息)是我们所不希望的。例如检测直线的神经元和检测曲线的神经元可能有负相关性。在负值区域单侧饱和的神经元则不会有上述问题,噪声的程度大小被饱和区域都截断为0,避免了无用信息的干扰

  LeakyReLU和PReLU满足第1个条件,不满足第2个条件;而ReLU满足第2个条件,不满足第1个条件。两个条件都满足的激活函数为ELU(Exponential Linear Unit),函数图像如图:
在这里插入图片描述
表达式如下:


其中 γ 是调整函数饱和的参数。
  从理论上来看,ELU的效果应该要比PReLU和LReLU更好,但是事实上,不同的激活函数其效果都是无法知道的,具体选择哪一个作为激活函数还是需要进行实验。
  虽然说ReLU的各种各样的改进看似是越来越好,解决了ReLU的几个缺点。例如中心不对称、梯度消失等等问题,但是,这些改进也默认丢弃了ReLu的一个缺点,即稀疏激活性。所以没有最优的激活函数,只有最合适的激活函数。从“没有免费午餐定理”中也能看出,不存在某种算法对所有的问题都有效,如果一个算法对某些问题有效,那么它肯定在另一个问题上面比随机搜索算法更差,也就是说,不能逃离具体问题来讨论算法的优劣。

7.Softplus

Softplus可以看成是ReLU的平滑版本,也算是对ReLU的一个改进,定义为:
y = l o g ( 1 + e 2 ) 注意到,Softplus求导正好等于Logistic函数,并且Soft函数也具有单侧抑制特性,但它却没有稀疏激活性,下图是SoftPlus、ReLU、PReLU、LReLU和ELU函数的对比:

在这里插入图片描述

8.Swish

  Swish函更加复杂,其本身就是一种类似自门控激活函数。定义为:
y = x σ ( β x ) 
其中 σ 是Sigmoid函数, β 是一个可学习的或者固定的超参数
 σ ( β x ) 接近1时,门处于开状态,激活函数的输出近似 x  本身,当 σ ( β x ) 接近0时,门的状态为关,激活函数输出近似为0;
在这里插入图片描述
可以看到,该函数可以成为ReLU,可以看成线性函数和ReLU函数之间的非线性插值函数,其程度由参数 β \beta β控制。

9.GELU

总结

  上文大约介绍了9个常见的激活函数,这些激活函数是训练神经网络时最常用。没有一个激活函数是完美的,简单的激活函数也有简单的优点,其训练简单,没有过多的超参数需要调整,一般在BP神经网络中,常作为中间层的是Sigmoid函数或者Tanh函数;如果是二分类问题,那么输出的激活函数就可以是Sigmoid函数。在深度神经网络中,ReLU的效果要比Sigmoid或者Tanh效果要好。
  我觉得作为激活函数,没有一种绝对的概念,选择合适的激活函数才是最重要的,例如在深度学习中由于网络的层级关系很多,计算量很大,所以选择激活函数时我们可以选择形式简单的ReLU函数。Sigmoid函数会导致多层传播累积的梯度很小,也就是梯度消失现象,天下没有免费的午餐,多实验才能找到合适的激活函数。

本文还有一些很细节的部分没有介绍说明,我会把补充的内容放在文章末尾处。

1、不以0点为对称的激活函数,为什么会导致学习效率下降?
2、为什么线性的ReLU能作为激活函数?
3、神经元的死亡本质是什么?有什么避免的办法?