乐趣区

关于人工智能:特定领域知识图谱DKG融合方案技术知识前置一文本匹配算法知识融合方案

特定畛域常识图谱 (Domain-specific KnowledgeGraph:DKG) 交融计划:技术常识前置【一】- 文本匹配算法、常识交融学术界计划、常识交融业界落地计划、算法测评 KG 生产品质保障

0. 前言

本我的项目次要围绕着特定畛域常识图谱 (Domain-specific KnowledgeGraph:DKG) 交融计划:技术常识前置【一】- 文本匹配算法、常识交融学术界计划、常识交融业界落地计划、算法测评 KG 生产品质保障解说了文本匹配算法的综述,从经典的传统模型到孪生神经网络“双塔模型”再到预训练模型以及有监督无监督联结模型,期间也波及了近几年前沿的比照学习模型,之后提出了文本匹配技巧晋升计划,最终给出了 DKG 的落地计划。这边次要以原理解说和技术计划论述为主,之后会缓缓把我的项目开源进去,一起共建 KG,从常识抽取到常识交融、常识推理、品质评估等争取走通残缺的流程。

1. 文本匹配算法综述(短文本匹配)

文本匹配工作在自然语言解决中是十分重要的根底工作之一,个别钻研两段文本之间的关系。有很多利用场景;如信息检索、问答零碎、智能对话、文本甄别、智能举荐、文本数据去重、文本类似度计算、自然语言推理、问答零碎、信息检索等,但文本匹配或者说自然语言解决依然存在很多难点。这些自然语言解决工作在很大水平上都能够形象成文本匹配问题,比方信息检索能够归结为搜索词和文档资源的匹配,问答零碎能够归结为问题和候选答案的匹配,复述问题能够归结为两个同义句的匹配。

  1. 如语言不标准,同一句话能够有多种表达方式;如“股市跳水、股市大跌、股市一片绿”
  2. 歧义,同一个词语或句子在不同语境可能表白不同意思;如“割韭菜”,“领盒饭”,“苹果”“小米”等在不同语境下语义齐全不同
  3. 不标准或谬误的输出;如“yyds”,“绝绝子”“夺笋”“耗子尾汁”
  4. 须要常识依赖;如奥运冠军张怡宁绰号“乒乓大魔王”等。

短文本匹配即计算两个短文本的类似度,通常分成无监督形式、有监督形式、有监督 + 无监督形式

常见的文本匹配算法如下表(简略列举),按传统模型和深度模型简略的分为两类:

算法 类型
Jaccord 传统模型
BM25 传统模型
VSM 传统模型
SimHash 传统模型
Levenshtein 传统模型
cdssm 深度模型
arc-ii 深度模型
match_pyramid 深度模型
mvlstm 深度模型
bimpm 深度模型
drcn 深度模型
esim 深度模型
textmatching 深度模型
bert-base 深度模型
albert-base 深度模型
albert-large 深度模型
raberta 深度模型
sbert 深度模型
DiffCSE 深度模型
ERNIE-Gram 深度模型

1.1 文本匹配传统模型(无监督形式)

文本表征:词袋模型(one-hot、TF)、词向量预训练(word2vector、fasttext、glove)
类似度计算:余弦类似度、曼哈顿间隔、欧氏间隔、jaccard 间隔等

1.1.1 Jaccord 杰卡德类似系数

jaccard 类似度是一种十分直观的类似度计算形式,即两句子分词后词语的交集中词语数与并集中词语数之比。

$\text {jaccard}=\frac{A \bigcap B}{A \bigcup B}$

def jaccard(list1, list2):
    """
    jaccard 类似系数
    :param list1: 第一句话的词列表 
    :param list2: 第二句话的词列表
    :return: 类似度,float 值 
    """
    list1, list2 = set(list1), set(list2) #去重
    intersection = list1.intersection(list2) # 交加
    union = list1.union(list2)  # 并集
    Similarity = 1.0 * len(intersection) / len(union) #交加比并集
    return Similarity

a. 分词

    内蒙古 锡林郭勒盟 多伦县 县医院    /    多伦县 医院

    绵阳市  四 零 四 医院     /     四川 绵阳 404 医院

    邓州市 人民 医院       /       南召县 人民 医院

b. 去重求交加 – 并集

    多伦县(交加)--      内蒙古、锡林郭勒盟、多伦县、县医院、医院(并集)医院(交加)--        绵阳市、四、零、医院、四川、绵阳、404(并集)人民、医院(交加)--     邓州市、人民、医院、南召县(并集)

c. 类似度

文本对 类似度 实在标签
内蒙古 锡林郭勒盟 多伦县 县医院 / 多伦县 医院 1/5=0.2 1
绵阳市 四零四医院 / 四川 绵阳 404 医院 1/7 = 0.14 1
邓州市 人民 医院 / 南召县 人民 医院 2/4 = 0.5 0

1.1.2.Levenshtein 编辑间隔

一个句子转换为另一个句子须要的编辑次数,编辑包含删除、替换、增加,而后应用最长句子的长度归一化得类似度。

def Levenshtein(text1, text2):
    """
    Levenshtein 编辑间隔
    :param text1: 字符串 1
    :param text2: 字符串 2
    :return: 类似度,float 值
    """
    import Levenshtein
    distance = Levenshtein.distance(text1, text2)
    Similarity = 1 - distance * 1.0 / max(len(text1), len(text2))
    return Similarity

a. 分词 - 计字数

    内 蒙 古 锡 林 郭 勒 盟 多 伦 县 县 医 院(14)/    多 伦 县 医 院(5)绵 阳 市  四 零 四 医 院(8)/     四 川 绵 阳 4 0 4 医 院(9)邓 州 市 人 民 医 院(7)/       南 召 县 人 民 医 院(7)

b. 计算编辑间隔

   内 蒙 古 锡 林 郭 勒 盟 多 伦 县 县 医 院 -------> 删除内、蒙、古、锡、林、郭、勒、盟、县

   绵 阳 市  四 零 四 医 院   -------> 加 四、川

                                           -------> 删除 市

                                           -------> 替换 四(4)、零(0)、四(4)邓 州 市 人 民 医 院         -------> 替换邓(南)、州(召)、市(县)
文本对 间隔 实在标签
内蒙古 锡林郭勒盟 多伦县 县医院 / 多伦县 医院 0.357 1
绵阳市 四零四医院 / 四川 绵阳 404 医院 0.333 1
邓州市 人民 医院 / 南召县 人民 医院 0.571 0

1.1.3 simhash 类似度

先计算两句子的 simhash 二进制编码,而后应用海明间隔计算,最初应用两句的最大 simhash 值归一化得类似度。

def simhash_(text1, text2):
    """
    simhash 类似度
    :param s1: 字符串 1
    :param s2: 字符串 2
    :return: 类似度,float 值
    """
    from simhash import Simhash
    text1_simhash = Simhash(text1, f=64)  #计算 simhash 向量
    text2_simhash = Simhash(text2, f=64)  #计算 simhash 向量
    distance = text1_simhash.distance(text2_simhash)  #汉明间隔
    Similarity = 1 - distance / max(len(bin(text1_simhash.value)), len(bin(text2_simhash.value))) #类似度
    return Similarity

a. 分词

    内蒙古 锡林郭勒盟 多伦县 县医院    /    多伦县 医院

    绵阳市  四 零 四 医院     /     四川 绵阳 404 医院

    邓州市 人民 医院       /       南召县 人民 医院

b. 计算词权重(此处用 tfidf 计算,其余办法也能够)

| Text | Text | Text |

内蒙古 5 锡林郭勒盟 5 多伦县 2 县医院 5 多伦县 7 医院 1
绵阳市 3 四 6 零 3 四 6 医院 1 四川 5 绵阳 5 4045 医院 1
邓州市 7 人民 4 医院 1 南召县 7 人民 4 医院 1

c.hash 函数映射词向量

  • 先将词映射到二进制编码,
  • 而后用 b 步骤中的权重值替换 1,
  • b 步骤中权重值的正数替换 0

d. 合并(将一段文本内的词向量进行累加)

e 海明间隔判断类似度

海明间隔能够了解为: 两个二进制串之间雷同地位不同的个数。举个例子,[1,1,1,0,0,0]和 [1,1,1,1,1,1] 的海明间隔就是 3。

1.1.4 Bm25 类似度

一句话详情其次要思维:对 Query(待查问语句)进行语素解析,生成语素 qi;而后,对于每个搜寻后果 D,计算每个语素 qi 与 D 的相关性得分,最初,将 qi 绝对于 D 的相关性得分进行加权求和,从而失去 Query 与 D 的相关性得分。公式如下:

$\operatorname{Score}(Q, d)=\sum_i^n W_i \cdot R\left(q_i, d\right)$

Q 示意 Query,qi 即 Q 分词后的每一个解析语素(对中文而言,咱们能够把对 Query 的分词作为语素剖析,每个词看成语素 qi)。d 示意一个搜寻后果文档,Wi 示意语素 qi 的权重,R(qi,d)示意语素 qi 与文档 d 的相关性得分。
判断一个词与一个文档的相关性的权重定义 Wi 办法有多种,较罕用的是 IDF。公式如下:

$\operatorname{IDF}\left(q_i\right)=\log \frac{N-n\left(q_i\right)+0.5}{n\left(q_i\right)+0.5}$

  • N 为索引中的全副文档数,
  • n(qi)为蕴含了 qi 的文档数。

依据 IDF 的定义能够看出当很多文档都蕴含了 qi 时,qi 的区分度就不高,因而应用 qi 来判断相关性时的重要度就较低。

$\operatorname{Score}(Q, d)=\sum_i^n I D F\left(q_i\right) \cdot \frac{f_i \cdot\left(k_1+1\right)}{f_i+k_1 \cdot\left(1-b+b \cdot \frac{d l}{a v g d l}\right)}$

求 Score(qi,d)具体的公式能够参考文本类似度 -BM25 算法
其中

  • f(qi, D)为单词在以后候选文档中的词频
  • k1、b 为调节因子,通常设为 k1=2,b=0.75
  • |D| 为以后候选文本数(与指标文本匹配的总条数)
  • avgdl 为语料库中所有文档的均匀长度。

在做文本匹配的时候(如反复问题检测)能够尝试 BM25 的办法,但在搜寻畛域中,有时候搜寻 query 和候选文档的长度是不一样甚至差距很大,所以 BM25 在计算相似性的时候须要对文档长度做肯定的解决。

文本类似度 -BM25 算法

#Bm25
import math
import jieba
class BM25(object):
    def __init__(self, docs):#docs 是一个蕴含所有文本的列表,每个元素是一个文本
        self.D = len(docs)  #总文本数
        self.avgdl = sum([len(doc)+0.0 for doc in docs]) / self.D   #均匀文本长度
        self.docs = docs #文本库列表
        self.f = []  # 列表的每一个元素是一个 dict,dict 存储着一个文档中每个词的呈现次数
        self.df = {} # 存储每个词及呈现了该词的文档数量
        self.idf = {} # 存储每个词的 idf 值
        self.k1 = 1.5
        self.b = 0.75
        self.init()
 
    def init(self):
        for doc in self.docs:  #对每个文本
            tmp = {}   #定义一个字典存储词呈现频次
            for word in doc:
                tmp[word] = tmp.get(word, 0) + 1  # 存储每个文档中每个词的呈现次数
            self.f.append(tmp)
            for k in tmp.keys():
                self.df[k] = self.df.get(k, 0) + 1
        for k, v in self.df.items():
            self.idf[k] = math.log(self.D-v+0.5)-math.log(v+0.5) #计算 idf
 
    def sim(self, doc, index):
        score = 0
        for word in doc:
            if word not in self.f[index]:
                continue
            d = len(self.docs[index])
            score += (self.idf[word]*self.f[index][word]*(self.k1+1)
                      / (self.f[index][word]+self.k1*(1-self.b+self.b*d
                                                      / self.avgdl)))
        return score
 
    def simall(self, doc):
        scores = []
        for index in range(self.D):
            score = self.sim(doc, index)
            scores.append(score)
        return scores
 
if __name__ == '__main__':
    sents1 = ["多伦县医院",  #数据库
                "四川绵阳 404 医院",
               "南召县人民医院"]
    sents2 = ["内蒙古锡林郭勒盟多伦县县医院","绵阳市四零四医院","邓州市人民医院"]# 待匹配文本
    doc = []
    for sent in sents1:
        words = list(jieba.cut(sent))
        doc.append(words)
    print(doc)
    s = BM25(doc)
    print(s.f)
    print(s.idf)
    for k in sents2:
        print(s.simall(jieba.lcut(k))) #打印类似度匹配后果
        
        

1.1.5 VSM(向量空间模型)算法

VSM 算法的思路次要分为两步:

(1) 用向量示意句子, 用向量示意句子的办法很多,简略的有 onehot,词频法,基于语义的有 word2vec/fastText/glove/bert/elmo 等,本例中应用基于简略的词频的向量化形式。

(2)计算两向量的余弦间隔(曼哈顿间隔、欧几里得间隔、明式间隔、切比雪夫间隔)得类似度。

#tfidf_余弦
def sim_vecidf(self, s1, s2):
    """词向量通过 idf 加权均匀后计算余弦间隔"""
    v1, v2 = [], []
    # 1. 词向量 idf 加权均匀
    for s in jieba.cut(s1):
        idf_v = idf.get(s, 1)
        if s in voc:
            v1.append(1.0 * idf_v * voc[s])
    v1 = np.array(v1).mean(axis=0)
    for s in jieba.lcut(s2):
        idf_v = idf.get(s, 1)
        if s in voc:
            v2.append(1.0 * idf_v * voc[s])
    v2 = np.array(v2).mean(axis=0)
    # 2. 计算 cosine
    sim = self.cosine(v1, v2)
    return sim

a. 句子向量化

a1. 取句子对的惟一词元组

set(内蒙古 锡林郭勒盟 多伦县 县医院 / 多伦县 医院) = (内蒙古 锡林郭勒盟 多伦县 县医院 医院)

set(绵阳市 四 零 四 医院 / 四川 绵阳 404 医院) = (绵阳市 四 零 医院 四川 绵阳 404)

set(邓州市 人民 医院 / 南召县 人民 医院) = (邓州市 人民 医院 南召县)

a2. 依据每个句子在元组中的词频建设向量示意

b. 计算余弦间隔

$\operatorname{Cos}(x 1, x 2)=\frac{x 1 \cdot x 2}{|x 1||x 2|}$

句子 间隔
内蒙古 锡林郭勒盟 多伦县 县医院 / 多伦县 医院 0.3535
绵阳市 四零四医院 / 四川 绵阳 404 医院 0.1889
邓州市 人民 医院 / 南召县 人民 医院 0.6666

1.1.6 word2vector + 类似度计算(BERT 模型 + 余弦类似度为例)

罕用做法是通过 word2vec 等预训练模型失去词向量,而后对文本做分词,通过 embedding_lookup 失去每个 token 对应的词向量,而后失去短文本的句向量。对两个文本的句子向量采纳类似度计算方法如余弦类似度、曼哈顿间隔、欧氏间隔等。无监督形式获得的后果取决于预训练词向量的成果

BERT 是谷歌在 2018 年推出的深度语言示意模型,是对于语言了解的深度双向 transformers 的预训练模型,开启了预训练模型的新篇章。它能够学习文本的语义信息,通过向量模式的输入能够用于上游工作。也就说,它本人曾经在大规模意料上训练好的参数,咱们在用的时候只须要在这个根底上训练更新参数。bert 模型能够解决多种自然语言解决问题,如单文本分类、语句对分类、序列标注等。在解决文本匹配工作时,有两种思路,第一种间接把文本匹配工作作为语句对分类工作,模型输出语句对,输入是否匹配的标签;第二种利用 bert 模型预训练文本对的上下文嵌入向量,再通过余弦类似度等类似度计算方法验证文本对是否匹配,在此基础上还有很多基于 bert 模型的变种,篇幅无限不做一一讲述。接下来简略介绍一下 bert 预训练文本嵌入 + 余弦类似度的算法框架。

a. 首先应用大量公域文本数据对 BERT 模型进行预训练(或间接用谷歌预训练好的模型)

b. 将文本间接输出模型

c. 对模型输入的语义向量 C,或两头隐层向量,计算余弦类似度,失去匹配后果。

基于深度学习的匹配算法品种繁多,如基于 CNN 网络、RNN 网络、LSTM 网络等及各种变种层出不穷,在此不一一列举实现。

传统的文本匹配办法次要关注文本间字与字,词与词的匹配关系,无奈精确辨认不同表达方式下不同文本的同一指向关系,即语义关系。因而在这一背景下,要对多源异构的海量地址数据进行匹配,传统的文本匹配办法已不再实用,深度学习办法大行其道。但深度学习办法也有本身的局限性,比方对海量文本和算力的高要求等,都使得深度学习办法的普适性大打折扣,因而没有最好的文本匹配算法,只有以后条件下最适宜的文本匹配算法。

2. 有监督形式

2.1 孪生神经网络(Siamese Network)

原文:《Learning a Similarity Metric Discriminatively, with Application to Face Verification》

  1. 要解决什么问题?

    • 用于解决类别很多(或者说不确定),然而训练样本的类别数较少的分类工作(比方人脸识别、人脸认证)
    • 通常的分类工作中,类别数目固定,且每类下的样本数也较多(比方 ImageNet)
  2. 用了什么办法解决?

提出了一种思路:将输出映射为一个特征向量,应用两个向量之间的“间隔”(L1 Norm)来示意输出之间的差别(图像语义上的差距)。
基于上述思路设计了 Siamese Network。每次须要输出两个样本作为一个样本对计算损失函数。

  • [x] 罕用的 softmax 只须要输出一个样本。
  • [x] FaceNet 中的 Triplet Loss 须要输出三个样本。
  • [x] 提出了 Contrastive Loss 用于训练。
  1. 成果如何?

文中进行了一个掂量两张人脸的类似度的试验,应用了多个数据库,较简单。siamese network 当初仍然有很多中央应用,能够获得 state-of-the-art 的成果。

  1. 还存在什么问题?
  • contrastive loss 的训练样本的抉择须要留神,论文中都是尽量保障了 50% 的正样本对和 50% 的负样本对。

分类问题:

  • 第一类,分类数量较少,每一类的数据量较多,比方 ImageNet、VOC 等。这种分类问题能够应用神经网络或者 SVM 解决,只有当时晓得了所有的类。
  • 第二类,分类数量较多(或者说无奈确认具体数量),每一类的数据量较少,比方人脸识别、人脸验证工作。

文中提出的解决方案:

learn a similar metric from data。核心思想是,寻找一个映射函数,可能将输出图像转换到一个特色空间,每幅图像对应一个特征向量,通过一些简略的“间隔度量”(比方欧式间隔)来示意向量之间的差别,最初通过这个间隔来拟合输出图像的类似度差别(语义差别)。

2.1.1 简介

  • Siamese Network 是一种神经网络的框架,而不是具体的某种网络,就像 seq2seq 一样,具体实现上能够应用 RNN 也能够应用 CNN。
  • Siamese network 就是“连体的神经网络”,神经网络的“连体”是通过共享权值来实现的。(共享权值即左右两个神经网络的权重截然不同)
  • siamese network 的作用是掂量两个输出的类似水平。孪生神经网络有两个输出(Input1 and Input2), 将两个输出 feed 进入两个神经网络(Network1 and Network2),这两个神经网络别离将输出映射到新的空间,造成输出在新的空间中的示意。通过 Loss 的计算,评估两个输出的类似度。

Siamese Network 有两个构造雷同,且共享权值的子网络。别离接管两个输出 X1 与 X2,将其转换为向量 Gw(X1)与 Gw(X2),再通过某种间隔度量的形式计算两个输入向量的间隔 Ew。

训练 Siamese Network 采纳的训练样本是一个 tuple (X1,X2,y)(X1,X2,y),标签 y = 0 示意 X1 与 X2 属于不同类型(不类似、不反复、依据利用场景而定)。y= 1 则示意 X2 与 X2 属于雷同类型(类似)。

LOSS 函数的设计应该是

  1. 当两个输出样本不类似 (y=0) 时,间隔 Ew 越大,损失越小,即对于 Ew 的枯燥递加函数。
  2. 当两个输出样本类似 (y=1) 时,间隔 Ew 越大,损失越大,即对于 Ew 的枯燥递增函数。

用 L +(X1,X2)示意 y = 1 时的 LOSS,L−(X1,X2)示意 y = 0 时的 LOSS,则 LOSS 函数能够写成如下模式:

Lw(X1,X2)=(1−y)L−(X1,X2)+yL+(X1,X2)

简略来说:孪生体现在应用雷同的编码器(sentence encoder),将文本转为高维向量。具体步骤为,有文本 A 和文本 B 别离输出 sentence encoder 进行特征提取和编码,将输出映射到新的空间失去特征向量 u 和 v;最终通过 u、v 的拼接组合,通过上游网络来计算文本 A 和 B 的相似性

  • 在训练和测试中,模型的编码器是权重共享的,编码器能够抉择 CNN、RNN、LSTM 等
  • 提取到特色 u、v 后,能够应用余弦间隔、欧氏间隔等失去两个文本的类似度。
  • 毛病是两个文本在编码时候没有交互,不足交互的构造没有充分利用到两个文本相互影响的信息

2.2 匹配聚合网络(ESIM,BIMPM)

在上述孪生网络的根底上,失去特色 u、v 然而不间接计算向量类似度,而是通过注意力机制将两个文本进行信息交互,最初通过全连贯层失去类似度。

代表的模型有 ESIM,BIMPM 等

以 ESIM 为例

  • 首先是对两个文本的初期编码,就是对两个文本做分词、文本表征,即对句子进行信息的提取。如果应用 LSTM 作为 encoder,能够失去每个时刻(每个单词)的输入,通常维度为[batch_size, seq_len, embedding_dim]。举例子为,句子 A 长度 10,句子 B 长度也为 10,那么进过编码当前句子 A 的维度[1,10,300],句子 B[1,10,300],这里就失去了上述所提到的 u、v
  • 接下来是交互操作,为了操作简略疏忽 batchsize 维度,交互即矩阵相乘失去[10,10],矩阵须要对句子 A 做横向概率归一,对句子 B 做纵向概率归一。下面这句话其实就是 ESIM 的外围要点。它是一个两个 item 之间相互做 attention,简略称之为 both attention。
  • 对 attention 后失去的向量做拼接后输入编码器,输入再接到全连贯层、softmax 就能够失去后果,即两个文本类似(label 1)或不类似(label 0)

3. 预训练语言模型

  1. 第一阶段,应用通用的意料库训练语言模型,
  2. 第二阶段预训练的语言模型(BERT 相干衍生的模型)做类似度工作,失去信息交互后的向量,
  3. 连贯全连贯层,输入概率。行将两个短文本拼接(CLS A1 A2 … A 10 SEP B1 B2 … B10 SEP),而后 CLS 向量连贯全连贯层,判断类似与否。

这种模型参数多,并且应用了通用的语料库,可能获取到短文本之间暗藏的交互信息,成果较好。

简略来说用拼接的办法相似“单塔”,孪生网络的办法相似“双塔”,不齐全精确后续会具体阐明,预训练模型就不开展讲了,大家去官网或者多看几篇学术论文吧,BERT ERNIE。

4. 有监督形式 + 无监督形式

无监督:间接相加失去句向量,不能很好的表白语义信息,并且词的地位信息没有失去体现,也不蕴含上下文的语义信息。

有监督学习:工夫复杂度太高。能够将规范库中的句向量计算实现并存储。新的文原本长期,只须要解决用户问题即可,而后与存储在库中的规范问句进行间隔度量。

能够应用 BERT 代替孪生网络的 CNN 或 LSTM 构造,获取更多语义信息的句向量,还能够通过蒸馏升高 BERT 模型的参数,节约工夫老本。

4.1 Sentence-BERT

文章链接:https://arxiv.org/pdf/1908.10…

论文代码:https://github.com/UKPLab/

为了让 BERT 更好地利用文本信息,作者们在论文中提出了如下的 SBERT 模型。SBERT 沿用了孪生网络的构造,文本 Encoder 局部用同一个 BERT 来解决。之后,作者别离试验了 CLS-token 和 2 种池化策略(Avg-Pooling、Mean-Pooling),对 Bert 输入的字向量进一步特征提取、压缩,失去 u、v。

对于 u、v 整合,作者提供了 3 种策略:

  1. 将 u、v 拼接,接入全连贯网络,通过 softmax 输入,损失函数用穿插熵损失
  2. 间接计算两个文本的余弦类似度,损失函数用均方根误差
  1. 如果输出的是三元组

SBERT 间接用 BERT 的原始权重初始化,在具体数据集微调,训练过程和传统 Siamese Network 相似。然而这种训练形式能让 Bert 更好的捕获句子之间的关系,生成更优质的句向量。在测试阶段,SBERT 间接应用余弦类似度来掂量两个句向量之间的类似度,极大晋升了推理速度。

应用 NLI 和 STS 为代表的匹配数据集,在分类指标函数训练时,作者测试了不同的整合策略,结果显示“(u, v, |u-v|)”的组合成果最好。最重要的局部是元素差:(|u – v|)。句向量之间的差别度量了两个句子嵌入维度间的间隔,确保类似的 pair 更近,不同的 pair 更远。

4.2 比照学习

深度学习的实质是做两件事件:①示意学习 ②演绎偏好学习。比照学习 (ContrastiveLearning) 则是属于示意学习的领域,它并不需要关注样本的每一个细节,然而学到的特色要使其可能和其余样本辨别开。比照学习作为一种无监督示意学习办法,最开始也是在 CV 畛域掀起浪潮,之后 NLP 跟进,在文本类似度匹配等工作上超过 SOTASOTA。该工作次要是对文本进行表征,使相近的文本间隔更近,差异大的文本间隔更远。

NLP 的比照学习算法下文将不具体讲述简略展现更多内容参考链接。

4.2.1 BERT-Flow 2020.11

很多钻研发现 BERT 示意存在问题:未经微调的 BERT 模型在文本类似度匹配工作上体现不好,甚至不如 Glove?作者通过剖析 BERT 的性质,如图:

在实践上 BERT 的确提取到了足够的语义信息,只是这些信息无奈通过简略的 consine 间接利用。次要是因为:

  • ①BERT 的词向量在空间中不是均匀分布,而是呈锥形。高频词都凑近原点,而低频词远离原点,相当于这两种词处于了空间中不同的区域,那高频词和低频词之间的类似度就不再实用;
  • ②低频词的散布很稠密。低频词示意失去的训练不充沛,散布稠密,导致该区域存在语义定义不残缺的中央(poorly defined),这样算进去的类似度存在问题。

针对以上问题,提出了 BERT-Flow,基于流式生成模型,将 BERT 的输入空间由一个锥形可逆地映射为规范的高斯分布空间。

4.2.2 BERT-Whitening 2021.03

BERT-Whitening 首先剖析了余弦类似度为什么能够掂量向量的类似度:向量 A 与 B 的乘积等于 A AA 在 B BB 所在直线上投影的长度。将两个向量扩大到 d 维

$\cos (A, B)=\frac{\sum_{i=1}^d a_i b_i}{\sqrt{\sum_{i=1}^d a_i^2} \sqrt{\sum_{i=1}^d b_i^2}}$

$\text {模的计算公式:}|A|=\sqrt{a_1^2+a_2^2+\ldots+a_n^2}$

上述等式的成立,都是在规范正交基 (忘了的同学能够自行温习一下) 的条件下,也就是说向量依赖咱们抉择的坐标基,基底不同,内积对应的坐标公式就不一样,从而余弦值的坐标公式也不一样。
所以,BERT 的句向量尽管蕴含了足够的语义,但有可能是因为此时句向量所属的坐标系并非规范正交基,而导致用基于规范正交基的余弦类似度公式计算时成果不好。那么怎么晓得具体用了何种基底呢?能够根据统计学去判断,在给向量汇合抉择基底时,尽量均匀地用好每一个基向量,这就体现为每个重量的应用都是独立的、平均的,如果这组基是规范正交基,那么对应的向量集应该体现出“各向同性”来,如果不是,能够想方法让它变得更加各向同性一写,而后再用余弦公式计算,BERT-Flow 正是想到了“flow 模型”的方法,而作者则找到了一种更简略的线性变换的办法。

标准化协方差矩阵

BERT-Whitening 还反对降维操作,能达到提速和提效的成果。

★PCA 和 SVD 差别剖析:PCA 能够将方阵合成为特征值和特征向量,SVD 则能够合成任意形态的矩阵。

4.2.3 ConSERT 2021.05

https://arxiv.org/pdf/2105.11…

美团技术团队提出了基于比照学习的句子示意迁徙办法——ConSERT,次要证实了以下两点:

①BERT 对所有的句子都偏向于编码到一个较小的空间区域内,这使得大多数的句子对都具备较高的类似度分数,即便是那些语义上齐全无关的句子对。咱们将此称为 BERT 句子示意的“坍缩(Collapse)”景象。

②BERT 句向量示意的坍缩和句子中的高频词无关。当通过均匀词向量的形式计算句向量时,高频词的词向量将会主导句向量,使之难以体现其本来的语义。当计算句向量时去除若干高频词时,坍缩景象能够在肯定水平上失去缓解。

为了解决 BERT 存在的坍缩问题,作者提出了句子示意迁徙框架:

对 BERT encoder 做了改良,次要包含三个局部:

*①数据加强模块,作用于 embedding 层,为同一文本生成不同的编码。

  1. shuffle:更换 position id 的程序
  2. token cutoff:在某个 token 维度把 embedding 置为 0
  3. feature cutoff:在 embedding 矩阵中,有 768 个维度,把某个维度的 feature 置为 0
  4. dropout:embedding 中每个元素都有肯定概率为 0,没有行或列的束缚

数据加强成果:Token Shuffle > Token Cutoff >> Feature Cutoff ≈ Dropout >> None

  • ②共享的 Bert encoder,生成句向量。
  • ③一个比照损失层,在一个 Batch 内计算损失,拉近同一样本不同句向量的类似度,使不同样本之间互相远离。损失函数:

$L_{i, j}=-\log \frac{\exp \left(\operatorname{sim}\left(r_i, r_j\right) / \tau\right)}{\sum_{k=1}^{2 N} 1_{[k \neq i]} \exp \left(\operatorname{sim}\left(r_i, r_k\right) / \tau\right)}$

N:Batchsize,2N 示意 2 种数据加强形式,sim(): 余弦类似度函数,r: 句向量,τ: 试验 0.08−0.12 最优

除了无监督训练之外,作者还提出了三种进一步交融监督信号的策略:

  • ①联结训练(joint):有监督的损失和无监督的损失通过加权联结训练模型。
  • ②先有监督再无监督(sup-unsup):先应用有监督损失训练模型,再应用无监督的办法进行示意迁徙。
  • ③联结训练再无监督(joint-unsup):先应用联结损失训练模型,再应用无监督的办法进行示意迁徙。

参考链接:https://blog.csdn.net/PX20120…

4.2.4 SimCSE:2021.04

前几节讲述了比照学习的原理和几种基于 Bert 的形式获取句子向量,例如 BERT-flow 和 BERT-whitening 等,对预训练 Bert 的输入进行变换从而失去更好的句子向量。前面将通过 ①结构指标函数 ②构建正负例 的比照学习办法训练模型,获得 SOTA 的成果。

SimCSE 是有大神陈丹琦发表的《Simple Contrastive Learning of Sentence Embeddings》,简略高效

SimCSE 蕴含无监督(图左局部)和有监督(图右局部)两种办法。实线箭头代表正例,虚线代表负例。

  • Unsupervised

翻新点在于应用 Dropout 对文本减少乐音。

1. 正例结构:利用 Bert 的随机 Dropout,同一文本通过两次 Bert enconder 失去不同的句向量形成类似文本。

2. 负例结构:同一个 Batch 中的其余样本作为负例被随机采样。

  • Supervised

1. 正例:标注数据
2. 负例:同 Batch 内的其余样本

4.2.5 R-Drop(Supervised):2021.06

https://arxiv.org/abs/2106.14448

Dropout 尽管能够避免模型训练中的过拟合并加强鲁棒性,然而其操作在肯定水平上会使训练后的模型成为一种多个子模型的组合束缚。SimCSE 就是心愿 Dropout 对模型后果不会有太大影响,也就是模型输入对 Dropout 是鲁棒的。所以,“Dropout 两次”这种思维是能够推广到个别工作的,这就是 R -Drop(Regularized Dropout),由微软亚洲研究院和苏州大学提出的更加简略无效的正则办法。

  • R-Drop 与传统作用于神经元或模型参数的束缚办法不同,而是作用于输入层,补救了 Dropout 在训练和测试时的不一致性。在每个 mini-batch 中,每个数据样本过两次带有 Dropout 的同一个模型,R-Drop 再应用 KL-divergence(KL 散度)束缚两次的输入统一。所以,R-Drop 束缚了因为 Dropout 带来的两个随机子模型的输入一致性。
  • R-Drop 只是简略减少了一个 KL- 散度损失函数项,并没有其余任何改变。尽管该办法看起来很简略,但在 NLP 和 CV 的工作中,都获得了十分不错的 SOTA 后果。

同样的输出,同样的模型,通过两个 Dropout 失去的将是两个不同的散布,近似将这两个门路网络看作两个不同的模型网络。基于此,这两个不同的模型产生的不同散布而这篇文章的次要奉献就是在训练过程中一直拉低这两个散布之间的 KL 散度。因为 KL 散度自身具备不对称性,作者通过替换这两种散布的地位以间接应用整体对称的 KL 散度,称之为双向 KL 散度。

4.2.6 ESimCSE(Unsupervised):2021.09

https://arxiv.org/abs/2109.04380

SimCSE 构建正负例时存在两个两个毛病:

  • ①结构正例长度相等,导致模型预测时存在偏差,长度相等的文本会偏向预测类似度高。
  • ②比照学习实践上负例越多,对之间模型学习的越好,但增大 Batch 会受到性能的限度。

ESimCSE 针对以上问题做了相应的改良:

  • 正例结构:通过引入噪声较小的“单词反复”形式扭转正例的长度,设置反复率 dup_rate,确定 dup_len 后利用均匀分布随机选取 dup_len 子词进行反复。
  • 负例结构:为了更无效的扩大负对,同时不升高性能,通过保护一个队列,重用后面紧接的 mini-batch 的编码嵌入来扩大负对:

    • ①将以后 mini-batch 的句嵌入放入队列,同时将“最老的”句子踢出队列。因为排队句子嵌入来自后面的 mini-batch,通过取其参数的挪动均匀来放弃动量更新模型,并利用动量模型生成排队句子嵌入。
    • 在应用动量编码器时,敞开了 dropout,这能够放大训练和预测之间的差距。

4.2.7 PromptBERT(Unsupervised):2022.01

https://arxiv.org/pdf/2201.04…

Prompt Learning 比拟炽热,号称 NLP 的第四范式,

  • 作者发现 BERT 在语义类似度方面体现不好,次要由:static token embeddings biases 和 ineffective layers,而不是 high cosine similarity of the sentence embedding。static token embedding 是在 bert 构造中,输出进 block 前,通过 embedding layer 产生的后果,这里强调是动态的 embedding,就是 embedding metrics 中每个 token 都惟一对应的 embedding,是不随句子环境而变动的。至于 ineffective layers 就很好了解了,就是 bert 中重叠的 block 构造,比方 bert-base 中的 12 层。作者认为这些构造,对语义类似度的表征这个方面是有效的。
  • Anisotropy(各向异性):上篇咱们曾经提到,词向量是有维度的,每个维度上基向量单位向量长度不一样,就是各向异性的。这会造成计算向量类似度的时候产生偏差。如何度量 Anisotropy:

作者剖析了造成 embedding bias 的起因,除了 token frequency 是造成 bias 的起因,作者又提出了:subwords,case sentitive

图中不同词频 token 的散布状况,色彩越深代表词频越高,咱们能够看出词频高的 token,散布比拟紧凑,词频低的 token,散布较扩散。作者输入这个图像还有一个目标是他提出各向异性(anisotropy)和偏差(bias)是不相干的,各向异性不是导致偏差的起因。
Embedding bias 意思是映射散布被一些不相干的信息所烦扰,是能够用降维的形式去可视化的。

更多细节参考原论文,Prompt 成果就不赘述了,百度开发的 UIE 模型在 NLP 就很弱小!

4.2.8 SNCSE(Unsupervised):2022.01

https://arxiv.org/abs/2201.05979

SNCSE 同样是由微软团队提出,次要是针对以上办法存在的问题:以后比照学习的数据加强形式,获取的正样本都极为类似,导致模型存在特色克制,即模型不能辨别文本类似度和语义类似度,并更偏差具备类似文本,而不思考它们之间的理论语义差别。

为了加重特色克制,该论文提出了通过软负样本联合双向边际损失的无监督句子嵌入比照学习办法。其中,软负样本,即具备高度类似,但与原始样本在语义上存在显著的差别的样本。双向边际损失,即通过扩充原始样本与正例和原始样本与软负例之间的间隔,使模型更好地学习到句子之间的语义差异。
软负样本结构:为原文本增加显示的否定词。

  • 在获取句子表征时,受 PromptBERT 启发,通过三种模板示意原样本、正样本和软负样本:

4.2.9 DiffCSE(Unsupervised):2022.04

https://arxiv.org/pdf/2204.10…

联合句子间差别的无监督句子嵌入比照学习办法——DiffCSE 次要还是在 SimCSE 上进行优化(可见 SimCSE 的重要性),通过 ELECTRA 模型的生成伪造样本和 RTD(Replaced Token Detection)工作,来学习原始句子与伪造句子之间的差别,以进步句向量表征模型的成果。

其思维同样来自于 CV 畛域(采纳不变比照学习和可变比照学习相结合的办法能够进步图像表征的成果)。作者提出应用基于 dropout masks 机制的加强作为不敏感转换学习比照学习损失和基于 MLM 语言模型进行词语替换的办法作为敏感转换学习「原始句子与编辑句子」之间的差别,独特优化句向量表征。

在 SimCSE 模型中,采纳 pooler 层(一个带有 tanh 激活函数的全连贯层)作为句子向量输入。该论文发现,采纳带有 BN 的两层 pooler 成果更为突出,BN 在 SimCSE 模型上仍然无效。

  • ①对于掩码概率,经试验发现,在掩码概率为 30% 时,模型成果最优。
  • ②针对两个损失之间的权重值,经试验发现,比照学习损失为 RTD 损失 200 倍时,模型成果最优。

参考链接:https://blog.csdn.net/PX2012007/article/details/127696477

4.2.10 小结

SimCSE 以来几种比拟重要的文本加强式的比照学习算法,按工夫程序,实践上应该是间隔越近的算法成果越好,但应用时,还是要联合具体的业务场景,算法没有好坏,还是用看怎么用。对于有些内容,可能叙述的不是很粗疏或是须要肯定的常识铺垫,感兴趣的同学能够针对性的研读论文和辅助其余材料。当然,算法层出不穷,更新很快,后续呈现比拟重要的比照学习算法。

5. 文本匹配常见思路(技巧晋升)

  • TextCNN/TEXTRNN
  • Siamese-RNN
  • 采纳多种 BERT 类预训练模型
  • 对单模型进行调参
  • 多模型交融
  • BERT 后接上 RCNN/RNN/CNN/LSTM/Siamese 等等

5.1 计划一

特色工程

  1. 数据荡涤:大赛给的数据比拟规整,数据荡涤局部工作不多,简略做了特殊字符解决等操作。
  2. 数据加强
  • 传递闭包裁减(标签传递)

依据 IF A=B and A=C THEN B= C 的规定,对正样本做了裁减加强。

依据 IF A=B and A!=C THEN B!= C 的规定,对负样本做了裁减加强。

在对负样本进行裁减后,正负样本比例从原始的 1.4:1, 变成 2.9:1。所以又对负样本进行了下采样,是的正负样本比例 1:1。

  • 同义词替换

    应用开源包 synormise 的成果不太好,前面能够尝试应用公开医学意料训练 word2vec 模型来做同义词替换(工夫问题,没有尝试)。

随机删除,随机替换,随机替换
句式比拟短,随机删除更短。
很多 query 仅仅相差一个单词,随机替换扭转语义。
少数属于问句,随机替换扭转了语义。

  1. 模型抉择

在预训练模型的根底上通过反抗训练加强模型的泛化性能。

  • BRET
    Bert 的一个上游根底工作语句对分类(Sentence Pair Classification Task), [CLS] Bert 的输入有一个维度的向量示意
  • BERT+CNN(LSTM)
    将 BERT 的输入特色作为文本的示意向量,而后前面再接上 LSTM 或者 CNN(成果降落)
  • BERT+siamese
    将大赛提供的 category 信息利用上,借用孪生网络的思维与两个 Query 进行拼接(成果降落)。
  1. 后果剖析
  • 单模型线上成果

目前所训练的模型中:

小模型中 BERT-wwm-ext 体现是最好的,

大模型中 RoBERTa-large-pair 体现最好。

在现有的资源和模型上,对单模型的参数寻优达到一个天花板,线上最高的分数为 0.9603。前面开始摸索多模型交融。

  • 多模型融合线上成果

将不同类型的预训练模型作为基模型进行多模型交融。基模型的筛选准则基于单模型的线上提交成果,从不同类型的单模型中筛选线上体现最好的参数,从新训练交融。

基模型:

BERT-wwm-ext + FGM

RoBERTa-large-pair + FGM

Ernie(BaiDu)+ FGM

模型交融策略应用的是 averaging,为了升高差异比拟小的模型对后果的影响,采纳 sigmoid 反函数的形式进行 ensemble。

对于反抗训练在 NLP 中的作用,援用大佬的一句话叫缘,妙不可言~

5.2 计划二

  1. 摸索剖析

文本长度:训练集和验证集散布相似,大都集中在 10-20 个字

标签散布

总体思路

  1. 数据划分

采纳 kfold 穿插验证(左边的划分形式)

•利用全副数据,取得更多信息

•升高方差,进步模型性能

  1. 模型设计

二分类穿插熵损失函数:

  1. 模型交融

小模型同时退出 CHIP2019 数据训练

模型 特点 权重 退出内部句对数据
BERT-wwm-ext 全词 Mask 1 YES
Ernie-1.0 对词、实体及实体关系建模 1 YES
RoBERTa-large-pair 面向相似性或句子对工作优化 1 NO
  1. 数据预处理

对称裁减、传递裁减(留神要放弃原来的散布,否则会过拟合)

  1. 训练
  • 三种构造:(理论应用差异不大,第一种又好又简略)
  • 反抗训练
# 代码来自苏剑林 bert4keras

def adversarial_training(model, embedding_name, epsilon=1):
    """ 给模型增加反抗训练
    其中 model 是须要增加反抗训练的 keras 模型,embedding_name
    则是 model 里边 Embedding 层的名字。要在模型 compile 之后应用。"""
    if model.train_function is None:  # 如果还没有训练函数
        model._make_train_function()  # 手动 make
    old_train_function = model.train_function  # 备份旧的训练函数

    # 查找 Embedding 层
    for output in model.outputs:
        embedding_layer = search_layer(output, embedding_name)
        if embedding_layer is not None:
            break
    if embedding_layer is None:
        raise Exception('Embedding layer not found')

    # 求 Embedding 梯度
    embeddings = embedding_layer.embeddings  # Embedding 矩阵
    gradients = K.gradients(model.total_loss, [embeddings])  # Embedding 梯度
    gradients = K.zeros_like(embeddings) + gradients[0]  # 转为 dense tensor

    # 封装为函数
    inputs = (model._feed_inputs +
              model._feed_targets +
              model._feed_sample_weights)  # 所有输出层
    embedding_gradients = K.function(
        inputs=inputs,
        outputs=[gradients],
        name='embedding_gradients',
    )  # 封装为函数

    def train_function(inputs):  # 从新定义训练函数
        grads = embedding_gradients(inputs)[0]  # Embedding 梯度
        delta = epsilon * grads / (np.sqrt((grads**2).sum()) + 1e-8)  # 计算扰动
        K.set_value(embeddings, K.eval(embeddings) + delta)  # 注入扰动
        outputs = old_train_function(inputs)  # 梯度降落
        K.set_value(embeddings, K.eval(embeddings) - delta)  # 删除扰动
        return outputs

    model.train_function = train_function  # 笼罩原训练函数
    
写好函数后,启用反抗训练只须要一行代码
adversarial_training(model, 'Embedding-Token', 0.5)
  1. 预测
  • 算数均匀→几何平均→sigmoid 均匀(用反函数取出 sigmoid/softmax 归一化之前的状态做均匀,信息量更大,晋升显著)
  • 分类阈值微调(0.47)
  • 伪标签

5.3 更多计划

更多计划就不一一开展了,参考下方链接:

https://tianchi.aliyun.com/no…

https://tianchi.aliyun.com/no…

https://tianchi.aliyun.com/no…

参考链接:

https://tianchi.aliyun.com/co…

https://tianchi.aliyun.com/no…

6. 特定畛域常识图谱 (Domain-specific KnowledgeGraph:DKG) 交融计划(重点!)

在后面技术常识下能够看看后续的理论业务落地计划和学术计划

对于图神经网络的常识交融技术学习参考上面链接:[PGL 图学习我的项目合集 & 数据集分享 & 技术演绎业务落地技巧[系列十]](https://aistudio.baidu.com/ai…)

从入门常识到经典图算法以及进阶图算法等,自行查阅食用!

文章篇幅无限请参考专栏按需查阅:NLP 常识图谱相干技术业务落地计划和码源

6.1 特定畛域常识图谱常识交融计划(实体对齐):优酷畛域常识图谱为例

计划链接:https://blog.csdn.net/sinat_39620217/article/details/128614951

6.2 特定畛域常识图谱常识交融计划(实体对齐):娱乐常识图谱构建之人物实体对齐

计划链接:https://blog.csdn.net/sinat_39620217/article/details/128673963

6.3 特定畛域常识图谱常识交融计划(实体对齐):商品常识图谱技术实战

计划链接:https://blog.csdn.net/sinat_39620217/article/details/128674429

6.4 特定畛域常识图谱常识交融计划(实体对齐):基于图神经网络的商品异构实体表征摸索

计划链接:https://blog.csdn.net/sinat_39620217/article/details/128674929

6.5 特定畛域常识图谱常识交融计划(实体对齐)论文合集

计划链接:https://blog.csdn.net/sinat_39620217/article/details/128675199

论文材料链接:两份内容不雷同,且依照序号从小到大重要性顺次递加

常识图谱实体对齐材料论文参考(PDF)+ 实体对齐计划 + 特定畛域常识图谱常识交融计划(实体对齐)

常识图谱实体对齐材料论文参考(CAJ)+ 实体对齐计划 + 特定畛域常识图谱常识交融计划(实体对齐)

6.6 常识交融算法测试计划(常识生产品质保障)

计划链接:https://blog.csdn.net/sinat_39620217/article/details/128675698

7. 总结

本我的项目次要围绕着特定畛域常识图谱 (Domain-specific KnowledgeGraph:DKG) 交融计划:技术常识前置【一】- 文本匹配算法、常识交融学术界计划、常识交融业界落地计划、算法测评 KG 生产品质保障解说了文本匹配算法的综述,从经典的传统模型到孪生神经网络“双塔模型”再到预训练模型以及有监督无监督联结模型,期间也波及了近几年前沿的比照学习模型,之后提出了文本匹配技巧晋升计划,最终给出了 DKG 的落地计划。这边次要以原理解说和技术计划论述为主,之后会缓缓把我的项目开源进去,一起共建 KG,从常识抽取到常识交融、常识推理、品质评估等争取走通残缺的流程。

退出移动版