目录
声明
文中出现的代码有些是部分的、表意用的,不能直接搬用,一个是直接上完整代码篇幅就太长了,另一个是我本人希望用“授人以渔”态度写文章。有不足的地方还请各位指正!
模型
项目是基于Seq2Seq模型实现的,基本结构如下图:
值得注意的是,实际上我是把源语言句子整句一次性输入编码器,但是解码器却是如图按时间步挨个预测的。这里体现了一个训练策略:Teachrer Forcing,在解码器中,把上一个时间步的正确结果作为当前时间步的输入得到当前时间步的预测输出。使用图中的例子,可以理解为教给解码器当前时刻的输入是“bos”,期望它预测出“I”,教给它“I”,期望它预测出“am”,目标就是最大化条件概率P(I|bos)、P(am|I)、P(author|I)…的乘积。当然本文偏于应用,严谨的数学推理什么的我做不来,哈哈。
实际应用中,除了编码器和解码器,还使用了注意力机制。其中编码器的简单结构如图:
解码器的简单结构如图:
注意力机制有多种,可以简单表达为:
a t t e n t i o n = v ( t a n h ( W 1 s + W 2 h ) s c o r e = s o f t m a x ( a t t e n t i o n ) c o n t e x t = s c o r e × e n c o d e r o u t attention = v ( tanh ( W_1 s + W_2 h)\\ score = softmax(attention)\\ context = score \times encoder_{out} attention=v(tanh(W1s+W2h)score=softmax(attention)context=score×encoderout
模型中的LSTM可以使用其他循环神经网络单元如GRU替换,这个读者自行选择。因为数据处理部分中,使用0填充短句但0又不作为词汇表中的词,因此需要忽略。TensorFlow已经实现,只需在嵌入层设置参数mask_zero
为True
且嵌入层必须在网络的第一层。代码如下:
class Encoder