Memory Networks原理及其代码解析

    http://blog.csdn.net/u011274209/article/details/53384232

原理:

文章来源:Memory NetworksAnswering Reading Comprehension Using Memory Networks

  对于很多神经网络模型,缺乏了一个长时记忆的组件方便读取和写入。作为RNN,lstm和其变种gru使用了一定的记忆机制。在Memory Networks的作者看来,这些记忆都太小了,因为把状态(state,也就是cell的输出)及其权重全部都嵌入到一个低维空间,把这些知识压缩成一个稠密的向量,丢失了不少信息。这也是文章(或者memory系列)的出发点,它的做法简单粗暴,增加一个m模块。m是一个对象的数组(an array of objects,for example an array of vectors or an array of strings),在文章里,更多叫成slot(插槽)。记忆一个事实(一般是对话组里的一句话),就把它“插”到记忆(数组)里。
  一个记忆网络(memory networks,简称为MemNN),包括了上述的记忆m,还包括以下4个组件I、G、O、R(是不是超级像lstm的三个门啊,然后m像cell的list):

组件名称描述
Iinputconverts the incoming input to the internal feature representation.
Ggeneralizationupdates old memories given the new input. “We call this generalization as there is an opportunity for the network to compress and generalize its memories at this stage for some intended future use.”
Ooutputproduces a new output in the feature representation space given the new input and the current memory state.
Rresponseconverts the output into the response format desired – for example, a textual response or an action.

I:用于将输入转化为网络里内在的向量。作者使用了简单的向量空间模型,维度为3*lenW+3(熟悉VSM会问为什么不是lenW,下面会说具体)。
G:更新记忆。在作者的具体实现里,只是简单地插入记忆数组里。作者考虑了几种新的情况,虽然没有实现,包括了记忆的忘记,记忆的重新组织。
O:从记忆里结合输入,把合适的记忆抽取出来,返回一个向量。
R:将该向量转化回所需的格式,比如文字或者answer。对于R来说,最简单的是,直接返回o的第一个支撑记忆,也就是一句话。当然作者,打算弄复杂点,返回一个词汇w。
MemoryNetworkArchitecture
  以下是统一的公式(可以看出作者把这玩意做成了一个架构,而不是一个具体的算法):
算法
  所有组件都是神经网络的话,叫做记忆神经网络(MemNNs,多了个s)。

Basic Model:

  这是作者自己做的一个基本模型,或者算作是这个架构的一个简单例子。以下从一个记忆四个组件的角度,对这个方法进行说明:
流程
I:I输入的是一句话,简单地将I转换为一个频率的向量空间模型。
G:也是如上,简单地把读到的对话组里的每一句话的向量空间模型,插到记忆的list里,这里默认记忆插槽比对话组句子还多。 mN=x , N=N+1 。是的,m、I和G都很简单,也就是重任就压到了O和R上了。
O:O干的事,就是输入一个问题x,将最合适的k个支撑记忆(the supporting memories,在下文的数据集里会举出例子),也就是top-k。做法就是把记忆数组遍历,挑出最大的值。最后,O返回一个长度为k的数组。
对于top1有 o1=O1(x,m)=argmaxi=1,...,NsO(x,mi)
对于top2有 o2=O2(x,m)=argmaxi=1,...,NsO([x,mo1],mi)
  这里有几点说明:1、在这里,返回的 oi 简单就是记忆数组的序号索引。
  2、在这里(向量空间模型向量表示),有 sO([x,mo1],mi)=sO(x,mi)+sO(mo1,mi) 。也就是对于多事实的情况,可以分开同时计算其与记忆的“关联度”,然后加总。如果对于其他向量表示方式,则不一定有这样的线性关系。
  3、作者给了一个有趣的例子反映了这个预测(test)过程,我觉得与其叫做回忆过程,还不如叫成推理过程好些,囧:
例子1
例子2
  R:为了返回一个词汇w,设置公式 r=argmaxwWsR([x,mo1,mo2],w) 。这里对所有的词汇进行循环遍历,挑出最适合答案(分数最高)的结果。在论文里,词汇被转化为同一空间里的向量空间模型的向量。如“memory”= [0,0,0,0,1,0,0,0] ,“network”= [1,0,0,0,0,0,0,0] ,则句子“memory network”= [1,0,0,0,1,0,0,0]
  最后:作者继续简化处理 sO=sR=s(x,y)=Φx(x)UUΦy(y)
  其中,U是一个权重矩阵,维度为n*D。D是输入向量的维度,n是嵌入的维度,n是一个超参数。作者使用D=3*lenW的维度。这里考虑了3倍向量空间模型长度,一份是给了phi_y Фy ,一份是给了x是输入的问题时的phi_x Фx ,一份是给了x是支撑记忆时的phi_x Фx ,三份直接连接在一起就可以了。(个人认为,作为对称,应该是4份。或许作者认为问题是一个空间,陈述句是另一个空间,而回答词汇只是属于陈述句空间,不用放在一起。) 和 使用不同的权重矩阵。
维度
  训练过程:使用margin ranking loss和sgd,在SVM和TransE里已经见识过了,就不赘述,复制公式如下:
训练
   f¯ f¯ 分别是第一和第二个支撑记忆, r¯ 是正确答案。对的,读者也发现了,MemNN是一个监督学习的算法。(以后很多记忆模型,改成了弱监督了,以N2N为代表)注意,这里有两个监督的部分,一个是支撑记忆,一个是正确答案。

basic model的改进

  作者考虑了一些新的情况:包括
  1、输入是连续的词汇。使用RNN之类的产生一些词序列,作者加了一层,叫做segment。
  2、在G的时候,我们是简单把原向量“插进”记忆数组里,如果是把向量“hash”进去呢?
  3、考虑写入的时间。由于下面的代码使用了这个情况,在这里就多讲述。作者针对这种情况的方法是增加了3个维度的,D=3*lenW+3。加上存在一个输入 x ,一个记忆y和另一个记忆 y 如图:
维度+3
  这里3个维度分别代表:x is older than y,x is older than y′, y older than y′,这里xyy’可以是问句也可以是陈述句。
  在训练之前三个维度都为0。训练的时候,对于三种情况,如果都符合,则都赋予1。特别的,如果x是问句时,则前两个维度都置为0,因为问句一定是最新的。
这时O的公式改变了,(R仍然不变,见上文):
sOt(x,y,y)=Φx(x)UotUot(Φy(y)Φy(y)+Φt(x,y,y))
  训练过程的cost变为如下。能看出这里分为两部分,加部分和减部分:
训练t
  预测过程的 o1=O1(x,m)=argmaxi=1,...,NsO(x,mi) 用下面算法代替,值大于0意味着 mi 好于 mt
算法t
  增加这三个维度,使得记忆模型可以知道记忆的相对写入时间,也就知道对话的顺序(order)。当然,如果对话里自身就包括了时间词或者时间状态,则也不一定需要这三个维度。
  4、如果有未登录词汇呢?For example, the first time the word “Boromir” appears in Lord of The Rings。作者把D增加到了5*lenW。
  5、更精确的匹配。作者把D增加到了8*lenW。

代码:

代码来源:https://github.com/npow/MemNN(万分感谢作者)
     https://github.com/wuxiyu/MemNN(我的folk,添加了注释和数据集)
数据集:

  来源于Facebook组织的对话集Toy QA tasks
先看一个训练集的例子:

  1 John travelled to the hallway.
  2 Mary journeyed to the bathroom.
  3 Where is John? hallway 1

  这是一个对话组,句子前面是id。对话组最前面n句是陈述句,用于记忆推论,最后有一句问句,及其答案。答案后面的数字叫做事实(fact),或者叫做支撑记忆(the supporting memories两个词混用),是一个索引,指向支持这个答案回答的那个对话句子。
  最后返回字典的数组。如list:[{‘text’: ‘Mary moved to the bathroom.’, ‘type’: ‘s’}, {‘answer’: ‘bathroom’, ‘text’: ‘Where is Mary’, ‘refs’: [1], ‘type’: ‘q’, ‘id’: 3}]

数据预处理:

  作者调用sklearn的类CountVectorizer进行预处理。
  先是fit传入数据构建模型,然后分别transform返回需要的向量(包括词汇的和句子的),将对话组转化为词频的向量空间模型。在这里,记忆的构建简单处理,每读到一句陈述句,就提取它在VSM里对应的向量,然后将向量插进memory_list记忆数组里,直到遇到了问句就停止。

函数剖析:
def create_train(self, lenW, n_facts):

  这是创建训练模型的函数。传入的包括了事实的数组,问句的id,memory_list(这里模拟了记忆的G过程,简单地将memory(也就是那些陈述句)的向量空间模型,放到这个memory_list数组里。)
  这个函数主要干的是模型O和R部分(正如作者所说的,这个模型主要大头在这两部分上)。
  函数里的m是里一个列表list,list[0]是问句的id,list剩下部分是支撑记忆(支撑记忆其实也是id,所指向的陈述句的id)。作者在这里做了一个小技巧,创建了一个2倍事实数量的数组cost_arr,其中偶数作为公式里的减部分,奇数作为公式里的加部分。当事实数大于一时,由于线性空间加总的缘故,利用scan的迭代,传入前i个事实(代码里是i+1,因为第一个是问句的id,不是事实),最后加总,具体见上面,不赘述。
  代码里有这么一句:

T.switch(T.or_(T.eq(t, f[i]), T.eq(t, T.shape(L)[0]-1)), 0, T.largest(gamma - s_Ot(T.stack(*m[:i+1]), f[i], t, L), 0))

  改成类似的ifelse如下,就好理解多了:

if ( (t == f[i]) ) | (t == T.shape( L )[0] - 1){ 
        return 0
}else{
        return T.largest( gamma - s_Ot( T.stack( *m[: i + 1] ), f[i], t, L ), 0 ) 
}

  函数最后返回的是用于训练的cost函数,具体公式见上文。

  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: 长短期记忆网络(Long Short Term Memory Networks,LSTM)是一种用于处理序列数据的深度学习模型,用于解决传统循环神经网络(RNN)中的梯度消失问题。 Python是一种通用的编程语言,可以使用Python编写LSTM模型。在Python中,可以使用多个深度学习框架(如TensorFlow、Keras、PyTorch等)中的库来实现LSTM网络。 要实现LSTM模型,首先需要导入相应的深度学习库。然后,通过定义模型的参数、数据预处理、定义LSTM层、编译模型、训练模型和评估模型等步骤来构建LSTM网络。在编写代码时,可以使用Python的强大的科学计算库来处理数据和进行数学计算。 在使用Python实现LSTM时,可以根据具体的需求进行调整和优化模型的结构和参数。可以通过调整LSTM层的单元数、增加隐藏层、引入正则化和优化算法来提高模型性能。此外,还可以使用交叉验证和调参技术来选择最佳的超参数。 Python作为一种简洁易用的编程语言,提供了丰富的工具和库来支持LSTM模型的实现和应用。通过使用Python,我们可以轻松地构建和使用LSTM网络,从而应用于各种序列数据相关的任务,如语音识别、自然语言处理、时间序列预测等。 ### 回答2: 长短期记忆网络(Long Short Term Memory Networks,简称LSTM)是一种特殊的循环神经网络(Recurrent Neural Networks,简称RNN),用于处理和预测序列数据。 在Python中,我们可以使用一些开源的深度学习框架,如TensorFlow或PyTorch,来构建和训练LSTM网络。这些框架提供了一系列函数和类,可以轻松地构建、训练和测试LSTM模型。 首先,我们需要导入相应的库和模块。例如,在TensorFlow中,我们可以使用`import tensorflow as tf`来导入TensorFlow库。 接下来,我们可以定义LSTM模型的结构。LSTM网络由多个LSTM单元组成,每个单元有一个隐藏状态和一个记忆单元。我们可以使用框架提供的API来定义一个LSTM层,并设置相应的参数,如隐藏单元的数量和输入序列的长度。 然后,我们可以定义模型的其余部分,如输入层、输出层和损失函数。根据具体任务的要求,我们可以选择不同的网络结构和损失函数来满足需求。 接下来,我们可以进行模型的训练。我们需要提供训练数据和标签,并选择适当的优化算法来更新模型的参数。通过迭代训练过程,我们可以逐渐改善模型的性能。 最后,我们可以使用训练好的模型对新的数据进行预测。我们可以加载保存的模型,并使用它来预测新的序列数据。 总之,使用Python可以方便地构建和训练LSTM网络。通过选择适当的开源深度学习框架和实现合适的网络结构,我们可以有效地在序列数据任务中应用LSTM网络

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值