本文来自CSDN博客,转载请注明出处:http://blog.csdn.net/a635661820/article/details/44748583
参考文献:RNNLM - Recurrent Neural Network Language Modeling Toolkit(点此打开)
参考文献:STATISTICAL LANGUAGE MODELS BASED ON NEURAL NETWORKS(点此打开)
由Mikolov用rnn对语言进行建模所获得的效果已经超过传统的N-GRAM了,具体的实验结果在他的系列论文中都有解释,不过现在可以看看 他的PHD论文(点此打开),里面有各种对比实验。随即之后,他将rnnlm toolkit开源,可供其他人作为一个baseline,点此进入rnnlm toolkit的下载地址
这一篇文章是简要介绍rnnlm tookit的使用的,下面的内容我会把下载好的开源包里面的example.sh的shell脚本命令分开执行,并且详细说明每条命令所带参数的含义,更高级的用处在下载地址那个网页里面有专门的例子。由于可供选择的命令参数确实很多,不会全部都写,更详细的可以看一看相关文档,以及源代码。本文旨在把rnnlm最基本的功能介绍清楚,好了,下面是正文,初次写博客不久,如果有哪里错误的地方,还请大家多多指正哈。
1.编译
我的软件包版本是0.4b的,首先在在终端中进入到rnnlm-0.4b的目录(我的版本是0.4b的),然后编译,执行下面的命令:
make
有可能会出现如下错误:
make: x86_64-linux-g++-4.6: Command not found
make: *** [rnnlmlib.o] Error 127
这个时候可以将makefile文件的内容改一下:
CC = x86_64-linux-g++-4.6
更改为==>
CC = g++
重新执行即可,这里的错误处理参考了(http://blog.csdn.net/wangxinginnlp/article/details/17754173 )
2.用rnnlm训练模型
我们先将训练数据放上来,内容大概如下:
也就是train文件里面的训练数据都是一个一个的句子,注意无论是训练数据还是测试数据,或是验证数据最后一行都最好换行。然后执行下列命令:
./rnnlm -train train -valid valid -rnnlm model -hidden 15 -rand-seed 1 -debug 2 -class 100 -bptt 4 -bptt-block 10 -direct-order 3 -direct 2 -binary
现在我们来解释一下各项命令的具体含义:
-train train:
这个命令是指定训练文件的名字,注意文件名不能超过100个字符
-valid valid:
这个命令是指定验证数据的名字,也是不能超过100个字符,这个文件的作用是用来early stopping的,诶,抱歉,我不太知道如何翻译这个词,就是当你的训练文件训练一遍完毕时,会马上将训练后的模型在valid文件上面试一下,看一下效果如何,如果这一遍训练的效果还不错的话,那么继续同样打学习率来训练train这个文件,如果效果没太多打提升,就将学习率降低为一半,继续学习,直到没太大的提升就不再训练了。至于这个效果怎么看,是指训练打模型在valid上面的困惑度。这个valid文件作用可以防止过拟合,因为我们是一边训练一边看效果的嘛。
-rnnlm model
这个命令是指定训练好后的语言模型的参数所存放打文件,也就是这个文件里面存放了一大堆浮点数和一些基本可读信息
-hidden 15
这个命令是用来指定网络隐层神经元的个数的,这里为15,也就是隐层神经元的大小是15。hidden所指定的数大的话网络可容纳的信息就多,但运算量也会增大。
-rand-seed 1
这个是指定随机种子,用来初始化网络的权值的,比如指定为1,那么内部会执行srand(1),网络的权值会初始化为一堆随机小数,如果你指定为2,那么网络会被初始化为另一堆不同于值为1的随机小数。
-debug 2
这个是一个控制开关,控制训练网络所输出的信息,默认为1,训练时会输出一些基本的信息,如果为debug > 2则会输出更详细的信息
-class 100
这个是指定单词的分类,100表示将训练文件中的词语分为100类,这个作用是用来加速网络计算的,但会丧失一些准确性,论文中指出,一般可以取值为sqrt(|V|),其中|V|是训练数据中不重复的单词数量
-bptt 4
这个命令参数如果为1,表示网络的一个常规的BPTT算法,即隐层只会往到前一个状态层,这么说比较抽象,见我的另一篇文章,介绍BPTT的。如果该参数值大于1,那么算法会学习向前到bptt+bptt_block-2那个时刻的状态
-bptt-block 10
这个参数是来控制BPTT学习算法的,表示每学习10个词,就进行一次BPTT算法。如果不控制的话,每训练一个词语时,都进行深度的学习,会使训练一个词语的时间比较长
-direct-order 3
这个参数是指定rnn中me(最大熵模型)部分特征的阶数。最大是不会超过20的,超过20也会自动指定为20
-direct 2
这个参数的含义就比较技术细节了,它来指定网络输入层到输出层所存放权值的一维数组的大小,并且单位是一百万,比如现在指定的值为2,其内部大小是2000000。
-binary
这个参数如果没有,则默认为text方式,区别在于binary是用二进制方式存储数据,text是以ascii方式,对于大量的浮点数来说,binary能更省文件大小,但是缺点是用文件打开,里面都是乱码。
下面是命令的执行结果:
debug mode: 2 train file: train valid file: valid class size: 100 Hidden layer size: 15 Direct connections: 2M Order of direct connections: 3 BPTT: 4 BPTT block: 10 Rand seed: 1 Model will be saved in binary format rnnlm file: model Starting training using file train Restoring network from file to continue training... Iter: 9 Alpha: 0.006250 TRAIN entropy: 8.9646 Progress: 12.29% W Iter: 9 53238.Alpha: 0.006250 TRAIN entropy: 6.8535 Progress: 24.59% W Iter: 9 60260.Alpha: 0.006250 TRAIN entropy: 6.1981 Progress: 36.88% W ter: 9 63232.Alpha: 0.006250 TRAIN entropy: 5.8457 Progress: 49.17% W Iter: 9 65056.Alpha: 0.006250 TRAIN entropy: 5.6123 Progress: 61.46% W Iter: 9 66436.Alpha: 0.006250 TRAIN entropy: 5.4747 Progress: 73.76% W Iter: 9 67084.Alpha: 0.006250 TRAIN entropy: 5.3561 Progress: 86.05% W Iter: 9 67802.Alpha: 0.006250 TRAIN entropy: 5.2776 Progress: 98.34% W Iter: 9 68190.Alpha: 0.006250 TRAIN entropy: 5.2688 Words/sec: 68239.9 VALID entropy: 6.1285 real 0m1.509s user 0m1.420s sys 0m0.064s |
看一下输出信息里面关键字的含义:
Iter
:所指的数字是对训练数据的第几次训练
Alpha:所指的数字是网络此刻的学习率
TRAIN entropy:所指的是熵,这个是在验证数据上的
Progress:表示在此刻处理的词语在训练数据中的位置的,也即进度
Words/sec:表示每秒训练的词语数
3.用srilm训练模型
执行如下命令:
ngram-count -text train -order 5 -lm templm -kndiscount -interpolate -gt3min 1 -gt4min 1
ngram -lm templm -order 5 -ppl test -debug 2 > temp.ppl
第一条命令就是用srlim建立了一个语言模型,第二条命令是用上面训练好的模型来测试,并且相关信息存放到temp.ppl,关于这个不细写啦,因为这完全是另一个工具的使用啦,可以看看我的另一篇博客,srilm的使用记录。
4.将temp.ppl转格式
命令如下:
gcc convert.c -O2 -o convert
./convert <temp.ppl >srilm.txt
这个命令是将上面生成的temp.ppl转成rnnlm能读取的数据格式。
5.插值两个模型并测试
命令如下:
./rnnlm -rnnlm model -test test -lm-prob srilm.txt -lambda 0.5
我们看一下各个参数的含义:
-rnnlm model
这个是指定训练好的模型文件,文件名不能超过100字符
-test test
这个命令是指测试文件,文件名不能超过100字符
-lm-prob srilm.txt
指明要使用其他的语言模型,并且文件所在为srilm.txt
-lambda 0.5
这个是指两个模型的插值系数,目前为0.5就表明,两个模型各占一半
我们看一下执行的结果:
rnnlm file: model test log probability: -15398.941513 test log probability given by other lm: -15498.214844 test log probability 0.500000*rnn + 0.500000*other_lm: -15218.938477 PPL net: 72.331327 PPL other: 74.355495 PPL combine: 68.800594 |
test log probability 是指在test文件上,对数累加概率和,即logp = log10pw1+log10pw2...
test log probability given by other lm和上面的计算方式是一样的,只不过它是用srilm训练的模型
test log probability 0.500000*rnn + 0.500000*other_lm:这个是指插值后的模型的对数累加概率
后面三个PPL net, PPL other, PPL combine,分别指三个模型在测试集上面的困惑度
好啦,rnnlm的基本功能就介绍到此,本文结束,有任何错误的地方欢迎指出,更详细的好请看相关代码和文档