赞
踩
在接触到深度学习(Deep Learning)后,特别是神经网络中,我们会发现在每一层的神经网络输出后都会使用一个函数(比如sigmoid,tanh,Relu等等)对结果进行运算,这个函数就是激活函数(Activation Function)。那么为什么需要添加激活函数呢?如果不添加又会产生什么问题呢?
首先,我们知道神经网络模拟了人类神经元的工作机理,**激活函数(Activation Function)是一种添加到人工神经网络中的函数,旨在帮助网络学习数据中的复杂模式。**在神经元中,输入的input经过一系列加权求和后作用于另一个函数,这个函数就是这里的激活函数。**激活函数是一种特殊的非线性函数,它能够在神经网络中使用,其作用是将输入信号转化成输出信号。**类似于人类大脑中基于神经元的模型,它将神经元中的输入信号转换为一个有意义的输出,从而使得神经网络能够学习和识别复杂的模式。激活函数最终决定了是否传递信号以及要发射给下一个神经元的内容。在人工神经网络中,一个节点的激活函数定义了该节点在给定的输入或输入集合下的输出。
激活函数可以分为线性激活函数以及**非线性激活函数,常用的激活函数有 Sigmoid、ReLU、Leaky ReLU 和 ELU 等。
一句话总结:为了提高模型的表达能力。
激活函数能让中间输出多样化,从而能够处理更复杂的问题。如果不使用激活函数,那么每一层的输出都是上一层输入的线性函数,最后的输出也只是最开始输入数据的线性组合而已。而激活函数可以给神经元引入非线性因素,当加入到多层神经网络时,就可以让神经网络拟合任何线性函数或非线性函数,从而使得网络可以适合更多的非线性问题,而不仅仅是线性问题。
激活函数被定义为一个几乎处处可微的函数。
sigmoid 是使用范围最广的一类激活函数,具有指数函数形状,它在物理意义上最为接近生物神经元,是一个在生物学中常见的S型的函数,也称为S型生长曲线。此外,(0, 1) 的输出还可以被表示作概率,或用于输入的归一化,代表性的如Sigmoid交叉熵损失函数。
函数的表达式如下:
图像如下:
sigmoid优点:
(1) 值域在0和1之间
(2)函数具有非常好的对称性
(3)sigmoid的优点在于输出范围有限,所以数据在传递的过程中不容易发散。当然也有相应的缺点,就是饱和的时候梯度太小
(4)求导容易
sigmoid缺点:
(1)容易出现梯度消失
(2)函数输出并不是zero-centered(零均值)
(3)幂运算相对来讲比较耗时
tanh激活函数又叫作双曲正切激活函数,在sigmoid基础上做出改进,与sigmoid相比,tanh输出均值为0,能够加快网络的收敛速度。然而,tanh同样存在梯度消失现象。
函数的表达式如下:
图像如下:
tanh优点:
(1)当输入较大或较小时,输出几乎是平滑的并且梯度较小,这不利于权重更新。tanh 的输出间隔为 1,并且整个函数以 0 为中心,比 sigmoid 函数更好
(2)在 tanh 图中,负输入将被强映射为负,而零输入被映射为接近零。
tanh缺点:
(1)仍然存在梯度饱和的问题
(2)依然进行的是指数运算
ReLU函数又称为修正线性单元(Rectified Linear Unit),是一种分段线性函数,通常指代以斜坡函数及其变种为代表的非线性函数。其弥补了sigmoid函数以及tanh函数的梯度消失问题,在目前的深度神经网络中被广泛使用。
函数的表达式如下:
图像如下:
ReLU优点:
(1)当输入为正时,导数为1,一定程度上改善了梯度消失问题,加速梯度下降的收敛速度
(2)计算速度快得多。ReLU 函数中只存在线性关系,因此它的计算速度比 sigmoid 和 tanh 更快
(3)被认为具有生物学合理性(Biological Plausibility),比如单侧抑制、宽兴奋边界(即兴奋程度可以非常高)
ReLU缺点:
(1)当输入为负时,ReLU 完全失效,在正向传播过程中,这不是问题。有些区域很敏感,有些则不敏感。但是在反向传播过程中,如果输入负数,则梯度将完全为零
(2)不以零为中心:和 Sigmoid 激活函数类似,ReLU 函数的输出不以零为中心,ReLU 函数的输出为 0 或正数,给后一层的神经网络引入偏置偏移,会影响梯度下降的效率
SiLU激活函数(又称Sigmoid-weighted Linear Unit)是一种新型的非线性激活函数,它是Sigmoid和ReLU的改进版。SiLU具备无上界有下界、平滑、非单调的特性。SiLU在深层模型上的效果优于 ReLU。可以看做是平滑的ReLU激活函数。SiLU激活函数的特征是它在低数值区域中表现较为平滑,而在高数值区域中表现起来十分“锐利”,从而能够有效地避免过度学习的问题。
函数的表达式如下:
图像如下:
SiLU优点:
(1)相对于ReLU函数,SiLU函数在接近零时具有更平滑的曲线,并且由于其使用了sigmoid函数,可以使网络的输出范围在0和1之间。
SiLU缺点:
(1)引入了指数函数,增加了计算量。
swish 是一个平滑的、非单调的函数,在深度网络上始终匹配或优于 ReLU,适用于各种具有挑战性的领域,如图像分类和机器翻译。通过self-gating,它只需要一个标量输入,而在多选通场景中,它需要多个双标量输入。
函数的表达式如下:
图像如下:
swish优点:
(1)无上界(避免过拟合)
(2)有下界(产生更强的正则化效果)
(3)平滑(处处可导 更容易训练)
(4)x<0具有非单调性(对分布有重要意义 这点也是Swish和ReLU的最大区别)
hardswish激活函数是对swish激活函数的改进,尽管swish非线性激活函数提高了检测精度,但不适合在嵌入式移动设备上使用,因为“S”型函数在嵌入式移动设备上的计算成本更高,求导较为复杂,在量化时计算较慢。但是如果在实验中使用hardswish非线性激活函数在准确性没差别的情况下部署在嵌入式移动设备上却会具有多重优势。
函数的表达式如下:
图像如下:
hardswish优点:
(1)hardswish相较于swish函数,具有数值稳定性好,计算速度快等优点
(2)消除了由于近似Sigmoid形的不同实现而导致的潜在数值精度损失
(3)在实践中,hardswish激活函数可以实现为分段功能,以减少内存访问次数,从而大大降低了等待时间成本
代码实现:
import torch import torch.nn as nn import torch.nn.functional as F import matplotlib.pyplot as plt # 定义标准的Mish激活函数 class Mish(nn.Module): @staticmethod def forward(x): return x * F.softplus(x).tanh() # 定义内存高效的Mish激活函数 class MemoryEfficientMish(nn.Module): class F(torch.autograd.Function): @staticmethod def forward(ctx, x): ctx.save_for_backward(x) return x.mul(torch.tanh(F.softplus(x))) @staticmethod def backward(ctx, grad_output): x = ctx.saved_tensors[0] sx = torch.sigmoid(x) fx = F.softplus(x).tanh() return grad_output * (fx + x * sx * (1 - fx * fx)) def forward(self, x): return self.F.apply(x) # 创建激活函数对象 mish = Mish() me_mish = MemoryEfficientMish() # 生成输入数据 x = torch.linspace(-5, 5, 100) # 计算激活函数的输出
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。