11.5.2 Seq2Seq 模型

- 理解 Seq2Seq 和分类类任务的根本差别
- 理解 encoder 和 decoder 各自负责什么
- 通过可运行示例建立“编码再生成”的直觉
- 理解 Seq2Seq 为什么成为很多生成任务的基础结构
先建立一张地图
Section titled “先建立一张地图”Seq2Seq 这节最适合新人的理解顺序不是“先看模型细节”,而是先看清任务形态变了什么:
flowchart LR A["输入一段文本"] --> B["编码器先读懂它"] B --> C["内部表示"] C --> D["解码器一步步生成输出"]所以这节真正想解决的是:
- 为什么“文本到文本”任务和分类任务根本不是一类问题
- 为什么要把系统拆成 encoder 和 decoder 两部分
一、Seq2Seq 在解决什么问题?
Section titled “一、Seq2Seq 在解决什么问题?”它不是“给整句打标签”
Section titled “它不是“给整句打标签””它更像:
- 输入一串 token
- 输出另一串 token
例如:
- “我爱学习” -> “I love studying”
为什么普通分类器不适合做这类任务?
Section titled “为什么普通分类器不适合做这类任务?”因为分类器输出通常是固定集合里的一个标签。 而 Seq2Seq 任务的输出:
- 长度不固定
- 内容不固定
- 生成过程有顺序依赖
分类像给作文打一个分数。 Seq2Seq 更像把中文作文重新写成英文作文。
二、编码器和解码器分别在做什么?
Section titled “二、编码器和解码器分别在做什么?”它负责:
- 读入输入序列
- 把输入压成内部表示
它负责:
- 基于编码结果
- 一步一步生成输出序列
为什么要分成两部分?
Section titled “为什么要分成两部分?”因为这类任务天然是:
- 先理解输入
- 再构造输出
这和单纯分类不一样。
三、先跑一个“编码后生成”的最小示例
Section titled “三、先跑一个“编码后生成”的最小示例”translation_memory = { "我": "I", "爱": "love", "学习": "study",}
def encode(source_tokens): return {"source_tokens": source_tokens, "length": len(source_tokens)}
def decode(encoded): output = [] for token in encoded["source_tokens"]: output.append(translation_memory.get(token, "<unk>")) return output
source = ["我", "爱", "学习"]encoded = encode(source)target = decode(encoded)
print("encoded:", encoded)print("decoded:", target)预期输出:
encoded: {'source_tokens': ['我', '爱', '学习'], 'length': 3}decoded: ['I', 'love', 'study']这只是玩具级词典 decoder,但它把 Seq2Seq 的形状展示出来了:先把整个输入编码起来,再由 decoder 生成一个输出序列。
这个例子最重要的启发是什么?
Section titled “这个例子最重要的启发是什么?”它说明 Seq2Seq 的核心流程是:
- 输入不直接变成最终答案
- 中间先过一层编码表示
- 再由解码器生成输出
新人第一次学 Seq2Seq,最该先记什么?
Section titled “新人第一次学 Seq2Seq,最该先记什么?”最值得先记住的是:
- encoder 更像“先把输入读懂”
- decoder 更像“根据理解结果一步步写输出”
- 输出不是固定标签,而是一个有顺序的生成过程
四、Seq2Seq 最常见的难点是什么?
Section titled “四、Seq2Seq 最常见的难点是什么?”输入压缩过于粗糙
Section titled “输入压缩过于粗糙”早期 encoder-decoder 的一个典型问题是:
- 整个输入被压成单个固定长度向量
输入一长,信息容易丢失。
输出是逐步生成的
Section titled “输出是逐步生成的”这意味着:
- 前一步错了
- 后面也容易跟着错
这也是为什么后面会引入注意力机制
Section titled “这也是为什么后面会引入注意力机制”注意力的核心目的之一,就是让解码器在生成时不必只依赖一个固定向量, 而是可以动态查看输入不同位置。
这节和后面注意力机制的关系是什么?
Section titled “这节和后面注意力机制的关系是什么?”这节最该先立住的是:
- Seq2Seq 的“编码 -> 解码”主线
而下一节注意力要解决的,正是这里的核心瓶颈:
- 固定长度表示太容易丢信息
五、Seq2Seq 适合哪些任务?
Section titled “五、Seq2Seq 适合哪些任务?”典型输入输出映射任务。
输入长文,输出短文。
改写与问答生成
Section titled “改写与问答生成”输入与输出不是同一份文本,但有明确对应关系。
六、最容易踩的坑
Section titled “六、最容易踩的坑”误区一:Seq2Seq 就只是“翻译模型”
Section titled “误区一:Seq2Seq 就只是“翻译模型””翻译只是最经典例子。 它本质上适用于更广的“文本到文本”任务。
误区二:有编码器和解码器就已经足够
Section titled “误区二:有编码器和解码器就已经足够”如果没有注意力和更强表示,长输入问题会很明显。
误区三:生成任务只要会输出就行
Section titled “误区三:生成任务只要会输出就行”Seq2Seq 任务真正难的是:
- 对输入忠实
- 生成合理
- 保持结构
学完这一页,至少保留这张证据卡:
- 源目标
- 源文本、目标文本和任务类型
- 解码输出
- 生成的摘要、翻译、转写或序列结果
- 对齐说明
- 注意力、CTC 路径、coverage,或复制的源证据
- 失败检查
- 遗漏、重复、幻觉、对齐错误或评估薄弱
- 期望产出
- 生成文本,以及事实性或对齐性复核说明
这节最重要的是把 Seq2Seq 理解成:
一类先编码输入、再逐步生成输出的结构,它是翻译、摘要和很多文本生成任务的基础范式。
只要这个结构主线清楚,后面学注意力和 T5 时就会很自然。
这节最该带走什么
Section titled “这节最该带走什么”- Seq2Seq 是“输入序列 -> 输出序列”的基础结构
- encoder / decoder 是为了解决“先理解,再生成”
- 注意力机制的出现,正是为了补 Seq2Seq 最核心的信息瓶颈
- 把示例里的词典扩成 5~10 个词,再试几个句子。
- 为什么说 Seq2Seq 的输出不是固定长度、也不是固定标签集?
- 想一想:如果输入非常长,为什么“只压成一个向量”会吃力?
- 用自己的话解释:encoder 和 decoder 各自负责什么?
解题思路与讲解
- 扩展字典后,玩具生成器能覆盖更多输入词,但仍会在未见词和词序上失败。
- Seq2Seq 输出不是固定长度,因为 decoder 会一步步生成 token,直到停止条件,而不是从固定标签集合里选一个。
- 把长输入压成一个向量很难,因为细节、顺序和长距离依赖都在争夺有限表示空间。
- encoder 负责读取输入并形成表示;decoder 使用这个表示和已经生成的输出继续生成目标序列。