写在前面

大家好,我是刘聪NLP。
今天给大家带来一篇ACL2022论文DCSR,面向开放域段落检索的句子感知的对比学习,通过引入「段落内负例抽样策略」,使得同一段落内容中生成「不同得句子表征」,构建一个基于更小粒度得上下文句子表征模型,从而解决在对比学习训练过程中,将同一个段落向量与多个语义差异较大问题向量对应的冲突问题,论文全称《Sentence-aware Contrastive Learning for Open-Domain Passage Retrieval》。
paper地址:https://aclanthology.org/2022.acl-long.76.pdf

code地址:https://github.com/chengzhipanpan/DCSR

介绍

对比学习技术在检索任务中已经取得了较好的效果,而对比学习的宗旨就是拉近相似数据,推开不相似数据,有效地学习数据表征。
在检索任务中,通常正例样本为问题query对应的正确段落,而通过BM25等方法构建一些难负例,通过问题query靠近正例样本,远离负例样本,获取更好的问题和段落的向量表征。
但是目前的对比学习框架,都忽略了一个至关重要的问题,如下图所示,每一个段落由多个句子组成,而每个句子对应的问题可能在语义上差别很大。这种一对多的关系,造成了学习过程中的冲突:
  • 「相似性传递」:对比学习框架的目标是使问题的向量表征与其对应的黄金段落的向量表征之间的相似性最大。而这种一对多的关系,会造成同一个段落中语义差异很大的不同问题之间的向量表征极其相似。
  • 「样本即正亦负」:对比学习框架中大批次是一个很重要的参数,而这种一对多的关系,会造成一个批次中包含同一个段落对应的多个问题,导致一个段落对于相同问题即使正样本也是负样本。
    为了解决上述冲突问题,该篇论文提出一种简单有效的策略,将段落的向量表示分解为多个具有上下文语义的句子级向量表示,详细如下。

模型

模型结构如上图所示,用两个预训练模型分别对问题query和段落内容passage进行编码,在每个段落中句子前插入一个特殊的<sent>标记。并且,「为了保留文本上下文的信息」,将段落内容作为一个整体输入到编码器中进行编码,<sent>取标记对应的向量作为句子向量。

正例获取

对于给定问题,在批次内的正段落为,包含多个句子,
其中,包含答案的句子作为训练的正例。

简单负例获取

通过BM25技术,针对问题从检索库中,找到与其相关的负段落,并且每个段落包含多个句子,
一部分简单负例从中随机抽取,一部分简单负例使用批次内其他句子。

段落内负例获取

由于希望编码器可以使同一段落中的不同句子尽可能具有不同的上下文句子表征,并且一个段落中并非所有的句子都包含答案或者与查询问题相关,因此引入段落内负例,以最大限度地提高同一段落中上下文句子向量表征的差异。
即,在正段落中,随机抽取一个不包含答案的句子。如果正段落不包含这样的句子,则从中随机抽取一个简单负例做代替。

检索排序

在检索中,计算问题向量和所有上下文句子向量之间的匹配分数,由于一篇段落中有多个句子,因此检索了前个句子进行排序,其中是所有段落中句子个数的平均数。
由于最终排序结果需要展现段落排序,因此需要将上述句子级别的分数转换为段落级别的分数。先采用Softmax函数对分数进行归一化,然后对于每篇段落的分数变换如下:
其中,为前个句子中在某个段落中句子的集合,为每个句子对应的概率值。
最终,按照每个段落的值进行重排序,获取真正的检索排序。

实验结果

针对SQuAD、TriviaQA和NQ数据进行分析,发现一对多现象越明显的数据,使用DCSR进行排序的效果越好。如下表所示,SQuAD平均一个段落对应2.66个问题,DCSR的效果相较于DPR的效果提升最大。
并且,加入段落内负例,效果相较于仅使用BM25检索得到的负例有较大的提升。
采用DCSR方法的迁移性,相较于DPR也是较好的。

总结

该论文在没有增加其他额外计算的情况下,检索时通过句子级排序推理出段落级排序。并且放大同一段落中的不同句子的表征,解决了一对多时产生的相似性传递并且减少了噪音。为了使得段落间的句子可以获取相互之间的信息,使用特殊字符获取句向量,而非将每个句子独立编码。
在真实场景下,其实这种思路也比较常见,我们在对文档进行排序时,往往通过先排序段落,再排序文档。并且这种分数换算的方式也不错,可以尝试。
请多多关注知乎「刘聪NLP」,有问题的朋友也欢迎加我微信「logCong」私聊,交个朋友吧,一起学习,一起进步。我们的口号是“生命不止,学习不停”。
往期推荐:
继续阅读
阅读原文