GELU函数的近似

一、背景

GELU(Gaussian Error Linear Unit)函数的定义为

GELU(x)=x\Phi (x)

其中

\Phi (x)=\frac{1}{\sqrt{2\pi }}\int_{-\infty }^{x}e^{-\frac{t^2}{2}}dt=\frac{1}{2}+\frac{1}{\sqrt{2\pi }}\int_{0 }^{x}e^{-\frac{t^2}{2}}dt

考虑高斯误差函数

erf(x)=\frac{2}{\sqrt{\pi }}\int_{0}^{x}e^{-t^2}dt

通过令t=\sqrt{2}u

GELU(x)=x\Phi (x)=x(\frac{1}{2}+\frac{1}{2}erf(\frac{x}{\sqrt{2}}))

由于高斯误差函数里面涉及了指数运算和积分运算,如何利用初等函数进行拟合,对于提高运算效率就显得比较有意义了。

二、方法

高斯误差函数的图像为

from scipy.special import erf 
import numpy as np 
import matplotlib.pyplot as plt 

fig, ax = plt.subplots()

ax.spines['right'].set_visible(False)
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))


x=np.linspace(-5,5,100)
y=erf(x)

plt.plot(x,y)
plt.title('graph of erf function')
plt.show()

可以验证erf(x)为奇函数,首先想到的是利用tanh(x)做近似。可以考虑两种拟合方式,局部拟合和全局拟合。全局拟合也就是数学里面的一致性问题。这里只考虑利用tanh(ax+bx^3)对erf(x)进行拟合。

局部拟合

局部拟合考虑利用泰勒展开,拟合前几项的系数

erf(x)=\frac{2}{\sqrt{\pi }}\int_{0}^{x}e^{-t^2}dt =\frac{2}{\sqrt{\pi }}\int_{0}^{x}[1-t^2+\frac{t^4}{2}+...]dt =\frac{2}{\sqrt{\pi }}\(x-\frac{x^3}{3}+...)

tanh(x)=x-\frac{x^3}{3}+\frac{2}{15}x^5+...

erf(\frac{x}{\sqrt{2}})-tanh(ax+bx^3)=\frac{2}{\sqrt{\pi }}\(\frac{x}{\sqrt{2}}-\frac{x^3}{3*2\sqrt{2}}+...)-(ax+bx^3)+\frac{​{(ax+bx^3)}^3}{3}=(\sqrt{\frac{2}{\pi}}-a)x+(\frac{a^3}{3}-b-\frac{2}{3\sqrt{2\pi }})x^3+...

\sqrt{\frac{2}{\pi }}-a=0\\ \frac{a^3}{3}-b-\frac{1}{3\sqrt{2\pi }}=0

求解得到

a=\sqrt{\frac{2}{\pi }}\\ b=\frac{4-\pi}{3\sqrt{2}\pi^{3/2}}

此时,拟合的函数为

GELU(x)=x\Phi (x)\approx \frac{1}{2}(1+ tanh(\sqrt{\frac{2}{\pi}}(x+0.04553992412252712))

import numpy as np 
import matplotlib.pyplot as plt 

a=np.sqrt(2/np.pi)
b=(4-np.pi)/(3*np.sqrt(2)*np.pi**(3/2))
b1=(4-np.pi)/(6*np.pi)

x=np.linspace(-5,5,100)
#y=erf(x)
def gelu(x):
    return 1/2*x*(1+erf(x/np.sqrt(2)))
def gelu_pro1(x):
    return 1/2*x*(1+np.tanh(np.sqrt(2/np.pi)*(x+b1*x**3)))

fig, ax = plt.subplots()
ax.spines['right'].set_visible(False)
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))

plt.plot(x,gelu(x))
plt.plot(x,gelu_pro1(x),'r-')
plt.legend(['gelu','gelu_pro'])
plt.title('performance of the approximate')
plt.show()

全局拟合

考虑到tanh(ax+bx^3)a的求解能够保证对GELU的一阶近似,这里我们先固定a,然后对b进行求解。即

\min_{b}\max_{x}|erf(\frac{x}{\sqrt{2}})-tanh(ax+bx^3)|

import numpy as np 
from scipy.special import erf 
from scipy.optimize import minimize


a=np.sqrt(2/np.pi)

def f(x,b):
    return np.abs(erf(x/np.sqrt(2))-np.tanh(a*x+b*x**3))

def g(b):
    return np.max([f(x,b) for x in np.arange(0,4,0.001)])

options={'xtol':1e-10,'ftol':1e-10,'maxiter':100000}
result=minimize(g,0,method='Powell',options=options)
print(result.x)


​​​​​​​

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值