character-RNN模型介绍以及代码解析
2016-10-10 11:34
183 查看
RNN是一个很有意思的模型。早在20年前就有学者发现了它强大的时序记忆能力,另外学术界以证实RNN模型属于Turning-Complete,即理论上可以模拟任何函数。但实际运作上,一开始由于vanishing and exploiting gradient问题导致BPTT算法学习不了长期记忆。虽然之后有了LSTM(长短记忆)模型对普通RNN模型的修改,但是训练上还是公认的比较困难。在Tensorflow框架里,之前的两篇博客已经就官方给出的PTB和Machine Translation模型进行了讲解,现在我们来看一看传说中的机器写诗的模型。原模型出自安德烈.卡帕西大神的char-rnn项目,意在显示RNN强大的能力以及并非那么困难的训练方法。对这个方面有兴趣的朋友请点击这里查看详情。原作的框架为Torch,点击这里查看原作代码。中山大学的zhangzibin以卡帕西大神的代码为样本制作了一款基于卡帕西RNN模型以及Samy
Bengio(Bengio大神的亲弟弟)提出的Schedule Sampling算法的可运行中文的RNN模型,源代码请点击这里查看。作为Tensorflow的玩家,我本人当然很想了解下这个框架的运行情况,特别是在Tensorflow框架里的运行情况。好在有人已经捷足先登,将代码移植完毕了。今天我们就来看看这个神奇框架在Tensorflow下的代码。对该项目感兴趣的朋友可以在这里下载到项目的源码并在自己的机器上运行。
既然有了Tensorflow版本的代码了,那么我们开始解剖这段代码吧!
在解剖代码之前,让我们先对代码的运行做一个了解。在运行时,我们需要做的是cd到项目里后,先运行train.py文件来训练代码。默认的迭代数是50个迭代,默认的训练文件是tinyshakespear目录里的input.txt文件,也就是莎士比亚的一些作品。由于默认都是设定好的,我们不需要做任何更改,直接运行python train.py就好了。训练速度还是比较客观的,大约需要运行一个小时(没算具体时间),我们会发现训练完成,参数已经保存。之后,如果我们想看看运行的结果如何,打入python sample.py后,就会随机产生一段文字,该段文字是由机器学习了训练文本后自行计算的。之后我会放上机器在学习了郭敬明的幻成和小时代后自己写出的句子供大家参考。
在了解了运行方式后,既然入口文件是train.py,那么我们就先来看看该文件的设计。不出所料,train.py文件的开始为一系列的parser.add_argument。在之前的代码里我们已经多次见到,无非是加入了运行系统所需的参数,他们的默认值以及参数的解释。从这里我们发现默认的RNN框架为lstm,2层RNN结构,每层有128个神经元节点。另外,我们的sequence length定义为50,也就是每一次可以执行50个时间序列。之后便是train函数。如同往常,我们发现textloader函数为录入训练集的函数,这个函数存在于utils.py文件里。该文件很容易理解,在读入数据后通过collections.Counter收集文本中不一样的character,并将他们写入vocab_file文件做保存,已备后用。之后,根据总数据大小,minibatch大小以及时序长短来界定运行完整个文件需要多少个minibatches,并将文本分类成minibatch的训练以及目标batches。由于这个模型的目的是学习一个character后下一个character的概率,训练集跟目标函数间的差异为一个character,即在训练句子My
name is Edward时,假设训练集为: My name is Edwar, 相对应的目标集为y name is Edward。 从逻辑角度上说,不管是这个util.py文件还是之前博客里的CBOW模型,他们的核心逻辑都是相似的,只是在处理上由于目标不同而产生出工程上的差异。有兴趣的朋友可以对比这个util.py文件里的逻辑和CBOW模型里读入输入的函数做对比。
之后,train.py文件对需要的目录以及文件进行确认后就是建立模型了。通过model = Model(args),我们建立了这个RNN所需要的模型。那么模型是如何建立的呢?让我们仔细来看看model.py文件。这个model.py文件里存在两个函数:init函数以及sample函数。他们分别被用来训练模型以及测试模型。让我们首先来看看模型的训练:
由上述代码可见,在制作RNN的模型里,不可或缺的步骤如下:
在了解了模型后,我们发现剩下的代码都是比较常见的,例如initialize_all_variables, 以及运用learning rate decay的方式训练模型。由此,train.py文件的训练过程我们已经做了一个大概的了解了。那么,系统又是如何让我们可以测试训练好的模型呢?让我们来看看sample.py文件。通过parser.add_arugment函数,我们发现文件会选取我们保存模型的地点,并会产生500字符的sample,至于sample选项,我们发现设定为0是得到最多的timestep,1是每一个timestep,
2是sample on spaces。之后,我们读取存储的模型内容后将内容传递进Model函数,并将infer设为True。在output的时候,我们运用sample函数来的到输出。在这个函数里,我们发现一般的prime开头是‘The’,这里我们可以通过sample.py里的prime函数来指定一个开头。在之后,我们发现那个sample参数设为0时选取的是argmax,1时是weighted_pick,2时以space为标准,如果有space则选择weighted_pick, 不然就是argmax。好了,实际运行的效果如何呢?让我们来几个例子看看。
这里是the为开始,我们看到了一开始有点乱码。之后,我们看到可是我知道了,他们三个女生等短句都是通顺的,同时,也有一些及其不通的,例如底忘记新地把满些了,这句话什么含义完全不清楚。再看下一个例子,如果以我开头会怎么样呢?
如果把sample设为0又会如何呢?
这里篇幅紧凑多了。再次运行,我们得到了相同的结果,因为是argmax么,所以在没改变的情况下我们会得到相同的结果。
这个运行结果还是很有意思的,有兴趣的朋友可以自行下载项目然后试着去操作一下!
Bengio(Bengio大神的亲弟弟)提出的Schedule Sampling算法的可运行中文的RNN模型,源代码请点击这里查看。作为Tensorflow的玩家,我本人当然很想了解下这个框架的运行情况,特别是在Tensorflow框架里的运行情况。好在有人已经捷足先登,将代码移植完毕了。今天我们就来看看这个神奇框架在Tensorflow下的代码。对该项目感兴趣的朋友可以在这里下载到项目的源码并在自己的机器上运行。
既然有了Tensorflow版本的代码了,那么我们开始解剖这段代码吧!
在解剖代码之前,让我们先对代码的运行做一个了解。在运行时,我们需要做的是cd到项目里后,先运行train.py文件来训练代码。默认的迭代数是50个迭代,默认的训练文件是tinyshakespear目录里的input.txt文件,也就是莎士比亚的一些作品。由于默认都是设定好的,我们不需要做任何更改,直接运行python train.py就好了。训练速度还是比较客观的,大约需要运行一个小时(没算具体时间),我们会发现训练完成,参数已经保存。之后,如果我们想看看运行的结果如何,打入python sample.py后,就会随机产生一段文字,该段文字是由机器学习了训练文本后自行计算的。之后我会放上机器在学习了郭敬明的幻成和小时代后自己写出的句子供大家参考。
在了解了运行方式后,既然入口文件是train.py,那么我们就先来看看该文件的设计。不出所料,train.py文件的开始为一系列的parser.add_argument。在之前的代码里我们已经多次见到,无非是加入了运行系统所需的参数,他们的默认值以及参数的解释。从这里我们发现默认的RNN框架为lstm,2层RNN结构,每层有128个神经元节点。另外,我们的sequence length定义为50,也就是每一次可以执行50个时间序列。之后便是train函数。如同往常,我们发现textloader函数为录入训练集的函数,这个函数存在于utils.py文件里。该文件很容易理解,在读入数据后通过collections.Counter收集文本中不一样的character,并将他们写入vocab_file文件做保存,已备后用。之后,根据总数据大小,minibatch大小以及时序长短来界定运行完整个文件需要多少个minibatches,并将文本分类成minibatch的训练以及目标batches。由于这个模型的目的是学习一个character后下一个character的概率,训练集跟目标函数间的差异为一个character,即在训练句子My
name is Edward时,假设训练集为: My name is Edwar, 相对应的目标集为y name is Edward。 从逻辑角度上说,不管是这个util.py文件还是之前博客里的CBOW模型,他们的核心逻辑都是相似的,只是在处理上由于目标不同而产生出工程上的差异。有兴趣的朋友可以对比这个util.py文件里的逻辑和CBOW模型里读入输入的函数做对比。
之后,train.py文件对需要的目录以及文件进行确认后就是建立模型了。通过model = Model(args),我们建立了这个RNN所需要的模型。那么模型是如何建立的呢?让我们仔细来看看model.py文件。这个model.py文件里存在两个函数:init函数以及sample函数。他们分别被用来训练模型以及测试模型。让我们首先来看看模型的训练:
2是sample on spaces。之后,我们读取存储的模型内容后将内容传递进Model函数,并将infer设为True。在output的时候,我们运用sample函数来的到输出。在这个函数里,我们发现一般的prime开头是‘The’,这里我们可以通过sample.py里的prime函数来指定一个开头。在之后,我们发现那个sample参数设为0时选取的是argmax,1时是weighted_pick,2时以space为标准,如果有space则选择weighted_pick, 不然就是argmax。好了,实际运行的效果如何呢?让我们来几个例子看看。
这里是the为开始,我们看到了一开始有点乱码。之后,我们看到可是我知道了,他们三个女生等短句都是通顺的,同时,也有一些及其不通的,例如底忘记新地把满些了,这句话什么含义完全不清楚。再看下一个例子,如果以我开头会怎么样呢?
如果把sample设为0又会如何呢?
这里篇幅紧凑多了。再次运行,我们得到了相同的结果,因为是argmax么,所以在没改变的情况下我们会得到相同的结果。
这个运行结果还是很有意思的,有兴趣的朋友可以自行下载项目然后试着去操作一下!
相关文章推荐
- character-RNN模型介绍以及代码解析
- PCL学习笔记(2):点云视窗类CloudViewer的介绍以及PCL程序:代码解析
- JS中封装解析xml的代码,以及实例应用
- OpenGL实现3D模型自由旋转——之代码解析
- TicToc 模型 代码解析
- 随便聊聊 SOA & SOAP & WebService 的一些东西,以及客户端开发的代码逻辑解析
- JVM内存模型以及垃圾收集策略解析(重要)
- 用代码来设置故障还原模型‘简单’以及‘收缩数据库
- 按Sybase的PowerDesigner工具设计的数据库模型 ---> 解析生成能兼容多种数据库的相应的C#底层代码
- JVM内存模型以及垃圾收集策略解析
- 按Sybase的PowerDesigner工具设计的数据库模型 ---> 解析生成能兼容多种数据库的相应的C#底层代码
- CharacterEncodingFilter.java以及修改web.xml所用代码
- OpenGL实现3D模型自由旋转——之代码解析
- 如何加快C++代码的编译速度-以及stdafx.h解析
- JVM内存模型以及垃圾收集策略解析【续】
- TicToc 模型 代码解析
- 续实例解析SOCKET编程模型之异步通信篇(上) 代码
- JVM内存模型以及垃圾收集策略解析
- 使用python的列表解析以及函数式计算来简化代码
- [emacs] Python代码补全的各种方法介绍以及对比