从seq2seq到注意力机制

seq2seq 模型

seq2seq模型诞生于语言模型的相关任务中,最初是用来处理翻译问题的,解决了将任意长度的输入序列转变为对应的输出序列的问题,普通的全连接网络结构没法接受一个可变长度的输入,也没法产生一个变长的输出,Sutskever, Ilya et al. “Sequence to Sequence Learning with Neural Networks.” NIPS (2014) 中提出了解决这一问题的比较直接的方式。因为 RNN 的输入长度可以不预先固定,简单想法就是通过RNN接受输入,接着通过另一个 RNN 将前一个 RNN 的输出,也就是通常所称的内容向量(context vector)转变为输出序列,注意此处的内容向量的维度是固定的。后来 seq2seq 模型逐渐用于多种语言之间的翻译文本-语音翻译或者是问答系统之类的任务中。

seq2seq 模型通常将接受输入的RNN称为编码器(encoder),将产生输出的RNN成为了解码器(decoder):

  • 编码器接受输入,并将信息压缩进固定长度的内容向量中(context vector),也有文献将其称为句子嵌入(sentence embedding)或者思维向量(thought vector),这种表示被认为能产生对于源语句所包含意义的编码表示。
  • 解码器用内容向量初始化,早期工作里编码器的初始化向量用的不是内容向量,而是编码器的最后状态,这样只能得到编码器最后一步的输出,相比较起内容向量的方式损失了更多信息。
编码器-解码器模型的简单示意

注意力机制

但是面对长句子的处理时,固定长度的内容向量的缺陷显露出来,它最大的问题在于无法记住长句子,很多时候编码器在处理完整个输入之后就忘了开头部分,解码的时候也是如此,内容向量随着时间步传输一段时间后就逐渐被遗忘。

Bahdanau, Dzmitry 等人在 “Neural Machine Translation by Jointly Learning to Align and Translate.(2015)"中提出了
改进方案,并且引入注意力机制解决长期记忆的问题,同时在编码器的结构上也做了细微调整,

  • 用双向RNN来处理输入序列,而且编码器在每一个编码步的信息都会被保留作为编码器的输出;
  • 解码的时候每次读入编码器的输出,并且输出一个单词,也就是说解码的每一步都能读取到所有的编码信息,并且借助注意力的方式来决定编码信息中的哪一部分和当前的联系最为紧密。

注意力机制可认为是一种权重分配,例如在图像处理中,图片像素和临近像素有多大程度上有关,或者句子中的单词之间的相关性的强弱。比起从编码器的最后隐层状态构建单个内容向量,注意力机制的秘密在于内容向量和整个源输入之间创建了快捷连接,这些快捷连接的权重是可以根据每个输出元素定制化的。简单来说,内容向量不再是固定不变的,而是在每一个解码步产生内容向量,这种方式考虑到了每次解码的时候的不同情况,因此更具灵活性。

Bahdanau 提出的加性注意力机制的图解.

注意力机制考虑的是输入序列和输出序列之间关联的紧密程度,自注意力机制则反映了输入序列内部之间不同组分之间(在自然语言处理的领域,也就是不同单词之间)关联的紧密程度。注意力机制显式地将选择过程交给我们控制,也就是对于目标单词,从源单词表中寻找其关注对象。自注意力机制除了考虑源单词表之外,还考虑了对于输出的关注,也就是对输出序列自身的关注,这一部分准备放到Transformer中详细叙述。

注意力机制的核心是注意力层,注意力层的输入被称为一个查询,对于该查询,注意力层会根据已有记忆(memory,在Transformer中叫键值对)返回一个输出,这个记忆也就是键值对(Key-Value Pair)。假设有个键值对,对于每个查询,其实也就是每次输入的源单词,可以得到一个输出,其维度和值一样。具体做法为:使用得分函数得到一组分数,对得分进行指数归一化,得到一个归一化的权重,最后得到值的凸组合。直观理解就是使用已有键值对对查询作插值,其重点在于得分函数的设计,也就是如何判断两个向量之间的相似程度,在不合理的设计中,相似度高不代表接近。

注意力的计算其实很多地方都可以找到,在此简单提及。

  • 对于encoder层的隐状态输出,假设编码步长为,为第步的encoder的输出,可以是单向RNN也可以是双向的,如果是双向的,这里的指双向隐状态的拼接。
  • 在每一步解码的时候,我们可以得到decoder的原始输出,记为,也就是解码到第步,此时我们将解码和编码向量通过得分函数作用,。
  • 在这个维得分向量上进行指数归一化得到,以此作为线性组合系数对encoder的隐状态作线性组合得到内容向量,也叫注意力向量,,
  • 以此为基础,可以结合原始输出的信息得到第步decoder的输出,接着可以将其投影到目标单词表维度上,得到单词表中的一个单词。

指针网络

注意力机制的改进或者说简化还有一些好玩的应用,指针网络就是一例,指针网络由Vinyals, Oriol et al 在“Pointer Networks.” NIPS (2015)中提出。作者提出可以被用来解决一些输出长度依赖于输入的可变输入的问题。此处需要做一个细致的分辨,seq2seq模型也能处理变长输入的问题,因为RNN结构可以不停地接受下一个时间步长的输入。

那指针网络的创新点在哪呢?这里涉及到模型构建中的一个小细节,指针网络所解决的变长问题不在于输入长度可变。在encoder-decoder结构的通常应用中,譬如说翻译问题,我们需要在解码的每一步输出目标词汇表中的一个单词,对于网络来说是输出一个目标词汇表上的分布,词汇表的长度在模型构建之前就已经确定了,因此在训练中不再可变,假如我从64个单词表的任务迁移到128个单词表的任务,就需要重新训练。

指针网络解决了输出长度依赖于输入长度的问题,传统的encoder-decoder结构的输出长度依赖于词汇表的大小。如果弄清楚了注意力机制,指针网络的实现就显得比较简单,它在计算内容向量之前就输出了,其实是对注意力的计算过程作了截断。在注意力计算中得到归一化系数之后,我们对此使用得到一个索引,这个索引指向的其实是输入中的某个位置,作者将其称为“指针”,也就是说在当前解码步,我们认为输入中的这个位置最为相关,将其作为网络的输出。在原文中,作者尝试用指针网络来解决旅行商问题、凸包问题和排序问题,结果表明,纯粹数据驱动的求解器也许可以在旅行商问题这类NP难问题上有所贡献。

你可能感兴趣的:(从seq2seq到注意力机制)