GeLU、ReLU函数学习

GeLU高斯误差线性单元

在bert模型里,里边的激活函数不是Relu等常见的函数,是一个新的激活函数GELU。

在神经网络的建模过程中,模型很重要的性质就是非线性,同时为了模型泛化能力,需要加入随机正则,例如dropout(随机置一些输出为0,其实也是一种变相的随机非线性激活), 而随机正则与非线性激活是分开的两个事情, 而其实模型的输入是由非线性激活与随机正则两者共同决定的。

GELU正是在激活中引入了随机正则的思想,是一种对神经元输入的概率描述,直观上更符合自然的认识,同时实验效果要比Relu与ELU都要好。

GELUs其实是 dropout、zoneout、Relus的综合,GELUs对于输入乘以一个0,1组成的mask,而该mask的生成则是依概率随机的依赖于输入。假设输入为X, mask为m,则m服从一个伯努利分布(Φ(x), Φ ( x ) = P ( X < = x ) , X服从标准正太分布 ),这么选择是因为神经元的输入趋向于正太分布,这么设定使得当输入x减小的时候,输入会有一个更高的概率被dropout掉,这样的激活变换就会随机依赖于输入了。

公式可表达成:

                                             GELU(x)=xP(X<=x)=xΦ(x)

这里Φ(x)是正太分布的概率函数,可以简单采用正太分布N(0,1), 也可以使用参数化的正太分布N ( μ , σ ), 然后通过训练得到μ , σ 。
对于假设为标准正太分布的G E L U ( x ) GELU(x)GELU(x), 论文中提供了近似计算的数学公式,如下:

在这里插入图片描述
BERT源码给出的代码如下:

def gelu(input_tensor):
	cdf = 0.5 * (1.0 + tf.erf(input_tensor / tf.sqrt(2.0)))
	return input_tesnsor*cdf

ReLU激活

激活函数的引入是为了增加神经网络模型的非线性,没有激活函数每层就相当于矩阵相乘。每一层输出都是上层的输入的线性函数,无论神经网络多少层,输出都是输入的线性组合,就是最原始的感知机。
加入激活函数,给神经元引入非线性因素,神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。

ReLU函数是目前比较火的一个激活函数,函数公式:f ( x ) = max( 0 , x )

函数图像如下:
在这里插入图片描述

相比sigmod函数与tanh函数有以下几个优点
1)克服梯度消失的问题
2)加快训练速度
注:正因为克服了梯度消失问题,训练才会快

缺点:
1)输入负数,则完全不激活,ReLU函数死掉。
2)ReLU函数输出要么是0,要么是正数,也就是ReLU函数不是以0为中心的函数

深度学习中最大的问题是梯度消失问题,使用tanh、sigmod等饱和激活函数情况下特别严重(神经网络在进行方向误差传播时,各个层都要乘以激活函数的一阶导数,梯度每传递一层就会衰减一层,网络层数较多时,梯度G就会不停衰减直到消失),使得训练网络收敛越来越慢,而ReLU函数凭借其线性、非饱和的形式,训练速度则快很多。

文章GeLU提到论文参考链接:https://arxiv.org/abs/1606.08415

### GELU 激活函数作为 ReLU 的替代 Gaussian Error Linear Unit (GELU) 是一种基于高斯误差线性的激活函数,在神经网络中表现出优于传统 ReLU 函数的效果。与 ReLU 不同的是,GELU 提供了一个平滑过渡而非硬阈值化处理方式。 #### 数学表达形式 ReLU GELU 主要区别在于其数学定义: 对于输入 \( x \),ReLU 定义如下: \[ f(x)=\max(0,x) \] 而 GELU 则通过累积分布函数来计算输出: \[ \text{GELU}(x) = x * P(X ≤ x) = 0.5x\left(1+\operatorname{tanh}\left[\sqrt{\frac{2}{\pi}}\left(x + 0.044715x^{3}\right)\right]\right) \][^1] 这种特性使得 GELU 能够更好地保持梯度流动并减少死区现象的发生概率。 #### 实现代码示例 以下是 Python 中使用 PyTorch 库实现 GELU 替代 ReLU 的简单例子: ```python import torch.nn as nn class Model(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(Model, self).__init__() # 使用 GELU 替换 ReLU self.fc1 = nn.Linear(input_size, hidden_size) self.gelu = nn.GELU() self.fc2 = nn.Linear(hidden_size, output_size) def forward(self, x): out = self.fc1(x) out = self.gelu(out) # 运用 GELU 激活函数 out = self.fc2(out) return out ``` #### 性能优势 相比于传统的 ReLU 激活函数,GELU 展现出以下几个方面的改进: - **更少的死亡神经元**:由于采用了软饱机制而不是硬截断的方式,因此减少了因负数输入导致权重更新停滞的情况。 - **更好的收敛速度**:实验表明采用 GELU 可以加速训练过程中的损失下降趋势[^2]。 - **更高的泛化能力**:在某些情况下,GELU 表现出更强的数据拟合能力测试集上的表现提升。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值