Press "Enter" to skip to content

万能的seq2seq:基于seq2seq的阅读理解问答

今天给 bert4keras 新增加了一个例子:阅读理解式问答( task_reading_comprehension.py ),语料跟之前一样,都是用WebQA和SogouQA,最终的得分在0.75左右(单模型,没精调)。

 

由于这次主要目的是给bert4keras增加demo,因此效率就不是主要关心的目标了。这次的目标主要是通用性和易用性,所以用了最万能的方案——seq2seq来实现做阅读理解。

 

用seq2seq做的话,基本不用怎幺关心模型设计,只要把篇章和问题拼接起来,然后预测答案就行了。此外,seq2seq的方案还自然地包括了判断篇章有无答案的方法,以及自然地导出一种多篇章投票的思路。总而言之,不考虑效率的话,seq2seq做阅读理解是一种相当优雅的方案。

 

这次实现seq2seq还是用UNILM的方案,如果还不了解的读者,可以先阅读 《从语言模型到Seq2Seq:Transformer如戏,全靠Mask》 了解相应内容。

 

用UNILM方案搭建一个seq2seq模型在bert4keras中基本就是一行代码的事情,所以这个例子的主要工作在并不在模型的建立上,而是在输入输出的处理上面。

 

首先是输入,输入格式很简单,一张图可以表达清楚:

 

 

用seq2seq做阅读理解的模型图示

 

如果输入单个篇章和单个问题进行回答,那幺直接按照seq2seq常规的处理方案——即beam search——来解码即可。

 

但是,WebQA和SogouQA面对的是搜索场景,即同时存在多篇文章来对同一个问题进行回答,这就涉及到投票方案的选择了。一种朴素的思路是:每个篇章结合问题单独用beam search解码,并且给出置信度,最后再按照 《基于CNN的阅读理解式问答模型:DGCNN》 的投票方式进行。这种方式的困难之处在于对每个答案给出一个合理的置信度,它相比我们后面给出的思路则显得不够自然,并且效率也稍低些。

 

这里我们给出一种跟beam search更加“契合”的方案:

 

先排除没有答案的篇章,然后在解码答案的每一个字时,直接将所有篇章预测的概率值(按照某种方式)取平均。

 

具体来说,所有篇章分别和问题拼接起来,然后给出各自的第一个字的概率分布。那些第一个字就给出[SEP]的篇章意味着它是没有答案的,排除掉它们。排除掉之后,将剩下的篇章的第一个字的概率分布取平均,然后再保留topk(beam search的标准流程)。预测第二个字时,每个篇章与topk个候选值分别组合,预测各自的第二个字的概率分布,然后再按照篇章将概率平均后,再给出topk。依此类推,直到出现[SEP]。(其实就是在普通的beam search基础上加上按篇章平均,如果实在弄不明白,那就只能去看源码了~)

 

此外,生成答案的方式应该有两种,一种是抽取式的,这种模式下答案只能是篇章的一个片段,另外一种是生成式的,即不需要考虑答案是不是篇章的片段,直接解码生成答案即可。这两种方式在本文的解码中都有相应的判断处理。

 

代码链接: task_reading_comprehension.py

 

最终在 SogouQA自带的评估脚本 上,valid集的分数大概是0.75,单模型成绩轻松超过了之前的 《开源一版DGCNN阅读理解问答模型(Keras版)》 模型。当然,提升是有代价的——预测速度大大降低,每秒只能预测2条数据左右。

 

(模型没精细调优,估计还有提升空间,当前还是以demo为主。)

 

本文主要是给出了一个基于bert和seq2seq思路的阅读理解例子,并且给出了一种多篇章投票的beam search策略,供读者参考和测试~

 

转载到请包括本文地址: https://kexue.fm/archives/7115

 

更详细的转载事宜请参考: 《科学空间FAQ》

 

如果您还有什幺疑惑或建议,欢迎在下方评论区继续讨论。

 

如果您觉得本文还不错,欢迎/本文。打赏并非要从中获得收益,而是希望知道科学空间获得了多少读者的真心关注。当然,如果你无视它,也不会影响你的阅读。再次表示欢迎和感谢!

 

如果您需要引用本文,请参考:

 

苏剑林. (2019, Dec 05). 《万能的seq2seq:基于seq2seq的阅读理解问答 》[Blog post]. Retrieved from https://kexue.fm/archives/7115

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注