多头注意力机制 - 代码测试
1 课程概览
本课测试多头注意力机制。步骤:创建多头注意力层对象 → 获取位置编码处理后的结果 → 定义 QKV(自注意力机制 Q=K=V)→ 创建掩码张量(可选)→ 送入模型获取结果 → 打印输出形状 → 返回结果。输出形状与输入形状保持一致 (2, 4, 512)。
2 核心概念与定义
- 自注意力机制:Q=K=V,用同一个变量。
- 多头注意力层对象:
MultiHeadAttention(512, 8)。 - 掩码张量:形状 (batch, 1, seq_len, seq_len),可选。
- 输出形状:与输入形状保持一致。
3 模型与算法详解
测试流程
1. 创建多头注意力层对象
2. 获取位置编码处理后的结果
3. 定义 QKV(自注意力机制 Q=K=V)
4. 创建掩码张量(可选)
5. 送入模型获取结果
6. 打印输出形状
7. 返回结果
函数命名
将
dm02改为use_position,统一命名。
dm01_input→ 词嵌入层use_position→ 位置编码测试use_multihead_attn→ 多头注意力测试
形状变化
| 步骤 | 形状 | 说明 |
|---|---|---|
| 位置编码结果 | (2, 4, 512) | 词嵌入 + 位置编码 |
| QKV | (2, 4, 512) | 自注意力机制,Q=K=V |
| 掩码张量 | (2, 1, 4, 4) | 可选 |
| 多头注意力结果 | (2, 4, 512) | 与输入形状一致 |
batch_size 的灵活性
batch_size 可以是 2 或 8,不影响多头注意力计算。
- 输入:(2, 4, 512) 或 (8, 4, 512)
- 头数:8
- 每头维度:64
4 数学原理与推导
自注意力机制
$$Q = K = V = \text{position_x}$$
多头注意力
$$\text{output} = \text{MultiHead}(Q, K, V, \text{mask})$$
5 代码示例
import torch
from dm01_input import Embeddings, PositionalEncoding
from dm04_attention import MultiHeadAttention
def use_multihead_attn():
"""测试多头注意力机制"""
# 1. 创建多头注意力层对象
my_attention = MultiHeadAttention(512, 8)
# 2. 获取位置编码处理后的结果
position_x = use_position() # (2, 4, 512)
# 3. 定义 QKV(自注意力机制,Q=K=V)
Q = K = V = position_x
# 4. 创建掩码张量(可选)
# 形状:(batch, 1, seq_len, seq_len)
mask = torch.ones(2, 1, 4, 4)
# 5. 送入模型获取结果
result = my_attention(Q, K, V, mask)
# 6. 打印输出形状
print(f"多头注意力层结果形状: {result.shape}")
# 7. 返回结果
return result
def use_position():
"""获取位置编码处理后的结果"""
VOCAB_SIZE = 1000
D_MODEL = 512
my_embedding = Embeddings(D_MODEL, VOCAB_SIZE)
x = torch.LongTensor([[1, 2, 3, 4], [5, 6, 7, 8]])
embedded_x = my_embedding(x)
my_position = PositionalEncoding(D_MODEL, dropout=0.1, max_len=60)
position_x = my_position(embedded_x)
return position_x
# 测试
if __name__ == "__main__":
result = use_multihead_attn()
print(f"最终结果形状: {result.shape}")
代码说明
| 代码 | 说明 |
|---|---|
MultiHeadAttention(512, 8) | 创建多头注意力层对象 |
Q = K = V = position_x | 自注意力机制,Q=K=V |
torch.ones(2, 1, 4, 4) | 创建掩码张量 |
my_attention(Q, K, V, mask) | 送入模型获取结果 |
6 重难点与易错提醒
- ❗重点:自注意力机制 Q=K=V,用同一个变量。
- ❗重点:输出形状与输入形状保持一致。
- ⚠️易错:函数命名要统一(
use_position而不是dm02)。 - 💡深入理解:掩码张量是可选的。
7 课堂问答精选
Q1:如何测试多头注意力机制?
A:步骤:①创建多头注意力层对象;②获取位置编码处理后的结果;③定义 QKV(自注意力机制 Q=K=V);④创建掩码张量(可选);⑤送入模型获取结果;⑥打印输出形状;⑦返回结果。
Q2:自注意力机制中 QKV 如何定义?
A:自注意力机制中 Q=K=V,用同一个变量。Q = K = V = position_x。
Q3:输出形状与输入形状有什么关系?
A:输出形状与输入形状保持一致。输入 (2, 4, 512),输出也是 (2, 4, 512)。
Q4:掩码张量是必须的吗?
A:不是必须的,掩码张量是可选的。可以根据需要选择是否使用。
8 本课小结
- 测试步骤:创建对象 → 获取结果 → 定义 QKV → 创建掩码 → 送入模型 → 打印 → 返回。
- 自注意力机制:Q=K=V。
- 输出形状与输入形状一致。
- 函数命名统一:
use_position、use_multihead_attn。 - 掩码张量可选。
9 延伸思考
- 前馈全连接层如何实现?
- 多头注意力层和前馈全连接层如何组合?