哪有什么岁月静好,不过是有人替你负重前行!

对比学习论文综述总结

  看了朱毅老师在B站讲的对比学习论文综述,这里稍微总结一下。视频笔记

第一阶段:百花齐放

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

  引入个体判别代理任务,正样本就是这个图片本身(可能经过一些数据增强),是batch中的图片,负样本就是数据集里所有其它的图片,是从memory bank 里随机地抽取出来的,使用NCE loss,在网络得到新特征之后,将memory bank里对应batch中图片的特征更换成新的特征 ,反复这个过程,不停的更新这个 memory bank,最后学到这个特征尽可能的有区分性。不过由于要把所有图片的特征全都存到memory bank 里,也就是一个字典,也就意味着如果图片很多的话,则每个特征的维度不能太高,否则存储代价太大了 

 

Inva Spread(Unsupervised Embedding Learning via Invariant and Spreading Instance Feature)  

  它可以被理解成是 SimCLR 的前身,它没有使用额外的数据结构去存储大量的负样本,它的正负样本就是来自于同一个 minibach,而且它只用一个编码器进行端到端的学习。代理任务也是选取了个体判别这个任务,正样本是batch中图片数据增强后的图片,负样本是所有剩下的这些图片(包括原始的图片以及经过数据增强后的图片)

 

CPCRepresentation Learning with Contrastive Predictive Coding)

  预测型任务,属于生成式代理任务,正样本其实就是未来的输入通过编码器以后得到的未来时刻的特征输出,这相当于做的预测是 query,而真正未来时刻的输出是由输入决定的,也就是说它们相对于预测来说是正样本;负样本的定义其实很广泛,比如可以任意选取输入通过这个编码器得到输出,它都应该跟预测是不相似的,这就是cpc定义正负样本的方式

 

CMCContrastive Multiview Coding)

  预测型代理任务,一张图片的多个视角互为正样本,这里包括四个视角:原始图像、图像对应的深度信息(每个物体离观察者到底有多远)、SwAV ace normal、这个物体的分割图像。其他不配对的视角作为负样本

 

第二阶段:CV双雄

MoCov1(Momentum Contrast for Unsupervised Visual Representation Learning)

  MoCo类似InstDisc的改进版本,用队列去解决大字典的问题,用动量编码器解决字典特征不一致的问题

 

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

  与Inva Spread十分类似,如果有一个mini-batch的图片,假如说是x,对这个mini-batch里的所有图片做不同的数据增强就会得到xi和xj,同一个图片延伸得到的两个图片就是正样本,也就是说如果batch size是n的话,正样本个数就是n,负样本的个数就是这个 batch size 剩下所有的样本以及它们数据增强过后的样本,也就和invariant spread里讲的一样,是两倍的 n 减1,然后当有了正负样本之后通过编码器f对它进行编码,两个f共享权重,也就说其实只有一个编码器,如果把它想象成一个 res50的话,得到的h(特征表示)是2048维了

  SimCLR的重大创新点其实是在特征之后又加了一个projector,它就是一个mlp层(只有一个全连接层,后面跟一个 relu 的激活函数)。

  本文其实整体的这个思路和结构跟SimCLR是基本一致的,SimCLR跟Inva Spread的区别其实都写在SimCLR的贡献列表里了

  首先第一个就是它用了更多的数据增强,它发现对比学习真的是需要很强的数据增强的技术
  第二就是它加了一个g函数(一个可以学习的分线性的变换,就是一个 mlp层)
  第三就是它们用了更大的batch size ,而且训练的时间更久,它发现这两个策略都能让网络学到的特征变得更好 

 

MoCov2(Improved Baselines With Momentum Contrastive Learning)

  作者发现SimCLR里的技术都是即插即用型的,所以作者直接把这些技术加到MoCo里,具体改动包括四个方面:1.加了一个 mlp 层。2.加了更多的数据增强。3.训练的时候用了cosine的learning rate schedule。4.训练更长的 epoch,从200变到了800 

  

SimCLRv2(Big Self-Supervised Models are Strong Semi-Supervised Learners)

   这篇论文主要内容是介绍如何用非常大的自监督训练出来的模型去做半监督学习,如何将SimCLR从V1变到V2是占了很少的篇幅,主要改动包括三个部分:1.换了一个更大的模型,换了一个152层的残差网络,同时用了这个selective kernels,也就是SK net。2.将MLP层从一层fc变成两层fc,原来是 fc + relu,现在是 fc + relu fc + relu。3.引入了动量编码器。

 

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

   给定同样一张图片,如果生成不同的视角,不同的 views 的话,希望可以用一个视角得到的特征去预测另外一个视角得到的特征,具体的做法就是把对比学习和聚类的方法合在了一起,在通过编码器得到z1,z2之后,并不是直接在这个特征上去做对比学习的loss,而是说先通过clustering让特征z和prototype c生成一个目标,也就是q1,q 2。

  q1,q2就相当于ground truth,那它真正要做的这个代理任务是什么呢?它的意思是说如果x1、x2是正样本的话,那z1 和 z 2的特征就应该很相似,也就跟之前对比学习一样,z1和z2要尽可能的相似。

  那如果两个特征非常相似,或者说含有等量的信息的时候,按道理来说应该是可以互相去做预测的,也就是说,如果拿z1这个特征去跟c去做点乘,按道理来说也是可以去预测q2;反之亦然,z2和这个c去做点乘也可以预测q1,所以说点乘之后的结果就是预测,而ground truth就是之前按照clustering分类而得到的q1和q2。

  所以通过这种Swapped prediction,也就是换位预测的方法,SwAV可以对模型进行训练。使用聚类中心的好处在于如果要跟很多的负样本去做类比,可能就需要成千上万的负样本,而且即使如此也只是一个近似,而如果只是跟聚类中心做对比,则可以用几百或者最多3,000个聚类中心,就足以表示了,此外这些聚类中心是有明确的语意含义的,如果之前只是随机抽样抽取负样本去做对比的话,那些负样本有的可能还是正样的,而且有的时候抽出来的负样本类别也不均衡,所以不如使用聚类中心有效。

  除此之外,论文中另一个性能提升点在于使用了一个trick,也就是multi crop。其实在没加multi crop时,SWaV的性能和MoCo v2是差不多的,也就是说一个纯聚类的方法,或者说聚类和对比学习结合的方法其实也并没有什么优势,真正提点的是multi crop的技术,所以说接下来的很多工作,也都借鉴是multi crop的这个技术,而不是 SwAV 这篇工作本身。

 

CPCV2

  用了更大的模型,用了更大的图像块、做了更多方向上的预测任务,把batch norm 换成了 layer norm,使用了更多的数据增强。

 

informing(What Makes for Good Views for Contrastive Learning)

  cmc 的作者做的一个分析型的延伸性工作,它主要是提出了一个InfoMin的原则,就是最小化互信息minimi mutual information,其实这里也不是严格意义上的最小,作者其实想说的是,他想要不多不少的互信息,如果最大化互信息以后比所需要的互信息要多,也是一种浪费,而且有可能泛化做的不好,但如果互信息比所需求的这个互信息要少,有可能达不到最优的性能,所以这个才是作者的本意,就是不能一味的最大化这个互信息,而是要不多不少刚刚好

 

总结

  其实到了第二阶段很多细节都处于统一了,比如说

  • 目标函数都是用infoNCE或者infoNCE类似的目标函数去算的
  • 模型最后也都归一到用一个编码器后面加一个projection head
  • 都采用了更强的数据增强
  • 都想用这个动量编码器
  • 都尝试着训练的更久
  • 最后在ImageNet上的准确度也逐渐逼近于有监督的基线模型

 

第三阶段:不用负样本

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

  对比学习中负样本就相当于一个约束,因为如果只有正样本,正样本之间要求相似,这时模型会有一个捷径解,就是所有的样本的输出结果相同,这样loss就永远是0,这种模型什么都没学到,显然不行,很多论文中也把这叫做model collapse或者learning collapse,模型坍塌或者学习坍塌。所以需要加上负样本这个约束,使得不相似的物体之间有不相似的特征,这样模型才有动力进行学习。但是BYOL中没有使用负样本,模型前半部分与之前类似,将x经过两次数据增强得到v和v',v通过fθ编码器得到特征yθ,v'通过fξ编码器得到特征y'ξ,这两个编码器使用同样的网络架构,但是参数是不同的,fθ是随着梯度更新而更新的,fξ是通过moving average的方式进行更新,其实就是使用了动量编码器,接下来与SimCLR类似使用了一个投影层,文中叫projector,也就是yθ通过gθ得到zθ,y'ξ通过gξ得到z'ξ,两个投层的区别于前面一样。

  接下来就是主要创新的地方,之前的工作中是要使得zθ与zξ尽可能的接近,但是BYOL中在gθ投影层后面又加了一层predictor,也就是qθ,与投影层网络结构一致,也就是一个MLP,得到一个新的特征,也就是预测,然后期望这个预测与z'ξ尽可能一致,也就是把原来一个匹配的问题换成了一个预测的问题,这与SwAV有点像,但是SwAV是借助了聚类中心去做预测任务,而BYOL什么都没有,相当于是用自己一个视角的特征去预测另外一个视角的特征。目标函数用的是MSE loss。

  但是为什么模型没有坍塌呢?作者也提供了一些解释,但是比较中规中矩。

  

针对BYOL的博客和他们的回应

  博客作者在复现BYOL时遗漏了一个小细节,结果就出现了模型坍塌的现象,这个细节跟batch norm有关,BYOL的projector是Linear+BN+ReLU+Linear,而博客作者在复现时参照的是MoCoV2,其中是没有用BN的,所以博客作者也没有用BN,就导致了坍塌,后来作者经过实验发现,只要在投影层或者预测层中放一个BN,结果就还行,作者在尝试将BN换成Layer Norm之后依旧出现了坍塌,所以作者任务BYOL没有坍塌肯定与BN有关。作者分析认为,BN在计算的时候是用一个batch中所有样本计算均值方差,然后再用均值方差进行归一化,所以在算某个样本的loss的时候其实也看到了其他样本的特征,也就是说其中是存在信息泄露的,所以作者认为可以把一个batch中的其他样本视作隐式的负样本,作者认为经过归一化的每张图片可以看成平均图片,与SwAV中的聚类中心类似,作者称之为mode,就是中值的意思。

  如果博客作者的观点正确,则BYOL的创新性会降低很多,因为没有脱离对比的范畴,BYOL的作者很快就写了一篇新的论文(BYOL works even without batch statisties)作为回应,作者进行了很多消融实验,发现大部分情况下博客中的内容都是正确的,但是作者发现了几个特例,即使Projector有BN,但是BYOL还是训练失败了,还有当编码器和Projector都没有BN时,SimCLR也失败了,所以论文作者和博客作者达成一致,也就是BN能帮助模型稳定训练,能提高模型的训练稳健性,从而不会出现坍塌,但是论文作者认为如果一开始就能让模型初始化的比较好,那么后面的训练没有BN也可以,后续作者进行了进一步的实验,发现在使用Group Norm和Weight standardization进行初始化时也能有很高的准确率

  

SimSiam

  对比学习虽然有了很多进展,但是好像是被一个个的创新点堆起来的,这不利于分析,所以作者试图将整个过程化繁为简,提出了SimSiam,结构十分简单,与BYOL类似,不需要负样本,且不需要大的batch size和动量编码器,两边共享参数,整体架构与BYOL十分相似,x分为x1,x2经过两个编码器,x1分支经过一个predictor,得到的结果去预测特征,与BYOL唯一的区别在于没有使用动量编码器,用MSE loss。

  最后作者得到的一个结论就是之所以SimSiam没有模型坍塌,就是因为有stop gradient这个操作存在。作者还提出一个假设,因为有stop gradient这个操作存在,SimSiam的结构可以想象成一个EM算法,因为有stop gradient这个操作之后,一个训练过程,或者一套模型参数就被认为分成了两份,就相当于在同时解决两个子问题,模型的更新也是在交替进行,作者经过一系列推导,认为到最后可以理解为一个K-means聚类问题,K-means其实也是分两步,先把所有的点分配给一些聚类中心,然后更新聚类中心,然后周而复始

 

第四阶段:基于Transformer

MoCov3

  这篇论文的大部分篇幅都在介绍自监督训练的ViT有多不稳定和发现的问题,以及如何通过改进使得训练更稳定且效果更好,如何将MoCo从V2变到V3只有1页,从架构上看,MoCoV3其实就是MoCoV2和SimSiam的合体,仍然有两个网络,一个是query编码器,一个是key编码器,key编码器是动量编码器,loss采用的是对比学习的loss,从这个角度看是MoCoV2,但是query编码器除了backbone之外,还有projection head和prediction head,这其实是BYOL或者SimSiam,而且目标函数也用的是对称项,就是既计算query1到key2的,也算query2到key1的,从这个角度看是SimSiam,由于ViT的出现,所以作者想把卷积网络给换掉,也就是把backbone从残差网络换成了ViT,作者发现当batch size较大时,训练时准确率会波动,作者通过观察回传的梯度发现,每次loss有大幅震动时,梯度也会有一个波峰,而这个波峰出现在第一层,就是在做patcn projection的时候,也就是ViT中将图片转为patch的那一层,其实就是一个可以训练的全连接层,作者认为既然这一层训练有问题,不如不进行训练,直接冻住,结果发现问题解决了,这个trick能获得更平滑的训练曲线。

 

DINO

  这篇文章的主要卖点是ViT在自监督训练的情况下会有一些非常有趣的特性,作者发现如果把自注意力图拿出来做可视化,能发现它能非常准确地抓住每个物体的轮廓,甚至能媲美直接做分割,在对比学习方面,其实就是延续了BYOL,x分为x1,x2经过两个编码器得到两个特征,编码器有projection head和prediction head,为了避免模型坍塌,提高训练稳定性,作者对teacher网络做了一个centering的操作, 就是把整个batch的样本都算一个均值,然后减掉这个均值,然后一边stop gradient,用另一边进行预测。

 

posted @ 2022-08-04 16:27  Lhiker  阅读(1132)  评论(0编辑  收藏  举报