LSTM源码分析

更新时间:2023-07-01 19:29:48 阅读: 评论:0

gre 查分LSTM源码分析
代码来源:
结合这篇⽂章阅读:
 LSTM模型图
 数据集:
thorough  数据集来⾃Stanford,数据是源⾃IMDB,互联⽹电影资料库(Internet Movie Databa,简称IMDB)。IMDB数据集被Bengio组⽤pickle打包了。情感分析的X,是数据的评论,⽽作为情感分析的Y,是评分与否(值只有0和1)。这个情感分析就是⼀个⼆元分类。 pickle序列号的格式:
  train[0]是⼀个矩阵,这个矩阵就是压缩的向量空间模型,第⼀维(⾏)是所有句⼦,也就是数据集⾥的评论。每⼀⾏就是⼀个句⼦。第⼆维(列)是句⼦⾥的词汇,准确来说,是词汇的索引,索引表在这。french letter
majoringtrain[1]是01的数组,数组的数量就是评论句⼦数量。
  test的格式相同,然后作者把train分离出⼀个验证集。此外在代码imdb.py⾥有⼀些预处理,在这⾥便不赘述。
 模型构建:
  代码⾥使⽤了SGD进⾏训练,每⼀个句⼦就是⼀个样本,多个句⼦组合在⼀起,形成⼀个minibatch。
  在代码⾥,batch⼤⼩为n_sample,batch⾥句⼦的最⼤长度为n_timesteps,投射维度为dim_proj,总词汇数为n_words,最后输出的分类数为ydim(这⾥ydim为2,⼆元情感分析)。
 各参数的维度如下:
  这⾥的乘以4,是因为总共有3个gate和1个cell,线性部分都是⼀致的(其中省去了Peephole),作者把这⼏个并在⼀起,利⽤
numpy的矩阵运算(更准确来说,是theano重新写的,只是函数名和⽤法相同),达到同时计算的⽬的。
 各参数的初始化⽅法:
  ⽣成⼀个dim_proj * dim_proj维⼤⼩的矩阵,元素都是服从均值为0 ⽅差为1的⾼斯分布的随机数。然后对该矩阵进⾏svd分解,取第⼀个矩阵作为参数初始化。原因见:
:初始化为0。
:服从均值为0 ⽅差为1的⾼斯分布的随机数乘上0.01。
:服从0到1之间的均匀分布。
美国大学托福
 函数剖析:
def init_params(options):
def param_init_lstm(options, params, prefix='lstm'):
def init_tparams(params):
  这三个函数,分别初始化上⾯的⼏个参数,包括了Word Embedding,输出层的参数 、,lstm层的参数,,。后者这⼏个参数,作者使⽤了atenate([list], axis=1)对第⼆维(也就是列)拼起来,向量化达到了lstm各个门之间并⾏运算。原因是:我们可以看到3个gate和1个cell 的计算公式⾥,都有这样的⼀个类似的部分 (下标x可以替换成i、f、o、c任意⼀个),前者是从input输⼊⽽来,⽽后者由上⼀个t-1时刻循环传递回来(这也是为什么lstm被称为RNN的变种)。
最后init_tparams将上述所有参数转换为theano的shared变量,存到显存⾥。五四青年节演讲稿励志
阅读dnadef lstm_layer(tparams, state_below, options, prefix='lstm', mask=None):中秋节快乐 英文
  这是lstm层的构建的代码。state_below就是下⾯会讲到的emb,3维的张量(n_timesteps * n_samples * dim_proj)
1.  state_below = (tensor.dot(state_below, tparams[_p(prefix, 'W')]) + tparams[_p(prefix, 'b')]) 这⾥是⼀个3维的张量点乘2维的矩阵,计算 (三个gate和⼀个cell的x部分)特别的,state_below是n_timesteps * n_samples * dim_proj,W是dim_proj * (dim_proj * 4),最后得到维度为n_timesteps * n_samples * (dim_proj * 4)。b维度(dim_proj*4) ,broadcast⼴播机制的存在,使得所有的样本都会加上b。这时state_below维数不是n_timesteps * n_samples * dim_proj,⽽是n_timesteps * n_samples * (dim_proj * 4)。阅读的过程中,我很好奇作者为什么要⽤同⼀个名称代表不同两个东西,我⾃⼰写TransE的代码时候,其实也⼲过这种破事。
2.  将_step函数传⼊theano的scan函数。mask, state_below,tensor.alloc(numpy_floatX(0.), n_samples, dim_proj),
alienationtensor.alloc(numpy_floatX(0.), n_samples, dim_proj)四个,分别代表m_, x_, h_, c_。在作者的命名⾥,X_代表变量X的上⼀个时序状态。h_是上⼀个时刻lstm层的输出,c_是上⼀时刻cell的值。维度均为n_samples * dim_proj,初始化为0。特别的,两个参数都没变成shared变量,估计是作者认为只需要记住⼀次就可以。
3.  scan函数会对quences、outputs_info的第⼀维(也就是⾏)进⾏循环处理。从上⽂可以知道,⾏数就是句⼦⾥的单词数,句⼦⾥有多少个词(取batch⾥最长的句⼦),就scan多少。如图:
4.  Python的嵌套⼦函数_step。preact计算的结果就是公共部分。然后分别对三个gate和⼀个cell(i、f、o、c)分别计算其激活函数。紧接着c = f * c_ + i * c 更新cell的值,这⾥参照原⽂,使⽤了元素相乘,cell的维度不变。
5. 最后返回scan的第⼀个返回值(没有shared第⼆个也⽤不到)的第⼀个元素(第⼀个元素是h,第⼆个元素是c)。scan会把所有迭代叠在⼀起。也就是h矩阵最后在scan⾥是h张量。我们上⽂知道,迭代是对句⼦长度迭代,也就是每⼀切⽚就是⼀个单词。最后的rval[0]的维度是n_timesteps * n_samples * dim_proj。
fairchilddef build_model(tparams, options):
  这个函数的作⽤如其名,构建模型,构建最终使⽤的cost函数。
1. 作者定义了⼏个Tensor变量,x,mask,y。
2. emb = tparams['Wemb'][x.flatten()].reshape([n_timesteps, n_samples, options['dim_proj']]),x是⼀个矩阵,⾏是句⼦数也就是样本数(batch ⼤⼩),flatten()之后,变成⼀个索引的列表,将Wemb⾥所对应的词向量取出来。得到emb是⼀个3维张量。
3.  将emb输⼊到lstm_layer函数⾥得到rval[0],这时候是⼀个3维张量。
4.  对这个结果进⾏Mean Pooling,就是对⼀句话的所有词汇所⽣成的各个h,进⾏加权平均(这种做法只是作者参考word2vec源码如此做的,也可以⽤别的⽅法汇集在⼀起,⽐如利⽤attention-bad model)。
5.  Dropout处理和offt(避免出现0)
6.  最后利⽤上⾯的参数 、 做了个softmax输出层,进⾏了分类(在这⾥⼆元其实就是逻辑斯谛)。

本文发布于:2023-07-01 19:29:48,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/163955.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:GCC使用说明
标签:作者   参数   矩阵   部分   向量
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图