Seq2Seq其实就是Encoder-Decoder结构的网络,它的输入是一个序列,输出也是一个序列。在Encoder中,将序列转换成一个固定长度的向量,然后通过Decoder将该向量转换成我们想要的序列输出出来。
-
Encoder和Decoder一般都是RNN,通常为LSTM或者GRU。
- 在Encoder中,“欢迎/来/北京”这些词转换成词向量,也就是Embedding,我们用
v
i
v_i
vi来表示,与上一时刻的隐状态
h
i
−
1
h_{i-1}
hi−1按照时间顺序进行输入,每一个时刻输出一个隐状态
h
i
h_i
hi ,我们可以用函数
f
f
f表达RNN隐藏层的变换:
h
i
=
f
(
v
i
,
h
i
−
1
)
h_i=f(v_i,h_{i-1})
hi=f(vi,hi−1)。
假设有t个词,最终通过Encoder自定义函数将q各时刻的隐状态变换为向量c: c = q ( h 0 , . . . , h t ) c=q(h_0,...,h_t) c=q(h0,...,ht),这个c就相当于从“欢迎/来/北京”这几个单词中提炼出来的大概意思一样,包含了这句话的含义。 - Decoder的每一时刻的输入为Encoder的输出c和Decoder前一时刻解码的输出
s
i
−
1
s_{i-1}
si−1,还有前一时刻预测的词的向量
E
i
−
1
E_{i-1}
Ei−1,(如果是预测第一个词的话,此时输入的词向量为“_GO”的词向量,标志着解码的开始)我们可以用函数g表达解码器隐藏层变换:
s i = g ( c , s i − 1 , E i − 1 ) s_i = g(c,s_{i-1},E_{i-1}) si=g(c,si−1,Ei−1)。直到解码出“_EOS”,标志着解码的结束。
- 在Encoder中,“欢迎/来/北京”这些词转换成词向量,也就是Embedding,我们用
v
i
v_i
vi来表示,与上一时刻的隐状态
h
i
−
1
h_{i-1}
hi−1按照时间顺序进行输入,每一个时刻输出一个隐状态
h
i
h_i
hi ,我们可以用函数
f
f
f表达RNN隐藏层的变换:
h
i
=
f
(
v
i
,
h
i
−
1
)
h_i=f(v_i,h_{i-1})
hi=f(vi,hi−1)。
-
在基础的模型中,Decoder的每一次解码又会作为下一次解码的输入,这样就会导致一个问题就是错误累计,如果其中一个RNN单元解码出现误差了,那么这个误差就会传递到下一个RNN单元,使训练结果误差越来越大。