持续创造,加快成长!这是我参加「日新方案 10 月更文应战」的第16天,点击查看活动详情


本文合计2944字,阅读大概需求花费6分钟


论文简介

论文链接:SimCSE: Simple Contrastive Learning of Sentence Embeddings

假如大家了解比照学习的话就好办了,这篇文章便是将比照学习运用到了自然语言处理范畴。起初对学习先是用在图像范畴的。假如你了解的话就能够继续往下看,假如你不了解的话我主张是先了解一下比照学习。 别的推荐几篇我写的比照学习的文章。

  • 诸神黄昏时代的比照学习 – ()
  • 军备竞赛时期的比照学习

无监督获取语句向量:

  • 运用预练习好的 Bert 直接获得语句向量,可所以 CLS 位的向量,也可所以不同 token 向量的平均值。

  • Bert-flow:On the Sentence Embeddings from Pre-trained Language Models,主要是运用流模型校正 Bert 的向量。

  • Bert-whitening:Whitening Sentence Representations for Better Semantics and Faster Retrieval,用预练习 Bert 获得一切语句的向量,得到语句向量矩阵,然后经过一个线性变换把语句向量矩阵变为一个均值 0,协方差矩阵为单位阵的矩阵。

有监督的办法主要是:

  • Sentence-Bert (SBERT):Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks,经过 Bert 的孪生网络获得两个语句的向量,进行有监督学习,SBERT 的结构如下图所示。

对于比照学习来说,最重要是怎么结构正负样本。

在图像中有多种结构比照学习的样本,比SimCLR中说到的:反转、部分裁剪、部分显出、裁剪翻转、调整饱和度、调整色彩、运用各种滤波器比方最大值滤波器,最小值滤波器、锐化滤波器。

SimCSE,丹琦女神把对比学习用到了NLP中了!

在自然语言处理中也有许多的数据增广办法,可是他们对语句的影响都特别大。会严峻下降比照学习的作用。为了处理这个问题SimCSE模型提出了一种经过随机采样dropout mask的操作来结构正样本的办法。模型运用的是BERT,每次出来的Dropout是不同的。随机dropout masks机制存在于模型的fully-connected layers和attention probabilities上,因而相同的输入,经过模型后会得到不同的成果。所以只需求将同一个语句两次喂给模型就能够得到两个不同的表明。运用这种办法产生出来的类似样本对语义完全共同,只是生成的embedding不同罢了,能够认为是数据增强的最小方式。比其他的数据增强办法都要好许多。

什么是dropout

SimCSE,丹琦女神把对比学习用到了NLP中了!

首要咱们要了解什么是dropout。dropout在深度学习中通常被用来防止模型过拟合。dropout最初由Hinton组于2014年提出。能够看一下我之前的文章:模型泛化 | 正则化 | 权重衰退 | dropout

模型为什么会过拟合。由于咱们的数据集相较于咱们的模型来说太小了。而咱们的模型相较于咱们的数据集来说太复杂。因而为了防止模型过拟合,咱们能够运用dropout,让模型在练习的时分忽略一些节点。就像上图中那样。这样模型在练习数据时每次都在练习不同的网络,模型不会太依靠某些部分的特征,所以模型的泛化性更强,下降了过拟合产生的概率。

dropout和其他数据增强办法进行比较

经过dropout masks机制进行数据增强结构正例的办法。

作者在STS-B数据集进步行试验。比较dropout与其他数据增强办法的差异。

裁剪,删去和替换等数据增强办法,作用均不如dropout masks机制,即便删去一个词也会危害功能,详细如下表所示:

SimCSE,丹琦女神把对比学习用到了NLP中了!

dropout正例与原始样本之间选用完全相同的语句,只要在向量表征过程中的dropout mask有所不同。能够视为一种最小方式的数据扩充。

不同的dropout rate

SimCSE,丹琦女神把对比学习用到了NLP中了!

为了验证模型dropout rate对无监督SimCSE的影响,作者在STS-B数据集进步行了融化试验。从上面表格中咱们能够看出当dropout rate设置为0.1的时分,模型在STS-B测验集的作用最好。

上图中Fixed0.1Fixed 0.1表明对于同一个样本运用相同的dropout mask,也便是说编码两次得到的向量是相同的,能够看到这种情况下作用是最差的。

我个人感觉Fixed0.1Fixed 0.1的时分能达到40%以上现已挺好的了。毕竟在我眼里或许会造成模型坍塌。

我还看了一下他人复现这篇论文的文章,复现的人说尝试了0.1 0.2 0.3,作用都差不多,最终仍是挑选了论文中的0.1.不。

比照学习评价目标

alignment 和 uniformity 是比照学习中比较重要的两种特点,可用于衡量比照学习的作用。

  • alignment 核算一切正样本对之间的距离,假如 alignment 越小,则正样本的向量越挨近,比照学习作用越好,核算公式如下:
ℓalign≜E(x,x+)∼ppos∥f(x)−f(x+)∥2\ell_{\text {align }} \triangleq \underset{\left(x, x^{+}\right) \sim p_{\text {pos }}}{\mathbb{E}}\left\|f(x)-f\left(x^{+}\right)\right\|^{2}
  • uniformity 表明一切语句向量分布的均匀程度,越小表明向量分布越均匀,比照学习作用越好,核算公式如下:
ℓuniform≜log⁡Ex,y∼i.i.d.pdatae−2∥f(x)−f(y)∥2\ell_{\text {uniform }} \triangleq \log \quad \mathbb{E}_{x, y \stackrel{i . i . d .}{\sim} p_{\text {data }}} e^{-2\|f(x)-f(y)\|^{2}}

其间pdatap_{data}表明数据分布。这两个目标与比照学习的目标是共同的:正例之间学到的特征应该是附近的,而任意向量的语义特征应该尽或许地涣散在超球体上。

至于这个“超球体”我认为是像InstDisc中右侧这个图相同,将每个样本的特征表明映射到空间中。(个人观点,假如了解有错请各位指导。)

SimCSE,丹琦女神把对比学习用到了NLP中了!

无监督

SimCSE,丹琦女神把对比学习用到了NLP中了!

无监督的目标函数是这样的。看一下上边,他图中示例是把三个语句作为输入传给编码器,然后编码器会得到对应语句的embedding。输入两次会得到两次不同的embedding。一个语句和它对应增强的语句是正样本,其余的语句作为负样本。终究运用的损失函数如下:

ℓi=−log⁡esim⁡(hizi,hizi′)/∑j=1Nesim⁡(hizi,hjzj′)/\ell_{i}=-\log \frac{e^{\operatorname{sim}\left(\mathbf{h}_{i}^{z_{i}}, \mathbf{h}_{i}^{z_{i}^{\prime}}\right) / \tau}}{\sum_{j=1}^{N} e^{\operatorname{sim}\left(\mathbf{h}_{i}^{z_{i}}, \mathbf{h}_{j}^{z_{j}^{\prime}}\right) / \tau}}

有监督

SimCSE,丹琦女神把对比学习用到了NLP中了!

运用有监督学习的一个难点,便是要找到适合结构正负样本的数据集。终究作者的挑选如下:

SimCSE,丹琦女神把对比学习用到了NLP中了!

那它的正负利是怎么结构的呢。 以其间的NLI数据集为例,在这个数据会集打进一个前提。便是注释者需求手动编写一个绝对正确的语句及蕴语句。一个或许正确的语句,中立语句。和一个绝对过错的语句对立语句。然后这篇论文就将这个数据集进行扩展,将原来的(语句,包括语句)改变为(语句,包括语句,对立语句)。在这个数据会集正样本是这个语句及其包括包括关系的语句。负样本有两种,是这个语句包括对立关系的语句以及其他的语句。 损失函数如下:

Li=−log⁡esim⁡(hi,hi+)/∑j=1N(esim⁡(hi,hj+)/+esim⁡(hi,hj−)/)L_{i}=-\log \frac{e^{\operatorname{sim}\left(h_{i}, h_{i}^{+}\right) / \tau}}{\sum_{j=1}^{N}\left(e^{\operatorname{sim}\left(h_{i}, h_{j}^{+}\right) / \tau}+e^{\operatorname{sim}\left(h_{i}, h_{j}^{-}\right) / \tau}\right)}

成果

对7个语义文本类似度(STS)使命进行了试验,将无监督和有监督的SimCSE与STS使命中的最先进的语句嵌入办法进行了比较,能够发现,无监督和有监督的SimCSE均获得了sota的作用,详细如下表所示:

SimCSE,丹琦女神把对比学习用到了NLP中了!

由于SimCSE做的是一个语句表征的使命,即获得更好的语句的embedding,试验作用如上图。作者运用根据BERT和根据RoBERTa的SimCSE别离与Baseline进行比较,均获得较好的作用。

下边是SimCSE运用不同版别的BERT及其变体做出的模型,对应的模型能够直接从hugging face上获取.

Model Avg. STS
princeton-nlp/unsup-simcse-bert-base-uncased 76.25
princeton-nlp/unsup-simcse-bert-large-uncased 78.41
princeton-nlp/unsup-simcse-roberta-base 76.57
princeton-nlp/unsup-simcse-roberta-large 78.90
princeton-nlp/sup-simcse-bert-base-uncased 81.57
princeton-nlp/sup-simcse-bert-large-uncased 82.21
princeton-nlp/sup-simcse-roberta-base 82.52
princeton-nlp/sup-simcse-roberta-large 83.76

代码实践

已然它的作用这么好,怎么方便的在电脑上运用SimCSE呢?

先安装一下:

pip install simcse

用这两行代码加载模型。我上面那个表格里写了不同的版别, SimCSE("在这里填写不同版别")

from simcse import SimCSE
model = SimCSE("princeton-nlp/sup-simcse-bert-base-uncased")

已然是用来做sentence embedding的,那先看一下他怎么给语句编码:

embeddings = model.encode("A woman is reading.")

它反应比较慢,你需求等一下它才会出成果。不出意外的话,它应该会给出一个特别长的embedding编码。

我输出一下看一下,他应该是把一个语句编码成768维度的向量。

SimCSE,丹琦女神把对比学习用到了NLP中了!

核算两组语句之间的‎‎余弦类似性‎:

sentences_a = ['A woman is reading.', 'A man is playing a guitar.']
sentences_b = ['He plays guitar.', 'A woman is making a photo.']
similarities = model.similarity(sentences_a, sentences_b)
similarities1 = model.similarity('A woman is reading.', 'A man is playing a guitar.')
similarities2 = model.similarity('He plays guitar.', 'A man is playing a guitar.')

除了核算语句组之间,我还放了核算两个语句的一些类似性。最终作用显现如下:

SimCSE,丹琦女神把对比学习用到了NLP中了!

他还能够为那一组语句构建index,构建之后你再输入一个语句,从其间进行查找。他会找到和哪个语句更为类似。而且输出类似度是多少。

sentences = ['A woman is reading.', 'A man is playing a guitar.']
model.build_index(sentences)
results = model.search("He plays guitar.")

在上一段代码中我现已核算过这两个语句之间的类似度,咱们能够看到跟上一段代码中的成果是相同的。

similarities2 = model.similarity('He plays guitar.', 'A man is playing a guitar.')的输出成果是0.8934233….. 现在你查询He plays guitar.它输出最类似的语句为A man is playing a guitar.类似度为0.8934233…..

SimCSE,丹琦女神把对比学习用到了NLP中了!