GELU函数的近似

(4) 2024-04-23 19:12

Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说GELU函数的近似,希望能够帮助你!!!。

一、背景

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

GELU函数的近似_https://bianchenghao6.com/blog__第1张

其中

GELU函数的近似_https://bianchenghao6.com/blog__第2张

考虑高斯误差函数

GELU函数的近似_https://bianchenghao6.com/blog__第3张

通过令GELU函数的近似_https://bianchenghao6.com/blog__第4张

GELU函数的近似_https://bianchenghao6.com/blog__第5张

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

二、方法

高斯误差函数的图像为

GELU函数的近似_https://bianchenghao6.com/blog__第6张

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)做近似。可以考虑两种拟合方式,局部拟合和全局拟合。全局拟合也就是数学里面的一致性问题。这里只考虑利用GELU函数的近似_https://bianchenghao6.com/blog__第7张对erf(x)进行拟合。

局部拟合

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

GELU函数的近似_https://bianchenghao6.com/blog__第8张

GELU函数的近似_https://bianchenghao6.com/blog__第9张

GELU函数的近似_https://bianchenghao6.com/blog__第10张

GELU函数的近似_https://bianchenghao6.com/blog__第11张

GELU函数的近似_https://bianchenghao6.com/blog__第12张

求解得到

GELU函数的近似_https://bianchenghao6.com/blog__第13张

此时,拟合的函数为

GELU函数的近似_https://bianchenghao6.com/blog__第14张

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()

GELU函数的近似_https://bianchenghao6.com/blog__第15张

全局拟合

考虑到GELU函数的近似_https://bianchenghao6.com/blog__第7张GELU函数的近似_https://bianchenghao6.com/blog__第17张的求解能够保证对GELU的一阶近似,这里我们先固定a,然后对b进行求解。即

GELU函数的近似_https://bianchenghao6.com/blog__第18张

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)

GELU函数的近似_https://bianchenghao6.com/blog__第19张
​​​​​​​

今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

上一篇

已是最后文章

下一篇

已是最新文章

发表回复