3

从函数光滑近似的角度统一理解激活函数

 3 years ago
source link: https://allenwind.github.io/blog/10705/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

神经网络强大的表示能力应该归功于网络模型中的激活函数,深度学习中,很多数学形式其实都是光滑逼近的结果。比如激活函数,sigmoid、swish、gelu、softplus,这里从光滑近似的角度统一理解激活函数。

更新:Transformer使用的激活函数GELU。

关于激活函数

神经网络中激活函数的作用:

  • 输出层,获得概率意义
  • 中间层,产生非线性
  • 门机制,如LSTM,信息筛选

激活函数作为输出层,获得概率意义;作为中间层,产生非线性,这些接下来会谈到。这里简单说说作为门机制的激活函数,比如以下网络模型,

f(x)=Dense(x)⊗σ(Dense(x))=(W1x+b1)⊗σ((W2x+b2))

称为Gated Linear Units (GLU),这里激活函数σ(x)​起到门控的作用。整体上看是一种swish形式的门机制。

激活函数的设计关注如下几点:

  • 非线性,产生非线性
  • 光滑性,以便求梯度
  • 线性区,以便在一定范围内保持输出的均值(0中心)与方差统计特征不漂移
  • 活性范围,关系到下层和输出
  • 计算性能,计算复杂度不能太大

对于第三点,这里展开说说。所谓的线性区是要求激活函数在自变量x​取值一定范围内,满足

S(x)≈x′

这样,输入x和输出x′​的均值与方差统计特征的变化不大,以保证网络学习的稳定。

关于次梯度,例如RELU激活函数在x=0​处不可导,那么是不是对于深度学习模型来说就无法进行误差逆向传播优化?

事实上,在工程上,有一种叫做次梯度的解决方案。就以RELU函数为例,当x>0时,梯度为1,当x<0时梯度为0。而0这个位置不存在梯度,而次梯度即选择[0,1]区间中的任意值。在实现时,一般会选择一个区间内的固定值。

逼近0-1函数

Heaviside step函数,

H(x)=ddxmax{0,x}={1,x>00,x≤0

在深度学习中其意义是,如果logit取值为负半轴,则把类别判别为负类(0),如果取值为正半轴,则把类别判别为正类(+1)。另外,从生物学上看,H(x)可以直接描述神经元的激活或非激活状态,或者说是一个开关,要么开,要么关。但是H(x)并不光滑,对于模型训练来说,寻找其光滑逼近版本相当重要。

这个取值可以改为1,−1​,即,

H(x)={+1,x>0−1,x≤0

这个函数不可导,模型优化困难。考虑到

sign(x)={−1if x<0,0if x=0,1if x>0.

如果规定H(0)=12,那么有H(x)=12[1+sign(x)]。​

当x≠0时,H(x)可以用|x|表示,

H(x)=x+|x|2x

根据H(x)​的分段特性可以为均匀分布的概率密度函数提供紧凑的表达形式,如下

f(x)=H(x−a)−H(x−b)b−a

H(x)​​本身难计算梯度,其梯度是一个非常特殊的函数狄拉克函数δ(x)​,

δ(x)=ddxH(x)

为此,应用于深度学习需要其光滑版本。以sigmoid为首的很多激活函数就是逼近H(x)的光滑版本。

sigmoid

对H(x)​函数的逼近是寻找一个S型函数且区间在(0,1)或(−1,1),最常见的是σ(x)函数,

f(x)=σ(x)=11+e−x

Sigmoid函数导出的另外一个角度中我们知道,σ(x)函数来说max(x)的光滑逼近ln(1+ex)的梯度,

H(x)=ddxmax{0,x}≈ddxln(1+ex)=ex1+ex=11+e−x=σ(x)

可以用tanh(x)来表示,

σ(x)=12(tanhx2+1)

这两个激活函数都存在当x很大时梯度饱和,即接近0。

注意到,tanh(x)可以用σ(x)表示

tanh(x)=ex−e−xex+e−x=2σ(2x)−1

是σ(x)​的一个仿射变换,因此还是S型函数,不过取值区间变为(−1,1)。

tanh(x)与σ(x)的梯度与自身相关,即:

(tanh(x))′=1−tanh2(x)σ′(x)=σ(x)(1−σ(x))

这个性质很有用,可以复用已有的计算结果。

softsign

softsign激活函数为,

f(x)=x1+|x|

该激活函数来自sign(x)的近似,

sign(x)=x|x|≈xβ+|x|≈x1+|x|

softsign激活函数可以推广开来,

fk(x)=x(1+|x|k)1k

按照类似的思路,有,

sign(x)=x|x|=xlne|x|≈xln(ex+e−x)

激活函数用S型函数逼近0-1阶跃函数的好处是在x较小时,有

S(x)≈x

例如tanh(x)≈x,这样通过激活函数输出后,均值和方差大致保存不变,这样便于模型的训练和优化。

逼近RELU函数

RELU函数,

relu(x)=max(0,x)=x×H(x)={0 for x≤0x for x>0

从神经元的角度看,RELU激活函数描述两种状态:

  • 非激活状态,即负半轴
  • 激活状态的激活程度,即正半轴,且不具有饱和性

用一句话来说就是单边抑制宽兴奋边界,这是有生物学合理性。但是从数学角度看,RELU的定义非光滑,不利于优化。

RELU激活函数的图形呈现无上界有下界,但有一个严重的问题,即死区,当网络输出值在负半轴时,非激活状态一直延续到后层。解决方案有:

  • 平滑RELU,平滑H(x)或平滑整体x×H(x),也就是寻找max(0,x)的光滑版本,如果是前者,则寻找一个S型函数逼近即可。
  • 分段化RELU,使其负半轴取值不为0

简而言之,如果找到H(x)的光滑逼近函数,那么也就找到relu(x)的光滑逼近;如果找到max(0,x)的光滑逼近,那么也找到relu(x)​​的光滑。

RELU改进应该满足一下几点:

  • 平滑RELU的函数应该连续可导
  • 平滑RELU的函数负半轴应该非单调,以便增加非线性
  • 平滑RELU的函数,在x​较小时,Rs(x)≈x

RELU改进方案:

  • Noisy ReLU
  • Softplus

下面我们来谈谈它们的设计思路。

Noisy ReLU

考虑添加噪声

f(x)=max(0,x+Y),Y∼N(0,σ2)

这个激活函数的出发点是增加鲁棒性。

ELU & SELU

改变RELU死区问题的一个思路是分段化,负半轴通过一定技巧避免其取值为0,常见有ELU函数,

f(α,x)={α(ex−1) for x≤0x for x>0

其中 α≥0​ 。

SELU函数,

f(x,α)=λ{α(ex−1) for x<0x for x≥0

其中λ=1.0507,α=1.67326​​ ,这两个参数用来微调ELU激活函数。SELU激活函数来自论文Self-Normalizing Neural Networks。论文提到该激活函数不使用Normalization手段能够自动归一化。

Softplus

Softplus函数为,

f(x)=ln(1+ex)

我们都知道Logsumexp是max的光滑近似,

limα→∞1αlog(n∑i=1eαxi)=max(x1,…,xn)

因此取n=2,x1=x,x2=0,α=1​有,

relu(x)=max{0,x}≤ln(1+ex)

因为是 RELU 的光滑化版本,故称为 SmoothReLU。这里Logsumexp可以认为是Softplus的推广。

此外,还有积分思路,

relu(x)={0 for x≤0x for x>0=max{0,x}=∫x−∞H(x)dx≈∫x−∞11+e−2kxdx=12kln(1+e2kx)

取k=12​得Softplus函数。Softplus激活函数是单调的,负半轴无法提供更多的非线性功能。

Swish

过去的一篇文章Google的激活函数Swish是怎么设计出来的?也分析过Swish的导出,可参看。Swish函数为,

f(x)=xσ(x)

σ(x)可以看做是一个门,控制x​​的输出。易知,

relu(x)=max{0,x}=x×H(x)

然后注意到Heaviside step函数H(x)可以用tanh(x)逼近,即,

H(x)=ddxmax{0,x}={1,x>00,x≤0≈12+12tanh(kx)=11+e−2kx

我们取k=12​,有基于H(x)​光滑逼近的relu(x)​近似,

relu(x)≈x1+e−x=xσ(x)

后面的文章更新了Mish激活函数的分析,见Mish激活函数的设计思路

GELU,全称为Gaussian Error Linear Unit,也算是RELU的变种。对比一下和RELU的区别,

首先我们知道误差函数erf(x),

erf(x)=1√π∫x−xe−t2dt=2√π∫x0e−t2dt

是一个像logistics函数图像一样的函数,易证erf(x√2)∈(−1,1)​​,函数图像如下,

可以变换到(0,1)​​区间,即12[1+erf(x√2)]​​,是H(x)的光滑近似。有趣的是,标准正态分布的累积分布函数可以用erf(x)​​表示,

Φ(x)=1√2π∫x−∞e−t22dt=12(1+erf(x√2))∈(0,1)

GELU可以由标准正态分布的累积分布函数表示,

GELU(x)=xP(X≤x)=xΦ(x) GELU(x)≈x2[1+erf(x√2)]

由于12[1+erf(x√2)]​,是H(x)​​的光滑近似,于是有,

relu(x)=max{0,x}=x×H(x)≈x×12[1+erf(x√2)]=xΦ(x)=GELU(x)

论文Gaussian Error Linear Units (GELUs)中还有如下结论近似GELU(x),

GELU(x)≈x2[1+tanh(√2π(x+0.044715x3))]

测试该函数可以用scipy.special.erf,有些框架并没有提供该函数则会使用近似。也就有,

erf(x√2)≈tanh[√2π(x+0.044715x3)]

其实该近似挺符合我们的数学直觉,erf(x√2)本身是S型函数,tanh(x)也是S型函数,因此,

tanh(ax+bx3)

形式的函数也是S型函数,通过a,b参数控制S形状可以逼近erf(x√2)​​。

光滑近似的构造是相当灵活的,可以自行构造。例如根据

|x−y|≈√(x−y)2+α max(x,y)=|x+y|+|x−y|2=12((x+y)+√(x−y)2)≈12((x+y)+√(x−y)2+α),α→0

于是relu激活函数有近似,

relu(x)=max(0,x)≈12(x+√x2+α)

这里α→0取等号,实践中可以取α=0.01​。​

类似地,考虑|x|≈√x2+α,有​

H(x)={1,x>00,x≤0={12(x|x|+1),x≠00,x=0≈12(x√x2+α+1)

其中α​是一个可以小的数,如α=0.1​​。可视化图像如下,

考虑到relu(x)=x×H(x),只要找到H(x)的光滑近似,自然就有relu(x)的光滑近似。因此,也有,

relu(x)=x×H(x)≈x2(x√x2+α+1)

诸如此类,等等。

补充:更多自行设计激活函数的思路可看最新文章天马行空:设计自己的激活函数

本文从光滑近似的角度统一理解激活函数。函数光滑近似能够创造更多的性能优良的激活函数。

sigmoid类激活函数的本质是平滑H(x),relu类函数的本质是平滑relu(x)=x×H(x)。​

对relu(x)=max(0,x)=x×H(x)​的光滑近似能够创造更多的激活函数,光滑近似思路有两种,平滑H(x)​或平滑整体x×H(x)​​,如果是前者,则寻找一个S型函数逼近即可,不同的逼近方式获得不同的激活函数。

转载请包括本文地址:https://allenwind.github.io/blog/10705
更多文章请参考:https://allenwind.github.io/blog/archives/


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK