干翻全岛蛙蛙 发表于 2024-8-14 17:05:22

Transformer架构中FFN层激活函数的演进与应用

Transformer模子自2017年被提出以来,在天然语言处理领域取得了巨大成功。随着研究的深入,模子的各个组件都在不断优化。本文将聚焦于Transformer架构中前馈神经网络(Feed-Forward Network, FFN)层的激活函数,探讨从最初的ReLU到近期广受欢迎的SwiGLU的演进过程。
1. Transformer架构简介

Transformer模子主要由多头注意力层(Multi-Head Attention)和前馈神经网络层交替堆叠而成。以编码器为例,其结构如下:
https://i-blog.csdnimg.cn/direct/03e4396afee04576b72e094f85e16e68.png
FFN层在Transformer架构中饰演着重要角色,它可以或许增加模子的非线性表达本领,资助捕捉更复杂的特征。
2. 使用ReLU激活的FFN

2.1 ReLU激活函数

最初的Transformer架构采用了ReLU(Rectified Linear Unit)作为FFN层的激活函数。ReLU的界说如下:
ReLU(x) = max(0, x)
ReLU函数简单高效,在x>0时保持线性关系,在x≤0时输出为0,这种特性有助于缓解梯度消散题目。
2.2 ReLU-FFN的数学表达

使用ReLU激活的FFN层可以表示为:
FFN_ReLU(x, W₁, W₂, b₁, b₂) = ReLU(xW₁ + b₁)W₂ + b₂
此中,x是输入向量,W₁和W₂是权重矩阵,b₁和b₂是偏置项。
值得注意的是,一些实现(如T5模子)选择省略偏置项,简化为:
FFN_ReLU(x, W₁, W₂) = ReLU(xW₁)W₂
3. 使用GELU激活的FFN

3.1 GELU激活函数

GELU(Gaussian Error Linear Unit)是由Dan Hendrycks和Kevin Gimpel在2016年提出的,可以看作是ReLU的平滑版本。GELU的界说如下:
GELU(x) = x * Φ(x)
此中,Φ(x)是标准正态分布的累积分布函数。
3.2 GELU vs ReLU

为了直观地比较GELU和ReLU,我们可以绘制它们的函数图像:
https://i-blog.csdnimg.cn/direct/0341101baf884272a90a7652203bf875.png
从图中可以看出,GELU在负值地区有非零输出,这使得它可以或许在反向传播时传递更多信息。
3.3 GELU-FFN的数学表达

使用GELU激活的FFN层可以表示为:
FFN_GELU(x, W₁, W₂) = GELU(xW₁)W₂
GELU的一个实际题目是计算复杂度较高。为了进步服从,通常会使用近似计算方法。比方,可以使用如下近似:
GELU(x) ≈ 0.5x(1 + tanh(√(2/π)(x + 0.044715x³)))
4. 使用Swish激活的FFN

4.1 Swish激活函数

Swish激活函数由Prajit Ramachandran等人在2017年提出,是另一种ReLU的平滑版本。Swish的界说如下:
Swish_β(x) = x * σ(βx)
此中,σ是sigmoid函数,β是一个可学习参数。当β=1时,我们得到标准的Swish函数。
4.2 Swish vs GELU vs ReLU

我们可以将Swish与GELU和ReLU进行比较:
https://i-blog.csdnimg.cn/direct/8d16d37ce5284c25b1b1aa90721361b1.png
从图中可以看出,Swish在负值地区也有非零输出,且通过调整β参数可以灵活地控制函数形状。
4.3 Swish-FFN的数学表达

使用Swish激活的FFN层可以表示为:
FFN_Swish(x, W₁, W₂) = Swish₁(xW₁)W₂
5. GLU及其变体

5.1 GLU简介

GLU(Gated Linear Units)严格来说不是一种激活函数,而是一种神经网络层结构。它结合了线性变换和门控机制,可以表示为:
GLU(x, W, V, b, c) = σ(xW + b) ⊗ (xV + c)
此中,σ是sigmoid函数,⊗表示逐元素乘法。
5.2 SwiGLU

SwiGLU是GLU的一个变体,它使用Swish函数替换了sigmoid函数:
SwiGLU(x, W, V, b, c) = Swish₁(xW + b) ⊗ (xV + c)
SwiGLU在近期的大型语言模子中得到广泛应用,如Google的PaLM和Meta的LLaMA都采用了这种激活函数。
5.3 SwiGLU的实现

在实际实现中,为了保持参数量稳定,通常会对隐藏层大小进行缩放。以下是一个PyTorch实现示例:
class FeedForward(nn.Module):
    def __init__(self, dim: int, hidden_dim: int, multiple_of: int, dropout: float):
      super().__init__()
      hidden_dim = multiple_of * ((2 * hidden_dim // 3 + multiple_of - 1) // multiple_of)
      self.w1 = nn.Linear(dim, hidden_dim)
      self.w2 = nn.Linear(hidden_dim, dim)
      self.w3 = nn.Linear(dim, hidden_dim)
      self.dropout = nn.Dropout(dropout)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
      return self.dropout(self.w2(F.silu(self.w1(x)) * self.w3(x)))
注意,这里使用的是F.silu函数,它实际上就是β=1时的Swish函数。
6. 结论

Transformer架构中FFN层的激活函数从最初的ReLU发展到现在的SwiGLU,每一次改进都为模子性能带来了提拔。这些激活函数的演进反映了研究者们对非线性变换的深入明白和不断探索。
在实际应用中,选择符合的激活函数需要思量多个因素,包罗但不限于:计算服从、梯度流动性、表达本领等。随着研究的深入,我们可能会看到更多新型激活函数的出现,进一步推动Transformer模子的性能提拔。
参考文献


[*]Vaswani, A., et al. (2017). Attention is All you Need.
[*]Hendrycks, D., & Gimpel, K. (2016). Gaussian Error Linear Units (GELUs).
[*]Ramachandran, P., et al. (2017). Swish: a Self-Gated Activation Function.
[*]Shazeer, N. (2020). GLU Variants Improve Transformer.

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Transformer架构中FFN层激活函数的演进与应用