一文搞懂对比学习(Contrastive Learning)
对比学习
自监督学习(Self-supervised learning)可以避免对数据集进行大量的标签标注。把自己定义的伪标签当作训练的信号,然后把学习到的表示(representation)用作下游任务里。最近,对比学习被当作自监督学习中一个非常重要的一部分,被广泛运用在计算机视觉、自然语言处理等领域。它的目标是:将一个样本的不同的、增强过的新样本们在嵌入空间中尽可能地近,然后让不同的样本之间尽可能地远
一般来说,机器学习任务分为监督学习和非监督学习
- 监督学习会有标注数据,训练的目标是为了让训练数据预测的标签或者得分接近真实的标签或者得分
- 无监督学习没有真实的标注数据,通常会设定一些度量指标或者启发函数,模型的训练的目标就是让这些指标达到一个极值收敛
对比函数主要的目标是构造一个对比损失或者对比函数,使得正样例的score远远大于负样例的score
因为这个函数的目标是为了建模构建两个类别的差异性,所以又称对比损失(Contrastive loss)
所以说具体到不同的问题有很多不同的构建对比loss的方式,例如用内积来计算样本的相似度,对比loss可以写成,
这个loss鼓励正例的相似度足够大(分子),鼓励负例的相似度足够小(分母)。类似于LDA(Linear Discriminant Analysis)
,对比学习是一种度量学习,度量学习的目标就是让同类别的距离尽可能近,不同类别的距离尽可能远。LDA、SVM是监督学习,现在更多的研究重点是通过自监督方式构建同源数据作为正样例来做大规模的预训练,有足够多的准确的同类标注数据做监督对比学习也是可以的
从上面可以看出,说对比学习最终的两个点就是正负样例的构建以及对比损失的构建。下面我们介绍一下文本表示还有对比学习在NLP文本表示的一些方法
一. 基于BERT的句子表示
BERT
虽然BERT在很多下游任务表现非常出色,但是BERT缺不适合做文本表示,一个很重要的原因是在预训练的时候并没有把文本表示作为目标来训练,而只是训练下游的NSP
或者MLM
任务,而这些任务对文本表示并没有正向作用,所以实际测试情况,BERT的表示直接拿来做文本表示,在计算文本相似度(STS)时,效果远不如Glove
的向量平均,所以很多对BERT做了改进,使其适合作文本表征
各向异性是指单词嵌入在向量空间中占据一个狭窄的圆锥体
- BERT的词向量在空间中并非均匀分布,而是呈锥形。高频词都靠近原点,而低频词远离原点,相当于这两种词处于了空间中不同的区域,那高频词和低频词之间的相似度就不再适用
- 低频词的分布稀疏,因为其表示训练不充分,导致该区域存在语义定义不完整的地方(poorly defined),这样算出来的相似度也有问题
Understanding Contrastive Representation Learning through Alignment and Uniformity on the Hypersphere中指出好的对比学习系统应该具备两个属性:
Alignment:指的是相似的例子,也就是正例,映射到单位超球面后应该有接近的特征,也即是说,在超球面上距离比较近
Uniformity:指的是系统应该倾向在特征里保留尽可能多的信息,这等价于使得映射到单位超球面的特征,尽可能均匀地分布在球面上,分布得越均匀,意味着保留的信息越充分。分布均匀意味着两两有差异,也意味着各自保有独有信息,这代表信息保留充分
所以很多时候,会使用相关系数衡量表示学习得到的向量好坏
BERT-flow
基于以上对相似度的深入探讨和问题研究,BERT-flow基于流式生成模型,将BERT的表示可逆地映射到一个均匀的空间,上述的问题就迎刃而解了
标准高斯分布是各向同性的,在传统的词嵌入方法中,研究表明词向量矩阵的前面几个奇异值通常和高频词高度相关,通过将嵌入分布变换到各向同性的分布上,奇异值就可以被压缩。另外,标准高斯分布是凸的,或者说是没有空洞
,因此语义分布更为光滑
Flow-based Generative Model:
基于流式生成模型建立了从潜在空间到观测空间的可逆转换,变换过程如下:
具体地,学习一个可逆的映射,把服从高斯分布的变量映射到BERT编码的,那就可以把到均匀的高斯分布。在训练的过程中保持BERT的参数不变,只优化标准化流的参数,优化目标为最大化从高斯分布中产生BERT表示的概率:
Sentence-BERT
Sentence-BERT是基于一个很直接的思想,既然原先的BERT任务不适合做句子表示,换个任务就好了,所以Sentence-BERT直接将添加了一个句子相似度的任务,两个正样本经过BERT得到句子向量,然后句子向量再做拼接,相减,计算softmax
针对分类问题,作者将向量三个向量拼接在一起,然后乘以一个权重参数,其中表示向量的维度,表示label的数量
损失函数为CrossEntropyLoss
二. 基于对比学习的BERT表示学习
上文分析得到,BERT得到的句子向量本身不适合做句子的相似度计算,所以对比学习就通过对比损失直接用句子表示来构建损失函数
SimCSE
SimCSE的思路是非常新颖的,因为本身BERT就是有DROPOUT操作,所以讲一句话输入到BERT两次,因为有DROPOUT操作的存在,所以这个就是两个不同的向量,这个构成了无监督SimCSE的训练方式,一个batch内,每句话输入两次,构造正样本,同一个batch内的其他作为负样本。监督方式训练的话,还是使用NLI的数据,entailment是正样本,contradiction的是负样本
监督的loss计算方式:
无监督loss的计算方式:
ConSERT
ConSERT方法以Simese Net结构为基础,使用一个预训练语言模型为基础,在一个任务同领域的无标注语料库上进行fine-tune,ConSERT的整体模型结构如下所示:
对每一条输入的训练文本,首先会进入到数据增强模块,它可以将这条文本转换为两个不同版本的token embeddings,然后通过BERT的多层transformer编码后,利用平均池化便可以分别得到这个句子的两个表征和。在训练的过程中首先从数据集中采样一个Batch的文本(条),那么通过数据增强后便可以得到条样本表征,然后在训练的过程中让每个样本取寻找与自己对应的另一个增强样本,而其它的条样本则被当做负样本,所以目标函数就是让原本属于同一样本的表示在空间中接近,同时远离其它的负样本:
上式中函数为余弦相似度函数,表示对应的句向量,表示temperature,是一个超参数,在论文中取0.1
它的结构主要包括以下几个部分:
- 共享BERT编码器:且在BERT的最后一层使用平均池化的方法将句子表征为句向量
- 对比损失层:用于在一个Batch的样本中计算损失的对比,最大化同一个样本不同增强版本句向量的相似度,同时使得不同样本的句向量相互远离
- 数据增强模块:可以在Embedding层将输入的同一个samples生成为不同版本
文本数据增强方法:
在论文中,文本数据增强方法是比较重要的一个部分,很多的文本增强方法(回译、CBERT)无法保证保证语义一致,并且每一次数据增强都需要做一次模型Inference,开销会很大。所以论文论文探索了4种在Embedding层隐式生成增强样本的方法 :
- Adversarial Attack:通过梯度反传生成对抗扰动,将该扰动加到原本的Embedding矩阵上,就能得到增强后的样本。由于生成对抗扰动需要梯度反传,因此这一数据增强方法仅适用于有监督训练的场景
- Token Shuffling:这一方法扰乱输入样本的词序。由于Transformer结构没有“位置”的概念,模型对Token位置的感知全靠Embedding中的Positionids得到。因此在实现上,只需要将Position Ids进行Shuffle即可
- Feature Cutoff:又可以进一步分为两种,Token Cutoff:随机选取Token,将对应Token的Embedding整行置为零。Feature Cutoff:随机选取Embedding的Feature,将选取的Feature维度整列置为零
- Dropout:Embedding中的每一个元素都以一定概率置为零,与Cutoff不同的是,该方法并没有按行或者按列的约束
这四种方法均可以通过对Embedding矩阵(或是BERT的Position Encoding)进行修改得到,因此相比显式生成增强文本的方法更为高效。实验的结果表明Token Shuffle和Feature Cutoff的组合取得了最优性能,从单种数据增强的方法而言,Token Shuffle > Token Cutoff >> Feature Cutoff ≈ Dropout >> None
Self-BERT
考虑到句子向量被广泛用于计算两个句子的相似性,对比学习引入的归纳偏差对BERT来说可能有助于良好地在这些任务中工作。但问题是,句子级的对比学习通常需要使用数据增强或关于训练数据的先验知识,例如句子顺序信息,以便合理的构建正/负样本,并通过利用BERT的隐藏表示来规避这些约束
-
将BERT分别克隆两个副本,即和。在训练期间,被固定以提供训练信号,而则通过微调来构建更好的句子嵌入。区分两个BERT的原因是希望能防止计算的训练信号随着训练的进行而退化,这通常会发生在时。这种设计决策也反映了我们的观点,我们的目标是将存储在BERT不同层中的知识动态合并以生产句子嵌入,而不是通过额外训练引入新的信息。来自最后一层的[CLS]向量,即被视为最终的句子嵌入,目标是分别在微调期间和微调后来优化和利用该向量
-
给定mini-batch中的个句子,记为,将每个句子带入并计算字符级隐藏表示:
其中,是BERT中的隐藏层的数量,是句子的长度,是BERT隐藏表示的维度。然后将池化函数应用于各层的以计算出各种句子级特征,即。最后,通过应用采样函数来选择一个最终的特征:
由于对和的定义中没有特定的限制,除非另有说明,否则分别使用最大池化和均匀采样来作为和。采样函数的这种简单选择意味着每个具有相同的重要性,不同的BERT层专门捕获不同的语言概念。 -
第三,采用下式来计算句子的句子嵌入:
其中对应着从BERT最后一层获取的[CLS]向量。然后,收集到一个计算的句子向量集合,并且对于所有的,计算对比学习目标NT-Xent损失:
其中,是一个温度超参数,是由MLP层组成的映射头,是余弦相似度计算函数,μ(·)是如下定义的匹配函数:最后,相加所有的并除以,然后,添加一个正则化项来防止偏离太远。因此,最终的损失为:
其中,是一个超参数。
通过改进BERT,使得句子嵌入与具有更高的相似性,其中是句子的另一种表示方式。在训练完成后,移除除之外的所有组件,只使用作为最终句子表示
Learning Objective Optimization:
在该节中,对通用对比学习目标(NT-Xent)
的损失进行简单变化,其由四个因素组成。给定句子和,在不丧失一般性情况下,由如下四个因素构成:
- 或者:这是损失的主要组成部分,反映了核心句子矢量的应该与BERT的中间特征一致
- :强制句子嵌入彼此远离
- 或者:强制句子嵌入或彼此远离
- :强制句子嵌入彼此远离
尽管上述四个因素都扮演了各自的角色,但一些组件可能是无用的甚至对目标产生负面影响
-
首先,由于目标是借助来改善,因此需要重新定义了损失,使得更多地关注,而不是同等考虑和:
其中。换句话说,只用作被鼓励接近或远离的点,并且不被视为要优化的目标。这种修改自然去除了第(4)个因素的影响 -
此外,因素(2)对于提高模型性能也不显着,因此得到一个新的目标:
-
最后,通过允许使用不同层的多个特征来指导,从而是得因素(1)到(3)多样化:
期望这种细化后的学习目标可以通过考虑额外提供的样本来获得更精确和丰富的训练信号,优化损失的最终形式是: