特定畛域常识图谱(Domain-specific KnowledgeGraph:DKG)交融计划:技术常识前置【一】-文本匹配算法、常识交融学术界计划、常识交融业界落地计划、算法测评KG生产品质保障
0.前言
本我的项目次要围绕着特定畛域常识图谱(Domain-specific KnowledgeGraph:DKG)交融计划:技术常识前置【一】-文本匹配算法、常识交融学术界计划、常识交融业界落地计划、算法测评KG生产品质保障解说了文本匹配算法的综述,从经典的传统模型到孪生神经网络“双塔模型”再到预训练模型以及有监督无监督联结模型,期间也波及了近几年前沿的比照学习模型,之后提出了文本匹配技巧晋升计划,最终给出了DKG的落地计划。这边次要以原理解说和技术计划论述为主,之后会缓缓把我的项目开源进去,一起共建KG,从常识抽取到常识交融、常识推理、品质评估等争取走通残缺的流程。
1.文本匹配算法综述(短文本匹配)
文本匹配工作在自然语言解决中是十分重要的根底工作之一,个别钻研两段文本之间的关系。有很多利用场景;如信息检索、问答零碎、智能对话、文本甄别、智能举荐、文本数据去重、文本类似度计算、自然语言推理、问答零碎、信息检索等,但文本匹配或者说自然语言解决依然存在很多难点。这些自然语言解决工作在很大水平上都能够形象成文本匹配问题,比方信息检索能够归结为搜索词和文档资源的匹配,问答零碎能够归结为问题和候选答案的匹配,复述问题能够归结为两个同义句的匹配。
- 如语言不标准,同一句话能够有多种表达方式;如“股市跳水、股市大跌、股市一片绿”
- 歧义,同一个词语或句子在不同语境可能表白不同意思;如“割韭菜”,“领盒饭”,“苹果”“小米”等在不同语境下语义齐全不同
- 不标准或谬误的输出;如 “ yyds”,“绝绝子”“夺笋”“耗子尾汁”
- 须要常识依赖;如奥运冠军张怡宁绰号“乒乓大魔王”等。
短文本匹配即计算两个短文本的类似度,通常分成无监督形式、有监督形式、有监督+无监督形式
常见的文本匹配算法如下表(简略列举),按传统模型和深度模型简略的分为两类:
算法 | 类型 |
---|---|
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算法
#Bm25import mathimport jiebaclass 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》
要解决什么问题?
- 用于解决类别很多(或者说不确定),然而训练样本的类别数较少的分类工作(比方人脸识别、人脸认证)
- 通常的分类工作中,类别数目固定,且每类下的样本数也较多(比方ImageNet)
- 用了什么办法解决?
提出了一种思路:将输出映射为一个特征向量,应用两个向量之间的“间隔”(L1 Norm)来示意输出之间的差别(图像语义上的差距)。
基于上述思路设计了Siamese Network。每次须要输出两个样本作为一个样本对计算损失函数。
- [x] 罕用的softmax只须要输出一个样本。
- [x] FaceNet中的Triplet Loss须要输出三个样本。
- [x] 提出了Contrastive Loss用于训练。
- 成果如何?
文中进行了一个掂量两张人脸的类似度的试验,应用了多个数据库,较简单。siamese network当初仍然有很多中央应用,能够获得state-of-the-art的成果。
- 还存在什么问题?
- 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函数的设计应该是
- 当两个输出样本不类似(y=0)时,间隔Ew越大,损失越小,即对于Ew的枯燥递加函数。
- 当两个输出样本类似(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.预训练语言模型
- 第一阶段,应用通用的意料库训练语言模型,
- 第二阶段预训练的语言模型(BERT相干衍生的模型)做类似度工作,失去信息交互后的向量,
- 连贯全连贯层,输入概率。行将两个短文本拼接(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种策略:
- 将u、v拼接,接入全连贯网络,通过softmax输入,损失函数用穿插熵损失
- 间接计算两个文本的余弦类似度,损失函数用均方根误差
- 如果输出的是三元组
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层,为同一文本生成不同的编码。
- shuffle:更换position id的程序
- token cutoff:在某个token维度把embedding置为0
- feature cutoff:在embedding矩阵中,有768个维度,把某个维度的feature置为0
- 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计划一
特色工程
- 数据荡涤:大赛给的数据比拟规整,数据荡涤局部工作不多,简略做了特殊字符解决等操作。
- 数据加强
- 传递闭包裁减(标签传递)
依据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仅仅相差一个单词, 随机替换扭转语义。
少数属于问句, 随机替换扭转了语义。
- 模型抉择
在预训练模型的根底上通过反抗训练加强模型的泛化性能。
- BRET
Bert的一个上游根底工作语句对分类(Sentence Pair Classification Task), [CLS] Bert的输入有一个维度的向量示意 - BERT+CNN(LSTM)
将BERT的输入特色作为文本的示意向量, 而后前面再接上LSTM或者CNN(成果降落) - BERT+siamese
将大赛提供的category信息利用上, 借用孪生网络的思维与两个Query进行拼接(成果降落)。
- 后果剖析
- 单模型线上成果
目前所训练的模型中:
小模型中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计划二
- 摸索剖析
文本长度:训练集和验证集散布相似,大都集中在10-20个字
标签散布
总体思路
- 数据划分
采纳kfold穿插验证(左边的划分形式)
•利用全副数据,取得更多信息
•升高方差,进步模型性能
- 模型设计
二分类穿插熵损失函数:
- 模型交融
小模型同时退出CHIP2019数据训练
模型 | 特点 | 权重 | 退出内部句对数据 |
---|---|---|---|
BERT-wwm-ext | 全词Mask | 1 | YES |
Ernie-1.0 | 对词、实体及实体关系建模 | 1 | YES |
RoBERTa-large-pair | 面向相似性或句子对工作优化 | 1 | NO |
- 数据预处理
对称裁减、传递裁减(留神要放弃原来的散布,否则会过拟合)
- 训练
- 三种构造:(理论应用差异不大,第一种又好又简略)
- 反抗训练
#代码来自苏剑林bert4kerasdef 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)
- 预测
- 算数均匀→几何平均→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,从常识抽取到常识交融、常识推理、品质评估等争取走通残缺的流程。