您的位置:首页 > 编程语言

oxford-cs-ml-2015/practical6 代码解读(LSTMs for language modelling)

2016-09-23 21:04 387 查看
查看具体项目文件请点击这里

1. train.lua



require(modelname)


require 用于加载不同的模块,torch、nn、nngraph、optim都为框架本身的模块,而’data.CharLMMinibatchLoader’、’LSTM’ 、’Embedding’、’model_utils’则为自定义模块。

其中data.表示在data目录下的CharLMMinibatchLoader文件。



local cmd = torch.CmdLine()  -- 新建一个CmdLine类的对象


查看CmdLine.lua的源码

cmd:text(txt)


函数源码如下,可以发现发现函数实际上是向table self.helpline中插入txt



cmd:option(key, default, help)


函数源码如下,此时未使用参数 _ type_, 实际上option是保存在table self.options[key] 中的,并且向table self.helpline中也插入了option的选项。





函数形式为parse(arg) ,功能是解析一个给定的table ,arg是lua直接使用的命令行参数。

函数源码如下,命令行中输入的要么是option,要么是option的参数值,所以对于不同类别的命令行参数,分别执行不同的读取操作,最终得到了一个参数的table。需要注意的是,这里输入,-help,-h,–help 会有torch提供的help函数,从而显示出所有的选项和选项介绍(都存储在 self.helpline中)。





torch.manualSeed(opt.seed)


函数形式为 manualSeed([gen,] number),功能是

设置随机数生成器的种子为给定的number。

opt.savefile = cmd:string(opt.savefile, opt,
{save_every=true, print_every=true, savefile=true, vocabfile=true, datafile=true})
.. '.t7'


函数形式为[string] string(prefix, params, ignore),prefix为字符串前缀,此处默认为model_autosave(可通过属性修改),params为参数table,ignore是形式为{dir = true}的table,里面包含了参数中忽略的选项,此处是忽略save_every、print_every、savefile、vocabfile以及datafile选项,整个函数返回的就是一个字符串,‘..’ 是用于字符串相连的运算符,默认文件名为”model_autosave.t7”(不加引号)。

比如,在命令行输入:

th train.lua -vocabfile vocab.t7 -datafile train.t7

文件名为”model_autosave.t7”

修改seed选项

th train.lua -vocabfile vocab.t7 -datafile train.t7 -seed 456

文件名为”model_autosave,seed=456.t7”(不加引号)。

修改print_every选项

th train.lua -vocabfile vocab.t7 -datafile train.t7 -print_every 15

文件名依然为”model_autosave.t7”,因为print_every选项是忽略的。



local loader = CharLMMinibatchLoader.create(
opt.datafile, opt.vocabfile, opt.batch_size, opt.seq_length)


新建一个CharLMMinibatchLoader类的对象,这里的类是自定义的,后面再详细讲。这里的loader也只是起到读取数据的作用。

vocab_size是指数据文件中出现的字符种类的数量。

比如ABCDE,这里就有A,B,C,D,E 五个不同的字符,vocab_size 就是5.



protos 变量用于存储模型原型,Embedding 是Module的子类,protos.embed为一个Embedding对象。

protos.lstm为一个gModule 对象。

protos.Sequential 为一个Module 对象。

2.Embedding.lua

Embedding
Module
的子类.



初始化函数



新建
Embedding
对象时,会调用这个函数,同时调用了
Module
的初始化函数:



所以一个
Embedding
对象,应该是具备了gradInput,output,_type, outputSize,weight,gradWeight这几个属性的。

gradInput:Tensor

output:Tensor

_type: 与output的type一致

outputSize:与参数outputSize一致

weight: Tensor , inputSize × outputSize

gradWeight: Tensor , inputSize × outputSize

updateOutput 函数:(在forward()的时候被调用)



self.output:resize(input:size(1),self.outputSize)


重新设置output的size,为input的第一维长度×outputSize

for i = 1, input:size(1) do
self.output[i]:copy(self.weight[input[i]])
end


如果input是一维张量,那么input[i]就是第i个值。

相当于把weight张量的第1维第input[i]个的所有值复制到output的第1维第i个中。

换成矩阵来讲,就是把weight矩阵的第input[i]行复制到output的第i行中。

updateGradInput函数:(在backward()的时候被调用)



重新设置gradInput的size,与input的size相同。

accGradParameters函数:(在backward()的时候被调用)



这里是对gradOutput 的一个累计。

scale = 0 时,gradWeight 清 0 。

3.LSTM.lua

输入



Identity
类 是
Module
类的子类。 它本身没有init()函数,所以会调用
Module
类的__init()函数。 nn.Identity() 新建一个nn.Identity()对象,nn.Identity() 会调用元表中的__call
() 函数。

nn.Module 中的函数如下:这里



但是在LSTM.lua 的文件之前的train.lua 中引用了

require 'nngraph'


并且在nngraph中override 了call函数



所以这里的nn.Identity()() 实际上是nngraph.Node({module=self}) ,这里的self 指向的是当前的nn.Identity() 实例。

输入求和函数



由nn.Linear的构建函数可知,



输入







未完待续 _ (:зゝ∠)_

9.24 更新
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: