整理Sigmoid~Dice常见激活函数,从原理到实现

2024-05-14 05:38

本文主要是介绍整理Sigmoid~Dice常见激活函数,从原理到实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文首发于我的个人博客:

激活函数:https://fuhailin.github.io/activation-functions/
并同步于我的公众号:赵大寳Note(ID:StateOfTheArt),回复关键词【激活函数】下载全部代码。

激活函数之性质

1. 非线性:即导数不是常数。保证多层网络不退化成单层线性网络。这也是激活函数的意义所在。

2. 可微性:保证了在优化中梯度的可计算性。虽然 ReLU 存在有限个点处不可微,但处处 subgradient,可以替代梯度。

3. 计算简单:激活函数复杂就会降低计算速度,因此 RELU 要比 Exp 等操作的激活函数更受欢迎。

4. 非饱和性(saturation):饱和指的是在某些区间梯度接近于零(即梯度消失),使得参数无法继续更新的问题。最经典的例子是 Sigmoid,它的导数在 x 为比较大的正值和比较小的负值时都会接近于 0。RELU 对于 x<0,其梯度恒为 0,这时候它也会出现饱和的现象。Leaky ReLU 和 PReLU 的提出正是为了解决这一问题。

5. 单调性(monotonic):即导数符号不变。当激活函数是单调的时候,单层网络能够保证是凸函数。但是激活函数如 mish 等并不满足单调的条件,因此单调性并不是硬性条件,因为神经网络本来就是非凸的。

6. 参数少:大部分激活函数都是没有参数的。像 PReLU 带单个参数会略微增加网络的大小。还有一个例外是 Maxout,尽管本身没有参数,但在同样输出通道数下 k 路 Maxout 需要的输入通道数是其它函数的 k 倍,这意味着神经元数目也需要变为 k 倍。

Sigmoid激活函数

σ ( x ) = 1 1 + e − x \sigma \left( x\right) =\dfrac {1} {1+e^{-x}} σ(x)=1+ex1

其导数为:

σ ′ ( x ) = σ ( x ) ⋅ ( 1 − σ ( x ) ) \sigma'(x) = \sigma(x) \cdot (1 - \sigma(x)) σ(x)=σ(x)(1σ(x))

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

sigmoid

优点:

  • 梯度平滑,求导容易
  • Sigmoid函数的输出映射在(0,1)之间,单调连续,输出范围有限,优化稳定,可以用作输出层

缺点:

  • 激活函数计算量大(在正向传播和反向传播中都包含幂运算和除法);
  • 梯度消失:输入值较大或较小(图像两侧)时,sigmoid导数则接近于零,因此在反向传播时,这个局部梯度会与整个代价函数关于该单元输出的梯度相乘,结果也会接近为 0 ,无法实现更新参数的目的;
  • Sigmoid 的输出不是 0 为中心(zero-centered)。因为如果输入都是正数的话(如 f = w T x + b f=w^{T}x+b f=wTx+b 中每个元素都 x > 0 x>0 x>0 ),那么关于 w w w 的梯度在反向传播过程中,要么全是正数,要么全是负数(具体依据整个表达式 f f f 而定),这将会导致梯度下降权重更新时出现 z 字型的下降。当然,如果是按 batch 去训练,那么每个 batch 可能得到不同的信号,整个批量的梯度加起来后可以缓解这个问题。因此,该问题相对于上面的神经元饱和问题来说只是个小麻烦,没有那么严重。

Tanh激活函数

t a n h ( x ) = e x − e − x e x + e − x tanh(x) = \frac{e^{x} - e^{-x}}{e^{x} + e^{-x}} tanh(x)=ex+exexex
其导数为:
t a n h ′ ( x ) = 1 − t a n h ( x ) 2 tanh'(x) = 1 - tanh(x)^{2} tanh(x)=1tanh(x)2

def tanh(x):return np.sinh(x)/np.cosh(x)

tanh

优点:

  • 比Sigmoid函数收敛速度更快
  • tanh(x) 的梯度消失问题比 sigmoid 要轻
  • 相比Sigmoid函数,输出是以 0 为中心 zero-centered

缺点:

  • 还是没有改变Sigmoid函数的最大问题——由于饱和性产生的梯度消失。

整流线性单元(ReLU)

def ReLU(x):return x * (x > 0)

ReLU

优点:

  • 计算与收敛速度非常快:不涉及指数等运算;
  • 一定程度缓解梯度消失问题:因为导数为 1,不会像 sigmoid 那样由于导数较小,而导致连乘得到的梯度逐渐消失。

缺点:

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

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

前面说了一大堆的 ReLU 的缺点,有很多大牛在此基础上做了改进,如 Leaky ReLU、PReLU(Parametric ReLU)等。

我整理了本文涉及到的全部十几种常见激活函数的底层实现代码Python版,关注我的公众号"趙大寳Note"(ID:StateOfTheArt)回复关键词:激活函数 下载收藏。

关注公众号趙大寳Note,回复“激活函数”下载全部代码

指数线性单元(ELU)

ELU

优点:

  • 能避免死亡 ReLU 问题:x 小于 0 时函数值不再是 0,因此可以避免 dying relu 问题;
  • 能得到负值输出,这能帮助网络向正确的方向推动权重和偏置变化。

缺点:

  • 计算耗时:包含指数运算;
  • α 值是超参数,需要人工设定

SELU

SELU 源于论文 *Self-Normalizing Neural Networks*,作者为 Sepp Hochreiter,ELU 同样来自于他们组。

SELU 其实就是 ELU 乘 lambda,关键在于这个 lambda 是大于 1 的,论文中给出了 lambda 和 alpha 的值:

  • lambda = 1.0507
  • alpha = 1.67326

selu ⁡ ( x ) = λ { x if  x > 0 α e x − α if  x ⩽ 0 \operatorname{selu}(x)=\lambda\left\{\begin{array}{ll}{x} & {\text { if } x>0} \\ {\alpha e^{x}-\alpha} & {\text { if } x \leqslant 0}\end{array}\right. selu(x)=λ{xαexα if x>0 if x0

SELU

优点:

  • SELU 激活能够对神经网络进行自归一化(self-normalizing);
  • 不可能出现梯度消失或爆炸问题,论文附录的定理 2 和 3 提供了证明。

缺点:

  • 应用较少,需要更多验证;
  • lecun_normal 和 Alpha Dropout:需要 lecun_normal 进行权重初始化;如果 dropout,则必须用 Alpha Dropout 的特殊版本。

Leaky ReLU

Leaky ReLU 是为解决“ ReLU 死亡”问题的尝试。

Leaky_ReLU

优点:

  • 类似于 ELU,能避免死亡 ReLU 问题:x 小于 0 时候,导数是一个小的数值,而不是 0;
  • 与 ELU 类似,能得到负值输出;
  • 计算快速:不包含指数运算。

缺点:

  • 同 ELU,α 值是超参数,需要人工设定;
  • 在微分时,两部分都是线性的;而 ELU 的一部分是线性的,一部分是非线性的。

Parametric ReLU (PRELU)

形式上与 Leak_ReLU 在形式上类似,不同之处在于:PReLU 的参数 alpha 是可学习的,需要根据梯度更新。

  • alpha=0:退化为 ReLU
  • alpha 固定不更新,退化为 Leak_ReLU

PReLU

优点:

与 ReLU 相同。

缺点:

在不同问题中,表现不一。

Gaussian Error Linear Unit(GELU)

高斯误差线性单元激活函数在最近的 Transformer 模型(谷歌的 BERT 和 OpenAI 的 GPT-2)中得到了应用。GELU 的论文来自 2016 年,但直到最近才引起关注。
GELU ⁡ ( x ) = 0.5 x ( 1 + tanh ⁡ ( 2 / π ( x + 0.044715 x 3 ) ) ) \operatorname{GELU}(x)=0.5 x\left(1+\tanh \left(\sqrt{2 / \pi}\left(x+0.044715 x^{3}\right)\right)\right) GELU(x)=0.5x(1+tanh(2/π (x+0.044715x3)))
GELU

优点:

  • 似乎是 NLP 领域的当前最佳;尤其在 Transformer 模型中表现最好;
  • 能避免梯度消失问题。

缺点:

  • 这个2016 年提出的新颖激活函数还缺少实际应用的检验。

Swish

Swish激活函数诞生于Google Brain 2017的论文 Searching for Activation functions中,其定义为:
f ( x ) = x ⋅ sigmoid ( β x ) f(x) = x · \text{sigmoid}(βx) f(x)=xsigmoid(βx)
β是个常数或可训练的参数.Swish 具备无上界有下界、平滑、非单调的特性。

Swish

Swish 在深层模型上的效果优于 ReLU。例如,仅仅使用 Swish 单元替换 ReLU 就能把 Mobile NASNetA 在 ImageNet 上的 top-1 分类准确率提高 0.9%,Inception-ResNet-v 的分类准确率提高 0.6%。
当β = 0时,Swish变为线性函数 f ( x ) = x 2 f(x) ={x\over 2} f(x)=2x.
β → ∞, σ ( x ) = ( 1 + exp ⁡ ( − x ) ) − 1 σ(x) = (1 + \exp(−x))^{−1} σ(x)=(1+exp(x))1为0或1. Swish变为ReLU: f(x)=2max(0,x)
所以Swish函数可以看做是介于线性函数与ReLU函数之间的平滑函数.

Data Adaptive Activation Function(Dice)

Dice激活函数诞生于alibaba 2018 的CTR论文Deep Interest Network中,根据 Parametric ReLU 改造而来,ReLU类函数的阶跃变化点再x=0处,意味着面对不同的输入这个变化点是不变的,DIN中改进了这个控制函数,让它根据数据的分布来调整,选择了统计神经元输出的均值和方差(实际上就是Batch_Normalization,CTR中BN操作可是很耗时的,可以推测Dice复杂的计算快不起来不会大规模引用)来描述数据的分布:
f ( s ) = p ( s ) . s + ( 1 − p ( s ) ) ⋅ α s , p ( s ) = 1 1 + e − s − E ( s ) Var ⁡ ( s ) + ϵ f(s)=p(s) . s+(1-p(s)) \cdot \alpha s, p(s)=\frac{1}{1+e^{-\frac{s-E(s)}{\sqrt{\operatorname{Var}(s)+\epsilon}}}} f(s)=p(s).s+(1p(s))αs,p(s)=1+eVar(s)+ϵ sE(s)1
优点:

  • 根据数据分布灵活调整阶跃变化点,具有BN的优点(解决Internal Covariate Shift),原论文称效果好于Parametric ReLU。

缺点:

  • 具有BN的缺点,大大加大了计算复杂度。

Maxout

Maxout 是对 ReLU 和 Leaky ReLU 的一般化归纳,它的函数公式是(二维时):
M a x o u t ( x ) = max ⁡ ( w 1 T x + b 1 , W 2 T x + b 2 ) Maxout(x) = \max \left( w_{1}^{T}x+b_{1},W_{2}^{T}x+b_{2}\right) Maxout(x)=max(w1Tx+b1,W2Tx+b2)
ReLU 和 Leaky ReLU 都是这个公式的特殊情况(比如 ReLU 就是当 w 1 , b 1 = 0 w_{1},b_{1}=0 w1,b1=0时)。

优点:

  • Maxout 神经元拥有 ReLU 单元的所有优点(线性和不饱和),而没有它的缺点(死亡的 ReLU 单元)

缺点:

  • 和 ReLU 对比,它每个神经元的参数数量增加了一倍,这就导致整体参数的数量激增。

Softplus

s o f t p l u s ( x ) = log ⁡ ( 1 + e x ) softplus(x)=\log \left(1+e^{x}\right) softplus(x)=log(1+ex)

Softplus

softplus可以看作是ReLu的平滑,不常见。

Softmax

Sigmoid函数只能处理两个类别,这不适用于多分类的问题,所以Softmax可以有效解决这个问题。Softmax函数很多情况都运用在神经网路中的最后一层网络中,使得每一个类别的概率值在(0, 1)之间。
s ( x i ) = e x i ∑ j = 1 n e x j s\left(x_{i}\right)=\frac{e^{x_{i}}}{\sum_{j=1}^{n} e^{x_{j}}} s(xi)=j=1nexjexi

def softmax(x):return np.exp(x) / sum(np.exp(x))

Softmax

如何选择激活函数?

通常来说,很少会把各种激活函数串起来在一个网络中使用的。

如果使用 ReLU ,那么一定要小心设置 learning rate ,而且要注意不要让你的网络出现很多 “ dead ” 神经元,如果这个问题不好解决,那么可以试试 Leaky ReLU 、 PReLU 或者 Maxout.

最好不要用 sigmoid ,可以试试 tanh ,不过可以预期它的效果会比不上 ReLU 和 Maxout.


看到这里你已经知道了足够多的激活函数,那你还记得你学习激活函数的初衷吗?我们为什么需要激活函数,激活函数的作用呢?为什么SVM这类算法没有激活函数也能进行非线性分类呢?一起思考

References:

[1]: (1, 2) http://cs231n.github.io/neural-networks-1/

[2]: ML Glossary | Activation Functions

[3]: 机器之心 | 激活函数

[4]: 激活函数(ReLU, Swish, Maxout)

这篇关于整理Sigmoid~Dice常见激活函数,从原理到实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/987897

相关文章

python常见环境管理工具超全解析

《python常见环境管理工具超全解析》在Python开发中,管理多个项目及其依赖项通常是一个挑战,下面:本文主要介绍python常见环境管理工具的相关资料,文中通过代码介绍的非常详细,需要的朋友... 目录1. conda2. pip3. uvuv 工具自动创建和管理环境的特点4. setup.py5.

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

Python中help()和dir()函数的使用

《Python中help()和dir()函数的使用》我们经常需要查看某个对象(如模块、类、函数等)的属性和方法,Python提供了两个内置函数help()和dir(),它们可以帮助我们快速了解代... 目录1. 引言2. help() 函数2.1 作用2.2 使用方法2.3 示例(1) 查看内置函数的帮助(

Python实现精准提取 PDF中的文本,表格与图片

《Python实现精准提取PDF中的文本,表格与图片》在实际的系统开发中,处理PDF文件不仅限于读取整页文本,还有提取文档中的表格数据,图片或特定区域的内容,下面我们来看看如何使用Python实... 目录安装 python 库提取 PDF 文本内容:获取整页文本与指定区域内容获取页面上的所有文本内容获取

基于Python实现一个Windows Tree命令工具

《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五