一文搞懂对比学习(Contrastive Learning)

对比学习

自监督学习(Self-supervised learning)可以避免对数据集进行大量的标签标注。把自己定义的伪标签当作训练的信号,然后把学习到的表示(representation)用作下游任务里。最近,对比学习被当作自监督学习中一个非常重要的一部分,被广泛运用在计算机视觉、自然语言处理等领域。它的目标是:将一个样本的不同的、增强过的新样本们在嵌入空间中尽可能地近,然后让不同的样本之间尽可能地远

一般来说,机器学习任务分为监督学习和非监督学习

  • 监督学习会有标注数据,训练的目标是为了让训练数据预测的标签或者得分接近真实的标签或者得分
  • 无监督学习没有真实的标注数据,通常会设定一些度量指标或者启发函数,模型的训练的目标就是让这些指标达到一个极值收敛

对比函数主要的目标是构造一个对比损失或者对比函数,使得正样例的score远远大于负样例的score
Score(f(x),f(x^+))>>Score(f(x),f(x^-))\tag{1}
因为这个函数的目标是为了建模构建两个类别的差异性,所以又称对比损失(Contrastive loss)

所以说具体到不同的问题有很多不同的构建对比loss的方式,例如用内积来计算样本的相似度,对比loss可以写成,
L_N=-E_X \left[ log \frac{exp(f(x)^Tf(x^+))}{exp(f(x)^Tf(x^+))+\sum_{j=1}^{N-1}exp(f(x)^Tf(x_j^-))}\right]\tag{2}
这个loss鼓励正例的相似度足够大(分子),鼓励负例的相似度足够小(分母)。类似于LDA(Linear Discriminant Analysis),对比学习是一种度量学习,度量学习的目标就是让同类别的距离尽可能近,不同类别的距离尽可能远。LDA、SVM是监督学习,现在更多的研究重点是通过自监督方式构建同源数据作为正样例来做大规模的预训练,有足够多的准确的同类标注数据做监督对比学习也是可以的

从上面可以看出,说对比学习最终的两个点就是正负样例的构建以及对比损失的构建。下面我们介绍一下文本表示还有对比学习在NLP文本表示的一些方法

一. 基于BERT的句子表示

BERT

虽然BERT在很多下游任务表现非常出色,但是BERT缺不适合做文本表示,一个很重要的原因是在预训练的时候并没有把文本表示作为目标来训练,而只是训练下游的NSP或者MLM任务,而这些任务对文本表示并没有正向作用,所以实际测试情况,BERT的表示直接拿来做文本表示,在计算文本相似度(STS)时,效果远不如Glove的向量平均,所以很多对BERT做了改进,使其适合作文本表征

各向异性是指单词嵌入在向量空间中占据一个狭窄的圆锥体

  1. BERT的词向量在空间中并非均匀分布,而是呈锥形。高频词都靠近原点,而低频词远离原点,相当于这两种词处于了空间中不同的区域,那高频词和低频词之间的相似度就不再适用
  2. 低频词的分布稀疏,因为其表示训练不充分,导致该区域存在语义定义不完整的地方(poorly defined),这样算出来的相似度也有问题

Understanding Contrastive Representation Learning through Alignment and Uniformity on the Hypersphere中指出好的对比学习系统应该具备两个属性:

Alignment:指的是相似的例子,也就是正例,映射到单位超球面后应该有接近的特征,也即是说,在超球面上距离比较近

Uniformity:指的是系统应该倾向在特征里保留尽可能多的信息,这等价于使得映射到单位超球面的特征,尽可能均匀地分布在球面上,分布得越均匀,意味着保留的信息越充分。分布均匀意味着两两有差异,也意味着各自保有独有信息,这代表信息保留充分

所以很多时候,会使用相关系数衡量表示学习得到的向量好坏

BERT-flow

基于以上对相似度的深入探讨和问题研究,BERT-flow基于流式生成模型,将BERT的表示可逆地映射到一个均匀的空间,上述的问题就迎刃而解了

标准高斯分布是各向同性的,在传统的词嵌入方法中,研究表明词向量矩阵的前面几个奇异值通常和高频词高度相关,通过将嵌入分布变换到各向同性的分布上,奇异值就可以被压缩。另外,标准高斯分布是凸的,或者说是没有空洞,因此语义分布更为光滑

Flow-based Generative Model:

基于流式生成模型建立了从潜在空间z到观测空间u的可逆转换,变换过程如下:
\mathrm{z} \sim p_{\mathcal{Z}}(\mathrm{z}), \mathbf{u}=f_{\phi}(\mathrm{z})\tag{3}

p_{\mathcal{U}}(\mathbf{u})=p_{\mathcal{Z}}\left(f_{\phi}^{-1}(\mathbf{u})\right)\left|\operatorname{det} \frac{\partial f_{\phi}^{-1}(\mathbf{u})}{\partial \mathbf{u}}\right|\tag{4}

具体地,学习一个可逆的映射f,把服从高斯分布的变量z映射到BERT编码的u,那f^{-1}就可以把u到均匀的高斯分布。在训练的过程中保持BERT的参数不变,只优化标准化流的参数,优化目标为最大化从高斯分布中产生BERT表示的概率:
\begin{aligned} \max _{\phi} & \mathbb{E}_{\mathbf{u}=\mathrm{BERT}(\text { sentence }), \text { sentence } \sim \mathcal{D}} ( \log p_{\mathcal{Z}}\left(f_{\phi}^{-1}(\mathbf{u})\right)+\log \left|\operatorname{det} \frac{\partial f_{\phi}^{-1}(\mathbf{u})}{\partial \mathbf{u}}\right| \end{aligned})\tag{5}

Sentence-BERT

Sentence-BERT是基于一个很直接的思想,既然原先的BERT任务不适合做句子表示,换个任务就好了,所以Sentence-BERT直接将添加了一个句子相似度的任务,两个正样本经过BERT得到句子向量,然后句子向量再做拼接,相减,计算softmax


针对分类问题,作者将向量u,v,|u-v|三个向量拼接在一起,然后乘以一个权重参数W_t\in \mathbb{R}^{3n\times k},其中n表示向量的维度,k表示label的数量
o = softmax(W_t[u;v;|u-v|])\tag{6}
损失函数为CrossEntropyLoss

二. 基于对比学习的BERT表示学习

上文分析得到,BERT得到的句子向量本身不适合做句子的相似度计算,所以对比学习就通过对比损失直接用句子表示来构建损失函数

SimCSE

SimCSE的思路是非常新颖的,因为本身BERT就是有DROPOUT操作,所以讲一句话输入到BERT两次,因为有DROPOUT操作的存在,所以这个就是两个不同的向量,这个构成了无监督SimCSE的训练方式,一个batch内,每句话输入两次,构造正样本,同一个batch内的其他作为负样本。监督方式训练的话,还是使用NLI的数据,entailment是正样本,contradiction的是负样本


监督的loss计算方式:
-log\frac{e^{sim(h_i,h_i^{+})/\tau}}{\sum_{j=1}^{N}(e^{sim(h_i,h_j^{+})/\tau}+e^{sim(h_i,h_j^{-})/\tau})}\tag{7}
无监督loss的计算方式:
-log\frac{e^{sim(h_i^{z_i},h_i^{z_i^{'}})/\tau}}{\sum_{j=1}^{N}e^{sim(h_i^{z_i},h_j^{z_j^{'}})/\tau}}\tag{8}

ConSERT

ConSERT方法以Simese Net结构为基础,使用一个预训练语言模型M为基础,在一个任务同领域的无标注语料库D上进行fine-tune,ConSERT的整体模型结构如下所示:

对每一条输入的训练文本x,首先会进入到数据增强模块,它可以将这条文本转换为两个不同版本的token embeddings,然后通过BERT的多层transformer编码后,利用平均池化便可以分别得到这个句子的两个表征r_ir_j。在训练的过程中首先从数据集D中采样一个Batch的文本(N条),那么通过数据增强后便可以得到2N条样本表征,然后在训练的过程中让每个样本取寻找与自己对应的另一个增强样本,而其它的2N-1条样本则被当做负样本,所以目标函数就是让原本属于同一样本的表示在空间中接近,同时远离其它的负样本:
L_{i,j} = -log\frac{exp(sim(r_{i},r_{j})/\tau)}{\sum_{k=1}^{2N}{l_{k\ne i}exp(sim(r_{i},r_{k})/\tau)}}\tag{9}
上式中sim函数为余弦相似度函数,r表示对应的句向量,\tau表示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的隐藏表示来规避这些约束

  1. 将BERT分别克隆两个副本,即BERT_F(fixed)BERT_T(tuned)。在训练期间,BERT_F被固定以提供训练信号,而BERT_T则通过微调来构建更好的句子嵌入。区分两个BERT的原因是希望能防止BERT_F计算的训练信号随着训练的进行而退化,这通常会发生在BERT_F=BERT_T时。这种设计决策也反映了我们的观点,我们的目标是将存储在BERT不同层中的知识动态合并以生产句子嵌入,而不是通过额外训练引入新的信息。来自BERT_T最后一层的[CLS]向量,即\textbf c_i被视为最终的句子嵌入,目标是分别在微调期间和微调后来优化和利用该向量

  2. 给定mini-batch中的b个句子,记为s_1,s_2,···,s_b,将每个句子s_i带入BERT_F并计算字符级隐藏表示H_{i,k}∈\mathbb R^{len(s_i)×d}
    [H_{i,0};H_{i,1}; · · · ;H_{i,k}; · · · ;H_{i,l}]=BERT_F(s_i)\tag{10}
    其中0≤k≤ll是BERT中的隐藏层的数量,len(s_i)是句子的长度,d是BERT隐藏表示的维度。然后将池化函数p应用于各层的H_{i,k}以计算出各种句子级特征\textbf h_{i,k}∈\mathbb R^d,即\textbf h_{i,k}=p(H_{i,k})。最后,通过应用采样函数σ来选择一个最终的特征:
    \textbf h_i=\sigma(\{\textbf h_{i,k}|0\le k\le l\})\tag{11}
    由于对p\sigma的定义中没有特定的限制,除非另有说明,否则分别使用最大池化和均匀采样来作为p\sigma。采样函数的这种简单选择意味着每个H_{i,k}具有相同的重要性,不同的BERT层专门捕获不同的语言概念。

  3. 第三,采用下式来计算句子s_i的句子嵌入\textbf c_i
    \textbf c_i=BERT_T(s_i)_{[CLS]}\tag{12}
    其中BERT(·)_{[CLS]}对应着从BERT最后一层获取的[CLS]向量。然后,收集到一个计算的句子向量集合X=\{\textbf x|\textbf x\in \{\textbf c_i\}∪\{\textbf h_i\}\},并且对于所有的\textbf x_m\in X,计算对比学习目标NT-Xent损失:
    \begin{array}{cc} L^{base}_m=-log(\phi(\textbf x_m,\mu(\textbf x_m))/Z),\\ where~\phi(\textbf u,\textbf v)=exp(g(f(\textbf u),f(\textbf v))/\tau)\\ and~Z=\sum^{2b}_{n=1,n\ne m}\phi(\textbf x_m,\textbf x_n). \end{array}\tag{13}
    其中,τ是一个温度超参数,f是由MLP层组成的映射头,g(\textbf u,\textbf v)=\textbf u·\textbf v/ ||\textbf u||~||\textbf v||是余弦相似度计算函数,μ(·)是如下定义的匹配函数:

    \mu(\textbf x)=\begin{cases} \textbf h_i & if~\textbf x~is~equal~to~\textbf c_i.\\ \textbf c_i & if~\textbf x~is~equal~to~\textbf h_i. \end{cases}\tag{14}

    最后,相加所有的L^{base}_m并除以2b,然后,添加一个正则化项L^{reg}=||BERT_F-BERT_T||^2_2来防止BERT_T偏离BERT_F太远。因此,最终的损失L^{base}为:
    L^{base}=\frac{1}{2b}\sum^{2b}_{m=1}L^{base}_m+\lambda\cdot L^{reg}\tag{15}

其中,\lambda是一个超参数。
通过改进BERT,使得句子嵌入\textbf c_i\textbf h_i具有更高的相似性,其中\textbf h_i是句子s_i的另一种表示方式。在训练完成后,移除除BERT_T之外的所有组件,只使用c_i作为最终句子表示

Learning Objective Optimization:

在该节中,对通用对比学习目标(NT-Xent)的损失进行简单变化,其由四个因素组成。给定句子s_is_j,在不丧失一般性情况下,由如下四个因素构成:

  1. \textbf c_i\rightarrow \leftarrow \textbf h_i或者\textbf c_j\rightarrow \leftarrow \textbf h_j cj:这是损失的主要组成部分,反映了核心句子矢量\textbf c_i的应该与BERT的中间特征\textbf h_i一致
  2. \textbf c_i←→\textbf c_j:强制句子嵌入(\textbf c_i,\textbf c_j)彼此远离
  3. \textbf c_i←→\textbf h_j或者\textbf h_i←→\textbf c_j:强制句子嵌入(\textbf c_i,\textbf h_j)(\textbf h_i,\textbf c_j)彼此远离
  4. \textbf h_i←→\textbf h_j:强制句子嵌入(\textbf h_i,\textbf h_j)彼此远离

尽管上述四个因素都扮演了各自的角色,但一些组件可能是无用的甚至对目标产生负面影响

  • 首先,由于目标是借助\textbf h_i来改善\textbf c_i,因此需要重新定义了损失,使得更多地关注\textbf c_i,而不是同等考虑\textbf c_i\textbf h_i
    L^{opt1}_i=-log(\phi(\textbf c_i,\textbf h_i)/\hat Z)\tag{16}
    其中\hat Z=\sum^b_{j=1,j\ne i}\phi(\textbf c_i,\textbf c_j)+\sum^b_{j=1}\phi(\textbf c_i,\textbf h_j)。换句话说,\textbf h_i只用作\textbf c_i被鼓励接近或远离的点,并且不被视为要优化的目标。这种修改自然去除了第(4)个因素的影响

  • 此外,因素(2)对于提高模型性能也不显着,因此得到一个新的目标L^{opt2}_i
    L^{opt2}_2=-log(\phi(\textbf c_i,\textbf h_i)/\sum^b_{j=1}\phi(\textbf c_i,\textbf h_j))\tag{17}

  • 最后,通过允许使用不同层的多个特征\{\textbf h_{i,k}\}来指导\textbf c_i,从而是得因素(1)到(3)多样化:
    L^{opt3}_{i,k}=-log\frac{\phi(\textbf c_i,\textbf h_{i,k})}{\phi(\textbf c_i,\textbf h_{i,k})+\sum^b_{m=1,m\ne i}\sum^l_{n=0}\phi(\textbf c_i,\textbf h_{m,n})}\tag{18}
    期望这种细化后的学习目标可以通过考虑额外提供的样本来获得更精确和丰富的训练信号,优化损失的最终形式是:
    L^{opt}=\frac{1}{b(l+1)}\sum^b_{i=1}\sum^l_{k=0}L^{opt3}_{i,k}+\lambda\cdot L^{reg}\tag{19}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容