星期六和星期天两天,本打算自己手敲一遍seq2seq,然后再写一篇博客。seq2seq是体验了,但是在各种报错中体验了一番,博客和实践代码没来得及做。不过,收获还是有的,因为在敲的时候,想弄懂每一步,所以查了不少API。虽然没有做到弄懂每个函数,但是整个流程以及对注意力机制的使用,算是很熟悉了。
seq2seq简单总结
seq2seq主要分成两个部分:Encoder和Decoder两部分。
而seq2seq的实现流程可分为:
- 数据预处理
- Encoder层
- Decoder层
- 训练
- 预测
数据预处理
这里主要是将字符(单词)编码成数字,所操作的过程就是先遍历所有字符,然后给每个字符分配一个对应的数字,生成一个letter_to_int和int_to_letter的映射关系。然后,将对应每句话就可以变成纯数字序列了。例如h
对应的是3,i
对应的是7,那么Hi
这句话编码就变成了[3, 7]。当然,我们对中文的处理有两种方式,可以像英文一样分成一个一个字来处理;也可以,使用分词工具将每句话分成一个一个词来进行处理,至于效果暂时还不知道哪个好。但是,看到过别人的实现,是直接分词的。分词有个好处,那就是每句话的长度变短了。
优达学城课程中,将get_batch放到了后面。其实,我觉得组合批量数据,也应该放在数据预处理部分,都是处理数据使用。
Encoder
Encoder主要做的事情有:
1、将输入的序列先进行Embedding,和word2vec一样,就是将每个字符转换成向量,此处若是有word2vec或golv的向量矩阵,可以直接拿已经训练过来的使用。
2、将Embeded之后的数据,放入到创建的RNN层。这个RNN层一般是使用LSTM或者GNU来实现。
Decoder
Decoder做的事情主要有:
1、先将targets数据进行Embedding,与Encoder不太一样的是,Decoder时需要这个Embedding矩阵,所以创建的方式是先创建一个tensorflow的dec_embeddings变量,然后使用lookup去查找。这个变量,在后面预测时是需要用到的。
2、构建Decoder的RNN层,使用的也是LSTM或GNU
3、构建一个全连接输出层,tensorflow已经帮我们封装好了,直接调用Dense来实现就行了
4、注意力机制在训练时,会关注输入的关键信息。所以,在实现时,需要先使用Encoder层的输出创建一个注意力机制,然后使用AttentionWrapper与Decoder层的RNN层封装起来。
5、创建一个Training时的Decoder,它使用主要是TrainingHelper、BasicDecoder、dynamic_decode来使用
6、创建一个Predictting时的Decoder,它与Training不同的是Helper,分别使用的是GreedyEmbeddingHelper、BasicDecoder、dynamic_decode
训练
这里感觉没有什么不可理解的,直接拿代码过来用就行了
预测
预测时主要先restore模型,然后拿取内部命名好的tensor使用,然后就可以获得结果。
其实,还有另外一种方法,和training一样,调用模型代码,然后传入输出,就可以得到对应的logits,就获得了结果。
总结与计划
总体上,对seq2seq流程了解很清楚了,也对大部分的api也知道使用了,但还有一些不足。那就是对GreedyEmbeddingHelper、BasicDecoder、dynamic_decode的内部机制不了解,特别是GreedyEmbeddingHelper很有必要知道。而且,预测结果,不仅仅这个Helper方法,还有beamsearch的方法。
计划:对seq2seq流程熟悉了,后面就是进行实践了。在后面可以跑一跑聊天机器人、生成小说(可以对比下与RNN直接粗暴实现的区别)。
网友评论