4.4 序列到序列与NLP应用


4.4 序列到序列与NLP应用

本节摘要:机器翻译这类"长短不一的输入换长短不一的输出"任务,需要把两个 RNN 拼起来:编码器把源序列压成一个上下文向量,解码器再由它逐词吐出新序列。本节讲清编解码分工、解码时的逐词生成,以及注意力为何应运而生,并落到情感分析等真实 NLP 场景。

4.1 到 4.3 都在讲"一个序列怎么被理解"。本节把镜头拉到更高一层:有些任务不是理解,而是从一段输入生成另一段输出——翻译、摘要、对话皆然。这会牵出一个更通用的骨架:序列到序列(Seq2Seq)。

长短不一的入和出,需要一个中转站

分类一个句子是正面还是负面,输出只有一个标签;可翻译一个句子,输出是另一串长短不定的词。这类任务用单个 RNN 办不到,于是人们把两个 RNN 焊成机关:编码器按顺序读过源序列,每次更新隐藏状态,把整句的语义慢慢"压"进一个收尾的上下文向量;解码器拿着这个上下文向量当起点,一次吐一个词,并把刚吐出的词再喂回自己,一路滚到句尾标记为止。

编码器读、解码器写,两端通过上下文向量交接。它有个朴素假设:整句的要点都能装进那一个向量里。句子一长,这个"单点收纳"就成了瓶颈——开头的重要信息传到解码器时往往淡了。解决它,正是第5章注意力的出场动机:解码时不再只盯那一个向量,而是回头看一眼源序列的"每个位置",按需取用。

画一张编解码流水图

按时间把编解码展开,流向一目了然:

这张图浓缩了两件事:左边是"压缩",右边是"展开"。注意解码器有一条自己喂自己的回环——这正是它"逐词生成"的来源,也是线上推理时最费算力的环节,因为必须等上一个词出来才能算下一个,无法并行。

用代码搭一个能跑的编解码骨架

不追求工程完善,把结构用框架直译出来,重点是看清"编码器输出如何喂给解码器":

import tensorflow as tf # 编码器:读源序列,产出最终状态 enc_in = tf.keras.Input(shape=(None,)) enc = tf.keras.layers.Embedding(src_vocab, 128)(enc_in) enc = tf.keras.layers.LSTM(256, return_state=True) enc_out, h, c = enc(enc) # 解码器:用编码器终态初始化自己的 LSTM 状态 dec_in = tf.keras.Input(shape=(None,)) dec = tf.keras.layers.Embedding(tgt_vocab, 128)(dec_in) dec = tf.keras.layers.LSTM(256, return_sequences=True, initial_state=[h, c]) dec = tf.keras.layers.Dense(tgt_vocab, activation="softmax")(dec) model = tf.keras.Model([enc_in, dec_in], dec) model.compile(optimizer="adam", loss="sparse_categorical_crossentropy")

initial_state=[h, c] 那一行就是"上下文携带"的落点:编码器学到的整句压缩,被解码器拿来当起点。骨架秒懂后,你需要补上的只是把源/目标序列 pad 到等长、做掩码这些工程细节。

从翻译到情感:一些真实 NLP 落点

这一整套结构从机器翻译成长起来,却远远不止翻译:

机器翻译:上文骨架的原型任务,源句长、目标句长,还牵扯词序颠倒,是考验长程建模的硬仗。

文本生成 / 摘要:解码器连句首与句尾做的是"接骨",先进的生成模型对每一步既考虑语言感也考虑主题感的取舍。

情感分析:相对简单——多数是分类(还要看是句子级还是方面级,比如"服务好但价格高"就得分两面看)。用分类的判别力,用 RNN 或直接卷到注意力上。

问答与对话:本质是"上下文 + 问题 → 答案序列"的 Seq2Seq 变体,近距离的下一站就是第5章注意力与 Transformer 的主场。

列这张清单时你会发现一个规律:越是任务复杂、上下文长,RNN 越吃力,注意力越成为刚需。这不只是本节的事,也是整本主线走到第5章的必然。

训练时为何要用"教师强迫"

解码器逐词生成时有个技巧:喂给解码器的"上一步输出",训练阶段用真实的上一词(对教学开局有利),推理阶段才用模型自己刚生成的词。这被称为教师强迫。好处是训练时模型不会因早期一步错而步步错、梯度更稳;坏处是训练与推理的输入分布有差异,学术界称之为"曝光偏差"。工程上的通用做法是训练时以一定概率混入模型自己的输出(计划采样),让两头逐渐对齐,只是要留一手防止训练因此崩溃。

比翻译更贴近主线的落点:摘要

如果说翻译是最典型的 Seq2Seq,那么摘要把"压缩输入"这一面放大了:一段长文压成一个简短摘要,本质上要求模型先"读进全貌"再"择要吐述"。原文越长,越考验长程建模,也越凸显单上下文向量的吃力——注意力在下文登场的一切动机,在摘要这类任务上尤其直观。做情感分析常是"判别式"的轻活,做摘要则是实打实"生成式"的硬仗,两者的差距,正是一扇观察"注意力为何必要"的好窗口。

变长债的最后一笔

Seq2Seq 里"长短不一"会在三处出现:输入序列、输出序列、以及 batch 内互相不等长。相应地要处理 pad 与掩码——pad 补零后要让编码器对这些位置不更新、解码器对补上的结束符不惩罚。把这些掩码理清楚,编解码模型才算真正在变长数据上跑得动。这一步看似琐碎,却是从"跑通 toy"到"喂真语料"之间最常卡人的一环。

本节要点回顾

  • Seq2Seq = 编码器压缩 + 上下文向量 + 解码器展开
  • 解码器逐词自喂是生成的本质,也是推理无法并行的瓶颈
  • 单上下文向量是长句瓶颈,注意力正是为打破它而来
  • 翻译 / 生成 / 情感 / 问答都能归入这套编解码骨架
  • 任务越复杂,注意力越刚需,主线由此转入第5章

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U