美文网首页
激活函数

激活函数

作者: xieyan0811 | 来源:发表于2020-06-11 21:25 被阅读0次

为什么使用激活函数

如果没有激活函数,神经网络就变成了线性模型,输出是输入的线性组合,使用一层与使用多层没有区别。如下式所示,输入为x,经过线性层计算出a1,将a1输入下个线性层得到a2,展开后可以看出,最终得到的仍然是wx+b的线性组合,只是参数值不同。

图片.png

另外,线性层无法解决非线性问题,如在预测房价问题中,如果不使用激活函数,则房价可能计算成负值,这也与实际不符。理论上,加了激活函数后,模型可以逼近任意函数。

激活函数又分线性激活函数和非线性激活函数,一般使用的都是非线性激活函数,线性激活函数与线性层类似,只在输出层偶尔使用,不在此展开讨论。

何时使用激活函数

激活函数一般放置在线性变换之后,在线性变换和激活函数之间,常常插入归一化层,用于解决饱和的非线性激活函数问题(下面Sigmoid函数部分详细说明)。

如何选择激活函数

从一些当前流行的深度学习网络代码中,可以看到,当前使用的激活函数绝大部分是ReLU;在一些特殊情况下,也使用Sigmoid,比如二分类问题的最后一层使用Sigmoid将输出转换到0-1之间;又如使用注意力网络时,注意力加权需要使用0-1之间的权值时,也用到Sigmoid函数。作为一般的夹在线性层之间的普通激活函数,ReLU是默认选择。

常用激活函数

下面介绍常用激活函数的方法、原理、梯度计算、直观图示,以及使用中可能遇到的问题。

sigmoid激活函数

sigmoid是较早期的激活函数,它的输入是任意的x,输出在0-1之间,实现数据映射。

其公式如下:

其求导过程如下:

Python代码实现:

def sigmoid(x):  
    return 1. / (1 + np.exp(-x))

试想将值代入时,当x趋近正无穷,分母为1,计算结果为1;当x趋近负无穷,分母为无穷大,计算结果为0。当x为0时,分母为2,计算结果为0.5。

函数图示如下:

如图所示,映射过程中将值压缩到0-1之间,它对0附近的值比较敏感,其图形接近线性,而其它部分的数值在sigmoid后绝对值缩小很多。

梯度是x方向上变化引起的y方向的变化,在x值较大的情况下,x的变化对y影响很小,这就是所谓的“非线性激活函数的饱和”问题。在使用梯度下降法给网络调参时,接近0的梯度使学习的速度变得非常缓慢。这一现象在调试程序时尤为明显:大不把网络参数以及输入数据设置得比较小,且不使用归一化层的情况下,使用Sigmoid函数收敛得非常慢。

此外,sigmoid还包括幂运算,运算量也比较大,目前除了上述比较特殊的场景,已很少使用。

tanh激活函数

tanh激活函数可视为sigmoid函数的改进版本,其图示如下:

在数学上,tanh是sigmoid的平移,它把数据范围压缩到-1~1之间,均值为0。前人证明0均值的tanh激活函数效果更好。0均值同样可应用于其它场景提高模型效果。

其公式如下:

Python代码实现:

import numpy as np  
np.tanh(x)

尽管tanh略优于sigmoid,但它也有sigmoid同样的缺点:计算量大及饱和问题,目前也很少使用,另外,0均值也可通过归一化层实现。因此,只做简单介绍,不再展开。

ReLU激活函数

ReLU激活函数,原理,计算以及求导都非常简单:如果x大于0,则y=x,如果小于0,则y=0,其图示如下:

其公式如下:

其导数是:

需要注意的是,ReLU在0值不可微,但一般情况下,不会遇到太多的0值,因此将0值的梯度置为0或1都可以。

Python代码实现:

def relu(x):  
    return np.maximum(0,x)

ReLU非常简单,运算速度非常快,收敛也快,由于它没有压缩数据,因此,也避免了由激活函数引起的梯度问题。另外,处理结果不能为负(如房价不能为负,或者避免sum累积时正负抵消)的问题时,也可以在层后添加ReLU激活函数。

ReLU衍生的激活函数

虽然ReLU相对于之前算法表现优异,但也存在问题,试想当梯度大幅变化时,由于ReLU在大于0的情况下,不做处理直接向后传递,则可能造成之前线性层参数的大幅变化,因此,很可能产生大量小于0的数据输入ReLU。若ReLU的输入大多是负数,则会导致大部分梯度无法向后传递,从而引起“Dead ReLU”问题。其现象是由于某些特殊数据引发了无法继续收敛。

为解决这一问题,出现了一些ReLU变种,来处理小于0的数据,比如ELU,Leaky RELU。

ELU公式如下:

做图如下:

Python代码如下:

def elu(x,a):  
    y = []  
    for i in x:  
        if i<0:  
            i = a * (np.exp(i)-1)  
        y.append(i)  
    return y

它的均值趋近0,没有Dead ReLU的问题,但计算量略大。更简单一点的还有Leaky ReLU,如下图所示:

它对于0以下的部分乘一个较小的a值,一般是0.01。另外,引入归一化层也可解决Dead ReLU问题,因此,推荐以ReLU作为默认的激活函数。

相关文章

  • 激活函数softmax-P2分类任务

    激活函数种类激活函数作用 激活函数 深度学习常用激活函数之— Sigmoid & ReLU & Softmax 深...

  • 6.神经网络训练细节part1

    一、激活函数 前边我们学到,一个节点的输出会进入激活函数进行处理 常见的激活函数有以下 sigmoid激活函数 s...

  • tanh函数&logistic函数

    传统Sigmoid系激活函数 传统Sigmoid系激活函数 传统Sigmoid系激活函数,Sigmoid系(Log...

  • 机器学习之神经网络

    什么是神经网络 就是使用了平滑的激活函数的多层感知机 激活函数 什么是激活函数呢? 激活函数就是从输入值到对应输出...

  • [Machine Learning From Scratch]-

    激活层激活函数定义 封装激活层

  • 2019-10-09

    深度学习第三天 激活函数: 激活函数是...

  • 理解激活函数

    一、何为激活函数? 深度学习中,激活函数通常指能够实现非线性映射的函数 二、为什么需要非线性激活函数? 定义:这里...

  • 03 多层感知机

    激活函数 ReLU ReLU(x)=max(x,0) Sigmoid函数 tanh函数 激活函数的选择 多层感知机...

  • 非线性激活函数的作用

    一直有个疑问 为什么需要非线性激活函数?如果没有激活函数g(z),即g(z)=z,就叫线性激活函数,或者叫恒等激活...

  • Machine Learning基础:激活函数(Activiat

    Machine Learning基础:激活函数(Activiation Function)   激活函数通常有如下...

网友评论

      本文标题:激活函数

      本文链接:https://www.haomeiwen.com/subject/zymitktx.html