大家好,我是半虹,这篇文章来讲序列到序列模型 (Sequence To Sequence, Seq2Seq)
本文写作思路如下:
从循环神经网络的应用场景引入,介绍循环神经网络作为编码器和解码器使用,最后是序列到序列模型
在之前的文章中,我们已经介绍过循环神经网络及其两个变体,长短期记忆网络和门控循环单元
这一系列模型是深度学习领域中处理时序数据的一种基础架构,在多种任务场景都有重要的应用
循环神经网络的第一个应用场景就是作为编码器使用,以编码时序数据
在深度学习时代,模型可以通过海量数据自动学习数据特征并得到数据在某个特征空间上的向量表示
这是深度学习中至关重要的一步,一个好的表示对后续的处理有非常大的帮助
举例来说,假设现在我们需要完成一个文本分类任务
首要的工作就是对文本编码得到其向量表示,然后在此基础上接一个分类模型做分类就好
如果在某个语义空间上,相同类别的文本向量能够聚集在一起,不同类别的文本向量能够分隔有距离
那么对于分类模型来说,很简单就可以区分不同类别的文本了
而循环神经网络正是对文本编码的一种常用方式,其按时间步展开的结构图如下所示
其中,对于时间步 t t t,输入为 X t X_{t} Xt,输出的隐状态为 H t H_{t} Ht
每个时间步的隐状态可以看作是在该时间步的输入的向量表示,这个表示能够建模当前输入的上下文语义
在此基础上,如果我们再对每个隐状态做分类预测或回归预测,就可以完成多种下游任务,例如序列标注
另外,最后一个时间步的隐状态可以看作是整个序列的表示,因为它包含了先前所有时间步的输入的信息
因此,我们对该隐状态做分类或回归预测后,就能完成一系列基于序列的任务,例如序列分类
循环神经网络的第二个应用场景就是作为解码器使用,解码出时序数据
所谓解码,其实可以理解成一个自回归生成过程
简单来说,就是根据上一步数据生成下一步数据,从而逐步地生成一个完整的序列
当这个序列具体为文本时,就是我们熟知的语言模型,一个能续写文字的生成模型
如上图所见,基于循环神经网络的语言模型除了会传递隐状态之外,还会将上一步输出作为下一步输入
这样,只要经过足够多的训练之后,语言模型就能根据用户的提示生成后续的文字
然而对于具体的任务来说,这样的续写仍然是不够的,因为生成的文字都是随机的,无法控制其生成的内容
我们更希望让模型生成的文字能满足某种给定的约束
下一个问题就是,这个约束要怎么接入到模型里面呢
首先要明确的是,我们通常会将约束表示成一个向量,并将该向量称为上下文向量 context vector \text{context vector} context vector
至于怎么将这个向量接入模型,那方法可以说得上是多种多样
最简单的方法就是用上下文向量初始化循环神经网络的隐状态
给定约束之后,可以更好地保证模型生成的内容与给定的约束相关,可以更好地应用到下游任务
假如上下文向量是一段文本的向量表示,就可以完成一系列文本到文本的任务,例如文本摘要等
假如上下文向量是一张图像的向量表示,就可以完成一系列图像到文本的任务,例如图像描述等
至此,我们已经介绍了循环神经网络的两种应用场景,是时候请出今天的主角:序列到序列模型
序列到序列模型可以说是一种范式,所有输入是序列、输出是序列的模型都可以称为序列到序列模型
序列到序列模型最常用的一种架构是编码器到解码器 Encoder-Decoder \text{Encoder-Decoder} Encoder-Decoder
其工作过程分为两个步骤:
- 编码:用编码器将输入序列编码成上下文向量(注:循环神经网络可以作为编码器)
- 解码:用解码器将上下文向量解码成输出序列(注:循环神经网络可以作为解码器)
实际上就是我们之前所说的,循环神经网络作为编码器和循环神经网络作为解码器的联合应用啦
下面是一个基于循环神经网络的序列到序列模型示意图,其中 R 1 R_{1} R1 表示编码器, R 2 R_{2} R2 表示解码器
当然,训练一个好的编码器到解码器模型有很多技巧,例如 Teacher Forcing \text{Teacher Forcing} Teacher Forcing、 Beam Search \text{Beam Search} Beam Search 等等
由于篇幅原因,就不在这篇文章里细说,预计会在之后的实战文章中进行介绍,敬请期待
至此本文结束,要点总结如下:
循环神经网络可以作为编码器使用,以编码时序数据
循环神经网络可以作为解码器使用,解码出时序数据
将上述两种应用联合起来,就是序列到序列模型