常用的激活函数的比较
1 激活函数的作用
在神经网络中使用激活函数,主要是用来加入非线性因素的,因为线性模型的表达能力不够。下面,我将给出一些例子来详细的对比说明。
1.1 线性模型
下图所示是一个比较简单的感知机,它有一个隐藏层,并且使用了线性函数将3个神经网络的结果简单的相加在一起,这样导致的问题就是输出的时候无论如何都是一个线性方程。
因此我们最终得到的分类器看似是一个非线性的,但是本质上只不过是复杂的线性组合罢了。下图训练得到的分类器实则是三个线性分类的组合。如果我们要去逼近一条曲线的话,我们需要无限条的直线去逼近,这和非线性函数比起来效率太低了。
1.2 非线性模型
那么如果我们在感知机的每一层后面都加一个非线形的激活函数,那我们就可以得到一个超级复杂的输出函数,这将使得我们的神经网络的表达能力更加强大。
加入非线性激活函数之后,我们训练得到的分类器将如下图所示:
因此,激活函数给神经网络加入了非线性因素,这使得神经网络可以逼近任何非线性函数,这样神经网络就可以用于多种非线性模型中,这就大大提高了神经网络的表达能力。
2 非线性激活函数
2.1 Sigmoid函数
函数表达式为:
σ
(
x
)
=
1
1
+
e
−
x
\sigma(x) = \frac{1}{1+e^{-x}}
σ(x)=1+e−x1
函数曲线图为:
从曲线图中,我们可以看出在sigmoid函数的输出是在(0,1)这个开区间内,我们可以把它想象成一个神经元的放电率,在中间斜率比较大的地方是神经元的敏感区,在两边斜率很平缓的地方是神经元的抑制区。
sigmoid函数的缺点:
- 梯度消失,从曲线图中我们可以看出,在离坐标原点较远的地方,函数的梯度几乎为0。因此在反向传播的过程中,会对误差求导来更新权重。因为sigmoid函数的导数几乎接近于0,而且经过多层的传递之后会导致权重不能得到更新,就会出现梯度消失的问题,模型将不能继续更新。
- 其次,计算量较大,反向传播求误差梯度时,求导涉及除法。
2.2 tanh函数
函数表达式为:
t
a
n
h
(
x
)
=
s
i
n
h
(
x
)
c
o
s
h
(
x
)
=
e
x
−
e
−
x
e
x
+
e
−
x
tanh(x) = \frac{sinh(x)}{cosh(x)} = \frac{e^x-e^{-x}}{e^x+e^{-x}}
tanh(x)=cosh(x)sinh(x)=ex+e−xex−e−x
函数曲线图为:
从曲线图中,我们可以看出在sigmoid函数的输出是在(-1,1)这个开区间内,整个函数是以0为中心点的,是0均值的,因此在实际使用过程中,tanh的效果要比sigmoid好。
2.3 ReLU函数
函数表达式为:
f
(
x
)
=
m
a
x
(
0
,
x
)
f(x) = max(0, x)
f(x)=max(0,x)
函数曲线图为:
ReLU激活函数的优点:
- 当输入为正数的时候,不存在梯度消失的问题。
- 计算速度更快,因此收敛的速度也更快。ReLU本质上是两个线性函数,因此不管在前向还是反向传播过程中,计算速度都比tanh/sigmoid快(它们需要进行指数运算)。
ReLU激活函数的缺点:
- 从曲线图中可以看出,在前向传播过程中,如果输入是负数,那么ReLU就完全不会被激活。更糟糕的是,在反向传播过程中,如果输入是负数,那么梯度就直接等于0,就会出现梯度消失的问题。
- ReLU函数不是以0为中心的函数。
2.4 ELU函数
函数表达式为:
f
(
x
)
=
{
x
,
x
>
0
α
(
e
x
−
1
)
,
x
<
=
0
f(x) = \begin{cases} x, x>0\\ \alpha(e^x-1), x<=0\\ \end{cases}
f(x)={x,x>0α(ex−1),x<=0
函数曲线图为:
ELU激活函数的优点:
- 对ReLU函数进行了改进,在前向传播的过程中不会出现不被激活的现象。
ELU激活函数的缺点:
- 但是在反向传播的时候,如果输入是负数,那么还是会出现梯度消失的问题。
2.5 PReLU函数
函数表达式为:
f
(
x
)
=
m
a
x
(
a
x
,
x
)
f(x) = max(ax, x)
f(x)=max(ax,x)
函数曲线图为:
PReLU激活函数的优点:
- 这个激活函数也是对ReLU函数的一种改进,在前向传播的过程中不会出现不被激活的现象。此外,在反向传播的过程中,当输入为负数的时候,梯度不为0,这也可以避免梯度消失的问题。
- 此外,其本质上也相当于两个线性函数的组合,因此计算速度也比较快。
其中 α \alpha α的取值一般在0-1之间,而且一般都取较小的数。需要注意的是,当 α = 0.01 \alpha=0.01 α=0.01时,就是Leaky ReLU函数。
总结
每个激活函数都有各自的优缺点,在实际训练过程中,要选择合适的激活函数。