这些任务需要"从一个序列映射到另一个序列",因此就有了 Seq2Seq 模型。-
- **机器翻译**:输入是某种语言的句子,输出是另一种语言的句子。
- **对话系统**:根据上一句话,输出一个回答或回应。
- **文本摘要**:输入可能是长篇文章,输出是简短摘要。
## 1. 编码器(Encoder)
输入**英文句子** "编码" 成**一个固定长度的向量**
Seq2Seq 的编码器主要将输入序列(例如英文句子)"编码"成一个固定长度的向量(也叫"上下文向量" context vector)。这个向量可以被视为对整个输入序列含义的压缩表达。
让我们以翻译 "What is your name?" 为例:
1. **词向量转换**
假设我们用 100 维的词向量,每个词会被转换成对应的向量:
- "What" →[0.2, -0.5, 0.1,..., 0.3]
- "is" →[-0.1, 0.3, 0.4,..., -0.2]
- "your" →[0.5, 0.1, -0.3,..., 0.1]
- "name" →[-0.3, 0.2, 0.1,..., 0.4]
- "?" →[0.1, -0.1, 0.2,..., -0.1]
1. **双向 LSTM 处理**
我们用双向 LSTM 处理这个序列:
```Java
正向: What → is → your → name → ?
反向: ? ← name ← your ← is ← What
```
每个时间步,LSTM 会:
- 读入当前词的词向量
- 更新内部状态(记忆单元和隐藏状态)
- 输出一个隐藏状态向量
比如对于 "your" 这个位置:
- 正向 LSTM 已经看过 "What is"
- 反向 LSTM 已经看过 "? name"
- 两个方向的隐藏状态拼接后能同时利用前后文信息
1. **得到上下文向量**
最后我们得到一个固定维度(比如 256 维)的上下文向量 C,它压缩了整个句子的信息,包含:
- 句子是疑问句
- 询问对方名字
- 语气比较礼貌正式
- 等等...
这个上下文向量 C 就会被传递给解码器,作为生成目标语言(比如中文)翻译的基础。
## 2. 解码器(Decoder)
让我用英译中的例子来说明解码器的工作过程,就拿 "What is your name?" → "你叫什么名字?" 为例:
1. **初始化阶段**
- 用编码器的上下文向量 C 初始化解码器的隐藏状态
- 输入起始符 ⟨GO⟩
1. **第一步生成**
输入: ⟨GO⟩
- 解码器读入 ⟨GO⟩ 的向量表示
- 结合隐藏状态,计算所有中文字/词的概率分布:
- "你": 0.82
- "请问": 0.10
- "告诉": 0.05
- 其他: 0.03
- 选择概率最高的 "你" 作为第一个输出
1. **第二步生成**
输入: "你"
- 将 "你" 的词向量输入 LSTM
- 更新隐藏状态
- 预测下一个字的概率:
- "叫": 0.78
- "是": 0.12
- "好": 0.06
- 其他: 0.04
- 输出 "叫"
1. **后续步骤**
- 输入: "叫" → 输出: "什"
- 输入: "什" → 输出: "么"
- 输入: "么" → 输出: "名"
- 输入: "名" → 输出: "字"
- 输入: "字" → 输出: "?"
- 输入: "?" → 输出: ⟨EOS⟩
值得注意的是,中文解码相比法语有一些特点:
1. 输出单位可能是字或词(取决于分词方式)
2. 语序差异更大(比如英语的疑问词在句首,中文在句中)
3. 需要处理标点符号的转换(如 "?" → "?")
解码器要在每一步都权衡:
- 已经生成的部分("你叫")是否通顺
- 未来要生成的部分("什么名字?")是否符合中文表达习惯
- 整体是否准确传达了原句的意思
这个中文的例子是否让解码过程更容易理解了?
## 注意力机制
让我用这个翻译例子具体解释为什么需要注意力机制。
假设我们要翻译一个较长的句子:
"The old man who lives next door to my family has a beautiful garden that blooms with colorful flowers every spring."
→
"住在我家隔壁的那位老人有一个漂亮的花园,每到春天都会开满彩色的花。"
**没有注意力机制时的问题**:
1. **信息瓶颈**
- 编码器必须把这整句28个英文单词的所有信息(人物特征、位置关系、花园特点、时间等)都压缩到一个固定维度(比如256维)的向量中
- 当解码器要生成"老人"时,相关信息("old man")可能已经在压缩过程中变得模糊
- 当要生成"春天"时,"spring"的信息可能已经被覆盖或削弱
1. **解码困境**
- 解码器只能依赖这一个全局向量来生成所有中文词
- 比如生成"花园"时,需要从这个向量中提取关于"garden"的信息
- 但这个信息可能已经和其他信息(如"老人"、"春天"等)混在一起,难以准确提取
**加入注意力机制后**:
- 生成"老人"时,可以主动关注输入中的"old man"部分的隐藏状态
- 生成"花园"时,可以聚焦于"beautiful garden"相关的隐藏状态
- 生成"春天"时,可以重点关注"every spring"对应的表示
这就像一个人在翻译时:
- 不用一次性记住整句话的所有细节
- 而是可以反复看原文的不同部分
- 需要翻译哪部分就重点看哪部分
- 从而保证翻译的准确性
这样解释是否帮助你更好地理解为什么需要注意力机制?