BERT句向量(一):Sentence-BERT

前言

句向量:能够表征整个句子语义的向量,目前效果比较好的方法还是通过bert模型结构来实现,也是本文的主题。

有了句子向量,我们可以将其用于聚类,处理大规模的文本相似度比较,或基于语义搜索的信息检索。

[En]

With sentence vector, we can use it for clustering, dealing with large-scale text similarity comparison, or information retrieval based on semantic search.

例如搜索系统中的输入query和匹配文档document、Q&A任务的问题和答案等等,都可以转化为计算两个句子的语义相似/相关度,相关度最高的n个作为模型的返回结果。

题外话

这种类似的模型一般称为passage retrieval models,即段落检索,有两个代表:

  1. sparse models:BM25、TF-IDF等;
  2. dense models(DPR,Dense Passage Retrieval):将query和doc(question和passage/answer)都转化为稠密向量,然后通过faiss等工具进行相关召回。

原生Bert

原生的BERT模型在诸多句子分类和句子对的回归任务上都取得了state-of-the-art的表现,它使用一种 cross-encoder的结构:将两个句子拼接输入到模型,经过带有self attention的transformer网络得到最终的预测值。

但这种做法不适用于大量句子对的回归任务,例如给定10000个句子,找出每个句子最相似的句子,那么每个句子就得需要与其他所有句子进行两两组合,才能得到与所有句子的相似度,即需要进行n*(n-1)/2= 49995000次的推理计算,这显然是不合理的。

这其实 与推荐场景类似,采用这种结构的话,query需要与所有的doc进行分别计算,才能分数相关度最高的doc,这是不现实。所以这种做法一般是放在后面的 排序阶段

而在此之前,一般会先经过 召回阶段,则是需要事先将所有doc输入到bert模型,提取出句向量进行存储,实际使用时,实时计算query的句向量,然后通过faiss等ann工具,来从所有doc中召回相关度最高的n个。

因此,sentence-bert此时就派上用场,它使得bert模型能够提取表征句子语义的句向量。

Sentence-BERT

相关论文:《Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks》

pooling strategies

其实原生bert模型本身是具备句向量提取的能力,一般是以下3种方法,sentence-bert也是采用相同的方法:

  1. CLS:使用[CLS]字符最后一层的输出向量,作为句向量;
  2. MEAN:使用句子的所有字符的最后一层输出向量,计算它们的均值,作为句向量;
  3. MAX:使用句子的所有字符的最后一层输出向量,所有字符向量对应位置提取最大值,作为句向量。

但是,如果直接使用原生bert模型来提取句向量,效果十分不理想,甚至不如GloVe提取的句向量。

fine-tune

所以,作者提出一种针对句向量,对bert模型进行微调的方法,包括无监督和监督训练。

BERT句向量(一):Sentence-BERT

fine-tune的三种结构:

1. Classification Objective Function

如图1的分类结构,句子A和句子B输入到 同个bert模型(参数绑定),然后使用[CLS]向量或者所有字符的向量均值得到A的句向量u、B的句向量v,然后拼接u、v和 element-wise的 |u-v|,最后通过softmax做一个k分类,loss为cross-entropy;

BERT句向量(一):Sentence-BERT

2. Regression Objective Function

如图2的回归结构,同样的方法得到u和v, 再经过cosine函数得到u和v的相似度,使用MSE( mean-squared-error)作为loss;

3. Triplet Objective Function

最后一种为三元组结构,如下式,句子a和p为负例,a和n为正例,s a s_a s a ​为句子a的句向量,方法同上。这个结构是让负例句子的距离要尽量比正例的大

BERT句向量(一):Sentence-BERT

其中|| · ||是距离度量,例如欧式距离,

ξ \xi ξ为 margin ,控制负例和正例句子的距离差最小为ξ \xi ξ

; inference

推理阶段,按照上图2的做法,两个句子u和v输入到Sentence-BERT结构微调后的模型,选择一种pooling策略,得到句子的向量,然后使用cosine函数来计算两个句子的相似/相关度。

无监督训练

作者使用 SNLI(Bowman et al., 2015) 和Multi-Genre NLI(Williams et al., 2018)两个公开的数据集,带有三种标签 contradiction、eintailment、neutral的句子对。

使用Classifification Objective Function来对bert模型进行微调,详细参数为:batch_size为16、Adam optimizer、2e-5的学习率、10%的线性学习率warmup,采用MEAN的pooling策略。

然后在STS数据集上进行验证, 由于未使用到目标数据集,因此可以认为是无监督训练,具体效果如下:

( STS12-STS16:SemEval 2012-2016, STSb: STSbenchmark, SICK-R: SICK relatedness dataset,这些数据集带有0-5级的相关程度)

明显看出微调后的sentence-bert比原生bert的句向量效果提升了许多,并且使用RoBERTa可以进一步提升效果。

(作者也是做了实验,才得出原生bert句向量甚至不如GloVe的结论)

BERT句向量(一):Sentence-BERT

; 监督训练

上面提到,STS数据的标签是0-5级的相关程度,作者使用了regression objective function的结构进行微调SBERT。

对两种监督培训方案进行了测试。

[En]

Two kinds of supervision training schemes were tested.

  1. 仅使用STSb数据进行监督训练;
  2. 先在NLI数据进行训练,然后再使用STSb数据

结果如下:

监督训练比无监督训练效果进一步提升,并且BERT的模型大小影响较大,BERT-large比base提升3-4点;

但使用RoBERTa未没有明显的效果提升。

BERT句向量(一):Sentence-BERT

代码实现

tensorflow1.x:https://github.com/QunBB/DeepLearning/tree/main/NLP/sentence_bert/sbert

pytorch推荐使用:Sentence-Transformers

Original: https://blog.csdn.net/sgyuanshi/article/details/124415436
Author: 我就算饿死也不做程序员
Title: BERT句向量(一):Sentence-BERT

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/527583/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球