文章目录

  • 1. 第一阶段:百花齐放
    • 1.1 InstDisc
    • 1.2 InvaSpread
    • 1.3 CPC
    • 1.4 CMC
  • 2. 第二阶段:CV双雄
    • 2.1 MoCov1
    • 2.2 SimCLRv1
    • 2.3 MoCov2
    • 2.4 SimCLRv2
    • 2.5 SWaV
    • 2.6 Other
  • 3. 第三阶段:不用负样本
    • 3.1 BYOL
    • 3.2 SimSiam
  • 4. 第四阶段:Transformer
    • 4.1 MoCov3
    • 4.2 DINO
  • 5. 总结

1. 第一阶段:百花齐放


在第一阶段上,方法模型都没有统一,目标函数,代理任务也没有统一,所以说是一个百花齐放的年代。

1.1 InstDisc

paper:Unsupervised Feature Learning via Non-Parametric Instance Discrimination

InstDisc的工作是受到了有监督学习结果的启发,如果把豹子的图片喂给一个已经用有监督学习方式训练好的分类器,会发现它给出来的分类结果排名前几的全部都是跟豹子相关的(比如猎豹和雪豹),而排名靠后的判断往往是和豹子一点关系也没有的类别。

InstDisc认为,让这些图片聚集在一起的原因,并不是这些图片有相似的语义标签信息,而是因为这些图片长得比较像。猎豹雪豹就是长得相似,和其他就是不相似,所以才会导致这里的分类分数。因此,作者将这种有监督的任务发挥到极致,提出了个体判别任务,作者将每一张图片都看作是一个类别,希望模型可以学习图片的表征,从而把各种图片都区分出来。

简单概括InstDisc的思想,通过一个卷积神经网络来将图片进行编码成一个低维特征,然后使得这些特征在特征空间上都尽可能的区分开,因为个体判别认为每张图片都是自成一类,结构图如下所示:

训练这个神经网络的方法是对比学习,所以需要有正样本,需要有负样本。正样本就是图像本身,可能经过数据增强,负样本就是数据集中其余的所有图片,该文章使用一个memroy bank存储这些负样本,imagenet中有128w的数据,意味着memory bank有128w行,因为负样本太多了,如果使用较高的维度表示图片的话,对于负样本的存储代价过高,因此作者让向量维度为128维。

简单的走一下这个前向传播的过程,假设模型的batchsize是256,有256张图片进入CNN网络,将256张图片编码为128维的向量。因为batchsize是256,因此有256个正样本。负样本来自memory bank,每次从memory bank中随机采样出4096个负数样本,利用infoNCE loss去更新CNN的参数。本次更新结束后,会将CNN编码得到的向量替换掉memory bank中原有的存储。就这样循环往复的更新CNN和memory bank,最后让模型收敛,就训练好一个CNN encoder了。

在InstDisc还有其他的细节,比如Proximal Regularizatio,给模型的训练增加了一个约束,从而可以让memory bank里面的特征进行动量式更新,保持一致性。

InstDisc中还有超参数的设定:

τ = 0.07 ;
passive numbers = 4096;
epoch = 200 ;
batch size = 256;
orgin learning rate = 0.03

InstDise提出了个体判别这个代理任务,而且用这个代理任务和nce loss去做对比学习取得了不错的无监督表征学习的结果,同时提出了用别的结构存储这些大量的负样本,以及如何进行动量的更新,为后续的对比学习的工作产生了推进的作用。

1.2 InvaSpread

paper:Unsupervised Embedding Learning via Invariant and Spreading Instance Feature

InvaSpread可以理解为是SimeCLR的前身。InvaSpread并没有用额外的数据结构存储大量的负样本,他就是用mini batch中的数据作为负样本,而且使用一个编码器进行端到端的学习。

InvaSpread的想法就是最基本的对比学习,同样的图片通过编码器其特征应该比较类似,而不同的图片通过编码器的特征就应该不类似。对于相似的图片或者物体,其特征应该保持不变形Invariant ,而对于不相似的图片或者是物体其特征应该分散开Spreading

InvaSpread的代理任务也是Instance Discrimination,这里着重讲一下该文章中正例和负例的选择。该文章设置的batchsize是256。首先利用数据增广,将每个图片增广一次,也就是将256张图片变为512个图片了。之后将512张图片通过CNN编码为向量,并使用一个全连接层将数据的维度降低。之后将xix_{i}xi和其经过增广后的图片x~i\widetilde{x}_{i}x

i作为正样本,其余的512-2张图片都认为是负样本。所以总计有256个正例,有2×(256-1)张负例。之后的在特征空间中xix_{i}xix~i\widetilde{x}_{i}x

i
的距离应该尽可能相近,而xix_{i}xix~j\widetilde{x}_{j}x

j
的距离应该尽可能相远。


该文章的思路和SimCLR的思路差不多,都设计用batch中的数据作为正例和负例,但是该文章取得的效果没有SimCLR的效果那般炸裂。主要是因为本文所选取的字典长度不够大,batchsize仅为256,本文也没有设计SimCLR那种投影函数和多样的数据增广方法,因此本文取得的效果不如SimCLR那么好。

以上两篇工作都是使用个体判别Instance Discrimination作为代理任务的,接下来介绍的这篇文章是利用其他代理任务进行对比学习的。

1.3 CPC

paper:Representation Learning with Contrastive Predictive Coding

一般机器学习分为生成式模型与判别式模型,个体判别Instance Discrimination属于判别式的范畴,那么肯定也会出现生成式的代理任务,这里的CPC就是属于生成式的代理任务。

CPC是一个很通用的结构,不光可以处理音频,图片,文字,还可以在强化学习里使用。其主要的想法是,有一个持续的序列,把之前时刻的输入喂给编码器,返回的特征再喂给一个自回归模型garauto-regressive,一般的自回归模型是RNN或LSTM),然后得到一个context representation,这是一个代表上下文的特征表示。如果context representation足够好,那么其应该可以做出一些合理的预测,所以可以用ctc_{t}ct预测未来时刻的特征输出zt+iz_{t+i}zt+i.

对比学习需要正负样本的对比,所以在CPC中,这里的正样本就是通过编码器之后得到未来时刻的特征输出zt+iz_{t+i}zt+i,将其他的序列作为负例,进行对比学习的训练。

CPC的思想比较朴实,把序列输入换成一个句子,就可以用前面的单词预测后面单词的特征输出。如果把序列换成一个图片的patch,那么就可以用上半部分的图片特征去预测后半部分的图片特征。

1.4 CMC

paper:Contrastive Multiview Coding

CMC提出一个想法,人通过很多的传感器来观察这个世界(比如眼睛或者是耳朵),来给大脑提供不同的信号,然后每一个视角都是带有噪声的,而且有可能是不完整的。但是最重要的那些信息,其实是在这些信息中共享的。比如说基础的物理定律,或者几何形状,或者是它们的语义信息,这些都是共享的。比如一只狗即可以被看见,也可以被听见,也可以被感受到。

基于这个现象,CMC想学一个非常强大的特征,其具有视角的不变性(不管是看见了一只狗,还是听到了狗叫声,都能判断出这是个狗)。所以,CMC的工作目的就是去增大这个互信息,就是所有视角之间的互信息。如果能学到一种特征,能够抓住所有视角下的这个关键的因素,那么这个特征就比较好。

CMC使用的数据集是NYU RGBD数据集,该数据集包含一张图片的四种view数据增强结果(包含原始的图像,以及这个图像对应的深度信息,SwAV ace normal,语义分割)。虽然这些不同的输入view来自于不同的传感器,或者说是不同的模态,但是这些所有的输入其实对应的都是一整的图片,一个东西,那么它们就应该互为正样本,相互配对。而这些相互配对的视角在特征空间中应该尽可能的相近,而与其他的视角尽可能的远离。

CMC定义正负样本的方式:将不同的view作为正例,将其他图片以及其他图片的views作为负例子,进行训练。

CMC的成功,让我们认识到对比学习可以如此的灵活,Open AI团队的工作CLIP将图片-文本对作为输入,将互相匹配的图像-文本对作为正例,将不匹配的作为负例。同时CMC的原班人马利用对比学习做知识蒸馏,他们认为相同的样本在不同的编码器下得到的结果应该尽可能的相似,因此设计的teacher和student编码得到的相同图片的向量互为正例,不同图片得到的输出作为负例,利用对比学习的思路进行知识蒸馏。

但是问题在于multi view的工作可能需要多个编码器进行编码,训练代价可能有点高。比如CLIP,就是用大型的语言编码器BERT对语言模型进行编码,用视觉模型VIT对视觉信息进行编码。

小结:

第一阶段介绍以上四篇工作,可以看到以上的工作代理任务不尽相同,其中有个体判别,有预测未来,还有多视角多模态。使用的目标函数也不尽相同,有NCE,infoNCE以及其变体。使用的模型也可以是不同的,比如InvaSpread使用的是相同的编码器对key和query进行编码,CMC对key和query使用的是不同的编码,是百花齐放的。

2. 第二阶段:CV双雄


2.1 MoCov1

paper:Momentum Contrast for Unsupervised Visual Representation Learning

主要贡献就是把之前对比学习的一些方法归纳为一个字典查询问题。提出了一个队列,一个动量编码器,从而形成一个又大又一致的字典,帮助更好的进行对比学习。

MOCO和InstDise有很多类似的地方,从模型的角度上都是用了残差网络,基线模型用的都是Res50,模型都是一样的。每个图片的特征维度都是128维,也对所有的特征作了L2归一化。至于目标函数,MoCo采用的是info NCE,InstDisc采用的是NCE,但是算loss的温度都是用了0.07。MOCO训练的学习率,epoch数,以及数据增强都是借鉴了InstDisc。但是MOCO对InstDise的改进可以说是简单又有效,其提出用队列替换memory bank以及提出了动量更新的方式,对效果有显著的提升,同时对后续工作也产生了深远的影响。

MoCo与之前工作的对比图:

其他有关MoCo的详细介绍,见:Unsupervised Learning | 对比学习——MoCo

2.2 SimCLRv1

paper:A Simple Framework for Contrastive Learning of Visual Representations

SimCLR方法比较简单,概念上也更容易理解,方法上也很容易解释,但是缺点就是batch size太大,一般人不好上手。

SimCLR结构如下图所示:

假如有一个minibatch的图片,对整个minibatch的所有图片做数据增强,对图片xxx做不同的数据增强就会得到xix_{i}xixjx_{j}xj 。同一个图片延申得到的两个图片就是正样本,比如batchsize是n的话,那么正样本就是n,这个batchsize剩下的所有的样本以及其经过数据增强后得到的都是负样本,也就是2(n-1)。有了正负样本之后,对其进行编码,通过一个编码器f(⋅)f(·)f()得到正负样本的编码结果hhh 。SimCLR的创新点就是在得到数据的编码之后在后面加了一个编码层g(⋅)g(·)g()函数,就是一个MLP层,得到较低维度的特征ziz_{i}zizjz_{j}zj ,用其进行对比学习,拉近正例之间的距离,拉远负例之间的距离。但是需要注意的一点就是投影函数仅仅在训练的时候才使用,在测试的时候是不使用的,测试的时候仅仅使用编码器f(⋅)f(·)f() 。加上投影函数的目的也仅仅是想让模型训练的更好。

可以发现,其实SimCLR与之前的InvaSpread是比较相似的,不同之处在于:
1)SimCLR使用了更多的数据增强
2)加入了投影的g(⋅)g(·)g()函数
3)就是SimCLR用了更大的batchsize,且训练的时间更久

SimCLR使用了以下的数据增强方式:

不同数据增强方式之间的消融实验:

这个消融实验证明随机的裁剪以及随机的色彩变换的必要性,其他的数据增强最后都只是锦上添花可有可无。

此外,SimCLR里还对这个投影层做了一些实验,这里的Linear表示不带relu;Non-linear表示带relu;None表示没有Projection。可以看到使用非线性变化的效果是十分显著的,同时对于对比学习维度变化,似乎并不会对效果产生影响,所以一般128维就足够了。

2.3 MoCov2

paper:Improved Baselines with Momentum Contrastive Learning

MoCov2其实是一篇只有两页的技术报告,严格上说并不是一篇论文,但是信息量还是比较大的。

MOCO v2相当于是把SimCLR中值得借鉴的地方拿来借鉴,比如其中MLP的投影层,更多的数据增强方式,cosine learning rate schedule,以及更多的迭代epoch。其中supervised是backbone在有监督训练中进行训练的结果。在加入了SimCLR的一些改进点后,确实取得了模型性能的进步。

paper对比了MOCO v2和SimCLR在相同的epoch和batch下的效果对比,在较小的batch和epoch下,MOCO v2取得了较好的效果,在较大的batch和epoch下,也取得了较好的效果。也就是说,MoCo可以更好的利用数据,可以在更短的时间内取得更好的结果。

paper又将MOCO v2和SimCLR的算力作对比,再一次强调MoCo的优越性。SimCLR在batch较少的情况下无法发挥效果,在batch多的情况下才可以出效果,但是算力要求太高了。所以MOCO是一个对于计算资源要求不是很高,但是却很有效的模型。

2.4 SimCLRv2

paper:Big Self-Supervised Models are Strong Semi-Supervised Learners

SimCLRv2只是paper中很小的一部分,只是说了一下怎么从v1变到v2,只是一个模型上的改进,而其他大部分的内容都是在讲如何去做这个半监督的学习。

SimCLR v2文章提出了一套用自监督网络作半监督训练的流程,该流程是用大网络(SimCLR v2)作自监督的预训练,预训练部分是没有特定下游任务的,因此不具备下游任务知识;之后使用少部分有标注的数据对模型进行微调,从而让模型学习下游任务的特定知识;让微调的模型作为teacher模型,为更多的数据生成伪标签,从而实现自学习。

ps:这里的半监督训练流程借鉴了noisy student self-distillation的工作,核心思想是指用标签的数据训练一个模型,然后用这个模型去预测一个大的没有标号的数据集,然后把那些置信度比较高的数据拿出来,跟之前的有标号的数据集一起拼成一个更大的数据。然后利用这个扩充的数据集重新再训练出一个模型出来。这样等价于数据集变大了,然后可以重复做很多次。

这里的关键点是需要加噪声进去,不然的话如果之前的模型预测一个样本预测错了,但是其置信度又比较高,那么这个错误的监督信号就会进去到训练样本中,使得下一次训练的时候可以在这个错误上更加的错误。而如果加入大量的噪声,比如数据增强,甚至是把标签做一些改变的话,模型就会可以比较好的处理这些不正确的标签。

SimCLR v1是升级到SimCLR v2的流程:
1)如果使用更大的模型,则无监督训练就会训练的更好,所以SimCLR v2使用了ResNet-152并且使用了selective kernels(也就是SE网络),从而让骨干网络更加强悍
2)原来的非线性投影层是十分有效的,那么更深的非线性层会不会更加有效呢?于是作者尝试使用2层,3层,最后发现2层的效果是最好的
3)作者尝试了MOCO的动量编码器,发现效果是有提升的,但是提升的不是非常显著,大概是一个百分点,原因是SimCLR v2已经有很大的batchsize了,所以不需要太多的动量以及队列的负样本了

总的来说,SimCLRv2相比SimCLRv1就是用了更大的模型,加深了projection head,最后用了半监督编码器。

2.5 SWaV

paper:Unsupervised Learning of Visual Features by Contrasting Cluster Assignments

SWaV(Swap Assignment Views)的想法是,给定同样的一张图片,如果去生成不同的视角(views),希望可以用一个视角得到的特征去预测另外一个视角的得到的特征,因为所有的这些视角的特征按道理来说都应该是非常接近的。然后SWaV将对比学习和之前的聚类的方法合在的一起,这样做也不是偶然,因为聚类也是无监督特征表示学习的方法,而且它也希望相似的物体都聚集在一个聚类中心附近,不相似的物体推到别的聚类中心。

SWaV如何与聚类相联系呢?下面是对比学习与SWaV的区别:

  • Contrastive instance learning
    以往的基于对比学习的方法都是将一个实例xxx通过两次数据增强变为x1x_{1}x1x2x_{2}x2,之后利用编码器对其进行编码,从而得到嵌入向量z1z_{1}z1z2z_{2}z2,之后使用对比学习的loss更新这个encoder。

  • SwAV
    即使以往的工作是非常有效并且简洁的,但是因为负样本太多了,从而造成资源的浪费,即使是MOCO这样用近似的方式用6w个负样本,但是总共还是有128w个负样本的,6w个负样本只是一种近视。所以SwAV的作者去想,能不能不做近似呢?可不可以使用先验信息,不去和大量的负样本对比,而是和一些更加简洁的东西去比呢?所以SwAV的作者想,可以和聚类的中心进行对比。这个聚类中心就是CCC ,维度是3000×向量为度,3000表示聚类中心的数量。
    这里的聚类中心CCC就是Prototypes,作为一个矩阵维度是dxk(d是特征的维度128维,k是聚类中心的数目3000)
    SwAV前向过程依旧是一个实例xxx通过两次数据增强变为x1x_{1}x1x2x_{2}x2,之后利用编码器对其进行编码,从而得到嵌入向量z1z_{1}z1z2z_{2}z2。但是有了z1z_{1}z1z2z_{2}z2之后,并不是直接在特征上去做对比学习的loss,而且让z1z_{1}z1z2z_{2}z2和聚类中心CCC进行聚类,从而得到ground truth的标签Q1Q_{1}Q1Q2Q_{2}Q2。如果说两个特征比较相似或者是含有等量的信息,按道理来说应该是可以相互预测的。也就是说,用z1z_{1}z1CCC作点乘按道理是可以去预测Q2Q_{2}Q2的,反过来用z2z_{2}z2CCC作点乘按道理是可以去预测Q1Q_{1}Q1的,SwAV通过这种换位交叉预测的方法来对模型进行训练更新参数。

SwAV的优势在于:
1)如果是和负例进行对比的话,需要和成千上万个负例进行对比,即使是MOCO中6w个负例,也只是一个近似的值,但是聚类的话,就仅仅需要和三千个聚类核心即可。
2)这些聚类中心是有含义的,而如果像之前一样用负样本进行对比学习的话,有的负样本不均衡,有的还可能是正样本,不如聚类中心有效。

SwAV的性能优势不仅仅是与聚类的方法融合了在一起,其还有另外的一个性能提升点Multi-crop

  • Multi-crop
    以往的对比学习方法都是在一张256×256的图片上用两个224×224的crop求两个正样本,但是因为crop过大了,所选取的crop都是基于全局特征的,所以可能忽视了局部特征。所以SwAV使用了一种multi-crop的思路进行操作,即选择了两个160×160的crop去注意全局特征,选择四个96×96的crop去注意局部特征。这样在计算量变化不大的情况下,可以获取更多的正样本,也可以同时注意了全局特征与局部的特征。

此外,Multi-crop对于其他的技术同样有用,如下图所示:

但是从图也可以看到,用纯聚类的方法或者说聚类和对比学习的方法结合在一起其实也并没有什么优势,真正提点的是Multi-crop这个技术。而且Multi-crop比较朴实,就是同时关注了全局特征与局部特征,想起Focal Transformer的工作就是提出了要同时结合粗粒度与细粒度的特征,所以看得出来结合全局与局部特征是比较有效果的。

有关Focal Transformer的笔记,见:论文阅读笔记 | Transformer系列——Focal Transformer

2.6 Other

  • CPCv2
    简单说一下,CPCv2也融合了比较多的技巧。用了更大的模型,用了更大的图片块,做了更多方向上的预测任务,把BatchNorm换成了LayerNorm,还使用了更多的数据增强。CPCv2在这些工作之后,把CPCv1从40+提高到70+的准确率。

  • InfoMin
    InfoMin是CMC的作者做的一个分析型的延伸性工作,paper叫《what makes for good views for contrastice learning》,选一个什么样的视角才能对对比学习最好。主要是提出了一个InfoMin的原则,最小化互信息minimi mutual information
    InfoMin的本意是不能一味的最大化这个互信息,而是要不多不少刚刚好,去选择合适的数据增强与合适的对比学习的视角。

小结

到了第二阶段,其实很多细节都趋于统一了,比如目标函数都是使用infoNCE,模型都归一为用一个encoder+projection head了,大家都采用了一个更强的数据增强,都想用一个动量编码器,也都尝试训练更久,最后在ImageNet上的准确度也逐渐逼近于有监督的基线模型。

3. 第三阶段:不用负样本


其实SwAV已经是不用负样本了,但是他还是和一个聚类的中心这样明确的对比对象进行比较,一下介绍的BYOL和SimSiam就是正样本自己在和自己玩,已经没有正样本,或者聚类中心这样明确的对比对象了。

3.1 BYOL

paper:Bootstrap Your Own Latent A New Approach to Self-Supervised Learning

  • BYOL的神奇之处

在对比学习中的负样本是一个约束,如果在算目标函数的时候只有一个正样本,这时候就只有一个目的,就是让相似的物体他们的特征也尽可能的相似。这时候就可能会有一个明显的捷径解,如果一个模型无论给什么样的输入,他都返回相同的输出,这样出来的所有特征,都是一模一样的,这样去计算对比学习的loss就全为0,模型这样躺平是学习不到实例的特征的,是无效的。

因此需要添加了负样本对模型造成一个约束,这样如果模型躺平直接输出输入的话,对于正样本的loss为0,但是对于负样本来说loss就无穷大,这样子模型才会学习如何权衡让正负样本的loss都往下降,达到一个最优解。所以负样本在模型中是一个必须的东西,可以防止模型躺平,学到这个捷径解。

BYOL的神奇之处在于模型没有使用负样本,仅仅是模型自己和自己去学,但是也实现了很不错的效果。

  • BYOL的前向过程

首先有一个mini-batch的输入xxx,经过两次不同的数据增强之后得到vvvv′v^{'}v,然后通过编码器fθf_{\theta}fθfξf_{\xi}fξ分别得到特征yθy_{\theta}yθyξ′y_{\xi}^{'}yξ(如果是ResNet50,就是得到了一个2048维的特征)。这里的编码器fθf_{\theta}fθfξf_{\xi}fξ使用的相同的网络架构,但是其参数是不同的,也就是分别独立,没有共享参数,只是架构相同而已。fθf_{\theta}fθ是随着梯度更新而更新的,而fξf_{\xi}fξ与MoCo一样,是用moving average的这种形式去更新的,其实也就是使用了动量编码器。

接下来与SimCLR一样,用了projection head编码器gθg_{\theta}gθgξg_{\xi}gξ(这里称为projector,其实就是一个MLP层)再得到zθz_{\theta}zθzξ′z_{\xi}^{'}zξ特征(这里是256维)。gθg_{\theta}gθgξg_{\xi}gξ同样也是一样的网络结构,但是参数不一样。gξg_{\xi}gξ也是通过动量的这种方式去更新的。

在之前的对比学习工作中,是让zθz_{\theta}zθzξ′z_{\xi}^{'}zξ尽可能的相似,而在BYOL这里,又加了一层predictor的全连接层qθq_{\theta}qθqθq_{\theta}qθ的网络结构和gθg_{\theta}gθ的网络结构是完全一样的。zθz_{\theta}zθ通过qθq_{\theta}qθ又得到了一个新的特征qθ(zθ)q_{\theta}(z_{\theta})qθ(zθ),现在的目的是想让特征qθ(zθ)q_{\theta}(z_{\theta})qθ(zθ)zξ′z_{\xi}^{'}zξ尽可能的相似。这相当于把原来匹配的问题,换成了现在一个预测的问题。

图中的sg表示stop gradient,这里是没有梯度的。这与MoCo很像,模型的上一支相当于query编码器,下面一支相当于key编码器,而key编码器都是通过query编码器来动量更新。不同是代理任务不一样,BYOL相当于是自己一个视角的特征去预测另外一个视角的特征,通过这种预测性的任务来完成模型的训练。

以上就是BYLO的训练流程,当训练结束后,只有编码器fθf_{\theta}fθ留下了,这相当于是一个特征提取器,其余的全部拿走。然后通过编码器fθf_{\theta}fθ输出的特征yθy_{\theta}yθ去做其他的下游任务。目标函数用的是MSE(mean squared error),因为目的就是让两个向量尽可能的接近,所以mse loss就可以了,公式如下图:

BYLO使用的目标函数与其他的对比学习都不一样,而且其不需要负样本,这是其创新性。

  • BYLO中关于BatchNorm的插曲

在一篇博客上,Understanding Self-Supervised and Contrastive Learning with “Bootstrap Your Own Latent” (BYOL)发现了BatchNorm的一个问题。首先对比一下SimCLR,MoCov2,BYOL中关于projection head的具体结构图。

1)SimCLR中的projection head有两个BatchNorm

2)MoCov2中的projection head没有BatchNorm

3)BYOL中的projection head只有一个BatchNorm

当BYOL的projection head不使用BatchNorm时,会发生模型坍塌的情况,博客作者作了一下实验:

实验发现,在BYOL里,当在任意一个projection head使用BatchNorm时,模型就不会坍塌。博客对这个情况作了一个解释,BatchNorm会吧一个batch里所有样本的特征计算均值方差,也就是running meanrunning variance。然后用整个batch算来的均值和方差去作归一化。这就说明,当用某个正样本的loss时,其实也看见了其他样本的特征,也就是发生了信息泄露。由于这种信息泄露的存在,可以把这个batch中的其他样本看成是一种隐式的负样本。所以BYOL就可以看出是当前的样本和平均图片有什么差别,平均图片就是BatchNorm产生的,这里的平均图片和SwAV的聚类中心的说法有点相似。

总的来说,这篇博客认为BatchNorm是BYOL成功的关键,相当于提供了一种隐式的正负样本学习。

  • BYOL的回应


这里对于SimCLR,及时提供了显式的负样本,没有BN还是失败,所以说明BN并不是提供了一种隐式的负样本。最后的结果是,BatchNorm可以提高模型的训练稳健性,从而导致不会模型坍塌,也就是如果一开始模型的初始化就比较好(比如使用group normweight standardization),那么BYOL其实没有BatchNorm也是可以正常训练的。

3.2 SimSiam

paper:Exploring Simple Siamese Representation Learning

SimSiam 不需要用负样本,不需要大的batchsize,不需要动量编码器,即使在这种条件下,SimSiam不仅没有模型谈谈,反而取得了很好的模型效果。

  • SimSiam的网络结构图如下:

前向过程是一个实例xxx经过数据增强变为x1x_{1}x1x2x_{2}x2,之后经过孪生的编码器f(⋅)f(·)f(),得到嵌入z1z_{1}z1z2z_{2}z2 ,之后经过预测层得到p1p_{1}p1p2p_{2}p2 ,之后让p1p_{1}p1预测z2z_{2}z2 ,用p2p_{2}p2去预测z1z_{1}z1,进行模型的训练。

  • SimSiam的伪代码如下:
# f: backbone + projection mlp
# h: prediction mlp
for x in loader: # load a minibatch x with n samplesx1, x2 = aug(x), aug(x) # random augmentationz1, z2 = f(x1), f(x2) # projections, n-by-dp1, p2 = h(z1), h(z2) # predictions, n-by-dL = D(p1, z2)/2 + D(p2, z1)/2 # lossL.backward() # back-propagateupdate(f, h) # SGD updatedef D(p, z): # negative cosine similarityz = z.detach() # stop gradientp = normalize(p, dim=1) # l2-normalizez = normalize(z, dim=1) # l2-normalizereturn -(p*z).sum(dim=1).mean()

SimSiam能够成功训练的原因,不会发生模型坍塌,主要就是因为有stop gradient这个操作的存在。由于stop gradient,可以将SimSiam的结构看成是一个EM算法,相当于是在解决两个子问题,而模型更新也在交替进行,相当于不断的更新聚类中心。

  • SimSiam与其他结构的对比:

    1)SimCLR使用的是端到端的训练,两个encoder,提出了projection head
    2)SwAV是和聚类中心进行对比的(通过Sinkhorn-Knopp算法生成聚类中心)
    3)BYOL是一个预测任务,其使用的是动量编码器,没有使用负样本,创新性地将匹配问题变成预测问题
    4)SimSiam也是预测任务,但是使用的是stop gradiant的方式进行预测的,并且使用孪生网络,不需要动量编码器

  • SimSiam与其他结构的效果对比:

4. 第四阶段:Transformer


在vision transformer之后,因为其大大提升了encoder的效果,所以很多对比学习任务打算使用vision transformer作为backbone进行对比学习,涌现出了两篇工作,分别是MoCov3和DINO。

4.1 MoCov3

paper:An Empirical Study of Training Self-Supervised Vision Transformers

MoCov3中大部分的篇幅都在将如何做Vision Transformers的自监督训练,而且由于MoCov3没有结构图,只能看伪代码:

# f_q: encoder: backbone + proj mlp + pred mlp
# f_k: momentum encoder: backbone + proj mlp
# m: momentum coefficient
# tau: temperaturefor x in loader: # load a minibatch x with N samplesx1, x2 = aug(x), aug(x) # augmentationq1, q2 = f_q(x1), f_q(x2) # queries: [N, C] eachk1, k2 = f_k(x1), f_k(x2) # keys: [N, C] eachloss = ctr(q1, k2) + ctr(q2, k1) # symmetrizedloss.backward()update(f_q) # optimizer update: f_qf_k = m*f_k + (1-m)*f_q # momentum update: f_k# contrastive loss
def ctr(q, k):logits = mm(q, k.t()) # [N, N] pairslabels = range(N) # positives are in diagonalloss = CrossEntropyLoss(logits/tau, labels)return 2 * tau * loss# Notes: mm is matrix multiplication. k.t() is k’s transpose. The prediction head is excluded from f k (and thus the momentum update).

可以发现,MoCov3有点像MoCov2和SimSiam的结合。
1)整体的网络还是有两个编码器,一个query编码器,一个是key编码器,而且key编码器是一个动量编码器,而且最后的目标函数用的是对比学习的loss。
2)而且编码器结构用还使用了projection headprediction head,而且目标函数也是一个对称性,就是相互预测,计算query1key2,也计算query2key1

当把backbone将残差网络换成是Vit时,在batch size比较小时,训练还算比较稳定,曲线比较平滑;但是一旦batch size变大,模型就出现了不稳定的情况,虽然最后也会回复上去,但是准确率会差很多,如下图所示:

作者观察了一下模型梯度回传时候的梯度情况。当每次loss有大幅的震动,导致准确度大幅下降的时候,梯度也会有一个波峰,波峰发生在第一层,在作patch projection的时候,因为这一层经常出现问题,所以作者尝试将这一层冻结住(也就是不再训练这层的参数)。解决的办法就是随机初始化了这个patch projection层,然后对其冻结,随后的训练过程中参数保持不变,然后问题就解决了,获得了平滑了训练曲线。

4.2 DINO

paper:Emerging Properties in Self-Supervised Vision Transformers

DINO也是用自监督来训练Vision Transformers的方式,其主要卖点是说Vision Transformers在自监督训练的情况下,会有一些非常有趣的特性,然后把这些图片放在了图1,如下所示:

这里想表达的意思是一个完全不用任何标签信息训练出来的Vision Transformers,如果将其自注意力图拿出来进行可视化,可以发现其可以非常准确的抓住每个物体的轮廓,这个效果甚至可以直接匹配对这个物体作语义分割。

DINO全称为Self-distillation with no labels,其将整个框架称为一个蒸馏的框架,结构如图所示:

DINO的前向过程都是类似的,当有一个图片xxx的两个视角x1x_{1}x1x2x_{2}x2之后,x1x_{1}x1x2x_{2}x2分别通过学生网络编码器gθsg_{\theta s}gθs和教师网络编码器gθtg_{\theta t}gθt得到两个特征p1p_{1}p1p2p_{2}p2,其中编码器结构中同样包含projection headprediction head。而为了避免模型的坍塌,DINO做了一个额外的工作centering,这个操作就是把整个batch里的样本都算一个均值,然后减掉这个均值其实就是centering。最后也是有一个stop gradient的操作,然后用p1p_{1}p1预测p2p_{2}p2

  • DINO的伪代码:
# gs, gt: student and teacher networks
# C: center (K)
# tps, tpt: student and teacher temperatures
# l, m: network and center momentum ratesgt.params = gs.params
for x in loader: # load a minibatch x with n samplesx1, x2 = augment(x), augment(x) # random viewss1, s2 = gs(x1), gs(x2) # student output n-by-Kt1, t2 = gt(x1), gt(x2) # teacher output n-by-Kloss = H(t1, s2)/2 + H(t2, s1)/2loss.backward() # back-propagate# student, teacher and center updatesupdate(gs) # SGDgt.params = l*gt.params + (1-l)*gs.paramsC = m*C + (1-m)*cat([t1, t2]).mean(dim=0)def H(t, s):t = t.detach() # stop gradients = softmax(s / tps, dim=1)t = softmax((t - C) / tpt, dim=1) # center + sharpenreturn - (t * log(s)).sum(dim=1).mean()

伪代码和MoCo比较像的,主要是目标函数上面有一点不同。

小结:

最后的这个阶段,从方法和模型的角度上来说,其实和第三阶段基本是一模一样的,主要就是融合了Vision Transformers。

5. 总结

下面,再把整个对比学习的发展脉络理一遍

  • 第一阶段

    • InstDisc:提出了个体判别任务, 而且提出用一个memory bank这么一个外部数据结构去存储负样本,从而得到一个又大又一致的字典去做对比学习。
    • InvaSpread:不用外部结构,使用端到端的学习,只用一个编码器。但是受限于batch size太小,所以性能不够好。
    • CPCv1:提出infoNCE这个目标函数,而且其是一个预测型的代理任务,不仅可以做图像、音频,还可以视频、文字和强化学习,是一个非常全能的结构。
    • CMC:将两个视角的任务扩展到多个视角,从而为之后的多视角或者多模态的对比学习打下了铺垫。
  • 第二阶段
    • MoCov1:算是InstDisc的延伸工作,把memory bank变成了一个队列,也是属于使用外部数据结构,然后把动量更新特征变成了动量更新编码器,从而能预训练一个很好的模型。MoCov1也是很多视觉下游任务上让一个无监督预训练模型比有监督预训练模型表现好的方法。
    • SimCLRv1:与InvaSpread方法很像,但是用了很多技术,比如说加大了batch size,用了更多的数据正确,加了一个projection head,训练得更长时间,总之这些技术堆起来让SimCLRv1在ImageNet上有一个非常好的结果。
    • CPCv2:CPCv2把这些新技术用了一遍,直接从40多点提升到70多点。
    • Infomin:CMC提出了Infomin的原则,两个样本或者两个视角之间的互信息要不多不少才是最好的。
    • MoCov2:MoCov2把SimCLRv1这些即插即用的计算用了起来,MoCov2的效果就比MoCov1和SimCLRv1的效果都要好。
    • SimCLRv2:SimCLR对模型进行了一点改动得到了SimCLRv2,其主要是做半监督学习的。
    • SwAV:把聚类学习和对比学习结合了起来也取得了不错的结果,但是这个结果主要是来自其提出的multi crop这个技术,如果没有这个技术,其与MoCov2与SimCLRv1是差不多的。
  • 第三阶段
    • BYOL:处理负样本过于麻烦,自己与自己学,把一个对比任务变成了一个预测任务。而且目标函数也比较简单,不再使用info NCE,而且用一个简单的mse loss就可以训练出来。
    • BN Blog:由于BYOL有点不可思议,提出BYOL能够工作主要是因为有batch normbatch norm提供了一种隐式的负样本,所以BYOL可以正常训练而不会模型坍塌。
    • BYOLv2:BYOL用来回应BN Blog的论文,其通过做了一系列实验之后,最后说batch norm只是帮助了模型的训练,如果能用另外一种方式能提供一个更好的模型初始化,BYOL不需要提供batch的那些统计量照样能工作,这样就把blog的假设给打破了。
    • SimSiam:把之前的工作总结了一下,因为技术堆得过多就不好分析了,这个领域就不好继续推进了,所以其化繁为简,又提出了一个很简单的孪生网络的学习方法。其既不需要大的batch size,也不需要动量编码器,也不需要负样本照样能取得不错的结果。其提出了一个假设stop gradient这个操作是至关重要的,因为这个操作的存在,所以SimSiam可以看出是一种EM算法,通过这种逐步更新的方式避免模型坍塌。
    • Barlow twins:主要是更换了一个目标函数,把之前的对比或者是预测变成了两个矩阵之间的对比相似性。
  • 第四阶段
    • 其实都是把backbone从残差网络换成 Vision Transformers,主要的学习方法其实没有改变,但是换成了Vision Transformers之后面临的问题都是说是训练不稳定或者是不好训练,所以各自提出了方法。两种方法都可以有效的提高模型训练的稳健性,防止模型坍塌,让 Vision Transformers用自监督的方法也可以训练得很好。
    • MoCov3:提出把patch projection layer给冻结
    • DINO: 把teacher网络的输出先做一下归一化,也就是centering操作

参考资料:

1)视频讲解:https://www.bilibili.com/video/BV19S4y1M7hm/?spm_id_from=333.788
2)视频笔记:https://zhuanlan.zhihu.com/p/452087382

Unsupervised Learning | 对比学习——13篇论文综述相关推荐

  1. 【CV】对比学习经典之作 SimLR 论文笔记

    论文名称:A Simple Framework for Contrastive Learning of Visual Representations 论文下载:https://arxiv.org/ab ...

  2. 重磅!悉尼科大ReLER实验室13篇论文入选CVPR 2021

    点击下方卡片,关注"CVer"公众号 AI/CV重磅干货,第一时间送达 本文作者:Pablo   |  来源:知乎(已授权) https://zhuanlan.zhihu.com/ ...

  3. NIPS 2022 | 一文了解腾讯AI Lab入选的13篇论文

    每天给你送来NLP技术干货! 来源:腾讯AI实验室 点击这里进群->加入NLP交流群 近日,NeurIPS 2022 正以线上与线下结合形式举行,为期两周.作为当前全球最负盛名的 AI 学术会议 ...

  4. 腾讯优图13篇论文入选ICCV2019,涉及2D图像多视图生成等研究

    允中 发自 凹非寺  量子位 报道 | 公众号 QbitAI 两年一度AI顶会ICCV已经召开,今年在韩国首尔举办. 随着论文收录名单揭晓,大会也进入放榜收获时刻. 腾讯旗下顶级视觉研发平台腾讯优图, ...

  5. ICCV2019 | 腾讯优图13篇论文入选,其中3篇被选为Oral

    点击我爱计算机视觉标星,更快获取CVML新技术 两年一度的国际计算机视觉大会 (International Conference on Computer Vision,ICCV) 将于 2019 年 ...

  6. 对比学习顶会论文系列-3-2

    文章目录 一.特定任务中的对比学习 1.2 摘要生成中的对比学习--SimCLS: A Simple Framework for Contrastive Learning of Abstractive ...

  7. 1470篇!CVPR2020结果出炉(附13篇论文链接/开源代码/解读)

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转载自:极市平台 编辑:Amusi(CVer) 今天,计算机视觉 ...

  8. 深度神经进化大有可为?Uber详解如何用它优化强化学习 | 5篇论文

    作者 Kenneth O. Stanley & Jeff Clune 夏乙 编译自 Uber Engineering Blog 量子位 出品 | 公众号 QbitAI 在深度学习领域,目前训练 ...

  9. 深度学习第一篇论文——半监督学习Mean Teacher 的学习

    最近一个月刚接触深度学习,导师给了一篇论文(mean teacher)让我先理解然后跑论文里面的代码,这个过程中我出现了很多问题,借这篇blog记录下来,也是鼓励自己接着学下去. Mean Teach ...

  10. NLP的“第四范式”之Prompt Learning总结:44篇论文逐一梳理

    作者 | 杨浩 @阿里达摩院 研究方向 | 自然语言处理 整理 | Paperweekly 背景 随着 GPT-3 诞生,最大的版本多达 1750 亿参数,是 BERT-BASE 的一千多倍.事实上 ...

最新文章

  1. java中需要用equals来判断两个字符串值是否相等
  2. 好好学python·函数
  3. maven 中 部署构件至Nexus(mvn deploy)
  4. go语言如何连接数据库
  5. Quartz CronTrigger时间最完整配置说明
  6. 如何在Windows上运行Redis?
  7. 怎么隐藏li标签_抖音账号如何打标签-7天让抖音账号打上标签
  8. 鸿蒙有什么好处,鸿蒙系统有什么好处-鸿蒙系统有什么用-鸿蒙系统有什么区别...
  9. 阿里云罗庆超:我为什么写《对象存储实战指南》这本书
  10. c语言setw函数怎么用,C++中setw()的用法?
  11. 题:斐波那契数列(Fibonacci数列)——一个数最少几步变成斐波那契数列的数
  12. 计算机连接拒绝无法连接失败,打印机拒绝访问,教您打印机拒绝访问无法连接怎么解决...
  13. SharePoint可上传编辑但不能删除的权限设置
  14. Linux配置sendmail实现PHP发送邮件
  15. 惠普1005w打印机使用说明书_首款能充粉的打印机来了 惠普1005w一体机评测
  16. python 使用mechanize进行web网页交互
  17. 托福阅读基础训练方法
  18. 小米 admob广告 ID_定了!小米5G新品发布会定在9月24日,4大新品值得期待
  19. 【设计模式】设计模式总结 ( 七大设计原则 | 创建型模式 | 结构型模式 | 行为型模式 ) ★★★
  20. 防止小孩长时间沉迷电脑游戏-卓越电脑定时关机软件

热门文章

  1. python3抓取图片脚本_使用Python3编写抓取网页和只抓网页图片的脚本
  2. jsp测试mysql_求一段jsp连接mysql的测试程序
  3. Excel解析的几种实现方式
  4. php 126怎么设置发送邮箱验证码,邮箱发送验证码(示例代码)
  5. 关于Python学习的一点说明
  6. 饮冰三年-人工智能-Python-11之HelloWorld
  7. rgb活体rgb对比rgb
  8. 【转载】Vue 2.x 实战之后台管理系统开发(二)
  9. 第一章: 当前主流的小型嵌入式 GUI
  10. python学习笔记--python简介