编码器层 - 代码测试
1 课程概览
本课测试编码器层。步骤:准备数据(位置编码处理后的数据)→ 实例化子层对象(多头注意力、前馈全连接)→ 创建编码器层对象 → 构建掩码张量 → 执行前向传播。输出形状仍为 (2, 4, 512)。介绍快捷键 Ctrl+Q 和悬浮查看参数。
2 核心概念与定义
- 位置编码处理后的数据:编码器层的输入。
- 子层对象:多头注意力对象、前馈全连接对象。
- 掩码张量:形状 (batch, 1, seq_len, seq_len)。
- 快捷键:
Ctrl+Q查看参数,悬浮 2 秒查看参数。
3 模型与算法详解
测试流程
1. 准备数据(位置编码处理后的数据)
2. 实例化子层对象(多头注意力、前馈全连接)
3. 创建编码器层对象
4. 构建掩码张量
5. 执行前向传播
形状变化
| 步骤 | 形状 | 说明 |
|---|---|---|
| 输入数据 | (2, 4, 512) | 位置编码处理后 |
| 掩码张量 | (2, 1, 4, 4) | batch, 1, seq_len, seq_len |
| 编码器层输出 | (2, 4, 512) | 形状不变 |
子层对象参数
| 子层 | 参数 | 说明 |
|---|---|---|
| 多头注意力 | (512, 8) | d_model, heads |
| 前馈全连接 | (512, 2048, 0.1) | d_model, d_ff, dropout |
快捷键
| 快捷键 | 作用 |
|---|---|
Ctrl+Q | 查看参数 |
| 悬浮 2 秒 | 查看参数 |
4 数学原理与推导
编码器层前向传播
$$\text{output} = \text{EncoderLayer}(x, \text{mask})$$
子层1
$$\text{output}_1 = \text{LayerNorm}(x + \text{MultiHeadAttention}(x, x, x, \text{mask}))$$
子层2
$$\text{output}_2 = \text{LayerNorm}(\text{output}_1 + \text{FeedForward}(\text{output}_1))$$
5 代码示例
import torch
from dm01_input import Embeddings, PositionalEncoding
from dm04_attention import MultiHeadAttention
from dm05_feedforward import FeedForward
from dm08_encoder_layer import EncoderLayer
def use_encoder_layer():
"""测试编码器层"""
# 1. 准备数据(位置编码处理后的数据)
x = use_position() # (2, 4, 512)
# 2. 实例化子层对象
# 2.1 多头注意力对象
multi_head_attn = MultiHeadAttention(512, 8)
# 2.2 前馈全连接对象
feed_forward = FeedForward(512, 2048, 0.1)
# 3. 创建编码器层对象
encoder_layer = EncoderLayer(512, multi_head_attn, feed_forward)
# 4. 构建掩码张量
# 形状:(batch, 1, seq_len, seq_len)
mask = torch.zeros(2, 1, 4, 4)
# 5. 执行前向传播
output = encoder_layer(x, mask)
print(f"输入形状: {x.shape}")
print(f"输出形状: {output.shape}")
return output
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_encoder_layer()
print(f"最终结果形状: {result.shape}")
代码说明
| 代码 | 说明 |
|---|---|
use_position() | 准备数据 |
MultiHeadAttention(512, 8) | 多头注意力对象 |
FeedForward(512, 2048, 0.1) | 前馈全连接对象 |
EncoderLayer(512, ...) | 创建编码器层对象 |
torch.zeros(2, 1, 4, 4) | 构建掩码张量 |
encoder_layer(x, mask) | 执行前向传播 |
6 重难点与易错提醒
- ❗重点:编码器层需要传入多头注意力对象和前馈全连接对象。
- ❗重点:掩码张量形状为 (batch, 1, seq_len, seq_len)。
- ⚠️易错:多头注意力参数是 (d_model, heads),前馈全连接参数是 (d_model, d_ff, dropout)。
- 💡技巧:使用
Ctrl+Q或悬浮 2 秒查看参数。
7 课堂问答精选
Q1:如何测试编码器层?
A:步骤:①准备数据(位置编码处理后的数据);②实例化子层对象(多头注意力、前馈全连接);③创建编码器层对象;④构建掩码张量;⑤执行前向传播。
Q2:多头注意力和前馈全连接的参数是什么?
A:多头注意力参数是 (512, 8),即 d_model 和 heads;前馈全连接参数是 (512, 2048, 0.1),即 d_model、d_ff 和 dropout。
Q3:掩码张量的形状是什么?
A:形状为 (batch, 1, seq_len, seq_len),例如 (2, 1, 4, 4)。
Q4:如何查看函数参数?
A:使用快捷键 Ctrl+Q,或将鼠标悬浮在函数名上 2 秒,会弹出参数说明。
8 本课小结
- 测试步骤:准备数据 → 实例化子层对象 → 创建编码器层 → 构建掩码 → 前向传播。
- 多头注意力参数:(512, 8)。
- 前馈全连接参数:(512, 2048, 0.1)。
- 掩码张量形状:(2, 1, 4, 4)。
- 快捷键:
Ctrl+Q查看参数。
9 延伸思考
- 编码器如何由 6 个编码器层组成?
- 解码器层如何实现?