社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  机器学习算法

21个经典深度学习句间关系模型|代码&技巧

机器学习算法与自然语言处理 • 4 年前 • 363 次点击  

公众号关注 “ML_NLP

设为 “星标”,重磅干货,第一时间送达!

转载自 | 李rumor


卷友们好,我是rumor。

鸽了很久的NLP入门系列终于在我的努力下又更新了。

上次聊了分类任务的模型与技巧,今天我们就来聊聊句间关系任务。句间关系的输入是一对文本,输出是文本间的关系。常用的判别有语义相似度、语义关系推理(蕴含/中立/矛盾)、问答对等,拿GLUE榜单来说,其中有6个(QQP/MNLI/QNLI/STS/RTE/MRPC)都是句间关系任务。这个任务的应用场景也很广泛,比如搜索推荐的语义相关性、智能问答中的问题-问题、问题-答案匹配、知识图谱中的实体链接、关系识别等,是成为NLPer必须卷的一个方向。

在深度学习中,文本匹配模型可以分为两种结构:双塔式和交互式

双塔式模型也称孪生网络、Representation-based,就是用一个编码器分别给两个文本编码出句向量,然后把两个向量融合过一个浅层的分类器;交互是也称Interaction-based,就是把两个文本一起输入进编码器,在编码的过程中让它们相互交换信息,再得到最终结果。如下图:

两种框架比较的话,交互式通常准确率会高一些,毕竟编码器能使用的信息更多了,而双塔式的速度会快很多,比如线上来一个query,库里有一百万个候选,等交互式算完了用户都走了,但双塔式的候选可以提前计算好,只用给query编码后去和候选向量进行浅层计算就好了。工程落地的话,通常会用双塔式来做召回,把一百万个候选缩减为10个,再对这10个做更精细的计算。

所以说这两种方式都是实际应用中必不可缺的,两个方向也都有着不少的模型:

下面我们就先讲讲双塔式模型的SOTA发展。这里面通常有三个点可以优化:encoder、merged_vec、classifier,大部分研究都在专注提升encoder的能力。我个人主要将双塔的发展分为词袋、有监督、预训练+迁移三个阶段。

词袋句向量

最简单的就是直接从词向量计算句向量。首先可以用mean、max池化,相比字面n-gram重合度肯定是有提升的。但当句子中的噪声多起来之后,如果两个句子有大量重合的无意义词汇,分数也会很高,这时候就可以考虑加权求和,比如TF-IDF。

SIF

题目:A SIMPLE BUT TOUGH-TO-BEAT BASELINE FOR SENTENCE EMBEDDINGS
论文:https://openreview.net/pdf?id=SyK00v5xx
代码:https://github.com/PrincetonML/SIF

ICLR2017论文SIF提出了名为smooth inverse frequency的方法,先由词向量加权平均得到句向量,再对多个句子组成的句向量矩阵进行PCA,让每个句向量减去第一主成分,去掉“公共”的部分,保留更多句子本身的特征。该方法在相似度任务上有10%-30%的提升,甚至超过了一些RNN模型,十分适合对速度要求高、doc相似度计算的场景。

WMD

题目:From Word Embeddings To Document Distances
论文:http://proceedings.mlr.press/v37/kusnerb15.pdf
代码:https://github.com/mkusner/wmd

之前提到的相似度任务都适用cosine相似度衡量的,也有学者研究了其他metric。2016年的WMD提出了Word Mover's Distance这一概念,用句子A走到句子B的最短距离来衡量两者的相似程度。表示在下图中就是非停用词的向量转移总距离:

上面介绍的两篇文章使用的都是word2vec向量,但实际操作中我推荐使用fasttext(就是加上ngram,但仍用word2vec结构训练),一方面ngram可以增加信息,另一方面也避免了OOV。

千万不要小看词向量,用好了真的是很强的baseline。另外现在很多线上场景因为对速度要求高,或者是toB的业务甲方不愿意买GPU,有不少落地都停留在这个阶段。

有监督句向量

词向量虽然可以经过处理变成句向量,但词袋式的融合也会丢失掉顺序信息,同时在训练时其目标还是word-level的,想要获得「真正的句向量」,还是需要寻找sentence-level的目标函数。

DSSM

题目:Learning Deep Structured Semantic Models for Web Search using Clickthrough Data
论文:https://www.microsoft.com/en-us/research/publication/learning-deep-structured-semantic-models-for-web-search-using-clickthrough-data/
代码:https://github.com/InsaneLife/dssm

微软在2013年提出的CIKM论文DSSM是相当知名的多塔模型,它对文本进行word hash(也就是表示成ngram,减少词表数),再将ngram转成向量再平均得到句向量,经过三层MLP得到128维的编码,用cosine相似度作为每个Q-D对的分数,经过sofamax归一化后得到P(D|Q),最终目标为最大化正样本被点击的概率。

但BOW式的词向量平均会损失上下文信息,所以之后也有学者提出了CNN-DSSM、LSTM-DSSM,基本上结构都差不多。

Siam-CNN

题目:Applying Deep Learning to Answer Selection: A Study and An Open Task
论文:https://arxiv.org/pdf/1508.01585.pdf

在2015年IBM提出的Siam-CNN架构中,作者尝试了多种孪生架构,使用CNN作为基础编码器,pairwise loss作为损失函数,最后实验发现第二种是最好的:

说实话这个结果有点迷,Query和Answer的表达还是略有不同的,经验上看我觉得第三个结构更靠谱些。不过作者只在一种数据集上进行了尝试,或许换个数据集结果会有变化。

Siam-LSTM

题目:Siamese Recurrent Architectures for Learning Sentence Similarity
论文:http://www.mit.edu/~jonasm/info/MuellerThyagarajan_AAAI16.pdf

2016年的Siam-LSTM在结构上比较简单,就是直接用共享权重的LSTM编码,取最后一步的输出作为表示。有个改进点是作者使用了Manhattan距离计算损失:

后续还有一些模型改成双向、char-level的,这里就不过多赘述了。

Multi-View

题目:Multi-view Response Selection for Human-Computer Conversation
论文:https://www.aclweb.org/anthology/D16-1036.pdf

百度的EMNLP2016论文针对多轮对话问题,提出了Multi-view的Q-A匹配方式,输入的query是历史对话的拼接,分别编码了word sequence view和utterance sequence view两种表示。词级别的计算和Siam-LSTM差不多,都是用RNN的最后一步输出做Q-A匹配,而句子级别的会对RNN每步输出做max pooling得到句子表示,然后再将句子表示输入到GRU中,取最后一步作为带上下文的表示与回答匹配,如下图:

融合了两个level的匹配后比普通方法的R@1要好上4-6个点,提升很明显。

预训练+迁移

有监督、领域内的语料总是有限的,目前很多任务都开始转向预训练+迁移的范式。

Skip-Thought

题目:Skip-Thought Vectors
论文:https://arxiv.org/pdf/1506.06726.pdf
代码:https://github.com/ryankiros/skip-thoughts

多伦多大学的NIPS2015论文Skip-Thought提出了一种无监督句向量训练方法,参考wrod2vec,一句话与它的上下文也是存在关联的,因此我们可以用一个句子的编码去预测它的上下句:

Skip-Thought用GRU作为编码器,条件GRU作为解码器,预测时候只用编码器就可以得到句子表示。

但这种方法训出的decoder不用比较浪费,后续也有学者用同样的思想改成了判别任务,比如Quick-Thought对句子分别编码,过分类器选择上下文,又或者BERT中的NSP,或者ALBERT的SOP。

FastSent

题目:Learning Distributed Representations of Sentences from Unlabelled Data
论文:https://www.aclweb.org/anthology/N16-1162.pdf
代码:https://github.com/fh295/SentenceRepresentation/tree/master/FastSent

2016年的FastSent主要对Skip-Thought的速度进行了改进,其实就是用词袋模型去替换RNN编码,再用中间句子的表示去预测上下文的词。同时也提出了一个FastSent+AE变体,预测目标也加上了自身的词。

最终效果在无监督任务上好于Skip-Thought,但有监督任务上还是略逊色。

InferSent

题目:Supervised Learning of Universal Sentence Representations from Natural Language Inference Data
论文:https://www.aclweb.org/anthology/D17-1070.pdf
代码:https://github.com/facebookresearch/InferSent

前几篇可迁移的encoder都是无监督的,因为学者们一直没有发现更通用的数据,直到InferSent。

EMNLP2017中Facebook提出了InferSent,文中使用NLI数据集来预训练双塔结构,超越了之前众多无监督方法。该文章用了很简单的双塔结构,但在计算loss时先对两个向量用了多种方式融合,再过分类器。同时也提出了多个基于RNN、CNN的编码器,最后实验发现BiLSTM+Max效果最好,在评估的10个任务中有9个达到了SOTA。

InferSent提出的结构到现在还用很多同学在用,包括后文的Sentence-BERT(19年的SOTA)也只是换了个编码器而已。同时用NLI来做预训练这个点也很重要,优质语料对模型提示有很大帮助

后续也有模型进行了小改进,比如2017年的SSE,使用3层堆叠BiLSTM+Shortcut,效果比InferSent好一些。

GenSen

题目:Learning General Purpose Distributed Sentence Representations via Large Scale Multi-task Learning
论文:https://arxiv.org/abs/1804.00079
代码:https://github.com/Maluuba/gensen

同样是提升可迁移性,微软在ICLR2018上提出了GenSen,使用GRU编码,将encoder下游接上4种不同的任务(预测上下文、翻译、NLI、句法分析),但只在6/10个任务上超越了之前的模型,个别情况下增加新的任务还会使效果下降。

这种多任务的思想后续也被用在其他模型上,比如MT-DNN(狗头。

USE

题目:Universal Sentence Encoder, Learning Semantic Textual Similarity from Conversations
论文:https://arxiv.org/pdf/1803.11175v1.pdf, https://arxiv.org/pdf/1804.07754.pdf

谷歌在ACL2018提出了USE模型,这也是引用量很高的一篇文章(但写的不是很清楚,推荐读第二篇),主要改进如下:

  1. 提出了用Transformer和平均池化+MLP作为encoder,分别适用不同的场景
  2. 爬取了大量reddit的问答数据,用于无监督Q-A训练,因为query和answer的表示空间不一样,结构上给answer多加一层DNN。并且在问答任务上使用batch negative策略,也就是除了对应的正确答案外batch内剩下的样本都作为负例,用softmax计算P(A|Q)的概率,跟现在对比学习的loss一样。
  3. 多任务,在无监督训练Q-A的同时也用SNLI进行有监督训练

这样训练出的模型比InferSent高3-5个点,效果很好。现在这个模型也在一直更新,可以在TFhub上使用,不仅速度快,效果也没比BERT系差太多。

Sentence-BERT

题目:Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks
论文:https://arxiv.org/pdf/1908.10084
代码:https://github.com/UKPLab/sentence-transformers

EMNLP2019的Sentence-BERT是目前最常用的BERT式双塔模型,一是效果真的好,二是作者的开源工具做的很方便,用的人越来越多。结果其实就是把InferSent改成BERT编码,训练语料也不变,做离线任务可以直接用起来。

BERT-flow

题目:On the Sentence Embeddings from Pre-trained Language Models
论文:https://arxiv.org/pdf/2011.05864.pdf
代码:https://github.com/bohanli/BERT-flow

字节在EMNLP2020提出了BERT-flow,主要是基于Sentence-BERT做改动,因为之前的预训练+迁移都是使用有监督数据,而作者基于对原生BERT表示的分析发现,那些表示在空间的分布很不均匀,于是使用flow-based生成模型将它们映射到高斯分布的均匀空间,比之前的Sentence-BERT提升了4个点之多。

但这个模型的缺点是又加了一层机制,在预测时候会降低速度,同时在知乎上看到个别同学在自己任务上的试用反馈也不太好。不过我倒是验证了SentEval上有监督的效果(论文只给了无监督的),效果跟Sentence-BERT差不多。

Cross-Thought

题目:Cross-Thought for Sentence Encoder Pre-training
论文:https://arxiv.org/abs/2010.03652
代码:https://github.com/shuohangwang/Cross-Thought

微软在EMNLP2020提出了Cross-Thought,先用transformer对每个句子编码,再取多个CLS(红点部分)作为句子表示再进行attention,得到一个整体的上下文表示,再回头去预测每个句子被mask的token。相比起NSP来说,该任务的解空间更丰富,相比单纯的BERT表示提升明显,在QA任务上更是提了几十个点。

对比学习

对比学习是20年图像领域火热的表示预训练方法,在训练时会给输入A生成一个数据增强版本B,经过编码器对A和B编码后,如果两个表示还是最接近的(batch内分类),就说明这个编码器抓住了用于区分A与其他样本的本质特征。对比学习目前在NLP领域还没开始大放异彩,从20年下半年的一些新论文来看,在预训练过程、精调中加入对比损失都会轻微提升模型效果并增强鲁棒性、小样本场景的表现。相信用对比做出的优秀文本表示不久就会出现。

!!!我是朋克风分割线!!!

上文讲了众多双塔模型,其主要的重点都在编码器的优化,对速度要求高的召回场景可以用BOW+MLP、CNN,精度要求高的排序场景可以用LSTM、Transformer。同时两个向量的融合方法以及loss也都可以优化,比如做一些轻微的交互、像Deformer一样前面双塔接后面的多层交互,或者根据需要选择pointwise、pairwise(排序场景)损失。

但真要想做句间关系SOTA的话,比如刷榜,光靠双塔模型还是不行的,它有两个问题比较大:

  1. 位置信息。如果用BOW的话“我很不开心”和“我不很开心”两句的意思就变成一样了,虽然用RNN、BERT引入位置编码可以减缓一些,但不去让两个句子相互比较的话对于最后的分类层还是很难的
  2. 细粒度语义。比如“我开心”和“我不开心”这两句话只有一个字的区别,但BOW模型很可能给出较高的相似度,交互式模型则可以稍有缓解

交互式匹配

比起双塔只能在encoder上下功夫,交互式模型的套路就多多了,其核心思想是将两个句子逐个词比较。比如判断“进击的巨人”和“进击的矮子”语义是否相同时,前三个字在两句话中都能找到,而第二句里没找到跟“巨人”接近的,那分数就会被降低一些。因此得让两个句子有interaction,一般用attention解决,因为没那么在意速度了,在交互前后都可以加encoder,再让向量拼接、做差、点积。。。不说了,请开始让它们表演。

DecAtt

题目:A Decomposable Attention Model for Natural Language Inference
论文:https://arxiv.org/pdf/1606.01933.pdf

Google在EMNLP2016提出了轻量级的交互模型DecAtt,作者的出发点是让句子中的各个元素相互对比,找出词级别的同义和反义。分为三步计算:

  1. Attend:将两个句子中每对次 相互attention,加权后得到对齐的
  2. Compare:将 分别拼接,过一层FFN得到
  3. Aggregate:分别将第二步得到的表示求和得到 ,拼接起来进行分类

比较难懂的主要是第二步,作者的解释是经过第一步attend后可以将问题拆解为子问题,再通过每个词向量的compare解决。

这个模型的缺点是最后一步求句向量时用了求和操作,如果序列过长的话数值会较大,造成梯度大,需要裁剪。但计算还是很轻量的,从结果来看跟LSTM差不多。

MatchPyramid

题目:Text Matching as Image Recognition
论文:https://arxiv.org/pdf/1602.06359.pdf
代码:https://github.com/pl8787/MatchPyramid-TensorFlow

计算所在2016AAAI发表的MatchPyramid主要受图像处理的启发,先对词进行交互得到Matching矩阵,然后通过多层2D卷积抽取更高维度的特征,最后得到表征用MLP分类。作者凭借此模型在2017年的Quora Question Pairs比赛上拿到了全球第四。

相比上文的DecAtt,MatchPyramid通过CNN捕获到了ngram特征。从结果看比DSSM等模型高出了3、5个点。

PWIM

题目:Pairwise Word Interaction Modeling with Deep Neural Networks for Semantic Similarity Measurement
论文:https://www.aclweb.org/anthology/N16-1108.pdf
代码:https://github.com/lanwuwei/Subword-PWIM

ACL2016的PWIM模型主打细粒度交互,模型非常的深,分为以下四个计算步骤:

  1. Context Modeling:用BiLSTM对输入编码
  2. Pairwise Word Interaction Modeling:作者定义了一个对比向量的函数coU(包含cosine、点积、欧式距离),对两句话的词进行两两比较,总共计算了前向向量、反向向量、前后向拼接、前后向相加四种表示的coU,作者将输出称为simCube
  3. Similarity Focus Layer:提出了一个算法,根据simCube的分数排序,计算出一个mask矩阵,其中重要元素的权重是1,非重要为0.1。作者认为如果句子A中的某个词在句子B中也找到了,那这就是一个衡量两者相似度的重要指标。最终mask和simCube相乘得到focusCube
  4. Deep ConvNet:作者把前面产出的三维矩阵看作图像,用19层卷积神经网络的到最后的表征,再过softmax分类

这篇文章真的是花式计算,虽然从结果来看超过了双层BiLSTM 2、3个点,但这计算复杂度让人难以承受。在后文也会被ESIM超越,所以就别用了,当做多学习一些思想吧~

ESIM

题目:Enhanced LSTM for Natural Language Inference
论文:https://www.aclweb.org/anthology/P17-1152.pdf
代码:https://github.com/coetaur0/ESIM

ACL2017中的ESIM也是效果很好的模型,基于DecAtt改动,在两句话交互融合后又加了一层BiLSTM,将效果提升了1-2个点。同时也尝试使用句法树进一步提升效果。它的计算过程有一下四步:

  1. 用BiLSTM对embedding编码,得到表示
  2. 将两句话的BiLSTM输出进行attention,得到融合的句子表示
  3. 拼接作为新表示,用BiLSTM进行推理
  4. 池化后过进行最终分类

DIIN

题目:Natural Language Inference over Interaction Space
论文:https://arxiv.org/pdf/1709.04348.pdf
代码:https://github.com/YerevaNN/DIIN-in-Keras

ICLR2018的DIIN看起来像PWIM一样花式,比ESIM高出5、6个点。主要有以下改动:

  1. 在embedding层除了使用词向量,还使用了字向量、词性特征和英文词根的完全匹配特征
  2. 使用Self-Attention编码

HCAN

题目:Bridging the Gap Between Relevance Matching and Semantic Matching for Short Text Similarity Modeling
论文:https://cs.uwaterloo.ca/~jimmylin/publications/Rao_etal_EMNLP2019.pdf
代码:https://github.com/jinfengr/hcan

HCAN是Facebook在EMNLP2019提出的模型,虽然比上文的ESIM、PWIM等模型高上4+个点,但还是被BERT甩了很远。不过这个模型的核心也不只是做语义匹配,而是同时做检索相关性(Relevance Matching),也就是搜索中query-doc的匹配。

模型计算如下:

  1. Encoding层作者提出了三种方法,堆叠的CNN作为Deep Encoder,不同尺寸卷积核作为Wide Encoder,BiLSTM作为Contextual Encoder编码更长距离的上下文
  2. 先把两句话交互得到attention score矩阵,之后对于query中每个词,求得doc中最相似的词的分数,作为向量Max(S),按照同样的方法求出Mean(S),长度都为|Q|,再分别乘上query中每个词的tfidf统计,得到相关性匹配向量
  3. 用加性attention对query和doc进行交互,得到新的表示,再花式拼接过BiLSTM,得到语义匹配向量
  4. 拼接起来过MLP,最后分类

通过实验结果来看,Deep Encoder的表现是最好的,在7/8个评估上都超过另外两个。

RE2

题目:Simple and Effective Text Matching with Richer Alignment Features
论文:https://www.aclweb.org/anthology/P19-1465.pdf
代码:https://github.com/hitvoice/RE2

RE2是阿里在ACL2019提出的模型,也是很不错的一个工作,优点是模型轻量且效果好。上文虽然很多模型都用到了交互,但只交互1、2次,而RE2则像transformer一样把两句话交互了多次。

计算逻辑是(图中只展示了双塔的一半):

  1. Encoding:对输入进行embedding得到,拼接上之前的输出,用CNN编码
  2. Alignment:把encoder的输入输出拼接起来,两句话进行attention
  3. Fusion:将encoder的输入输出与attention的结果一起融合,得到的表示进入下一循环或max pooling输出句子表示
  4. 将两个句子表示各种拼接后进行分类

这个模型除了多次交互之外,还有个点是一直都把最初的embedding拼接上,从消融实验看可以提升1-6个点。

!!!我是朋克风分割线!!!

一口气讲了7个交互式匹配模型,感觉自己都不会爱了。其实大部分都是为了解之前的思想,因为现在无脑用BERT就够了。

同时老司机们也很清楚,模型只是工具,数据才是天花板,数据质量不好/数量不够,模型再花哨也没用。所以这里分享两个数据洗刷刷经验:

  1. 负例的构造。都说句间关系任务负例的构造是很重要的,确实如此。但构造前一定要把正、负界定清楚,明确这个任务的粒度有多细。比如“我很不开心”和“我不太开心”都是不开心,但程度不一样,在自己的任务中到底是算正例还是负例呢?这个界定的越清楚、标注人员培训越到位,数据噪声也就越少。之后才是尽量构造有难度的负例,比如用BOW召回一些再人工标注,让样本们越来越逼近分类边界
  2. 数据增强。交互式模型虽然准确,但他们有个缺点是容易过拟合,因为对“交互”看得太重了。比如一对正例里只有一两个字一样,模型可能就会认为这两个字很重要,有些overlap超低的文本对也会给出高得分。这时候就要对正例进行清洗,看看特殊情况是否存在,再尝试用增删改的方法加一些负例,避免过拟合这种极端正例。另外BERT这种交互式模型是不对称的,如果做paraphrase任务也可以镜面构造些新正负例。

总结

可能是文本匹配方面看得比较多吧,终于把我收藏的模型都扒拉出来了,直接像文本分类一样再给大家提供一个选型方案吧:


点击下方卡片,关注公众号“机器学习算法与自然语言处理”,获取更多信息:

下载1:四件套

在机器学习算法与自然语言处理公众号后台回复“四件套”

即可获取学习TensorFlow,Pytorch,机器学习,深度学习四件套!


下载2:仓库地址共享

在机器学习算法与自然语言处理公众号后台回复“代码”

即可获取195篇NAACL+295篇ACL2019有代码开源的论文。开源地址如下:https://github.com/yizhen20133868/NLP-Conferences-Code


重磅!机器学习算法与自然语言处理交流群已正式成立

群内有大量资源,欢迎大家进群学习!


额外赠送福利资源!深度学习与神经网络,pytorch官方中文教程,利用Python进行数据分析,机器学习学习笔记,pandas官方文档中文版,effective java(中文版)等20项福利资源

获取方式:进入群后点开群公告即可领取下载链接

注意:请大家添加时修改备注为 [学校/公司 + 姓名 + 方向]

例如 —— 哈工大+张三+对话系统。

号主,微商请自觉绕道。谢谢!


推荐阅读:

Tensorflow 的 NCE-Loss 的实现和 word2vec

多模态深度学习综述:网络结构设计和模态融合方法汇总

awesome-adversarial-machine-learning资源列表

点击下方卡片,关注公众号“机器学习算法与自然语言处理”,获取更多信息:

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/110152
 
363 次点击