英译法案例 - 构建基于 GRU 的编码器
1 课程概览
本课讲解构建基于 GRU 的编码器。编码器包含两层:①词嵌入层(nn.Embedding)将单词转为词向量;②GRU 神经网络层处理词向量得到隐藏状态。编码器的输出(隐藏状态)即为中间语义张量 C,传给解码器进行生成。
2 核心概念与定义
- Encoder:编码器,将输入序列编码为中间语义张量 C。
- nn.Embedding:词嵌入层,将单词索引转为词向量。
- nn.GRU:门控循环单元,处理词向量得到隐藏状态。
- 中间语义张量 C:编码器的总输出(隐藏状态)。
- input_size:输入维度(词汇表大小)。
- hidden_size:隐藏层维度。
3 模型与算法详解
编码器结构
输入单词索引 → [nn.Embedding] → 词向量 → [nn.GRU] → 输出 + 隐藏状态(C)
编码器流程
- 输入:单词索引 + 上一时刻隐藏状态
- 词嵌入层:将单词索引转为词向量
- GRU 层:处理词向量,得到输出和隐藏状态
- 输出:输出 + 隐藏状态(即中间语义张量 C)
网络层说明
| 网络层 | 作用 |
|---|---|
| nn.Embedding | 词嵌入层,将单词索引转为词向量 |
| nn.GRU | 神经网络层,处理词向量得到隐藏状态 |
编码器三个方法
__init__:定义网络层(Embedding + GRU)- forward:前向传播
- initHidden:初始化隐藏状态
4 数学原理与推导
词嵌入
$$\text{embedded} = \text{Embedding}(x_t)$$
GRU 计算
$$\text{output}, h_t = \text{GRU}(\text{embedded}, h_{t-1})$$
中间语义张量 C
$$C = h_T$$
其中 $h_T$ 是最后一个时间步的隐藏状态。
5 代码示例
import torch
import torch.nn as nn
class Encoder(nn.Module):
"""基于 GRU 的编码器"""
def __init__(self, input_size, hidden_size):
"""
初始化函数
:param input_size: 输入维度(词汇表大小)
:param hidden_size: 隐藏层维度
"""
super().__init__()
self.hidden_size = hidden_size
# 定义网络层
# 1. 词嵌入层:将单词索引转为词向量
self.embedding = nn.Embedding(input_size, hidden_size)
# 2. GRU 层:处理词向量
self.gru = nn.GRU(hidden_size, hidden_size)
def forward(self, input, hidden):
"""
前向传播
:param input: 输入单词索引
:param hidden: 上一时刻隐藏状态
:return: output, hidden(hidden 即为中间语义张量 C)
"""
# 1. 词嵌入:将单词索引转为词向量
embedded = self.embedding(input)
# 2. GRU 处理
output, hidden = self.gru(embedded, hidden)
return output, hidden
def initHidden(self):
"""初始化隐藏状态"""
return torch.zeros(1, 1, self.hidden_size, device=device)
# 测试
if __name__ == "__main__":
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
input_size = 2803 # 英语词汇表大小
hidden_size = 256
# 创建编码器
encoder = Encoder(input_size, hidden_size).to(device)
# 初始化隐藏状态
hidden = encoder.initHidden()
# 模拟输入(一个单词的索引)
input = torch.tensor([[1]], device=device)
# 前向传播
output, hidden = encoder(input, hidden)
print("输出形状:", output.shape)
print("隐藏状态形状:", hidden.shape)
6 重难点与易错提醒
- ❗重点:编码器包含两层——nn.Embedding(词嵌入)和 nn.GRU。
- ❗重点:编码器的输出(隐藏状态)即为中间语义张量 C。
- ⚠️易错:nn.Embedding 的输入是单词索引,不是 one-hot。
- ⚠️易错:GRU 的输入需要是三维张量
(seq_len, batch, input_size)。 - 💡深入理解:编码器理解语义,将输入序列编码为中间语义张量 C。
7 课堂问答精选
Q1:编码器包含哪些网络层?
A:包含两层:①nn.Embedding(词嵌入层),将单词索引转为词向量;②nn.GRU(神经网络层),处理词向量得到隐藏状态。
Q2:编码器的输出是什么?
A:输出是 output 和 hidden。其中 hidden(隐藏状态)即为中间语义张量 C,传给解码器进行生成。
Q3:编码器需要实现哪些方法?
A:三个方法:①__init__:定义网络层(Embedding + GRU);②forward:前向传播;③initHidden:初始化隐藏状态。
Q4:nn.Embedding 的作用是什么?
A:词嵌入层,将单词索引转为词向量。输入是单词索引,输出是词向量。
8 本课小结
- 编码器两层:nn.Embedding + nn.GRU。
- 流程:单词索引 → Embedding → 词向量 → GRU → 输出 + 隐藏状态(C)。
- 三个方法:
__init__、forward、initHidden。 - 输出:隐藏状态即为中间语义张量 C。
9 延伸思考
- 如何构建解码器?
- 如何加入注意力机制?