本文主要是介绍深度学习-激活函数:饱和激活函数【Sigmoid、tanh】、非饱和激活函数【ReLU、Leaky ReLU、RReLU、PReLU、ELU、Maxout】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
深度学习-激活函数:饱和激活函数【Sigmoid、tanh】、非饱和激活函数【ReLU、Leaky ReLU、RReLU、PReLU、ELU、Maxout】
- 一、激活函数的定义:
- 二、激活函数的用途
- 1、无激活函数的神经网络
- 2、带激活函数的神经网络
- 三、饱和激活函数与非饱和激活函数
- 1、饱和激活函数
- 2、非饱和激活函数
- 四、激活函数的种类
- 1、Sigmoid函数
- 2、TanH函数
- 3、ReLU(Rectified Linear Units)
- 4、ELU (Exponential Linear Units) 函数
- 5、LReLU(Leaky ReLU)、PReLU(Parameteric ReLU)
- 5.1 LReLU(Leaky ReLU)
- 5.2 PReLU(Parameteric ReLU)
- 6、RReLU
- 7、MaxOut函数
- 五、激活函数的选择
一、激活函数的定义:
- 激活函数(activation function)运行时激活神经网络中某一部分神经元,将激活信息向后传入下一层的神经网络。神经网络之所以能解决非线性问题,本质上就是激活函数加入了非线性因素,弥补了线性模型的表达力,把“激活的神经元的特征”通过函数保留并映射到下一层。
- 激活函数不会更改输入数据的维度,也就是输入和输出的维度是相同的。
- 在计算网络中, 一个节点的激活函数(Activation Function)定义了该节点在给定的输入或输入的集合下的输出。
- 激活函数:神经网络中的每个神经元节点接受上一层神经元的输出值作为本神经元的输入值,并将输入值传递给下一层,输入层神经元节点会将输入属性值直接传递给下一层(隐层或输出层)。在多层神经网络中,上层节点的输出和下层节点的输入之间具有一个函数关系,这个函数称为激活函数(又称激励函数)。
二、激活函数的用途
如果不用激励函数(其实相当于激励函数是 f ( x ) = x f(x) = x f(x)=x),在这种情况下你每一层节点的输入都是上层输出的线性函数,很容易验证,无论你神经网络有多少层,输出都是输入的线性组合,与没有隐藏层效果相当,这种情况就是最原始的感知机(Perceptron)了,那么网络的逼近能力就相当有限。正因为上面的原因,我们决定引入非线性函数作为激励函数,这样深层神经网络表达能力就更加强大(不再是输入的线性组合,而是几乎可以逼近任意函数)。
为了解释激活函数如何引入非线性因素,接下来让我们以神经网络分割平面空间作为例子。
1、无激活函数的神经网络
神经网络最简单的结构就是单输出的单层感知机,单层感知机只有输入层和输出层,分别代表了神经感受器和神经中枢。
下图是一个只有2个输入单元和1个输出单元的简单单层感知机。
- x 1 x_1 x1、 w 2 w_2 w2 代表神经网络的输入神经元受到的刺激,
- w 1 w_1 w1、 w 2 w_2 w2 代表输入神经元和输出神经元间连接的紧密程度,
- b b b 代表输出神经元的兴奋阈值, y y y 为输出神经元的输出。
- 我们使用该单层感知机划出一条线将平面分割开,如图所示:
同理,我们也可以将多个感知机(注意,不是多层感知机)进行组合获得更强的平面分类能力,如图所示:
再看看包含一个隐层的多层感知机的情况,如图所示:
通过对比可以发现,上面三种没有激励函数的神经网络的输出是都线性方程,其都是在用复杂的线性组合来试图逼近曲线。
2、带激活函数的神经网络
让我们在神经网络每一层神经元做完线性变换以后,加上一个非线性激励函数对线性变换的结果进行转换,结果显而易见,输出立马变成一个不折不扣的非线性函数了,如图所示:
拓展到多层神经网络的情况, 和刚刚一样的结构, 加上非线性激励函数之后, 输出就变成了一个复杂的非线性函数了,如图所示:
总结:加入非线性激励函数后,神经网络就有可能学习到平滑的曲线来分割平面,而不是用复杂的线性组合逼近平滑曲线来分割平面,使神经网络的表示能力更强了,能够更好的拟合目标函数。 这就是为什么我们要有非线性的激活函数的原因。如下图所示说明加入非线性激活函数后的差异,上图为用线性组合逼近平滑曲线来分割平面,下图为平滑的曲线来分割平面:
激活函数的作用除了前面说的增加模型的非线性分割能力外,还有
- 提高模型鲁棒性:可以拟合各种不同情形中的数据
- 缓解梯度消失问题
- 加速模型收敛等
三、饱和激活函数与非饱和激活函数
1、饱和激活函数
假设 h ( x ) h(x) h(x) 是一个激活函数
1、当 n n n 趋近于负无穷时,激活函数的导数趋近于0,则该激活函数为左饱和。
lim n → + ∞ h ′ ( x ) = 0 \lim_{n \rightarrow +∞}h'(x)=0 n→+∞limh′(x)=0
2、当 n n n 趋近于正无穷时,激活函数的导数趋近于0,则该激活函数为右饱和。
lim n → + ∞ h ′ ( x ) = 0 \lim_{n \rightarrow +∞}h'(x)=0 n→+∞limh′(x)=0
当一个函数既满足左饱和、又满足右饱,则称之为饱和函数。典型的饱和函数有Sigmoid,Tanh函数。
2、非饱和激活函数
不满足饱和函数条件的函数则称为非饱和激活函数。
ReLU及其变体则是“非饱和激活函数”。
使用“非饱和激活函数”的优势在于两点:
- "非饱和激活函数”能解决所谓的“梯度消失”问题。
- 它能加快收敛速度。
四、激活函数的种类
- 早期研究神经网络主要采用sigmoid函数或者tanh函数,输出有界,很容易充当下一层的输入。
- 近些年Relu函数及其改进型(如Leaky-ReLU、P-ReLU、R-ReLU等)在多层神经网络中应用比较多。下面我们来总结下这些激活函数:
1、Sigmoid函数
Sigmoid函数曾被广泛地应用,但由于其自身的一些缺陷,现在很少被使用了。Sigmoid函数被定义为:
σ = 1 1 + e − x \begin{aligned} σ=\frac{1}{1+e^{-x}} \end{aligned} σ=1+e−x1
函数对应的图像是:
优点:
- Sigmoid函数的输出映射在(0,1)之间,单调连续,输出范围有限,优化稳定,可以用作输出层。
- 求导容易。 σ ′ = σ ( 1 − σ ) σ'=σ(1-σ) σ′=σ(1−σ)
- Sigmoid函数的导数在0处取得最大值1/4。
sigmoid函数曾经被使用的很多,不过近年来,用它的人越来越少了。主要是因为它固有的一些缺点。
缺点:
- 其输出并不是以0为中心的。
- 由于其软饱和性,容易产生梯度消失,导致训练出现问题。
- sigmoid函数在取值很大或很小的时候,导数非常小,会导致参数的更新速度很慢。
- 在深度神经网络中梯度反向传递时导致梯度爆炸和梯度消失,其中梯度爆炸发生的概率非常小,而梯度消失发生的概率比较大。
- 如果我们初始化神经网络的权值为 [ 0 , 1 ] [0,1] [0,1] 之间的随机值,比如 0.25,由反向传播算法的数学推导可知,梯度从后向前传播时,每传递一层梯度值都会减小为原来的0.25倍,如果神经网络隐层特别多,那么梯度在穿过多层后将变得非常小接近于0,即出现梯度消失现象;当网络权值初始化为 ( 1 , + ∞ ) (1,+∞) (1,+∞) 区间内的值,则会出现梯度爆炸情况。
- Sigmoid 的 output 不是0均值(即zero-centered)。这是不可取的,因为这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。 产生的一个结果就是:如果 x > 0 , f = w T x + b x>0,f=w^Tx+b x>0,f=wTx+b,那么对 w w w 求局部梯度则都为正,这样在反向传播的过程中 w w w 要么都往正方向更新,要么都往负方向更新,导致有一种捆绑的效果,使得收敛缓慢。 当然了,如果按batch去训练,那么那个batch可能得到不同的信号,所以这个问题还是可以缓解一下的。因此,非0均值这个问题虽然会产生一些不好的影响,不过跟上面提到的梯度消失问题相比还是要好很多的。
- 其解析式中含有幂运算,计算机求解时相对来讲比较耗时。对于规模比较大的深度网络,这会较大地增加训练时间。
由于使用sigmoid激活函数会造成神经网络的梯度消失和梯度爆炸问题,所以许多人提出了一些改进的激活函数,如:tanh、ReLU、Leaky ReLU、PReLU、RReLU、ELU、Maxout。
2、TanH函数
现在,比起Sigmoid函数我们通常更倾向于tanh函数。tanh函数被定义为:
t a n h ( x ) = e x − e − x e x + e − x tanh(x)=\cfrac{e^x-e^{-x}}{e^x+e^{-x}} tanh(x)=ex+e−xex−e−x
函数位于 [ − 1 , 1 ] [-1, 1] [−1,1] 区间上,对应的图像是:
TanH函数与Sigmoid函数的关系
优点:
- 比Sigmoid函数收敛速度更快。
- 相比Sigmoid函数,其输出以0为中心。
- 它解决了Sigmoid函数的不是zero-centered输出问题,然而,梯度消失(gradient vanishing)的问题和幂运算的问题仍然存在。
- 求导容易。 t a n h ′ = 1 − t a n h 2 ( x ) tanh'=1-tanh^2(x) tanh′=1−tanh2(x)
缺点:还是没有改变Sigmoid函数的最大问题——由于饱和性产生的梯度消失。
TanH激活函数在RNN中用的比较多。
3、ReLU(Rectified Linear Units)
ReLU是最近几年非常受欢迎的激活函数。被定义为
f ( x ) = { 0 f o r x < 0 x f o r x ≥ 0 f(x)=\begin{cases}0 \quad for \quad x<0\\x \quad for \quad x≥0\end{cases} f(x)={0forx<0xforx≥0
对应的图像是:
ReLU函数其实就是一个取最大值函数,注意这并不是全区间可导的,但是我们可以取sub-gradient,如上图所示。ReLU虽然简单,但却是近几年的重要成果,有以下几大优点:
优点:
- 相比起Sigmoid和tanh,ReLU(e.g. a factor of 6 in Krizhevsky et al.)在SGD中能够快速收敛。例如在下图的实验中,在一个四层的卷积神经网络中,实线代表了ReLU,虚线代表了tanh,ReLU比起tanh更快地到达了错误率0.25处。据称,这是因为它线性、非饱和的形式。
- Sigmoid和tanh涉及了很多很expensive的操作(比如指数),ReLU可以更加简单的实现。
- 由于当 x > 0 x>0 x>0 时的梯度值一直为1,有效缓解了梯度弥散、梯度爆炸的问题。
- 在没有无监督预训练的时候也能有较好的表现。
- 提供了神经网络的稀疏表达能力(Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生)。
缺点:
- 随着训练的进行,可能会出现神经元死亡,权重无法更新的情况。如果发生这种情况,那么流经神经元的梯度从这一点开始将永远是0。也就是说,ReLU神经元在训练中不可逆地死亡了。
- Dead ReLU Problem,指的是某些神经元可能永远不会被激活,导致相应的参数永远不能被更新。有两个主要原因可能导致这种情况产生:
- 非常不幸的参数初始化,这种情况比较少见
- learning rate太高导致在训练过程中参数更新太大,不幸使网络进入这种状态。解决方法是可以采用Xavier初始化方法,以及避免将learning rate设置太大或使用Adagrad等自动调节learning rate的算法。
4、ELU (Exponential Linear Units) 函数
f ( x ) = { x i f x > 0 α ( e x − 1 ) o t h e r w i s e f(x)=\begin{cases}x \quad if\ x>0\\α(e^x-1) \quad otherwise\end{cases} f(x)={xif x>0α(ex−1)otherwise
函数及其导数的图像如下图所示:
ELU也是为解决ReLU存在的问题而提出,显然,ELU有ReLU的基本所有优点,以及:
- 不会有Dead ReLU问题、
- 输出的均值接近0,zero-centered
它的一个小问题在于计算量稍大。类似于Leaky ReLU,理论上虽然好于ReLU,但在实际使用中目前并没有好的证据ELU总是优于ReLU。
5、LReLU(Leaky ReLU)、PReLU(Parameteric ReLU)
- 通常在LReLU和PReLU中,我们定义一个激活函数为
f ( x ) = { α i x i f o r x i ≤ 0 x i f o r x i > 0 f(x)=\begin{cases}α_ix_i \quad for \quad x_i≤0\\x_i \quad for \quad x_i>0\end{cases} f(x)={αixiforxi≤0xiforxi>0
5.1 LReLU(Leaky ReLU)
- 当 α i α_i αi 比较小而且固定的时候,我们称之为LReLU。 i i i 表示不同的通道。
- LReLU最初的目的是为了避免梯度消失。但在一些实验中,我们发现LReLU对准确率并没有太大的影响。很多时候,当我们想要应用LReLU时,我们必须要非常小心谨慎地重复训练,选取出合适的 α α α,LReLU的表现出的结果才比ReLU好。因此有人提出了一种自适应地从数据中学习参数的PReLU。
5.2 PReLU(Parameteric ReLU)
- PReLU是LReLU的改进,可以自适应地从数据中学习参数。PReLU具有收敛速度快、错误率低的特点。PReLU可以用于反向传播的训练,可以与其他层同时优化。
- 其中 α i α_i αi 是可以学习的的。如果 α i α_i αi =0,那么 PReLU 退化为ReLU;如果 α i α_i αi 是一个很小的固定值(如ai=0.01),则 PReLU 退化为 Leaky ReLU(LReLU)。
- PReLU 只增加了极少量的参数,也就意味着网络的计算量以及过拟合的危险性都只增加了一点点。特别的,当不同 channels 使用相同的 α i α_i αi 时,参数就更少了。BP 更新 α i α_i αi 时,采用的是带动量的更新方式(momentum)。
- 值得一提的是,在tflearn中有现成的LReLU和PReLU可以直接用。
6、RReLU
- RReLU也是Leaky ReLU的一个变体。在RReLU中,负值的斜率在训练中是随机的,在之后的测试中就变成了固定的了。RReLU的亮点在于,在训练环节中, a j i a_{ji} aji 是从一个均匀的分布U(I,u)中随机抽取的数值。形式上来说,我们能得到以下结果:
f ( x ) = { α j i x j i f o r x j i < 0 w h e r e α j i ∈ U ( l , u ) , l < u , l , u ∈ [ 0 , 1 ) x j i f o r x j i > 0 f(x)=\begin{cases}α_{ji}x_{ji} \quad for \quad x_{ji}<0 \quad where \quad α_{ji}∈U(l,u),l<u,l,u∈[0,1)\\x_{ji} \quad for \quad x_{ji}>0\end{cases} f(x)={αjixjiforxji<0whereαji∈U(l,u),l<u,l,u∈[0,1)xjiforxji>0
7、MaxOut函数
- Maxout是深度学习网络中的一层网络,就像池化层、卷积层一样等,我们可以把maxout 看成是网络的激活函数层,我们假设网络某一层的输入特征向量为: X = ( x 1 , x 2 , … … x d ) X=(x_1,x_2,……x_d) X=(x1,x2,……xd),也就是我们输入是 d d d 个神经元。Maxout隐藏层每个神经元的计算公式如下:
h i ( x ) = max j ∈ [ 1 , k ] z i j h_i(x)=\max_{j∈[1,k]}z_{ij} hi(x)=j∈[1,k]maxzij - 上面的公式就是maxout隐藏层神经元 i i i 的计算公式。其中, k k k 就是maxout层所需要的参数的数量了,由我们人为设定大小。就像dropout一样,也有自己的参数 p p p(每个神经元dropout概率),maxout的参数是 k k k。公式中 Z Z Z 的计算公式为:
z i j = x T w . . . i j + b i j z_{ij}=x^Tw_{...ij}+b_{ij} zij=xTw...ij+bij - 权重 w w w 是一个大小为 ( d , m , k ) (d,m,k) (d,m,k) 三维矩阵, b b b 是一个大小为 ( m , k ) (m,k) (m,k) 的二维矩阵,这两个就是我们需要学习的参数。如果我们设定参数 k = 1 k=1 k=1,那么这个时候,网络就类似于以前我们所学普通的MLP网络。
- 我们可以这么理解,本来传统的MLP算法在第 i i i 层到第 i + 1 i+1 i+1 层,参数只有一组,然而现在我们不这么干了,我们在这一层同时训练 n n n 组的 w w w、 b b b 参数,然后选择激活值 Z Z Z 最大的作为下一层神经元的激活值,这个 m a x ( z ) max(z) max(z) 函数即充当了激活函数。
五、激活函数的选择
- 这个问题目前没有确定的方法,凭一些经验吧。
- 深度学习往往需要大量时间来处理大量数据,模型的收敛速度是尤为重要的。所以,总体上来讲,训练深度学习网络尽量使用zero-centered数据 (可以经过数据预处理实现) 和zero-centered输出。所以要尽量选择输出具有zero-centered特点的激活函数以加快模型的收敛速度。
- 如果使用 ReLU,那么一定要小心设置 learning rate,而且要注意不要让网络出现很多 “dead” 神经元,如果这个问题不好解决,那么可以试试 Leaky ReLU、PReLU 或者 Maxout.
- 当输入数据特征相差明显时,用 tanh 的效果会很好,且在循环过程中会不断扩大特征效果并显示出来。
- 当特征相差不明显时, sigmoid 效果比较好。同时,用 sigmoid 和 tanh 作为激活函数时,需要对输入进行规范化,否则激活后的值全部都进入平坦区,隐层的输出会全部趋同,丧失原有的特征表达。
- ReLU会好很多,有时可以不需要输入规范化来避免上述情况。因此,现在大部分的卷积神经网络都采用ReLU作为激活函数。
参考资料:
深度学习中几种常见的激活函数理解与总结
[常用激活函数(激励函数)理解与总结])(https://blog.csdn.net/tyhj_sf/article/details/79932893)
深度学习(七)梯度弥散(消散)和梯度爆炸
这篇关于深度学习-激活函数:饱和激活函数【Sigmoid、tanh】、非饱和激活函数【ReLU、Leaky ReLU、RReLU、PReLU、ELU、Maxout】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!