Logo
Section 1 / 10

序列到序列模型

学习如何使用深度学习处理序列数据(尤其是文本)。

导入

序列到序列模型

学习如何使用深度学习处理序列数据(尤其是文本)。

要理解注意力机制,我们需要先探讨它在自然语言处理中的起源。机器翻译——即将一种语言的输入句子转换为另一种语言——是一个非常典型的应用场景。

那么,在此之前我们是如何处理自然语言中的文本和句子的呢?

从机器学习的角度建模文本

我们首先从机器学习的角度来形式化这个问题。

先思考输入与输出的关系,有助于我们理解这类模型。

表示方式非常直观:句子可以被视为词语的序列。

在展示任何复杂的模型之前,让我们先全面了解一下。我们将输入句和输出句都表示为序列。

序列到序列模型(Seq2Seq)

理想情况下,模型需要理解一种语言中的输入句子,这一过程由所谓的“编码器”(encoder)完成。编码器生成一个中间表示,图中记作 z。

接着我们需要将这种语义信息转换成另一种语言,因此引入“解码器”(decoder)模型来完成这一任务。

事实上,这些术语本身并无特别之处。

该类方法统称为序列到序列(Seq2Seq),其工作原理大致如上图所示。

序列中的元素 x1,x2x_1, x_2 等通常被称为 token(词元),它们可以是任意形式的内容。

例如,它们可以是文本的表示、像素值,甚至在视频任务中可以是图像帧。

但为什么我们要使用这类模型?

目标是将一个输入序列(源序列)转换为另一个新序列(目标序列)。这两个序列可以长度相同,也可以是任意长度。

你可能已经注意到,在此前课程中介绍过的循环神经网络(RNNs)曾主导了序列到序列任务。

原因很简单:我们习惯于按顺序处理序列。这听起来似乎很自然且高效?然而注意力机制以及后来的Transformer模型证明,事实并非如此!

编码器与解码器的完整视角

假设这里的 编码器 和 解码器 是由堆叠的 RNN 或 LSTM 单元构成,比如 LSTM 网络。

编码器逐个处理输入序列,并基于所有时间步的输入生成一个紧凑的中间表示,称为 z。

z 可以被看作是对输入信息的一种压缩表示。

另一方面,解码器接收上下文向量 z,并据此生成输出序列。

Seq2Seq 最常见的应用就是机器翻译。

我们可以把输入序列理解为一句英文句子的表示,而输出则是该句子对应的法语翻译。

事实上,基于 RNN 的架构曾经表现非常出色,尤其是结合 LSTM 组件时。

问题出在哪里?仅限于较短的序列(<20 个时间步)。直观来看:

让我们分析一下背后的原因。

RNN 的局限性

主要问题在于:中间表示 z 无法有效编码所有输入时间步的信息。这通常被称为 瓶颈问题。向量 z 必须承载整个源句子的全部信息。

理论上,数学上认为这是可能的;但在实践中,模型能回顾的历史信息(即所谓的“感受野”)是有限的。数据量有限也是一个重要因素。因此,RNN 容易遗忘较早时间步的信息。

来看一个具体的例子。设想一个包含 97 个单词的句子:

“当那个男人主动提出要帮助那位盲人时,他还没有产生任何恶意念头,恰恰相反,他所做的不过是遵从了人们普遍具有的慷慨与利他之心,众所周知,这两种品质正是人性中最优秀的特质,甚至连比他更凶恶的罪犯身上也常常能找到。实际上,此人不过是个毫无前途可言的普通偷车贼,受雇于幕后真正的老板,因为真正从中获利的是那些利用穷人困境的人。” ~ 若泽·萨拉马戈,《失明症漫记》

你是否注意到什么问题?帮助理解的关键词(加粗部分)之间相隔甚远!

大多数情况下,向量 z 很难同时保留开头几个词和第 97 个词的完整信息。

最终,系统往往更关注序列末尾的部分。但这通常不是处理序列任务的最佳方式,也不符合人类翻译或理解语言的习惯。

此外,堆叠的 RNN 层还常常引发著名的 梯度消失问题。由于反向传播过程中涉及多个小于 1 的数值连乘,导致梯度逐渐趋近于零。而这些乘法运算是梯度在网络中回传所必需的,在 RNN 结构中难以避免。下图可帮助你直观理解这一现象:

图中蓝色的深浅表示梯度值的衰减程度。

生成对抗网络

注意力