Transformer 模型核心原理与从零实现详解
Transformer 是一种基于自注意力机制的神经网络架构,广泛应用于自然语言处理任务。本文详细解析了 Transformer 的核心组件,包括自注意力机制、位置编码、多头注意力及前馈网络,并通过纯 Python 和 NumPy 从零实现了一个简化版的 Transformer 模型。内容涵盖数学公式推导、数据预处理流程以及完整的代码示例,帮助读者深入理解模型内部运作机制。
1. Transformer 简介
传统的序列建模方法(如 RNN 或 LSTM)是按顺序处理数据的,这限制了并行计算的能力,且难以捕捉长距离依赖关系。Transformer 通过引入自注意力机制(Self-Attention),能够一次性处理整个序列,并直接建立任意两个词之间的关联,无论它们之间的距离有多远。
1.1 核心优势
- 并行处理:不再依赖时间步,训练速度显著提升。
- 长距离依赖:自注意力机制允许模型关注序列中的任意位置。
- 可扩展性:结构易于堆叠,适合构建深层网络。
2. 核心组件详解
2.1 自注意力机制 (Scaled Dot-Product Attention)
自注意力机制是 Transformer 的灵魂。其目标是为序列中的每个元素生成一个上下文相关的表示。过程如下:
- 输入向量:每个词通过嵌入层得到向量表示 $X$。
- 生成 Query, Key, Value:对于每个输入向量,通过可学习的权重矩阵 $W^Q, W^K, W^V$ 生成 Query ($Q$), Key ($K$), Value ($V$)。 $$ Q = XW^Q, \quad K = XW^K, \quad V = XW^V $$
- 计算注意力得分:计算 $Q$ 和 $K$ 的点积,并除以缩放因子 $\sqrt{d_k}$ 以防止梯度消失。 $$ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V $$ 其中 $d_k$ 是 Key 向量的维度。
2.2 位置编码 (Positional Encoding)
由于 Transformer 不处理序列的顺序信息,必须显式地注入位置信息。通常使用正弦和余弦函数生成位置编码矩阵 $PE$,将其加到输入嵌入上: $$ PE_{(pos, 2i)} = \sin(pos / 10000^{2i/d_{model}}) $$ $$ PE_{(pos, 2i+1)} = \cos(pos / 10000^{2i/d_{model}}) $$ 这使得模型能够区分不同位置的词。
2.3 多头注意力 (Multi-Head Attention)
为了增强模型的表达能力,Transformer 将自注意力机制重复多次(多头),并在最后拼接输出。每个头学习不同的子空间特征: $$ \text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, ..., \text{head}_h)W^O $$ 其中 $\text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V)$。
2.4 前馈网络与残差连接
每个注意力层后接一个全连接的前馈网络(FFN),通常包含两个线性变换和一个激活函数(如 ReLU)。同时,所有子层都采用残差连接(Residual Connection)和层归一化(Layer Normalization)来稳定训练。
3. 案例构建:基于 NumPy 的实现
为了深入理解原理,我们使用基础 Python 库(NumPy, Pandas)从零实现一个简化的 Transformer 情感分类器,不使用 PyTorch 或 TensorFlow。
3.1 数据集准备
我们使用 IMDb Movie Reviews 数据集进行二分类(正面/负面情感)。
import numpy as np
import pandas pd
re
sklearn.model_selection train_test_split
:
df = pd.read_csv()
FileNotFoundError:
df = pd.DataFrame({: [, ],
: [, ]})
():
text = re.sub(, , (text))
text = re.sub(, , (text))
text.lower()
df[] = df[].apply(clean_text)
df[] = df[].({: , : })
X_train, X_test, y_train, y_test = train_test_split(
df[], df[], test_size=, random_state=
)


