神经网络常见激活函数 10-GELU函数

GELU

  • 高斯误差线性单元(Gaussian error linear unit)

函数+导函数

  • GELU函数的公式 (近似表达式)
    G E L U ( x ) = x ∗ P ( X < = x ) = x ∗ Φ ( x ) \rm GELU(x) = x*P(X<=x)=x*\Phi(x) GELU(x)=xP(X<=x)=xΦ(x)
    其中 Φ ( x ) \Phi(x) Φ(x) 指的是 x 的高斯正太分布的累积分布函数(CDF),进一步地,可得该函数的具体表达为
    x ∗ P ( X < = x ) = x ∫ − ∞ x e − ( X − μ ) 2 2 σ 2 2 π σ d X x*P(X<=x) = x \int^x_{-\infty} \frac{e^{-\frac{(X-\mu)^2}{2\sigma^2}}}{\sqrt{2\pi}{}\sigma} dX xP(X<=x)=xx2π σe2σ2(Xμ)2dX

    其中 μ , σ \mu ,\sigma μ,σ 分别代表正太分布的均值和方差,由于上面这个函数是无法直接计算的,所以研究证在研究过程中发现可以被近似的表示为
    G E L U ( x ) = 0.5 × x × ( 1 + tanh ⁡ [ 2 π × ( x + 0.044715 x 3 ) ] ) \rm GELU(x) = 0.5 \times x \times \left( 1 + \tanh{\left[\sqrt{\frac{2}{\pi}}{} \times (x+0.044715x^3)\right]} \right) GELU(x)=0.5×x×(1+tanh[π2 ×(x+0.044715x3)])

    或者
    G E L U ( x ) = x ∗ σ ( 1.702 x ) \rm GELU(x) = x * \sigma(1.702x) GELU(x)=xσ(1.702x)
    其中 $\sigma(x) $ 代表 Sigmoid 函数。

  • GELU函数的公式 (误差函数 erf 的表达式)
    G E L U ( x ) = x ⋅ Φ ( x ) = x ⋅ 1 2 ( 1 + e r f ( x 2 ) ) \begin{aligned} \rm GELU(x) &= x\cdot\Phi(x) \\ &=x\cdot\frac{1}{2}(1+erf(\frac{x}{\sqrt{2}{}})) \end{aligned} GELU(x)=xΦ(x)=x21(1+erf(2 x))
    其中 Φ ( x ) \Phi(x) Φ(x) 指的是 x 的高斯正太分布的累积分布函数(CDF), e r f ( x ) erf(x) erf(x)是误差函数
    e r f ( x ) = 2 π ∫ 0 x e − t 2 d t \rm erf(x) = \frac{2}{\sqrt{\pi}{}} \int^x_0e^{-t^2} dt erf(x)=π 20xet2dt
  • GELU函数导数

    已知 ϕ ( x ) \phi(x) ϕ(x) 是标准正太分布的概率密度函数 (PDF)
    ϕ ( x ) = 1 2 π e − x 2 2 \phi(x) = \frac{1}{\sqrt{2\pi}{}} e^{-\frac{x^2}{2}} ϕ(x)=2π 1e2x2

    以及 Φ ( x ) \Phi(x) Φ(x)
    Φ ( x ) = x ⋅ 1 2 ( 1 + e r f ( x 2 ) ) \Phi(x) = x\cdot\frac{1}{2}(1+erf(\frac{x}{\sqrt{2}{}})) Φ(x)=x21(1+erf(2 x))


    d d x G E L U ( x ) = ( x ⋅ Φ ( x ) ) ′ = Φ ( x ) + x ⋅ ( Φ ′ ( x ) ) = Φ ( x ) + x ⋅ 1 2 π e − 1 x 2 = Φ ( x ) + x ⋅ ϕ ( x ) \begin{aligned} \frac{d}{dx} \rm GELU(x) & = (x\cdot\Phi(x))' \\ &=\Phi(x) + x \cdot(\Phi'(x)) \\ &=\Phi(x) + x \cdot \frac{1}{\sqrt{2\pi}} e^{-\frac{1}{x^2}} \\ &= \Phi(x) + x\cdot\phi(x) \end{aligned} dxdGELU(x)=(xΦ(x))=Φ(x)+x(Φ(x))=Φ(x)+x2π 1ex21=Φ(x)+xϕ(x)


函数和导函数图像

  • 画图

    import numpy as np
    from scipy.special import erf
    import matplotlib.pyplot as plt
    
    # 定义 GELU 函数
    def gelu(x):
        return 0.5 * x * (1 + erf(x / np.sqrt(2)))  # 使用误差函数 erf 计算[^1^][^3^]
    
    # 定义 GELU 的导数
    def gelu_derivative(x):
        return 0.5 * (1 + erf(x / np.sqrt(2))) + (x / np.sqrt(2 * np.pi)) * np.exp(-x ** 2 / 2)  # 导数公式[^3^]
    
    # 生成数据
    x = np.linspace(-5, 5, 1000)
    y = gelu(x)
    y1 = gelu_derivative(x)
    
    # 绘制图形
    plt.figure(figsize=(12, 8))
    ax = plt.gca()
    plt.plot(x, y, label='GELU')
    plt.plot(x, y1, label='Derivative')
    plt.title('GELU and Derivative')
    
    # 设置上边和右边无边框
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')
    
    # 设置 x 坐标刻度数字或名称的位置
    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.legend(loc=2)
    plt.show()
    

    GELU


优缺点

  • GELU 的优点

    1. 当方差为无穷大,均值为 0 的时候,GeLU就等价于ReLU了。GELU可以当作为RELU的一种平滑策略。GELU是非线性输出,具有一定的连续性。GELU有一个概率解释,因为它是一个随机正则化器的期望。

    2. GELU的实用技巧。首先,建议在使用GELU训练时使用具有动量的优化器,这是深度神经网络的标准。其次,使用对高斯分布的累积分布函数的密切近似是很重要的

  • GELU 的缺点

    1. 计算复杂度增加:GELU的计算比ReLU等更简单的选择更为复杂,因为它涉及误差函数或其近似值。
    2. 性能依赖于任务:激活函数的有效性可能因任务和数据集而异。
    3. 复杂性导致解释性降低:由于其复杂的行为,可能更难以解释和调试。

pytorch中的GELU函数

  • 代码

    import torch
    
    # 定义 GELU 函数
    f = torch.nn.GELU()  # PyTorch 提供的 GELU 激活函数模块
    x = torch.randn(2)   # 生成一个随机张量作为输入
    
    gelu_x = f(x)        # 应用 GELU 函数
    
    print(f"x: \n{x}")
    print(f"gelu_x:\n{gelu_x}")
    
    """输出"""
    x: 
    tensor([ 1.6743, -1.2534])
    gelu_x:
    tensor([ 1.5956, -0.1316])
    

tensorflow 中的GELU函数

  • 代码

    python: 3.10.9

    tensorflow: 2.18.0

    import tensorflow as tf
    
    # 创建 GELU 激活函数
    gelu = tf.keras.activations.gelu
    
    # 生成随机输入
    # x = tf.random.normal([2])
    x = [ 1.6743, -1.2534]
    
    # 应用 GELU 激活函数
    gelu_x = gelu(x)
    
    print(f"x: \n{x}")
    print(f"gelu_x:\n{gelu_x}")
    
    """输出"""
    x: 
    [1.6743, -1.2534]
    gelu_x:
    [ 1.5955479  -0.13164471]
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值