查看原文
其他

【动手学计算机视觉】第十二讲:激活函数

Jackpop 平凡而诗意 2022-06-20

点击蓝字关注我

激活函数是卷积神经网络模型中必不可少的一个单元,它不仅让深层神经网络变得有意义,而且使得模型对非线性空间的拟合效果更好。目前有很多种类的激活函数,其中比较常用的包括逻辑函数、双曲正切函数、线性整流函数、带泄露线性整流函数等,它们各有自身的优缺点,下面分别介绍一下各个激活函数,之后在项目中可以根据不同的场景选择对应的激活函数。

—▼—

本文涉及的完整代码请查看链接:

https://github.com/Jackpopc/aiLearnNotes/blob/master/computer_vision/activation.py

前言

激活函数不仅对于卷积神经网络非常重要,在传统机器学习中也具备着举足轻重的地位,是卷积神经网络模型中必不可少的一个单元,要理解激活函数,需要从2个方面进行讨论:

  • 什么是激活函数?

  • 为什么需要激活函数?

什么是激活函数?

对于神经网络,一层的输入通过加权求和之后输入到一个函数,被这个函数作用之后它的非线性性增强,这个作用的函数即是激活函数。

为什么需要激活函数?

试想一下,对于神经网络而言,如果没有激活函数,每一层对输入进行加权求和后输入到下一层,直到从第一层输入到最后一层一直采用的就是线性组合的方式,根据线性代数的知识可以得知,第一层的输入和最后一层的输出也是呈线性关系的,换句话说,这样的话无论中加了多少层网络都没有任何价值,这是第一点。

第二点是由于如果没有激活函数,输入和输出是呈线性关系的,但是现实中很多模型都是非线性的,通过引入激活函数可以增加模型的非线性,使得它更好的拟合非线性空间。

目前激活函数有很多,例如阶跃函数、逻辑函数、双曲正切函数、ReLU函数、Leaky ReLU函数、高斯函数、softmax函数等,虽然函数有很多,但是比较常用的主要就是逻辑函数和ReLU函数,在大多数卷积神经网络模型中都是采用这两种,当然也有部分会采用Leaky ReLU函数和双曲正切函数,本文就介绍一下这4个激活函数长什么样?有什么优缺点?在tensorflow中怎么使用?

Sigmoid

Sigmoid函数的方程式为:

绘图程序:

def sigmoid():
    x = np.arange(-10, 10, 0.1)
    y = 1 / (1+np.exp(-x))
    plt.plot(x, y)
    plt.grid()
    plt.show()

Sigmoid函数就是前面所讲的逻辑函数,它的主要优点如下:

  • 能够将函数压缩至区间[0, 1]之间,保证数据稳定,波动幅度小

  • 容易求导

缺点

  • 函数在两端的饱和区梯度趋近于0,当反向传播时容易出现梯度消失或梯度爆炸

  • 输出不是0均值(zero-centered),这样会导致,如果输入为正,那么导数总为正,反向传播总往正方向更新,如果输入为负,那么导数总为负,反向传播总往负方向更新,收敛速度缓慢

  • 对于幂运算和规模较大的网络运算量较大

tanh

双曲正切函数方程式:

绘图程序:

def tanh():
    x = np.arange(-10, 10, 0.1)
    y = (np.exp(x) - np.exp(-x)) / (np.exp(x) + np.exp(-x))
    plt.plot(x, y)
    plt.grid()
    plt.show()

可以看出,从图形上看双曲正切和Sigmoid函数非常类似,但是从纵坐标可以看出,Sigmoid被压缩在[0, 1]之间,而双曲正切函数在[-1, 1]之间,两者的不同之处在于,Sigmoid是非0均值(zero-centered),而双曲是0均值的,它的相对于Sigmoid的优点就很明显了:

  • 提高了训练效率

虽然双曲正切函数解决了Sigmoid函数非0均值的问题,但是它依然没有解决Sigmoid的两位两个问题,这也是tanh的缺点

  • 梯度消失和梯度爆炸

  • 对于幂运算和规模较大的网络运算量较大

ReLU

ReLU函数方程式:

绘图程序:

def relu():
    x = np.arange(-10, 10, 0.1)
    y = np.where(x<0, 0, x)
    plt.plot(x, y)
    plt.grid()
    plt.show()

线性整流函数(Rectified Linear Unit,ReLU),对比于Sigmoid函数和双曲正切函数的优点如下:

  • 梯度不饱和,收敛速度快

  • 减轻反向传播时梯度弥散的问题

  • 由于不需要进行指数运算,因此运算速度快、复杂度低

虽然解决了Sigmoid和双曲正切函数的缺点,但是它也有明显的不足:

  • 输出不是0均值(zero-centered)

  • 对参数初始化和学习率非常敏感,设置不当容易造成神经元坏死现象,也就是有些神经元永远不会被激活(由于负部梯度永远为0造成)

Leaky ReLU

Leaky ReLU函数方程式:

绘图程序:

def leaky_relu():
    x = np.arange(-2, 2, 0.1)
    y = np.where(x<0, 0.01*x, x)
    plt.plot(x, y)
    plt.grid()
    plt.show()

为了解决ReLU函数神经元坏死现象,Leaky ReLU函数在输入为负是引入了一个(0, 1)之间的常数,使得输入为负时梯度不为0。虽然Leaky ReLU解决了ReLU的这个严重问题,但是它并不总是比ReLU函数效果好,在很多情况下ReLU函数的效果还是更胜一筹。

tensorflow激活函数使用

tensorflow中激活函数在tf.nn模块下,例如,

tf.nn.relu
tf.nn.sigmoid
tf.nn.tanh
tf.nn.leaky_relu

其中relu、sigmoid、tanh函数的参数完全相同,leaky_relu多一个输入参数,就是斜率,默认值为0.2,以relu函数为例介绍一下tensorflow中激活函数的使用,

features = tf.nn.max_poo()
tf.nn.relu(features, name=None)

tensorflow中激活函数输入有两个参数:
  • features:输入的特征张量,也就是前一层池化层或者卷积层输出的结果,数据类型限制在float32, float64, int32, uint8, int16, int8, int64, float16, uint16, uint32, uint64

  • name:运算的名称,这个可以自行命名

END


有趣的灵魂在等你

长按扫码可关注 

相关文章【动手学计算机视觉】第一讲:图像预处理之图像去噪【动手学计算机视觉】第二讲:图像预处理之图像增强【动手学计算机视觉】第三讲:图像预处理之图像分割【动手学计算机视觉】第四讲:图像预处理之图像增广【动手学计算机视觉】第五讲:传统目标检测之特征工程【动手学计算机视觉】第六讲:传统目标检测之Harris角点检测【动手学计算机视觉】第七讲:传统目标检测之SIFT特征【动手学计算机视觉】第八讲:传统目标检测之HOG特征【动手学计算机视觉】第九讲:传统目标检测之DPM模型【动手学计算机视觉】第十讲:传统目标检测之卷积神经网络概述【动手学计算机视觉】第十一讲:卷积层与池化层
文章好看就点这里

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存