前言
本文是对神经网络中常见的激活函数的一个总结,我会介绍各种激活函数的基本形式和优缺点等。
什么是激活函数
激活函数可以说是神经网络的基础,假设默认你已经了解过神经网络的基础结构,那么在神经网络中,输入层与隐含层或者隐含层与隐含层之间都会存在激活函数,其最主要的功能就是向神经网络中引入非线性因素。
正常来说,对于某两层神经网络来说,有上一层的输出
x
i
x_i
xi和这一层的输入
y
y
y,它们之间有
y
i
=
w
x
+
b
y_{i}=wx+b
yi=wx+b,在这一层中如果没有激活函数的话,那么在传输到下一层的时候仍然是
y
i
+
1
=
w
y
i
+
b
=
w
(
w
x
+
b
)
+
b
=
w
2
x
+
w
b
+
b
y_{i+1} = wy_i+b=w(wx+b)+b=w^2x+wb+b
yi+1=wyi+b=w(wx+b)+b=w2x+wb+b。这时的
x
x
x还是一次函数,仍然是一个线性函数,但是如果有了激活函数后
σ
(
x
)
\sigma (x)
σ(x),可以将线性映射为非线性。众所周知感知机只能解决线性问题,当遇到复杂的非线性问题时,就需要引入多层感知机了,而且多层感知机的基础结构中就包含激活函数。如果没有激活函数,那么神经网络就没有任何意义了。
常见的激活函数
1.Sigmiod函数
Sigmoid型函数是一类S型曲线函数,也叫两端饱和函数,又称Logistic函数,逻辑回归其实就是单层的神经元模型,它可以很好的解决二分类问题,例如01输出。在神经网络结构中,Sigmoid是一个非常常见的激活函数,先来看一下它的图像
它的表达式为:
y
=
1
1
+
e
−
x
y = \frac{1}{1+e^{-x}}
y=1+e−x1
它导数的表达式为:
y
′
=
y
(
1
−
y
)
y' = y(1-y)
y′=y(1−y)
Sigmoid函数的值域是0到1,其梯度的值域是0到0.25。并且Sigmoid函数存在明显的两端饱和现象。由此可以得出Sigmoid函数的使用条件及其优缺点。
Sigmoid函数的特点
- 函数的输出范围是0到1,对每个神经元的输出进行了归一化;
- 用于将预测概率作为输出的模型,因为概率的取值是0到1,正好和Sigmoid的值域相等;
- 函数可微,能够适用于神经网络中的误差反向传播;
Sigmoid函数的缺点
- 梯度消失问题,假如神经网络的传输值变为较大的正数或者较小的负数,那么此时Sigmoid的梯度将会非常小,可想而知,在多层神经网络的误差传播过程中,如果上述情况多次出现,最后传播的梯度可能就等于0,网络也就无法学习,所以在深度学习中是很少使用Sigmoid作为激活函数的。
- 计算费时,Sigmoid函数本身自带幂计算,在大规模计算过程中,会很影响计算速率。
- 不以0为中心,会导致学习效率下降,原因放在附录。
可以看到,虽然Sigmoid能将值域固定在0到1之间,并且能够很好处理概率分类问题,但是Sigmoid不适合在多层神经网络中进行传播,一般来说,Sigmoid函数都会放在分类问题的最后一层。
2.Tanh函数
Tanh函数也是一种常见的Sigmoid函数,它是对Sigmoid函数的一中改进,但是并不能从根本上解决Sigmiod函数来带的梯度消失问题。Tanh函数的定义如下:
y
=
e
x
−
e
−
x
e
x
+
e
−
x
y = \frac{e^x-e^{-x}}{e^x+e^{-x}}
y=ex+e−xex−e−x
求导形式:
y
′
=
1
−
(
e
x
−
e
−
x
)
2
(
e
x
+
e
−
x
)
2
y'=1-\frac{(e^x-e^{-x})^2}{(e^x+e^{-x})^2}
y′=1−(ex+e−x)2(ex−e−x)2
图像如下:
从图像可以看出,Tanh与Sigmoid最大的区别就是输出的值域发生了变化,Tanh的值域变为-1到1,但是其是关于中心0点对称,这很好的解决了Sigmoid传播低效的问题。但是输出却不能表达概率值,而且Tanh不能有效解决梯度消失问题,因为其仍然是一个两端饱和图像。
Tanh函数的特点
- Tanh解决了Sigmoid函数不以0点位中心的问题,在更新参数上要比Sigmoid函数要好;
- Tanh并没有解决梯度消失问题,在饱和时(x很大或者x很小时)也会出现梯度等于0的现象;
- Tanh函数的值域是-1到1,无法表示概率的输出,所以在神经网络分类问题上,可以将Tanh函数放在隐含层的传输中,在最后一层使用Sigmoid函数表示概率的输出。
总的来说,Tanh并没有从根本问题上来改进Sigmoid函数。
3.ReLU函数
ReLU的提出就是为了解决梯度消失问题,其全名为修正线性单元,也是目前深度神经网络使用最多的激活函数,定义为:
y
=
{
x
x
>
0
0
x
≤
0
y=\left\{ \begin{aligned} x\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,x > 0\\ 0\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\, x\le0\\ \end{aligned} \right.
y={xx>00x≤0
导数为:
y
=
{
1
x
>
0
0
x
≤
0
y=\left\{ \begin{aligned} 1\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,x > 0\\ 0\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\, x\le0\\ \end{aligned} \right.
y={1x>00x≤0
下面是ReLU的函数图像:
可以看到,ReLU函数非常简单,它能作为激活函数肯定有很多特点,下面总结:
ReLU函数的特点分析
- 当输入为正时,导数为1,一定程度上改善了梯度消失问题,加速梯度下降的收敛速度;
- 计算速度快得多,ReLU只是很简单的线性表示,要么1要么0,所以不会出现很复杂的计算;
- 可能会出现神经元死亡现象,如果参数在一次不恰当的更新后,第一个隐含层中的某个ReLU神经元在所有的训练数据上都不能被激活,那么这个神经元自身参数的梯度就永远都会是0,在以后的训练过程中永远都不会被激活,这种现象叫做死亡ReLU问题。
- ReLU不是以0为中心,所以和Sigmoid激活函数类似,会影响梯度下降的效率;
可以看到没有一个激活函数是完美的,各自都有各自的缺点,例如Sigmoid和Tanh可能会出现梯度消失,ReLU和Sigmoid不是以0为中心,会影响梯度下降的速度,Tanh计算复杂等等,这些各种各样的问题说明,在选择合适的激活函数时没有一个固定的答案,要看你的需求来确定合适的激活函数。
4.LReLU
LReLU全名Leaky ReLU,又称带泄露的ReLU,是ReLU函数的一个改进,具体如下:
y
=
{
x
x
>
0
γ
x
x
≤
0
y=\left\{ \begin{aligned} x\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,x > 0\\ \gamma x\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\, x \le0\\ \end{aligned} \right.
y={xx>0γxx≤0
其中
γ
\gamma
γ是一个很小的常数,例如可以取0.01。下面是图像:
LReLU不但继承了ReLU的所有优点,还解决了ReLU出现神经元死亡的问题。
5.PReLU
PReLU与LReLU函数非常相似,只不过LReLU使用的参数在全局训练过程中不改变,而PReLU的
γ
\gamma
γ是学习的,即动态的,对于每一个不同的神经元,都有一个对应的
γ
\gamma
γ。
当
γ
=
0
\gamma=0
γ=0,PReLU就变成了ReLU;当
γ
\gamma
γ为一个很小的参数,PReLU就变成了LReLU,由于PReLU允许不同的神经元具有不同的参数,所以一般情况下,PReLU的效果是比较好的。学习PReLU可以看成LReLU。
LReLu、PReLu和ReLU的对比
- LReLU和PReLU通过把 x x x的非常小的线性分量分给负输入来调整负值的零梯度问题;
- 前者有助于扩大ReLU函数的范围,通常参数 γ \gamma γ的取值为0.01左右;
- 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),函数图像如图:
表达式如下:
y
=
{
x
x
>
0
γ
(
e
x
−
1
)
x
≤
0
y=\left\{ \begin{aligned} &x\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,x > 0\\ &\gamma(e^x-1)\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\, x \le0\\ \end{aligned} \right.
y={xx>0γ(ex−1)x≤0
其中
γ
\gamma
γ是调整函数饱和的参数。
从理论上来看,ELU的效果应该要比PReLU和LReLU更好,但是事实上,不同的激活函数其效果都是无法知道的,具体选择哪一个作为激活函数还是需要进行实验。
虽然说ReLU的各种各样的改进看似是越来越好,解决了ReLU的几个缺点。例如中心不对称、梯度消失等等问题,但是,这些改进也默认丢弃了ReLu的一个缺点,即稀疏激活性。所以没有最优的激活函数,只有最合适的激活函数。从“没有免费午餐定理”中也能看出,不存在某种算法对所有的问题都有效,如果一个算法对某些问题有效,那么它肯定在另一个问题上面比随机搜索算法更差,也就是说,不能逃离具体问题来讨论算法的优劣。
7.Softplus
Softplus可以看成是ReLU的平滑版本,也算是对ReLU的一个改进,定义为:
y
=
l
o
g
(
1
+
e
2
)
y = log(1+e^2)
y=log(1+e2)
注意到,Softplus求导正好等于Logistic函数,并且Soft函数也具有单侧抑制特性,但它却没有稀疏激活性,下图是SoftPlus、ReLU、PReLU、LReLU和ELU函数的对比:
8.Swish
Swish函更加复杂,其本身就是一种类似自门控激活函数。定义为:
y
=
x
σ
(
β
x
)
y = x\sigma(\beta x)
y=xσ(βx)
其中
σ
\sigma
σ是Sigmoid函数,
β
\beta
β是一个可学习的或者固定的超参数
当
σ
(
β
x
)
\sigma(\beta x)
σ(βx)接近1时,门处于开状态,激活函数的输出近似
x
x
x本身,当
σ
(
β
x
)
\sigma(\beta x)
σ(βx)接近0时,门的状态为关,激活函数输出近似为0;
可以看到,该函数可以成为ReLU,可以看成线性函数和ReLU函数之间的非线性插值函数,其程度由参数
β
\beta
β控制。
9.GELU
GELU也是一种通过门控机制来调整其输出值的激活函数,和Swish函数比较类似
y
=
x
P
(
X
<
x
)
y = xP(X<x)
y=xP(X<x)
其中
P
(
X
≤
x
)
P(X\le x)
P(X≤x)是高斯分布的累积分布函数,其中
μ
、
σ
\mu、\sigma
μ、σ为超参数,一般
μ
=
0
,
σ
=
1
\mu=0,\sigma=1
μ=0,σ=1即可,由于高斯分布的累积分布函数为S型函数,因此GELU函数可以用Tanh函数或者Logistic函数来近似。
y
=
x
σ
(
1.702
x
)
y = x\sigma(1.702x)
y=xσ(1.702x)
当使用Logistic函数来近似时,相当于一种特殊的Swish函数。
总结
上文大约介绍了9个常见的激活函数,这些激活函数是训练神经网络时最常用。没有一个激活函数是完美的,简单的激活函数也有简单的优点,其训练简单,没有过多的超参数需要调整,一般在BP神经网络中,常作为中间层的是Sigmoid函数或者Tanh函数;如果是二分类问题,那么输出的激活函数就可以是Sigmoid函数。在深度神经网络中,ReLU的效果要比Sigmoid或者Tanh效果要好。
我觉得作为激活函数,没有一种绝对的概念,选择合适的激活函数才是最重要的,例如在深度学习中由于网络的层级关系很多,计算量很大,所以选择激活函数时我们可以选择形式简单的ReLU函数。Sigmoid函数会导致多层传播累积的梯度很小,也就是梯度消失现象,天下没有免费的午餐,多实验才能找到合适的激活函数。
本文还有一些很细节的部分没有介绍说明,我会把补充的内容放在文章末尾处。
1、不以0点为对称的激活函数,为什么会导致学习效率下降?
2、为什么线性的ReLU能作为激活函数?
3、神经元的死亡本质是什么?有什么避免的办法?