[Deep Learning] GELU

[Deep Learning] GELU ,第1张

[Deep Learning] GELU (Gaussian Error Linerar Units)

(转载请注明出处哦~)

参考链接:

1. 误差函数的wiki百科:https://zh.wikipedia.org/wiki/%E8%AF%AF%E5%B7%AE%E5%87%BD%E6%95%B0

2. 正态分布的博客:https://blog.csdn.net/hhaowang/article/details/83898881

3. StackExchange Mathematics: Why the error function is so similar to the hyperbolic tangent?

https://math.stackexchange.com/questions/1892553/why-the-error-function-is-so-similar-to-the-hyperbolic-tangent

4. WolframAlpha: y = tanh(x) - \int_{0}^{x}e^{-t^{2}}dt

https://www.wolframalpha.com/input/?i=y+%3D+tanh(x)+-+%5Cint_%7B0%7D%5E%7Bx%7De%5E%7B-t%5E%7B2%7D%7Ddt

前导知识:正态分布(section 1),误差函数(section 2),ReLU,ELU, dropout, zoneout.

5. GELU 论文:https://arxiv.org/abs/1606.08415

6. Data Science: What is GELU activation?  https://datascience.stackexchange.com/questions/49522/what-is-gelu-activation

7. Logistic vs Gaussian: http://visionlab.harvard.edu/Members/Anne/Math/Logistic_vs_Gaussian.html

8. Normal approximation to logistic distribution: https://www.johndcook.com/blog/2010/05/18/normal-approximation-to-logistic/

$$GELU(x) = \Phi(x) * I(x) + (1 - \Phi(x)) * 0x = x\Phi(x) $$

其近似为:

$$ GELU(x) = 0.5x(1 + tanh[\sqrt{2/\pi} (x + 0.044715x^3)]) $$

或者 $x\sigma(1.702x)$

TL; NR

GELU激活函数的最大特点是将非线性与依赖输入数据分布的随机正则化器相结合在一个激活函数的表达中。


与以往dropout指定随机概率值或ReLU根据输入值的正负进行mask的方式不同,GELU根据当前input大于其余inputs的概率进行随机正则化,即为在mask时依赖输入的数据分布。


Trick:对公式中的正态分布的累积分布函数进行了tanh三阶多项式近似,取得了相较于swish用sigmoid近似更好的效果。


博客中section1,2为推导tanh近似表达式的先导知识,不需要的话可以直接跳过,直接看section3.

1. 正态分布 1.1 定义

若随机变量$X$服从一个数学期望为$\mu$,方差为$\sigma^2$的正态分布,记为$N(\mu, \sigma^2)$。


当$\mu = 0$,$\sigma = 1$时的正态分布为标准正态分布。


  

图1. 正态分布的概率密度函数图像                                图2. 正态分布的累积分布函数图像

1.2 概率密度函数

1.3 累积分布函数

累积分布函数是指随机变量$X$小于或等于$x$的概率,用概率密度函数表示为:

正态分布的累积分布函数可以用“误差函数” erf 表示:

其中误差函数的表达式为:

1.4 标准正态分布

标准正态分布的累积分布函数:

用误差函数表示的公式简化可得:

它的反函数被称为反误差函数:

该分位数函数有时也被称为probit函数。


probit函数已被证明没有初等原函数。


正态分布的累积分布函数$\Phi(x)$没有解析表达式,它的值可以通过数值积分、泰勒级数、或者渐近序列近似得到。


2. 误差函数 2.1 定义

1) 误差函数,也称高斯误差函数(Error Function or Gauss Error Function), 是一个非基本函数(即不是初等函数)。


自变量为$x$ 的误差函数的定义为:

2) 互补误差函数

2.2 误差函数与正态分布

误差函数与标准正态分布的累积分布函数$\Phi$的关系为:

二者本质上是相同的。


2.3 性质(部分)

1) 误差函数是奇函数 $erf(-z) = -erf(z)$

2) 误差函数的导数

3) 泰勒级数

泰勒级数(Taylor Series) 的定义:

如果$f(x)$在点$x = x_0$具有任意阶导数,则幂函数

称为$f(x)$在点$x_0$处的泰勒级数。


注意区分泰勒公式和泰勒级数:泰勒级数要求在$x = x_0$处具有任意阶导数,而泰勒公式要求具有直到$n + 1$阶连续导数


泰勒公式

误差函数的泰勒级数:

4) 与Tanh的关系

$$erf(x) \approx 2/sqrt{\pi}tanh(x)$$

(1) 可以查看 WolframAlpha的关于二者对比的图像:

https://www.wolframalpha.com/input/?i=y+%3D+tanh(x)+-+%5Cint_%7B0%7D%5E%7Bx%7De%5E%7B-t%5E%7B2%7D%7Ddt

图3. $tanh(x) - \sqrt{\pi}/2erf(x)$的图像

可以看出,大约在 x < 0.8,二者非常接近。


(2) 也可以通过分析二者的泰勒级数来计算差距:

 当 $x < 0.809$时,

3. GELU

GELU: Gaussian Error Linear Unit 高斯误差线性单元

3.1 Abstract

GELU非线性的实现是对神经网络的输入进行随机正则化的变化,为输入匹配一个或0或1的随机值。


与ReLU的不同:GELU为其按照输入的magnitude(等级)为inputs加权值的;ReLUs是根据inputs的sign(正负)来gate(加门限)的。


论文实验证明GELU在多项计算机视觉, 自然语言处理,语音任务上效果优于ReLU, ELU。


3.2 Introduction

TL; NR:

1) 以往的激活函数为神经网络进入了非线性(binary threshold, sigmoid, ReLU, ELU, 及特点和优劣)

2) 另外神经网络中需要在网络层中加入一些noise,或通过加入dropout等方式进行随机正则化。


3) 以往的非线性和随机正则化这两部分基本都是互不相关的,因为辅助非线性变换的那些随机正则化器是与输入无关的。


4) GELU将非线性与随机正则化结合,是Adaptive Dropout的修改。


3.3 GELU Formulation

GELU的motivation是结合dropout, zoneout, ReLUs。


3.3.1 GELU与ReLU, dropout, zoneout 之间的联系与区别

1) dropout 与 ReLU:ReLU中Input乘以一个0或者1,所乘的值是确定的;dropout也会乘以一个0或者1,所乘的值是随机的;

2) zoneout:zoneout是一个RNN正则化器,它会为inputs随机乘1.

3) GELU:GELU也会为inputs乘以0或者1,但不同于以上的或有明确值或随机,GELU所加的0-1mask的值是随机的,同时是依赖于inputs的分布的


可以理解为:GELU的权值取决于当前的输入input有多大的概率大于其余的inputs.

3.3.2 GELU的表达式 1) 定义:

将input x 乘以一个服从伯努利分布的m。


而该伯努利分布又是依赖于输入Input x的。


$$ m \sim Bernoulli(\Phi(x)) , where \Phi(x) = P(X <= x)$$

$X \sim N(0, 1) $是标准正态分布的累积分布函数。


选用正态分布的原因:一般神经元的输入数据的分布倾向于服从正态分布,尤其是进行了BatchNorm之后。


如何理解呢?

举个例子:

有一个服从正态分布的随机变量X,它在不断地变化,它不停歇的沿着钟形曲线走来走去。


现在网络中有了 输入值 input x = x0,就在此刻这个服从正态分布的随机变量取值为 X = X0,就可以比较 X0 与 x0的大小了。


当然X是服从正态分布的,我们可以依据该概率分布函数的特点,分析出一般情况下 X有多大概率是小于某个确定值x的。


(比如P(X < 0.5) = 0.5)就得到了$\Phi(x)$。


正态分布的累积分布函数如上图2所示,可以看出当x变小时,P(X <= x)的值会减小,也就是当输入值inpuits 较小时,inputs被drop 的可能性更大。


GELU通过这种方式加mask,既保持了不确定性,又建立了与input的依赖关系


2) GELU的表达式:

$$GELU(x) = \Phi(x) * I(x) + (1 - \Phi(x)) * 0x = x\Phi(x) $$

其近似为:

$$ GELU(x) = 0.5x(1 + tanh[\sqrt{2/\pi} (x + 0.044715x^3)]) $$

或者 $x\sigma(1.702x)$

3) GELU的图示:

$$GELU(x):=xP(X<= x) = x\Phi(x) = 0.5x(1 + erf(x / \sqrt{2})) $$

图4. GELU函数图像

4) GELU的tanh近似表达的推导过程:

$$GELU(x):=xP(X<= x) = x\Phi(x) = 0.5x(1 + erf(x / \sqrt{2})) $$

$$erf(x) \approx 2/\sqrt{\pi} tanh(x)$$

因为gelu中含有erf项,无解析表达式,这里主要对该项进行近似表达。


(GELU论文中是引用的 Amit Choudhury. A simple approximation to the area under standard normal curve. In Mathematics and Statistics, 2014) (以下推导内容是网上搜集到的两种方法)

(1) 通过采样点拟合多项式参数的方法

因为在x = 0处 $erf(2 / \sqrt{2})$的一阶导与$tanh(\sqrt{2/\pi})$相同,均为$sqrt{2 / \pi}$,推导见下图5:

那么我们可以通过寻找

$$tanh(\sqrt{2/\pi}*(x + ax^2 + bx^3 + cx^4 + dx^5))$$

(或更多项的)系数来用tanh近似表示这一系列点的集合$(x_i, erf(x_i / \sqrt{2}))$

图5. $erf(2 / \sqrt{2})$的一阶导与$tanh(\sqrt{2/\pi})$均为$sqrt{2 / \pi}$的推导

之后,可以在https://mycurvefit.com/中输入erf的一些采样点,来拟合tanh函数的参数。


在https://datascience.stackexchange.com/questions/49522/what-is-gelu-activation中一个answer中采用了在(-1.5, 1.5)之间的20个采样点,得到的系数为:

图6. tanh函数内多项式系数

通过设置a = c = d = 0,得到b的估计值为 0.04495641。


如果采用更大的范围或更多的采样点,b将会更加接近0.044715.

所以可以推导出GELU论文中所给出的

$$ GELU(x) = 0.5x(1 + tanh[\sqrt{2/\pi} (x + 0.044715x^3)]) $$

(2) 通过泰勒展开拟合多项式系数

$$erf(x) = 2 / \sqrt{\pi} * (x - x^3 / 3) + o(x^3) $$

$$tanh(x) = x - x^3 / 3 + o(x^3) $$

我们已知:

那么带入后得到:

   

二者的对应项系数应相同。


解得 $a \approx 0.04553992412252714$ 与paper中的0.044715接近。


$$erf(x/\sqrt{2}) \approx tanh(\sqrt{2/\pi} (x + 0.044715x^3))$$

在pretrained-BERT-pytorch/modeling的代码中:

 def gelu(x):
"""Implementation of the gelu activation function.
For information: OpenAI GPT's gelu is slightly different (and gives slightly different results):
0.5 * x * (1 + torch.tanh(math.sqrt(2 / math.pi) * (x + 0.044715 * torch.pow(x, 3))))
Also see https://arxiv.org/abs/1606.08415
"""
return x * 0.5 * (1.0 + torch.erf(x / math.sqrt(2.0)))

tensorflow版本的GELU或是GPT使用的是上面红色注释中的公式。


其实由上面的推到可以知道,两段代码的GELU公式是近似的。


3.4 实验结果

3.4.1 MNIST 分类

图7. MNIST实验结果图示







其余实验结果请直接参考论文~

3.5 Discussion 3.5.1 GELU, ReLU, ELU形式上的包容

1) GELU 与ReLU

当$\sigma \rightarrow 0$, $\mu = 0$时,GELU将会变成ReLU.

GELU可以看做是对ReLU的平滑


(就像sigmoid是对binary threshold的平滑)

2) GELU与ELU

ELU函数: 

与ReLU 均为非负不同,GELU, ELU 均可正可负。


ELU可以看作是$xP(C <=x),  C \sim Cauchy(0, 1)$ (Cauchy distribution 柯西分布) 的变型,与GELU形式上相近。


3.5.2 GELU, ReLU, ELU的不同

1) GELU这个非凸、非单调的函数在正域内是非线性的,并且在所有点处都有曲率


ReLU, ELU是凸的、单调的函数,并且在正域处是线性的,因此会缺乏曲率。


鉴于此,所增加的曲率部分和非单调性也许可以使GELU表示更为复杂的函数。


(相较于ReLU, ELU)

2) ReLU为input加的权重取决于input的正负符号,而当$\mu = 0, \sigma = 1$时,GELU可以理解为其为input加的权值取决于当前的input有多大概率大于其余inputs.

因此,GELU具有概率方面的理解意义,即可以看作是随机正则化器的期望。


3.5.3 使用GELU的两条建议

1) 建议与momentum一起使用;

2) 使用高斯分布的累积分布函数的近似表示是非常重要的。


(这里介绍了sigmoid函数也是正态分布的累积分布函数的近似表示,但是Sigmoid Linear Unit (SiLU) xσ(x)的效果虽然比ReLU, ELU的效果好,但不如GELU。


因此最终采用的是$0.5x(1 + tanh[ \sqrt{2/\pi}(x + 0.044715x^3 )]))$或者$x\sigma(1.702x)$.

补充:logistic distribution和Gaussian distribution 是非常相近的,见图8。


http://visionlab.harvard.edu/Members/Anne/Math/Logistic_vs_Gaussian.html  相比较而言,Logistic distribution function的图像在尾处稍厚重一些。


       

图8. logistic与Gaussian对比                                  图9. Gaussian $\sigma = 1.6$时 Gaussian与logistic概率密度函数对比

Normal approximation to logistic distribution: https://www.johndcook.com/blog/2010/05/18/normal-approximation-to-logistic/ 这篇博客介绍了一般可以用正态分布改变$\sigma$来拟合logistic分布,(但logistic 可能很难用于拟合正态分布)。


以标准正态分布为例:当$\sigma \rightarrow 1.6$时,二者非常接近,最大相差为0.017.此时二者的图像见图9.

3.6 GELU的导数

我在https://www.desmos.com/calculator/l0puzw0zvm中画了一下GELU的图像和其对x求导的图像。


    

图10. GELU的图像和其对x求导的函数图像

由于paper中介绍说xσ(x)的效果不及GELU,所以,也画了一下swish(x) = xσ(x)的及其导数的图像:

    

图11. GELU与swish函数及其导数的函数图像

在谷歌的另一篇论文中介绍了swish函数,即为$swish(x) =xσ(x)$ 链接:https://arxiv.org/pdf/1710.05941.pdf

对比GELU与swish函数,GELU在正值区间的变化更为显著,因此具有稍高一些的梯度,在反向传播时可以更有效的更新梯度;

在负值区域,GELU函数的值相较于swish普遍更接近与x轴,因此具有更佳的单边抑制效果。


比较有意思的是GELU与swish的导数均在负值区间内出现了负数的情况,这与以往的激活函数ReLU, sigmoid, tanh等不同,这些激活函数的导数取值非负。


但是GELU导数的负值出现的更早,并且负值更小,swish有较长一段区间都有非常微小的负值,变化并不明显。


个人认为这可能是GELU效果优于xσ(x)及其他激活函数的原因之一。


即当input的值在接近-1边界时,可以通过负的导数的调节,将其拉回较大取值处。


GELU相较于swish可能有更好的调节效果。


另外,GELU的导数相较于xσ(x)的导数变化幅度更大一些,对于网络中权值的更新调节可能更为灵敏。


---这只是个人的理解,并非官方论文的结论。



 您愿意请我吃一根雪糕吗?[支付宝] O(∩_∩)O

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/586658.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-12
下一篇 2022-04-12

发表评论

登录后才能评论

评论列表(0条)

保存