注意力机制的实现可以分解为几个核心步骤,其本质是通过动态计算权重,决定不同位置信息的重要性,再对信息进行加权融合。以下从数学原理、代码实现到直观解释逐步展开:
一、核心实现步骤
以最常见的**点积注意力(Dot-Product Attention)**为例:
1. 输入向量化
- 假设输入序列有 ( N ) 个词,每个词转换为向量 ( \mathbf{x}i )(维度为 ( d{\text{model}} ))。
2. 生成Query、Key、Value
- 对每个词向量分别进行线性变换,生成三组向量:
- Query(查询向量):
Q = X W Q \mathbf{Q} = \mathbf{X} \mathbf{W}^Q \ Q=XWQ - Key(键向量):
K = X W K \mathbf{K} = \mathbf{X} \mathbf{W}^K \ K=XWK - Value(值向量):
V = X W V \mathbf{V} = \mathbf{X} \mathbf{W}^V \ V=XWV - 其中
W Q , W K , W V \mathbf{W}^Q, \mathbf{W}^K, \mathbf{W}^V \ WQ,WK,WV 是可学习的权重矩阵。
- Query(查询向量):
3. 计算注意力分数
- 通过 Query 和 Key 的点积 计算词与词之间的相关性分数:
Scores = Q K T \text{Scores} = \mathbf{Q} \mathbf{K}^T Scores=QKT- 分数越高,表示两个词的相关性越强。
4. 缩放与归一化
- 缩放(Scale):为避免点积结果过大导致梯度消失,除以 ( \sqrt{d_k} )(( d_k ) 是 Key 的维度):
Scaled Scores = Q K T d k \text{Scaled Scores} = \frac{\mathbf{Q} \mathbf{K}^T}{\sqrt{d_k}} Scaled Scores=dkQKT - Softmax 归一化:将分数转换为概率分布(和为1):
Attention Weights = softmax ( Scaled Scores ) \text{Attention Weights} = \text{softmax}(\text{Scaled Scores}) Attention Weights=softmax(Scaled Scores)
5. 加权求和
- 用注意力权重对 Value 加权求和,得到最终输出:
Output = Attention Weights ⋅ V \text{Output} = \text{Attention Weights} \cdot \mathbf{V} Output=Attention Weights⋅V
二、数学公式整合
注意力机制的完整公式为:
Attention ( Q , K , V ) = softmax ( Q K T d k ) V \text{Attention}(\mathbf{Q}, \mathbf{K}, \mathbf{V}) = \text{softmax}\left( \frac{\mathbf{Q} \mathbf{K}^T}{\sqrt{d_k}} \right) \mathbf{V} Attention(Q,K,V)=softmax(dkQKT)V
三、代码实现(PyTorch示例)
import torch
import torch.nn as nn
import torch.nn.functional as Fclass DotProductAttention(nn.Module):def __init__(self, d_k):super().__init__()self.d_k = d_k # Key的维度def forward(self, Q, K, V):# 计算点积注意力分数scores = torch.matmul(Q, K.transpose(-2, -1)) / torch.sqrt(torch.tensor(self.d_k))# Softmax归一化attention_weights = F.softmax(scores, dim=-1)# 加权求和output = torch.matmul(attention_weights, V)return output# 示例输入
batch_size = 2
seq_len = 5 # 序列长度
d_model = 64 # 输入维度
d_k = d_v = 32 # Key和Value的维度# 随机生成输入向量
X = torch.randn(batch_size, seq_len, d_model)
# 定义权重矩阵(实际中应使用nn.Linear)
W_Q = nn.Linear(d_model, d_k)
W_K = nn.Linear(d_model, d_k)
W_V = nn.Linear(d_model, d_v)# 生成Q, K, V
Q = W_Q(X) # shape: [batch_size, seq_len, d_k]
K = W_K(X)
V = W_V(X)# 计算注意力
attention = DotProductAttention(d_k)
output = attention(Q, K, V) # shape: [batch_size, seq_len, d_v]
四、多头注意力(Multi-Head Attention)
为了增强模型捕捉不同模式信息的能力,通常会将注意力机制扩展为多头形式:
1. 实现步骤
- 分割向量:将 ( \mathbf{Q}, \mathbf{K}, \mathbf{V} ) 按头数(( h ))分割为 ( h ) 组子向量。
- 独立计算注意力:每组子向量并行计算注意力。
- 拼接结果:将各头的输出拼接,再通过线性层融合。
2. 数学公式
MultiHead ( Q , K , V ) = Concat ( head 1 , … , head h ) W O \text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \dots, \text{head}_h) \mathbf{W}^O MultiHead(Q,K,V)=Concat(head1,…,headh)WO
其中
head i = Attention ( Q W i Q , K W i K , V W i V ) \text{head}_i = \text{Attention}(Q \mathbf{W}_i^Q, K \mathbf{W}_i^K, V \mathbf{W}_i^V) \ headi=Attention(QWiQ,KWiK,VWiV)
五、直观解释
1. Query-Key-Value的比喻
- Query(问题):当前词想知道什么?
- Key(标签):其他词能提供什么信息?
- Value(答案):实际传递的信息内容。
注意力机制相当于通过 问题 和 标签 的匹配程度,决定从 答案 中提取多少信息。
2. 动态权重的作用
- 若两个词的 Key 和 Query 高度匹配(点积大),它们的权重会接近1,反之接近0。
- 例如:句子 “猫追老鼠,因为它饿了” 中,处理“它”时,模型会给“猫”高权重,给“老鼠”低权重。
六、注意力机制的变体
类型 | 特点 |
---|---|
加性注意力 | 使用神经网络计算相关性分数(如Bahdanau注意力) |
局部注意力 | 仅计算局部窗口内的注意力权重,降低计算成本 |
稀疏注意力 | 通过规则或随机采样减少计算量(如Longformer、BigBird) |
轴向注意力 | 在多维数据(如图像)中沿特定轴计算注意力 |
七、总结
注意力机制通过以下步骤实现:
- 向量变换:生成Query、Key、Value。
- 相关性计算:通过点积衡量词与词之间的关联。
- 权重归一化:Softmax转换为概率分布。
- 信息融合:加权求和得到最终输出。
其核心优势在于动态聚焦关键信息,而多头注意力进一步增强了模型的表达能力。这种机制不仅是Transformer的基础,也被广泛应用于计算机视觉、语音处理等领域。