从Swish到SwiGLU:激活函数的进化与革命,qwen2.5应用的激活函数
swiGLU和RMSNorm
1.什么是swiGLU
SwiGLU(Swish-Gated Linear Unit)是一种结合了Swish激活函数和GLU(Gated Linear Unit)门控机制的激活函数,广泛应用于现代大型语言模型中
1.什么是Swish激活函数
1.1 Swish激活函数
Swish 激活函数是一种平滑的、非单调的激活函数,由 Google Brain 团队在 2017 年提出。它结合了 ReLU 的非线性特性与 Sigmoid 函数的平滑特性,旨在解决 ReLU 在某些情况下的局限性,例如梯度消失和“死亡神经元”问题。
1.2 Swish 激活函数的定义
Swish 的数学表达式为:
Swish
(
x
)
=
x
⋅
σ
(
β
x
)
\text{Swish}(x) = x \cdot \sigma(\beta x)
Swish(x)=x⋅σ(βx)
其中:
- σ ( x ) \sigma(x) σ(x) 是 Sigmoid 函数,定义为 σ ( x ) = 1 1 + e − x \sigma(x) = \frac{1}{1 + e^{-x}} σ(x)=1+e−x1 。
- β \beta β 是一个可选的缩放参数,通常在实际应用中设置为 1(即 β = 1 \beta = 1 β=1 )。
当 β = 1 \beta = 1 β=1 时,Swish 函数可以简化为:
$$\text{Swish}(x) = x \cdot \sigma(x) $$
1.3Swish 的特性
-
平滑性:
- Swish 是一个平滑的函数,其导数在任何地方都是连续的。这使得它在优化过程中能够避免 ReLU 的梯度消失问题。
- 平滑性也有助于模型在训练初期更快地收敛。
-
非单调性:
- Swish 是一个非单调函数,这意味着它的输出可以随着输入的增加而减少,这为模型提供了更丰富的表达能力。
-
自门控特性:
- Swish 的输出取决于输入 x x x 和 Sigmoid 函数的乘积,这使得它具有自门控的特性。这种特性允许模型动态地选择哪些信息是重要的,哪些可以被忽略。
-
可学习的参数:
- 在某些变体中,Swish 的缩放参数 β \beta β 是可学习的,这使得模型可以根据数据自动调整激活函数的形状。
1.4Swish 的优点
-
训练稳定性:
- Swish 的平滑性和非单调性使其在训练过程中更加稳定,尤其是在处理复杂数据集时。
-
性能提升:
- 在许多实验中,使用 Swish 的模型在性能上优于使用 ReLU 或其他激活函数的模型。
-
适用于深度网络:
- Swish 的特性使其在深度网络中表现良好,尤其是在需要处理长距离依赖关系的场景中。
1.5Swish 的缺点
-
计算复杂度:
- Swish 的计算复杂度比 ReLU 稍高,因为它需要计算 Sigmoid 函数。
-
可能的过拟合:
- 在某些情况下,Swish 的复杂性可能导致模型过拟合,尤其是在数据量较少时。
1.6Swish 的变体
-
SiLU(Sigmoid Linear Unit):
- SiLU 是 Swish 的一个变体,其中
β
=
1
\beta = 1
β=1 。它在 PyTorch 中被广泛使用,公式为:
SiLU ( x ) = x ⋅ σ ( x ) \text{SiLU}(x) = x \cdot \sigma(x) SiLU(x)=x⋅σ(x)
- SiLU 是 Swish 的一个变体,其中
β
=
1
\beta = 1
β=1 。它在 PyTorch 中被广泛使用,公式为:
-
Swish-1、Swish-β:
- Swish-1 是原始论文中提出的版本,其中 β = 1 \beta = 1 β=1 。
- Swish-β 是一个更通用的形式,其中 β \beta β 是一个可学习的参数。
1.7Swish 的代码实现
以下是一个基于 PyTorch 的 Swish 激活函数的实现:
import torch
import torch.nn as nn
import torch.nn.functional as F
class Swish(nn.Module):
def __init__(self, beta=1.0):
super(Swish, self).__init__()
self.beta = beta
def forward(self, x):
return x * torch.sigmoid(self.beta * x)
# 使用 SiLU(Swish-1)作为激活函数
class SiLU(nn.Module):
def forward(self, x):
return x * torch.sigmoid(x)
1.18为什么 Swish 被广泛使用?
Swish 的平滑性和非单调性使其在训练深度神经网络时表现出色,尤其是在处理复杂数据集和长距离依赖关系时。它在许多现代深度学习模型中被广泛使用,例如 Transformer、BERT 和一些大型语言模型。
通过上述介绍,可以更好地理解 Swish 激活函数的特性及其在深度学习中的重要性。
2.Gated Linear Unit (GLU)
即门控线性单元,是一种引入了门控机制的激活函数,广泛应用于深度学习模型中,尤其是在处理序列数据和自然语言处理任务时表现出色。
2.1GLU 的定义
GLU 的核心思想是将输入数据通过两个线性变换,其中一个变换的结果通过 Sigmoid 函数进行非线性处理,另一个保持线性,然后两者逐元素相乘。其数学表达式为:
GLU
(
x
)
=
σ
(
W
1
x
+
b
1
)
⊙
(
W
2
x
+
b
2
)
\text{GLU}(x) = \sigma(W_1 x + b_1) \odot (W_2 x + b_2)
GLU(x)=σ(W1x+b1)⊙(W2x+b2)
其中:
- σ \sigma σ 是 Sigmoid 函数,用于生成门控信号。
- W 1 W_1 W1 和 W 2 W_2 W2 是权重矩阵, b 1 b_1 b1 和 b 2 b_2 b2 是偏置项。
- ⊙ \odot ⊙ 表示逐元素乘法。
2.2GLU 的工作原理
-
线性变换:
- 输入 x x x 经过两个线性变换,分别得到 W 1 x + b 1 W_1 x + b_1 W1x+b1 和 W 2 x + b 2 W_2 x + b_2 W2x+b2。
- 第一个变换的结果通过 Sigmoid 函数,生成门控信号;第二个变换的结果保持线性。
-
门控机制:
- 门控信号 σ ( W 1 x + b 1 ) \sigma(W_1 x + b_1) σ(W1x+b1) 决定了哪些信息可以通过,哪些需要被抑制。
- 线性信号 W 2 x + b 2 W_2 x + b_2 W2x+b2 与门控信号逐元素相乘,从而实现信息的选择性传递。
-
输出:
- 最终输出是门控信号与线性信号的逐元素乘积,保留了输入数据的重要特征。
2.3GLU 的优势
-
选择性信息传递:
- 通过门控机制,GLU 能够动态决定哪些特征对模型的预测更有帮助,从而提高模型的表达能力。
-
非线性增强:
- GLU 结合了线性变换和非线性激活,使得模型能够学习复杂的模式。
-
高效计算:
- 相比 LSTM 和 GRU 等复杂的门控机制,GLU 的计算更加高效,同时避免了梯度消失问题。
-
并行处理能力:
- GLU 可以并行处理序列数据,类似于 Transformer 的机制,但计算复杂度更低。
2.4GLU 的变体
GLU 的变体通过替换 Sigmoid 激活函数来进一步优化性能,常见的变体包括:
- ReGLU:使用 ReLU 替代 Sigmoid。
- GEGLU:使用 GELU 替代 Sigmoid。
- SwiGLU:使用 Swish 替代 Sigmoid,是 GLU 的一种改进版本。
2.5GLU 的代码实现
以下是一个基于 PyTorch 的 GLU 实现示例:
import torch
import torch.nn as nn
import torch.nn.functional as F
class GLU(nn.Module):
def __init__(self, input_dim, output_dim):
super(GLU, self).__init__()
self.linear1 = nn.Linear(input_dim, output_dim)
self.linear2 = nn.Linear(input_dim, output_dim)
def forward(self, x):
gate = torch.sigmoid(self.linear1(x)) # 门控信号
linear = self.linear2(x) # 线性信号
return gate * linear # 逐元素相乘
3.SwiGLU(Swish-Gated Linear Unit)
一种结合了 Swish 激活函数 和 GLU(Gated Linear Unit) 特点的激活函数,广泛应用于现代深度学习模型中,尤其是在大型语言模型(如 LLaMA 和 PaLM)中表现出色。
3.1SwiGLU 的定义
SwiGLU 的数学表达式为:
SwiGLU
(
x
)
=
Swish
(
Linear
1
(
x
)
)
⊗
Linear
2
(
x
)
\text{SwiGLU}(x) = \text{Swish}(\text{Linear}_1(x)) \otimes \text{Linear}_2(x)
SwiGLU(x)=Swish(Linear1(x))⊗Linear2(x)
其中:
- Swish 是一个平滑的非线性激活函数,定义为 Swish ( x ) = x ⋅ σ ( x ) \text{Swish}(x) = x \cdot \sigma(x) Swish(x)=x⋅σ(x),其中 σ ( x ) \sigma(x) σ(x) 是 Sigmoid 函数。
- Linear 表示线性变换,通常由两个独立的全连接层实现。
- ⊗ 表示逐元素相乘。
3.2SwiGLU 的工作原理
-
线性变换:
- 输入
x
x
x 经过两个独立的线性变换:
- Linear 1 ( x ) \text{Linear}_1(x) Linear1(x) 的输出通过 Swish 激活函数,生成门控信号。
- Linear 2 ( x ) \text{Linear}_2(x) Linear2(x) 的输出保持线性。
- 输入
x
x
x 经过两个独立的线性变换:
-
门控机制:
- Swish 激活函数的输出作为门控信号,与线性变换的输出逐元素相乘,从而实现信息的选择性传递。
-
输出:
- 最终输出是门控信号与线性信号的逐元素乘积,保留了输入数据的重要特征。
3.3SwiGLU 的优势
-
平滑非线性:
- Swish 函数的平滑性使得反向传播的梯度更新更稳定,减轻梯度消失问题。
-
门控特性:
- GLU 的门控机制允许模型动态调整信息流,增强模型对长序列数据的处理能力。
-
高效计算:
- 尽管引入了额外的非线性激活函数,SwiGLU 的计算开销相对较小,适合大规模模型。
-
性能提升:
- 在多个基准测试中,SwiGLU 表现出色,优于 GLU、ReLU 等传统激活函数。
3.4SwiGLU 的应用场景
SwiGLU 广泛应用于以下领域:
- 自然语言处理:如语言建模、机器翻译和文本生成。
- 计算机视觉:如视觉 Transformer(ViT)等结构。
- Transformer 架构:如 GPT 系列和 BERT 的改进版本。
3.5SwiGLU 的代码实现
以下是一个基于 PyTorch 的 SwiGLU 实现示例:
import torch
import torch.nn as nn
import torch.nn.functional as F
class SwiGLU(nn.Module):
def __init__(self, input_dim, hidden_dim):
super(SwiGLU, self).__init__()
self.linear1 = nn.Linear(input_dim, hidden_dim)
self.linear2 = nn.Linear(input_dim, hidden_dim)
self.swish = nn.SiLU() # 使用内置的 Swish 激活函数
def forward(self, x):
return self.linear1(x) * self.swish(self.linear2(x))
# 示例输入
x = torch.randn(4, 128) # Batch size 4, input dimension 128
model = SwiGLU(input_dim=128, hidden_dim=256)
output = model(x)
print(output.shape) # 输出维度为 (4, 256)
3.6总结
SwiGLU 通过结合 Swish 的平滑非线性特性和 GLU 的门控机制,提供了一种高效的激活函数,适用于需要复杂非线性转换的任务,如自然语言处理和计算机视觉。