激活函数的作用
对于一个神经网络中的神经元(节点),需要根据输入计算这个神经元的输出(节点激活值)。以下图表示的这个神经元为例,计算它的输出包括两步
- 对输入值的线性加权, z = ∑ i = 1 3 w i x i + b z=\sum_{i=1}^{3} w_{i} x_{i}+b z=∑i=13wixi+b;
- 对加权和
z
z
z 进行非线性变换,
y
=
f
(
z
)
y=f(z)
y=f(z)
这里 f f f 是激活函数,一般为非线性函数。那么为什么一定要用非线性函数呢?原因在于如果使用了线性激活函数,无论这个神经网络有多深,得到的输出仍旧是输入的线性组合,这样的网络对于线性不可分的问题是没有作用的。
常用的激活函数
神经网络中常用的激活函数包括:sigmoid函数,tanh函数和ReLU函数。
1. sigmoid函数
Logistic中讲到过sigmoid函数
g
(
z
)
=
1
1
+
e
−
z
g(z)=\frac{1}{1+e^{-z}}
g(z)=1+e−z1它能够将
(
−
∞
,
+
∞
)
(-\infty,+\infty)
(−∞,+∞) 中的值映射到
(
0
,
1
)
(0,1)
(0,1),函数图像如下
sigmoid函数还有一个很优秀的特性就是它的导函数,对它求导可以发现
g
′
(
z
)
=
g
(
z
)
(
1
−
g
(
z
)
)
g'(z)=g(z)(1-g(z))
g′(z)=g(z)(1−g(z))这样在用梯度下降法求梯度就很容易,推导过程很简单,就不展开了。
优点有了,但是缺点同样也很明显。从导函数的函数式和sigmoid的函数图像也可以看出来,即当
z
z
z 很大(
g
(
z
)
≈
1
g(z)\approx1
g(z)≈1) 或者很小(
g
(
z
)
≈
0
g(z)\approx0
g(z)≈0) 的时候
g
′
(
z
)
≈
0
g'(z)\approx0
g′(z)≈0,这样在使用梯度下降法优化权重的时候由于梯度接近0,权重更新十分缓慢,称之为梯度消失。因此一般不在神经网络的隐层中使用sigmoid函数,但是对于二分类问题,将sigmoid用在输出层作为激活函数仍旧是一个不错的选择。
2. tanh函数
另一个和sigmoid函数很像的激活函数是tanh函数,它将 ( − ∞ , + ∞ ) (-\infty,+\infty) (−∞,+∞) 中的值映射到 ( − 1 , 1 ) (-1,1) (−1,1),函数式和函数图像如下 g ( z ) = e z − e − z e z + e − z g(z)=\frac{e^{z}-e^{-z}}{e^{z}+e^{-z}} g(z)=ez+e−zez−e−z
对tanh函数求导可以得到其导函数为
g
′
(
z
)
=
1
−
g
2
(
z
)
g'(z)=1-g^2(z)
g′(z)=1−g2(z)
可以看到在是用梯度下降法的时候也是很容易求梯度的。吴恩达老师的深度学习课程视频里说到tanh函数大多数情况下性能会比sigmoid函数的性能好,Emmm至于为什么好的原因视频里没有讲到(可能是因为引入了负值之后放大了特征???)。但是,结合函数表达式和图像,以及导函数的表达式也可以看出使用tanh函数作为激活函数的时候同样存在梯度消失的问题。
3. ReLU函数
针对sigmoid函数和tanh函数求梯度时存在的梯度下降的问题,ReLU被提出。ReLU全称为非线性修正单元(Rectified Liner Unit),目前已经是机器学习和深度学习里非常受欢迎的一个函数,其表达式和图像如下 g ( z ) = m a x ( 0 , z ) g(z)=max(0,z ) g(z)=max(0,z)
ReLU在 z > 0 z>0 z>0 时,输出与输入保持线性关系,因此梯度永远存在 g ‘ ( z ) = 1 g‘(z)=1 g‘(z)=1,在 z < 0 z<0 z<0 时梯度为零,然后 z > 0 z>0 z>0 与 z < 0 z<0 z<0 部分共同组成了非线性函数。RuLU函数在 z = 0 z=0 z=0 时倒数是没有定义的,但是实际应用中,ReLU函数的输入(即前一层网络的线性加权和)为0的概率非常非常低,因此不同担心这一点,或者可以在程序中定义 z = 0 z=0 z=0 时的导数值为0或1) 。
4. Leaky ReLU函数
Leaky ReLU是ReLU的改进版本,表达式和图像如下 g ( z ) = { 0.001 z , z < 0 z , z ≥ 0 g(z)=\left\{\begin{array}{c}{0.001 z, z<0} \\ {z \quad, z \geq 0}\end{array}\right. g(z)={0.001z,z<0z,z≥0
可以看到,在 z < 0 z<0 z<0函数的斜率不再为0,而是一个很小的值,这样能保证在 z < 0 z<0 z<0 时仍旧存在梯度。但是Leaky ReLU的使用频率却没有ReLU那么高,原因在于通常情况下有足够多的来保证 z > 0 z>0 z>0 。
总结
上面介绍了神经网路中常用的激活函数,但是事实上,在神经网络中一般默认使用ReLU函数或者Leaky ReLU函数,因为它们的梯度优势会加快神经网络的训练速度。sigmoid函数一般仅仅用在二分类网络的输出层,其他情况下sigmoid函数都可以被性能更好的tanh函数代替。吴恩达老师在视频中给的建议是,如果不知道选择激活函数,那么直接使用ReLU函数就OK了!