序言
在序列建模领域,循环神经网络( RNN \text{RNN} RNN)及其变体,如长短期记忆网络( LSTM \text{LSTM} LSTM)和门控循环单元( GRU \text{GRU} GRU),因其处理序列数据的能力而备受关注。然而,对于某些复杂任务,如机器翻译、语音识别和问答系统,传统的 RNN \text{RNN} RNN模型在处理不等长输入和输出序列时显得力不从心。基于编码/解码的序列到序列( Seq2Seq \text{Seq2Seq} Seq2Seq)架构的提出,为这些难题提供了新的解决方案。
基于编码/解码的序列到序列架构
- 我们已经在下面篇章的图例中看到 RNN ‾ \underline{\text{RNN}} RNN如何将输入序列映射成固定大小的向量。
- 我们已经在下面篇章的图例中看到 RNN ‾ \underline{\text{RNN}} RNN如何将固定大小的向量映射成一个序列。
- 我们已经在下列篇章的图例中看到 RNN ‾ \underline{\text{RNN}} RNN如何将一个输入序列映射到等长的输出序列。
- 本篇我们讨论如何训练
RNN
\text{RNN}
RNN,使其将输入序列映射到不一定等长的输出序列。
- 这在许多场景中都有应用,如语音识别、机器翻译或问答,其中训练集的输入和输出序列的长度通常不相同(虽然它们的长度可能相关)。
- 我们经常将RNN的输入称为 ‘‘上下文’’。
- 我们希望产生此上下文的表示, C C C。
- 这个上下文 C C C 可能是一个概括输入序列 X = ( x ( 1 ) , … , x ( n x ) ) \boldsymbol{X}=(\boldsymbol{x}^{(1)},\dots,\boldsymbol{x}^{(n_x)}) X=(x(1),…,x(nx))的向量或者向量序列。
- 用于映射可变长度序列到另一可变长度序列最简单的
RNN
\text{RNN}
RNN架构最初由
Cho et al. (2014a)
\text{Cho et al. (2014a)}
Cho et al. (2014a) 提出,之后不久由
Sutskever et al. (2014)
\text{Sutskever et al. (2014)}
Sutskever et al. (2014) 独立开发,并且第一个使用这种方法获得翻译的最好结果。
- 前一系统是对另一个机器翻译系统产生的建议进行评分,而后者使用独立的循环网络生成翻译。
- 这些作者分别将该架构称为编码-解码或序列到序列架构,如
图例1
所示。 - 这个想法非常简单:
- (1) 编码器 ( encoder \text{encoder} encoder)或读取器( reader \text{reader} reader) 或输入 ( input \text{input} input) RNN \text{RNN} RNN处理输入序列。 编码器输出上下文 C C C(通常是最终隐藏状态的简单函数)。
- (2) 解码器 (decoder) 或写入器 (writer) 或输出 (output)
RNN
\text{RNN}
RNN则以固定长度的向量(如
循环神经网络篇 - 图例7
)为条件产生输出序列 Y = ( y ( 1 ) , … , y ( n y ) ) \boldsymbol{Y}=(\boldsymbol{y}^{(1)},\dots,\boldsymbol{y}^{(n_y)}) Y=(y(1),…,y(ny))。 - 这种架构对比
前几篇章
提出的架构的创新之处在于长度 n x n_x nx 和 n y n_y ny 可以彼此不同,而之前的架构约束 n x = n y = τ n_x = n_y = \tau nx=ny=τ。 - 在序列到序列的架构中,两个 RNN \text{RNN} RNN共同训练以最大化 log P ( y ( 1 ) , … , y ( n y ) ∣ x ( 1 ) , … , x ( n x ) ) \log P(\boldsymbol{y}^{(1)},\dots,\boldsymbol{y}^{(n_y)}|\boldsymbol{x}^{(1)},\dots,\boldsymbol{x}^{(n_x)}) logP(y(1),…,y(ny)∣x(1),…,x(nx))(关于训练集中所有 x \boldsymbol{x} x 和 y \boldsymbol{y} y 对的平均)。
- 编码器 RNN \text{RNN} RNN的最后一个状态 h n x \boldsymbol{h}_{n_x} hnx 通常被当作输入的表示 C C C 并作为解码器 RNN \text{RNN} RNN的输入。
- 如果上下文
C
C
C 是一个向量,则编码器
RNN
\text{RNN}
RNN只是在
循环神经网络篇 - 基于上下文的RNN序列建模
描述的向量到序列 RNN \text{RNN} RNN。- 正如我们所见,向量到序列 RNN \text{RNN} RNN至少有两种接受输入的方法。
- 输入可以被提供为 RNN \text{RNN} RNN的初始状态,或连接到每个时间步中的隐藏单元。这两种方式也可以结合。
- 这里并不强制要求编码器与解码器的隐藏层具有相同的大小。
- 此架构的一个明显限制是,编码器
RNN
\text{RNN}
RNN输出的上下文
C
C
C 的维度太小而难以适当地概括一个长序列。
- 这种现象由 Bahdanau et al. (2015) \text{Bahdanau et al. (2015)} Bahdanau et al. (2015) 在机器翻译中观察到。
- 他们提出让 C C C 成为可变长度的序列,而不是一个固定大小的向量。
- 此外,他们还引入了将序列 C C C 的元素和输出序列的元素相关联的注意机制 ( attention mechanism \text{attention mechanism} attention mechanism)。可在后续篇章中了解更多详情。
- 图例1:在给定输入序列
(
x
(
1
)
,
…
,
x
(
n
x
)
)
(\text{x}^{(1)},\dots,\text{x}^{(n_x)})
(x(1),…,x(nx)) 的情况下学习生成输出序列
(
y
(
1
)
,
…
,
y
(
n
y
)
)
(\text{y}^{(1)},\dots,\text{y}^{(n_y)})
(y(1),…,y(ny))的编码器-解码器或序列到序列的
RNN
\text{RNN}
RNN架构的示例。
-
在给定输入序列 ( x ( 1 ) , … , x ( n x ) ) (\text{x}^{(1)},\dots,\text{x}^{(n_x)}) (x(1),…,x(nx)) 的情况下学习生成输出序列 ( y ( 1 ) , … , y ( n y ) ) (\text{y}^{(1)},\dots,\text{y}^{(n_y)}) (y(1),…,y(ny))的编码器-解码器或序列到序列的 RNN \text{RNN} RNN架构的示例。
-
说明:
- 它由读取输入序列的编码器 RNN \text{RNN} RNN以及生成输出序列(或计算给定输出序列的概率)的解码器 RNN \text{RNN} RNN组成。
- 编码器 RNN \text{RNN} RNN的最终隐藏状态用于计算一般为固定大小的上下文变量 C C C, C C C表示输入序列的语义概要并且作为解码器 RNN \text{RNN} RNN的输入。
-
总结
- 基于编码/解码的序列到序列架构通过分离编码和解码过程,有效地映射了可变长度的输入序列到另一可变长度的输出序列。
- 编码器部分,通常是一个 RNN \text{RNN} RNN或其变体,负责读取并处理输入序列,将其压缩成一个固定长度的上下文向量 C C C,该向量蕴含了输入序列的语义信息。
- 解码器部分,则是以此上下文向量为条件,逐步生成输出序列。此架构的一个关键优势在于其灵活性,能够处理长度不一的输入输出序列,并且可以通过引入注意力机制( Attention Mechanism \text{Attention Mechanism} Attention Mechanism)进一步提升性能,使模型在生成当前输出时能够聚焦于输入序列的相关部分。
- 总之,基于编码/解码的序列到序列架构为序列建模任务提供了一种强大而灵活的方法,极大地推动了自然语言处理等领域的发展。
往期内容回顾
序列建模之循环和递归网络 - 展开计算图篇
序列建模之循环和递归网络 - 循环神经网络篇
序列建模之循环和递归网络 - 双向RNN篇