整理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

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P