SentenceBert
Sentence-BERT: 如何通过对比学习得到更好的句子向量表示 - 哔哩哔哩 (bilibili.com)
(229条消息) Sentence-BERT详解_数学家是我理想的博客-CSDN博客_sentence-bert
动机:
直接把2个句子串联起来输入Bert做分类(即Cross-Encoder方式),当需要找N个句子里相似度最大的2个句子时,要经过Bert的次数是N*(N-1)/2次;计算量太大了;
把每个句子单独经过Bert,得到各自的句子向量后,再计算相似度,即Bi-Encoder方式,节省计算量;
孪生网络:
将句子对输入到参数共享的两个Bert模型中,然后Bert输出句子的所有字向量传入pooling层进行平均池化(在句子长度这个维度上对所有字向量求均值)(经实验,Mean Pooling比Max Pooling和[CLS]效果都好些)获取到每个句子的句向量表示。
文中损失函数用的均方误差MSE(Mean-Square Error):
直接用预训练的Bert来做Bi-Encoder,效果比Cross-Encoder更差;
怎么办?需要Fine tuning;
要预测的目标是2个句子之间的相似度;如果没有Label,则可通过对比学习来构造正负例样本;
对比学习:
假设有三个句子, s1,s2,s3 ,对应的向量分别是v1,v2,v3,句子类别分别是c1,c2,c3,我们不仅希望能通过 v 学习到 c ,还希望 v1 和 v2的距离小于 v1和 v3,也就是Dis(v1,v2)≤Dis(v1,v3),我们可以用triplet loss来表示:
如何找到合适的三元组( sa,sp,sn )来训练模型,其中 sp 和 sa 属于同一个"类别",被称为正样本, sn 和 sa 不是同一个"类别",被称为负样本,这里的类别是广义上的类别,可以是文本分类的类别,甚至也可以是每个句子单独对应一个类别(instance classification),典型的工作是恺明大神的MoCo系列。
直接分类:
如果已经有了句子对相似程度的标注数据,则没必要用对比学习;在拿到两个句子的向量 u 和 v 之后,如果句子对的标签是离散数值,作者设计了如下的分类网络结构: