深度学习中的激活函数
激活函数的作用
摘自:https://www.zhihu.com/question/22334626
激活函数(Activation Function)是用来加入非线性因素的,因为线性模型的表达能力不够。
以下,同种颜色为同类数据。
某些数据是线性可分的,意思是,可以用一条直线将数据分开。比如下图:
这时候你需要通过一定的机器学习的方法,比如感知机算法(perceptron learning algorithm) 找到一个合适的线性方程。
但是有些数据不是线性可分的。比如如下数据:
第二组数据你就没有办法画出一条直线来将数据区分开。
这时候有两个办法,第一个办法,是做线性变换(linear transformation),比如讲x,y变成x2,y2,这样可以画出圆形。如图所示:
如果将坐标轴从x,y变为以x2,y2为标准,你会发现数据经过变换后是线性可分的了。大致示意图如下: image.png
另外一种方法是引入非线性函数。
我们来看异或问题(xor problem)。以下是xor真值表:
个真值表不是线性可分的,所以不能使用线性模型,如图所示:
image.png我们可以设计一种神经网络,通过激活函数来使得这组数据线性可分。
激活函数我们选择阀值函数(threshold function),也就是大于某个值输出1(被激活了),小于等于则输出0(没有激活)。这个函数是非线性函数。
神经网络示意图如下:
其中直线上的数字为权重。圆圈中的数字为阀值。第二层,如果输入大于1.5则输出1,否则0;第三层,如果输入大于0.5,则输出1,否则0。
我们来一步步算。第一层到第二层(阀值1.5):
image.png第二层到第三层(阀值0.5):
image.png可以看到第三层输出就是我们所要的xor的答案。
经过变换后的数据是线性可分的(n维,比如本例中可以用平面),如图所示:
这是一个单层的感知机, 也是我们最常用的神经网络组成单元啦. 用它可以划出一条线, 把平面分割开:
image.png那么很容易地我们就会想用多个感知机来进行组合, 获得更强的分类能力, 这是没问题的啦~~~~ 如图所示:
image.png那么我们动笔算一算, 就可以发现, 这样一个神经网络组合起来,输出的时候无论如何都还是一个线性方程哎~~~~纳尼, 说好的非线性分类呢?
我们在每一层叠加完了以后, 加一个激活函数, 如图中的 image.png有了这样的非线性激活函数以后, 神经网络的表达能力更加强大。
image.png加上非线性激活函数之后, 我们就有可能学习到这样的平滑分类平面。
image.pngimage.png
所以到这里为止,我们就解释了这个观点,加入激活函数是用来加入非线性因素的,解决线性模型所不能解决的问题。
激活函数的类型
image.png
- 红色:ReLU
- 蓝色:Tanh
- 绿色:Sigmoid
- 紫色:Linear
Sigmoid
Sigmoid 非线性函数将输入映射到 (0,1) 之间。它的数学公式为
image.png image.png历史上,sigmoid 函数曾非常常用,然而现在它已经不太受欢迎,实际很少使用了,因为它主要有两个缺点:
1. 函数饱和使梯度消失
sigmoid 神经元在值为 0 或 1 的时候接近饱和,这些区域,梯度几乎为 0。因此在反向传播时,这个局部梯度会与整个代价函数关于该单元输出的梯度相乘,结果也会接近为 0 。
这样,几乎就没有信号通过神经元传到权重再到数据了,因此这时梯度就对模型的更新没有任何贡献。
除此之外,为了防止饱和,必须对于权重矩阵的初始化特别留意。比如,如果初始化权重过大,那么大多数神经元将会饱和,导致网络就几乎不学习。
2. sigmoid 函数不是关于原点中心对称的
这个特性会导致后面网络层的输入也不是零中心的,进而影响梯度下降的运作。
因为如果输入都是正数的话(如
当然,如果是按 batch 去训练,那么每个 batch 可能得到不同的信号,整个批量的梯度加起来后可以缓解这个问题。因此,该问题相对于上面的神经元饱和问题来说只是个小麻烦,没有那么严重。
tanh
image.png tanh非线性函数将实数值压缩到[-1,1]之间。和sigmoid神经元一样,它也存在饱和问题,但是和sigmoid神经元不同的是,它的输出是零中心的。因此,在实际操作中,tanh非线性函数比sigmoid非线性函数更受欢迎。注意tanh神经元是一个简单放大的sigmoid神经元,具体说来就是: image.png
注: σ函数就是sigmoid函数
ReLU
image.png近些年ReLU变得非常流行。它的函数公式是
image.png
换句话说,这个激活函数就是一个关于0的阈值。使用ReLU有以下一些优缺点:
-
优点:相较于sigmoid和tanh函数,ReLU对于随机梯度下降的收敛有巨大的加速作用( Krizhevsky等的论文指出有6倍之多)。据称这是由它的线性,非饱和的公式导致的。
image.png
-
优点:sigmoid和tanh神经元含有指数运算等耗费计算资源的操作,而ReLU可以简单地通过对一个矩阵进行阈值计算得到。
-
缺点:在训练的时候,ReLU单元比较脆弱并且可能“死掉”。举例来说,当一个很大的梯度流过ReLU的神经元的时候,可能会导致梯度更新到一种特别的状态,在这种状态下神经元将无法被其他任何数据点再次激活。如果这种情况发生,那么从此所以流过这个神经元的梯度将都变成0。也就是说,这个ReLU单元在训练中将不可逆转的死亡,因为这导致了数据多样化的丢失。例如,如果学习率设置得太高,可能会发现网络中40%的神经元都会死掉(在整个训练集中这些神经元都不会被激活)。通过合理设置学习率,这种情况的发生概率会降低。
Leaky-ReLU、P-ReLU、R-ReLU
Leaky ReLUs :就是用来解决这个 “dying ReLU” 的问题的。与 ReLU 不同的是:
f(x)=αx,(x<0)
f(x)=x,(x>=0)
这里的 α 是一个很小的常数。这样,即修正了数据分布,又保留了一些负轴的值,使得负轴信息不会全部丢失。
image.png关于Leaky ReLU 的效果,众说纷纭,没有清晰的定论。有些人做了实验发现 Leaky ReLU 表现的很好;有些实验则证明并不是这样。
Parametric ReLU: 对于 Leaky ReLU 中的α,通常都是通过先验知识人工赋值的。然而可以观察到,损失函数对α的导数我们是可以求得的,可不可以将它作为一个参数进行训练呢?
Kaiming He的论文指出,不仅可以训练,而且效果更好。
公式非常简单,反向传播至未激活前的神经元的公式就不写了,很容易就能得到。对α的导数如下:
image.png原文说使用了Parametric ReLU后,最终效果比不用提高了1.03%。
Randomized ReLU:Randomized Leaky ReLU是 leaky ReLU 的random 版本 (α 是random的)。它首次试在 kaggle 的NDSB 比赛中被提出的。
核心思想就是,在训练过程中,α 是从一个高斯分布 U(l,u) 中 随机出来的,
然后再测试过程中进行修正(有点像dropout的用法)。
数学表示如下:
image.png在测试阶段,把训练过程中所有的 αij 取个平均值。NDSB 冠军的 α 是从 U(3,8) 中随机出来的。那么,在测试阶段,激活函数就是就是:
image.png看看 cifar-100 中的实验结果:
image.pngMaxout
一些其他类型的单元被提了出来,它们对于权重和数据的内积结果不再使用
image.png
函数形式。一个相关的流行选择是Maxout(最近由Goodfellow等发布)神经元。
Maxout是对ReLU和leaky ReLU的一般化归纳,它的函数是:
image.png
ReLU和Leaky ReLU都是这个公式的特殊情况(比如ReLU就是当[w1=0,b1=0]的时候)。这样Maxout神经元就拥有ReLU单元的所有优点(线性操作和不饱和),而没有它的缺点(死亡的ReLU单元)。然而和ReLU对比,它每个神经元的参数数量增加了一倍,这就导致整体参数的数量激增。
image.pngMaxout出现在ICML2013上,作者Goodfellow将maxout和dropout结合后,号称在MNIST, CIFAR-10, CIFAR-100, SVHN这4个数据上都取得了start-of-art的识别率。
Maxout的拟合能力是非常强的,它可以拟合任意的的凸函数。作者从数学的角度上也证明了这个结论,即只需2个maxout节点就可以拟合任意的凸函数了(相减),前提是”隐隐含层”节点的个数可以任意多.
image.pngsoftmax
softmax用于多分类过程中,它将多个神经元的输出,映射到(0,1)区间内,可以看成概率来理解,从而来进行多分类!
假设我们有一个数组,V,Vi表示V中的第i个元素,那么这个元素的softmax值就是 :
更形象的如下图表示:
image.pngsoftmax直白来说就是将原来输出是3,1,-3通过softmax函数一作用,就映射成为(0,1)的值,而这些值的累和为1(满足概率的性质),那么我们就可以将它理解成概率,在最后选取输出结点的时候,我们就可以选取概率最大(也就是值对应最大的)结点,作为我们的预测目标!
举一个我最近碰到利用softmax的例子:我现在要实现基于神经网络的句法分析器。用到是基于转移系统来做,那么神经网络的用途就是帮我预测我这一个状态将要进行的动作是什么?比如有10个输出神经元,那么就有10个动作,1动作,2动作,3动作...一直到10动作。原理图如下图所示:
image.png那么比如在一次的输出过程中输出结点的值是如下:
[0.2,0.1,0.05,0.1,0.2,0.02,0.08,0.01,0.01,0.23]
那么我们就知道这次我选取的动作是动作10,因为0.23是这次概率最大的,那么怎么理解多分类呢?如果你想选取俩个动作,那么就找概率最大的俩个值即可。
其他的一些激活函数
image.png
image.png
如何选择激活函数?
一句话:“那么该用那种呢?”用ReLU非线性函数。注意设置好学习率,或许可以监控你的网络中死亡的神经元占的比例。如果单元死亡问题困扰你,就试试Leaky ReLU或者Maxout,不要再用sigmoid了。也可以试试tanh,但是其效果应该不如ReLU或者Maxout。
最后需要注意一点:在同一个网络中混合使用不同类型的神经元是非常少见的,虽然没有什么根本性问题来禁止这样做。
------参考:https://zhuanlan.zhihu.com/p/21462488
------参考:https://zhuanlan.zhihu.com/p/25723112
------参考:http://blog.csdn.net/cyh_24/article/details/50593400