SQuAD 数据集包含 10 万个(问题,原文,答案)三元组,原文来自于 536 篇维基百科文章,而问题和答案的构建主要是通过众包的方式,让标注人员提出最多 5 个基于文章内容的问题并提供正确答案,且答案出现在原文中。即在给定文档D,给定问题Q的情况下,答案A是D中的一个text span。
在微软官方文章(从短句到长文,计算机如何学习阅读理解)中讲明了机器阅读理解是自然语言处理任务中难度系数较高的一个,如SQuAD问题和答案具有非常丰富的多样性。这五个问题中可能涉及文章中的某一个人,某一个地点,或是某一个时间等等实体;也有可能会问一些为什么(Why)、怎么样(How)的问题。后者的答案可能实际上是一句话,甚至是一小段话,因此解决这个问题只会更加棘手。
1、基本原理
今天实践的算法是微软提出的r-net,其架构如下所示:
该模型也就分为这样的四层。
(1)最下面的一层做表示学习,就是给问题和文本中的每一个词做一个表示,即深度学习里的向量。这里研究组使用的是多层的双向循环神经网络。从图上可以看出,它在做Embed 的时候同时使用了 word 和 char 两种 embedding 以丰富输入特征,从而可以较好地解决一些问句中不同表述形式的关系。
(2)将问题中的向量和文本中的向量做一个比对,这样就能找出那些问题和哪些文字部分比较接近。
(3)将这些结果放在全局中进行比对。这些都是通过注意力机制(attention)达到的。
其中(2)和(3)两步是门控卷积网络+注意力机制来实现的,对原文中每个词,计算其关于问题的注意力分布,并使用该注意力分布汇总问题表示,将原文该词表示和对应问题表示输入 RNN 编码,得到该词的 query-aware 表示。不同的是,在原文词表示和对应问题表示输入 RNN 之前,r-net 使用了一个额外的门来过滤不重要的信息。
(4)针对挑出的答案候选区中的每一个词汇进行预测,哪一个词是答案的开始,到哪个词是答案的结束。这样,系统会挑出可能性最高的一段文本,最后将答案输出出来。整个过程就是一个基于以上四个层面的神经网络的端到端系统
2、实践测试
找了一个开源代码https://github.com/unilight/R-NET-in-Tensorflow,进行编译,环境为tensorflow 1.3, python3.6,对源代码进行适应性地修改到python3.0的环境下。
(1)数据预处理
执行preprocess.py --gen_seq True
执行完,可以看到data目录下已经得到了预处理后的数据结果。
(2)训练
修改代码,进行训练。
(3)测试
这个代码不是微软公开的,也只是单个模型,效果ExactMatch (EM) and F1 scores分别为57%和71%,离微软最终的集成模型还有一定的距离 。