神经网络中的激活函数
2017-09-05 10:56
357 查看
整理这个问题源自于一次面试。
我们使用神经网络来分割平面空间作为例子。
神经网络最简单的结构就是单输出的单层感知机,单层感知机只有输入层和输出层,分别代表了神经感受器和神经中枢。下图是一个只有2个输入单元和1个输出单元的简单单层感知机。图中x1、w2代表神经网络的输入神经元受到的刺激,w1、w2代表输入神经元和输出神经元间连接的紧密程度,b代表输出神经元的兴奋阈值,y为输出神经元的输出。我们使用该单层感知机划出一条线将平面分割开,如图所示:
![](https://img-blog.csdn.net/20170905104001838?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamluYmVpYmVpMDYwNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
同理,我们也可以将多个感知机(注意,不是多层感知机)进行组合获得更强的平面分类能力,如图所示:
![](https://img-blog.csdn.net/20170905104025770?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamluYmVpYmVpMDYwNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
再看看包含一个隐层的多层感知机的情况,如图所示:
![](https://img-blog.csdn.net/20170905104049088?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamluYmVpYmVpMDYwNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
仔细看的话不难发现,上面三种没有激励函数的神经网络的输出是线性方程,其在用复杂的线性组合来逼近曲线。
我们在神经网络每一层神经元做完线性变换以后,加上一个非线性激励函数对线性变换的结果进行转换,那么输出就是一个不折不扣的非线性函数了,如图所示:
![](https://img-blog.csdn.net/20170905104226427?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamluYmVpYmVpMDYwNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
拓展到多层神经网络的情况, 更刚刚一样的结构, 加上非线性激励函数之后, 输出就变成了一个复杂的非线性函数了,如图所示:
![](https://img-blog.csdn.net/20170905104253570?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamluYmVpYmVpMDYwNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
加入非线性激励函数后,神经网络就有可能学习到平滑的曲线来分割平面,而不是用复杂的线性组合逼近平滑曲线来分割平面。 这就是为什么我们要有非线性的激活函数的原因。如下图所示说明加入非线性激活函数后的差异,上图为用线性组合逼近平滑曲线来分割平面,下图为平滑的曲线来分割平面:
![](https://img-blog.csdn.net/20170905104353850?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamluYmVpYmVpMDYwNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](https://img-blog.csdn.net/20170905104701323?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamluYmVpYmVpMDYwNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
Sigmoid 是常用的非线性的激活函数,它的数学形式如下:
![](https://img-blog.csdn.net/20170905104810040?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamluYmVpYmVpMDYwNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
正如前一节提到的,它能够把输入的连续实值“压缩”到0和1之间。
特别的,如果是非常大的负数
d202
,那么输出就是0;如果是非常大的正数,输出就是1.
sigmoid 函数曾经被使用的很多,不过近年来,用它的人越来越少了。主要是因为它的一些 缺点:
Sigmoids saturate and kill gradients. (saturate 这个词怎么翻译?饱和?)sigmoid 有一个非常致命的缺点,当输入非常大或者非常小的时候(saturation),这些神经元的梯度是接近于0的,从图中可以看出梯度的趋势。所以,你需要尤其注意参数的初始值来尽量避免saturation的情况。如果你的初始值很大的话,大部分神经元可能都会处在saturation的状态而把gradient kill掉,这会导致网络变的很难学习。
Sigmoid 的 output 不是0均值. 这是不可取的,因为这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。
当然了,如果你是按batch去训练,那么那个batch可能得到不同的信号,所以这个问题还是可以缓解一下的。因此,非0均值这个问题虽然会产生一些不好的影响,不过跟上面提到的 kill gradients 问题相比还是要好很多的。
Sigmoids saturate and kill gradients. (saturate 这个词怎么翻译?饱和?)sigmoid 有一个非常致命的缺点,当输入非常大或者非常小的时候(saturation),这些神经元的梯度是接近于0的,从图中可以看出梯度的趋势。所以,你需要尤其注意参数的初始值来尽量避免saturation的情况。如果你的初始值很大的话,大部分神经元可能都会处在saturation的状态而把gradient kill掉,这会导致网络变的很难学习。
Sigmoid 的 output 不是0均值. 这是不可取的,因为这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。
产生的一个结果就是:如果数据进入神经元的时候是正的(e.g. x>0 elementwise in f=wTx+b),那么 w 计算出的梯度也会始终都是正的。
当然了,如果你是按batch去训练,那么那个batch可能得到不同的信号,所以这个问题还是可以缓解一下的。因此,非0均值这个问题虽然会产生一些不好的影响,不过跟上面提到的 kill gradients 问题相比还是要好很多的。
tanh
tanh 是上图中的右图,可以看出,tanh 跟sigmoid还是很像的,实际上,tanh 是sigmoid的变形:
tanh(x)=2sigmoid(2x)−1
与 sigmoid 不同的是,tanh 是0均值的。因此,实际应用中,tanh 会比 sigmoid 更好(毕竟去粗取精了嘛)。
![](https://img-blog.csdn.net/20170905105051801?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamluYmVpYmVpMDYwNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
ReLU
近年来,ReLU 变的越来越受欢迎。它的数学表达式如下:
f(x)=max(0,x)
很显然,从图左可以看出,输入信号<0时,输出都是0,>0 的情况下,输出等于输入。w 是二维的情况下,使用ReLU之后的效果如下:
ReLU 的优点:
ReLU 的缺点: 当然 ReLU 也有缺点,就是训练的时候很”脆弱”,很容易就”die”了. 什么意思呢?
如果这个情况发生了,那么这个神经元的梯度就永远都会是0.
实际操作中,如果你的learning rate 很大,那么很有可能你网络中的40%的神经元都”dead”了。
当然,如果你设置了一个合适的较小的learning rate,这个问题发生的情况其实也不会太频繁。
Leaky-ReLU、P-ReLU、R-ReLU
Leaky ReLUs: 就是用来解决这个 “dying ReLU” 的问题的。与 ReLU 不同的是:
f(x)=αx,(x<0)
f(x)=x,(x>=0)
这里的 α 是一个很小的常数。这样,即修正了数据分布,又保留了一些负轴的值,使得负轴信息不会全部丢失。
![](https://img-blog.csdn.net/20170905105220580?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamluYmVpYmVpMDYwNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
关于Leaky ReLU 的效果,众说纷纭,没有清晰的定论。有些人做了实验发现 Leaky ReLU 表现的很好;有些实验则证明并不是这样。
还有一些常见的如maxout等。
如果你使用 ReLU,那么一定要小心设置 learning rate,而且要注意不要让你的网络出现很多 “dead” 神经元,如果这个问题不好解决,那么可以试试 Leaky ReLU、PReLU 或者 Maxout.
友情提醒:最好不要用 sigmoid,你可以试试 tanh,不过可以预期它的效果会比不上 ReLU 和 Maxout.
还有,通常来说,很少会把各种激活函数串起来在一个网络中使用的。
reference
[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/
转自:http://blog.csdn.net/u010002387/article/details/52797287
1.激活函数有哪些性质?为什么要用激活函数 ?
关于神经网络激励函数的作用,常听到的解释是:不使用激励函数的话,神经网络的每层都只是做线性变换,多层输入叠加后也还是线性变换。因为线性模型的表达能力不够,激励函数可以引入非线性因素。 其实很多时候我们更想直观的了解激励函数的是如何引入非线性因素的。我们使用神经网络来分割平面空间作为例子。
神经网络最简单的结构就是单输出的单层感知机,单层感知机只有输入层和输出层,分别代表了神经感受器和神经中枢。下图是一个只有2个输入单元和1个输出单元的简单单层感知机。图中x1、w2代表神经网络的输入神经元受到的刺激,w1、w2代表输入神经元和输出神经元间连接的紧密程度,b代表输出神经元的兴奋阈值,y为输出神经元的输出。我们使用该单层感知机划出一条线将平面分割开,如图所示:
同理,我们也可以将多个感知机(注意,不是多层感知机)进行组合获得更强的平面分类能力,如图所示:
再看看包含一个隐层的多层感知机的情况,如图所示:
仔细看的话不难发现,上面三种没有激励函数的神经网络的输出是线性方程,其在用复杂的线性组合来逼近曲线。
我们在神经网络每一层神经元做完线性变换以后,加上一个非线性激励函数对线性变换的结果进行转换,那么输出就是一个不折不扣的非线性函数了,如图所示:
拓展到多层神经网络的情况, 更刚刚一样的结构, 加上非线性激励函数之后, 输出就变成了一个复杂的非线性函数了,如图所示:
加入非线性激励函数后,神经网络就有可能学习到平滑的曲线来分割平面,而不是用复杂的线性组合逼近平滑曲线来分割平面。 这就是为什么我们要有非线性的激活函数的原因。如下图所示说明加入非线性激活函数后的差异,上图为用线性组合逼近平滑曲线来分割平面,下图为平滑的曲线来分割平面:
激活函数的性质: 非线性: 可微性: 单调性:
2.常见的激活函数有哪几种?
Sigmoid:Sigmoid 是常用的非线性的激活函数,它的数学形式如下:
正如前一节提到的,它能够把输入的连续实值“压缩”到0和1之间。
特别的,如果是非常大的负数
d202
,那么输出就是0;如果是非常大的正数,输出就是1.
sigmoid 函数曾经被使用的很多,不过近年来,用它的人越来越少了。主要是因为它的一些 缺点:
Sigmoids saturate and kill gradients. (saturate 这个词怎么翻译?饱和?)sigmoid 有一个非常致命的缺点,当输入非常大或者非常小的时候(saturation),这些神经元的梯度是接近于0的,从图中可以看出梯度的趋势。所以,你需要尤其注意参数的初始值来尽量避免saturation的情况。如果你的初始值很大的话,大部分神经元可能都会处在saturation的状态而把gradient kill掉,这会导致网络变的很难学习。
Sigmoid 的 output 不是0均值. 这是不可取的,因为这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。
当然了,如果你是按batch去训练,那么那个batch可能得到不同的信号,所以这个问题还是可以缓解一下的。因此,非0均值这个问题虽然会产生一些不好的影响,不过跟上面提到的 kill gradients 问题相比还是要好很多的。
Sigmoids saturate and kill gradients. (saturate 这个词怎么翻译?饱和?)sigmoid 有一个非常致命的缺点,当输入非常大或者非常小的时候(saturation),这些神经元的梯度是接近于0的,从图中可以看出梯度的趋势。所以,你需要尤其注意参数的初始值来尽量避免saturation的情况。如果你的初始值很大的话,大部分神经元可能都会处在saturation的状态而把gradient kill掉,这会导致网络变的很难学习。
Sigmoid 的 output 不是0均值. 这是不可取的,因为这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。
产生的一个结果就是:如果数据进入神经元的时候是正的(e.g. x>0 elementwise in f=wTx+b),那么 w 计算出的梯度也会始终都是正的。
当然了,如果你是按batch去训练,那么那个batch可能得到不同的信号,所以这个问题还是可以缓解一下的。因此,非0均值这个问题虽然会产生一些不好的影响,不过跟上面提到的 kill gradients 问题相比还是要好很多的。
tanh
tanh 是上图中的右图,可以看出,tanh 跟sigmoid还是很像的,实际上,tanh 是sigmoid的变形:
tanh(x)=2sigmoid(2x)−1
与 sigmoid 不同的是,tanh 是0均值的。因此,实际应用中,tanh 会比 sigmoid 更好(毕竟去粗取精了嘛)。
ReLU
近年来,ReLU 变的越来越受欢迎。它的数学表达式如下:
f(x)=max(0,x)
很显然,从图左可以看出,输入信号<0时,输出都是0,>0 的情况下,输出等于输入。w 是二维的情况下,使用ReLU之后的效果如下:
ReLU 的优点:
Krizhevsky et al. 发现使用 ReLU 得到的SGD的收敛速度会比 sigmoid/tanh 快很多(看右图)。有人说这是因为它是linear,而且 non-saturating 相比于 sigmoid/tanh,ReLU 只需要一个阈值就可以得到激活值,而不用去算一大堆复杂的运算。
ReLU 的缺点: 当然 ReLU 也有缺点,就是训练的时候很”脆弱”,很容易就”die”了. 什么意思呢?
举个例子:一个非常大的梯度流过一个 ReLU 神经元,更新过参数之后,这个神经元再也不会对任何数据有激活现象了。
如果这个情况发生了,那么这个神经元的梯度就永远都会是0.
实际操作中,如果你的learning rate 很大,那么很有可能你网络中的40%的神经元都”dead”了。
当然,如果你设置了一个合适的较小的learning rate,这个问题发生的情况其实也不会太频繁。
Leaky-ReLU、P-ReLU、R-ReLU
Leaky ReLUs: 就是用来解决这个 “dying ReLU” 的问题的。与 ReLU 不同的是:
f(x)=αx,(x<0)
f(x)=x,(x>=0)
这里的 α 是一个很小的常数。这样,即修正了数据分布,又保留了一些负轴的值,使得负轴信息不会全部丢失。
关于Leaky ReLU 的效果,众说纷纭,没有清晰的定论。有些人做了实验发现 Leaky ReLU 表现的很好;有些实验则证明并不是这样。
还有一些常见的如maxout等。
3.怎么选择激活函数
我觉得这种问题不可能有定论的吧,只能说是个人建议。如果你使用 ReLU,那么一定要小心设置 learning rate,而且要注意不要让你的网络出现很多 “dead” 神经元,如果这个问题不好解决,那么可以试试 Leaky ReLU、PReLU 或者 Maxout.
友情提醒:最好不要用 sigmoid,你可以试试 tanh,不过可以预期它的效果会比不上 ReLU 和 Maxout.
还有,通常来说,很少会把各种激活函数串起来在一个网络中使用的。
reference
[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/
相关文章推荐
- 神经网络常用激活函数对比:sigmoid VS sofmax(附python源码)
- 深度学习/神经神经网络常用激活函数总结
- python绘制神经网络中的Sigmoid和Tanh激活函数图像(附代码)
- 神经网络中的激活函数(activation function)-Sigmoid, ReLu, TanHyperbolic(tanh), softmax, softplus
- 神经网络中的激活函数-Sigmoid, ReLu, TanHyperbolic(tanh), softmax, softplus简述
- 神经网络之激活函数(Activation Function)
- 神经网络的激活函数
- 机器学习-神经网络之激活函数(Activation Function)
- 【机器学习】神经网络-激活函数-面面观(Activation Function)
- 神经网络之激活函数(Activation Function)
- Tensorflow中神经网络的激活函数
- 神经网络中的激活函数
- 【机器学习】神经网络-激活函数-面面观(Activation Function) (Sigmoid Relu tanh)
- 深度神经网络及TensorFlow实现1-激活函数(Activation Function)2
- 深度学习神经网络激活函数的优点
- 神经网络之激活函数(Activation Function)
- 神经网络中激活函数比较
- 神经网络之激活函数面面观
- 神经网络-激活函数-Activation
- 神经网络激活函数