本文是“Attention-over-Attention Neural Networks for Reading Comprehension”的阅读笔记。这篇论文所处理的任务是阅读理解里面的完形填空问题。其模型架构是建立在“Text Understanding with the Attention Sum Reader Network”这篇论文至上。该论文首先提出了将Attention用于完形填空任务,本篇论文则在其基础之上添加了一个额外的Attention层,可以免去启发式的算法和一些超参数调整等问题。我们接下来结合两篇论文进行介绍。
数据集
首先介绍一下数据集,目前常用的大规模数据集主要包括CNN/Daliy Mail和Children’s Book Test(CBTest)。前面两个是新闻数据集,将一整篇新闻文档作为完形填空的文本(Document),然后将其新闻摘要中的一句话去掉一个词之后作为查询(Query),去掉的那个词作为答案(Answer)。其中Document中的命名实体会被替换成不同的标识符:@entity1、@entity2、、、等例如,第一行为网页URL(无用),第三行为Document, 第五行为Query, 第七行为answer,并且其中的命名实体均被替换:
CBT数据集是从儿童读物中获取,由于其没有摘要,所以采用,前面连续的21句话作为Document,第22句话作为Query等方式构建。然后其还根据答案的词性分为四个子集:命名实体(NE)、公共名词(CN)、动词、介词。但是由于后面两种答案与文本并没有十分紧密的关系,比如人们常常不需要读文本就可以判断出介词填空等,所以常用的是前面两种。
最终每条数据被构建为如下三元组:
<D, Q, A>
模型
首先我们可以看一下“Text Understanding with the Attention Sum Reader Network”这篇论文所提出的模型架构,如下图所示:
从上图可以看出,模型首先通过嵌入矩阵V得到Document和Query中每个单词的词向量e(w)。接下来分别使用两个encoder网络获得文本中每个单词的向量contextual embedding
和Query的表示向量。这里的encoder使用的是双向GRU循环神经网络。然后使用点积的方式将Query向量和每一个单词的contextual embedding
相乘,得到的结果可以视为每个单词对于该查询的权重,亦可理解为attention。最后使用softmax函数将权重转化为归一化的概率,将概率最大的结果视为该query的答案。
接下来我们再看一下本文提出的模型架构,如下图所示:
模型的前半部分与上面完全一样,差别在于本文提出了一种“Attention over Attention”的机制,也就是获得Document和Query的向量之后,不将Query的所有单词合为一个向量,而是直接以矩阵的形式与Document矩阵相乘,然后分别从行和列两个维度对相乘后的矩阵进行softmax操作得到document的注意力矩阵和query的注意力矩阵。在对query矩阵每一列的元素进行求和当做权重,对document的attention矩阵进行点积即可。
模型的代码实现
其实模型使用tensorflow实现的时候十分简单,直接调用tf.contrib.rnn下面的GRUCell即可,难点在于数据的处理和读取操作。这里我们可以参考github上面的两个实现方案:OlavHN,marshmelloX。第一个使用了TF内置的读取数据的API,代码十分简洁明了,我有时间需要研究一下其实现原理整理出一份博客来。第二个使用的是传统的数据处理方式,也可以参考,此外在github上面应该可以找到CNN等数据集的处理代码结合着一起学习。但是上面两个代码实现都用的是比较老的版本,如果用的是tf1.0及以上的版本可能会出现一些函数的不兼容问题,我参照第一份代码实现进行了一定的修改,可以再1。0的版本上运行。代码后续会放到我的github上面,欢迎查看。在服务器上跑需要四五天的样子,现在还没跑完==下图是结果截图: