2018.06.06论文:12个NLP分类模型

文章目录
  1. 1. 1 概述
    1. 1.1. 1.1模型概览
    2. 1.2. 1.2各模型效果对比:
    3. 1.3. 1.4 代码用法:
  2. 2. 2 模型细节:
    1. 2.1. 2.1 快速文本(fastText)
      1. 2.1.1. 介绍
      2. 2.1.2. 解释
      3. 2.1.3. 总结
    2. 2.2. 2.2文本卷积神经网络(Text CNN)
    3. 2.3. 2.3文本循环神经网络(Text RNN)
    4. 2.4. 2.4 双向长短期记忆网络文本关系(BiLstm Text Relation)
    5. 2.5. 2.5 两个卷积神经网络文本关系(two CNN Text Relation)
    6. 2.6. 2.6 双长短期记忆文本关系双循环神经网络(BiLstm Text Relation Two RNN)
    7. 2.7. 2.7 循环卷积神经网络(text-RCNN)
    8. 2.8. 2.8 分层注意力
    9. 2.9. 2.9具有注意的Seq2seq模型
      1. 2.9.1. 2.9.1 encoder to decoder
      2. 2.9.2. 2.9.2 引入注意力机制
      3. 2.9.3. 2.9.3 attention的计算方式
    10. 2.10. 2.10 Transformer(“Attention Is All You Need”)
    11. 2.11. 2.11 循环实体网络(Recurrent Entity Network)
    12. 2.12. 2.12 动态记忆网络

注1:本文翻译自GitHub上的一篇介绍,介绍了基于深度学习的文本分类问题。代码和部分模型介绍在GitHub上:https://github.com/DX2017/text_classification

注2:本文参考风起云杨译文:https://blog.csdn.net/qq_35273499/article/details/79498733 并加入自己的理解整理。

1 概述

这个库 的目的是探索用深度学习进行NLP文本分类的方法。它具有文本分类的各种基准模型。

它还支持多标签分类,其中多标签与句子或文档相关联(作者的一篇论文:链接:large scale muli-label text classification with deep learning)。

虽然这12个模型都很简单,可能不会让你在这项文本分类任务中游刃有余,但是这些模型中的其中一些是非常经典的,因此它们可以说是非常适合作为基准模型的。每个模型在模型类型(github代码)下都有一个测试函数。这个几个模型也可以用于构建问答系统,或者是序列生成。

如果你想了解更多关于文本分类,或这些模型可以应用的任务的数据集详细信息,可以点击链接进行查询,我们选择了一个:https://biendata.com/competition/zhihu/

1.1模型概览

这篇文章介绍的模型有以下:

  • 1.fastText
  • 2.TextCNN
  • 3.TextRNN
  • 4.RCNN
  • 5.分层注意网络(Hierarchical Attention Network)
  • 6.具有注意的seq2seq模型(seq2seq with attention)
  • 7.Transformer(“Attend Is All You Need”)
  • 8.动态记忆网络(Dynamic Memory Network)
  • 9.实体网络:追踪世界的状态
  • 10.Ensemble models
  • 11.Boosting:
    该模型是多模型堆叠而来的。每一层都是一个模型。结果将基于加在一起的logits,层之间的唯一链接是标签权重。每个标签的浅层预测误差率将成为下一层的权重。那些错误率很高的标签会有很大的权重。所以后面的层将更加关注那些错误预测的标签,并试图修复前一层的误差。结果是,我们可以得到一个很强大的模型。查看: a00_boosting/boosting.py

还包括一下其他模型:

  • 1.BiLstm Text Relation
  • 2.Two CNN Text Relation
  • 3.BiLstm Text Relation Two RNN

1.2各模型效果对比:

性能(多标签标签预测任务,要求预测能够达到前5,300万训练数据,满分:0.5)
性等对比

1.4 代码用法:

  1. 模型在xxx_model.py中

  2. 运行python xxx_train.py来训练模型

  3. 运行python xxx_predict.py进行推理(测试)。

  • 运行环境:

python 2.7+tensorflow 1.1

TextCNN 模型已经可以转换成python 3.6版本

  • 注意:

一些util函数是在data_util.py中的;典型输入如:“x1 x2 x3 x4 x5 label 323434”,其中“x1,x2”是单词,“323434”是标签;它具有一个将预训练的单词加载和分配嵌入到模型的函数,其中单词嵌入在word2vec或fastText中进行预先训练。

2 模型细节:

2.1 快速文本(fastText)

介绍

参考:https://www.sohu.com/a/219080991_129720

FastText是Facebook开发的一款快速文本分类器,提供简单而高效的文本分类和表征学习的方法,不过这个项目其实是有两部分组成的:

  1. 一部分是 文本分类paper:A. Joulin, E. Grave, P. Bojanowski, T. Mikolov, Bag of Tricks for Efficient Text
    Classification
    (高效文本分类技巧)。
  2. 另一部分是词嵌入学习(paper:P. Bojanowski, E. Grave, A. Joulin, T. Mikolov, Enriching Word Vectors with Subword Information(使用子字信息丰富词汇向量))。

本文主要关注FastText 用于文本分类,其词向量的用法可以参考博文:NLP︱高级词向量表达(二)——FastText(简述、学习笔记)

fastText是Facebook于2016年开源的一个词向量计算和文本分类工具,在学术上并没有太大创新。但是它的优点也非常明显,在文本分类任务中,fastText(浅层网络)往往能取得和深度网络相媲美的精度,却在训练时间上比深度网络快许多数量级。在标准的多核CPU上, 能够训练10亿词级别语料库的词向量在10分钟之内。可以看出fastText有两个主要的特点:

  1. 速度很快
  2. 在速度的基础上精度较高 。

对应的解决办法就是:

  1. 层级简单 + embedding叠加 + 分层Softmax
  2. 字符级别的n-gram

解释

  • 快的原因:
  1. 层级简单:image
  2. 单词的embedding叠加获得的文档向量. 全连接参数由 n L 1024 变成 1 L 1024
  3. 在输出时,fastText采用了分层Softmax,大大降低了模型训练时间:

标准的Softmax回归中,要计算y=j时的Softmax概率:,我们需要对所有的K个概率做归一化,这在|y|很大时非常耗时。于是,分层Softmax诞生了,它的基本思想是使用树的层级结构替代扁平化的标准Softmax,使得在计算时,只需计算一条路径上的所有节点的概率值,无需在意其它的节点。

下图是一个分层Softmax示例:

image

树的结构是根据类标的频数构造的霍夫曼树。K个不同的类标组成所有的叶子节点,K-1个内部节点作为内部参数,从根节点到某个叶子节点经过的节点和边形成一条路径。从根节点走到叶子节点,实际上是在做了3次二分类的逻辑回归。通过分层的Softmax,计算复杂度一下从|K|降低到log|K|。

  • 准的原因:字符级别的n-gram:

word2vec把语料库中的每个单词当成原子的,它会为每个单词生成一个向量。这忽略了单词内部的形态特征,比如:“apple” 和“apples”,“达观数据”和“达观”,这两个例子中,两个单词都有较多公共字符,即它们的内部形态类似,但是在传统的word2vec中,这种单词内部形态信息因为它们被转换成不同的id丢失了。

为了克服这个问题,fastText使用了字符级别的n-grams来表示一个单词。对于单词“apple”,假设n的取值为3,则它的trigram有:

1
“<ap”, “app”, “ppl”, “ple”, “le>”

其中,<表示前缀,>表示后缀。于是,我们可以用这些trigram来表示“apple”这个单词,进一步,我们可以用这5个trigram的向量叠加来表示“apple”的词向量。

这带来两点好处:(论文中怎么说》》》》》????)

  1. 对于低频词生成的词向量效果会更好。因为它们的n-gram可以和其它词共享。

  2. 对于训练词库之外的单词,仍然可以构建它们的词向量。我们可以叠加它们的字符级n-gram向量。

总结

于是fastText的核心思想就是:将整篇文档的词及n-gram向量叠加平均得到文档向量,然后使用文档向量做softmax多分类。这中间涉及到两个技巧:字符级n-gram特征的引入以及分层Softmax分类。github代码:p5_fastTextB_model.py

2.2文本卷积神经网络(Text CNN)

《卷积神经网络进行句子分类》ConvolutionalNeuralNetworksforSentenceClassification论文的实现

结构:降维—> conv —> 最大池化 —>完全连接层——–> softmax

github代码查看:p7_Text CNN_model.py

textcnn

卷积神经网络是解决计算机视觉问题的主要手段。 现在我们将展示CNN如何用于NLP,特别是文本分类。句子长度会略有不同。 所以我们将使用padding来获得固定长度,n。

对于句子中的每个标记,我们将使用单词嵌入来获得一个固定的维度向量d。 所以我们的输入是一个二维矩阵:(n,d)。这跟CNN用于图象是类似的。

首先,我们将对我们的输入进行卷积计算。他是滤波器和输入部分之间的元素乘法。我们使用k个滤波器,每个滤波器是一个二维矩阵(f,d)注意d与词向量的长度相同。现在输出的将是k个列表,每个列表的长度是n-f+1。每个元素是标量(scalar)。请注意,第二维将始终是单词嵌入的维度。我们使用不同的大小的滤波器从文本输入中获取丰富的特征,这与n-gram特征是类似的。

其次,我们将卷积运算的输出做最大池化。对于k个特征映射,我们将得到k个标量。

第三,我们将连接所有标量来获得最终的特征。他是一个固定大小的向量。它与我们使用的滤波器的大小无关。

最后,我们将使用全连接层把这些特征映射到之前定义的标签。

2.3文本循环神经网络(Text RNN)

Github 代码查看:p8_Text RNN_model.py

尽管TextCNN能够在很多任务里面能有不错的表现,但CNN有个最大问题是固定 filter_size 的视野,一方面无法建模更长的序列信息,另一方面 filter _size 的超参调节也很繁琐。CNN本质是做文本的特征表达工作,而自然语言处理中更常用的是递归神经网络(RNN, Recurrent Neural Network),能够更好的表达上下文信息。

模型结构:embedding—>bi-drectional lstm —> concat output –>average—–> softmax layer

image

通过利用双向LSTM建模,然后输出最后一个词的结果直接接全连接层softmax输出了。

2.4 双向长短期记忆网络文本关系(BiLstm Text Relation)

Github 代码查看:p9_BiLstm Text Relation_model.py

结构:结构与Text RNN相同。但输入是被特别设计,直接把两个句子进行拼接。

例如:

1
#   "how much is the computer? EOS price of laptop"---> label:1

“EOS”是一个特殊的标记,将问题1和问题2分开。但是 模型并没有把两个句子分割开来,而是当做一个输入进行建模: 把 (背后的逻辑应该是 BiLstm 的自动“双向”建模能力)

2.5 两个卷积神经网络文本关系(two CNN Text Relation)

Github 代码查看:p9_two CNN Text Relation_model.py

结构:首先用两个不同的卷积来提取两个句子的特征,然后连接两个特征,使用线性变换层将投影输出到目标标签上,然后使用softmax二分类。

image

更多文档、代码参考 参见USTC大佬、iflytek之光 Randolph的github库:Text-Pairs-Relation-Classification

2.6 双长短期记忆文本关系双循环神经网络(BiLstm Text Relation Two RNN)

Github 代码查看:p9_BiLstm Text Relation Two RNN_model.py

结构:一个句子的一个双向lstm(得到输出1),另一个句子的另一个双向lstm(得到输出2)。拼接之后加全连接, 最后:softmax(输出1 输出0)

2.7 循环卷积神经网络(text-RCNN)

Github 代码查看:p71_TextRCNN_model.py

《用于文本分类的循环卷积神经网络》Recurrent Convolutional Neural Networks for Text Classification论文的实现。

结构:1)循环结构(卷积层)2)最大池化3)完全连接层+ softmax

image

重点是 循环结构(卷积层),在循环神经网络中,加入了“上一个单词”的词向量,类似于 卷积神经网络的2-gram特征。这就是为什么是循环网络 却叫卷积层,重点代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def get_context_left(self,context_left,embedding_previous):
"""
:param context_left:
:param embedding_previous:
:return: output:[None,embed_size]
"""
left_c=tf.matmul(context_left,self.W_l) #context_left:[batch_size,embed_size];W_l:[embed_size,embed_size]
left_e=tf.matmul(embedding_previous,self.W_sl)#embedding_previous;[batch_size,embed_size]
left_h=left_c+left_e
context_left=self.activation(left_h)
return context_left

def get_context_right(self,context_right,embedding_afterward):
"""
:param context_right:
:param embedding_afterward:
:return: output:[None,embed_size]
"""
right_c=tf.matmul(context_right,self.W_r)
right_e=tf.matmul(embedding_afterward,self.W_sr)
right_h=right_c+right_e
context_right=self.activation(right_h)
return context_right

2.8 分层注意力

代码:p1_HierarchicalAttention_model.py

《用于文档分类的分层注意网络》Hierarchical Attention Networks for Document Classification 论文的实现。

结构:

  1. 词编码器:词级双向GRU,以获得丰富的词汇表征
  2. 词注意力:词级注意在句子中获取重要信息
  3. 句子编码器:句子级双向GRU,以获得丰富的句子表征
  4. 句子注意:句级注意以获得句子中的重点句子
  5. FC + Softmax

image

它有两个独特的特点:

1)它具有体现文件层次结构的层次结构

2)它在单词和句子级别使用两个级别的注意力机制,它使模型能够捕捉到不同级别的重要信息。

一个重要问题: ==Uw和Us 的来源 去向?==

计算方式:image

  • 就是一个 随机初始化的“权重向量”,通过训练更新, 每次计算出前向神经网络的隐层输出之后,乘以权重得到注意力向量。

从代码来研究:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
def AttentionLayer(self, inputs, name):
#inputs是GRU的输出,size是[batch_size, max_time, encoder_size(hidden_size * 2)]
with tf.variable_scope(name):
# u_context是上下文的重要性向量,用于区分不同单词/句子对于句子/文档的重要程度,
# 因为使用双向GRU,所以其长度为2×hidden_szie
u_context = tf.Variable(tf.truncated_normal([self.hidden_size * 2]), name='u_context')
#使用一个全连接层编码GRU的输出的到期隐层表示,输出u的size是[batch_size, max_time, hidden_size * 2]
h = layers.fully_connected(inputs, self.hidden_size * 2, activation_fn=tf.nn.tanh)
#shape为[batch_size, max_time, 1]
alpha = tf.nn.softmax(tf.reduce_sum(tf.multiply(h, u_context), axis=2, keep_dims=True), dim=1)
#reduce_sum之前shape为[batch_szie, max_time, hidden_szie*2],之后shape为[batch_size, hidden_size*2]
atten_output = tf.reduce_sum(tf.multiply(inputs, alpha), axis=1)
return atten_output

###########################################################################################

1. 词向量层:省略

2. 句子级注意力:
def sent2vec(self, word_embedded):
with tf.name_scope("sent2vec"):
#GRU的输入tensor是[batch_size, max_time, ...].在构造句子向量时max_time应该是每个句子的长度,所以这里将
#batch_size * sent_in_doc当做是batch_size.这样一来,每个GRU的cell处理的都是一个单词的词向量
#并最终将一句话中的所有单词的词向量融合(Attention)在一起形成句子向量

#shape为[batch_size*sent_in_doc, word_in_sent, embedding_size]
word_embedded = tf.reshape(word_embedded, [-1, self.max_sentence_length, self.embedding_size])
#shape为[batch_size*sent_in_doce, word_in_sent, hidden_size*2]
word_encoded = self.BidirectionalGRUEncoder(word_embedded, name='word_encoder')
#shape为[batch_size*sent_in_doc, hidden_size*2]
sent_vec = self.AttentionLayer(word_encoded, name='word_attention')
return sent_vec

3.文档级注意力
def doc2vec(self, sent_vec):
#原理与sent2vec一样,根据文档中所有句子的向量构成一个文档向量
with tf.name_scope("doc2vec"):
sent_vec = tf.reshape(sent_vec, [-1, self.max_sentence_num, self.hidden_size*2])
#shape为[batch_size, sent_in_doc, hidden_size*2]
doc_encoded = self.BidirectionalGRUEncoder(sent_vec, name='sent_encoder')
#shape为[batch_szie, hidden_szie*2]
doc_vec = self.AttentionLayer(doc_encoded, name='sent_attention')
return doc_vec
4. 全连接层:省略

2.9具有注意的Seq2seq模型

具有注意的Seq2seq模型的实现是通过《共同学习排列和翻译的神经机器翻译》NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN AND TRANSLATE来实现的。

首先学习一下什么是seq2seq模型:https://blog.csdn.net/qq_27505047/article/details/79531049

2.9.1 encoder to decoder

首先是第一篇《NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN AND TRANSLATE》,这篇论文算是在自然语言处理(NLP)中第一个使用attention机制的工作,将attention机制用到了神经网络机器翻译(NMT),NMT其实就是一个典型的Seq2Seq模型,也就是一个encoder to decoder模型,传统的NMT使用两个RNN,一个RNN对源语言进行编码,将源语言编码到一个固定维度的中间向量,再使用一个RNN进行解码翻译到目标语言:

image

按照论文所述,encoder中的每个隐层单元的计算公式为:

image

encoder的输出语义编码向量c为:

image

而decoder通过将联合概率p(y)分解成有序条件来定义翻译y的概率:
image

2.9.2 引入注意力机制

而引入注意力机制后的模型如下:

此时,关于p(y)的定义变化如下:

此处c变成了ci,即要输出的第i个单词时对应的ci向量,因此要如何计算ci向量时注意力机制实现的关键.但在此之前si的计算也变成了:

image

此时引入 论文示意图:

image

2.9.3 attention的计算方式

那么重点来了,这个系数a是怎么计算的呢?

注意机制计算过程:

  1. 计算每个编码器输入 与 解码器隐藏状态的相似度,以获得每个编码器输入的可能性分布。
  2. 计算 基于可能性分布的 编码器注意力的加权和。ci是所有具有概率αij的hj的期望。
    image

2.10 Transformer(“Attention Is All You Need”)

参考mijiaoxiaosan的博文:《对Attention is all you need 的理解》

参考 paperweekly 《一文读懂「Attention is All You Need」| 附代码实现》 https://yq.aliyun.com/articles/342508

带注意的 seq2seq是解决序列生成问题的典型模型,如翻译、对话系统。

Transformer,它仅仅依靠注意机制执行这些任务 (编码器 解码器 都只用attention),是快速的、实现新的最先进的结果。

结构如下:

  • 编码器:

由N = 6个相同层的堆叠组成。

每个层都有两个子层。第一是多向自注意机制;第二个是全连接前馈网络。

  • 解码器:

1.解码器由N = 6个相同层的堆叠组成。

2.除了每个编码器层中的两个子层之外,解码器多加入了一层 多向注意。

image

这个模型主要创新点: ==多头注意力 和位置编码== 关键点:

  1. ==位置编码==: 由于模型没有任何循环或者卷积,为了使用序列的顺序信息,需要将tokens的相对以及绝对位置信息注入到模型中去。论文在输入embeddings的基础上加了一个“位置编码”。位置编码和embeddings由同样的维度都是d 所以两者可以直接相加。 有很多位置编码的选择,既有学习到的也有固定不变的。本文中用了正弦和余弦函数进行编码。$PosEnc_{(pos,2i)} = sin(pos/10000^{2i/{d_{model}}})$ $PE_{(pos,2i+1)} = cos(pos/10000^{2i/{d_{model}}})$
    其中的pos是位置,i是维度(比如50维的词向量 如果位置 和 确定了 )。 偶数维度用sin 奇数维度用cos。 最后将词向量与位置向量直接相加。
  2. ==多头注意力 的基本组成单位==:
    1. 普通注意力 :attention函数可以看作将一个query和一系列key-value对映射为一个输出(output)的过程(多数情况下 K和V是同一向量)事实上这种 Attention 的定义并不新鲜,但由于 Google 的影响力,我们可以认为现在是更加正式地提出了这个定义,并将其视为一个层地看待。。image
    2. 论文自创在普通attention的基础上加了一个Scale(缩放层):计算query和所有keys的点乘,然后每个都除以dk−−√(这个操作就是所谓的Scaled)。之后利用一个softmax函数来获取values的权重。 这样可以起到“归一化”的作用。Mask层没看懂。
    3. 总的来说 attention公式如下:$Attention(Q,K,V) = softmax({QK^T\over {\sqrt {d_k}}})V$ 。只要稍微思考一下就会发现,这样的 Self Attention模型并不能捕捉序列的顺序。换句话说,如果将 K,V 按行打乱顺序(相当于句子中的词序打乱),那么 Attention 的结果还是一样的。但是对于 NLP 中的任务来说,顺序是很重要的信息,它代表着局部甚至是全局的结构,学习不到顺序信息,那么效果将会大打折扣。于是 Google 再祭出了一招——Position Embedding,也就是上面的“位置向量”。
  3. ==Multi-Head Attention 多头注意力==:本文结构中的Attention并不是简简单单将一个attention应用进去。作者发现对 原始向量 进行h 次不同的attention,再拼接起来 效果特别好。所谓“多头”(Multi-Head),就是只多做几次同样的事情(参数不共享),然后把结果拼接。

分别对每一个映射之后的得到的queries,keys以及values进行attention函数的并行操作,最后拼接成output值。具体操作细节如以下公式。 $MultiHead(Q,K,V) = Concat(head_1,...,head_h)$ $where: head_i = Attention(Q{W_i}^Q,K{W_i}^K,V{W_i}^V)$ 结构示意图: image

2.11 循环实体网络(Recurrent Entity Network)

这篇论文是facebook AI在2017年的ICLR会议上发表的,文章提出了Recurrent Entity Network的模型用来对world state进行建模,根据模型的输入对记忆单元进行实时的更新,从而得到对world的一个即时的认识。该模型可以用于机器阅读理解等领域。

输入:

  1. 故事:它是多句话,作为上下文。
  2. 问题:一个句子,这是一个问题。
  3. 回答:一个单一的标签。

和之前的模型一样,Entity Network模型共分为Input Encoder、Dynamic Memory和Output Model三个部分。如下图的架构图所示:

image

模型结构:

1.输入编码层:利用RNN或者LSTM等时序神经网络模型,使用最后一个时间步长的状态作为句子编码 来编码故事(上下文)和查询(问题)st就是固定长度的句子的向量表示。

2.动态记忆:

a. 通过使用键的“相似性”,输入故事的值来计算门控。

b. 通过转换每个键,值和输入来获取候选隐藏状态。

c. 组合门和候选隐藏状态来更新当前的隐藏状态。

t时刻输入st时,每个隐含层状态hj通过st和key wj来更新,更新公式如下:

$g_j \gets \sigma (s_t^T h_j + s_t^T w_j)$

$\tilde{h_j} \gets \phi( Uh_j + Vw_j + Ws_t)$

$h_j \gets h_j + g_j \odot \tilde{h_j}$

$h_j \gets \frac{h_j}{|h_j|}$

例如:

  • Mary picked up the ball.
  • Mary went to the garden.
  • Where is the ball?

前两句是文本,最后一句是问题。由第一句得到在时间步长t的句子表达st,由第二句得到时间步长t+1的句子表达st+1。

  1. 当st被读取,w1记录实体Mary,h1记录实体状态Mary拿了一个ball;
  2. w2记录实体ball,h2记录实体状态ball被Mary拿着;
  3. 然后st+1被读取,读取到Mary,因为w1是记录Mary的key,位置寻址项sTt+1w1变化,门函数被激活,更新h1实体状态Mary去了garden;
  4. 因为h2记录ball被mary拿着,因此内容寻址项sTt+1h2变化,门函数被激活,更新h2的实体状态球被mary拿着,球在garden。
  • Output Model
    在原文中使用了一层的记忆网络,因此得到最后一个时间步长的隐层向量hj以后,就可以直接输出。

2.12 动态记忆网络

原文:《Ask me anything: dynamic memory networks for natural language processing》

博客参考:https://blog.csdn.net/javafreely/article/details/71994247

Question answering 是自然语言处理领域的一个复杂问题. 它需要对文本的理解力和推理能力.DMN 的输入包含事实输入,问题输入,经过内部处理形成片段记忆,最终产生问题的答案.

DMN 由4个模块组成:

  • 输入模块: 将原生文本输入编码成分布式向量表示. NLP 问题中,输入可以是一个句子,一个故事,电影评论,新闻文章或者维基百科文章等. 它的输入是 Work embedding(如通过 word2vec 或 GloVe 编码).
  • 问题模块: 同输入模块类似,也是一个 RNN 网络. 输出是最后隐藏节点.
  • 片段记忆模块: 片段记忆模块通过注意力机制决定关注输入数据的那些部分,并根据之前的记忆和问题产生新的记忆.
  • 回答模块:回答模块也是一个 GRU 网络.其中上次输出和问题一起作为gru节点的输入。 根据最终记忆,产生问题的回答.

image

  1. 输入模块
  • 输入模块是一个 RNN 网络. 它的输入是 Work embedding(如通过 word2vec 或 GloVe 编码). 输入是 TI个单词 w1,…,wTI .
  • 在每个时间点 t,RNN 更新其隐藏状态 ht=RNN(L[wt],ht−1) . L 是 word embedding matrix.
  • 在输入只有一个句子的情况下,输入模块输出 RNN 的所有隐藏状态.
  • 在输入是多个句子的情况下,我们将所有句子拼接,并在每个句子末尾插入句末 token. RNN 每个句末 token 位置的隐藏状态作为输出.
  • 输入模块的输出序列为 Tc 个 fact representation c. 其中 $c_t$ 是输出序列的第 t 个元素. 输入多个句子的情况下,TC 是句子个数.
  • RNN 的选择: 原生的 RNN 性能较差, GRU 和 LSTM 性能差不多,但 LSTM 的计算更加昂贵,所以一般使用 GRU.
  1. 问题模块
  • 同输入模块类似,也是一个 RNN 网络.
  • 输出是最后隐藏节点 qTQ. (不同于输入模块,输入模块的输出是多个隐藏节点)
  1. 片段记忆模块
  • 每个迭代都根据之前的记忆$m^{i-1}$、问题q 和事实 c 产生新的片段 ei.新的episode (e)等$e_t^i = G(c_t, m^{m-1}, q)$ (其中初始: m 0 = q) (e每次都带着q)
  • 在当前E之下:片段记忆在输入模块输出的事实 c 上迭代,更新内部的片段记忆.$m^i = GRU(e^i, m^{i-1})$
  • 注意力机制:本文使用门控功能作为我们的注意机制,门函数 G(c,m,q)=σ(W(2)tanh(W(1)z(c,m,q)+b(1))+b(2)) 来衡量当前 句子的关注力
  1. 回答模块
  • 回答模块也是一个 GRU 网络.
  • 初始值为 a0=mTM
  • 输出为 yt=softmax(W(a)at)
  • 隐藏状态 at=GRU([yt−1,q],at−1), 上次输出和问题一起作为输入
分享到 评论