如果把 近几年对比学习在视觉领域有代表性的工作做一下总结,那么对比学习的发展历程大概可以分为四个阶段:
- 百花齐放
这个阶段代表性工作有InstDisc(instance discrimination,)、CPC、CMC等。在这个阶段中,方法、模型、目标函数、代理任务都还没有统一,所以说是一个百花齐放的时代 - CV双雄
代表作有MoCo v1、SimCLR v1、MoCo v2、SimCLR v2;CPC、CMC的延伸工作、SwAV等。这个阶段发展非常迅速,有的工作间隔甚至不到一个月,ImageNet上的成绩基本上每个月都在被刷新。 - 不用负样本
BYOL及其改进工作、SimSiam(CNN在对比学习中的总结性工作) - transformer
MoCo v3、DINO。这个阶段,无论是对比学习还是最新的掩码学习,都是用Vision Transformer做的。
第一阶段:百花齐放(2018-2019Mid)
InstDisc(instance discrimination)
这篇文章提出了个体判别任务(代理任务)以及memory bank ,非常经典,后人给它的方法起名为InstDisc。
研究动机
在有监督学习的分类模型中,如果给一张豹子图片进行分类,会发现排前几名的都是跟这张图很像的图片,而排名靠后的那些往往是跟豹子一点关系都没有的类别。
作者研究发现,让这些图片聚集在一起的原因并不是因为它们有相似的语义标签,而是因为这些照片里的物体都很相似。最后作者由此提出了个体判别(individual instances)任务:把每一个instance(实例,这里就是指每一张图)都看成是一个类别,目标是学一种特征,把每张图片都区分开来。

算法
模型结构
将图片经过CNN网络编码后得到的图片特征,使用对比学习的方式将其在特征空间中尽可能的区分开来(因为每张图都是自己的类)。既然是对比学习,就需要正负样本。InstDisc中正样本就是就是这个图片本身(可能经过一些数据增强),负样本就是数据集里所有其它的图片,这些负样本都存储在 memory bank里。对于ImageNet有128万张图片,那么memory bank就要存储128万行,所以最后每张图都用128维特征表示(维度太高存储不了)

前向过程
- \(image\overset{ResNet50}{\rightarrow}2048Dim\rightarrow 128Dim\),即经过ResNet50编码得到128维的图片特征
- 论文的softmax不设置参数\(w\)。而是和Word2vec一样把特征当作参数,并创建一个叫做memory bank的堆进行存储所有单词的128维特征,每次通过loss更新。这样训练和测试通过存储的memory bank同使用一个度量空间。
- 论文取
batch_size=256,则每个batch有256个正样本,然后从 memory bank 里随机地抽取4096个负样本。根据正负样本计算对比学习目标函数NCELoss。然后根据loss更新backbone和memory bank(把 mini batch里的数据样本所对应的那些特征,在 memory bank 里更换掉,这样无论是训练还是测试就都来自于一个度量空间了)。 - 测试时,使用KNN进行分类 我们获得了训练好的模型后,对于一张图片提取他的特征,将他和memorybank中所有的存储图片特征计算相似度,然后采用k近邻算法,返回最相似的k张图片。最后根据相似度权重投票,得到其类别c。
训练细节
本文的一些超参数设定,比如backbone选择ResNet50,batch_size=256,负样本采样数为4096,特征维度\(dim=128\),\(epoch=200\),初始\(lr=0.03\),计算NCELoss时\(τ=0.07\);这些超参数在在MoCo 中也是沿用的,没有进行更改。
NCELoss损失函数
- Parametric Classifier参数分类器
在传统的参数softmax函数中,对图片\(x\)及特征 \(v=f_\theta (x)\),被识别为第\(i\)类样例的概率为:
其中 \(v\)是卷积网络输出的特征表示,\(i \)是预测类别(实例级),\(w\)是需要优化的权重向量。
- Non-Parametric Softmax Classifier
作者认为纯粹的参数\(w\)阻碍了个体之间的对比,于是文章采用的无参softmax:使用L2正则化的 \(v_i^{T}\)来替换\(w_i^{T}\), \(\tau\) 用来调整类别分布的集中程度:
使用Mermory Bank \(V\) 来存储上述的 \(v_j\),在每个iteration对应修改其值 \(f_i\to v_i\) ,在初始化时通过单位随机向量对V进行初始化。
- Noise-Contrastive Estimation:多分类问题转化为一组二分类问题,其中二分类任务是区分数据样本和噪声样本。
由上式可知,计算瓶颈在于分母,需要枚举所有图片,这样的计算复杂度是无法接受的。为了解决这一问题,我们不再采用原先的采样方式,而是用随机负采样,即从噪音分布当中进行随机采样,真实样本和噪音分布的数据比为 \(m\)。
如果噪音分布当中采样\(n\)个数据,那么真实样本就采样\(n/m\)个数据(一般就为1个)。这样原先的多元问题就转化为了二元问题,则Memory bank中特征表示\( v \)对应于第\(i \)个样例的概率为:
我们设定噪声分布为一个均匀分布\(P_n=1/n\),则\(v\)属于第\(i\)个个体的后验概率为:
训练目标为最小化似然函数
Proximal Regularization
由于每个“类”只有1个样例,在每个epoch中,一个“类”只被访问一次,训练的过程比较不稳定。为了使训练更加平滑,在损失函数上增加一项针对v 的惩罚, 来稳定训练过程:
其中, \(v_i^{(t)}=f_\theta(x_i)\)(第\(t\)次迭代时backbone的输出特征),\(V={v_i^{(t-1)}}\) 来自于memory bank。这样随着多次迭代,由于 \({v_i^{(t)}}-{v_i^{(t-1)}}\) 的加入,backbone和memory bank存储的特征就逐渐相同了,回到了原始的损失,加速了收敛。
所以Proximal Regularization相当于模型的训练加了一个约束,从而能让 memory bank 里的那些特征进行动量式的更新(当前时刻的输出和上一时刻的输入有关),跟 MoCo 的想法是非常一致的。

结论
Inst Disc 这篇论文也是一个里程碑式的工作:它不仅提出了个体判别这个代理任务,而且用这个代理任务和 NCE loss做对比学习,从而取得了不错的无监督表征学习的结果。同时它还提出了用别的数据结构存储这种大量的负样本,以及如何对特征进行动量的更新,所以真的是对后来对比学习的工作起到了至关重要的推进作用。
Inva Spread
这是一篇 CVPR 19的论文,跟今天要说的其它论文相比,它的影响力可能不是那么大,之所以提一下这篇论文,是因为它可以被理解成是 SimCLR 的一个前身,它没有使用额外的数据结构去存储大量的负样本,它的正负样本就是来自于同一个 minibach,而且它只用一个编码器进行端到端的学习
本文的想法其实就是最基本的对比学习
这篇文章作者同样没有为自己的方法起名字,所以后面一般将其简称为Inva Spread。Inva Spread是一种端到端的训练方式,直接训练特征本身,无需额外的数据结构(比如上文的memory bank),提升了效率和准确度。作者还使用了新的采样方式,降低了计算复杂度。
如图1所示,同样的图片通过编码器以后,它的特征应该很类似,不同的图片,它的特征出来就应该不类似,这就是题目中说的invariant和 spreading,就是说对于相似的图片、相似的物体,特征应该保持不变性,但是对于不相似的物体或者完全不沾边的物体,特征应该尽可能的分散开

简单来说,本文中的正负样本都来自同一个mini_batch。比如对于图片 \(x_i\),其正样本就是数据增强后的图片 \({x_{i}}'\) ,而负样本就是这个mini_batch中除了 \((x_i,{x_{i}}')\) 之外的所有样本,而不是整个数据集中的所有其它样本。这样负样本数大大减少,可以不需要额外的数据结构来存储,就可以用一个编码器做端到端的训练了。
Inva Spread可以看做是SimCLR的前身,但由于数据增强策略不足以及负样本数量太少,也没有SimCLR提出的mlp projector ,使得最终的训练效果不好,没有太大的影响力。
Inva Spread的作者太穷,没有TPU,只能选择batch_size=256来训练。这样每次迭代的负样本只有255*2个,数量太少,对比学习的效果不够好(也就是在MOCO中说过的字典太小)。而SimCLR的作者来自谷歌,可以使用大量的TPU,最终训练的batch_size=8192,足以达到不错的训练效果。
方法

- 代理任务也是选取了个体判别这个任务
- 前向过程:
- 如果 batch size 是256,也就是说一共有256个图片,经过数据增强,又得到了256张图
- 对于 \(x_1\) 这张图片来说, \(x_1^{'}\) 就是它的正样本,它的负样本是所有剩下的这些图片(包括原始的图片以及经过数据增强后的图片),也就是说正样本是256,负样本是\((256-1)*2\),就是除去样本本身之外 mini-batch 剩下的所有样本以及它经过数据增强后的样本,也就是这里为什么要乘2,这些都是负样本
- 它和 Inst Disc的区别:Inst Disc中,正样本虽然是256,它的负样本是从一个 memory bank 里抽出来的,它用的负样本是4096甚至还可以更大
- 本文为什么要从同一个 mini-batch 里去选正负样本?因为这样就可以用一个编码器做端到端的训练了,这也就是MoCo里讲过的端到端的学习方式
- 剩下的前向过程都是差不多的,就是过完编码器以后,再过一层全连接层就把这个特征的维度降的很低,就变成128了,正样本比如说上图中绿色的球在最后的特征空间上应该尽可能的接近,但是这个绿色的球跟别的颜色的特征应该尽可能的拉远
- 本文所用的目标函数也是 NCE loss 的一个变体
- 所以说之所以讲这篇论文,是因为它刚好属于另一个流派,也就是端到端的学习,而且只用一个编码器,不需要借助外部的数据结构去存储大量的负样本,它的正负样本都来自于同一个 minibach
- 既然它跟 SimCLR 这么像,为什么它没有取得那么好的结果呢?就是之前在MoCo那篇论文里反复强调过的,就是这个字典必须足够大,也就是说在做对比学习的时候,负样本最好是足够多,而本文的作者是没有 TPU 的,所以说它的 batch size 就是256,也就意味着它的负样本只有500多个,再加上它还缺少像 SimCLR 那样那么强大的数据增广以及最后提出的那个 mlp projector,所以说呢这篇论文的结果没有那么炸裂,自然也就没有吸引大量的关注,但事实上它是可以理解成 SimCLR 的前身
CPC(contrastive Predictive coding)
一般机器学习分为判别式模型和生成式模型,个体判别显然是属于判别式范畴的,那肯定就会有一些生成式的代理任务,比如最常见的预测型的任务
cpc 这篇论文其实非常厉害,因为它是一个很通用的结构

- 上图中描述的是CPC不仅可以处理音频,还可以处理图片、文字以及在强化学习里使用, 这里为了简单,它用的是一个音频的信号作为输入
- 本文的想法:假如说有一个输入\( x\)(一个持续的序列),\(t\)表示当前时刻,\(t-i\)表示过去的时刻,\(t+i\)表示未来的时刻。把之前时刻的输入全都扔给一个编码器,这个编码器就会返回一些特征,然后把这些特征喂给一个自回归的模型(gar,auto regressive),一般常见的自回归模型,就是 RNN 或者 LSTM的模型,所以每一步最后的输出,就会得到图中红色的方块(ct,context representation,代表上下文的一个特征表示),如果这个上下文的特征表示足够好(它真的包含了当前和之前所有的这些信息),那它应该可以做出一些合理的预测,所以就可以用ct预测未来时刻的这个\(z_{t +1}\)、\(z_{t + 2}\)(未来时刻的特征输出)
- 对比学习在哪里体现的呢?正样本其实就是未来的输入通过编码器以后得到的未来时刻的特征输出,这相当于做的预测是 query,而真正未来时刻的输出是由输入决定的,也就是说它们相对于预测来说是正样本;负样本的定义其实很广泛,比如可以任意选取输入通过这个编码器得到输出,它都应该跟预测是不相似的,这就是cpc定义正负样本的方式
这套思想是很朴实的,把输入序列换成一个句子,也可以说用前面的单词来预测后面的单词的特征输出;如果把这个序列想象成一个图片的patch块从左上到右下形成一个序列,就可以用上半部分的图片特征去预测后半部分的图片特征,总之是非常灵活 - 并且这篇文章也是提出了infoNCE 的loss, 详情可以查阅: Contrastive Predictive Coding (CPC)
CMC(contrastive multiview coding)
CMC使用一个物体的多个视角来作为正样本。这个思想来自于人类对世界的感受、观察。
在摘要中,作者说人类观察这个世界是通过很多个不同视角的传感器,比如说眼睛或者耳朵,来给大脑提供不同的信号。每一个视角都是带有噪声的,而且有可能是不完整的。但是最重要的那些信息,比如物理性质,几何形状以及语义信息,在所有的这些视角中间共享。例如一只狗可以被看到、听到、感受到。
基于此,作者认为一个强大的特征,应该具有视角不变性(view-invariant)(不论是看到还是听到,都应该能判断出那是一只狗)。所以CMC目的,就是最大化同一个场景不同视角的互信息,并且可以扩展到任意数量的未知视角,且视角越多效果越好。
如果能学到一种特征能够抓住所有视角下的关键的因素,那这个特征就很好了,至少解决分类问题不在话下
算法

如上图所示,CMC选用 NYU RGBD 数据集进行 训练。数据集中每张图有4个视角(view):原始的图像、原图对应的深度信息(每个物体离观察者到底有多远)、SwAV ace normal以及原图的分割图像。
在CMC中,一张图的四个视角就是互为正样本,因为其代表的是同一个东西;其它的图片就是负样本。在上图表示,就是特征空间中四个绿色的点互相靠近,而都和红色的点远离。
这就是 cmc 定义正负样本的方式,它的正样本来自于多个视角,一旦定义好了正负样本,剩下的工作就大差不差了
cmc是第一个或者说比较早的工作去做这种多视角的对比学习,它不仅证明了对比学习的灵活性,而且证明了这种多视角、多模态的这种可行性。所以说接下来open AI,很快就出了clip模型:也就是说如果有一个图片,还有一个描述这个图片的文本,那这个图像和文本就可以当成是一个正样本对,就可以拿来做多模态的对比学习
结论
- CMC正负样本确定的方式由个体升级成了个体的不同的视角(如色彩模型)。
- 它同样使用了NCE,但将其扩展以适应不同的视角。CMC采用多视角对比学习,证明了对比学习的灵活性,也同时证明了多视角多模态的可行性,为之后的CLIP工作(图文配对的多模态对比学习)打下了基础。
- 但是本文也有一个局限,即处理不同的视角(模态)时,可能需要不同的编码器,因为不同的输入特点不一样。 如果每个视角都有一个编码器,那么训练的成本就有点高(比如在CLIP里,文本编码器是BERT,图片编码器是ResNet或者ViT)。
- 所以这也是现在Transformer最吸引人的地方,这个结构可以同时处理文本和图片,那么就可以用一个解码器处理两种模态,而不用做针对每种数据去做特有的改进, 在2022ICLR上发表的MA-CLIP,就是用一个Transformer去同时处理两个输入模态,效果反而更好。
小结
第一阶段大概讲了这四篇论文,可以看到
- 它们使用的代理任务是不一样的,有个体判别,有预测未来,还有多视角多模态
- 它们使用的目标函数也不尽相同,有 NCE,有infoNCE,还有NCE的其它变体
- 它们使用的模型也都不一样,比如说invariant spread用了一个编码器;Inst Disc用一个编码器和memory bank;cpc有一个编码器,还有一个自回归模型;cmc可能有两个甚至多个编码器
- 它们做的任务从图像到视频到音频到文字到强化学习,非常的丰富多彩
第二阶段:CV双雄(MoCo和SimCLR)
MoCo
详细见这里:MoCo系列
这里主要就罗列和其它工作的区别和联系
MoCo 的主要贡献就是把之前对比学习的一些方法都归纳总结成了一个字典查询的问题,它提出了两个东西
- 队列
- 动量编码器
从而去形成一个又大又一致的字典,能帮助更好的对比学习, MoCo跟Inst Disc是非常相似的
- 它用队列取代了原来的memory bank作为一个额外的数据结构去存储负样本
- 它用动量编码器去取代了原来loss里的约束项,从而能达到动量的更新编码器的目的,而不是动量的去更新特征,从而能得到更好的结果
但是整体的出发点以及一些实现的细节都是非常类似的
SimCLR
详细见这里:SimCLR系列

这里稍微做下总结,
本文其实整体的这个思路和结构跟invariant spread 是基本一致的,SimCLR跟Inva Spread的区别其实都写在SimCLR的贡献列表里了
- 首先第一个就是它用了更多的数据增强,它发现对比学习真的是需要很强的数据增强的技术

如上图所示,SimCLR这篇论文使用了这么多的数据增强的方法,从最开始的原始图片,到裁剪,到改变色彩,到旋转,使用 cut out,还有使用高斯的噪声和高斯 blur,以及最后使用sobel的这种滤波器。真的是把前人想到的这些数据增强的方式全都用了个遍,然后为了让读者知道,到底哪些数据增强有用,哪些数据增强没用,作者还做了详细的这个消融实验
- 第二就是它加了一个g函数(一个可以学习的分线性的变换,就是一个 mlp层),也做了对应的消融实验,加上这个mlp对整个对比学习的训练来说提升还是很明显的

- 第三就是它们用了更大的batch size ,而且训练的时间更久,它发现这两个策略都能让网络学到的特征变得更好
MoCoV2
MoCov2主要是借鉴了SimCLR而做的优化,比如引入了mlp projection head以及使用更多的数据增强。MoCov2刷新了ImageNet 上的最好成绩,比之前的MoCo以及最新的SimCLR都高很多 。其上传的日期是3月9日,离SimCLR的发布还不到一个月。
MoCov2对比MoCo主要有4个改动:
改进策略
- 添加 projection head
- 使用更多的数据增强
- 训练时使用cosine的learning rate schedule
- 训练的epoch,从200增加到800
SimCLR V2
模型结构

整个模型分为三个部分:
- 第一部分就是SimCLR,怎样自监督或者说自监督的对比学习去训练一个大的模型出来
- 第二部分就是说,一旦有了这么好的一个模型,只需要一小部分有标签的数据,然后去做一下有监督的微调,一旦微调结束了,就相当于有一个 teacher 模型
- 第三部分是可以用这个teacher模型去生成很多伪标签,这样就可以在更多的无标签的数据上去做自学习了
改进策略
SimCLRv2相比SimCLRv1有三处改进:
- 大模型:backbone从ResNet50替换为ResNet152+SK net (selective kernels)
- 加深protection head :从一层加到两层。
protection head在SimCLRv1和MOCOv2中都被证明很有用,所以作者考虑多家几层。最后发现加到两层效果就够了 - 引入了动量编码器:使用了类似MOCO的动量编码器,效果提升了一个点。
作者解释是,SimCLR模型的 batch_size已经够大了,也就是字典的大小和字典里特征一致性,SimCLR v2 都已经做的很好了。换成MOCO这种队列结构的动量编码器,虽然可训练的负样本更多,但是提升没有那么明显了。
微调
SimCLRv1在微调时,是去掉\(g(\cdot )\)(projector层),只保留编码器\( f(\cdot )\) 进行微调,即\(f^{task}(x_{i})=W^{task}f(x_{i})\)
SimCLRv2在微调时,是保留 \(g(\cdot )\) 的第一层 ,即\(f^{task}(x_{i})=W^{task}\cdot \sigma (W^{MLP}\cdot f(x_{i}))\)
SwAV
研究动机
SwAV即swap assignment view的缩写,意思就是一张图片不同视角的特征可以互相预测,因为来自同一张图片的不同视角特征按道理来说都是相似的。具体的做法,就是将聚类加入到了对比学习中。(将匹配问题转为预测问题,预测时借助簇类中心)
本文的具体的做法就是把对比学习和之前的聚类的方法合在了一起,当然这么想也不是偶然
- 首先,聚类方法也是一种无监督的特征表示学习方式,而且呢它也是希望相似的物体都聚集在某一个聚类中心附近,不相似的物体尽量推开推到别的聚类中心,所以跟对比学习的目标和做法都比较接近
- 另外,这篇文章的一作其实之前一直也是做聚类的,它之前就做过deep cluster这篇工作,也是一篇非常好的无监督学习的论文
作者认为之前的对比学习,直接拿所有图片的编码特征去做对比有点原始而且计算量太大,因为所有的图片都是自己的类。作者考虑,能不能借助一些先验信息,一些更简洁的东西比进行对比,而不是和所有负样本直接进行对比。由此作者提出了可以和聚类中心特征进行对比(128万张图片被聚成3000个簇类中心cluster center)。
比如MoCo在ImageNet上训练那就有128万类,即使在计算loss时取近似,只是取队列编码器里的作为负样本,那负样本也有6万多个。
算法

- 左图:普通的对比学习方法。 同一张图片,做两次数据增强得到 \(x_1,x_2\)(正样本),然后所有的样本通过一个图片编码器(比如ResNet50等等,也可以加几层mlp之类的,这里没有具体说明)输出编码特征\(z_1,z_2\),然后在编码特征 \(z\)上去做对比学习。
- 右图:SwAV的做法
- 每个batch输入数据为\(x\in R^{NCH*W}\), 分别经过不同的Aug, 得到 \(x_1, x_2\)
- 将 \(x_1, x_2\) 输入编码器中,得到编码特征 \(z_1, z_2 \in R^{N*d}\)
- 已知K个聚类中心prototypes \(\left \{ c_1,...,c_K \right \}\),表示为 \(C\in R^{Kd}\)。将编码特征与聚类中心计算相似度,得到相似度矩阵\(Q \in R^{KN}\),这样算完又获得了一个新的表示 \(q_1, q_2\)(Codes) 理想情况下,样本与自己的类簇中心相似度为1,与其他的为0,类似于有监督任务中的one-hot label。不过作者发现soft label效果会好一些。
- 理论上同一张图片不同view(比如Augment)所产生的 z 和 q 可以相互预测。也就是说,如果拿\(z_1\) 这个特征去跟 \(c\) 去做点乘,按道理来说也是可以去预测 \(q_2\);反之亦然。所以说点乘之后的结果就是预测,而ground truth就是之前按照clustering分类而得到的q1和q2。作者由此定义了新的loss:
其中
- 通过这种Swapped prediction,也就是换位预测的方法,SwAV可以对模型进行训练
用聚类做对比学习的好处到底有哪些?
- 减少计算量 聚类可以将需要对比的样本数大大减少。比如之前的对比学习,需要去和成千上万的负样本进行对比,即便如此也只是算一个近似。而如果只是跟聚类中心做对比,则只需要最多3,000个聚类中心。因为ImageNet也就1,000类,COCO才80类,所以说 3,000个聚类中心就足够用了。
- 聚类对比更加合理 随机抽取的负样本中,有的可能还是正样本(本身就相似的图片),而且有的时候抽出来的负样本类别也不均衡。但是聚类中心是有明确的语意含义的,自然更加有效,这也是SwAV的基本思想。
Multi-crop增强
SwAV也提出了一种新的数据增强方法Multi-crop(多次裁剪)。
- 之前的那些对比的学习方法都是用的两个crop。比如输入一张图片,先把它resize 到256×256,然后随机crop两个224×224的图片当成 正样本对 \(x_1, x_2\)
- Multi-crop:一张图片经过两个160×160的crop,和四个96×96的crop得到6个正样本。 前两个crop争取学习到全局特征,后四个crop争取学到局部特征。因为之前crop尺寸是224,明显非常大,学习到的基本都是全局特征。如果可以学习局部特征,就更容易关注到局部的物体了。但是为了保持和原来计算量差不多,所以原先的尺寸从224降到了160。 这个想法非常简单但是确实有用,在后面的很多对比学习中也被一直沿用。
- 增加的\(V\)个小的crops和标准的两个crop做loss,最终的loss就变为
实验
不同模型在ImageNet上的Top-1精度对比

- 左侧图:冻结模型只将其作为特征提取器,然后接一个线性分类器。此时SwAV(batch_size=4096,且训练了800epoch)比目前最好的无监督模型MoCov2还要高4.2个点,和自监督的baseline模型只差了1.2%(之后要讲的BYOL和SimSiam都是74点几)。
- 右侧图:backbone使用不同宽度的ResNet50后的对比结果。可以看到随着模型宽度的增加,其效果也更好。最大的模型(SwAV5×)和有监督baseline模型精度差缩小到了0.6%。
下面是将模型作为特征提取器后在ImageNet上训练不同epoch时的的top-1精度对比(backbone都是ResNet50)
- 基线模型就是2224,它用了 multi crop 的这个技术,就是2160加上4*96
- 如果现在把multi crop的技术用到SimCLR上会发现它涨了2.4个点,这个涨幅还是非常明显,所以说其实如果把 multi crop这个技术用到 BYOL 上有可能BYOL会比SwAV的效果高
- 接下来作者又对比了一些聚类的方法,对于聚类的这些方法用multi crop的方式提点就更多了,对于这几个方式来说都提了四个多点,更是非常显著
- 所以我们可以看到,如果没有这个multi crop的这个技术,把这四个点拿掉,其实SwAV的性能也就跟MoCo v2是差不多的,也就是说一个纯聚类的方法,或者说聚类和对比学习结合的方法其实也并没有什么优势,真正提点的是multi crop的技术
- multi crop这个技术其实非常朴实了,它其实就是一种思想,就是说全局的和这个局部的特征都要关注,所以说接下来的很多工作,也都借鉴是multi crop的这个技术,而不是 SwAV 这篇工作本身

CPC V2和Informing
CPC v2其实也是融合了很多的技巧,它用了更大的模型、用了更大的图像块、做了更多方向上的预测任务,把batch norm 换成了 layer norm,而使用了更多的数据增强,所以这一系列操作下来,CPC v2直接就把CPC v1之前在 ImageNet 上40多的准确率一下就拔到70多
informing其实是 cmc 的作者做的一个分析型的延伸性工作,它论文本身的名字叫 What Makes for Good Views for Contrastive Learning(我们到底选什么样的视角才能对对比学习最好?)
- 它主要是提出了一个InfoMin的原则,就是最小化互信息minimi mutual information,那乍一听觉得可能有点奇怪,因为之前大家做的都是 maximize mutual information,都是想要两个视角之间的互信息达到最大,为什么作者这里就想让它达到最小呢?
- 其实这里也不是严格意义上的最小,作者其实想说的是,他想要不多不少的互信息,如果最大化互信息以后比所需要的互信息要多,也是一种浪费,而且有可能泛化做的不好,但如果互信息比所需求的这个互信息要少,有可能达不到最优的性能,所以这个才是作者的本意,就是不能一味的最大化这个互信息,而是要不多不少刚刚好
- 然后按照Info Min的原则选择合适的数据增强,然后拿到合适的对比学习的视角以后,作者发现对于很多的方法都有提升,它们最后在 ImageNet 上也有73,也是相当不错的
小结
其实到了第二阶段很多细节都处于统一了,比如说
- 目标函数都是用infoNCE或者infoNCE类似的目标函数去算的
- 模型最后也都归一到用一个编码器后面加一个projection head
- 都采用了更强的数据增强
- 都想用这个动量编码器
- 都尝试着训练的更久
- 最后在ImageNet上的准确度也逐渐逼近于有监督的基线模型
第三阶段----不用负样本
其实在上一阶段已经有不用负样本的趋势了,比如SwAV就是用的聚类中心进行对比。接下来要讲的BYOL和SimSiam其实就是正样本自己在玩,已经没有负样本或者聚类中心这样明确的一个对比的东西去做对比了。
BYOL
BYOL就是论文标题Boostrap Your Own Latent的缩写。Latent、Hidden、Feature、Embedding其实都是特征的意思,就是各种花里胡哨的用法而已;Boostrap就是类似自我改造的意思。 BYOL使用了一种新的对比学习方法(A New approach),即没有引入任何形式的负样本,而是用图片的编码特征(梯度更新)去预测自己的编码特征(动量更新),模型就这样训练起来了。(相当于用一个视角的特征取预测另一个视角的特征,将匹配转为预测问题)
为什么不用负样本就这么新奇、这么吸引人注意?
- 因为在对比学习中,负样本是一个约束,如果在算目标函数的时候只有正样本,其实目的就只有一个,那就是让所有相似的物体的特征也尽可能的相似,那这个时候就有一个很明显的捷径:如果一个模型不论给它什么输入,它都返回同样的输出,这样的话,它出来的所有的特征都是一模一样的,那拿这个去算对比学习的loss就都是零,意思就是模型直接就躺平了,它直接用这个捷径解就能完美解决问题loss永远是0模型根本都不用学
- 只有加上负样本这个约束,就是说不光相似的物体要有相似的特征,然后不相似的物体也要有不相似的特征。这样模型才有动力去继续学,因为如果输出的所有特征都一样,那负样本的loss就无穷大,所以它必须想办法让正样本和负样本的loss都往下降,达到一个最优解
- 所以说,负样本在对比学习里是个必须的东西,它能防止模型学到捷径,很多论文里也管这个叫model collapse或者learning collapse ,就是模型坍塌或者学习坍塌,说白了就是什么也没学到,负样本就是为了限制这种情况的发生
- 但BYOL之所以神奇就是它没有用负样本,正样本自己跟自己学最后在ImageNet上也达到了74.3的top-1准确率,也是相当高了
算法

前向过程:
- 输入\(x\)经过两次不同的Aug得到 \(v,{v}'\)
- 编码特征
- 上面的online分支 \(v\)经过编码器 \(f_{\theta }\)得到编码特征 \(y_{\theta }\),\(f_{\theta }\)是梯度更新
- 下面的target分支 \(v'\)经过编码器 \(f_{\xi }\)得到编码特征 \({y_{\xi }}'\), \(f_{\xi }\)和 \(f_{\theta }\)模型结构一样,但用的是动量更新的方式。也就是说 \(f_{\xi }\)引入了MoCo中的动量编码器,其参数和 \(f_{\theta }\)不同,但是结构一样。
- 如果这两个编码器都是ResNet50,则输出特征是2048维
- projection head
- 使用类似SimCLR中一样的projection head \(g_{\xi }\)和 \(g_{\theta }\)(也是一个MLP,BYOL中也把这个结构叫predictor),将特征降到256维,得到特征 \(z_{\theta },{z_{\xi }}'\)
- \(g_{\xi }\)和 \(g_{\theta }\)分别是梯度更新和动量更新,但二者结构一样。
- 对比预测
- 在
SimCLR中,是在 \(z_{\theta },{z_{\xi }}'\)之间做maximum agreement,即使不同增强后再编码和MLP映射后的特征尽可能的接近 - 在
SwAV中,是将 \(y_{\theta },{y_{\xi }}'\)分别和\(K\)个簇类中心\(c\)计算相似度得到 \(q_\theta, {{q_\xi }}'\),然后互相预测作对比学习( \(y_{\theta }\)和相似度矩阵点乘的结果去预测 \(q_\xi\),反之亦然) BYOL中,上分支使用prediction head(也是predictor结构)将 \(z_{\theta }\)映射为\(q_{\theta }(z_{\theta })\),然后用\(q_{\theta }(z_{\theta })\)去预测 \(sg({z_{\xi }})'\)来进行对比学习,其中sg表示stop-gradient,因为下分支编码器是动量更新。- 损失函数是MSELoss,即直接计算预测特征 \(q_{\theta }(z_{\theta })\)和标签 \(sg({z_{\xi }})'\)这两个向量之间的mse。
- 在
推理: 当训练完成只留下编码器 \(y_{\theta }\),剩下所有的东西都被拿掉了。然后用这个编码器编码图片,输出维特征去做下游任务的推理。
对比:
- 按过程来看,BYOL就是将上分支输入经过一个梯度更新的编码器和两个predictor得到的\(q_{\theta }(z_{\theta })\),去预测下方输入经过一个动量更新的编码器和一个predictor得到的 \(sg({z_{\xi }})'\)
- 所以可以看出BYOL使用了MoCo的动量编码器、SimCLR的projection head以及预测任务,但是没有负样本,目标函数也不一样。通过自己预测自己就学起来了。
- BYOL的两个分支叫online和target,其实就相当于MoCo中的query和key分支。
理解BYOL
因为不用BYOL不用负样本去学习一个对比网络很神奇,所以就引发了一系列的讨论,这里有一位博主就发了一篇blog去尝试解释:Understanding self-supervised and contrastive learning with "Bootstrap Your Own Latent" (BYOL)
这篇博客的作者其实也是看到BYOL之后觉得非常有意思,所以就尝试复现了一下,结果在复现的时候遗漏了一个小细节,从而导致它的模型训练不动,出现了这个模型坍塌的现象
作者觉得毕竟这是在 DeepMind 的工作,可信度还是非常高的,应该不是论文的问题,肯定是它们自己复现的问题,所以自己就去仔细检查了
检查结果发现确实是遗漏了一个很小的细节,这个细节跟batch norm有关
在讲这个发现之前,先来看一下batch norm带来了什么麻烦,因为之前没有好好说projection head 里面具体的结构,所以先来复习一下
- SimCLR

SimCLR就是说一个图片进了编码器以后就得到了这个embedding,就是特征\(y\)(2048 维),然后把它扔给\(g_θ\),就是一个projection head,也就是图中右侧的mlp
- 这个mlp由一个全连接层、一个batch norm、一个ReLU 激活函数、一个全连接层、一个batch norm的结构组成
- 第一个全连接层的维度是2048*2048
- 第二个全连接层的维度是2048*128,就把维度降下去了,这个128的特征就是最后用来做对比学习的特征
- 注意:这里面有两个batch norm 操作
- MoCo V2

- MoCo v2确实是用了projection head,就是\(g_θ\),但是它的 \(g_θ\)里面是没有batch norm的,就是直接全连接层、ReLU然后又全连接层
- 第一个全连接层还是2048*2048
- 第二个全连接层还是128
- BYOL

- \(g_{\xi }\)和 \(g_{\theta }\)都是projection head
- \(q_θ\)是prediction head
- 这三个东西用的都是同样的结构,如图右侧紫色的mlp结构所示,这个结构里面是全连接层+batch norm+ReLU+全连接层 ,第二个全连接层后面没有 batch norm,但是第一个后面是有 batch norm
- 也就是因为这点小小的差别造成了这个发现
为什么呢?因为像MoCo v2的代码写的实在是太好了,而且又是基于 pytorch ,所以这篇博客的作者就是借鉴MoCo v2来复现的 BYOL ,但是因为MoCo v2里projection head没有batch norm,所以他们在复现BYOL的时候,这里也没有用batch norm,所以它的mlp就是全连接层+relu+全连接层,然后模型的学习就坍塌了,然后这篇博客的作者就觉得实在是太奇怪了,所以赶紧又做了一些额外的实验,如下表所示

- Projection MLP Norm:第二第三列这里指的是两层Projector有没有用归一化
- Loss Function:普通对比学习loss是交叉熵损失函数,而BYOL用的是L2 loss,即mse 损失函数。
- performance:测试模型性能是在一个STL-10的数据集上做的,不是 ImageNet,但衡量标准还是准确度。
实验结果:
- random:使用一个随机初始化的残差网络,没有经过任何训练,直接去抽特征。然后在这个特征上训练一个全连接层,最后的结果是28.8。所以这个结果是一个完全随机的结果。
- 正常的BYOL:两层Projector都使用BN,效果最好
- BYOL变体:只使用一层BN,模型起码 也有学到东西。如果是都用LN或者干脆都不用BN,模型坍塌,什么都没学到。
最终分析:
作者认为在Projector层使用BN之后,是计算了整个batch的均值和方差,这意味着是有信息泄露的(MoCo使用了 Shuffling BN ,就是为了防止这种信息泄露)。模型不光是正样本自己和自己学,还和batch norm产生的平均图片(mode,中值)对比着学,这种平均图片就类似 SwAV的聚类中心了。
所以说,这篇博客的作者认为batch norm是BYOL能够成功的关键,其实是做了一种隐式的对比学习,这个观点很快就被大家所接受了,因为听起来确实很合理,而且后续试验也都验证了这一点。batch norm确实至关重要,拿掉batch norm以后模型就是不好训练,对超参数的设置非常的敏感,稍有不慎它就啥也不学了。
作者对BN的回应
但是BYOL的作者看到这个以后就急了就觉得说如果真是这样的话,如果真的要用这种方式去解释的话,BYOL的创新性就大大降低了,因为它还是没有逃脱出对比学习的范畴,它还是找了一个东西去做对比,所以赶紧做实验看看能不能找到另外一种解释,为什么BYOL 能够不模型坍塌
BYOL的作者很快就找到了另外一种方式去解释这个现象,迅速写了一篇论文(BYOL works even without batch statistics)来做回应,它的题目上来就说BYOL即使在没有batch norm的时候照样能工作,而且它甚至把这个even斜体了,真的就是用来回应上面提到的那篇博客。因为BYOL 的作者不想让大家觉得BYOL 的成功是依赖于 batch norm,然后BYOL 的作者做了一系列非常详细的实验看看问题到底出在哪,实验结果如下表所示

作者发现了几个现象
- batch norm确实是比较关键,因为只要是没有batch norm的地方,SimCLR都工作的很好,可能有一些性能下降,但是都还在学,BYOL全都没有再学了,模型坍塌了
- 通过这个完整的消融实验,作者还发现了几个特例,正是这些特例帮助作者找到了另外一个可以解释的理由:即使当projector有 BN, predictor没用BN的时候,BYOL 还是训练失败了,这个就不能解释batch norm很关键了,因为如果batch norm真的很关键,如果真的能在这个隐式负样本提供对比学习的话,训练就不应该失败
- 还有就是当编码器和project都没有用batch norm的时候,SimCLR也失败了,因为SimCLR没有predictor,所以说这里predictor就无所谓了,意思就是说当什么归一化都不用的时候,不光是BYOL,SimCLR 也不行,它即使用了负样本也训练不出来,所以这就再次证明了,batch norm不是提供了一个隐式的负样本,因为这里即使给它显式的负样本了,它还是训练不出来
- 所以这时BYOL 的作者和原来博客的作者后来就达成了一个比较一致的结论,就是说batch norm跟它原来的设计初衷一样,它主要的作用就是能帮助这个模型稳定训练,它能提高模型的训练稳健性,从而不会导致模型坍塌,BYOL的作者又把这个结论进一步延伸,然后给出来了一个可以解释的理由,如果一开始就能让模型初始化的比较好,后面的训练即使离开了batch norm也没有问题
- 于是作者就做了另外一个实验,就是用group norm和weight standardization,group norm就是一种归一化的方式,而weight standardization就是一种模型初始化的方式,这一套方法其实是vit的原班作者在他们之前的论文 BEiT 里提出来了,也就是现在很多人说的ResNet v2就是用这种方式做训练,然后换上这种初始化方式以后,BYOL 的作者发现又能训练74左右的top-1准确率了,跟原来论文里用batch norm的那个74.3的结果非常接近
- 所以作者最后再次强调说group norm或者weight standardization都没有计算批统计量,所以说这个版本的 BYOL,也就是说这个73.9的 BYOL 是没有跟mini batch里其它的样本做对比的,意思就是说没有隐式的对比,也就意味着说BYOL 还是一个全新的方式,它就是很厉害,就是能自己跟自己学,模型就能学的很好,不需要这种假设batch norm提供的一个隐式的这个对比学习的项,就是说大家不要被那篇博客带跑偏了,赶紧来follow BYOL这个套路,这个套路没问题,别再去管负样本的事了
SimSiam(Simple Siamese network)
其实在BYOL放到 arxiv 上之后,就已经有很多研究者在做对对比学习的分析性工作了,因为大家发现,对比学习的成功好像是被很多很小的点堆起来的性能,比如说我们一路走来可以看到用了新的projection head、训练的时间更长、用了更多的数据增强或者用动量编码器、用更大的 batch size,总之好像都缺一不可,对比学习的性能好像是一点一点被这么堆上去的
这样就不是很好,不方便分析,因为有太多点了,所以不知道从哪分析起,也不知道每个点到底带来了哪些贡献,所以凯明团队又再次出手,把整个过程化繁为简了一下,最后提出了SimSiam
SimSiam结构非常简单,不需要用负样本(结构类似 BYOL)、大的batch size,也不需要动量编码器。然而即使在这种情况下,模型效果也很好。
算法
模型结构

之所以叫siamese network(孪生网络)是因为一般会有两个编码器,这两个编码器一般网络结构是一样的,而且一般是要共享参数的,所以才叫孪生网络
整体架构是跟BYOL 非常一样的:一个图片经过数据增强变成 \(x_1、x_2\),然后经过过两个编码器,有一个predictor,其实predictor出来的就是要去预测另外一个编码器出来的特征
这里跟BYOL唯一的不一样就是它没有用动量编码器
伪代码

D函数就是定义怎么计算loss,这里使用的也是mse损失函数。结合模型结构和伪代码,其前向过程如下:
- image x经过两次数据增强得到 \(x_1,x_2\)
- 经过两个编码器encoder \(f\)(结构一样参数共享,所以叫孪生网络)得到编码特征 \(z_1,z_2\)
- \(z_1,z_2\)经过Projector得到预测 \(p_1,p_2\),然后计算对称性loss(\(p_1\)预测 \(z_2\),同时 \(p_2\)预测 \(z_1\),单次结果除以2)。
- 和BYOL不同的是,这里没有使用动量编码器,两个encoder完全一样。
作者还做了很多实验,比如说batch size对模型训练的影响、还有 batch norm对模型训练的影响,而这些都跟BYOL非常像,这里就不一一展开了,最后作者得到一个结论:之所以SimSiam能够成功训练,不会有模型坍塌,主要是因为有stop gradient这个操作的存在
作者还提出了一个假设,而且在第五节里做了一个 hypothesis:因为有了stop gradient这个操作的存在,所以SimSiam这个结构是可以把它想象成一个EM的算法
EM 算法真是无所不在,感觉很多事情最后都可以归结到 EM 算法去解释,都有点量子力学那个意思
这里作者的意思是说因为有了stop gradient这个操作之后,这一个训练过程或者说这一套模型参数其实就被人为劈成了两份,就相当于在解决两个子问题一样,模型的更新其实也是在交替进行的,作者接下来又做了一些推导,写的非常好,推荐大家可以去看一下,其实到最后应该可以把它理解成是一个k-means这个聚类问题
k-means其实就是分两步走的,每次先要把所有的点分配给一些聚类中心,一旦分配好了以后,再去更新这个聚类中心,然后再周而复始地去做这个操作
从这个角度来说SimSiam又跟SwAV有点关系了,于是作者其实在最后还画了这么一张图如下图所示,这张图真的画的非常好,它把所有孪生网络的做法都归纳到在这里,然后做一下总结和对比

- SimCLR:SimCLR因为是端到端的学习,所以说两边都有梯度回传,但是它还是做的一个对比任务
- SwAV:做的也是一个对比任务,但它并没有跟负样本去比,而是跟聚类中心去比的,那聚类中心是通过SK算法得到的
- BYOL:BYOL就有一个新的贡献(就是predictor,图中已经单独画出来了),它就不是一个对比任务,变成一个预测任务了,要用左边去预测右边,同时还使用了动量编码器
- SimSiam: 整体跟BYOL非常像,左边其实就是一模一样,只不过右边没有用动量编码器,所以这个对比还是比较简洁明了的
实验
最后再看一下结果如下表所示,之前BYOL也没有看结果,鉴于SimSiam是一个总结性的工作,它跟之前里程碑式的工作都有对比,所以看这个表格就足够了

- 在 ImageNet 上linear classification的结果:这里比较的都是重量级工作,比如SimCLR、MoCo v2、BYOL
- 从batch size来说,只有MoCo v2和SimSiam是可以用256的,其它工作都要用更大的batch size,所以说凯明大佬的工作真的是好follow
- 前两项工作SimCLR和MoCo v2要用负样本,但是对于BYOL来说就完全没有用,SwAV用的是聚类中心
- 对于动量编码器来说,SimCLR没有用,SimCLR v2用了,但是v1没有用,MoCo v2和 BYOL用了,SwAV没有用
- 总的来说,SimSiam就是这些都没有用
- 看结果的话发现在训练100个epochs的时候,SimSiam的结果是最好的,所以说明它学的非常快,但是随着训练的推进慢慢就不行了,涨幅比较慢,到最后也是有71.3,但是这个时候BYOL已经有74.3这么高了(其实我之前也有做过很多实验,发现动量编码器真的是很好用,也非常能提点的一个东西,所以可能这也是为什么BYOL能够训练的这么好)
- 当然作者在SimSiam这篇论文里,它只是想说把这些trick全拿掉照样能训练,所以说它没有用动量编码器
- 再来看SwAV,SwAV只有71.8,这个应该是没有用multi crop的技术,所以这就跟之前讲SwAV的时候说的一样,就是如果不用multi crop,SwAV 就跟MoCo v2差不多,还不如MoCo v2,所以说只从分类来说,最强的方法就是BYOL
下游任务如下表所示

第四阶段:Transformer
MoCo v3
无监督的预训练(BERT/GPT等)已经彻底改变了NLP,自从Vision Transformer成功之后,将ViT引入CV领域的自监督训练已经是大势所趋了。但是使用ViT作为backbone会导致训练很不稳定,这种不稳定性是造成模型准确率降低的一个主要问题。
本文作者发现只需要做一点小小的改动(冻结ViT的patch projection层),就能让这个训练变得更稳定、效果也更好。所以作者不得不写一篇论文来把这个发现告诉大家,也就是标题说的An Empirical Study (一个实验性的study )。这篇论文是ICCV 21的一篇口头报告论文,但它的的影响力依旧很大。
具体还是参考: MoCo系列
DINO
DINO这个名字,来自于它的题目self distillation with no labels,也就是无标签的自蒸馏方法(学生网络预测教师网络的输出)。本文和MoCov3一样,也是一种自监督训练Vision Transformer的方式,但作者使用另一种操作——centering,使ViT可以稳定训练。另外本文发现自监督训练为 Vision Transformer features提供了一些新的特性。
本文将ViT和自监督学习结合,并研究自监督预训练对ViT feature的影响。
自监督学习通过利用句子中的词创建pretext tasks ,相比于有监督学习中每个句子对应一个label, pretext task提供了更加丰富的学习信号。类似的,图像层面的有监督学习将丰富的图片信息减少到单一的分类概念。
通过研究,本文发现自监督ViT features具有一些独有的特性
- 自监督ViT features 中包含清晰的图像语义分割信息,而这在有监督ViT和convnets中都没有类似的表现。

一个完全不用任何标签信息训练出来的Vision Transformer ,将它的自注意力图进行可视化,会发现能非常准确的抓住每个物体的轮廓,效果甚至可以媲美对这个物体做分割。
算法
模型结构:

伪代码:

详情参考:DINO系列
总结
