一文读懂对比学习在CV进展

2022-11-18 15:02:41 浏览数 (3)

  • 上篇文章从MoCO入手,初步入门了自监督学习和对比学习,本文将会从最初的instance discrimination开始,回顾对比学习在计算机视觉的研究进展(同样是follow朱老师的思路)

发展脉络

对比学习在计算机视觉的发展历程大概分为四个阶段(1)百花齐放:有InstDisc(Instance Discrimination)、CPC、CMC代表工作。在这个阶段方法模型都还没有统一,目标函数也没有统一,代理任务也没有统一,所以是一个百花齐放的时代。(2)CV双雄:这个阶段的代表工作就是MoCo v1、SimCLR v1、MoCo v2、SimCLR v2以及还有CPC CMC它们的延伸工作,还有SwAV。(3)不用负样本:这个阶段主要就是BYOL这个方法以及它后续的一些改进,最后SimSiam出现,把所有方法归纳总结了一下,都融入到了SImSiam这个框架之中,算是卷积神经网络做对比学习的一个总结性的工作。(4)Transformer:这里会提到MoCo v3和Dino。

百花齐放

(InstDisc)Unsupervised Feature Learning via Non-Parametric Instance Discrimination

这篇论文提出了上次在MoCo中提到的代理任务,也就是个体判别任务(Instance Discrimination)。如上图所示,作者说他们的方法是受到了有监督学习结果的启发,如果我们把一张豹子的图片喂给一个已经用有监督学习训练好的分类器,我们会发现它的结果排名前几的全是和豹子相关的,总之在图片来看这些物体都是长得很相近的。通过这个现象作者认为并不是因为这些标签有相似的语义信息,而是因为它们这些照片长得很像。所以作者根据这个观察提出了个体判别的任务。他说它们提出的无监督学习方式,就是要把这种按照类别的有监督信号推到极致,现在把每张图片都看成是一个类别,目标就是做到一个特征能把每一个图片都区分开来。

文章方法我们可以看上图,即想通过一个卷积神经网络,把一张图片编码成一个特征,他们希望这个特征在最后的特征空间里能尽可能分开。训练的方式使用的就是对比学习,正样本就是每张图本身,再经过一些数据增强,负样本就是数据集里其他的图片。那负样本要存在哪呢?这个方法就用了memory bank的形式,即把所有图片的特征全都存到了这个memory bank里。每个前向会获取一批数据作为正样本,然后在memory bank里抽一些负样本出来,然后用NCE loss作为对比学习的目标函数进行模型更新。更新完之后就可以把这个mini-batch的数据样本对应的特征到memory bank里更换,更新memory bank。

这个方法还有一些细节比较巧妙,如Proximal Regularization,这个方法给模型加了一个约束,从而能让memory bank里的那些特征进行动量式的更新,跟MoCo的想法还是比较一致的。

(InvaSpread)Unsupervised Embedding Learning via Invariant and Spreading Instance Feature

这篇论文可以理解为SimCLR的一个前身,它没有使用额外的数据结构去存储大量的负样本,它的正负样本就是来自于同一个minibatch,而且只使用一个编码器去进行端到端的学习

这篇论文的想法就是最基本的对比学习,如上图所示,同样的图片通过一个CNN的编码器以后它的特征应该很类似,不同的图片应该不类似。

具体的做法如上图所示,代理任务也选取了个体判别的任务,如果batch size是3,那么我们就能得到x1 x2 x3三张图片,对x1来说, x1'就是它的正样本,负样本就是其他图片,包括原始图片和对应数据增强的图片。即此时正样本数量是3,负样本是(3-1)×2=4,这里就和InstDisc不太一样了,因为InstDisc的负样本是从memory bank抽出来的。这篇论文之所以从同一个batch去选正负样本,是因为这样就可以使用一个编码器去做端到端的训练,即在上篇文章MoCo里讲到端到端的学习方式。剩下的前向过程是类似的,即过完编码器之后,通过一个全连接层把维度降低,那么正样本(同样颜色的球)在特征空间里应该尽可能近,负样本即不同颜色的球在特征空间里应该尽可能的远。它的目标函数也是NCE loss的一个变体。

这篇文章效果之所以没有那么好,就是我们在MoCo论文里强调的,即这个字典必须足够大,即在做对比学习时负样本最好是足够多,但在这里作者是没有TPU的,所以batch size只能取256,意味着负样本只有500多个,再加上他没有SimCLR那么多的数据增广和mlp projector,所以结果就没有那么好了。

CPC(Representation Learning with Contrastive Predictive Coding)

前两个工作都是用个体判别这个代理任务去做对比学习,接下来就提一个用别的代理任务做对比学习的工作。个体判别属于判别式的代理任务,CPC这种预测就属于生成式的代理任务。

如上图所示,cpc提出了一个很通用的结构,它不光可以处理音频,还可以处理图片,文字以及可以在强化学习里面使用。它大概的想法就是我们有一个时序的序列,假如说有一个输入x,从t-3的时候到t时刻,t 1到t 4是未来时刻,现在我们把之前时刻的输入都扔给一个编码器,然后把提取的特征扔给一个自回归的编码器,即上图的gar,一般常见的自回归模型就是RNN或LSTM这种,这样就得到ct这个隐变量,即代表上下文的一个特征表示。如果这个上下文的特征表示足够好,即真的包含了当前和之前的所有信息的话,那它应该可以做出一些合理的预测,即可以用ct预测未来时刻的特征输出zt 1,zt 2。

那对比学习又是在哪体现的呢?这里的正样本就是未来时刻的输入xt 1,xt 2通过编码器得到的未来时刻的特征输出,就相当于你做出的未来预测是query,而真正未来时刻的输出的特征是key。负样本的定义就比较广泛了,比如我们可以任意选取输入,然后通过这个编码器得到输出,那他都应该给你的预测是不相似的,所以这就是cpc定义正负样本的方式。当然这套框架是比较通用的,下面的音频可以换成一个个单词,用前面的单词去预测后面单词的特征输出,如果把这个序列想象成一个图片的patch块,从左上到右下形成一个序列,那我们可以用上半部分的图片特征去预测后半部分的图片特征,是很灵活的。

CMC(Contrastive Multiview Coding)

看完CPC这种用预测来做代理任务去做对比学习之后,我们再看一下CMC这篇论文。这篇论文定义正样本的方式就更为广泛了。它的核心观点是一个物体的很多个视角都可以被当做正样本。因为我们人观察这个世界是通过很多个传感器的,比如我们的眼睛和我们的耳朵,这些都充当着不同的传感器来给我们大脑提供不同的信号,每一个视角都有可能是带有噪声且不完整的,但是最重要的那些信息其实是在所有的这些视角中间共享的,如基础的物理定律,几何形状,语音信息这些都是共享的。比如一只狗,他可以被我们眼睛看见,也可以被耳朵听到,也可以被感受到。因为作者提出我们想学一个很强大的特征,具有视角的不变性,即不管你给我看哪个视角,到底是看到了一只狗,还是听到了狗叫声,我都能判断出这是一只狗。所以CMC这篇文章就是想增大这个互信息,如果能学到一种特征,可以抓到所有视角下的这个关键因素,那这个特征就很好了。

CMC选取正负样本的方式如上图所示,它选取的是NYU RGBD这个数据集,这个数据集同时有4个view,分别是原始图像,这个图像对应的深度信息,surface normal和语义分割后的图像。cmc就是说虽然这些不同的输入来自不同的传感器,或者说不同的模态,但是所有的输入其实对应的都是一张图片,都是一个东西,所以应该互为正样本。这时候再随机挑一个其他图片,这时候这个图片的特征应该和那四个视角的图片特征尽量远离。、

cmc是比较早的工作去做这种多视角的对比学习,它不仅证明了对比学习的这个灵活性,而且证明了多视角多模态的可行性,所以openAI很快就出了CLIP模型。即如果有一个图片,还有描述这个图片的文本,那这个图像和文本就可以当成是一个正样本对,就可以做多模态的对比学习了。同时cmc团队用对比学习还做了一篇蒸馏的工作,意思就是无论用什么网络,只要输入是同一张图片,那么得到的特征应该尽可能相似,也就意味着我们想让teacher模型的输出跟student模型的输出尽可能相似,它就通过这种方式把teacher和student的输出做成了一个正样本对,从而可以做对比学习。

另外CMC有一个局限性,当你在处理不同的视角或模态时,可能需要不同的编码器,因为不同的输入可能很不一样,所以有几个视角就得有几个编码器,那么这个计算代价就有点高。ma clip就用一个模型同时处理了不潼模态的输入而且效果更好,这就是transformer真正起作用的地方。

从第一阶段可以看到:它们使用的代理任务是不一样的,有个体判别,有预测未来,还有多视角多模态;它们使用的目标函数也不尽相同,有 NCE,有infoNCE,还有NCE的其它变体;它们使用的模型也都不一样,比如说invariant spread用了一个编码器;Inst Disc用一个编码器和memory bank;cpc有一个编码器,还有一个自回归模型;cmc可能有两个甚至多个编码器;它们做的任务从图像到视频到音频到文字到强化学习,非常的丰富多彩

CV双雄

MoCo v1(Momentum Contrast for Unsupervised Visual Representation Learning)

MoCo v1的主要细节都在上一篇文章中讲了,MoCo v1的主要贡献就是把之前的对比学习的一些方法归纳总结成字典查询问题,它提出了两个东西:一个是队列,一个是动量编码器,从而形成了一个又大又一致的字典帮助对比学习。MoCo v1和InstDisc是非常像的,比如它就是用这个队列去取代了原来的memory bank作为一个额外的数据结构去存这个负样本。然后用动量编码器去取代原来loss的约束项从而达到动量更新编码器的目的,而不是动量的去更新那个特征,从而得到更好的结果。具体MoCo v1的细节可以看上一篇文章。

(SimCLR)A Simple Framework for Contrastive Learning of Visual Representations

从上图可以看到SimCLR有多简单,输入mini-batch的图片x,先对里面的所有图片做数据增强,就会得到xi和xj,那么同一个图片数据增强后的不同图片就是正样本,其他图片及其对应的数据增强后的样本就是负样本。有了正负样本之后我们就要进行编码,通过一个编码器f(2个f共享权重)就能得到特征表示了。然后SimCLR的一个重大创新点就是在这个特征之后,又加了一个叫projector的东西,即g函数,就是一个全连接层跟了一个relu函数。就是这么一个简单的mlp,可以让最后学到的特征在ImageNet上提点将近10个点。我们可以想象有了一个特征h之后,再做一个非线性的变化,就得到另外一个特征z,一般这个z会维度小一点,最后就衡量一下正样本之间是不是能达到最大的一致性。它们采用的是一个叫normalized temperature-scaled的交叉熵函数,normalized指的是在特征后面进行了L2归一化,temperature-scaled就是说在这个loss上乘了一个

tau

,所以这个loss和之前说的InfoNCE也是非常接近的。

另外这里的projection head也就是g函数只有在训练的时候才用,而当你在做下游任务的时候我们把这个函数扔掉了,还是只用h去做特征,这样和别的任务就能公平对比了。

SimCLR的主要贡献是这几点(1)用了更多的数据增广技术,对对比学习十分有益(2)加了g函数这个可以学习非线性变化的层(3)用了更大的batch size来让字典更大,而且训练的更久。

如上图所示,SimCLR里面使用了这么多数据增强,从原始图片,到裁剪,改变色彩一直到用sobel滤波器,可以说把前人想到的数据增强方式用了个遍。

SimCLR另一个创新就是提出的非线性变换,也就是说在编码器后面加一层mlp。如上图所示,linear就是只加一层全连接层,non-linear就是在全连接层后加一个relu,None就是像MoCo一样编码器出来的特征直接做对比学习。我们会发现Non-linear相比原来什么都不用,提了10几个点,另外最后z这个维度,无论是128,512,1024都没有对效果有太多区别,所以这就是对比学习为什么一般都选比较低的特征维度,因为128就够了。

MoCo v2(Improved Baselines With Momentum Contrastive Learning)

MoCo团队看到SimCLR比较好的结果后,发现SimCLR里面的技术都是即插即用型,所以MoCo v2就都拿过来了。就在MoCo上做很简单的改动,把mlp projectioin head以及更多的数据增强的trick也加进来。

MoCo v2具体做的改进如上表所示:加了MLP层,加了更多的数据增强,训练的时候用了cos的学习率调整策略以及训练更长的epoch。

最后作者再强调了一下使用MoCo相比于SimCLR的这个优越性,其实这个优越性就在于这个硬件你玩不玩的动,如上图所示,MoCo在普通batch size256就能训练,训练一个模型也只需要53个小时;而SimCLR这种end to end的方式用小的batch效果是很差的,但是消耗的资源和时间也比MoCo多,就更不要说SimCLR用4096的batch size的话,对硬件要求就太高了。

(SimCLR v2)Big Self-Supervised Models are Strong Semi-Supervised Learners

说完MoCo v2,我们说一下SimCLR v2,如上图所示,这篇文章分为了三个部分:第一个部分就是SimCLR v2,即怎么样通过自监督的对比学习去训练一个大的模型。第二部分就是一旦有了大模型,我们只需要一小部分的这个有标签的数据做一下有监督的微调。一旦微调结束,就等于有了一个teacher模型,就可以去生成很多伪标签,这样就可以在更多无标签的数据上去做这种自学习。这篇文章的框架主要受启发于google的另一篇noisy student的工作,noisy student就是在ImageNet上先训练了一个teacher模型,然后在JFT300上生成了很多伪标签,最后一起训练了一个student模型,在ImageNet上达到了SOTA。

我们重点关注SimCLR v2的升级,主要从这三方面提升:(1)第一方面是大家都公认,无监督学习在模型越大的时候表现会越好,所以这里就换了一个更大的模型,换了152层的ResNet和selective kernels,来让骨干网络变强。(2)SimCLR v1提出了projector层,MoCo v2也证明了这个层确实有用,所以SimCLR v2的作者就想这个层变深会不会更有用,于是经过实验发现2层的projector层最好。(3)使用动量编码器。但是动量编码器在SimCLR v2的提升在一个点以内,主要原因就是SimCLR本身已经有很多的负样本了,所以无论从字典大小和一致性来说已经很好了。

SwAC(Unsupervised Learning of Visual Features by Contrasting Cluster Assignment)

SwAC的思想就是给定一张图片,如果我去生成不同的视角,我希望可以用一个视角的特征去预测另外一个视角得到的特征,因为所有视角的特征按道理来都应该是非常接近的。这篇文章的做法就是把对比学习和之前聚类的方法合在了一起,这么想也不是偶然,因为聚类的方法本身也是一种无监督的特征表示学习,而且他也是希望相似的物体都聚集在某一个聚类中心附近,而不相似的物体尽量推开推到别的聚类中心,所以跟对比学习做法都比较接近。

上图左边把之前对比学习的方法总结了一下,右边把SwAC画到了右边。左边就是我们前面讲的形式,不同的样本对通过编码器提取特征,然后用对比学习学习。SwAC认为你直接拿所有图片的这个特征和特征做对比有点原始且有点费资源,因为所有的图片都是自己的类,所以像MoCo有6万个负样本,这还只是个近似(一共有128万个负样本),那我们能不能不去做近似呢?我们能不能借助一些先验信息,不去跟大量的负样本比,而去跟一些更简洁的东西比呢?因此SwAC作者就想出来了,可以和聚类的中心比。聚类中心就是右图画的c,即prototypes,它其实就是一个矩阵,维度是D×K,D是提取出来特征的维度,K是聚类中心的个数,这里取的是3000。我们来看一下SwAC的前向过程:我们有一些原始数据,先做数据增强,然后分别过编码器提取出来特征z1 z2,有了特征之后不是直接在特征上去做对比学习loss,而是说你先通过一个clustering聚类的方法,让你的特征z1 z2和prototypes C去生成一个目标,即q1 q2,q1 q2相当于是一个groundtruth一样的东西,而他真正要做的代理任务是什么呢?如果x1 x2是正样本,那么z1 z2应该很相似,那么按道理来说应该是可以互相去做预测的,即现在用z1和c做点乘,按道理来说是可以去预测q2的,反之亦然。那么点乘之后的结果就是我们的预测,而groundtruth就是之前按照聚类分类得到的这个q1和q2,所以通过这种swapped prediction也就是换位预测的方式,SwAC可以对模型进行训练。

我们来强调一下用聚类的好处有哪些:首先如果你是要跟很多的负样本去做类别,你需要成千上万个负样本,而且即使如此你也只是一个近似。而如果只是跟聚类中心去做对比,可以用几百或最多3000个聚类中心就足以表示了,因为也没有那么多类,像ImageNet也只有1000个类。那这个相对于几万个负样本来说是小了很多的。第二个好处是聚类的中心是有明确的语义含义的,而之前只是随机抽样负样本去做对比,那些负样本有的可能还是正样本,而且有时候抽出来的负样本这个类别也不均衡,所以不如聚类中心有效。

但SwAC有这么好的性能,不光是因为和聚类的方法融合在了一起,另一个主要的性能提升点,叫multi-crop。之前的对比学习方法,都是用两个crop,也就是说一个正样本对x1 x2就两个图片,即一张图先resize到256×256,然后随机crop2个224×224的图片当成x1 x2,因为这两张图片都非常大,所以它们重叠的区域也非常多,于是它们应该代表是一个正样本。但SwAC作者觉得如果你用这么大的crop,你明显抓住的,是整个场景的这个特征,如果我更想学习这些局部物体的特征该怎么办?所以我们应该多做几个crop,那这样就能关注到一些局部的物体了。但是增加这个crop,模型的计算复杂度一下就上去,因为你相当于使用了更多的正样本,那如何同时使用更多的正样本而又不增加太多的计算成本呢?我们可以做一个取舍:原本我们是crop2个224×224的图片,现在可以把crop变小一点,把原来2个224×224的图片区域改成160×160的图片,为了关注局部特征,我再随机去crop4个96×96的图片.通过这么取舍,计算复杂度没增加,也关注到了局部的特征。

另外还有CPC和CMC的一些延伸工作,就是CPC v2和InfoMin。CPC v2其实也是融合了很多技巧,它用了更大的模型,用了更大的图像块,做了更多方向上的预测任务,把batch norm换成了layer norm,而且用了更多的数据增强,而且一系列的操作下来,CPC v2直接就把CPC v1之前在ImageNet上40多的这个准确率一下就拔到70多了,就跟现在这些方法效果就差不多了。InfoMin其实是CMC的作者做的一个分析型的延伸性工作,它论文本身的名字,叫What Makes for Good Views for Contrastive Learning,即我们到底要选什么样的视角才能对对比学习最好,它主要是提出了一个InfoMin的原则,就是最小化互信息,这么一听很奇怪,因为之前大家做的都是最大化互信息,即想要两个视角之间的这个互信息达到最大。为什么作者想要让他达到最下呢?其实这里也不是严格意义的最小,他想要表达的是它想要不多不少的互信息,如果你最大化互信息之后比你所需要的这个互信息要多,那也是一种浪费,而且有可能泛化做的不好。但如果你的互信息比你想要的要少,你有可能达不到最优的性能,所以作者的本意是不能一味的最大化互信息,而是要不多不少。按照他们的InfoMin的原则而去选择合适的数据增强,然后拿到合适的这个对比学习的视角以后,作者发现对于很多的方法都有提升。

我们发现到了第二阶段很多东西就趋于统一了,比如目标函数都是用InfoNCE,或者类似的目标函数去算的,比如说模型最后也都归一到用一个编码器后面加一个projection head,然后大家也都采用了更强的数据增强,也都想用这个动量编码器,也尝试训练的更久,最后在ImageNet上的这个准确度也逐渐逼近这个有监督的基线模型。

不用负样本

接下来我们就进入第三阶段,说一下不用负样本的对比学习。其实第二阶段我们说的SwAV,就已经有这个趋势了,毕竟他也没有使用负样本,用的是一个聚类中心。但是他也是有一个明确的对比对象,但接下来要说的BYOL和SimSiam完全就只有正样本,没有负样本和聚类中心。

BYOL(Bootstrap Your Own Latent A New Approach to Self-Supervised Learning)

为什么不用负样本在对比学习中这么稀奇呢?是因为在对比学习中,负样本是一个约束,如果你在算目标函数的时候你只有正样本,那其实你的目的就只有一个,那就是让所有相似的物体它们的特征也尽可能相似,那这个时候就有一个很明显的捷径解:即一个模型不论你给它什么输入,它都给你返回同样的输出,那这样他出来的所有特征都是一模一样的,那你拿这个去算对比学习的loss就都是0。而只有加上负样本这个约束,模型才有动力去继续学,因为他输出的都一样的话,那在负样本这边loss就无穷大,所以负样本在对比学习里面是一个必须的东西,防止模型学到一个捷径解,很多论文里把这个叫做model collapse,就是啥都没学到

BYOL出了之后引起了很多讨论,因为大家都觉得很奇怪为什么这样模型不会崩塌,接下来我们来看一个很有意思的博客。

Understanding self-supervised and contrastive learning with "Bootstrap your own latent(BYOL)"

这篇博客的作者也是看到BYOL很有意思,所以去复现了一下,但是在复现的时候遗漏了一个细节,导致模型训练不动,就出现了模型坍塌的现象。

我们先来看SimCLR的projection结构,里面有一个全连接 BN relu 然后全连接 BN层。

然后是MoCo v2的projection结构,里面有一个全连接 然后加了relu再加一个全连接。

接下来是BYOL的projection,里面是全连接 BN ReLU再全连接层。

接下来作者就发现了一个他们复现致命的问题,他们复现BYOL是follow MoCo v2的代码复现的,里面的projection是没有加BN的,而这造成了模型的 坍塌。然后作者做了一些额外的实验:

可以发现,如果做的是正确的BYOL,那么结果是正确的,但是如果没有用BN的话,结果就和随机的差不多。接下来作者发现只要在某一块放了BN,结果就不会太差,因此觉得肯定是BN惹的祸。而且思考出了一个结论:BN是把一个batch的所有数据拿过来算一下均值和方差,然后用这个均值和方差做归一化,那这也就意味着你在算某个正样本的loss的时候,你也看到了其他样本的这个特征,也就是说这里是有信息泄露的,因为有这个信息泄露的存在,所以可以把这个batch里面的其他样本,想象成一个隐式的这个负样本;换句话说,有了BN的时候,BYOL其实不光是正样本在自己跟自己学,他其实也在跟自己做对比,它的对比任务是当前的正样本图片,跟你这个平均图片有什么差别,而这个平均图片,就是batch norm产生的,还有很多图片的总结量。这个就跟SwAV很像了,因为SwAV就是没有跟负样本去比,而是找了一个聚类中心去比,而这里batch norm生成的这种平均图片相当于聚类中心。

BYOL works even without batch statistics

BYOL作者看到上一篇博客就急了,因为如果真的是这样的话,BYOL还是在使用负样本,那创新就没那么多了,于是迅速写了一篇论文来回应。

如上图所示,作者做了一系列的实验,核心就是看有没有用BN和LN的消融实验,作者发现了几个现象(1)BN确实比较重要,因为只要没有BN,BYOL就全部没有在学了,模型就坍塌了(2)但是作者还是发现,比如当projector和preditor都有BN的时候,BYOL还是训练失败了,那这个就不能解释BN很关键了,因为如果BN如果真的很关键,可以提供隐式负样本的话,这里训练不会失败(3)当Encoder projector没有使用BN的时候,不光是BYOL,SimCLR也失败了,他即使用了负样本也训练不出来,所以证明了BN不是提供了隐式的负样本,因为这里提供了显式的负样本也训练失败了。后面作者和博客作者达成了一致意见,就是BN的作用还是能帮助这个模型稳定训练,导致不会模型坍塌。后面作者又用了group norm和weight standardization,换成这种没有计算统计量的初始化方式之后,BYOL作者就发现这样也是可以训练到差不多的效果,又一次印证了结论,证明了博客说的是错的。

SimSiam(Exploring Simple Siamese Representation Learning)

BYOL出来之后,就有很多分析型的工作在分析对比学习的成功,因为很多对比学习的工作,好像都是被很多改进堆起来的这个性能,比如projection head,动量编码器等等。这样其实不太好,因为我们不知道这么多点到底每个点带来了哪些贡献,所以凯明团队再次出手,化繁为简,提出SimSiam。这篇文章有多简单呢,既不需要负样本,不需要大的batch size,不需要动量编码器,在这种情况下SimSiam也能取得很好的结果。

网络结构如上所示,首先两个编码器的网络结构是一样的,而且是要共享参数的,然后有一个predictor,然后预测另一个特征,和BYOL不一样的就是不需要动量更新。目标函数用的是negative cosine similarities loss,说白了就是一个mse loss,然后预测可以是双向的,即可以用x1出去的特征过predictor预测x2出去的特征也可以反过来。

作者后续还做了很多实验,结论就是SimSiam之所以不会模型坍塌,主要就是因为有stop gradient这个操作的存在,然后作者还提出了一个假设,因为有stop gradient的存在,所以SimSiam这个结构是可以把它想象成是一个EM算法。作者的意思就是说因为有了stop gradient操作,这一个训练过程,或者说这一套训练参数,其实就人为劈成两半,就相当于我们在解决两个子问题一样,然后模型的更新其实也是在交替进行的,作者也做了一系列推导,到最后我们可以把他理解为一个kmeans问题,即每次先把一些点分配给一些聚类中心,一旦分配好了再去更新这个聚类中心,然后再反复去做这个操作。从这个角度来说,SimSiam又跟SwAV有点关系了。

最后作者还画了一个图,清晰的表达出各个结构的异同,这里我就不多赘述了。讲到这第三阶段就结束了,当然还有一篇论文叫Barlow Twins,是Yann LeCun组的一篇论文,那篇论文就是把目标函数换掉了,既不是在作对比,也不是在做预测,是生成了一个关联矩阵,希望这个矩阵能跟一个identity matrix即对角线是1,其他部分是0的矩阵尽量相似,说白了就是希望正样本相似性尽量逼近于1,然后跟别的样本尽量不相似,相似尽量就是0。

Transformer

MoCo v3(An Empirical Study of Training Self-Supervised Vision Transformers)

实际上MoCo v3只是一个架构,卷积神经网络可以用,Transformer也可以用。

因为没有模型总览图,所以我们就对着伪代码来讲。我们可以发现,MoCo v3其实就相当于是MoCo v2和SimSiam的合体,整体还是有2个网络,而且key网络是动量编码器,而且最后的目标函数用的是对比学习的loss,所以从这个角度来讲,它是个MoCo v2。但是query还有projection和predictor,而且目标函数用的是一个对称项,也就是算query1到key2,也算query2到key1,从这个角度讲又是SimSiam。然后因为Vision Transformer的爆火,所以作者也换了骨干。

但是从实验结果来看,batch size小的时候不会出现什么问题,但是当这个batch size变大了以后,这个曲线会训练训着训着就掉了,最后效果也差了,一般越大的batch size效果应该最好,但在这里却更差了。所以作者认为要解决这个问题,Vision transformer才会发挥它真正的力量。

针对这个问题,MoCo v3提出了一个小trick。他们去看每一层回传的梯度,作者发现目标函数每次震荡的时候,梯度也发生了震荡,这个波峰就发生在每次Transformer第一层做patch projection的时候,即把图片打成patch的操作。所以作者就尝试了不让他训练,把这层冻住,看结果会怎样,作者具体做法就是随机初始化了一个patch projection层,然后就冻住了,发现问题就解决了,而且这个问题在BYOL也有用(骨干换成Transformer)。

DINO(Emerging Properties in Self-Supervised Vision Transformers)

最后一篇论文就是DINO,这篇文章的卖点就是vision transformer在自监督训练的情况下,会有一些非常有趣的特性,我们来看看下图。

如果我们把自监督学习下的vision transformer的自注意力图拿出来可视化,会发现他可以抓到每个物体的轮廓,甚至匹配语义分割的效果。

DINO的做法和之前的差不多,就是换了一种方式来讲故事:它把整个框架叫做是蒸馏的框架,至于为什么是自蒸馏呢,其实就跟BYOL一样,因为是自己跟自己学。DINO把左边叫做student网络,右边叫做Teacher网络,因为student要去预测teacher网络的输出,具体前向过程跟BYOL是十分相似的,唯一不同的就是DINO做了一个Centering的操作,这个操作就是把整个batch的样本都去算一个均值,然后减掉这个均值就算是这个centering,这个就很像BYOL关于batch norm的讨论,最后也是有一个stop gradient的操作。

第四阶段这两篇工作从方法和模型的角度来说,和第三阶段基本一样,主要就是融合了Vision Transformer。

总结

从最开始的InstDisc开始,它提出了个体判别的任务,而且提出用一个memory bank的外部数据结构存储负样本,从而达到一个又大又一致的字典。如果不用外部结构,就是另外一条路端对端学习,也就是InvaSpread这篇论文做的,它只用一个编码器从而可以端到端的学习。但受限于batch size太小,性能不太好。接下来CPC v1这篇论文提出了InfoNCE这个loss,而且CPC v1是一个预测型的代理任务,不仅可以做图像,还可以做音频视频和强化学习。最后还有CMC的工作,把两个视角的任务扩展到了多个视角,从而给多视角或者多模态的这个对比学习打下了铺垫。另外还有一篇Deepcluster我们没有讲,它是基于聚类学习,没有用对比学习。第二阶段就是MoCo v1打头,它算是InstDisc一个延伸性工作,把memory bank变成了一个队列,把动量更新个特征变成了动量更新编码器,从而能训练一个很好的模型。MoCo也是第一个在很多下游任务上让一个无监督预训练的模型比有监督预训练模型表现好的方法。然后他是属于使用外部数据结构的,那自然端到端学习也有延伸性的工作,就来到了SimCLR v1。SimCLR v1跟InvaSpread方法是很像的,但是他用了很多技术,比如加大了batch size,用了更多的数据增广,加了projection head,训练了更长时间,总之所有技术堆起来让SimCLR效果变得很好。CPC看到效果这么看,于是把技术也都来拿来用一遍,然后CPC v2就比v1在ImageNet高了30多个点。最后CMC把这些都分析了一下,提出了infoMIn的原则,他们说两个样本或两个视角之间的互信息,要不多不少才是最好的。MoCo作者看到SimCLR提出的这些即插即用的技术都很好用,于是都拿了过来,于是用了MoCo v2。SimCLR v2也对模型做了一些改动,但SimCLR v2主要是去做半监督学习的。另外之前提到Deepcluster是想引出SwAV这个方法,它和MoCo v2和SimCLR v2效果是差不多的。然后第三阶段就到了BYOL这种不用负样本的方法,把配对任务改成预测任务,把目标函数也改成了简单的mse loss就可以训练,但是大家都觉得很不可思议,所以就有一篇blog提出BYOL能工作主要是因为有BN,BN提供了隐式的负样本。但是BYOL作者很快发了v2,通过做实验最后说BN只是帮助模型训练,不用BN用别的帮助模型训练不提供统计量的方法,BYOL也能工作的很好。紧跟着BYOL v2,SimSiam就出来了,SimSiam就把之前的工作都总结了一下,化繁为简,提出了一个孪生网络的学习方法,既不用大的batch size,也不需要动量编码器,也不需要负样本也能取得很好的效果。他提出的一个假设就是stop gradient操作很重要,因为这个操作SimSiam可以看成是一个EM算法,通过逐步更新避免模型坍塌。另外还有一篇barlow twins,主要就是更换了一个目标函数,把之前大家做的这种对比或预测变成了两个矩阵之间去比这个相似性。最好第四阶段来到了Transformer的时代,就是MoCo v3和DINO,其实就是骨干换成了Transformer,但是换成了vision transformer之后,面临的问题都是说训练不稳定或者不好训练,所以提出了各自的办法:MoCo v3就是提出把这个patch projection layer冻住,DINO就是提出把teacher网络的输出做centering,这两种方式都能有效提高模型训练的这个稳健性,防止模型坍塌,让Vision Transformer用自监督的方式也能训练的很好。

参考

朱毅老师的解读https://www.bilibili.com/video/BV19S4y1M7hm/?spm_id_from=333.999.0.0&vd_source=d8673d961b825117f97b7ea28c540f9d

0 人点赞