查看原文
其他

前沿重器[7] | 小布助手登顶百度千言短文本相似度的秘诀

机智的叉烧 CS的陋室 2022-08-08
 

【前沿重器】


栏目主要给大家分享各种大厂、顶会的论文和分享,从中抽取关键精华的部分和大家分享,和大家一起把握前沿技术。具体介绍:仓颉专项:飞机大炮我都会,利器心法我还有


往期回顾

来自我们自己团队的工作,经过长时间的研发,登顶了百度千言,必须给赞。文章在这里:https://mp.weixin.qq.com/s/6VqFTj2MVF24yF2KwPOcpQ。排行榜如下:

今天我就来和大家一起学习这篇文章,这篇文章不仅仅聚焦于比赛本身,还分享了大量有关语义相似度的操作,虽然立场来看觉得我是在做广告,但我还是要说,想要了解语义相似度的同学,建议大家熟读并背诵全文!

另外补充一点,我自己并未参与到本项目中,只能对文章本身进行基于个人理解的解读,有问题欢迎讨论。

短文本相似度背景

相似度问题应该是NLP领域一个非常经典的问题了,该问题已经在闲聊对话、智能问答、搜索推荐被广泛应用,这些场景下出现的大部分文本都是短文本,而短文本的语义理解相比长文本,又有一定的特色问题,因此需要有针对性的进行解决。

  • 短文本的上下文信息少,上下文依赖大的文本基本用不了。
  • 口语化句子较多,变化也较大,可能会存在信息缺失。
  • 句式、关键词、语序等信息较为关键,对句子整体信息的把握要求较高。

主流方案

根据具体的场景、问题的特异性,主流方法其实非常多,不应该聚焦于其中几个方法,而是应该在吸收足够多的方式下因地制宜的选择,文章主要分为无监督和有监督进行讨论。

无监督

我们深知有监督学习的效果好于无监督,但是有监督学习需要的标注数据并非什么时候多有,为了快速有一个初步的版本,无监督学习仍有学习了解的必要。

最直接能够想到的方式就是word2vector,这个东西的出现应该说是NLP的一个里程碑级别的产物了,通过将句子中的每个词都向量化后,再用池化等方式即可得到句子的向量表征,该表征就可以直接用余弦或者欧氏距离。简单的好处就是简单,别的没啥好处了,泛化能力虽然有且比tf-idf之类的要高不少,但问题是这个泛化能力其实没有想象中那么的高,其实只是词汇进行了简单的表征而已,哪怕是同义词其实相似度也不会很高。

当然还出现了ELMO之类的复杂度更高,灵活性更强的语言模型,但bert相信更容易为人们所熟知,但是实验表明bert的效果可能不如GloVe之类的模型,文章指出该模型的的MLM任务对词频敏感,本身不是为了语义匹配设计的,高频词效果还行但是低频词的表征并不准确,且会出现一些“HOLE”,导致相似度出现一些偏差,为了解决该问题,bert-flow能将bert的语义空间映射到标准搞死空间,使之更加均匀。

有监督

有监督应该是本领域的主流,但是由于场景的应用,可以划分为两种形式,表征式和交互式。说起这两个概念,其实可以用游戏“找不同”来理解,表征式其实是让模型先看完一张图片在看另一张,就要说出两者的不同之处,而交互式则可以让你随时切换看第一张图和第二张图,反复比对,显然第二种难度较小,准度较高但是第二种仍有存在的必要。

表征式效果不如交互式,但是的确有非常明确地应用场景,就是召回,现在的召回很多都是采用向量召回的形式,离线阶段训练好模型,并把一批query进行向量化后存入向量索引,在线来了一个新的query后同样进行向量化,然后通过向量索引找到距离新query最接近的那个入库的query(最近邻相似)。这种形式就约束了两个个匹配的句子只有一次见面机会,这次见面机会就要直接出相似度了,因此交互匹配不可行。常用的网络就是孪生网络,简单的就是CBOW,当然还能换各种积木,如cnn、lstm之类的。由于NLP的特异性,两个输入都是句子,所以可以用同一个模型进行表征。

表征型

交互型更多用在召回后的排序阶段,简单实用可以是直接考虑语义从而直接用语义相似度直接排序,当然在搜索之类的场景下,可能有更多的特征,此时可以把语义相似度作为特征之一,综合起来做排序。重点还是聚焦在交互式,交互式可以在预测阶段范式对q1和q2进行特征的交互,如ABCNN、ESIM等,就是交互式语义相似度计算的代表方法。

ESIM

当然,要聊主流方案肯定要提大规模预训练模型的使用,bert是一个里程碑式的工作,后续也有roberta、albert、ernie等等,虽然这些东西的确在性能上有很大问题,但是效果是真的好,至少在语义理解的能力上有了质的提升,后续相信有更多工作让这些大家伙能走入寻常百姓家。

业务应用

在现实应用中,往往需要考虑到更多问题,智能问答的基本结构和我之前提的很多场景类似——“召回+排序”,这个思路的讨论我专门整了一篇文章来总结,此处看看小布助手闲聊这块的处理逻辑:


表征和召回

相似度上,核心就在于离线需要训练一个足够靠谱的语义相似度模型,这块非常机智的参考了人脸识别的一些思路,大家可以细品,人脸识别的任务是给定一张脸,需要找库里面最接近的一个还要评估相似度,向量召回的任务是给定一个query找与之最接近的,然后评估相似度,实质上这两者都是一个表征的问题,我们希望语义相似的句子能分布在一个比较集中的空间内,而语义不同的则能差的足够远,按照人脸识别领域的经验,通过损失函数引导模型往这方面学,则有很大的收益了。如果只是平行样本(q1,q2,label),那训练起来信息不够,参考DSSM的思路(说实话,DSSM给这块真的提供了和很多思路,不能仅要关注模型本身),可以1个anchor,若干正负样本(对比anchor)来构成一串输入样本,来进行计算,更有好处,即有了对比,A和B是相似,和C是不相似,那我们可以很有把握地定位好A的位置,从而训练好模型,这个对比,则借助损失函数来进行引导,文章中提到的几个分别是ASoftmax、AMSoftmax、ArcFace,建议大家可以去看看论文,他们的核心思路是各一个margen让相似的和不相似的弄一段距离出来。

具体上面提到的几个损失函数的设计,大家可以去参考论文,脉络和文章内容还是挺明确的,这里给大家看看这几个方法划分的空间是什么样的:

交互和排序

上面已经提到,交互相比表征型效果更好,但是受限性能,只能先用召回缩小范围然后再来做交互的相似度计算,排序阶段我们就有机会做这个事情了。

根据文章,小布助手内部其实使用了ABCNN、ESIM等操作,但是依旧打不过bert等预训练模型,团队内进行了一些列操作研发了Xbert,列举一下这里面涉及的操作:

  • 融入自研知识图谱数据。
  • WWM、DAE、Entity MLM等与训练任务。
  • LAMB优化器。
  • 蒸馏用于线上推断。(这应该是目前把大规模预训练模型落地上线的最佳方式了,建议学习)

有好的东西肯定是可以尝试和前沿的大佬们比划比划,在多个数据集上其实都有不错的效果,值得高兴的是在百度举办的千言文本相似度比赛中成功登顶。

大佬们的强大的气息迎面扑来,我只能在旁瑟瑟发抖,给项目相关的大佬们点赞!

小结

近期的确是要进行一些语义相似度的调研的,这篇文章给了我很大的思路启发,虽然通篇没太多的公式和具体细节,但是其实给出了很多深入研究的方向,向量表征、损失函数优化、样本处理思路等,我这里进行了很多的阉割,也给了一些自己的思考,如果有什么新的想法,欢迎大家讨论。


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存