人工智能之语言领域
第十一章 注意力机制
文章目录
- 人工智能之语言领域
- [前言 注意力机制](#前言 注意力机制)
- [11.1 注意力机制的核心思想](#11.1 注意力机制的核心思想)
- [11.2 经典注意力类型](#11.2 经典注意力类型)
- [11.2.1 自注意力(Self-Attention)](#11.2.1 自注意力(Self-Attention))
- [11.2.2 多头注意力(Multi-Head Attention)](#11.2.2 多头注意力(Multi-Head Attention))
- [11.2.3 跨注意力(Cross-Attention)](#11.2.3 跨注意力(Cross-Attention))
- [11.3 注意力机制的可视化与理解](#11.3 注意力机制的可视化与理解)
- [11.4 注意力机制在NLP中的应用](#11.4 注意力机制在NLP中的应用)
- [11.4.1 机器翻译中的注意力机制](#11.4.1 机器翻译中的注意力机制)
- [11.4.2 文本分类中的注意力优化](#11.4.2 文本分类中的注意力优化)
- [架构:BiLSTM + Attention](#架构:BiLSTM + Attention)
- 补充:注意力机制的演进与局限
- 小结
- 资料
前言 注意力机制
注意力机制(Attention Mechanism)是自然语言处理(NLP)近十年来最具影响力的突破之一,它模拟人类"聚焦关键信息"的认知过程,使模型能够动态地关注输入中最相关的部分。从早期的机器翻译改进,到如今 Transformer 架构的核心组件,注意力机制彻底改变了序列建模的方式。本章将深入浅出地讲解注意力机制的核心思想、数学原理、经典类型,并通过可视化与代码实现帮助你真正掌握这一关键技术。
11.1 注意力机制的核心思想
11.1.1 注意力的本质:加权求和的特征聚焦
想象你在阅读这句话:
"爱因斯坦 提出了相对论 ,他是一位伟大的物理学家。"
当被问"谁提出了相对论? "时,你的大脑会自动聚焦于"爱因斯坦" ,而忽略其他词。
注意力机制正是模拟这一过程 :对输入序列中的每个元素分配一个权重(重要性分数),然后进行加权求和,得到一个聚焦后的上下文表示。
✅ 核心公式:
Attention ( Q , K , V ) = softmax ( Q K T d k ) V \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right) V Attention(Q,K,V)=softmax(dk QKT)V
其中:
- Q (Query):查询向量,代表"我想找什么"
- K (Key):键向量,代表"每个元素是什么"
- V (Value):值向量,代表"每个元素的实际内容"
输入序列
生成 Q, K, V
计算 Q 与 K 的相似度
Softmax → 注意力权重
对 V 加权求和
上下文向量
💡 通俗比喻:
- 你(Query)在图书馆(Key-Value 对)找一本关于"量子力学"的书
- 图书管理员计算你需求与每本书标题(Key)的匹配度
- 最匹配的书(Value)被推荐给你
11.1.2 注意力机制的数学原理
以 Scaled Dot-Product Attention 为例(Transformer 使用的标准形式):
步骤分解:
- 计算相似度: QK\^T 得到所有 Query-Key 对的点积(相似度)
- 缩放:除以 \\sqrt{d_k} 防止梯度消失(当 d_k 大时,点积方差大)
- 归一化:Softmax 将相似度转为概率分布(权重和为1)
- 加权聚合:用权重对 Value 加权求和
数学表达:
Score = Q K T Scaled Score = Score d k Attention Weights = softmax ( Scaled Score ) Output = Attention Weights ⋅ V \begin{aligned} \text{Score} &= QK^T \\ \text{Scaled Score} &= \frac{\text{Score}}{\sqrt{d_k}} \\ \text{Attention Weights} &= \text{softmax}(\text{Scaled Score}) \\ \text{Output} &= \text{Attention Weights} \cdot V \end{aligned} ScoreScaled ScoreAttention WeightsOutput=QKT=dk Score=softmax(Scaled Score)=Attention Weights⋅V
📐 维度说明(假设序列长 n ,向量维 d ):
- Q, K, V \\in \\mathbb{R}\^{n \\times d}
- QK\^T \\in \\mathbb{R}\^{n \\times n} (注意力矩阵)
- Output \\in \\mathbb{R}\^{n \\times d}
11.2 经典注意力类型
11.2.1 自注意力(Self-Attention)
定义 :Query、Key、Value 全部来自同一输入序列。
作用 :让序列中每个元素都能关注其他所有元素,捕获全局依赖关系。
🌰 示例:
句子:"他 把书 给了她。"
- "他" 需要知道动作发出者
- "她" 需要知道动作接收者
- 自注意力建立三者间的关联
Self-Attention
输入: [x₁, x₂, x₃]
W_Q
W_K
W_V
Q = XW_Q
K = XW_K
V = XW_V
Attention(Q,K,V)
输出: [z₁, z₂, z₃]
✅ 优势:
- 并行计算(无 RNN 的时序依赖)
- 直接建模任意距离依赖
11.2.2 多头注意力(Multi-Head Attention)
动机 :单头注意力只能学习一种相关性模式。
思想 :并行使用多个注意力头,每个头学习不同子空间的表示,最后拼接融合。
结构:
- 将 Q, K, V 投影到 h 个子空间(通常 h=8 )
- 每个头独立计算自注意力
- 拼接所有头输出,再线性变换
MultiHead ( Q , K , V ) = Concat ( head 1 , . . . , head h ) W O \text{MultiHead}(Q,K,V) = \text{Concat}(\text{head}_1, ..., \text{head}_h) W^O MultiHead(Q,K,V)=Concat(head1,...,headh)WO
其中 \\text{head}_i = \\text{Attention}(QW_i\^Q, KW_i\^K, VW_i\^V)
python
# PyTorch 实现多头注意力(简化版)
import torch
import torch.nn as nn
class MultiHeadAttention(nn.Module):
def __init__(self, d_model=512, num_heads=8):
super().__init__()
assert d_model % num_heads == 0
self.d_k = d_model // num_heads
self.num_heads = 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)
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)
# Scaled Dot-Product Attention
scores = torch.matmul(Q, K.transpose(-2, -1)) / (self.d_k ** 0.5)
if mask is not None:
scores = scores.masked_fill(mask == 0, -1e9)
attn_weights = torch.softmax(scores, dim=-1)
output = torch.matmul(attn_weights, V)
# 拼接多头
output = output.transpose(1, 2).contiguous().view(batch_size, -1, self.num_heads * self.d_k)
return self.W_o(output)
✅ 优势:
- 增强模型表达能力
- 允许关注不同位置的不同表示子空间
11.2.3 跨注意力(Cross-Attention)
定义 :Query 来自一个序列,Key 和 Value 来自另一个序列。
典型应用:编码器-解码器架构(如机器翻译)
🌰 机器翻译:
- 编码器输出 → Key & Value(源语言句子)
- 解码器当前状态 → Query(目标语言已生成部分)
- 跨注意力让解码器聚焦源句中最相关的词
编码器\n(源语言)
K
V
解码器\n(目标语言)
Q
Cross-Attention
上下文向量
💡 与自注意力区别:
- 自注意力:
Q=K=V=X- 跨注意力:
Q=Y, K=V=X(X≠Y)
11.3 注意力机制的可视化与理解
注意力权重矩阵可直观展示模型"关注了什么"。
可视化示例(机器翻译):
| 目标词 | 源词注意力权重 |
|---|---|
| the | [0.1, 0.8, 0.1] → 聚焦"le" |
| animal | [0.7, 0.2, 0.1] → 聚焦"l'animal" |
python
# 使用 matplotlib 可视化注意力权重
import matplotlib.pyplot as plt
import seaborn as sns
def plot_attention(attention, src_tokens, tgt_tokens, title="Attention Weights"):
plt.figure(figsize=(10, 8))
sns.heatmap(
attention,
xticklabels=src_tokens,
yticklabels=tgt_tokens,
cmap="Blues"
)
plt.title(title)
plt.xlabel("Source Tokens")
plt.ylabel("Target Tokens")
plt.show()
# 假设 attention 是 [tgt_len, src_len] 的 numpy 矩阵
# plot_attention(attention, ["l'", "animal", "est", "..."], ["the", "animal", "is", "..."])
🔍 观察发现:
- 模型能对齐"le" ↔ "the"
- 但也会关注无关词(噪声),说明并非完美
11.4 注意力机制在NLP中的应用
11.4.1 机器翻译中的注意力机制
背景 :传统 Seq2Seq 模型(RNN 编码器-解码器)存在信息瓶颈------整个源句压缩为固定长度向量。
注意力改进(Bahdanau et al., 2015):
- 解码器每步动态计算对源句的注意力
- 生成上下文向量 c_t 作为额外输入
架构流程:
Decoder
Encoder
源句 x₁...xₙ
BiRNN
隐藏状态 h₁...hₙ
yₜ₋₁
RNN
cₜ
yₜ
Attention
sₜ₋₁
✅ 效果:显著提升长句翻译质量,成为 NMT 标准组件
11.4.2 文本分类中的注意力优化
问题 :CNN/RNN 分类器通常用最后隐藏状态 或平均池化,忽略关键词。
解决方案 :引入注意力层,自动聚焦判别性词语。
架构:BiLSTM + Attention
- BiLSTM 编码句子 → 隐藏状态序列 \[h_1, ..., h_n\]
- 计算每个 h_i 的注意力权重 \\alpha_i
- 加权求和得到句子表示 s = \\sum \\alpha_i h_i
- s 输入分类器
python
class AttentionClassifier(nn.Module):
def __init__(self, vocab_size, embed_dim=128, hidden_dim=256, num_classes=2):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embed_dim)
self.lstm = nn.LSTM(embed_dim, hidden_dim, bidirectional=True, batch_first=True)
self.attention = nn.Linear(hidden_dim * 2, 1)
self.classifier = nn.Linear(hidden_dim * 2, num_classes)
def forward(self, x):
# x: [B, L]
embed = self.embedding(x) # [B, L, D]
lstm_out, _ = self.lstm(embed) # [B, L, 2*H]
# 计算注意力权重
attn_weights = torch.softmax(self.attention(lstm_out), dim=1) # [B, L, 1]
# 加权求和
context = torch.sum(attn_weights * lstm_out, dim=1) # [B, 2*H]
return self.classifier(context)
# 使用示例
model = AttentionClassifier(vocab_size=10000)
output = model(torch.randint(0, 10000, (32, 50))) # [32, 2]
✅ 优势:
- 可解释性强(可视化哪些词重要)
- 提升分类准确率,尤其对长文本
补充:注意力机制的演进与局限
| 演进方向 | 代表工作 | 改进点 |
|---|---|---|
| 稀疏注意力 | Longformer, BigBird | 降低 O(n²) 计算复杂度 |
| 线性注意力 | Performer | 近似注意力,O(n) 复杂度 |
| 局部注意力 | Reformer | 关注局部窗口,适合长序列 |
当前局限:
- 计算和内存开销大(O(n²))
- 可能关注无关词(需结合先验知识约束)
- 对低资源语言泛化能力有限
小结
注意力机制通过动态加权聚焦关键信息 ,解决了传统序列模型的长距离依赖和信息瓶颈问题。从自注意力 捕获全局依赖,到多头注意力 增强表达能力,再到跨注意力实现跨序列交互,注意力已成为现代 NLP 模型的基石。尽管存在计算开销等挑战,但其强大的建模能力和可解释性使其在机器翻译、文本分类、问答系统等任务中持续发挥核心作用。理解注意力机制,是通往 Transformer 和大语言模型的关键一步。
资料
咚咚王
《Python 编程:从入门到实践》
《利用 Python 进行数据分析》
《算法导论中文第三版》
《概率论与数理统计(第四版) (盛骤) 》
《程序员的数学》
《线性代数应该这样学第 3 版》
《微积分和数学分析引论》
《(西瓜书)周志华-机器学习》
《TensorFlow 机器学习实战指南》
《Sklearn 与 TensorFlow 机器学习实用指南》
《模式识别(第四版)》
《深度学习 deep learning》伊恩·古德费洛著 花书
《Python 深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》
《深入浅出神经网络与深度学习 +(迈克尔·尼尔森(Michael+Nielsen)》
《自然语言处理综论 第 2 版》
《Natural-Language-Processing-with-PyTorch》
《计算机视觉-算法与应用(中文版)》
《Learning OpenCV 4》
《AIGC:智能创作时代》杜雨 +&+ 张孜铭
《AIGC 原理与实践:零基础学大语言模型、扩散模型和多模态模型》
《从零构建大语言模型(中文版)》
《实战 AI 大模型》
《AI 3.0》