激活函数汇总

一、sigmoid( Logistic function)

公式:

图像:

特点:它能够把输入的连续实值变换为0和1之间的输出,特别的,如果是非常大的负数,那么输出就是0;如果是非常大的正数,输出就是1。

缺点:

1.在深度神经网络中梯度反向传递时导致梯度爆炸和梯度消失,其中梯度爆炸发生的概率非常小,而梯度消失发生的概率比较大。

2. 其解析式中含有幂运算,计算机求解时相对来讲比较耗时。对于规模比较大的深度网络,这会较大地增加训练时间。

参考来源:常用激活函数(激励函数)理解与总结-CSDN博客

二、Hard Sigmoid

公式:

图像:

特点:是 Logistic Sigmoid 激活函数的分段线性近似。它更易计算,这使得学习计算的速度更快,尽管首次派生值为零可能导致静默神经元/过慢的学习速率(详见 ReLU)。

三、Symmetrical Sigmoid

公式:

图像:

特点:Symmetrical Sigmoid是另一个Tanh 激活函数的变种(实际上,它相当于输入减半的 Tanh) 。和 Tanh一样,它是反对称的、零中心、可微分的,值域在-1到1之间。它更平坦的形状和更慢的下降派生表明它可以更有效地进行学习。

四、 Signum(或者简写为 Sign)

公式:

图像:

特点:是二值阶跃激活函数的扩展版本。它的值域为 [-1,1],原点值是 0。尽管缺少阶跃函数的生物动机,Signum 依然是反对称的,这对激活函数来说是一个有利的特征。

五、Hyperbolic Tangent (tanh)

公式:

/

图像:

特点:

1.解决了Sigmoid函数的不是zero-centered输出问题,然而,梯度消失(gradient vanishing)的问题和幂运算的问题仍然存在。

2.与 sigmoid 函数相比,使用 tanh 函数的一个优点是 tanh 函数以零为中心。这使得优化过程更加容易。

3.tanh 函数的梯度比 sigmoid 函数的梯度更陡

tanh替代选择:Softsign 

Softsign Tanh 激活函数的另一个替代选择。就像 Tanh 一样,Softsign 是反对称、去中心、可微分,并返回-1 1 之间的值。其更平坦的曲线与更慢的下降导数表明它可以更高效地学习。另一方面,导数的计算比 Tanh 更麻烦。

六、The ReLU family

1. Rectified Linear Unit (ReLU)

公式:

图像:

特点:

1 解决了gradient vanishing问题 (在正区间)
2)计算速度非常快,只需要判断输入是否大于0
3)收敛速度远快于sigmoidtanh

ReLU也有几个需要特别注意的问题:

1)ReLU的输出不是zero-centered

2)Dead ReLU Problem,指的是某些神经元可能永远不会被激活,导致相应的参数永远不能被更新。有两个主要原因可能导致这种情况产生: (1) 非常不幸的参数初始化,这种情况比较少见 (2) learning rate太高导致在训练过程中参数更新太大,不幸使网络进入这种状态。解决方法是可以采用Xavier初始化方法,以及避免将learning rate设置太大或使用adagrad等自动调节learning rate的算法。

 尽管存在这两个问题,ReLU目前仍是最常用的activation function,在搭建人工神经网络的时候推荐优先尝试!                      

原文链接:https://blog.csdn.net/tyhj_sf/article/details/79932893

2. Leaky Rectified Linear Unit (Leaky ReLU)

公式:

图像:

特点:人们为了解决Dead ReLU Problem,提出了将ReLU的前半段设为α x而非0,通常α =0.01。另外一种直观的想法是基于参数的方法,即,其中α 可由方向传播算法学出来。理论上来讲,Leaky ReLU有ReLU的所有优点,外加不会有Dead ReLU问题,但是在实际操作当中,并没有完全证明Leaky ReLU总是好于ReLU。

3. Parametric Rectified Linear Unit (PReLU)

公式:

图像:

特点:如果ai=0,那么PReLU退化为ReLU;如果ai是一个很小的固定值(如ai=0.01),则PReLU退化为Leaky ReLU(LReLU)。 有实验证明,与ReLU相比,LReLU对最终的结果几乎没什么影响。
链接:https://www.jianshu.com/p/d49905dee072
 

4. Exponential Linear Unit (ELU)

公式:

图像:

特点:

(右侧的线性部分能够缓解梯度消失,左侧的软饱和能够对于输入变化鲁棒.而且收敛速度更快。)

1.不会有Dead ReLU问题

2.输出的均值接近0,zero-centered

计算量稍大。类似于Leaky ReLU,理论上虽然好于ReLU,但在实际使用中目前并没有好的证据ELU总是优于ReLU

3.ELU包含了ReLU的所有优点。

来源:神经网络常见的激活函数汇总_神经网络激活函数-CSDN博客

5. S-shaped Rectified Linear Activation Unit,SReLU)      、FReLU、AReLU、

来源:https://www.ai2news.com/paper/1512.07030/

6.ReLU代替选择:SoftPlus

公式:

图像:

特点: 能够返回任何大于 0 的值。与 ReLU 不同,SoftPlus 的导数是连续的、非零的,无处不在,从而防止出现静默神经元。然而,SoftPlus 另一个不同于 ReLU 的地方在于其不对称性,不以零为中心,这兴许会妨碍学习。此外,由于导数常常小于 1,也可能出现梯度消失的问题。

Softplus函数可以看作是ReLU函数的平滑。根据神经科学家的相关研究,Softplus函数和ReLU函数与脑神经元激活频率函数有神似的地方。也就是说,相比于早期的激活函数,Softplus函数和ReLU函数更加接近脑神经元的激活模型,而神经网络正是基于脑神经科学发展而来,这两个激活函数的应用促成了神经网络研究的新浪潮                       

原文链接:https://blog.csdn.net/hy592070616/article/details/120623303

7.SiLU(也叫做Swish函数)具体看下面的Swish

8. Relu6

公式

图像:

特点:

1.ReLU 和 ReLU6 之间的主要区别在于,ReLU 允许正侧的值非常高,而 ReLU6 限制为正侧的值 6。 任何 6 或大于 6 的输入值都将被限制为值 6(因此得名)。

2.ReLU6 函数由三个线性分量组成。 它是一个非线性函数

比较有意思的是,为什么是6,不是7或者其他呢?结合原文的说明,可能是作者尝试了多种,ReLU6 效果最好。

七、 Identity

公式:

图像:

特点:

1.这也被称为线性激活函数。

2.当我们讨论激活函数时,这是唯一一个被认为是线性函数的函数。

3.这个函数按原样输出输入值。对输入不做任何更改。

用法:

该函数仅用于解决回归问题的神经网络模型的输出层。

不要在隐藏层中使用这个函数。

八、 Bent Identity

公式:

图像:

特点:激活函数 Bent Identity 是介于 Identity ReLU 之间的一种折衷选择。它允许非线性行为,尽管其非零导数有效提升了学习并克服了与 ReLU 相关的静默神经元的问题。由于其导数可在 1 的任意一侧返回值,因此它可能容易受到梯度爆炸和消失的影响。

九、Exponential Linear UnitELU

公式:

图像:

特点:

ELU 主要是对小于等于 0 的部分进行了改进,使得函数在 x = 0 处可导, 而且 使得神经元的平均激活均值趋近为 0,对噪声更具有鲁棒性。
缺点是由于又引入了指数,计算量增大了。

十、Gaussian Error Linear Unit (GELU)高斯误差线性单元

公式:

 我们可以用GELU来近似

/

特点:它一种高性能的神经网络激活函数。GELU的非线性是随机正则化器的预期变换,随机正则化器(防止过拟合)将等式或零映射随机应用于神经元的输入。GELU的非线性按其幅度输入,而不是按照ReLU中的符号进行门控输入

来源:https://blog.csdn.net/qq_28385535/article/details/89839154?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171206365116800186544984%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=171206365116800186544984&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-89839154-null-null.nonecase&utm_term=GELU&spm=1018.2226.3001.4450

八、Swish

公式:

图像:

特点:

  • 该函数是通过将 sigmoid 函数乘以输入 z 构成的。
  • 这是一个非线性函数。
  • 该图与 ReLU 激活函数的图非常相似。
  • 曲线比 ReLU 激活函数更平滑。 在训练模型时,这种平滑度很重要。 该函数在训练时很容易收敛。

用法:

  • 仅在隐藏层中使用。
  • 不在神经网络模型的输出层使用这个函数。

缺点:

  • Swish 函数的主要缺点是计算量很大,因为函数中包含了 e^z 项。 这可以通过使用下面定义的称为“Hard Swish”的特殊函数来避免。

来源:https://zhuanlan.zhihu.com/p/460177194

十一、HardSwish

公式:

/

图像:

特点:HardSwish平滑地在Re LU和线性函数之间进行了非线性差值。HardSwish的属性与Swish相似,但非线性提高了精度。因为它们都是上下无界的,它是非单调的。该函数与Swish相比,它的计算速度更快。

十二、Gaussian

公式:

图像:

特点:高斯激活函数(Gaussian)并不是径向基函数网络(RBFN)中常用的高斯核函数,高斯激活函数在多层感知机类的模型中并不是很流行。该函数处处可微且为偶函数,但一阶导会很快收敛到零

十三、 Absolute

公式:

图像:

特点:绝对值(Absolute)激活函数返回输入的绝对值。该函数的导数除了零点外处处有定义,且导数的量值处处为 1。这种激活函数一定不会出现梯度爆炸或消失的情况

十四、 Sinusoid

公式:

图像:

特点:Sinusoid(或简单正弦函数)激活函数为神经网络引入了周期性。该函数的值域为 [-1,1],且导数处处连续。此外,Sinusoid 激活函数为零点对称的奇函数。

十五、Cos

公式:

图像:

特点:如同正弦函数,余弦激活函数(Cos/Cosine)为神经网络引入了周期性。它的值域为 [-1,1],且导数处处连续。和 Sinusoid 函数不同,余弦函数为不以零点对称的偶函数。

十六、Sinc

公式:

图像:

特点:Sinc 函数(全称是 Cardinal Sine)在信号处理中尤为重要,因为它表征了矩形函数的傅立叶变换(Fourier transform)。作为一种激活函数,它的优势在于处处可微和对称的特性,不过它比较容易产生梯度消失的问题。

十七、Log Log

公式:

图像:

十八、Mish

公式:

图像:

特点:

重点对比了 Mish 和 Swish,结论是 Mish 更牛逼。但是 YOLO v5 用的 Swish。

十九、Softmax

公式:

特点:Softmax 函数可视为 Sigmoid 函数的泛化形式, 其本质就是将一个 K 维的任意实数向量压缩(映射)成另一个 K 维的实数向量, 其中向量中的每个元素的取值范围都介于 [ 0 , 1 ] [0,1][0,1] 之间(可以理解为概率)。Softmax 常常是作为多分类神经网络的输出,比如 LeNet-5 中就用Softmax 映射到最后的输入结果,其表示1~10的概率。                       

原文链接:https://blog.csdn.net/kuweicai/article/details/93926393

部分绘制激活函数代码

# -*- coding: utf-8 -*-

import numpy as np

import matplotlib.pyplot as plt

import math

def single_sigmoid(x):

    return 1/(1 + np.e**(-x))

def sigmoid(x):

    y = np.zeros_like(x)

    for i, ele in enumerate(x):

        y[i] = single_sigmoid(ele)

    return y

def swish(x):

    y = np.zeros_like(x)

    for i, ele in enumerate(x):

        y[i] = single_sigmoid(ele)*ele

    return y

def swish_d1(x):

    y = np.zeros_like(x)

    for i, ele in enumerate(x):

        temp = single_sigmoid(ele)

        y[i] = temp + ele * temp * (1-temp)

    return y

def hard_sigmoid(x):

    y = np.zeros_like(x)

    for i, ele in enumerate(x):

        if ele < -2.5:

            y[i] = 0

        elif ele > 2.5:

            y[i] = 1

        else:

            y[i] = 0.2 * ele + 0.5

    return y

def hard_sigmoid_d1(x):

    y = np.zeros_like(x)

    for i, ele in enumerate(x):

        if ele < -2.5:

            y[i] = 0

        elif ele > 2.5:

            y[i] = 0

        else:

            y[i] = 0.2

    return y

def relu6(x):

    y = np.zeros_like(x)

    for i, ele in enumerate(x):

        if ele < 0:

            y[i] = 0

        elif ele > 6:

            y[i] = 6

        else:

            y[i] = ele

    return y

def relu6_d(x):

    y = np.zeros_like(x)

    for i, ele in enumerate(x):

        if ele < 0:

            y[i] = 0

        elif ele > 6:

            y[i] = 0

        else:

            y[i] = 1

    return y

def hardswish(x):

    y = np.zeros_like(x)

    for i, ele in enumerate(x):

        if ele < -3:

            y[i] = 0

        elif ele > 3:

            y[i] = ele

        else:

            y[i] = ele*(ele+3)/6

    return y

def hardswish_d(x):

    y = np.zeros_like(x)

    for i, ele in enumerate(x):

        if ele < -3:

            y[i] = 0

        elif ele > 3:

            y[i] = 1

        else:

            y[i] = ele/3 + 0.5

    return y

def tanh(k):

    a = np.e**(k)

    b = np.e**(-k)

    return (a - b)/(a+b)

def mish(x):

    y = np.zeros_like(x)

    for i, ele in enumerate(x):

        y[i] = ele * tanh(math.log(1 + np.e**ele))

    return y

def mish_d(x):

    y = np.zeros_like(x)

    for i, ele in enumerate(x):

        n = np.e**ele

        m = math.log(1 + n)

        y[i] = ele * (1 - (tanh(m))**2) * n /(1 + n) + tanh(m)

    return y

def draw(X, *args):

    plt.figure(figsize=(8, 5), dpi=80)

    ax = plt.subplot(111)

    ax.spines['right'].set_color('none')

    ax.spines['top'].set_color('none')

    ax.xaxis.set_ticks_position('bottom')

    ax.spines['bottom'].set_position(('data',0))

    ax.yaxis.set_ticks_position('left')

    ax.spines['left'].set_position(('data',0))

    color = ['blue', 'red', 'green', 'yellow', 'brown']

    for i, F in enumerate(args):

        clr = color[i%6]

        Y = F(X)

        plt.plot(X, Y, color=clr, linewidth=2.5, linestyle="-", label=F.__name__)

    plt.xlim(X.min()*1.1, X.max()*1.1)

    plt.ylim(Y.min()*4, Y.max()*1.1)

    plt.legend(loc='upper left', frameon=False)

    #

    # t = 2*np.pi/3

    # plt.plot([t,t],[0,np.cos(t)],

    #          color ='blue',  linewidth=1.5, linestyle="--")

    # plt.scatter([t,],[np.cos(t),], 50, color ='blue')

    # plt.annotate(r'$\sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$',

    #              xy=(t, np.sin(t)),  xycoords='data',

    #              xytext=(+10, +30), textcoords='offset points', fontsize=16,

    #              arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))

    #

    # plt.plot([t,t],[0,np.sin(t)],

    #          color ='red',  linewidth=1.5, linestyle="--")

    # plt.scatter([t,],[np.sin(t),], 50, color ='red')

    # plt.annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$',

    #              xy=(t, np.cos(t)),  xycoords='data',

    #              xytext=(-90, -50), textcoords='offset points', fontsize=16,

    #              arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))

    #

    #

    # plt.savefig("exercice_10.png",dpi=72)

    plt.show()

if __name__ == '__main__':

    x = np.linspace(-10, 10, 500, endpoint=True)

    # draw(x, hard_sigmoid, hard_sigmoid_d1)

    # draw(x, relu6, relu6_d)

    # draw(x, hardswish)

    draw(x, mish, mish_d)

  • 24
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值