深度学习之激活函数

文章目录


前言

激活函数是人工神经网络的重要组成部分,负责对输入信号进行非线性变换,可以拟合各种曲线,并输出最终结果。激活函数中的“激活”一词是指对网络中的某个神经元是否被接受到的所有输入信号之和激活,即这个神经元接收到的信号是起作用还是被忽视。激活函数将神经元的所有输入,包括输入值、连接权重,经过代数运算,得到一个综合的激活值,激活函数根据这个激活值离阈值的远近决定这个神经元输出 0 ∼ 1 0\sim1 0∼1或 − 1 ∼ 1 -1\sim 1 −1∼1的数值。

激活函数需要具备以下几点性质:

  1. 可导性:由于人工神经网络的误差反向传播算法需要对损失函数求导数,因此激活函数必须是可导的。
  2. 单调性:只有当激活函数是单调的,才能保证根据输出的误差值,逐步调整网络参数,达到误差收敛的效果。
  3. 非线性行:如果使用线性函数作为激活函数,增加网络层次将变得没有意义。无论神经网络有多少层,输出都是输入的线性组合,网络仅能够表达线性映射,此时即便有再多的隐藏层,整个网络跟单层神经网络是等价的。为了保证网络的非线性建模能力,激活函数必须是非线性的。
  4. 输出值的范围:原则上对激活函数输出值的范围是没有限定的。但当输出值为有限时,基于梯度的优化方法会更加稳定。如果激活函数输出值为无限时,模型的训练会更加高效,不过在这种情况下,一般需要更小的学习率。另外,激活函数的值域最好是在概率空间 [ 0 , 1 ] [0,1] [0,1]范围内,否则不能直接作为输出层的输出值,还需要通过softmax函数来计算分类的概率。

1. 阶梯函数

M-P模型和感知机使用如下的阶梯函数作为激活函数
f ( x ) = { 0 , i f ∑ i = 1 n w i x i − h ≤ 0 1 , i f ∑ i = 1 n w i x i − h > 0 f(x)=\left\{ \begin{aligned} 0 & , if \sum\limits_{i=1}^n w_i x_i - h \le 0 \\ 1 & , if \sum\limits_{i=1}^n w_i x_i - h > 0 \end{aligned} \right. f(x)=⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧​01​,ifi=1∑n​wi​xi​−h≤0,ifi=1∑n​wi​xi​−h>0​ 其中 x i x_i xi​为网络的输入, w i w_i wi​为连接权重, h h h为阈值。

深度学习之激活函数

2. sigmoid函数

使用阶梯函数作为激活函数的想法很自然,满足条件(阈值)函数取值为1,不满足条件时函数取值为0. 但是在数据分析中,很多判断只能是一个概率值,无法给出一个明确的二值逻辑值,所以阶梯函数在很多场景是不适用的,于是引入了sigmoid函数。
f ( u ) = 1 1 + e − u u = ∑ i = 1 n w i x i − h \begin{aligned} f(u) &= \frac{1}{1+e^{-u}} \\ u & = \sum\limits_{i=1}^n w_i x_i - h \end{aligned} f(u)u​=1+e−u1​=i=1∑n​wi​xi​−h​ sigmoid函数与阶梯函数的不同之处在于:阶梯函数在阈值处出现陡变,在阈值处不连续,无法求导,在其他地方导数值为0;sigmoid函数是一条光滑的曲线,在区间 ( 0 , 1 ) (0,1) (0,1)连续取值,处处可以求导,且导数值为正数;反向误差传播算法需要对损失函数求导,因此阶梯函数无法满足学习调整的任务,而sigmoid函数可以。

sigmoid函数的倒数满足: f ′ ( x ) = f ( x ) ( 1 − f ( x ) ) f^{'}(x)=f(x)(1-f(x)) f′(x)=f(x)(1−f(x))

sigmoid函数存在以下几个缺点:

  1. sigmoid函数的一阶导数(梯度值) ≤ 0.25 \le 0.25 ≤0.25,而且变量取值只有在区间 [ − 5 , 5 ] [-5, 5] [−5,5]之间梯度较大,其余区域梯度值会很小,可能引发梯度消失的问题;
  2. sigmoid函数包括指数函数,运算量很大;
  3. sigmoid函数的值域是 ( 0 , 1 ) (0,1) (0,1),函数值都是正值。算法并不是对称算法,并不是所有情况下都希望下一个神经元只能接受正值输入,而且算法收敛缓慢。

由于sigmoid函数存在以上缺点,因此在深度学习模型中已不常使用。

3. tanh函数

杨立昆先生建议采用双曲正切函数tanh来解决sigmoid函数的非对称问题。tanh函数的图像形状与sigmoid函数很像,区别在于值域从 ( 0 , 1 ) (0,1) (0,1)扩大到(-1,1),这是一个对称区间。
t a n h : f ( x ) = e x + e − x e x − e − x tanh:f(x) = \frac{e^x + e^{-x}}{e^x - e^{-x}} tanh:f(x)=ex−e−xex+e−x​ tanh函数的导数为 f ( x ) = 1 − f 2 ( x ) f(x)=1-f^2(x) f(x)=1−f2(x)。tanh函数的值域是以0为中心的区域 ( − 1 , 1 ) (-1,1) (−1,1),因此优化更容易,但同样存在梯度消失和运算效率的问题。

深度学习之激活函数

4. ReLU函数

激活函数ReLU(Rectified Linear Unit, 修正线性函数)是一个非常简单的函数,但有着不简单的效果。其定义公式如下: f ( x ) = m a x ( x , 0 ) f(x) = max(x,0) f(x)=max(x,0). 显然,ReLU函数的导数值是一个阶梯函数。

深度学习之激活函数
ReLU函数及其导数计算简单,有研究称,ReLU函数的收敛速度较tanh函数提高了6倍。但是ReLU函数解决梯度消失和梯度爆炸的问题的同时,又出现了以下两个问题:

  1. 取值范围为 [ 0 , ∞ ] [0,\infty] [0,∞],已经超过概率空间 [ 0 , 1 ] [0,1] [0,1],因此不能直接作为输出值出现在输出层,还需要使用softmax函数来计算分类的概率。
  2. ReLU的另一个问题是“死神经元”问题。当 x ≤ 0 x\le0 x≤0时,对应的梯度值为0,神经元无法更新;当 x > 0 x>0 x>0时,因为ReLU函数的梯度值可以很大,可能导致权重 w w w调整步伐过大,使得某个神经元经过调整,以后的梯度都是0,神经元不会再被激活。
  3. 和sigmoid激活函数类似,ReLU函数的输出同样不以零为中心。

尽管存在这些问题,ReLU目前仍是最常用的激活函数,在搭建人工神经网络时推荐优先尝试。以下函数可以解决ReLU的死神经元问题。

  • Maxout
  • Leaky ReLU
  • Parametric ReLU(PReLU)
  • Randomized leaky Rectified Linear Units(RReLU)

5. maxout函数

maxout函数是一种新型的激活函数,是一个可学习得分段线性函数,从 k k k个候选值中选取最大的一个作为这个值得输出。

深度学习之激活函数

实际上,是将网络的中间层所有 m m m个元素分成 d d d个小组,每个小组有 k k k个元素,每个小组只取其最大值作为这个小组的代表输出。设 z p l z_{pl} zpl​为中间层的第 p p p小组的第 l l l个元素,第 p p p小组唯一输出值 h p ( x ) h_p(x) hp​(x)的计算公式为:
z p l = ∑ j = 1 k w p j x j + b p , ( p = 1 , 2 , . . . , d ) h p ( x ) = max ⁡ l ∈ [ 1 , k ] z p l z_{pl} = \sum\limits_{j=1}^{k} w_{pj} x_j + b_p, (p=1,2,...,d) \\ h_p(x) = \max\limits_{l \in [1,k]} z_{pl} zpl​=j=1∑k​wpj​xj​+bp​,(p=1,2,...,d)hp​(x)=l∈[1,k]max​zpl​

6. ReLU函数的衍生函数

由于函数ReLU在 x < 0 x<0 x<0时梯度为0,这样,这个神经元有可能再也不会被任何数据激活。下图时三个基于ReLU函数改进的激活函数

深度学习之激活函数
Leaky ReLU函数的计算公式如下:
y = f ( x ) = { x , i f x > 0 a x , i f x ≤ 0 y = f(x) = \left\{ \begin{aligned} x & , if x > 0 \\ ax & , if x \le 0 \end{aligned} \right. y=f(x)={xax​,ifx>0,ifx≤0​ 当 x < 0 x<0 x<0时,Leaky ReLU函数让变量乘以一个很小的常数 a a a,例如 a = 0.01 a=0.01 a=0.01,这样就可以得到0.01的正梯度,从而避免出现死神经元问题。

PReLU函数: y = m a x ( α x , x ) y=max(\alpha x, x) y=max(αx,x), α \alpha α是一个超参数,不是一个固定值,是由误差反向传播算法计算出来的。

理论上来说,ReLU函数的衍生函数有ReLU的所有优点,且不会有死神经元问题,但是在实际操作中,并没有完全证明它们总是好于ReLU函数。

上一篇:常用激活函数


下一篇:数值稳定性QA