由于简书不支持编辑公式,更好的阅读体验请点击深度学习中的激活函数
激活函数的作用
在介绍几种常见的激活函数之前,我们先来说一下激活函数的作用。不要被它的名字所迷惑,激活函数的主要作用并不是模仿人脑神经元的激活机制。神经网络中引入激活函数主要是为了处理非线性问题,也正是由于这个原因,激活函数必须是非线性函数。如果没有激活函数,无论神经网络有多少层,最终得到的也只能是线性模型。以三层的网络为例,没有激活函数的情况下,网络的输出为:
其中上标表示对应层的参数,将上式展开后得到:
可以看到,最终得到的模型仍然是线性的,无论有多少层,道理和上面的例子一样。
几种常见的激活函数
1. sigmoid函数
sigmoid函数曾经得到广泛的应用,它的函数形式以及图像如下图所示:
sigmoid函数有以下几个缺点:
(1) 饱和性。由上图可以看到,sigmoid函数图像的两端是处于饱和状态的,在这种状态下,导数近似于0,饱和性会杀死梯度,使得深度网络难以训练。为什么这么说?回想一下,BP算法中残差(或敏感度)的计算公式:
当某个神经元处于饱和状态时,它的导数近似为0,那么此时这个神经元的残差也近似为0,而这个残差继续向前传递时,几乎不会对前面那些层的神经元产生什么影响了,基本上梯度到这里就无法继续向前反向传播了。因此,前面的参数无法得到有效的更新。即使神经元不处于饱和区,当网络层数很深的时候,使用sigmoid函数的网络也难以训练,sigmoid函数的导数图像如下图所示:
可以看到,它的导数最大值也只有0.25,而梯度进行反向传播时,有连乘操作,即使每个神经元的导数都能取到最大值,当网络的层数很深时,最后梯度消失现象也会比较严重。
(2) 输出不是0均值。sigmoid的输出在0到1之间,如果神经元全是正数,那么权值更新时只能全为正或全为负,会造成锯齿形晃动,使得收敛速度变慢。但是如果更新权值时使用的是批量数据,那么权值的更新就会更准确、更稳定,一定程度上会缓和这个问题。因此,相比较而言,梯度消失是sigmoid激活函数最致命的缺点。
2. tanh函数
tanh函数和sigmoid函数有些相似,tanh函数可以由sigmoid函数表示出来:
它的函数图像为:
可以看到,相比于sigmoid函数,tanh函数的输出是0均值的。但是它也存在sigmoid函数的另一个缺点,那就是饱和性。虽然比sigmoid函数好,但是同样难以训练。
3. ReLU函数
ReLU函数(Rectified Linear Units)是近几年很受欢迎的一种激活函数。它的函数表达式为:max(x,0),函数图像为:
ReLU函数有以下优点:
(1) 非饱和性。相比于之前的激活函数,ReLU函数很好的解决了梯度消失严重的问题。从上图可以看到,函数在大于0的部分,导数都为1。因此不会出现导数为0的情况,而且即使连乘,也不会损失梯度。
(2) 便于计算。ReLU是分段线性的,相比于指数形式的函数,ReLU函数无论是前向还是反向传播时,计算起来都十分简单。AlexNet论文中曾通过实验比较了分别使用ReLU函数和tanh函数时,网络的收敛速度,得到的结果是使用ReLU函数时,收敛速度远远快于使用tanh函数时。
(3) 稀疏性。比较这几种函数的图像,不难发现,在ReLU函数中,只有大于0的神经元才会被激活,其余都被置为0,而另外两种函数中,即使小于0,也会有部分神经元会被激活。这就使得使用ReLU函数时,会有更少的神经元被激活,使得网络更加稀疏。而稀疏性会带来很多优点,比如:
(i) 解离出特征中最关键的部分,获得更稀疏的表示,可以使得模型更加鲁棒。试想一下,如果是密集表示的话,那么即使对于稍微有些不同的两个个体,也可能会得到完全截然不同的结果,过于敏感。
(ii) 可变尺度的特征表示能表示更丰富的信息。每个样本所包含的信息可能有多有少,而通过激活神经元的数目变化,可以有效的表示它们所包含信息的丰富程度。激活的神经元越多,说明包含的信息越丰富,而激活的神经元越少,说明包含的信息越少。而稀疏性就为激活神经元数目的变化提供了余地。反之,如果原本特征表示就很密集,那么所有样本的特征表示都是密集的,根本没有为被激活神经元的数目提供变化的余地。
(iii) 稀疏的特征表示更易于线性可分。
(关于ReLU函数的优点,可以参考论文"Deep Sparse Rectifier Neural Networks"、"Rectified Linear Units Improve Restricted Boltzmann Machines"、"Rectifier Nonlinearities Improve Neural Network Acoustic Models")
当然,ReLU并不是完美的,它也有一些缺点:
(1) 和sigmoid函数一样,它的输出也不是0均值的。
(2) 可能会造成神经元"死亡"。当一个较大的梯度流过一个ReLU单元后,权值可能会更新的过猛。如果对于所有的输入,ReLU单元得到的结果总是0,然后它的导数也是0,导致权值无法更新,如此陷入恶性循环。相当于这个ReLU单元死掉了,不会被激活,也没有任何反向传播的作用。解决这个问题的一个办法是设置较小的学习率,避免权值更新过猛。
针对ReLU存在缺点,后来又有了许多改进的版本,比如LReLU、PReLU等等,这里不再进行详细介绍。