【研一小白论文精读】《MoCo》

其实之前读simclr那篇论文的时候已经涉及到一些moco的内容,现在的moco已经更新到了v3。
moco是一种典型的contrastive unsupervised learning。

Momentum Contrast for Unsupervised Visual Representation Learning

在moco提出的时候现有的contrastive learning有两种手段:
【研一小白论文精读】《MoCo》_第1张图片
第一种是end to end,就是一个sample经过不同的图像增强作为querry和key,放到两个encoder里面,然后算相似程度,同一个样本产生的querry和key相似程度是高的,不同样本产生的相似程度是低的,这种方法对两边的encoder都做传递,这一点和attention很像,互搏。
第二种呢则是memory bank,memory bank就是锁住一边的key,其实就相当于把所有的key存在一个bank里,那么每次一个新图像进来过encoder得到一个querry的时候,从bank中sample出一些representation和这个querry来做比较,那么显然这一部分是不需要传递梯度的。
那么最后就是moco
【研一小白论文精读】《MoCo》_第2张图片
moco的原理其实非常简单,就是一个batch的图像仍然经过不同的图像增强策略,左边这支叫querry,右边这支叫key,querry过一个encoder,key也过一个encoder,不过这个encoder是momentum ecdoer。然后呢我们就得到了他们的represention,但是key的represention不仅有这个batch的represention,还有之前batch保存下来的represention,所以我们看到这里其实是维护了一个队列。这样做的好处就是比起之前的simclr一个batch内相互做contrastive learning,现在一个batch通过很少的代价获得了更多的negative samples,那么还是两个represention之间计算相似度来得到这个contrastive loss。
【研一小白论文精读】《MoCo》_第3张图片
而这个contrastive loss如上图就是我们很熟悉的NCE,分子部分就是querry和对应的key的相似程度,分母就是querry和其他所有的key他们对应的相似程度的和,这里的“套”就是temperature,用来控制loss的分布,这就是contrastive loss的部分。
【研一小白论文精读】《MoCo》_第4张图片
momentum ecdoer部分就是我在更新了querry的encoder之后呢,并不是直接复制到key的encoder里面,而是我已一定的比例更新这个key。

Methodology

接下来结合作者提供的伪代码来看一下:
【研一小白论文精读】《MoCo》_第5张图片

【研一小白论文精读】《MoCo》_第6张图片
代码一开始momentum encoder和encoder的参数是相等的已经初始化好了,然后对于一个sample来说,做不同的两种图像增强策略,得到querry的sample和key的sample,分别送到两个encoder里面。因为key是不需要计算梯度的,所以detach一下。先把q的vetor和k的vetocr做一个变形,然后两个做内积,就产生positive loss了。那么negaive loss就是所有的q和之前维护的队列中的key一起做个矩阵乘法。然后把得到的positive loss和negaive loss做串起来,传入这个形如softmax加CrossEntropy的loss中计算。这里非常巧妙的一点就是这里的logits有n行k+1列,第一列是positive sample,其余的key列都是样本和negaive的相关程度。告诉CrossEntropy index为0的这一列是positive sample。然后再做传递,更新一下encoder network的参数,然后再用momentum更新一下momentum encoder,到此网络就结束了。最后维护一下key的队列,然后把最早的一个bacth的样本弹出来。
以上就是moco的实现方法。

Resuluts:Linear Classification

【研一小白论文精读】《MoCo》_第7张图片
实验结果也是对比了之前end to end还有memory bank,随着negative sample的增加,模型的效果肯定也越来越好。
【研一小白论文精读】《MoCo》_第8张图片

作者也测试了不同的momentum,应该以怎样的速率更新这个momentum encoder呢,可以看到这些结果。【研一小白论文精读】《MoCo》_第9张图片
这里其实是一个非常有意思的实验,shufflinfg batch normalization,作者说其实包括之前的论文也有汇报,我们的batch normalization其实会阻碍unsupervised learning的,阻碍我们的模型学到好的representation,那么可能的原因就是network在做batch normalization时应用到了一个batch中所有样本的信息,那么在这个normalization的过程中,不同不同样本之间的信息可能就泄露给对方了,这样呢就会使contrastive loss更容易达成,为了克服这个困难作者就使用了shufflinfg batch normalization,具体来说就是作者在多块GPU上训练了这个模型,他就是在每一个GPU上做 batch normalization,同时因为有两支,一支是key,一支是query,query又是打乱顺序之后送到GPU里的,也就说到最后对应的query和key不是从同一个batch normalization里出来的,这个技巧就称之为shufflinfg batch normalization。并且可以看到使用linear layer,也就是虚线,可以看到区别不是很明显,linear layer毕竟还是很强的模型,但是如果用KNN作为分类器,有没有shufflinfg batch normalization还是有影响的。
再接下来就是吊打前任工作的环节:
【研一小白论文精读】《MoCo》_第10张图片
从模型复杂度和性能表现来看还是不错的,对比当时之前的方法也是最好的。

Results:Transferring

【研一小白论文精读】《MoCo》_第11张图片
除了分类还有Transferring,作者在PASCAL VOC上做目标检测和在COCO数据集上做目标检测语义分割等,从不同的模型培训出来的moco,再对比之前的方法,就是好啊。
【研一小白论文精读】《MoCo》_第12张图片

Improved Baselines with Momentum Contrastive Learning

随着simclr的提出,作者对moco又做了小部分的改进,也就是MoCo v2。
这其中包含三条改进:
1.An MLP head
原来的query encoder和momentum encoder加上一层什么什么layer?把后面的head变成MLP
2.Extra blur augmentation
图像增强方面额外增加了模糊这种增强
3.Cosine learning rate schedule
把学习率改成一个余弦函数
【研一小白论文精读】《MoCo》_第13张图片
以mocov1作为一个baseline,加上这些东西性能表现就是好。
【研一小白论文精读】《MoCo》_第14张图片
并对比同样使用这些trick策略的simclr,mocoV2的优势就是batch_size小,因为在本文中维护了一个队列,并且在队列中只存放了key representation,那显然这样又节省了内存,而且还可增加很多negative samples,这是一个非常好的方法。
【研一小白论文精读】《MoCo》_第15张图片
最后还有对比之前的end to end,本文使用的内存也好,训练的时间也好还是有很大的优势的。

An Empirical Study of Training Self-Supervised Vision Transformers

之前不管是moco v1还是moco v2之前都是用resnet作为backbone的,这篇论文主要就是把resnet换成vision transformers。最大的改动了就是取消了原来的队列,之前这个队列存储了计算的所有key,帮助我们在不扩大batch_size的情况下提供更多的negative samples,而作者现在说已经没有必要了,现在已经可以训练很大的batch_size了,无语了哈哈。第二点改动就是原来的不管是query encoder还是momentum encoder使用的都是backbone加pred mlp这种结构,那么在这篇论文中呢,作者把BYOL的东西搬进来了就是加了两层proj mlp。
【研一小白论文精读】《MoCo》_第16张图片
那么在应用以上两项的改进下,用ResNet-50作为backbone的情况下,对比相对于之前版本的moco,性能是有提升的。做好这些准备之后就要开始真正面对transformer encoder了。

Stability

虽然我们再训练transformer的时候能够得到一个训练不错的模型,但是在这个不错的模型基础上隐藏了很多不稳定的因素,影响了训练的过程,作者为了揭示这个不稳定性,使用了这个kNN curves。kNN就是在训练完一个epoch之后,或者是几个循环迭代之后呢加入几个有标记的样本,然后用kNN测试这个representation他的表现。
1.bacth_size
在bacth_size相对较少的情况比如2048,曲线相对比较平稳,随着batch_size增大,虽然能够享受到大的bacth_size所带来的contrastive loss,但是模型变得更加不稳定了,经常会出现断崖式的下降。
【研一小白论文精读】《MoCo》_第17张图片
2.learning rate
同样呢,learning rate也是,我们再选择相对较低的learning rate还是很平稳的,但是随着learning rate的提升,不稳定性也随之凸显出来。
【研一小白论文精读】《MoCo》_第18张图片
3.optimizer
【研一小白论文精读】《MoCo》_第19张图片
我们看到不管是哪种curve,都会在准确率上大幅下降,然后再缓缓地提升回来。为什么我们训练transformer模型会有这样的问题呢?以及这样的问题我们是否有办法先去克服它呢?

A Trick for Improving Stability

Why?

【研一小白论文精读】《MoCo》_第20张图片

通过观察发现呢,在我们的性能出现下降的时候,因为我们突然产生一个非常大的Gradinet,然后这个Gradinet先从第一层出现,在后面几个Iteration之后到了最后一层。也就是说这个大的Gradinet的尖刺是从浅的一层传到深的一层。那么更进一步的研究表明这个尖刺来自于从image patch到patch embedding的时候,我们训练MLP所产生大的梯度尖刺。

How wo fix?

那么怎么样规避这个问题呢?直接在这个patch projection也就是patch embedding之后把这个梯度停掉,前面的MLP就保持随机的初始化状态。于是使用随机初始化的MLP作为patch embedding,甚至比训练这个MLP效果还要好,训练过程中也更加的稳定。
【研一小白论文精读】《MoCo》_第21张图片
而且同样的特性,不仅在moco观察到,如果在SimCLR,BYOL,或者是SwAV这些模型中都是用vision transformer这个model,这些算法也都会出现性能的突然的下降这个问题,但是只要把前面的Gradient停掉,使用随机初始化MLP直接作为modle embedding,训练就会变得稳定。
这真是一个很有意思的发现,作者还尝试了BatchNorm,WeightNorm但是这些都不能改变上面遇到的这些问题。作者还试了Grandient clip,相当于把Grandient限制到一定程度,作者发现把这个Grandient 限制的足够小,也能达到平稳训练的效果,但是本质和stop Grandient 是一样的。虽然是个治标不治本的方法,从原理上解决还有待进一步的研究。如果前面用resnet-50来提取image embedding,用VGG这样的网络或者用卷积神经网络提取embedding,如果将这种embedding作为transformer的input作为token效果会怎么样呢?

Result

【研一小白论文精读】《MoCo》_第22张图片
这里是几种transformer的配置,他们的计算量相对于resnet-50的对比,还有TPU,训练的时间,这都是钱啊。

【研一小白论文精读】《MoCo》_第23张图片
这里是对比的不同的backbone model,和不同的learning frameworks的对比,可以看到再借鉴了BYOL里面的projection之后呢,moco的方法在之前的几个backbone都取得了最好的效果。
下面的图,横轴使用resnet-50,纵轴使用ViT,做出来的准确率,可以看出SimClR和moco都比较偏向于vision transformer作为backbone,但是SwAV和BYOL对什么作为backbone没有有太大区别。

Ablations

再此基础上作者又汇报了一些玻璃实验:
【研一小白论文精读】《MoCo》_第24张图片
position embedding还是使用现成的sin-cos最好,不加position embedding当然是不可以的。
【研一小白论文精读】《MoCo》_第25张图片
class token也就是CLS,如果没有class token行不行呢?显然是不行的,性能是大幅度下降的。即便把所有的token集合起来,性能的表现也是不如单独说一个class tolen来的好。

【研一小白论文精读】《MoCo》_第26张图片
还有MLP head里面的BatchNormalization。
【研一小白论文精读】《MoCo》_第27张图片
prediction head的影响就是从BYOL上借鉴过来的,性能还是有些提升的。
【研一小白论文精读】《MoCo》_第28张图片
模型更新的多快
【研一小白论文精读】《MoCo》_第29张图片
训练的时长,等等。

More results

最后使用了transformer,不免和resnet在参数量准确率上比较,参考下图:
【研一小白论文精读】《MoCo》_第30张图片

Transfer learning

最后作者也是测试了迁移学习,就是现在image net上pretraining,在拿到别的数据集上fine-turn,可以看到大部分情况下使用self-supervised上做pretraining,然后再另一个数据集上做fine-turn,大部分情况下是有改善的,除了再宠物数据集上性能有所降低。
在这里插入图片描述

你可能感兴趣的:(论文,计算机视觉,深度学习,神经网络)