结合pytorch中的激活函数,来总结一下深度学习中的激活函数
一、激活函数的概念和作用
概念:在神经网络中每个神经元节点接受上一层神经元的输出作为本神经元的输入,并将输出值传入到下一层,输入层神经元节点会将输入属性值直接传递给下一层(隐藏层或输出层)。在多层神经网络中,上层节点的输出和下层节点的输入之间具有一个函数关系,这个函数称为激活函数(又称激励函数)。
对激活函数的理解:不使用激活函数的话,神经网络的每层都只是做线性变换,多层叠加后还是线性变换。因为线性模型的表达能力通常不够,所以引入激活函数,加入非线性因素,来增强模型的表达能力。
Q:激活函数是如何引进非线性因素的? A: 1、没有激活函数的神经网络 神经网络中最简单的结构是单层输出的感知机,单层的感知机只有输入层和输出层。下图是一个只有2个输入单元和1个输出单元的简单单层感知机。图中x1、w2代表神经网络的输入神经元受到的刺激,w1、w2代表输入神经元和输出神经元间连接的紧密程度,b代表输出神经元的兴奋阈值,y为输出神经元的输出。我们使用该单层感知机划出一条线将平面分割开,如图所示: 同理,也可以将多个感知机组合,获得更强的平面分类能力 再看一个包含隐藏层的感知机: 上面三种没有激活函数的神经网络的输出都是线性方程的,其实都是在用复杂的线性组合来逼近曲线。 2、带激活函数的神经网络 在神经网络每一层神经元做完线性变换以后,加上一个非线性激励函数对线性变换的结果进行转换,结果显而易见,输出是一个非线性函数了,如图所示: 拓展到多层神经网络的情况, 和刚刚一样的结构, 加上非线性激励函数之后, 输出就变成了一个复杂的非线性函数了,如图所示: 总结:加入非线性激励函数后,神经网络就有可能学习到平滑的曲线来分割平面,而不是用复杂的线性组合逼近平滑曲线来分割平面,使神经网络的表示能力更强了,能够更好的拟合目标函数。 这就是为什么要有非线性的激活函数的原因。如下图所示说明加入非线性激活函数后的差异,上图为用线性组合逼近平滑曲线来分割平面,下图为平滑的曲线来分割平面:
二、几种激活函数的对比
什么是饱和的激活函数: 假设h(x)是一个激活函数 1、当n趋近于正无穷时,激活函数的导数趋近于0,则称之为右饱和 2、当n趋近于负无穷时,激活函数的导数趋近于0,则称之为左饱和 当一个函数既满足左饱和,又满足右饱和时,则称之为饱和函数,典型的函数有Sigmoid,Tanh函数,反之,不满足以上条件的则称为非饱和激活函数。 sigmoid和tanh是饱和激活函数,而relu及其变体则是非饱和激活函数。使用非饱和激活函数的优势在于:1、非饱和激活函数能解决梯度消失问题;2、能加快收敛的速度
常见的几种激活函数:
1、Sigmoid激活函数
sigmoid激活函数,它将一个实数值压缩到0至1范围内,当我们最终的目标是预测概率时,它可以被应用到输出层,它使很大的复数向0转变,很大的正数向1转变。数学表示为: sigmoid函数图像及其导数图像 sigmoid函数的主要缺点: 1、梯度消失:sigmoid函数在0和1附近是平坦的。也就是说,sigmoid的梯度在0和1附近为0。在通过sigmoid函数网络反向传播时,当神经元的输出近似于0和1时它的梯度接近于0。这些神经元被称为饱和神经元。因此,这些神经元的权值无法更新。不仅如此,与这些神经元相连接的神经元的权值也更新得非常缓慢。这个问题也被称为梯度消失。所以,如果有一个大型网络包含有许多处于饱和动态sigmoid激活函数的神经元,那么网络将会无法进行反向传播; 2、不是0均值:sigmoid函数输出不是0均值的; 3、计算量太大:指数函数与其他非线性激活函数相比,计算量太大。
另外: Sigmoid函数和Softmax函数的区别: Sigmoid是将输出值映射到(0,1)之间,用来做二分类。而softmax是将一个k维的real value向量(a1,a2,…)映射成一个(b1,b2,…),其中bi是0~1的常数,输出的神经元之和为1,相当于概率值,然后可以根据bi概率值的大小来进行多分类任务。二分类时sigmoid和softmax是一样的,求的都是cross entropy loss,而softmax可以用于多分类问题,多个logistic回归通过叠加也同样可以实现多分类的效果,但是 softmax回归进行的多分类,类与类之间是互斥的,即一个输入只能被归为一类;多个logistic回归进行多分类,输出的类别并不是互斥的,即"苹果"这个词语既属于"水果"类也属于"3C"类别。
2、Tanh激活函数
tanh也称为双曲正切激活函数,tanh也是把实数值进行压缩,它将输出值压缩到-1到1之间,输出是0均值的,可以将tanh看作两个sigmoid加在一起的。 tanh与sigmoid不同的是,tanh输出是0均值的。因此实际应用中,tanh会比sigmoid好些,但是tanh也没有解决梯度消失问题。 优点:输出是0均值 缺点:存在梯度消失问题,指数函数计算量大
3、ReLu
Relu函数及其导数的函数图像如上图所示,Relu激活函数从底部进行了半矫正,数学表达式为: 这意味着,当输入z<0时,输出为0。当输入z>0时,输出就是输入z的值。这个激活函数能够使网络更快的收敛。没有饱和意味着至少在正数范围内,能够对梯度消失有抵抗能力,所以神经元至少在一半的输入范围内不会反向传播,全部都是0的结果。ReLU在计算上非常有效率,因为它是使用简单的阈值实现的。 优点: ● Relu解决了梯度消失问题,至少x在正区间内,神经元不会饱和; ● 由于ReLU线性、非饱和的形式,在SGD中能够快速收敛; ● 运算速度快,Relu只是线性关系,不需要指数运算,不管向前传播还是反向传播,速度要比sigmoid和tanh快。 缺点: ● Relu输出不是零均值; ● 随着训练的进行,会出现权值无法更新,神经元死亡的问题。
Q:神经网络中的relu函数是线性还是非线性函数? A:Relu是非线性函数。Relu虽然大于0的区间是线性的,小于0的区间也是线性的,但它整体不是线性的,因为不是一条直线,所以是非线性的。
4、Leaky Relu
为了解决relu激活函数在x<0时的梯度消失问题,引入Leaky Relu,数学表达式为: 函数图像为: Leaky relu的思想就是当x<0时,会有个很小0.1的正斜率,这是一个超参数,可调。这个函数多少消除了relu的消亡问题,但是它的结果并不一致。虽然它具有relu激活函数的所有特征,例如:计算效率高、收敛速度快、在正区域不饱和等。它的思想可以进一步的扩展。如用一个常数项代替乘以x,从而能够将这个常数项乘以一个能够使leaky relu更好工作的超参数。这个leaky relu的拓展被称为parametric relu(参数relu)。 优点: ● 神经元不会出现死亡问题; ● 对于所有的输入,不管是大于0还是小于等于0,神经元不会饱和; ● 由于Leaky Relu是线性的非饱和,在SGD中能够快速收敛; ● 计算速度快,由于只有线性计算,不需要指数运算,无论是正向传播还是反向传播,计算速度都要比sigmoid和tanh快。 缺点:Leaky ReLU函数中的α,需要通过先验知识人工赋值。
总结:Leaky ReLU很好的解决了“dead ReLU”的问题。因为Leaky ReLU保留了x小于0时的梯度,在x小于0时,不会出现神经元死亡的问题。对于Leaky ReLU给出了一个很小的负数梯度值α,这个值是很小的常数。比如:0.01。这样即修正了数据分布,又保留了一些负轴的值,使得负轴信息不会全部丢失。但是这个α通常是通过先验知识人工赋值的。
5、PRelu
RReLU的英文全称是“Randomized Leaky ReLU”,中文名字叫“随机修正线性单元”。RReLU是Leaky ReLU的随机版本。数学表达式及函数图像为: RReLU的核心思想是,在训练过程中,α是从一个高斯分布中随机出来的值,然后再在测试过程中进行修正。在测试阶段,取训练过程中所有值取个平均值。 特点: (1).RReLU是Leaky ReLU的random版本,在训练过程中,α是从一个高斯分布中随机出来的,然后再测试过程中进行修正。 (2).数学形式与PReLU类似,但RReLU是一种非确定性激活函数,其参数是随机的
Relu、Leaky Relu、PRelu 三种激活函数的比较 各自的图像为:
6、ELU
ELU的英文全称是“Exponential Linear Units”,中文全称是“指数线性单元”。它试图将激活函数的输出平均值接近零,从而加快学习速度。同时,它还能通过正值的标识来避免梯度消失的问题。根据一些研究显示,ELU分类精确度是高于ReLU的。数学表达式为; 优点: ● ELU包含了ReLU的所有优点。 ● 神经元不会出现死亡的情况。 ● ELU激活函数的输出均值是接近于零的。 缺点:计算的时候是需要计算指数的,计算效率低的问题。
7、SELU
经过该激活函数后使得样本分布自动归一化到0均值和单位方差(自归一化,保证训练过程中梯度不会爆炸或消失,效果比Batch Normalization 要好) 其实就是ELU乘了个lambda,关键在于这个lambda是大于1的。以前relu,prelu,elu这些激活函数,都是在负半轴坡度平缓,这样在activation的方差过大的时候可以让它减小,防止了梯度爆炸,但是正半轴坡度简单的设成了1。而selu的正半轴大于1,在方差过小的的时候可以让它增大,同时防止了梯度消失。这样激活函数就有一个不动点,网络深了以后每一层的输出都是均值为0方差为1。
三、如何选择激活函数
● 通常来说,不能把各种激活函数串起来在一个网络中使用。 ● 如果使用ReLU,那么一定要小心设置学习率(learning rate),并且要注意不要让网络中出现很多死亡神经元。如果死亡神经元过多的问题不好解决,可以试试Leaky ReLU、PReLU、或者Maxout。
|