Seq2Seq
在RNN模型需要解决的问题中,有一类N v M的问题,即输入输出不等长问题。例如Machine Translation、Summarization就是这类问题的一些经典粒例子。这种结构又叫做Seq2Seq模型,或者叫Encoder-Decoder模型。
Intuition
我们以机器翻译问题为例,对于机器翻译问题,我们的任务是将一种语言的一句话翻译成另一种语言的一句话。那么显而易见的是,这就涉及到NLU(文本理解)和NLG(文本生成)任务。
Seq2Seq中的NLU
首先,我们需要使用一种语言模型对源文本进行理解,或者说是特征的提取。而RNN模型可以很好的完成这一任务
模型最后的隐状态 h n h_n hn就可以当作我们对整个句子理解后的信息。
Seq2Seq中的NLG
理解完源文本的信息后,我们要生成目标语言的文本。对于语言模型来说,一旦训练好之后,就可以使用它来做文本的生成。因此,我们也可以使用RNN模型来做Seq2Seq中的文本生成任务。
根据以上的分析,我们不难得到一个Encode-Decoder模型:Encoder是一个用于文本理解的RNN模型,Decoder是一个用于文本生成的RNN模型。
模型结构
Encoder
Encoder可以直接用一个RNN网络,它的主要任务是把输入数据编码成一个上下文向量 c c c,可以直接用RNN的输出或最后一个隐状态向量 h t h_{t} ht来得到 c c c
Decoder
Decoder也是一个RNN网络,它的主要任务是解码,即拿到Encoder得到的 c c c作为其初始隐状态向量 h 0 h_{0} h0(或者是每一时间步的隐状态输入),然后得到翻译的结果
在解码过程中,获得预测单词y的方法有以下几种:
Greedy Search
根据字面意思,就是经过 s o f t m a x softmax softmax之后取 a r g m a x argmax argmax,这种方式是最简单的,但也存在着问题:局部最优不一定是全局最优
暴力搜索
这只是一种理论上的方法,但它的复杂度是 O ( ∣ V ∣ m ) O(|V|^m) O(∣V∣m),V是词库大小,显然是不可行的
Beam Search
Beam Search是一种可以认为是结合了Greedy Search和暴力搜索的方法,即每次取概率最大的前k个,k也叫做我们的Beam Size,这样选取的最后结果是一棵树,我们只需要选取路径得分最大的即可。但是这种算法的复杂度也是指数级别的。
Attention机制
到这里,我们首先来分析一下原始Seq2Seq模型存在的问题:
- 由于encoder和decoder仍然使用的是RNN系列模型,所以不可避免地会出现gradient vanishing问题(注意,即便是LSTM也只是缓解了这一问题),因此不能很好地处理长期依赖问题
- encoder得到的向量 c c c是一个瓶颈,整句话用一个向量来表示不能得到很好的结果
为了解决原始Encoder-Decoder模型存在的问题,Attetion注意力机制被引入。先从字面上感性理解,Attention机制做的事情就是把模型的"注意力"集中到真正对Decode有用的部分上去。例如翻译"机器学习",当我们在解码出"machine"这个词的时候,显然是"机器"这两个字对我们有用,而"学习"对我们用处不大,因此我们希望模型能把注意力集中在"机器"这个词上。
接下来,我们重点介绍attention机制在Seq2Seq模型中的应用:
Encoder
encoder没有什么变化,仍然是一个RNN或LSTM模型,用于提取文本特征。
Decoder
decoder部分是我们attention mechanism的主战场。就如我们之前所说,在翻译某一个单词的时候,只有源文本的部分内容对我们有价值。因此,我们引入注意力向量 α \alpha α。
首先,我们利用encoder最后时刻的隐状态
h
m
e
n
c
h^{enc}_m
hmenc(可以加上cell state
c
m
e
n
c
c^{enc}_m
cmenc)作为decoder的初始状态
h
0
d
e
c
h^{dec}_0
h0dec。然后对于每个时刻
i
i
i,我们把reference translation中当前时刻单词的embedding
x
i
x_i
xi与上一时刻Decoder得到的单词
o
i
−
1
o_{i-1}
oi−1 concat起来得到
x
^
\hat {x}
x^。最后用LSTM得到当前时刻的隐状态:
h
i
d
e
c
,
c
i
e
n
c
=
D
e
c
o
d
e
r
(
x
^
,
h
i
−
1
d
e
c
,
c
i
−
1
d
e
c
)
h^{dec}_{i},c^{enc}_{i}\ =\ Decoder(\hat{x},h^{dec}_{i-1},c^{dec}_{i-1})
hidec,cienc = Decoder(x^,hi−1dec,ci−1dec)
我们令
α
i
j
\alpha_{ij}
αij表示第
i
i
i时刻Decoder的隐状态
h
i
d
e
c
h^{dec}_i
hidec和第Encoder中第
j
j
j个隐状态
h
j
e
n
c
h^{enc}_j
hjenc之间的相关性,或者说是一个权重。
α
i
j
\alpha_{ij}
αij的计算方式有以下三种:
1
、
(
h
j
e
n
c
)
T
h
i
d
e
c
(
d
o
t
)
1、(h^{enc}_{j})^{T}h^{dec}_i \ \ \ \ \ \ \ \ \ (dot)
1、(hjenc)Thidec (dot)
2 、 ( h j e n c ) T W α h i d e c ( m u l t i p l i c a t i v e ) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 2、(h^{enc}_j)^TW_{\alpha}h^{dec}_i\ \ \ \ \ \ \ \ \ \ (multiplicative) 2、(hjenc)TWαhidec (multiplicative)
3 、 v α T t a n h ( W 1 h j e n c + W 2 h i d e c ) ( a d d i t i v e ) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 3、v_{\alpha}^Ttanh(W_1h^{enc}_j + W_2h^{dec}_i)\ \ \ \ \ \ \ \ \ \ \ \ (additive) 3、vαTtanh(W1hjenc+W2hidec) (additive)
得到每一个
α
i
j
\alpha_{ij}
αij后,由于我们定义的
α
\alpha
α表示的是对不同
h
j
h_j
hj的权重,因此要用
s
o
f
t
m
a
x
softmax
softmax做一个归一化。
得到最终的
α
\alpha
α后,我们利用
α
\alpha
α计算Decoder第
i
i
i时刻Encoder隐状态的加权平均,即
z
i
=
∑
j
=
1
n
α
i
j
h
j
z_i = \sum_{j=1}^{n}\alpha_{ij}h_j
zi=j=1∑nαijhj
接着,我们把
z
i
z_i
zi和当前Decoder的隐状态
g
i
g_{i}
gi进行concat得到
u
i
u_i
ui,然后利用
u
i
u_i
ui去得到
i
i
i时刻预测的单词
o
i
o_i
oi。
接下来每一时刻都重复上述步骤。
在pytorch tutorial中找到了一张结构非常清晰的图,很好的解释了这种方式下Decoder模型的结构