英译法案例 - 测试基于 GRU 的编码器
1 课程概览
本课讲解英译法案例中基于 GRU 的编码器的测试代码。获取数据加载器对象,初始化编码器参数(vocab_size=28036,hidden_size=256),创建编码器模型,遍历数据加载器进行测试,打印输入句子、索引张量和输入张量的形状。
2 核心概念与定义
- 编码器参数:vocab_size(英文词汇表大小)、hidden_size(隐藏层维度)。
- vocab_size = 28036:英文单词数量。
- hidden_size = 256:隐藏层维度。
- device:CPU 或 GPU。
3 模型与算法详解
测试流程
1. 获取数据加载器对象
2. 初始化编码器参数
3. 创建编码器模型对象
4. 将模型移动到指定设备(CPU/GPU)
5. 遍历数据加载器进行测试
6. 打印输入句子、索引张量和形状
编码器参数
| 参数 | 值 | 说明 |
|---|---|---|
| vocab_size | 28036 | 英文词汇表大小 |
| hidden_size | 256 | 隐藏层维度 |
输入张量形状
输入张量形状 [1, 6]。
[1, 6] → 1 批次,6 个单词
索引张量示例
索引张量内容。
tensor([4243, 139, 7907, 4323, 9088, 1])
- 开头是 0(SOS)
- 结尾是 1(EOS)
- 中间是单词索引
4 数学原理与推导
编码器
$$\text{output}, \text{hidden} = \text{GRU}(\text{embedding}(\text{input}))$$
其中:
- $\text{input}$ 是输入张量 [1, 6]
- $\text{embedding}$ 是词嵌入层
- $\text{GRU}$ 是 GRU 模型
5 代码示例
import torch
import torch.nn as nn
class EncoderGRU(nn.Module):
"""基于 GRU 的编码器"""
def __init__(self, vocab_size, hidden_size):
super(EncoderGRU, self).__init__()
self.hidden_size = hidden_size
# 1. 词嵌入层
self.embedding = nn.Embedding(vocab_size, hidden_size)
# 2. GRU 层
self.gru = nn.GRU(hidden_size, hidden_size)
def forward(self, input, hidden):
# 1. 词嵌入
embedded = self.embedding(input).view(1, 1, -1)
# 2. GRU
output, hidden = self.gru(embedded, hidden)
return output, hidden
def initHidden(self):
"""初始化隐藏状态"""
return torch.zeros(1, 1, self.hidden_size)
def test_encoder_gru():
"""测试基于 GRU 的编码器"""
print("=== 英译法案例 - 测试基于 GRU 的编码器 ===")
# 1. 获取数据加载器对象
# my_data_loader = get_data_loader()
# 2. 初始化编码器参数
vocab_size = 28036 # 英文词汇表大小
hidden_size = 256 # 隐藏层维度
# 3. 创建编码器模型对象
my_encoder_gru = EncoderGRU(vocab_size, hidden_size)
# 4. 将模型移动到指定设备(CPU/GPU)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
my_encoder_gru = my_encoder_gru.to(device)
print(f"设备: {device}")
print(f"词汇表大小: {vocab_size}")
print(f"隐藏层维度: {hidden_size}")
# 5. 遍历数据加载器进行测试
# for i, (x, y) in enumerate(my_data_loader):
# 模拟测试
input_tensor = torch.tensor([[4243, 139, 7907, 4323, 9088, 1]])
print(f"\n输入张量形状: {input_tensor.shape}")
print(f"输入张量内容: {input_tensor}")
# 6. 前向传播
hidden = my_encoder_gru.initHidden().to(device)
input_tensor = input_tensor.to(device)
for i in range(input_tensor.size(1)):
input_word = torch.tensor([[input_tensor[0][i].item()]]).to(device)
output, hidden = my_encoder_gru(input_word, hidden)
print(f"单词 {i+1} - output 形状: {output.shape}, hidden 形状: {hidden.shape}")
print(f"\n最终 hidden 形状: {hidden.shape}")
# 测试
if __name__ == "__main__":
test_encoder_gru()
代码说明
| 代码 | 说明 |
|---|---|
nn.Embedding(vocab_size, hidden_size) | 词嵌入层 |
nn.GRU(hidden_size, hidden_size) | GRU 层 |
my_encoder_gru.to(device) | 移动到指定设备 |
torch.zeros(1, 1, hidden_size) | 初始化隐藏状态 |
input_tensor.size(1) | 遍历每个单词 |
6 重难点与易错提醒
- ❗重点:vocab_size = 28036(英文词汇表大小)。
- ❗重点:hidden_size = 256(隐藏层维度)。
- ❗重点:使用 GPU 时需要将模型移动到 device。
- 💡技巧:CPU 可以不写
to(device),GPU 必须写。
7 课堂问答精选
Q1:编码器的参数有哪些?
A:vocab_size = 28036(英文词汇表大小),hidden_size = 256(隐藏层维度)。
Q2:如何将模型移动到 GPU?
A:使用 my_encoder_gru.to(device),其中 device 是 torch.device("cuda" if torch.cuda.is_available() else "cpu")。
Q3:输入张量的形状是什么?
A:输入张量形状为 [1, 6],表示 1 批次,6 个单词。
8 本课小结
- 编码器参数:vocab_size = 28036,hidden_size = 256。
- 测试流程:获取数据加载器 → 初始化参数 → 创建模型 → 移动到设备 → 遍历测试。
- 使用 GPU 时需要将模型移动到 device。
9 延伸思考
- 如何构建基于 GRU 的解码器?
- 如何实现无 Attention 的解码器?