Seq2seq

Seq2seq全名是Sequence-to-sequence,也就是从序列到序列的过程,是近年当红的模型之一。Seq2seq被广泛应用在机器翻译、聊天机器人甚至是图像生成文字等情境。
seq2seq 是一个Encoder–Decoder 结构的网络,它的输入是一个序列,输出也是一个序列, Encoder 中将一个可变长度的信号序列变为固定长度的向量表达,Decoder 将这个固定长度的向量变成可变长度的目标的信号序列。

整个过程可以用下面这张图来诠释:

  • 编码阶段
    在RNN中,当前时间的隐藏状态由上一时间的状态和当前时间输入决定的,即:
    \[
    h_t = f(h_{t-1},x_t)
    \]
    获得了各个时间段的隐藏层以后,再将隐藏层的信息汇总,生成最后的语义向量
    \[
    C = q(h_1,h_2,h_3,...,h_x)
    \]
    当然,有一种最简单的方法是将最后的隐藏层作为语义向量C,即
    \[
    C = q(h_1,h_2,h_3,...,h_x) = h_x
    \]
  • 解码阶段
    可以看做编码的逆过程。这个阶段,我们根据给定的语义向量\(C\)和之前已经生成的输出序列\(y_1\),\(y_2\),...,\(y_{t-1}\)来预测下一个输出的单词\(y_t\),即
    \[
    y_t = \argmax P(y_t)=\sum_{t=1}^T p(y_t|y_1,...,t_{t-1},C)
    \]
    也可以写作
    \[
    y_t = g({y_1,...,y_{t-1}},C)
    \]
    在RNN中,也可以简化成
    \[
    y_t = g(y_{t-1},s_t,C)
    \]
    其中\(s\)是输出RNN(即RNN解码器)中的隐藏层,\(C\)代表之前编码器得到的语义向量,\(y_{t-1}\)表示上个时间段的输出,反过来作为这个时间段的输入。\(g\)可以是一个非线性的多层神经网络,产生词典中各个词语属于\(y_t\)的概率。

Attention模型

encoder-decoder模型虽然非常经典,但是局限性也非常大。最大的局限性就在于编码和解码之间的唯一联系就是一个固定长度的语义向量C。也就是说,编码器要将整个序列的信息压缩进一个固定长度的向量中去。但是这样做有两个弊端,一是语义向量无法完全表示整个序列的信息,二是先输入的内容携带的信息会被后输入的信息稀释掉。输入序列越长,这个现象就越严重。这就使得在解码的时候一开始就没有获得输入序列足够的信息, 那么解码时准确率就要打一定折扣。
为了解决上述问题,在 Seq2Seq出现一年之后,Attention模型被提出了。该模型在产生输出的时候,会产生一个注意力范围来表示接下来输出的时候要重点关注输入序列的哪些部分,然后根据关注的区域来产生下一个输出,如此反复。attention 和人的一些行为特征有一定相似之处,人在看一段话的时候,通常只会重点注意具有信息量的词,而非全部词,即人会赋予每个词的注意力权重不同。attention 模型虽然增加了模型的训练难度,但提升了文本生成的效果。模型的大概示意图如下。

当前输出词\(Y_i\)针对某一个输入词\(j\)的注意力权重由当前的隐层\(H_i\),以及输入词\(j\)的隐层状态(\(h_j\))共同决定;然后再接一个\(sofrmax\)得到0-1的概率值。即通过函数\(F(h_j,H_i)\)来获得目标单词\(Y_i\)和每个输入单词对应的对齐可能性。

Attention算法过程

1)encode对输入序列编码得到最后一个时间步的状态\(c\),和每个时间步的输出\(h\),其中\(c\)又作为decode的初始状态\(z_0\)。

2)对于每个时间步的输出\(h\)与\(z_0\)做匹配也就是match操作,得到每个时间步的匹配向量\(α_{01}\),如图。

4)求各个时间步的输出\(h\)与匹配分数的加权求和得到\(c_0\),作为decode的下一个时间步的输入,如图。

图解Attention模型

CNN的seq2seq

现在大多数场景下使用的Seq2Seq模型是基于RNN构成的,虽然取得了不错的效果,但也有一些学者发现使用CNN来替换Seq2Seq中的encoder或decoder可以达到更好的效果。最近,FaceBook发布了一篇论文:《Convolutional Sequence to Sequence Learning》,提出了完全使用CNN来构成Seq2Seq模型,用于机器翻译,超越了谷歌创造的基于LSTM机器翻译的效果。此网络获得暂时性胜利的重要原因在于采用了很多的窍门,这些技巧值得学习:
•捕获long-distance依赖关系
底层的CNN捕捉相聚较近的词之间的依赖关系,高层CNN捕捉较远词之间的依赖关系。通过层次化的结构,实现了类似RNN(LSTM)捕捉长度在20个词以上的Sequence的依赖关系的功能。

改进

Attention model虽然解决了输入句仅有一个context vector的缺点,但依旧存在不少问题。
1.context vector计算的是输入句、目标句间的关联,却忽略了输入句中文字间的关联,和目标句中文字间的关联性;
2.不管是Seq2seq或是Attention model,其中使用的都是RNN,RNN的缺点就是无法平行化处理,导致模型训练的时间很长,有些论文尝试用CNN去解决这样的问题,像是Facebook提出的Convolutional Seq2seq learning,但CNN实际上是透过大量的layer去解决局部信息的问题,在2017年,Google提出了一种叫做”The transformer”的模型,透过self attention、multi-head的概念去解决上述缺点,完全舍弃了RNN、CNN的构架。
Seq2Seq的核心部分是其解码部分,大部分改进基于此:
greedy search:基础解码方法
beam search:对greedy search的改进
attention:它的引入使得解码时,每一步可以有针对地关注与当前有关的编码结果,从而减小了编码器输出表示的学习难度,也更容易学到长期的依赖关系。
memory network:从外部获取知识。
其他方法:
堆叠多层RNN的Decoder
增加dropout机制
与Encoder建立残差连接

Self attention

传统的rnn难于并行,而流行的attention模型往往会利用rnn。总之为了解决无法并行训练问题,google提出了self-attention,完全摒弃了rnn单元,从而做到并行训练。
Attention函数的本质可以被描述为一个查询(query)到一系列(键key-值value)对的映射,如下图。

Attention is all you need 是google机器翻译团队在2017年nips上发表的论文,
主要亮点在于:
1)不同于以往主流机器翻译使用基于RNN的seq2seq模型框架,该论文用attention机制代替了RNN搭建了整个模型框架。
2)提出了多头注意力(Multi-headed attention)机制方法,在编码器和解码器中大量的使用了多头自注意力机制(Multi-headed self-attention)。
3)在WMT2014语料中的英德和英法任务上取得了先进结果,并且训练速度比主流模型更快。
该论文模型的整体结构如下图,还是由编码器和解码器组成,在编码器的一个网络块中,由一个多头attention子层和一个前馈神经网络子层组成,整个编码器栈式搭建了N个块。类似于编码器,只是解码器的一个网络块中多了一个多头attention层。为了更好的优化深度网络,整个网络使用了残差连接和对层进行了规范化(Add&Norm)。

self-attention可以是一般attention的一种特殊情况,在self-attention中,Q=K=V每个序列中的单元和该序列中所有单元进行attention计算。Google提出的多头attention通过计算多次来捕获不同子空间上的相关信息。self-attention的特点在于无视词之间的距离直接计算依赖关系,能够学习一个句子的内部结构,实现也较为简单并行可以并行计算。从一些论文中看到,self-attention可以当成一个层和RNN,CNN,FNN等配合使用,成功应用于其他NLP任务。

05-11 18:27