Transformer 架构

Transformer 架构简介

Transformer 是一种革命性的深度学习架构,最初由 Vaswani 等人于 2017 年在论文《Attention is All You Need》中提出,广泛应用于自然语言处理(NLP)和计算机视觉等领域。它通过注意力机制(Attention Mechanism)取代传统的循环神经网络(RNN),实现了高效的并行计算和对长距离依赖的捕捉。本教程基于 2025 年 10 月的最新技术和 Python 生态(Python 3.10+),介绍 Transformer 架构的原理、组件、应用和代码示例,适合初学者和中级开发者。


1. Transformer 的核心概念

  • 定义:Transformer 是一种基于注意力机制的序列到序列(Sequence-to-Sequence)模型,擅长处理序列数据(如文本、图像序列)。
  • 核心思想:通过自注意力(Self-Attention)捕捉序列中任意两个位置的关系,避免 RNN 的序列化计算。
  • 关键特点
  • 并行化:支持批量处理序列,训练速度快。
  • 长距离依赖:有效捕捉远距离词语间的关系。
  • 可扩展性:适配 NLP、视觉和多模态任务。
  • 应用
  • NLP:机器翻译(如 Google Translate)、文本生成(如 GPT)、情感分析。
  • 计算机视觉:Vision Transformer(ViT)、图像生成。
  • 多模态:图文模型(如 CLIP)。

2. Transformer 架构详解

Transformer 由编码器(Encoder)解码器(Decoder)组成,每个部分包含多个堆叠层。以下是核心组件:

2.1 编码器(Encoder)

  • 结构:由 ( N ) 个(通常 ( N=6 ))相同的层组成,每层包含:
  1. 多头自注意力(Multi-Head Self-Attention)
    • 计算序列中每个词与所有词的相关性。
    • 公式:
      [
      \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V
      ]
      其中 ( Q )(查询)、( K )(键)、( V )(值)是输入向量的线性变换,( d_k ) 是维度。
    • 多头机制:并行计算多个注意力,捕捉不同语义。
  2. 前馈神经网络(Feed-Forward Neural Network, FFN)
    • 每个位置独立应用全连接层:( \text{FFN}(x) = \text{ReLU}(W_1x + b_1)W_2 + b_2 )。
  3. 残差连接和层归一化(Add & Norm)
    • 残差连接:( x + \text{SubLayer}(x) )。
    • 层归一化(Layer Normalization):稳定训练。
  • 输入
  • 词嵌入(Word Embedding)+ 位置编码(Positional Encoding)。
  • 位置编码:为每个词添加位置信息(如正弦/余弦函数或可学习参数)。

2.2 解码器(Decoder)

  • 结构:由 ( N ) 个层组成,每层包含:
  1. 掩码多头自注意力(Masked Multi-Head Self-Attention)
    • 屏蔽未来信息,防止解码器“看到”后续词。
  2. 多头交叉注意力(Multi-Head Cross-Attention)
    • 解码器输入与编码器输出交互。
  3. 前馈神经网络(FFN):同编码器。
  4. 残差连接和层归一化:同编码器。
  • 输出:预测下一个词或生成序列。

2.3 整体架构

  • 编码器:将输入序列转为上下文表示。
  • 解码器:基于编码器输出和已有序列生成目标序列。
  • 变体
  • 仅编码器:如 BERT,用于理解任务(分类、NER)。
  • 仅解码器:如 GPT,用于生成任务。
  • 编码器-解码器:如 T5,用于翻译、摘要。

3. Transformer 的优缺点

  • 优点
  • 并行计算,训练速度快(相比 RNN)。
  • 捕捉长距离依赖,性能优异。
  • 可扩展,适配多种任务。
  • 缺点
  • 计算复杂度高(自注意力为 ( O(n^2) ),( n ) 为序列长度)。
  • 内存需求大,需高效优化。
  • 对大规模数据依赖性强。
  • 改进
  • 高效 Transformer:如 Longformer、Performer(降低复杂度)。
  • 轻量模型:DistilBERT、TinyBERT。

4. 常用工具

以下是 2025 年主流的 Python 库,适合实现 Transformer:

  • PyTorch:灵活实现 Transformer 架构。
  • TensorFlow:提供 Transformer 模块,适合生产。
  • Transformers (Hugging Face):预训练模型(如 BERT、GPT、T5)。
  • spaCy/NLTK:辅助文本预处理。

安装命令

pip install torch tensorflow transformers nltk spacy
python -m spacy download en_core_web_sm  # 英语模型
python -m spacy download zh_core_web_sm  # 中文模型

5. Transformer 实现示例

5.1 自定义 Transformer 编码器

实现简单的 Transformer 编码器层,展示注意力机制和 FFN。


import torch
import torch.nn as nn
import torch.nn.functional as F
import math

缩放点积注意力

class ScaledDotProductAttention(nn.Module):
def init(self, d_k):
super(ScaledDotProductAttention, self).init()
self.d_k = d_k

def forward(self, Q, K, V, mask=None):
    scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(self.d_k)
    if mask is not None:
        scores = scores.masked_fill(mask == 0, -1e9)
    attn = F.softmax(scores, dim=-1)
    output = torch.matmul(attn, V)
    return output, attn

多头注意力

class MultiHeadAttention(nn.Module):
def init(self, d_model, num_heads):
super(MultiHeadAttention, self).init()
self.d_model = d_model
self.num_heads = num_heads
self.d_k = d_model // num_heads
self.W_q = nn.Linear(d_model, d_model)
self.W_k = nn.Linear(d_model, d_model)
self.W_v = nn.Linear(d_model, d_model)
self.W_o = nn.Linear(d_model, d_model)
self.attention = ScaledDotProductAttention(self.d_k)

def forward(self, Q, K, V, mask=None):
    batch_size = Q.size(0)
    Q = self.W_q(Q).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
    K = self.W_k(K).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
    V = self.W_v(V).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
    output, attn = self.attention(Q, K, V, mask)
    output = output.transpose(1, 2).contiguous().view(batch_size, -1, self.d_model)
    output = self.W_o(output)
    return output, attn

前馈网络

class FeedForward(nn.Module):
def init(self, d_model, d_ff):
super(FeedForward, self).init()
self.linear1 = nn.Linear(d_model, d_ff)
self.linear2 = nn.Linear(d_ff, d_model)

def forward(self, x):
    return self.linear2(F.relu(self.linear1(x)))

编码器层

class EncoderLayer(nn.Module):
def init(self, d_model, num_heads, d_ff, dropout=0.1):
super(EncoderLayer, self).init()
self.attention = MultiHeadAttention(d_model, num_heads)
self.norm1 = nn.LayerNorm(d_model)
self.ffn = FeedForward(d_model, d_ff)
self.norm2 = nn.LayerNorm(d_model)
self.dropout = nn.Dropout(dropout)

def forward(self, x, mask=None):
    attn_output, attn_weights = self.attention(x, x, x, mask)
    x = self.norm1(x + self.dropout(attn_output))
    ffn_output = self.ffn(x)
    x = self.norm2(x + self.dropout(ffn_output))
    return x, attn_weights

测试

d_model, num_heads, d_ff = 64, 4, 256
batch_size, seq_len = 2, 10
x = torch.rand(batch_size, seq_len, d_model)
encoder_layer = EncoderLayer(d_model, num_heads, d_ff)
output, attn_weights = encoder_layer(x)
print(“输出形状:”, output.shape)
print(“注意力权重形状:”, attn_weights.shape)

输出示例

输出形状: torch.Size([2, 10, 64])
注意力权重形状: torch.Size([2, 4, 10, 10])

说明

  • 多头注意力:并行计算 4 个注意力头。
  • FFN:扩展维度到 256,增加表达能力。
  • 残差连接和归一化:稳定训练。

5.2 使用 Hugging Face Transformer 进行情感分析

利用预训练 BERT(包含 Transformer 编码器)进行情感分析。


from transformers import pipeline

加载预训练 BERT 模型

classifier = pipeline(“sentiment-analysis”, model=”distilbert-base-uncased-finetuned-sst-2-english”)

测试文本

texts = [
“This movie is fantastic and highly recommended!”,
“The film was a complete disappointment.”
]
results = classifier(texts)

输出

for text, result in zip(texts, results):
print(f”文本: {text}”)
print(f”情感: {result[‘label’]}, 置信度: {result[‘score’]:.4f}”)

输出示例

文本: This movie is fantastic and highly recommended!
情感: POSITIVE, 置信度: 0.9998
文本: The film was a complete disappointment.
情感: NEGATIVE, 置信度: 0.9991

说明

  • 模型distilbert-base-uncased 是轻量 Transformer,包含 6 层编码器。
  • pipeline:简化推理,内置分词和分类。

5.3 微调 BERT 情感分析

微调 Transformer 模型,适配特定任务。


from transformers import BertTokenizer, BertForSequenceClassification
from transformers import Trainer, TrainingArguments
import torch
from torch.utils.data import Dataset
import nltk
from nltk.corpus import movie_reviews
from sklearn.model_selection import train_test_split
import re

nltk.download(‘movie_reviews’)

预处理函数

def preprocess_text(text):
text = re.sub(r’http\S+|[^\w\s]’, ”, text)
text = re.sub(r’\s+’, ‘ ‘, text).strip()
return text.lower()

自定义数据集

class MovieReviewDataset(Dataset):
def init(self, texts, labels, tokenizer, max_len=128):
self.texts = [preprocess_text(text) for text in texts]
self.labels = labels
self.tokenizer = tokenizer
self.max_len = max_len

def __len__(self):
    return len(self.texts)

def __getitem__(self, idx):
    text = self.texts[idx]
    label = self.labels[idx]
    encoding = self.tokenizer(text, truncation=True, padding='max_length', max_length=self.max_len, return_tensors='pt')
    return {
        'input_ids': encoding['input_ids'].flatten(),
        'attention_mask': encoding['attention_mask'].flatten(),
        'labels': torch.tensor(label, dtype=torch.long)
    }

准备数据

texts = [movie_reviews.raw(fileid) for fileid in movie_reviews.fileids()]
labels = [1 if fileid.startswith(‘pos’) else 0 for fileid in movie_reviews.fileids()]
train_texts, test_texts, train_labels, test_labels = train_test_split(texts, labels, test_size=0.2, random_state=42)

加载分词器和模型

tokenizer = BertTokenizer.from_pretrained(“distilbert-base-uncased”)
model = BertForSequenceClassification.from_pretrained(“distilbert-base-uncased”, num_labels=2)

创建数据集

train_dataset = MovieReviewDataset(train_texts, train_labels, tokenizer)
test_dataset = MovieReviewDataset(test_texts, test_labels, tokenizer)

训练参数

training_args = TrainingArguments(
output_dir=”./results”,
num_train_epochs=3,
per_device_train_batch_size=8,
evaluation_strategy=”steps”,
logging_steps=100,
save_steps=500,
)

训练

trainer = Trainer(model=model, args=training_args, train_dataset=train_dataset, eval_dataset=test_dataset)
trainer.train()

测试

test_text = preprocess_text(“This movie is fantastic and highly recommended!”)
inputs = tokenizer(test_text, return_tensors=”pt”, truncation=True, padding=True)
outputs = model(**inputs)
prediction = torch.argmax(outputs.logits, dim=1).item()
print(“预测情感:”, “正面” if prediction == 1 else “负面”)

说明

  • 模型:DistilBERT(6 层 Transformer 编码器),微调后适配情感分析。
  • 训练:需要 GPU,约 10-20 分钟。
  • 优势:Transformer 的注意力机制捕捉复杂语义。

6. Transformer 与 RNN 的比较

模型优点缺点适用场景
RNN/LSTM参数少,适合短序列梯度消失,序列化计算小型数据集,时间序列
Transformer并行计算,长依赖捕捉计算复杂,内存需求高大规模 NLP、视觉任务

趋势:2025 年,Transformer 因性能优势主导 NLP(如 BERT、LLaMA),但在边缘设备上,RNN 或轻量 Transformer 仍有应用。


7. 性能优化技巧

  • 模型优化
  • 轻量模型:DistilBERT、TinyBERT 减少参数。
  • 高效 Transformer:Longformer、Performer 降低 ( O(n^2) ) 复杂度。
  • 量化:使用 ONNX 或 torch.quantization
  • 数据优化
  • 缓存分词结果:保存 tokenizer 输出。
  • 批量处理:设置 batch_size=32
  • 硬件加速
  • GPU:确保 PyTorch 支持 CUDA(pip install torch --index-url https://download.pytorch.org/whl/cu118)。
  • TPU:TensorFlow 支持 TPU 加速。

8. 注意事项

  • 数据质量
  • 清洗文本,移除噪声(参考文本预处理教程)。
  • 序列长度:设置 max_len=128 平衡性能和效率。
  • 模型选择
  • 小型任务:DistilBERT 或 Sentence Transformers。
  • 复杂任务:BERT、RoBERTa、T5。
  • 语言支持
  • 英文:bert-base-uncaseddistilbert-base-uncased
  • 中文:bert-base-chinesehfl/chinese-roberta-wwm-ext
  • 评估:使用准确率、F1 分数,验证注意力权重(可视化 attn_weights)。

9. 进阶学习建议

  • 复杂模型
  • 编码器-解码器:实现 T5 或 BART(机器翻译、摘要)。
  • 视觉 Transformer:学习 ViT(图像分类)。
  • 多模态:结合 CLIP(图文任务)。
  • 优化技术
  • 高效注意力:学习 Sparse Transformer、Linformer。
  • 蒸馏:将大模型(如 BERT)蒸馏为小模型。
  • 可视化:使用 torch.nn.MultiheadAttentionattn_output_weights 可视化注意力。
  • 资源
  • Hugging Face 文档:Transformer 指南。
  • PyTorch Transformer:官方教程。
  • CSDN Transformer:中文案例。

如果你需要针对特定任务(如中文翻译、注意力可视化)或更复杂的实现(如 T5 微调),请告诉我,我可以提供详细代码和指导!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注