对比学习简介
前言
对比学习属于无监督学习中的自监督学习,所以它是没有label的,而在传统的监督学习中,我们往往使用label和预测值进行损失函数构建,进而对模型进行优化,而在自监督学习中,我们采取代理任务(proxy task)来后天构建label,进而可以像监督学习一样构建损失函数,我们最终的目的不是代理任务,而是利用代理任务学到的神经网络作为特征提取器,将他作用在下游的任务中,是他只需要少量的标注或微调就能得到较好的效果。所以,我们相信代理任务学到特征能泛化到下游任务中。
而在对比学习中,最常用的代理任务就是实例判别,即将所有的样本都判断为独立的类别,我们要学到的就是能判别是否属于同一类别的特征,尽管这些样本本身并无标签、可以被视为彼此独立的类别,但这恰恰无法训练出能够泛化的语义特征,因此我们通过数据增强人为构造“正样本对”,将该任务转化为一个“判断样本对是否来自同一语义类别”的分类任务。来让模型学到能泛化的类别判别特征。在实例判别的代理任务中,我们认为该任务构建了一种类别的label,将任务转换为了多分类问题。就能构建损失函数了。
流程
数据增强
前面我们提到需要构建正样本,而对比学习一般用在cv领域,所以这里提到的是图片的数据增强。
对每个样本,我们都进行数据增强(裁切,翻转,颜色扰动,模糊等),生成两个(只用两个,大多数方法只要一个正样本,要多个正样本的也不是通过这里获得的)不同视图,将它们作为一个正样本对,将其他样本作为负样本
特征提取(编码器Encoder)
为什么要特征提取,因为我们要学到的是类别判别的特征来作用于下游任务,并且我们要进行对比,也需要用特征来对比。我们使用ResNet、transformer等方式进行特征提取,我们后续用损失函数优化的也是这里的超参数。有时还会使用投影头(Projection Head),例如一个 MLP,将表示进一步映射到一个对比空间。
构建对比损失
- 计算正样本之间的相似度,想要他们靠近
- 计算负样本之间的相似度,想要他们远离
- 常见的损失函数有NT-Xent(Normalized Temperature-scaled Cross Entropy),InfoNCE,Triplet Loss,NCE
模型优化
-
通过梯度下降等优化方法最小化对比损失;
-
编码器学习到的特征表示能捕捉样本间的语义相似性。
表示使用或下游任务评估
训练完后,去除投影头,仅保留编码器,就可以作为提取特征的部分作用于下游任务
不同的负样本方式
大 Batch 构造(end-to-end)
代表:SimCLR
该方式使用的负样本为同一批次的样本构建而来,不使用其他批次样本。这种方式的效果极度依赖于一批次的样本数,适用于有TPU的情况下,可以采用成百上千的批次样本数。能生成一个很大的、能更新的负样本库。这样的优势是他能够在每次反向传播更新encoder超参数后更新负样本,但这种方式依赖大内存,不然无法存太多负样本。
memory bank
静态
代表:Inst Disc
在Inst Disc(最早期对比学习论文提出的方式)中,使用的是一个静态的memory bank,初始化时直接用编码器训练的初始特征。他的更新只在样本前向传播并计算损失与梯度后更新。而且这个表是全局表,会存储所有。但他的更新就会很少,所以说他是静态的。
动量编码器更新的负样本队列
代表:MoCo
在MoCo中,使用了一种动量编码器更新的memory bank,他存储在一个更新的队列中。相较于 InstDisc 中静态、长时间未更新的 memory bank,MoCo 使用动量编码器搭配有限长度队列动态更新负样本,更能保持负样本的时效性与稳定性。
什么是动量更新
在一些对比学习的方式中,正样本的编码器和负样本的编码器是共用参数的,也就是说他们实际上是一样的。但是这种不断直接更新的编码器会对负样本的memory bank造成影响。因为不同参数的Encoder获得的负样本差别太大。所以MoCo采取了一种动量的更新方式,即正负样本的编码器用两套参数(正:Query encoder,负:Key encoder)其中query encoder是采用传统的反向传播更新方式,而key encoder是采用的动量的更新,是怎样动量的呢,可以看看他的公式:
该公式代表了 Key Encoder 权重以一定比例向 Query Encoder 权重靠拢,从而保持稳定的特征表示。其中k和q正是我们的两个编码器,m是一个可调的参数,它决定了这个编码器更新的程度。在MoCo论文中,发现m在0.99和0.999等很大的参数时效果最好。
为什么用更新队列
就像之前说的不同参数的Encoder获得的负样本差别很大,特别是key encoder更新很多轮后,如果我们还是像字典一样将特别久之前的还没更新的负样本存起来,不仅效果不好,还会占内存。所以我们用一个有限的队列存储。新的负样本进入队列,同时队列满时会将老的负样本弹出队列。这样就能保证负样本的动态更新,同时节约内存。
不使用负样本(无负样本对比)
代表:BYOL、SimSiam
这是后期的对比学习采用的方式。它完全不使用负样本,而是通过正样本自对齐来学习特征。能避免复杂的负样本设计。但本文不讲这个(或许是我也没学😭)
上图是inst disc中生成负样本的流程
上图是MoCo论文中对几种方式的介绍
损失函数
在对比学习中有多种损失函数,本文讲其中的两个,NCE,和InfoNCE
NCE
下面的 是人为可添加的采样的噪声分布,如均匀分布、正态分布等。是真实分布下样本i的后验概率。参照上面的MoCo的图可以看出,就是指从memory bank中按这种分布抽取负样本进行对比
下面这张图是NCE的对数似然损失函数,其实就类似于sigmoid的对数似然损失函数。第一项是最大化真实样本被判为“真”的概率。
第二项是最小化噪声样本被误判为“真”的概率,乘上 m 表示噪声采样数量。
InfoNCE
表示相似度,常用余弦相似度或向量点积(这两个实际上只有数值上的差异,初高中数学就有讲),它的作用是最大化查询与正样本的相似度,最小化与负样本的相似度。类似于softmax。
结语
本文只是对对比学习进行了简单的介绍。对比学习从早期探索到18年Inst DIsc论文发表进入快速发展时期,涌现了大量优秀和别具匠心的论文,他们使用巧妙的方式将没有标签的困难克服,证明了Yann LeCun的蛋糕假说(AI的三层结构中,感知(perception)是蛋糕主体,代表的是通过自监督学习获取的表征;监督学习只是蛋糕上的糖霜。),人们逐渐发现了无监督学习领域具有的优秀潜力,而对比学习领域正是其中的佼佼者。学习它的路径是坎坷并漫长的,但正如“路漫漫其修远兮,吾将上下而求索”,怀揣着一颗求知的心,总会抵达前方的。