日常 coding 中,我们会很自然的使用一些激活函数,比如:sigmoid、ReLU等等。不过好像忘了问自己一( n )件事:
本文正是基于这些问题展开的,欢迎批评指正!
(此图并没有什么卵用,纯属为了装x …)
激活函数通常有如下一些性质:
这些性质,也正是我们使用激活函数的原因!
Sigmoid 是常用的非线性的激活函数,它的数学形式如下:
正如前一节提到的,它能够把输入的连续实值“压缩”到0和1之间。
特别的,如果是非常大的负数,那么输出就是0;如果是非常大的正数,输出就是1.
sigmoid 函数曾经被使用的很多,不过近年来,用它的人越来越少了。主要是因为它的一些 缺点:
tanh 是上图中的右图,可以看出,tanh 跟sigmoid还是很像的,实际上,tanh 是sigmoid的变形:
与 sigmoid 不同的是,tanh 是0均值的。因此,实际应用中,tanh 会比 sigmoid 更好(毕竟去粗取精了嘛)。
近年来,ReLU 变的越来越受欢迎。它的数学表达式如下:
很显然,从图左可以看出,输入信号 <0 时,输出都是0, >0 的情况下,输出等于输入。 w 是二维的情况下,使用ReLU之后的效果如下:
ReLU 的优点:
ReLU 的缺点: 当然 ReLU 也有缺点,就是训练的时候很”脆弱”,很容易就”die”了. 什么意思呢?
举个例子:一个非常大的梯度流过一个 ReLU 神经元,更新过参数之后,这个神经元再也不会对任何数据有激活现象了。
如果这个情况发生了,那么这个神经元的梯度就永远都会是0.
实际操作中,如果你的learning rate 很大,那么很有可能你网络中的40%的神经元都”dead”了。
当然,如果你设置了一个合适的较小的learning rate,这个问题发生的情况其实也不会太频繁。
Leaky ReLUs: 就是用来解决这个 “dying ReLU” 的问题的。与 ReLU 不同的是:
这里的 α 是一个很小的常数。这样,即修正了数据分布,又保留了一些负轴的值,使得负轴信息不会全部丢失。
关于Leaky ReLU 的效果,众说纷纭,没有清晰的定论。有些人做了实验发现 Leaky ReLU 表现的很好;有些实验则证明并不是这样。
Parametric ReLU: 对于 Leaky ReLU 中的 α ,通常都是通过先验知识人工赋值的。
然而可以观察到,损失函数对 α 的导数我们是可以求得的,可不可以将它作为一个参数进行训练呢?
Kaiming He的论文《Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification》指出,不仅可以训练,而且效果更好。
公式非常简单,反向传播至未激活前的神经元的公式就不写了,很容易就能得到。对 α 的导数如下:
原文说使用了Parametric ReLU后,最终效果比不用提高了1.03%.
Randomized ReLU:
Randomized Leaky ReLU 是 leaky ReLU 的random 版本 ( α 是random的).
它首次试在 kaggle 的NDSB 比赛中被提出的。
核心思想就是,在训练过程中, α 是从一个高斯分布 U(l,u) 中 随机出来的,然后再测试过程中进行修正(有点像dropout的用法)。
数学表示如下:
在测试阶段,把训练过程中所有的 αij 取个平均值。NDSB 冠军的 α 是从 U(3,8) 中随机出来的。那么,在测试阶段,激活函数就是就是:
看看 cifar-100 中的实验结果:
Maxout出现在ICML2013上,作者Goodfellow将maxout和dropout结合后,号称在MNIST, CIFAR-10, CIFAR-100, SVHN这4个数据上都取得了start-of-art的识别率。
Maxout 公式如下:
假设 w 是2维,那么有:
可以注意到,ReLU 和 Leaky ReLU 都是它的一个变形(比如, w1,b1=0 的时候,就是 ReLU).
Maxout的拟合能力是非常强的,它可以拟合任意的的凸函数。作者从数学的角度上也证明了这个结论,即只需2个maxout节点就可以拟合任意的凸函数了(相减),前提是”隐隐含层”节点的个数可以任意多.
所以,Maxout 具有 ReLU 的优点(如:计算简单,不会 saturation),同时又没有 ReLU 的一些缺点 (如:容易 Go die)。不过呢,还是有一些缺点的嘛:就是把参数double了。
还有其他一些激活函数,请看下表:
怎么选择激活函数呢?
我觉得这种问题不可能有定论的吧,只能说是个人建议。
如果你使用 ReLU,那么一定要小心设置 learning rate,而且要注意不要让你的网络出现很多 “dead” 神经元,如果这个问题不好解决,那么可以试试 Leaky ReLU、PReLU 或者 Maxout.
友情提醒:最好不要用 sigmoid,你可以试试 tanh,不过可以预期它的效果会比不上 ReLU 和 Maxout.
还有,通常来说,很少会把各种激活函数串起来在一个网络中使用的。
[1]. http://www.faqs.org/faqs/ai-faq/neural-nets/part2/section-10.html
[2]. http://papers.nips.cc/paper/874-how-to-choose-an-activation-function.pdf
[3]. https://en.wikipedia.org/wiki/Activation_function
[4]. http://cs231n.github.io/neural-networks-1/
Please feel free to contract me if you have any questions.