英译法案例 - 模型搭建总结
1 课程概览
本课总结模型搭建。编码器包含词嵌入层和 GRU 层,处理后的数据用于获取中间语义张量 C。解码器结合 QKV,通过 GRU 得到 4345 个法语单词的概率分布。带注意力机制的解码器通过 QKV 运算将普通 Q 升级为更强大的 Q(中间语义张量 C)。
2 核心概念与定义
- 编码器:词嵌入层 + GRU,输出中间语义张量 C。
- 解码器:结合 QKV,通过 GRU 得到概率分布。
- 注意力机制:通过 QKV 运算将普通 Q 升级为更强大的 Q。
- 概率分布:4345 个法语单词的概率。
3 模型与算法详解
编码器总结
| 网络层 | 作用 |
|---|---|
| nn.Embedding | 词嵌入层,将单词索引转为词向量 |
| nn.GRU | 神经网络层,处理词向量得到隐藏状态 |
输出:中间语义张量 C,传给解码器进行生成。
解码器总结(不带注意力)
- 输入:中间语义张量 C + 上一时刻隐藏状态
- 输出:4345 个法语单词的概率分布
- 选择概率最高的作为预测结果
解码器总结(带注意力)
通过 QKV 运算,把普通 Q 升级成更强大的 Q(中间语义张量 C)。
流程:
- Q 和 K 算匹配分
- 匹配分 × V 得到中间语义张量 C
- C 充当本次输入
- 结合上一时刻隐藏状态
- 通过 GRU 得到输出
图一 vs 图二
| 对比项 | 图一(不带注意力) | 图二(带注意力) |
|---|---|---|
| 注意力机制 | 无 | 有 |
| 中间语义张量 | 所有时间步用同一个 C | 每个时间步用不同的 $C_t$ |
图二中的 QKV
| 组件 | 作用 |
|---|---|
| Q | 查询,当前要生成的词 |
| K | 键,编码器的输出 |
| V | 值,编码器的输出(词向量) |
维度变化
Q: [1, 1, 256]
K: [1, sentence_len, 256]
V: [1, sentence_len, 256]
BMM 之前:[1, sentence_len] → [1, 10, sentence_len]
4 数学原理与推导
编码过程
$$\text{embedded} = \text{Embedding}(x_t)$$ $$\text{output}, h_t = \text{GRU}(\text{embedded}, h_{t-1})$$ $$C = h_T$$
注意力计算
$$\text{score} = Q \cdot K^T$$ $$\alpha = \text{softmax}(\text{score})$$ $$C_t = \alpha \cdot V$$
解码过程
$$\text{output}, h_t = \text{GRU}(C_t, h_{t-1})$$ $$P = \text{softmax}(\text{Linear}(\text{output}))$$
5 代码示例
import torch
import torch.nn as nn
import torch.nn.functional as F
class Encoder(nn.Module):
"""编码器:词嵌入层 + GRU"""
def __init__(self, input_size, hidden_size):
super().__init__()
self.hidden_size = hidden_size
self.embedding = nn.Embedding(input_size, hidden_size)
self.gru = nn.GRU(hidden_size, hidden_size)
def forward(self, input, hidden):
embedded = self.embedding(input)
output, hidden = self.gru(embedded, hidden)
return output, hidden
def initHidden(self):
return torch.zeros(1, 1, self.hidden_size)
class AttnDecoder(nn.Module):
"""带注意力机制的解码器"""
def __init__(self, output_size, hidden_size):
super().__init__()
self.hidden_size = hidden_size
self.embedding = nn.Embedding(output_size, hidden_size)
self.attn = nn.Linear(hidden_size * 2, hidden_size)
self.attn_combine = nn.Linear(hidden_size * 2, hidden_size)
self.gru = nn.GRU(hidden_size, hidden_size)
self.out = nn.Linear(hidden_size, output_size)
def forward(self, input, hidden, encoder_outputs):
# QKV 运算
embedded = self.embedding(input) # Q
# 注意力权重
attn_weights = F.softmax(
torch.matmul(embedded, encoder_outputs.T),
dim=1
)
# 加权求和得到 C_t
C_t = torch.matmul(attn_weights, encoder_outputs) # V
# GRU 解码
output, hidden = self.gru(C_t, hidden)
# 全连接分类
output = F.log_softmax(self.out(output), dim=1)
return output, hidden, attn_weights
6 重难点与易错提醒
- ❗重点:编码器两层——词嵌入层 + GRU。
- ❗重点:带注意力机制的解码器通过 QKV 运算升级 Q。
- ⚠️易错:图一不带注意力,图二带注意力。
- ⚠️易错:BMM 之前维度会从
[1, sentence_len]变为[1, 10, sentence_len]。 - 💡深入理解:中间语义张量 C 充当本次输入,结合上一时刻隐藏状态。
7 课堂问答精选
Q1:编码器包含哪些层?
A:包含两层:①词嵌入层(nn.Embedding),将单词索引转为词向量;②GRU 神经网络层,处理词向量得到隐藏状态。处理后的数据用于获取中间语义张量 C。
Q2:带注意力机制的解码器如何工作?
A:通过 QKV 运算,把普通 Q 升级成更强大的 Q(中间语义张量 C)。Q 和 K 先算匹配分,匹配分 × V 得到中间语义张量 C,C 充当本次输入,结合上一时刻隐藏状态,通过 GRU 得到输出。
Q3:图一和图二的区别是什么?
A:图一不带注意力机制,所有时间步用同一个 C;图二带注意力机制,每个时间步用不同的 $C_t$。
Q4:图二中的 QKV 分别是什么?
A:Q 是查询(当前要生成的词),K 是键(编码器的输出),V 是值(编码器的输出,词向量)。
8 本课小结
- 编码器:词嵌入层 + GRU,输出中间语义张量 C。
- 解码器(不带注意力):C + 隐藏状态 → GRU → 概率分布。
- 解码器(带注意力):QKV 运算 → 升级 Q → GRU → 概率分布。
- 图一不带注意力,图二带注意力。
- QKV:Q 查询,K 键,V 值。
9 延伸思考
- 如何训练模型?
- 什么是 Teacher Forcing?