激活函数的意义:
在生物意义上的神经元中,只有前面的树突传递的信号的加权和值大于某一个特定的阈值的时候,后面的神经元才会被激活。
简单的说激活函数的意义在于判定每个神经元的输出
有没有达到阈值。
放在人脸识别卷积神经网络中来思考,卷积层的激活函数的意义在于这一块区域的特征强度如果没有达到一定的标准,就输出0,表明这种特征提取方式(卷积核w)不能在该块区域提取到特征,或者说这块区域的这种特征很弱。由于输出0时,激活函数梯度几乎都为0,所以在特征很弱的区域,梯度几乎不下降,也就是说,和该特征无关的区域不会影响到该特征提取方式的训练。
反过来说,如果没有激活函数,就算特征很弱时,仍然可以得到输出,后面的层次继续把这个输出当成一个特征使用,这是不合理的。为了形象起见,我们做个比喻,本来我们可能希望在这个区域看到一个圆形,但是这里却是一个三角形,如果该三角形和我们期望看到的圆形形状相差很大的时候神经元的输出WX+B很小,我们就不希望输出值去衡量这个三角形有多不圆,而是希望输出这里没有一个圆形(对于分类问题而言,有多不圆对于我们的分类没有意义,因为我们是通过了解到形状的组合来判定人脸属于哪一类,验证问题同理)。
个人理解这也是激活函数要非线性的意义。
Sigmod与tanh
Sigmoid. Sigmoid 非线性激活函数的形式是σ(x)=1/(1+e−x),其图形如上图左所示。之前我们说过,sigmoid函数输入一个实值的数,然后将其压缩到0~1的范围内。特别地,大的负数被映射成0,大的正数被映射成1。sigmoid function在历史上流行过一段时间因为它能够很好的表达“激活”的意思,未激活就是0,完全饱和的激活则是1。而现在sigmoid已经不怎么常用了,主要是因为它有两个缺点:
1.Sigmoid**容易饱和,并且当输入非常大或者非常小的时候,神经元的梯度就接近于0了,从图中可以看出梯度的趋势。这就使得我们在反向传播算法中反向传播接近于0的梯度,导致最终权重基本没什么更新**,我们就无法递归地学习到输入数据了。另外,你需要尤其注意参数的初始值来尽量避免这一情况。如果你的初始值很大的话,大部分神经元可能都会处在饱和的状态而把梯度kill掉,这会导致网络变的很难学习。
对于这一点,我个人的理解就是对于数据特别小的时候,梯度确实应该接近0(等于0就不好了),理由如上所述,数据特别大的时候,梯度不应该接近0。就像Relu函数做的那样。
2.Sigmoid 的输出不是0均值的,这是我们不希望的,因为这会导致后层的神经元的输入是非0均值的信号,这会对梯度产生影响:假设后层神经元的输入都为正(e.g. x>0 elementwise in f=wTx+b),那么对w求局部梯度则都为正,这样在反向传播的过程中w要么都往正方向更新,要么都往负方向更新,导致有一种捆绑的效果,使得收敛缓慢。
当然了,如果你是按batch去训练,那么每个batch可能得到不同的符号(正或负),那么相加一下这个问题还是可以缓解。因此,非0均值这个问题虽然会产生一些不好的影响,不过跟上面提到的 kill gradients 问题相比还是要好很多的。
(个人认为,如果使用SGD,则Batch训练仍然不能达到上面说的效果,所以sigmod使用SGD效果不好。)
Tanh. Tanh和Sigmoid是有异曲同工之妙的,它的图形如上图右所示,不同的是它把实值得输入压缩到-1~1的范围,因此它基本是0均值的,也就解决了上述Sigmoid缺点中的第二个,所以实际中tanh会比sigmoid更常用。但是它还是存在梯度饱和的问题。Tanh是sigmoid的变形:tanh(x)=2σ(2x)−1。
RELU
ReLU. 近年来,ReLU 变的越来越受欢迎。它的数学表达式是:
f(x)=max(0,x)
很显然,从上图左可以看出,输入信号 \<0时,输出为0,>0时,输出等于输入。ReLU的优缺点如下:
优点1:Krizhevsky et al.在ImageNet Classification with Deep Convolutional
Neural Networks 提出使用 ReLU 得到的SGD的收敛速度会比 sigmoid/tanh 快很多(如上图右)。有人说这是因为它是linear,而且梯度不会饱和。
为什么线性不饱和,就会收敛的快?反向传播算法中,下降梯度等于敏感度乘以前一层的输出值,所以前一层输出越大,下降的梯度越多。该优点解决了sigmod的问题1的一部分
优点2:相比于 sigmoid/tanh需要计算指数等,计算复杂度高,ReLU 只需要一个阈值就可以得到激活值。
缺点1: ReLU在训练的时候很”脆弱”,一不小心有可能导致神经元”坏死”。举个例子:由于ReLU在x<0时梯度为0,这样就导致负的梯度在这个ReLU被置零,而且这个神经元有可能再也不会被任何数据激活。如果这个情况发生了,那么这个神经元之后的梯度就永远是0了,也就是ReLU神经元坏死了,不再对任何数据有所响应。实际操作中,如果你的learning rate 很大,那么很有可能你网络中的40%的神经元都坏死了。 当然,如果你设置了一个合适的较小的learning rate,这个问题发生的情况其实也不会太频繁。
这个缺点类似sigmod问题1的另一部分,也就是说,如果在训练中某一次下降的太快,会导致该卷积核对要提取的特征要求过高,形象的说,就是变成了一个“完美主义”卷积核,所有形状都入不了它的眼,这样这个神经元就没用了,坏死了
leaky ReLU
Leaky ReLU. Leaky ReLUs 就是用来解决ReLU坏死的问题的。和ReLU不同,当x\<0时,它的值不再是0,而是一个较小斜率(如0.01等)的函数。也就是说f(x)=1(x\<0)(ax)+1(x>=0)(x),其中a是一个很小的常数。这样,既修正了数据分布,又保留了一些负轴的值,使得负轴信息不会全部丢失。关于Leaky ReLU 的效果,众说纷纭,没有清晰的定论。有些人做了实验发现 Leaky ReLU 表现的很好;有些实验则证明并不是这样。
Leaky ReLU相当于对sigmod问题2有一定改善,更主要的是解决了ReLu的坏死问题,让坏了的神经元可以自我慢慢恢复,但是坏处就是,如果a过大,会丢失作为激活函数的原意。
我认为,Leaky ReLu的作用肯定是有的,但是既有好处也有坏处,关键在于a值的把握。
PReLU. 对于 Leaky ReLU 中的a,通常都是通过先验知识人工赋值的。然而可以观察到,损失函数对a的导数我们是可以求得的,可不可以将它作为一个参数进行训练呢? Kaiming He 2015的论文《Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification》指出,不仅可以训练,而且效果更好。原文说使用了Parametric ReLU后,最终效果比不用提高了1.03%.
-Randomized Leaky ReLU. Randomized Leaky ReLU 是 leaky ReLU 的random 版本, 其核心思想就是,在训练过程中,a是从一个高斯分布中随机出来的,然后再在测试过程中进行修正。
maxout
假设我们网络第i层有2个神经元x1、x2,第i+1层的神经元个数为1个,如下图所示:
img
(1)以前MLP的方法。我们要计算第i+1层,那个神经元的激活值的时候,传统的MLP计算公式就是:
z=W*X+b
out=f(z)
其中f就是我们所谓的激活函数,比如Sigmod、Relu、Tanh等。
(2)Maxout 的方法。如果我们设置maxout的参数k=5,maxout层就如下所示:
img
相当于在每个输出神经元前面又多了一层。这一层有5个神经元,此时maxout网络的输出计算公式为:
z1=w1*x+b1
z2=w2*x+b2
z3=w3*x+b3
z4=w4*x+b4
z5=w5*x+b5
out=max(z1,z2,z3,z4,z5)
所以这就是为什么采用maxout的时候,参数个数成k倍增加的原因。本来我们只需要一组参数就够了,采用maxout后,就需要有k组参数。
我的理解是,本来只能提取一类特征,现在提供五类特征提取方式,选择其中最符合一类。
那么可以分析得知:
优势是具有上述的恢复能力,而且恢复的是最接近的一个特征提取方式,由于有五个备选,那么虽然是线性,但是对整体系统影响不那么大。
缺点是参数数目大幅增加,网络结构复杂。
References:
1.《ImageNet Classification with Deep Convolutional
Neural Networks》
2.《Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification》
3.《A Lightened CNN for Deep Face Representation》