keras系列︱seq2seq系列相关实现与案例(feedback、peek、attention类型)

  • 时间:2017-07-18
  • 分类:数据库/系统
  • 1606 人浏览
[导读]之前在看《Semi-supervised Sequence Learning》这篇文章的时候对seq2seq半监督的方式做文本分类的方式产生了一定兴趣,于是开始简单研究了seq2seq。

之前在看《Semi-supervised Sequence Learning》这篇文章的时候对seq2seq半监督的方式做文本分类的方式产生了一定兴趣,于是开始简单研究了seq2seq。

先来简单说一下这篇paper的内容:
创立的新形式Sequence AutoEncoder LSTM(SA-LSTM),Pre-trained RNNs are more stable, generalize better, and achieve state-of-the-art results on various text classification tasks. The authors show that unlabeled data can compensate for a lack of labeled data(来源dennybritz/deeplearning-papernotes).
这里写图片描述

创新之处:

(1)第一种模型Sequence autoencoder(SA-LSTM):The objective is to reconstruct the input sequence itself,其中output序列就是Input序列,输出的结果作为下一个LSTM的初始值

(2)第二种模型称为Language Model LSTM(LM-LSTM),encoder部分去掉就是LM模型。

(3)jointly training模式.一般用LSTM中的最后一个hidden state作为输出,但本文也尝试用了每个hidden state权重递增的线性组合作为输出。
这两种思路都是将无监督和有监督分开训练,本文也提供了一种联合训练的思路作为对比,称为joint learning。

优势:

(1)unsupervised,不用标签

(2)large quantities of unlabeled data to improve its quality,不用标签之外,用大量无标注数据反而还可以增强模型的泛化能力

(3)相较于LSTM的随机初始化,可以fine-tuning过来别的整个部分的weight作为初始化权重


一、seq2seq几类常见架构

不累述seq2seq的原理,来看看《漫谈四种神经网络序列解码模型【附示例代码】》中总结的四类:

1、模式一:普通作弊 basic encoder-decoder

编码时RNN每个时刻除了自己上一时刻的隐层状态编码外,还有当前时刻的输入字符,而解码时则没有这种输入。那么,一种比较直接的方式是把编码端得到的编码向量做为解码模型的每时刻输入特征。如下图所示:
这里写图片描述
简单直观而且解码模型和编码模型并没有任何区别
.

2、模式二: 学霸模式 encoder-decoder with feedback

编码端则是对课本的理解所整理的课堂笔记。解码端的隐层神经网络则是我们的大脑,而每一时刻的输出则是考试时要写在卷子上的答案。在上面最简单的解码模型中,可以考虑成是考试时一边写答案一边翻看课堂笔记。如果这是一般作弊学生的做法,学霸则不需要翻书,他们有一个强大的大脑神经网络,可以记住自己的课堂笔记。解码时只需要回顾一下自己前面写过什么,然后依次认真的把答案写在答卷上,就是下面这种模型了:
这里写图片描述
.

3、模式三:学弱作弊 encoder-decoder with peek

很多学弱,他们不只需要作弊,而且翻看笔记的时候还需要回顾自己上一时刻写在答卷上的答案
这里写图片描述
.

4、模式四:学渣作弊 encoder-decoder with attention

然而学渣渣也是存在的,他们不只需要作弊,不只需要回顾自己上一时刻卸载答卷上的答案,还需要老师在课本上画出重点才能整理出自己的课题笔记(这就是一种注意力机制Attention,记笔记的时候一定要根据考题画出重点啊!)
这里写图片描述

5、结果对比

设定一些参数如下:
(‘Vocab size:’, 51, ‘unique words’)
(‘Input max length:’, 5, ‘words’)
(‘Target max length:’, 5, ‘words’)
(‘Dimension of hidden vectors:’, 20)
(‘Number of training stories:’, 5)
(‘Number of test stories:’, 5)
这里写图片描述
.

二、seq2seq的实现 1、四类seq2seq实现-encoder_decoder

上述文章 《漫谈四种神经网络序列解码模型【附示例代码】》中总结的四类的实现在作者的github之中,由于作者用keras0.3做的,笔者在实践过程中遇到很多坑,而且py2与py3之间都会有各自的问题,所以这边只贴其输入输出的数据:

输入数据: input_list

tar_list

训练输入数据【en_de_model.fit(inputs_train, tars_train, batch_size=3, nb_epoch=1, show_accuracy=True)】:

inputs_train:5*5

tars_train:5*5*51(51为单词个数 + 1)

来看一个完整的keras0.3版本的code:

其中遇到的报错:

.

2、keras实现farizrahman4u/seq2seq

本github里面用Keras做的seq2seq封装比较好,使用的方法有点类似上述的模式二

其中有5款seq2seq款式可以选择:

(1)A simple Seq2Seq model

(2)Deep Seq2Seq models

depth=3(效果为3 + 3 = 6)或者也可设置深度为(4, 5)

(3)Advanced Seq2Seq models

(4)Peeky Seq2seq model

the decoder gets a ‘peek’ at the context vector at every timestep.
打开peek=True,类似于上述的模式三
这里写图片描述

(5)AttentionSeq2Seq

类似于模式四,带注意力机制
这里写图片描述

来看一个案例:

其中遇到以下报错:

其中dropout设置不正确,加入dropout=0.3就可以执行

Encoder(即第一个 LSTM) 只在序列结束时输出一个语义向量,所以其 “return_sequences” 参数设置为 “False” Decoder(即第二个 LSTM) 需要在每一个 time step 都输出,所以其 “return_sequences” 参数设置为 “True” 使用 “RepeatVector” 将 Encoder 的输出(最后一个 time step)复制 N 份作为 Decoder 的 N 次输入 TimeDistributed 是为了保证 Dense 和 Decoder 之间的一致,可以不用太关心

之所以说是 “简单的 seq2seq 模型”,就在于第 3 点其实并不符合两篇论文的模型要求,不过要将 Decoder 的每一个时刻的输出作为下一个时刻的输入,会麻烦很多,所以这里对其进行简化,但用来处理 Pig Latin 这样的简单问题,这种简化问题是不大的。

另外,虽然 seq2seq 模型在理论上是能学习 “变长输入序列-变长输出序列” 的映射关系,但在实际训练中,Keras 的模型要求数据以 Numpy 的多维数组形式传入,这就要求训练数据中每一条数据的大小都必须是一样的。针对这个问题,现在的常规做法是设定一个最大长度,对于长度不足的输入以及输出序列,用特殊的符号进行填充,使所有输入序列的长度保持一致(所有输出序列长度也一致)。
.

三、tensorflow实现seq2seq的相关案例 1、seq2seq简单实现

相关github: https://github.com/ichuang/tflearn_seq2seq
来简单看看实现:
输入:0 1 2 3 4 5 6 7 8 9
输出:prediction=[8 8 5 3 6 5 4 2 3 1] (expected=[9 8 7 6 5 4 3 2 1 0])

2、自动标题生成案例

tensorflow实现的中文自动标题生成案例可见:https://github.com/rockingdingo/deepnlp/tree/master/deepnlp/textsum
textsum基于tensorflow (1.0.0) 实现的Seq2Seq-attention模型, 来解决中文新闻标题自动生成的任务。

Example:  
这里写图片描述

Output examples

来源:本文为线上采编,如涉及作品内容、版权和其它问题,请及时与本网联系,我们将在第一时间删除!