seq2seq 是一个Encoder–Decoder 结构的网络,它的输入是一个序列,输出也是一个序列。Encoder 中将一个可变长度的信号序列变为固定长度的向量表达,Decoder 将这个固定长度的向量变成可变长度的目标的信号序列。
很多自然语言处理任务,比如聊天机器人,机器翻译,自动文摘,智能问答等,传统的解决方案都是检索式(从候选集中选出答案),这对素材的完善程度要求很高。seq2seq模型突破了传统的固定大小输入问题框架。采用序列到序列的模型,在NLP中是文本到文本的映射。其在各主流语言之间的相互翻译以及语音助手中人机短问快答的应用中有着非常好的表现。
在NLP任务中,其实输入的是文本序列,输出的很多时候也是文本序列,下图所示的是一个典型的机器翻译任务中,输入的文本序列(源语言表述)到输出的文本序列(目标语言表述)之间的变换。
(1)编码器处理输入序列中的每个元素(在这里可能是1个词),将捕获的信息编译成向量(称为上下文内容向量)。在处理整个输入序列之后,编码器将上下文发送到解码器,解码器逐项开始产生输出序列。如,机器翻译任务
(2)上下文向量
提升效果,不会寄希望于把所有的内容都放到一个上下文向量(context vector)中,而是会采用一个叫做注意力模型的模型来动态处理和解码,动态的图如下所示。
所谓的注意力机制,可以粗略地理解为是一种对于输入的信息,根据重要程度进行不同权重的加权处理(通常加权的权重来源于softmax后的结果)的机制,如下图所示,是一个在解码阶段,简单地对编码器中的hidden states进行不同权重的加权处理的过程。
输入: x = ( x 1 , . . . , x T x ) x = (x_1,...,x_{T_x}) x=(x1,...,xTx)
输出: y = ( y 1 , . . . , y T y ) y = (y_1,...,y_{T_y}) y=(y1,...,yTy)
1、 h t = R N N e n c ( x t , h t − 1 ) h_t = RNN_{enc}(x_t, h_{t-1}) ht=RNNenc(xt,ht−1) , Encoder方面接受的是每一个单词word embedding,和上一个时间点的hidden state。输出的是这个时间点的hidden state。
2、 s t = R N N d e c ( y t − 1 ^ , s t − 1 ) s_t = RNN_{dec}(\hat{y_{t-1}},s_{t-1}) st=RNNdec(yt−1^,st−1) , Decoder方面接受的是目标句子里单词的word embedding,和上一个时间点的hidden state。
3、 c i = ∑ j = 1 T x α i j h j c_i = \sum_{j=1}^{T_x} \alpha_{ij}h_j ci=∑j=1Txαijhj , context vector是一个对于encoder输出的hidden states的一个加权平均。
4、 α i j = e x p ( e i j ) ∑ k = 1 T x e x p ( e i k ) \alpha_{ij} = \frac{exp(e_{ij})}{\sum_{k=1}^{T_x}exp(e_{ik})} αij=∑k=1Txexp(eik)exp(eij) , 每一个encoder的hidden states对应的权重。
5、 e i j = s c o r e ( s i , h j ) e_{ij} = score(s_i, h_j) eij=score(si,hj) , 通过decoder的hidden states加上encoder的hidden states来计算一个分数,用于计算权重(4)
6、 s t ^ = t a n h ( W c [ c t ; s t ] ) \hat{s_t} = tanh(W_c[c_t;s_t]) st^=tanh(Wc[ct;st]), 将context vector 和 decoder的hidden states 串起来。
7、 p ( y t ∣ y < t , x ) = s o f t m a x ( W s s t ^ ) p(y_t|y_{
(1) h t = R N N e n c ( x t , h t − 1 ) h_t = RNN_{enc}(x_t, h_{t-1}) ht=RNNenc(xt,ht−1) , Encoder方面接受的是每一个单词word embedding,和上一个时间点的hidden state。输出的是这个时间点的hidden state。
(2) s t = R N N d e c ( y t − 1 ^ , s t − 1 ) s_t = RNN_{dec}(\hat{y_{t-1}},s_{t-1}) st=RNNdec(yt−1^,st−1) , Decoder方面接受的是目标句子里单词的word embedding,和上一个时间点的hidden state。
(3) c i = ∑ j = 1 T x α i j h j c_i = \sum_{j=1}^{T_x} \alpha_{ij}h_j ci=∑j=1Txαijhj , context vector是一个对于encoder输出的hidden states的一个加权平均。
(4) α i j = e x p ( e i j ) ∑ k = 1 T x e x p ( e i k ) \alpha_{ij} = \frac{exp(e_{ij})}{\sum_{k=1}^{T_x}exp(e_{ik})} αij=∑k=1Txexp(eik)exp(eij) , 每一个encoder的hidden states对应的权重。
(5) e i j = s c o r e ( s i , h j ) e_{ij} = score(s_i, h_j) eij=score(si,hj) , 通过decoder的hidden states加上encoder的hidden states来计算一个分数,用于计算权重(4)
下一个时间点
(6) s t ^ = t a n h ( W c [ c t ; s t ] ) \hat{s_t} = tanh(W_c[c_t;s_t]) st^=tanh(Wc[ct;st]), 将context vector 和 decoder的hidden states 串起来。
(7) p ( y t ∣ y < t , x ) = s o f t m a x ( W s s t ^ ) p(y_t|y_{
在luong中提到了三种score的计算方法。这里图解前两种:
输入是encoder的所有hidden states H: 大小为(hid dim, sequence length)。decoder在一个时间点上的hidden state, s: 大小为(hid dim, 1)。
(1)旋转H为(sequence length, hid dim) 与s做点乘得到一个 大小为(sequence length, 1)的分数。
(2)对分数做softmax得到一个合为1的权重。
(3)将H与第二步得到的权重做点乘得到一个大小为(hid dim, 1)的context vector。
输入是encoder的所有hidden states H: 大小为(hid dim1, sequence length)。decoder在一个时间点上的hidden state, s: 大小为(hid dim2, 1)。此处两个hidden state的纬度并不一样。
(1)旋转H为(sequence length, hid dim1) 与 Wa [大小为 hid dim1, hid dim 2)] 做点乘, 再和s做点乘得到一个 大小为(sequence length, 1)的分数。
(2)对分数做softmax得到一个合为1的权重。
(3)将H与第二步得到的权重做点乘得到一个大小为(hid dim, 1)的context vector。
参考文献:本文为网易云课堂 NLP课程学习笔记。