重庆档案馆建设网站,青岛网站建设效果,台山网站设计,宗亲网站开发bryanyzhu的个人空间-bryanyzhu个人主页-哔哩哔哩视频
评价 今天我们一起来读一下 MOCO 这篇论文。 MOCO 是 CVPR 2020 的最佳论文提名#xff0c;算是视觉领域里使用对比学习的一个里程碑式的工作。而对比学习作为从 19 年开始一直到现在视觉领域乃至整个机器学习领域里最炙…bryanyzhu的个人空间-bryanyzhu个人主页-哔哩哔哩视频
评价 今天我们一起来读一下 MOCO 这篇论文。 MOCO 是 CVPR 2020 的最佳论文提名算是视觉领域里使用对比学习的一个里程碑式的工作。而对比学习作为从 19 年开始一直到现在视觉领域乃至整个机器学习领域里最炙手可热的方向之一。它简单、好用、强大以一己之力盘活了从 2017 年开始就卷得非常厉害的计算机视觉领域涌现了一大批优秀的工作而 MOCO 就是其中之一。 MOCO 作为一个无监督的表征学习的工作它不仅在分类这个任务上逼近了有监督的基线模型而且在很多主流的视觉任务上比如说检测、分割人体关键点检测都超越了有监督预训练的模型也就是 Imagenet 上预训练的模型有的数据集上甚至是大幅度超越。所以说 MOCO 的出现从某种意义上来说是给视觉领域吃了一个定心丸就是无监督学习真的可以我们有可能真的不需要大规模的标好的数据去做预训练。 这个结论其实从侧面上也证明了之前颜乐坤在 Europes 2016 做演讲时候用的一张图。这张图其实后来在 Twitter 上都已经被大家玩坏了已经变成了一张梗图。它的意思就是说如果你把机器学习比作一个蛋糕的话那强化学习只能算是这个蛋糕上的一个小樱桃有监督学习最多就算这个蛋糕上的这层糖霜只有无监督学习才是这块蛋糕的本质才是我们真正想要的。 而现在也确实如此不光是在自然语言处理那边很多我们耳熟能详的大模型都是用自监督的方式去预训练得到那在视觉这边也基本上快了。所以说多听大佬的 talk 也是有好处的说不定就是找到下一个研究方向了。 那在接着往下读之前我想先介绍一下什么是对比学习以及前人的一些工作这样好做个铺垫。因为我发现 MOCO 这篇论文的写作是假设你对比学习已经有一定的了解了如果我们对之前的工作不是很了解的话就不能理解这里为什么要做 momentum contrast动量对比学习也无法体会到 MOCO 的这个精妙之处。
1什么是对比学习 那到底什么是对比学习假如说我们有两张图一图二还有一个图3然后图一里有一个人儿图 2 里也有一个人儿可能图一里的这个人是高兴的图 2 这个人是不高兴的然后图 3 里我们有一只狗我这个画画水平有点儿糙大家忍一下。那我们希望模型在看到这三张图片以后它能分辨出前面这两张图片属于一个类别后面这个明显跟前面不是一个类别所以对比学习顾名思义就是说对比着去学习。模型并不需要真的知道这两张图片代表的是人也不需要知道这张图片代表的是狗它只需要知道这两张图片类似而这张图片跟前两张图片不类似。 那如果说的再明白一点就是假如说我现在把这三张图片都通过一个网络m然后我去得到三个特征F1、F2、 F3 分别对应的就是这三张图片的特征。那现在假如说我们最后有一个学好的 embedding space就一个特征空间F1、F2、 F3 分别是这个特征空间里的三个点那我们希望对比学习能做到什么呢就是能把这两个类似图片的这个特征尽量的拉近而让不相似图片的特征尽量跟这两个远离。
1.1还是需要知道哪两张图片相似哪两张图片不相似你才能去做这个模型的训练。那为什么对比学习在视觉领域一般被认为是无监督的训练方式 那如果我们真的能做到所有类似的物体都在这个特征空间里相邻的区域而不类似的物体都在不相邻的区域的话那其实我们目的也就达到了我们学到的这个特征就会是一个很好的特征那可能这里就会有人问了对比学习虽然不需要知道标签的信息比如说它不需要知道图一、图二是人或者说图 3 是狗它不需要知道这个标签信息但它不还是需要知道这两张图片是类似的这张图片跟前两张不类似吗也就意味着你不还是需要标签信息去做这种有监督学习吗你还是需要知道哪两张图片相似哪两张图片不相似你才能去做这个模型的训练。那为什么对比学习在视觉领域一般被认为是无监督的训练方式 因为在视觉领域大家通过去设计一些巧妙的代理任务就是 pretext task从而人为地定立一些规则这些规则可以用来定义哪些图片是相似的哪些图片是不相似的从而可以提供一个监督信号去训练模型这也就是所谓的自监督训练。
1.2举例一个最广为应用的代理任务instance discrimination 那我们现在就先举个例子讲一个最广为应用的代理任务叫 instance discrimination。这个代理任务就是说如果我们有一个没有标注的数据集里面如果有 n 张照片比如说X1X2一直到 x n那我们该如何去定义哪些图片是相似的哪些图片是不相似的 Instant discrimination 是这么做的如果我们从这个数据集里随机选一张图片比如说XI现在我在这张图片上做随机裁剪从而得到另外两张图一张我们叫 X I 1一张我们叫做 X I 二、当然在这个裁剪之后我们还做了很多数据增广我们把这个裁剪和数据增广都叫做transformation。所以这块比如说我们用 T1 来代表这块用 T2 来代表那我们现在就得到两张看起来应该很不一样的照片但因为它们都是从同一张照片 XI 经过某些变化而得到的它们的语义信息不应该发生变化然后这两张照片就被称作是正样本。至于哪些图片是跟 XI 这张图片不相似的 Instant discrimination这个代理任务就认为这个数据集里剩下所有的图片都可以被当作是不相似也就是说 XJJ 不等于i那这些样本相对于 XI 来说就都是负样本。所以说到这儿你可能也明白为什么这个代理任务叫做 Instant discrimination而直译过来就是叫个体判别。 因为在这个代理任务看来每张图片都是自成一类剩下所有的图片都跟它不是一个类的。那拿 image net 的数据集来举例的话我们现在就不是有 1000 个类了我们想而是有 100 多万个类因为每个图片都是它自己的类。那一旦我们有了这个代理任务有了这么一种去定义什么是正样本什么是负样本的规则那接下来就好办了。 接下来就是我们通过一个模型再去得到一些特征然后在这些特征上使用一些常见的对比学习的目标函数就可以了。比如说 NCE loss 这个目标函数的细节我们之后会来正文的时候讲到。
1.3为什么对比学习简单好用强大 那基本这样一个框架就是对比学习里常见的一种实现方式了看起来好像平平无奇的样子但对比学习最厉害的地方就在于它的灵活性。就像我们这里看到的一样你只要能找着一种方式去定义什么是正样本什么是负样本这就够了。剩下这些操作都是比较标准的那这样就很有意思因为你可以大开脑洞去制定很多如何定义正样本和负样本的规则。比如说在视频领域很多人就认为同一个视频里的任意两帧都可以认为是正样本而其他视频里的所有帧都可以是负样本。那在 NLP 领域你也可以这么用比如说 SimCSE 那篇论文就是把同样的句子扔给模型但是做两次forward每次 forward 使用不同的这个 drop out这样得到的两个特征它认为是正样本然后其他所有句子的特征就是负样本。 在 CMC 这篇论文作者是说一个物体的不同 wheel 就是不同视角也可以是作为正样本的比如说一个物体的正面和背面一个物体的 RGB 图像和一个物体的深度图像这些通通都可以作为不同形式的正样本。所以你可以看到对比学习实在是太灵活真的是比天比地比空气什么都能比只要你脑洞够大哪个领域都能用所以自然而然后来也扩展到了多模态领域也就造就了 OpenAI 的 CLIP 模型。
2题目 那简单的介绍完对比学习和 Instant discrimination 这个代理任务之后我们现在就来精读一下 MOCO 这篇论文题目说用 MOMENTUM contrast动量对比学习的方法去做无监督的表征。学习 MOCO 这个方法的名字其实也就来源于前两个单词的头两个字母那对比学习我们之前已经简单介绍过了。
2.1什么是动量 那什么是动量动量可以从数学上理解成为是一种加权移动平均就是 y t 等于 m 乘以 y t 减一加上一减 m 乘以 x t这里的 m 就是动量这个超参数。 YT 减一是上一个时刻的输出 YT 是你这一时刻你要想改变的输出 XT 是当前时刻的输入说白了它的意思就是说我不想让我当前时刻的输出完全依赖于当前时刻的输入。所以说我让之前的这个输出也来凑凑热闹也给它一个权重因为这里动量这个超参 m 是介于 0 和一之间的一个数如果 m 很大就是趋近于一的时候其实这个 YT 是改变得非常缓慢因为后面这个一减 m 就基本是趋近于0。意思就是不怎么依赖于当前的输入。那反过来说如果 m 很小的话那就是说当前的输出更多的依赖于当前的输入。 MOCO 也是利用了动量的这种特性从而去缓慢地更新一个编码器从而让中间学习的字典中的特征尽可能的保持一致。
作者团队来自fair个个都是鼎鼎有名的大佬我就不用过多介绍了。他们五个人在 Google scholar 上的引用加起来已经超过 50 万了在各个视觉会议上也是拿奖拿到手软。好我们来看摘要上来就说哇本文我们就提出来 MOCO 这个方法去做无监督的表征学习。虽然我们是基于对比学习的但是我们是从另外一个角度来看对比学习也就是说把对比学习看成是一个字典查询的任务。具体来说就是我们做了一个这个动态的字典这动态的字典由两个部分组成第一个部分就是我们有一个队列第二个部分我们有这么一个移动平均的编码器因为这个队列里的样本我们不需要做梯度回传所以我们就可以往队列里放很多副样本从而使得这个字典可以变得很大。
至于为什么用这个移动平均的编码器我们是想让字典里的特征尽量的保持一致然后我们发现在训练的过程中如果你能有一个很大的而且比较一致的这个字典会对无监督的对比学习非常有好处。而这篇论文主要的亮点在于它的结果所以说剩下大篇幅的摘要留给了结果。
首先是分类就是在 Imagenet 数据集上如果你用这个大家普遍采用的这个 Linear Protocol 去做测试的话 MOCO 是能取得跟之前最好的无监督学习方式差不多或者更好一点的结果。这里的 Linear Protocol 指什么呢就说如果我先预训练好了一个骨干网络当我现在要把它用到不同的数据集上的时候我把它的骨干网络冻住就是 backbone freeze然后只去学习最后的那个全连接层也就是那个分类头。这样就相当于我们把一个提前学好的预训练模型当做了一个特征提取器我们只从它去抽特征这样就可以间接地证明之前预训练好的那个模型的特征到底学的好不好。然后这是分类。接下来他说更重要的是 MOCO 学到的特征是能够很好地迁移到下游任务的这个才是这篇文章的精髓也是这篇文章最大的卖点。因为我们之所以想做大规模的无监督预训练就是想去学到一个很好的特征然后这个特征拥有很好的迁移性我们就可以在一些没有那么多标注数据的下游任务里获得很好的结果。
MOCO 作为一个无监督的预训练模型能够在 7 个下游任务上就分割检测而且在比如说VOC、 Coco 这些各种数据集上超越之前的这个有监督的预训练模型有时候甚至是大幅度的超越它。这里的 counterpart 的意思就是说我的模型使用的是一样的比如说都是 rise 50我们只是训练的方式不一样一个是用有监督带标签的去训练一个是用无监督不带标签的数据去训练。
最后作者总结说这个就意味着什么呢意味着无监督和有监督的表征学习中间的这个鸿沟对于很多视觉任务来说已经填上了。那这个结果确实是非常惊人因为之前虽然有一些无监督的工作能在某个数据集或者某个任务上能够比它对应的有监督预训练模型好一点但是 MOCO 是第一个能够在这么多主流视觉任务上全面的让无监督训练的模型比有监督训练模型表现要好。那接下来我们一起看引言。
他说 GPT 和 Bert 已经证明了无监督的表征学习在 NLP 领域里是非常成功的但是在视觉领域有监督的预训练还是占主导地位。虽然也有很多出色的无监督工作但是他们往往要比这些有监督的模型效果上要差很多。那这是为什么呢作者认为这个原因有可能是来源于他们非常不同的这个原始的信号空间。他说对于自然语言处理的任务来说它们是离散的这个信号空间也就是说它原始的信号空间是由这些单词或者这些词根词缀去表示的从而可以很容易地建一些这个 tokenized 字典。
tokenize 的意思就是说把某一个词对应成某一个特征那一旦有了这个字典无监督学习也可以基于它还很容易地展开。因为你可以简单的把这个字典里所有的key就是所有的条目想象成是一个类别这不就又变成了一个有监督学习的范式了吗你还是有一个类似于标签一样的东西去帮助你进行学习所以在 NRP 那边无监督学习就很容易去建模而且建好的这个模型也相对比较容易优化。
但是对于视觉来说就完全不一样因为视觉的原始信号是在一个连续的而且高维的空间里它并不像单词那样有很强的语义信息而且浓缩得非常好没有那么简洁所以导致说它并不适合去建立一个这样的字典。那如果没有这个字典无监督学习就很难去建模所以导致了在视觉这边无监督学习还远不如有监督学习。接下来第二段说他说最近有一些无监督表征学习的方式是基于对比学习的而且取得了非常不错的效果。虽然这些方式的出发点都不一样或者说具体的做法不一样但是它们都可以被归纳成一种方法也就是说在构造一个动态的字典。
那这句话该怎么理解如果我们去看之前画的流程图就是说有一个数据集里面有 n 张图片现在我们随机选一张图片假如说是X1在这张图片上经过不同的变换以后我们得到了 X11 和X12那这两张图片就组成了一个正样本。对一般我们是管这个 XEEE 叫Anchor也就是锚点基准点的意思那这个 XER 我们叫它positive也就是说相对于这个基准点来说 XER 是 XEE 的一个正样本然后剩下的所有的这些图片从 X2 到 XN 这些全都是负样本这是negative。那一旦有了正负样本这些概念接下来就是把这些样本扔给编码器去得到一些特征输出。比如说图片 XEE 进到编码器 EEE 里就会得到一个特征FEE然后图片 XER 进到编码器 EER 里就会得到特征FER。这两个编码器既可以是同一个模型也可以是不同的模型。因为在 MOCO 这篇论文里选用的是不同的模型所以我就把它们分开画了。
那至于这些负样本到底该用哪个编码器负样本其实是应该用 E12 这个编码器的因为所有的这些负样本和这个正样本 f 一二都是相对于原来的这个锚点 F1 来说的所以说这些负样本也应该和这个正样本使用同样的编码器从而让它们的特征保持一致性。于是这些负样本也通过这个编码器从而得到了这些F2 F3 到 FN 的特征。
那我们之前说对比学习是干什么的对比学习就是让这个正样本对的特征在特征空间里尽可能的相近而让这些负样本的特征在特征空间里尽量地远离FEE。那为什么 Moco 的作者认为之前的这些对比学习的方法都可以被归纳成为在做一个动态的字典他说如果你把这些特征当成是一个字典也就是他这里说的这句话。他说字典里的这些条目也就是这些 key 是从数据里面抽样出来的然后用一个编码器去表示也就是说这里的 key 其实对应的是特征而不是原来的图像。
那如果我们把这个 FEE 当成是一个query那所有这些字典里的特征都当成是key那对比学习不就转化成为一个字典查询的问题了吗具体来说就是对比学习要去训练一些编码器从而去进行一个字典的查找。查找的目的是什么呢就是让一个已经编码好的query也就是 query 这个 feature F E 1 尽可能的和它匹配的那个 key 的特征相似。那匹配的 key 的特征是什么呢就是 f 一二就是这个正样本的特征然后和其他的 key 远离也就是和其他负样本的这些特征了。远离那整个学习的过程不就变成了一个对比学习的框架从而你只需要去最小化一个对比学习的目标函数就可以。
那在 MOCO 这篇论文里因为它已经把所有的这些对比学习的方法归纳成了一个动态字典的问题所以它很少使用 Anchor 或者正负样本这些词而代之的它都用的是 query 和key。所以说这里的 x 一它一般用 XQ 表示这里的 x 一二它用 XK 表示就是 x query 和 x key 同样的那特征 f 一一它用的是 q 来代表这是query。剩下的这些特征它用K0 K1 一直下去。
那读完这两段以后大家可能就明白为什么我刚开始要先讲一下对比学习是什么了因为 MOCO 的作者是一个自顶向下的方式来写这篇论文的它假设你对比学习的这些前任的工作已经了如指掌了它假设你能跟上它的节奏。那我们接着读第三段作者说从这个角度来看哪个角度就是把对比学习当成动态字典的角度他们猜想最后要有好的结果。
这个字典应该具有两个特性第一个就是说必须要大第二个就是在训练的时候要保持尽可能的一致性。那为什么这么说我们先把这个 query 和这个字典这里面全都是 key 的这个字典写在这里说因为这个字典越大就能更好的从这个连续的高维的视觉空间去做抽样。那这个很容易理解因为这字典里的 key 越多你所能表示的这个视觉信息视觉特征就越丰富。那当你拿一个 query 去跟后面的这些 key 做对比的时候你就真的有可能学到那些把物体之间区分开的特征那些更本质的特征那如果这个字典很小你的模型很有可能就学到了一个捷径就一个 shortcut solution从而导致你预训练好的模型不能很好地做泛化。
那第二个关于一致性作者说字典里的这些 key 都应该用相同或者说相似的编码器去产生得到。也就是说这个 K0K 一直到 k n 的直接 key 应该是用相同或者相似的编码器抽取得到的。这样当你去跟 query 做对比的时候才能保证这个对比尽可能力一致。
否则如果你这些特征是由不同的编码器得到的很有可能这个 query 就找到了和它使用相同或者相似编码器的那个key而不是真的和它含有相同语义信息的那个key这样其实也就是变相地引入了一个 shortcut solution这引入了一条捷径从而让模型学不好。
所以作者最后说但是现在已有的这些使用对比学习的方法都至少被上述说的两个方面中的一个所限制。其实如果这里说一下现在已有的方法是怎么受限的会更有助于我们大家理解但确实是一言难尽。所以受限于篇幅作者只能说接下来在该谈的时候我们会谈的。那介绍完了研究动机还有之前工作的局限性以及想要达到的目标那接下来很自然的就是作者要提出他们自己的方法了。他说他们提出 MOCO 是为了给无监督的对比学习构造一个又大又一致的字典具体的模型总览图看图一所以我们现在来看图1。
其实图一跟我们刚才画的对比学习的一般框架是很相像的我们也有一个 query 的图片还有一些 key 的这些图片然后这些图片通过一些编码器从而得到了最后的特征然后这个 query 的特征去跟所有的 key 的特征去做类比最后用对比学习的 loss 去训练整个模型那它跟我们之前讲的框架有哪儿不同其实也就是这个 q 和这个 momentum encoder 不同也就是 MOCO 这篇论文的贡献所在。
首先我们来看为什么要用一个队列去表示这个字典主要还是受限于显卡的内存因为我们知道如果这里的字典太大也就意味着我们要输入很多很多的图片那如果这个字典的大小是几千或者甚至上万的话显卡的内存肯定是吃不消的。所以我们需要想一个办法能让这个字典的大小当每次模型去做前向过程时的 batch size 的大小剥离开。那于是作者就想到了一个巧妙的办法就是用队列的这种数据结构来完成这项任务。
具体来说就是这个队列可以很大但是我们每次更新这个队列是一点儿进行的也就是说当我们用一个很小的 batch size 的时候现在这个 batch 抽得的特征进入队列然后把最老的也就是最早的那个 mini batch 移出队列这样一下就把训练时候用的 mini batch 的大小跟队列的大小直接分开了所以最后这个队列的大小也就是一个字典的大小可以设得非常大因为它里面大部分的元素都不是每个 iteration 都需要更新的这样只用普通的 GPU 我们也能训练一个很好的模型。
但是作者之前也说了这个字典里的这些 key 最好要保持一致性也就是说它最好是用同一个或者说相似的编码器而产生得到的。那你现在如果只有一小部分也就是当前的 batch 是从当前的编码器得到的而之前的这些 key 都是用不同时刻的编码去抽取的特征那不就不一致了吗所以作者又提出了第二个改进也就是这个 momentum encoder 动量编码器那如果我们用刚才讲过的动量的概念来写一下数学表达式就是如果现在这个编码器用 set a q 代替就 set a query然后这个 momentum encoder 用 set a key 代替 seed a key那这个 c 大 k 的更新就等于 m c 大 k 减一加上一减 m 乘以 c 大q。
也就是说虽然我这个动量编码器刚开始是由这边的编码器 c 大 q 初始化而来的但是在模型的训练过程中如果我们选择了一个很大的动量那这个动量编码器 Theta k 其实是更新的非常缓慢的它不会跟着这个 Theta q 去快速的改变从而保证了这个字典里所有的 key 都是由相似的编码器抽取得到的尽最大可能地保持了它们之间的一致性。
所以作者最后说基于这两点贡献 MOCO 这个方法可以构建一个又大又一致的字典从而去无监督地学习一个视觉表征。那讲完了 MOCO 是什么接下来就该说选用什么代理任务去充当这个自监督信号从而进行模型的训练了。因为 MOCO 只是建立中间模型的一个方式它只是为对比学习提供了一个动态的字典。那具体选择什么样的代理任务去做这个字监督学习这里它说其实 MOCO 是非常灵活的它可以跟很多代理任务去合起来用。那在这篇论文里它就选择了一个比较简单的 Instant discrimination 任务也就是我们之前讲过的个体判别任务。那为什么选它其实不光是简单而且是因为它的效果确实也非常好。
那这个任务是什么呢简单用一句话来概括就是说如果一个 query 和一个 key 是同一个图片不同的视角比如说不同的随机裁剪得到的那我们就说这个 query 和这个 key 能配上。对也就是说能在这个动态字典里查找到这个 query 所对应的key。那用了这个代理任务之后 Moco 在 image net 这个数据集上去做 Linear evaluation 的时候能跟之前最好的方法打个平手或者有更好的表现。
那最后一段自然还是老套路慢一下结果他说无监督的表征学习最主要的目的就是当你在很大的一个没有标注的数据集上去做完预训练以后你这个预训练好的特征是能够直接迁移到下游任务上 MOCO 就做到了这一点。他们说在 7 个下游的任务上这七个任务既有检测也有分割。
MOCO 这种无监督的预训练方式能不能超越用 image net 去做有监督的预训练方式有的时候甚至还是大幅度的超越那这个重要性是不言而喻的 MOCO 是第一个做到这么好的结果。然后其实大家对无监督学习还有另外一个要求或者说还有另外一个期待就是像 NLP 那边如果你用更多的数据用更大的模型我们希望这个模型的提升是永无止境的最好不要有性能保护的现象。所以说作者这里为了实验的完整性他又做了另外一组实验。他除了把 Moco 在 image net 去做预训练之外他在 Facebook 自己的一个数据集就有 10 亿 Instagram 图片的数据集上也去做了预训练最后的结果还能提升。所以这就证明了 MOCO 是可以在一个更偏向于真实世界而且有亿级规模图片的数据集上工作的很好的它。
这里为什么说 relative accurated scenario因为这个数据集并不像 Imagenet 一样是精心挑选过而且大部分图片都是只有一个物体在中间的。 Instagram 图片的场景当然就非常丰富了而且也会展示出真实世界中数据有的一些特性比如说数据分裂不均衡导致的长尾问题或者说一张图片可能现在含有多个物体所以跟 image net 比起来可能从数据的挑选和标注上都没有那么严格。然后因为 MOCO 不论是在中型数据集上去做预训练还是在大型数据集上去做预训练都能取得很好的结果所以作者最后说这些结果证实了 MOCO 可以在很多视觉的任务上把无监督学习和有监督学习的坑填平而且甚至可以在一些真实的应用上去取代大家之前一直使用的这个 image net 预训练的模型。
这句话虽然读起来平平无奇但它的影响力实在是巨大的因为不光是学术界几万篇甚至几十万篇论文之前都是用 Imagenet 预训练的模型去接着往下做实验那在工业界更是有数不清的产品之前是基于 Imagenet 预训练的模型的。那 MOCO 的影响力就是说所有的这些应用你都可以换成用 MOCO 无监督的训练方式训练好的模型说不定效果还会更好。
接下来我们看文章的最后一节结论部分。 MOCO 的结论部分其实不光是结论主要的内容都围绕在了讨论上。结论其实就一句话我们的方法在一系列视觉的任务和数据集上取得了比较正面就比较好的结果。大佬的论文就是这么直白且有力。接下来主要就是讨论了两个比较有趣的问题。第一个就是通过实验 Moco 的作者发现当这个预训练的数据集从 Imagenet 换到 Instagram 的时候提升虽然是有的但是都相对来说比较小就是说只有零点几个点或者一个点但是你的数据集可是从 100 万增加到 10 个亿了就你扩大了 1000 倍。这样的提升着实是有些小。所以说作者觉得是因为大规模的数据集没有被很好地利用起来他们觉得可能一个更好的代理任务有可能解决这个问题。
接下来这一段话其实是我读 MOCO 这篇文章给我感触最深令我大受震撼的一段话。我们来看作者接着说除了这个简单的个体判别任务我们有没有可能把 MOCO 和另外一个代理任务也就是 mask auto encoding 结合起来用就像 NLP 那边 Bert 一样用 mask language modeling 完形填空句子监督的训练模型。
那你读到这儿是不是发现这个词很熟悉那这不就是凯明大神最近星火的 m a e 吗也就是说这个想法大佬在两年前就已经有了甚至有可能已经做了一些初步的实验这在当时来看还是非常前瞻性的毕竟当时多模态也没有很火 vision Transformer 也还没有到来 NLP 降维打击 CV 也是最近一年才有的事儿。所以我每每读到这儿都被大佬的远见所折服而且同时也说明做研究真的急不来它真的需要积累。
最后毕竟是结论所以作者还是展望了一下点了个题说希望 MOCO 能对其他那些使用对比学习的代理任务有帮助。之所以强调对比学习是因为 MOCO 设计的初衷就是去构造一个大的字典从而让正负样本能够更有效地去对比提供一个稳定的自监督信号最后去训练这个模型。
好我们现在一起回来读相关工作。他说无监督学习或者自监督学习一般有两个方向可以做一个就是在代理任务上做文章一个就是在目标函数上做文章。作者这里打了个脚注那下面解释说其实自监督学习是无监督学习的一种但之前在前人的工作中大家一般都不去做区分就都是混着叫的。所以在 MOCO 这篇论文里作者就选择使用了无监督学习这个词儿因为定义的更广泛一些。
接下来就是大概介绍一下什么是代理任务什么是目标函数。他说代理任务一般指的是那些大家不太感兴趣的任务就是说不是分类分割检测这种有实际应用场景的任务。这些代理任务的提出主要是为了学习一个好的特征然后目标函数自然就很广泛了。所以它这里说目标函数的研究其实是可以和这个代理任务分开的。 MOCO 主要就是在目标函数上下的功夫它提出的这个又大又一致的字典主要影响的是后面info、nc e 这个目标函数的计算。先说目标函数这里的目标函数主要是针对无监督的方式而说的说最常见的构建目标函数的一个方式就是去衡量一下一个模型的输出而它应该得到的那个固定的目标之间的差距。比如说如果你用 auto encoder on 自编码器的话就是你输入一张原图或者一张已经备感扰过的图你现在通过一个编码器解码器然后你现在想把这张图重建出来这里你既可以用 l e loss也可以用L2LOSS但总之你衡量的是原图和你现在新建图之间的差异。这种就属于生成式网络的做法因为你是在生成一张图片。
如果你是想走判别式网络那一般有什么做法比如说它这里说的 eight position 其实就是 15 年的一篇论文它主要的思想就是说如果你把一张图片打成九宫格假如这个九宫格儿有序号就是从 123 一直到9现在先把中间这一格儿 5 给你然后再随机从剩下的格儿里挑一格儿给你。
你能不能预测出这个随机挑选的格儿是位于中间这一格儿的哪个方位比如说左上还是右下因为这里的每一块儿它其实都自带序号儿其实就相当于把这个代理任务转化成了一个分类任务因为它只有 8 个方位可以去预测所以 MOCO 这里就用 8 个位置来代表这个方法。然后作者又说除了判别式或者生成式这种常见的目标函数还有一些方法我们立马就讲一个就是对比学习的目标函数另外一个就是对抗性的目标函数那对比学习的目标函数主要是去一个特征空间里衡量各个样本对之间的这个相似性它要达到的目标就是要让相似物体的特征拉得尽量近两不相似物体之间的特征推开的尽量远。
那对比学习跟我们之前说的这种判别式或者生成式的目标函数有什么不一样它有一个很大的区别就是我们刚才说的不论你是判别式你是去预测 8 个位置还是说生成式你是去重建整张图你的目标都是一个固定的目标。但是在对比学习这边它的目标是在训练的过程中不停地改变的也就是他这里说的在训练的过程中目标其实是由一个编码器抽出来的这个数据特征而决定的也就是 Moco 这篇文章指的字典。接下作者说最近几篇效果不错的方法他们的核心思想都是用的对比学习具体的讨论我们一会儿会在三点儿一章节看到那对抗性的目标函数。之前牧神在讲干这篇论文的时候也提到过它主要衡量的是两个概率分布之间的差异。那对抗性的目标函数我们都知道它主要是用来做这个无监督的数据生成的但是后来也有一些对抗性的方法是用来去做这种特征学习了。因为大家觉得如果你能生成很好很真实的图片的话按道理来说你是已经学到了这个数据的底层分布那这样模型学出来的特征应该也是不错的。
接下来作者就说另外一个方面也就是这代理任务那代理任务其实过去几年大家提出非常多的形式脑洞真是开得五花八门。像这个 denosing auto encoder 重建整张图或者说 context auto encoder 就是重建某个patch或者说我们刚才说过的 colorization 的方法用给图片上色当词监督信号。然后作者说还有很多代理任务是去生成一些伪标签。像第一个说的这个 example image其实也就是给同一张图片做不同的这个数据增广它们都属于一个类 patch ordering也就我们刚刚说的九宫格方法要么就是打乱了以后你去预测它的顺序要么就是说随机选一个patch你去预测它的这个方位。当然还有利用视频的信息去做tracking以及就是一些聚类的方法了。
那最后一段作者还讨论一下对比学习和之前这些不同的代理任务之间的关系。他说不同的这个代理任务是可以和某种形式的这个对比学习的目标函数配对使用。比如说 Moco 这篇论文里使用的这个个体判别的方式就跟之前的这个 Exemplar based 代理任务很相关。那对于之前两个比较重要的工作一个是CPC一个 CMC 来说 CPC 做的是预测性的对比学习它是用上下文的信息去预测未来。
这个就跟我们上面讲到的这个上下文字编码代理任务非常相关。对于 CMC 来说它是利用一个物体的不同视角去做对比那这个就跟给图片上色这个代理任务就非常像了因为给图片上色这个任务就涉及了同一个图片两个视角黑白和彩色。那大概总结一下相关工作还是写得相当简洁明了。
之所以围绕目标函数和代理任务这两个方向去写相关工作是因为这两个部分是主要跟有监督学习不一样的地方。那如果我们和有尖头学习的对比一下假如说我们有一个输入x然后现在通过一个模型然后得到一个y也就是输出有了输出之后我们就去和一个 ground truth 去做比较然后我们需要一个目标函数去衡量一下这个比较的结果这个就是有监督学习的流程了。
对于无监督学习或者自监督学习来说那我们缺少的也就是标签就是这里这个 ground truth那如果没有标签儿怎么办那就自己造呗。所以这时候代理任务就派上用场了代理任务的用处就是去生成一个自见度的信号儿从而去充当这个 ground truth 这个标签信息。
那一旦我们有了输出y又有了这个标签信息那接下来我们还需要什么呢就需要一个目标函数去衡量它们之间的差异从而让模型去学得更好。所以说这也就是为什么 MOCO 这篇论文从这两个角度就是目标函数和代理任务去写这个相关工作。接下来就到了文章的主体方法部分三点儿一的标题直接就跟它的第一句话相呼应就是说之前的对比学习以及最新的一些效果比较好的变体它们都可以想象成是训练一个编码器从而去做一个字典查找的人物。然后我们就往细里说假设我们已经有一个编码好了的query q 也就是一个特征还有一系列这个已经编码好的样本也就是K0、K1、K2这些可以看作是一个字典里的那些key。然后他这里做了个假设他说在这个字典里只有一个 key 是跟这个 query 是配对儿的也就是说它俩互为正样本对它们把这个 key 叫做 key positive。
之所以有这个假设其实我们之前在讲个体判别任务的时候也提到过这个代理任务就是从一个图片经过两种变换得到两个图片其中一个作为基准图片另外一个作为正样本所以说就是只有一个正样本对。当然这里理论上你可以是使用多个正样本对的之后也有工作证明了使用更多的正样本对有可能会提升你任务的性能。然后我们一旦定义好了正样本和负样本接下来就需要一个对比学习的目标函数了。作者说这个对比学习的目标函数最好能满足以下这个要求就是当 query q 和唯一的那个正样本 key k plus 相似的时候它的这个 loss 的值应该比较低。然后还有就是当这个 query q 和其他所有 key 都不相似的时候这个 loss 的值也应该低因为这个本来就是我们的目标如果我们已经能达到这么一种状态就说明模型差不多训练好了。我们当然希望这个目标函数的 loss 值尽可能的低就不要再去更新模型了。那反之如果 q 和正样本 key plus 不相似或者说这个 query q 和本来应该是负样本的那些 key 相似那这个目标函数的 loss 值就应该尽可能的大从而去惩罚这个模型让模型赶紧更新它的参数。
接下来作者说在 MOCO 这篇论文里我们就采取了一个叫 info NCE 的对比学习函数来训练整个模型。那英符 NCE loss 到底是什么呢我们先不着急看这个公式一如果我先写这么一个式子你会联想到什么呢就是一个向量的exponential然后处于很多向量 exponential 的之和。很多人一看这不就是 Softmax 吗对的这就是 Softmax 操作。那如果我们现在是在有监督学习的范式下也就是说我们有一个 one hot 向量当作这个 ground truth那其实在前面加上一个副log整个这个公式其实就是 cross entry loss也就是交叉生目标函数了。
那注意一下这里的这个 k 在有监督学习里指的是这个数据集一共有多少类别。比如说 Imagenet 的话就是 1000 类这里的 k 就是1000它是一个固定的数字。那我们现在回到对比学习其实对比学习理论上来说是可以用这个公式去计算 loss 的但是实际上行不通。如果说我们像大部分对比学习的工作一样就使用 instance discrimination 这个代理任务去当资金 no 信号的话那它这里的类别数 k 将会是一个非常巨大的数字。就拿 Imagenet 数据集来举例这里的 k 就不再是 1000 了而是 128 万就是你有多少图片它就有多少类。那我们大家也知道 Softmax 操作在有这么多类别的时候它其实是工作不了同时因为这里还有 exponential 操作当你这个向量的维度是几百万的时候计算复杂度是相当高的。
如果每个训练的 iteration 你都要去这样去算loss那训练的时间将会大大的延长所以该怎么办那这个时候 NCE loss 就出来了CEE也就是 noise contrasted estimation 的缩写它是什么意思那之前你不是说因为类别太多所以我没法去算Softmax从而没法去算这个目标函数吗 i n c e 就说不如我们把这么多类就简化成一个二分类。
问题就是我现在只有两个类别了一个是数据类别就是 data sample一个是噪声类别就是 noise sample。那我每次只需要去拿这个数据样本去和这个噪声样本做对比就可以所以这也就是这里说的 noise contrasted。
但是如果你还是把整个数据集剩下的图片都当作负样本那即使 noise contrast 解决了你这个类别多的问题但你的计算复杂度还是没有降下来那怎么能让这个 loss 算得更快一点儿呢没有别的办法只有取近似了。那意思就是说与其你在整个数据集上去算这个loss不如我就从这个数据集里去选一些这个负样本来算 loss 就可以了。这也就是这里这个 estimation 的含义就是它只是一个估计一个近似。但是我们也知道按照一般的规律如果你这里选取的样本很少那它就没有那么近似了结果自然也就会比较差。那它选的样本越多自然就跟使用整个数据集的图片的结果更加近似效果自然也会更好。
所以这也就是 MOCO 为什么一直强调的他希望这个字典足够大因为越大的字典就能够提供一个越好的近词所以说总结一下就是 NCE 这个 loss 就是把一个超级多类分类的问题变成了一系列的二分类问题从而让大家还是可以开心的使用 Softmax 操作。
那这里说的 Infor NCE 又是什么呢其实它就是 NCE 一个简单的变体它觉得如果你只把问题看作是一个二分类就只有数据样本和噪声样本的话可能对模型学习不是那么友好毕竟在那么多噪声样本里大家很有可能不是一个类所以还是把它看成一个多分类的问题比较合理。于是 n c e 华丽转身就变成了这个公式一它从而也就变成了 influence loss。那我们现在来看公式一这里的 q 乘以k还有底下的 q 乘以k其实就相当于是Logics也就可以类比于我们之前的softmaxy这里用了这个 z 也是模型出来的Logics。
那这里的套其实下面说了是一个温度的超参数这个温度一般是用来控制分布的形状的比如说你原来的 largest 分布大概长这个样子然后如果你现在这个套的值变大也就是一减套变小了就相当于把这个分布里的数值都变小了尤其是经过 exponential 之后就变得更小了最后就会导致这个分布变得更平滑。
那相反如果你这个 TA 取得值小也就是 1 除以 TA 变得更大那就是说这个分布里的值都相应的变大尤其是经过 exponential 之后原来大的值会更大就使得这个分布更集中也就是变得更 peak 了。所以说这个温度超参数的选择也是很有讲究的。
如果温度设得越大那对比损失对所有的负样本都一视同仁导致模型的学习没有轻重。但如果温度的值设的过小又会让模型只关注那些特别困难的负样本其实那些负样本很有可能是潜在的正样本。如果模型过度的关注这些特别困难的负样本会导致模型很难收敛或者学好的特征不好去泛化。
但是温度的这个超参数终究只是一个标量我们如果把它忽略不看你就会发现其实这个 influencie loss 不就是 cross centripy loss 吗唯一的区别就在于在 cross centripy loss 中这个 k 指代的是数据集里类别的多少但是在对比学习的 influencer e loss这个 k 指的是负样本的数量。然后作者接下来说公式下面的这个和就是这个 sum 其实是在一个正样本和 k 个负样本上做的因为是从 0 到k所以是 k 加一个样本也就指的是字典里所有的key。
那接着说如果你直观的想一想这个 influence loss 也就是一个 cross entry loss它做的就是一个 k 加一类的分类任务然后它的目的就是想把 q 这个图片分成 k plus 这个类。所以我们读到这儿也会发现 info n c e 也不是那么难理解跟之前我们常用的 cross entry loss 是有这么大联系的。而且其实如果我们现在直接跳到后面的这个 MOCO 的伪代码的话我们也会发现 MOCO 这个 loss 的实现它就是基于 cross Centrby loss 的实现。
接下来第二段作者说既然你已经有了这个代理任务提供给你的正负样本也有了可以用来训练模型的目标函数那接下来就该讨论一下这个输入和模型大概是什么样。但这里作者还是从一个字顶向下的方式去写这篇论文比如他说普遍来讲这个 query q 是一个输入 SQ 通过一个编码器 FQ 得到的那同理那所有的那些 key 的表示也都是那些 key 的输入通过了一个 key 的编码器至于这个输入到底是什么模型到底是什么作者说它们具体的实现是由具体的这个代理任务决定。比如说在代理任务不一样的时候这个输入的 SQ 和 SK 既可以是图片也可以是图片块儿或者是含有上下文的一系列的图片块儿。
至于模型作者说这个 query 的编码器和 key 的编码器 g 可以是相等的就是说模型架构也一样它们的参数也是完全共享的或者说它们的参数是部分共享那再或者说就是彻底不一样的两个的网络。那从总体上大概讲完了什么是输入模型输出还有目标函数之后接下来就该具体讲一讲什么是 MOCO 了作者在这里又写了一段再次强调了一下他们的研究动机到底是什么为什么要剔除MOCO这其实是一种很好的写作方式就是说你整个论文每段和每段之间最好都有承上启下的段落。当你每开始讲一个新的东西的时候最好先讲一下我们为什么需要它。一旦有了这个承上启下的段落也就是这个因为所以的这个逻辑关系之后大家读起你的论文来就会更顺畅。否则如果你的论文上来每一段都是直接就讲方法的话很容易会让人看得一头雾水的。无论你觉得你写得有多清晰读者可能从一开始就根本没明白你为什么要这么做这就很伤了。
我们回到文章作者说从以上的这个角度对比学习是一种在高维的连续的输入信号上去构建字典的一种方式它这里的高维连续其实就指的是图片了然后他说这个字典是动态的为什么是动态的因为这个字典里的 key 都是随机去取样的而且用来给j、j、 k 做编码的那个编码器也是在训练的过程中不停的改变。
这个就跟我们之前讲过的不论是有监督还是无监督的方法都不太一样因为之前的那些工作他最后学习的那个 target 都是一个固定的目标。所以说作者认为如果想学一个好的特征这个字典就必须拥有两个特性。我们已经也说过很多遍了一个就是大一个就是一致性因为大的字典能够包含很多很多这个语义丰富的负样本从而有助于能让你学到更有判别性的那些特征。那一致性主要是为了模型的训练避免他学到一些 trivial solution就是一些捷径解。所以说基于这些研究动机作者们提出了 momentum contrast所以说这整个一段都是在承上启下。
接下来就先介绍文章的第一个公信就是如何把一个字典看成是队列。作者说我们方法的核心其实就是把一个字典用队列的形式表现出来队列其实是一种数据结构这样如果你现在有一个队列里面有很多元素假如说新来的元素现在从下面进来那为了维持这个队列的大小就得有一些东西就是说最老的那个数据会从队列里出去。
所以说队列一般都被称作是一个 FIFO 的值的数据结构也就是 first in first out 就先进先出的数据结构。那作者这里是用这个队列就代表一个字典也就是说这整个的这个队列就是一个字典里面的元素就是我们的放进去的那些key。在模型训练的过程中每一个 Mini batch 就会有新的一批 key 被送进来同时也会有一批老的 key 移出去。
所以作者说用队列的好处可以让我们重复用那些已经编码好的key而这些 key 是从之前的那些 Mini batch 里得到的它的意思就是说比如说这块儿的元素就指代的是当前 Mini batch 送进来新的key那紧挨着它上面的这些 key 就是它之前的那些 Mini batch 编码好送进来的。这样使用了队列之后就可以把这个字典的大小和这个 mini batch 的大小彻底就剥离开了。那我们就可以在模型的训练过程中使用一个比较标准的 mini batch size 一般就是 128 或者256但是我们的这个字典的大小可以变得非常大它的大小非常灵活而且可以当做一个超参数一样才可以单独设置。然后文章接着说这个字典一直都是所有数据的一个子集因为我们之前说过想在算对比学习的这个目标函数的时候只是取一个近似而不是在整个数据集上去算一个loss。而且作者说使用队列这个数据结构可以让维护这个字典的计算开销非常小。事实上也确实如此我自己其实也试过如果把这个字典的大小从几百变到几千或者上万整体的这个训练时间基本是不变的。
最后作者又强调了一下说为什么就要使用队列这个数据结构是因为队列有这个先进先出的特性这样每次移出队列的都是最老的那些 mini batch也就是最早计算的那些 Mini batch这样对于对比学习来说是很有利的因为从一致性的角度来说最早计算的那些 Mini batch 的 key 是最过时的也就是说跟最新的这个 Mini batch 算的这个新的 key 是最不一致的。
那讲完队列之后作者就开始写文章的第二个贡献也就是如何用动量的思想去更新这个编码器。他说用队列的形式当然可以让这个字典变得非常大但是也因为用了非常大的字典也就是说非常长的这个队列就导致我们没有办法给这个队列里所有的元素去进行梯度回传了。也就是说这个 key 的编码器没办法通过反向传播的方式去更新它的参数。那这个问题怎么解决总不能 query 编码器那边那个 FQ 一直在更新但是你这边 key 的编码器就一直不动。然后作者说如果你想更新这个 key 的编码器其实有一个非常简单的方法就是说你每个训练 iteration 结束之后你把那个更新好的编码器参数 FQ 直接复制过来给这个 key 的编码器 FK 不就行了吗那这个想法简单确实是简单但是作者紧接着说这个方式的结果并不好他们觉得这个结果不好的原因是因为你一个快速改变的编码器降低了这个队列里所有 key 的这个特征的一致性。
那这句话怎么理解假如说我们现在有一个队列新的元素从左边进然后旧的元素就右边出假设我们的 Mini batch size 就是一意思就是我们每次只更新一个key那K1、K2、K3、K4K5就所有的直接 key 都是由不同的编码器产生。那这样你这些快速改变的编码器就会降低所有 key 之间的这个一致性。
所以作者接下来说我们提出了一个动量更新的方式来解决这个问题。那现在如果我们把 key 编码器 FK 的参数设为CDAK query 编码器 FQ 的参数设为CDAQ那 CDAK 就是以这种动量改变的方式进行更新的。这个式子我们之前在引言的时候也已经讲过了这里面 m 就是动量参数它是一个 0- 1 之间的数。 set a q 也就是 query 编码器是通过梯度反向回传来更新它的模型参数的。而 set a k 除了刚开始是用 set AQ 去初始化以外它后面的更新大部分主要是靠自己因为如果这个动量 m 设的很大那 set a k 更新就非常缓慢了。
这位作者杰西尔说因为使用了这种动量更新的方式所以虽然在队列里这些 key 都是由不同的编码器产生得到的但是因为这些编码器之间的区别都太小所以产生的这些 key 它的一致性还是非常强的。那为了强调这个观点作者说在他们的实验里他们用了一个相对比较大的动量就是 0. 2999那这个确实比较大了。意思就是说这个 seed k 每次的更新 99. 9% 就是原来的编码器参数只有 0. 1% 是从更新好的 c 代 q 里借鉴过来的那自然这个 CDAK 的更新就非常缓慢了。
然后作者还做了对比实验就是当它把这个动量变小一点就是变成 0. 9 的时候其实 0. 9 也不算小了但是作者说使用一个相对较大的动量零点儿九九九要比零点儿 9 效果好得多。所以就意味着说如果你想充分利用好队列那一个缓慢更新的 key 编码器是至关重要的因为它可以保证这个队列里所有的 key 是相对一致的。那读到这儿其实 MOCO 的主要贡献就已经讲完了但是如果对比学习不是很熟的人来说可能现在还是有点儿懵就是 MOCO 它这个前向过程到底长什么样儿它有没有一个模型总览图可以让我们看呢那可惜 MOCO 这篇论文并没有提供一个很直观形象的模型总览图取而代之的它直接给你上了伪代码那我们再等几分钟就能读到这份伪代码了写的是相当简洁明了别说是理解 MOCO 了就算是去复现 MOCO 也没有问题。
那在讲伪代码之前作者还有一个坑要填这是之前在引言第三段提到过的他说之前的那些对比学习的方法都可以看作是字典查找但它们都或多或少受限于这个字典的大小和这个字典一致性的问题。所以作者这里就得详细的解释一下到底之前的方法是怎么受限的那 MOCO 又是如何通过动量对比的方式去解决这些局限性的。
所以作者这里就把之前的方法大概总结了一下就归纳成了两种架构第一种就是比较直接的这个端到端学习的方式那我们现在就去看一下这个图 2A 跟着图讲会比较直观。那端到端学习顾名思义就是说这个编码器都是可以通过梯度回传来更新模型参数的。在图 2 的标题里作者也写到这个编码器 q 和 k 可以是不同的网络但是之前很多工作都用的是同样的网络。为了简单起见 MOCO 的实验里这个编码器 q 和 k 是同一个模型也就是一个 RES 五十。
那为什么它可以用同一个模型因为它的正负样本都是从同一个 mini batch 里来的就是说这里的 XQ 和 XK 都是从同一个 batch 里来它做一次 forward 就能得到所有样本的特征而且这些样本是高度一致的因为都是从一个编码器里来听起来确实很美好编码器都能用反向回传学习了特征也高度一致了。
但它的局限性就在于字典的大小因为在端到端的学习框架中字典的大小和 Mini batch science 的大小是等价的。那如果我们想要一个很大的字典里面有成千上万个 key 的话也就意味着 Mini batch 的 size 大小必须也是成千上万那这个难度就很高了因为现在的 GPO 是塞不下这么大的 batch size而且就算你有内存更大的硬件你能塞下那么大的 batch size。但我们也知道大 batch size 的优化也是一个难点如果处理不得当模型是很难收敛的。所以作者这里说这种端到端学习的方式就是受限于字典的大小。但我这里想插一句之所以我们选择读 MOCO 这篇论文而不是读 same clear是因为 same clear 其实就是这里这种端到端的学习方式当然它还用了更多的这个数据增强而且提出了在编码器之后再用一个Projector会让学到的特征大大变好。
但是总体来说 same clear 就是这里的端到端学习方式。他们之所以能这么做是因为 Google 有TPU TPU 内存大所以就可以无脑上 batch size。像 same clear 里他们就选用了 8192 当作 batch size这样最后就会有 1 万多个负样本那这个负样本的规模就足够对比学习了所以 same clear 就可以用这么简单的方式直接去做端到端的学习。
那看完端到端学习的这种做法以后我们发现它的优点在于编码器是可以实时更新的所以导致它的字典里的那些 key 一致性是非常高的。但它的缺点就在于因为字典的大小就是 Mini bash 的大小导致这个字典不能设的过大否则硬件内存持不行。那这样的话很自然另外一个流派就应运而生了也就是说我更关注字典的大然后牺牲一些一致性这也就是我们马上要看的第二种方式就是 memory bank。
在 memory bank 里其实就只有一个编码也就是 query 的编码器是可以通过梯度回传进行更新学习的但是对于字典这个 key 这边是没有一个单独的编码器的那它是怎么操作的其实 memory bank 就是把整个数据集的特征都存到了一起那对于 Imagenet 来说这个 memory bank 里就有 128 万的特征听起来好像很大的样子但其实 memory bank 的作者也就是 MOCO 这篇论文里的文献61他在论文里说因为每一个特征只有 128 维所以即使我整个 memory bank 里有 128 万个key最后我也只需要 600 兆的空间就能把所有的这节 key 存下来了。即使是对整个数据集的特征做一遍最近连查询在泰坦 x 的 GPU 上也只需要 20 毫秒所以是非常高效的。
然后一旦有了这个 memory bank那在每次模型做训练的时候只需要从这个 memory bank 里去随机抽样很多 key 出来当作字典就可以了。就相当于这整个右边这些操作都是在线下执行的所以完全不用担心硬件内存的问题。也就是说这个字典可以抽样抽得很大但有得必有舍 member bank 的做法在特征一致性上就处理的不是很好。那假如说我们现在有这么一个 memory bank里面有 128 万个key它在训练的时候是随机抽样很多样本出来当作这个字典的。那我们这里为了讲解方便我们就说它是顺序抽样而且这个字典大小就是三。那就是说当你在做对比学习的时候你当前的 mini batch 可以先把这个K1、K2、 K3 这三个 key 抽出来把当成负样本然后去跟你这个 query 算loss当你算完这个loss回传了梯度然后更新了这边这个编码器之后 memberbank 的做法就是会用这个新的编码器在原来对应位置上也就是这个K1、K2、 K3 的位置上的那些样本去生成新的特征。也就是我用蓝色笔写的新的K1、K2、 K3 这三个key然后我们把这个新的 key 放回到 memory bank 里。
3 它就把这个 memory bank 更新了依次类推。那下次假如说我把 456 这三个 key 抽出来做一次模型更新然后再把新的 key 456 放回去那这个 456 也就被更新了那这里就会有一个问题也就我们之前反复讲过的问题因为你这里的特征都是在不同时刻的编码器得到的而而且这些编码器都是通过梯度回传来很快的更新的那就意味着你这里得到的这些特征都缺乏一致性。而且 memory bank 还有另外一个问题因为 memory bank 里存了所有的图片那就意味着你模型训练了整整一个epoch才能把整个 memory bank 更新一遍。
那就意味着当你开始下一个 epoch 训练的时候比如说下一个epoch我选了 158 这三个key那这 3 个 key 的特征都是上一个 epoch 不知道是哪个时间点算出来的特征了这也就导致说这个 query 这边的特征跟 key 这边的特征差非常远。所以说总结一下 member bank 的做法就是牺牲了特征的一致性从而获得了可以构造很大的字典的特权。但显然这两种流派无论是端到端的学习还是 memory bank 的方法它都像 MOCO 的作者说的一样受限于字典大小和特征一致性这两个方面中的至少一个。所以为了解决之前这两种做法的局限性作者提出了 MOCO 采用队列的形式去实现一个字典从而使得它不像端到端的学习一样受限于 batch size 的大小。同时为了提高字典中特征的一致性 MOCO 使用了动量编码器。其实从整体上来看 MOCO 跟 memberbank 的方法是更加接近的它们都是只有一个编码器就是query这边的编码器是通过梯度回传来更新模型参数的然后他们的字典都是采取了额外的数据结构进行存储从而和 batch size 剥离开来。
memberbank 里就是使用了memberbank MOCO 里就是使用了队列而且 memory bank 这篇论文它也意识到特征不一致性带来的坏处了所以他们当时还加了另外一个loss叫 proximal optimization目的就是让训练变得更平滑。
其实跟 MOCO 里的这个动量更新是有异曲同工之效的。这里对这个 loss 我就不展开说了感兴趣的同学可以去看他们原来的论文也就是这里的文献。 61 关于这一点 MOCO 的作者在后面也提到了 memory bank 这篇论文他们也用了动量更新的方法只不过他们的动量更新的是特征而我们动量更新的是编码器。而且 MOCO 的作者还补充说 MOCO 的扩展性是很好的它可以在上亿级别的图像库上去进行训练。但是对于特别大的数据集 Marabank 的方法就捉襟见肘因为你需要把所有的特征都存到一个 memory bank 里那对于 Imagenet 这种百万规模的数据集来说存下所有的特征只需要 600 兆的空间那对于拥有一个亿级图片规模的数据集存储所有的这些特征就需要几十 g 上百 g 的内存了。所以 member bank 的扩展性不如 MOCO 好。
总之就是一句话 MOCO 既简单又高效而且扩展性还好它能同时提供一个又大而且又一致的字典从而进行对比学习。终于读完了 3. 2 章节大家应该对 MOCO 的研究动机它的贡献有了一定的了解那接下来马上就可以看伪代码了。作者在 3. 3 节写的是代理任务但因为我们已经讲了很多遍了所以这里就不重复了。作者就是说为了简单起见他们就用了这个个体判别的任务然后个体判别的任务定义就在这里。接下来作者说算法一提供了 MOCO 的伪代码我们现在来看。算法一它先定义了一些参数比如说 f q f k 分别是 query 和 key 的编码器然后 q 这个队列就指的是字典里面一共有 cake key所以它的维度就是 c 乘以key这里的 c 就是每个特征的维度。然后 m 是动量 e 就是算 info n c e loss 的时候那个温度。
好那我们现在走一下这个模型的整体的前向过程。首先我们要初始化两个编码器那对于 query 编码器这个 FQ 来说它是随机初始化的。然后我们把 FQ 的参数直接复制过去给FK就把 FK 也初始化了。接下来从 dataloader 里去拿一个 bash 的数据这里数据用 x 表示然后它有 n 个sample那在 MOCO 的代码里这个默认的 batch size 是256也就是这个 n 是256所以是非常标准的 batch size。你是可以在常用的 GPU 上进行训练的。
接下来第一步就是得到一个正样本。对所以从原始的数据 x 开始我先做一次数据增强得到了一个 query 图片。然后我再去随机的做一次数据增强得到了一个 key 的图片。因为这个 query 和 key 都是从同一个数据 x 得到的它的语义不应该发生太大的变化。所以说这个 SQ SK 就成为了一个重要门队。
接下来我们把 query 的数据通过 query 的编码器做一次前向从而得到真正的那个特征 q q 的特征维度是 n 乘c也就是我们刚才说的 256 乘以128那为了便于理解我们这里再具体化一些。那假如说这个编码器FQFK它就是一个 rise 50 的网络那我们也知道 rise 50 等到最后一层做完 global average pulling 以后它会得到一个 2048 尾的特征。一般如果你是在 Imagenet 数据集上去做有监督训练的时候你会加一个分类头把这个 2048 维变成 1000 维然后这样你就可以去做分类了。那在这里呢作者就是把那个 1000 换成了128也就是说从 2048 维变成了 128 维。那为什么使用128其实是为了跟之前的工作保持一致也就是之前 memory bank 那个工作文献61。 memory bank 那篇文章里为了让整个 memory bank 变得尽可能的小所以它特征的维度选的也相对较小就只有128。
好我们回到尾代码那接下来就是这个key通过编码器 FK 得到正样本的那个key它的维度也是 256 乘以128。接下来因为是 Pytorch 的代码所以用一个这个 detach 操作把这个 gradient 去掉这样对于 key 来说就没有梯度回传了反正也是要放到队列里去的。
那接下一步就是算Logics也就是之前公式一里算 info NCE loss 的时候这样的那个分子就是 q 乘以 k positive也就是这里的这个 q 乘以 k positive那我们就得到了这个正样本的logics这特征维度就变成了 n 乘一2561。那对于负样本来说我们怎么去算它的Logis首先我们得从队列里把负样本拿出来也就是这里的q那接下来就是算公式一里应付 NCE 的分母了也就是你做一个求和然后你的 query 乘以KI而这个 i 是从 0 到 k 的。
那做完这一步乘法之后你就得到了负样本的logges也就是这里的 n 乘以k所以就是 256 乘以6536。因为 MOCO 这篇论文里它默认的字典大小是65536里面有 6 万多个 key 这么大。那最后总体的logics也就是既有正样本又有负样本就是所有的 Logis 拼接起来就变成了一个 256 乘以 65537 的一个向量。也就是像公式一里说的一样我们现在其实就是在做一个 k 加一路的分类问题那一旦我们有了正负样本的Logis那接下来就是算 loss 了。这里我们之前也提过它其实就是用了一个 cross attribute loss 去做这个实现。那既然你是交叉伤loss你肯定就得有一个 ground truth那作者这里非常巧妙它这里的 ground truth 就设计了一个全零的向量。为什么是全零因为按它这种实现方式所有的正样本永远都是在这个 largest 第一个位置上的也就是位置0。所以对于正样本来说如果你找对了那个key你在分类任务里得到的正确的类别就是类别0所以就巧妙地用这种方式创建了一个 ground truth从而算了一个对比学习的loss那有了 loss 之后自然就是先做一次梯度回传有了梯度之后就可以去更新这个 query 的编码器了。
接下来就到了 MOCO 的第二个贡献也就是动量更新。因为我们不想让这个 FK 变得太快所以 FK 的参数大部分都是从上一个时刻的参数直接搬过来的只有非常少一部分是从当前更新过的 FQ 里拿过来的这样就保证了这个 key network 是缓慢更新的。
最后一步就是更新队列把你新算的这波 key 放进队列里然后把最老的那个 key 队列里移除。那读完了这份伪代码其实我们应该对 MOCO 就有一个更全面的了解了而且我非常建议你去看一下 MOCO 的那个官方代码真的是写得极其出色非常简洁明了而且那个代码基本就跟这个伪代码是一模一样的。那读到这里就把 MOCO 整体的算法以及大部分的细节都说完了。
最后我还想大概提一讲 MOCO 这篇论文里用的一个小trick也就是这个 shuffle b n 的操作。我并不会很细致的讲因为这个操作在接下来很多论文里甚至包括作者团队接下来的工作比如 Sam 也没有再用 shuffle b n 这个操作了。
它的意思是说因为你用了 b n 以后很有可能造成当前 batch 里的这些样本中间的信息会泄露因为 b n 要算这些样本的 running mean 和 running variance也就是说它能通过这些泄露的信息很容易的去找到那个正样本而不需要真正去学一个好的模型也就是作者这里说的这个模型会走一条捷径。
那怎么解决这个问题因为 BN 这个操作大部分时候都是在当前这个 GPU 上算的所以作者们在做多卡训练之前先把样本的顺序打乱再送到所有的 GPU 上去等算完了特征再把顺序恢复来去算最后的loss那这样对 loss 是没有任何影响的在你每个 GPU 上的 BN 计算就可就变了就不会再存在这种信息泄露的问题了。
类似的 BN 操作还在后续 BYOL 那篇论文里引起了一段很有意思的乌龙事件我们接下来会录一期关于对比学习的论文串烧会在那里讲一讲 b n 到底引起了一个怎样的讨论。总之 b n 这个操作真是让人又爱又恨。用得好当然威力无穷但是 90% 的情况可能都是属于用得不好会带来各种莫名其妙的问题而且很难去debug。所以现在换成 Transformer 也好这样直接就用 layer known 就能暂时不用理会鼻音了。
最后我们来看一下实验。作者先说了一下数据集的使用就是在做无监督的预训练时候他们用了标准的 image net 数据集然后为了验证 MOCO 的扩展性很好他们还是了 Facebook 自己的 Instagram Evilian 的数据集。然后作者这里说Imagenet一般之前大家都叫它 Imagenet one k因为它有 1000 个类别但是它们这里叫 Imagenet one million。至于 MOCO 的论文里用的是个体判别的任务所以类别数不再是1000而是整个数据集图片的数量也就是 one million。然后这个 Instagram 数据集作者之前在引言也提到过就是说它跟 image net 有一些不一样的特性比如它展示了真实世界中数据的分布就是长尾的或者说是不均衡的同时它的图片既有那种只有一两个物体的也有那种有很多物体或者是场景层面的图片。
接下来作者又讲了一下训练的情况因为还是 CNN 时代所以说就用的是 SGD 当成优化器那对于 Imagenet 这个数据集来说他们用的是标准的batch size 就是256然后是在一台扒卡机上训练的如果用 RES 50 这个网络结构的话训练 200 个 epoch 大概需要是 53 个小时。这真的已经是大佬给我们送福利了。
因为相对于之后的工作 same clear swab 或者 BIOL 这些工作 moco 不仅是从硬件本身还是从训练时长上都已经是最 affordable 的方法了。而且其实我们后面还可以了解的 MOCO 或者 MOCO v two 这一系列的方法它的泛化性非常好就是说当你在做下游任务的时候它学到的特征依旧非常强大。所以虽然看起来 same clear 的这个引用会比 MOCO 稍微高一些但其实真正在视觉领域里大家在别的任务上用对比学习的时候绝大多数工作都是沿用的 MOCO 这套框架。
说完了预训练所用的数据集以及是如何训练模型的接下来就该看结果了。作者是分了两个大部分去展示结果的第一部分就是用这种 Linear classification Protocol就我们之前讲过的把这个训练好的模型当作一个特征提取器。在 4. 2 章节主要作者就讲了一下牵引学习的效果。
我们先看 4. 1作者说在他们完成了这个无监督的预训练之后他们把模型的 backbone 冻住只把它当作一个特征提取器然后在它上面训练一个全连接层去充当一个分类头训练这个分类头用了 100 个一炮。至于结果的衡量是在 Imagenet 的测试集上报告了 one crop top one 的这个准确度。这里面其实最有意思的是接下来这段话他说他们做了一个 great search然后发现这个最佳的学习率是30。
这个其实是很不可思议的因为除了在神经网络搜索就是 NARS 那些工作里可能会搜到一些比较夸张的 learning rate 之外过去几十年里用神经网络的工作都没有用超过一的这种 learning rate因为你已经预训练好一个网络了你现在要做的只是微调所以说大家最大可能也就是设等 0. 1然后降到 0. 010. 001 这样往下降。
很少有人会设一个比一大的 learning rate但在这里竟然是30所以说做无监督学习或者说对比学习的同学可以回去看一下你的 learning rate如果你的结果还不好很有可能是你的这个学习率还没有设置对。然后基于这个现象作者其实也总结了一下他说这个学习率确实比较诡异。他安但是就是这种无监督对比学期学到的特征的分布跟有监督学习到的这个特征分布是非常不一样。接下来我们看第一个消融实验这个消重实验主要是用来对比之前图 2 里展示着三种对比学习的流派也就是端到端学习 a memory bank 和本文提出的MOCO。这个图的横坐标用 k 表示也就是说我用了多少个这个负样本你可以粗略地把它理解成字典的大小然后纵坐标就指的是在 Imagenet 上的这个 top one 准确率也就是 Linear classification protocol 下的那个准确率那我们就按顺序看。
首先第一个我们看黑色这条线就是端到端的学习那端到端的学习的结果就只有这三个点因为受限于显卡内存作者刚才也说了用一台现在已经很好的 8 卡 V100 机器就是有 32 g b 内存的那种它能塞下的最大的 batch size 也就只有1024所以即使是大佬也得止步于此。那对于第二种方法就是 memory bank 的形式当然它可以用很大的字典所以说它的这个曲线可以走得很远但是它的效果整体上要比端到端和 MOCO 的结果都要差一截作者说这就是因为特征的不一致性导致。
最后我们来看 MOCO 确实可以有很大的字典之所以停在6万这个数字我们也可以看到其实从 1 万到6万这个性能也已经比较饱和了所以说再大可能也不会带来更多的性能提升了。如果拿 MOCO 去跟端到端学习的方法做比较我们可以看到在刚开始的时候这个曲线的重合度还是非常高的但是作者说因为没有实验的支撑我们也不知道这条黑线是否能继续按照这个趋势增长下去它有可能结果会更高当然也有可能结果会更低但是做不了实验所以我们也无从得知。所以基于这个图3 MOCO 是性能最好对硬件要求最低而且扩展性也比较好的方法。
那说完了使用队列的好处接下来就该做消融实验去证实第二个贡献也就是动量更新所带来的好处了。所以说这也是写论文时候必须注意的东西就是如果你提出了几点贡献那你就一定得做针对这几点贡献的消融实验这样才能有效地证明你提出的贡献是有效的否则口说无凭。
那我们来看针对动量从小到大到底会对模型的性能带来什么样的影响。作者说使用一个相对较大的值就是 0. 999 或者 0. 9999 的时候性能是最好的它俩差不多都是59。这也就说明一个变化非常缓慢的编码器是对比学习有好处的因为它能提供一个一致性的特征但是当你把这个动量逐渐变小变到 0. 99 或者 0 点儿九的时候这个性能的下降就比较明显了。尤其是当你直接去掉动量我就是把那边儿快速更新的 query 编码器直接拿过来当 key 的编码器用你就会发现不光是性能下降的问题整个模型甚至都不能收敛了它的这个 loss 一直在震荡从而导致训练失败。所以说别看小小的一个 table 就一行它其实非常有力地证明了作者的论点就是说我们要建立一个一致性的字典。
那讲完了消融实验接下来我们就来到了这个兵家必争之地也就是 Imagenet 上的这个效果的比较。作者强调说这里的所有的方法都是在这个 Linear classification protocol 下面进行的也就是说都是把这个网络当成一个特征提取器抽出来特征再去训练一个全连接层当做分类头最后得到这些结果所有的这些结果都没有去更新那个backbone。然后这个表格上面这些方法都不是用对比学习的这些方法就都是用了对比学习的。我们首先可以看到就对比学习效果还是确实不错的因为明显这些结果就要比上面这些结果要高一大截。然后同时作者还强调说无监督学习里这个模型的大小是非常关键的因为一个公认的事实就是说如果你的模型越大一般你的效果就会越好所以如果你只比最后的这个准确度而不去关注模型大小的话这个就有点赖皮了。
所以说作者在这个表格里也把具体使用的网络结构还有就是网络所用的这个模型参数大小也都罗列了出来这样就可以去做一个相对全面而且相对公平的比较了。比如说如果我们只看标准的 rise 50也就是这块儿 rise 50它们的模型参数都是 24 米连这么大那之前利用标准的 rise 50 得到的结果这个最高也就是这个 58 点儿 8 了而 MOCO 是能达到 60. 6 的所以要比之前的结果高两个点已经算是很大的提升了。
然后我们现在如果不对模型架构做限制就是你可以变得很大比如说这里这些三层、二层、四层就是说我把这个模型里的这个 channel 数增多让它变得更宽它还是 50 层那么深但是它更宽了也就是说它的模型参数更大了。那在这种情况下之前最好的结果也就是比如说这块儿 68 点儿四 60 八点儿一这种但 MOCO 只用 375 million 就已经能达到 68 点儿 6 了还是比之前的方法都高的。而且作者这里还加了特殊标记而是有这些标记的方法都用了 fast auto Augment 去做这个数据增强而这个数据增强的策略其实之前是在 Imagenet 那边用有监督的训练方式训练得到的其实这就不太好说就有点儿不公平。
然后对于 56 这个方法也就是 CMC 来说它其实是用了两个网络而不是只用一个网络所以你这里可以看到它其实是 47 兆也就是两个 24 这么大但不论你是用了更好的这个数据增强还是用了两个甚至多个编码器。总之 MOCO 既能在小模型上得到最好的结果也能在大模型的比较中得到最好的结果。接下来就是最后一个章节了也是全文的点睛之处作者就是想验证一下 MOCO 预训练模型得到的这个特征到底在下游任务上能不能有好的这个迁移学习效果。接下来这两句话要划重点作者说无监督学习最主要的目标就是去学习一个可以迁移的特征用 Imagenet 去做这种有监督的预训练它最有用的时候也就是说最有影响力的时候就是当你在下游任务上做微调你可以用这个预训练好的模型去做这个模型的初始化从而当下游任务只有很少的标注数据的时候也能获得很好的效果。所以说这个章节的结果才是我们真正关心的。那接下来作者就拿视觉领域里最常见、应用最广的任务也就是检测来做。
这个无监督的 MOCO 预训练模型和 image net 有监督预训练模型之间的比较但是在展示结果之前作者说我还得讲两个事情为什么要谈归一化因为我们之前在这个 4. 1 章节刚开始的时候也提到了如果我们拿 MOCO 学出来这个模型直接当一个特征提取器那他在做微调的时候他的最佳学习率竟然是30也就说明 MOCO 学到的特征跟有监督学到的特征它分布是非常不一样那我们现在是要拿这个特征去做不同的下游任务我不可能在每个下游任务上都去做一遍 great search都去找一下它最佳的那个学习率是多少。那这个就有点太麻烦了也有点儿失去了这个无监督预训练的意义。
这位作者还是想如果我们可以拿之前就大家为这些有监督的预训练已经设置好的超参数来做微调的话那不就既可以做公屏对比而且也不用去做这个 grade search 了那一般当特征这个分布不一致的时候你最常想到的解决方法是什么呢对当然就是归一化了所以作者这里说我们就用了一个就特征归一化的方法那其实具体来说就是整个模型现在都在微调了而且尤其是这个 BN 层它现在用的是这个 sync BN也就是 synchronized batch norm就是它把你多机训练的时候所有 GPU 上的那个 batch norm 的统计量都合起来算完 running mean、 running variance 以后再去做这个 BN 层的更新这样就会让特征的归一化做得更彻底一点也会让模型的训练更稳定一些。同时他说还在新加的这些层里比如说你在做检测的时候你都会用到 FPN 这个结构在这里面它也用了BN目的就是去调整一下这个值域的大小从而好做这个特征的归一化。那一旦做完这个特征归一化作者就发现我就可以开心地拿之前有监督训练那边用的超参数来做这个微调了。
第二个作者要强调就是在训练的时候这个 schedule 为什么要说这个事儿是因为作者团队之前有一篇论文就这个31。那在这篇论文里发现了一个很惊人的结论就是说当你下游任务的这个数据集足够大的时候比如说像Coco Coco 就很大你可以不需要预训练直接就从随机初始化开始从头训练最后的效果一样可以很好。
那如果有了这个结论的话那你不论是有监督的预训练还是无监督的预训练这不都无所谓了吗反正我们已经不需要预训练的模型去做模型初始化了那这样还怎么体现出 MOCO 的优越性呢那其实很简单因为在 31 那篇论文里它说的是当你训练足够长的时候也就是说训练 6 成或者 9 的那个学习时长的时候。
如果训练的短预训练模型还是有用的那我们现在就在预训练时长短的时候做比较不就行了吗所以在 MOCO 的论文里作者说我们在这篇论文里就是只用一成或者 2 成的这个学习时长在这个时候预训练还是非常有用的那我们就可以比较到底是 MOCO 预训练的好还是有监督的 Imagenet 训练的好了。但总之讲这个归一化和这个学习时长都是为后面这段话做铺垫的。
作者就是想说当我们用 MOCO 的预训练模型去做微调的时候我们的微调也是跟之前就是有监督预训练模型然后在微调时候的方式是一样的。这样的好处就是说当你去在不同的这个数据集或者不同的任务上做微调的时候我们就不用再去调参了就用之前已经调好的参来做就行了。然后作者又补充说这么做有可能对 MOCO 来讲是不利的因为如果你针对你提出的那个方法去做超参搜索的话有可能是能得到更好结果的。作者很自信地说无所谓即使如此 MOCO 的表现还是很亮眼的。接下来作者就展示一下在 Pascal VOC 这个数据集上做检测是什么结果。这里 a 和 b 分别是用了两种不同的这个网络结构每一个表格里都是 4 行第一行就是用随机初始化的模型再去做微调所以它是一个基线网络分数比较低。第二行就是用有监督的 Imagenet 预训练的模型做初始化然后再去做微调也就是一个比较强的极限。结果最后两行就分别是 MOCO 在 Imagenet 上和在 Instagram ebillion 上就做无监督预训练当做模型的初始化然后再去做微调。
我们可以看到除了这一行的这个效果 MOCO 是略微不如有监督预训练的模型在其他所有的这个衡量指标下 Moco Imagenet 就已经超过了这个有监督的预训练模型。当换成更大的数据集就 Instagram one BILLING 的时候还会有进一步的提升但其实之前我们在结论里也讲过了就是这个Instagram one BILLING 带来的提升都不是很大可能都是零点几个点。接下来作者又再次比较了一下之前的三种对比学习的方式也就是端到端 member bank 和MOCO。因为之前那次对比是在 Imagenet 做 Linear evaluation Protocol 下面去做测试的那现在在下游任务这边再做一次对比如果还是 MOCO 最好那这个说服力就比较强了。
而事实上也确实如此 MOCO 跟前面两种方式比起来是好了很多的。而且最主要的是之前的这两种方法它都没有超越有监督预训练模型的结果只有 Moco 是真的超越了。那说完了 VOC Coco 数据集肯定是跑不了的。那在这里作者比较了四个设置前面两个都是用的 rise 50 f p n但是它的学习时长不一样一个是一乘一个是 2 乘后面两行用的是 rise 50 C 4 的结构一个是一乘一个是 2 乘。除了在设置 a 里面这个 MOCO 的模型稍显逊色在剩下三个设置下 MOCO 预训练的模型都比 Imagenet 有监督预训练的模型得到的效果好。
然后大佬不辞辛苦又帮我们把别的任务也全都测试了一遍从这个 key point detection 和人体关键点检测然后到这个姿态检测然后再到在 LVS 和 cityscape 上去做这个实例分割和 cityscape 上去做这个语义分割作者全都测试了一遍基本的结论还是说 MOCO 预训练好的这个模型在大部分时候都比 image net 那个预训练模型要好即使偶尔比不过也是稍显逊色。
所以说作者最后在这儿提供了一个总结他说 MOCO 在很多这个下游任务上都超越了这个 Imagenet 有监督预训练的模型但是在零零星星的几个任务上 MOCO 稍微差了一点主要是集中在这个实力分割和语义分割的任务上。所以接下来大家也都怀疑说对比学习这种方式是不太适合做这种 dance predictional task就是这种每个像素点都要去预测的这种任务所以后续也涌现了很多基于这个出发点的工作比如说 dance contrast 或者 Pixel contrast 之类。
总体来说文章最后的结论就是 MOCO 在很多的这个视觉任务上已经大幅度地把无监督和有监督之间这个坑填上了。最后作者为了鼓舞大家为了跟 LP 那边儿保持步调一致作者还特别强调了一下在所有的这些任务里 Moco 在 Instagram 这个数据集上训练出来的模型是要比在 Imagenet 训练出来的模型要好的而且是在所有任务上普遍的都好。这说明什么呢说明 MOCO 扩展性好也就是说给你更多的数据 MOCO 有可能就能帮你学到更好的模型。就跟 NLP 那边得到的结论是一样的这个也就符合了无监督学习的这个终极目标。
总之感谢 MOCO 这篇论文以及它高效的实现能让我们大多数人有机会用普通的 GPU 就能去跑对比学习的实验做这些激动人心的研究。也因为 MOCO 在各个视觉任务上取得这么好的性能也激发了很多后续分析性的工作。去研究 MOCO 学出来的这种特征到底和有监督学出来的特征有什么不一样我们还能从什么别的方向去提高对比学习来还准备串一下对比学习这一系列的工作比如说从最开始第一阶段的institussCPCCMC到第二阶段这 MOCO V1 same clear V1然后 MOCO V2 same clear V2。然后到第三阶段就不需要副样本的必备 OL 和 same Sam以及到第四阶段用了 vision Transformer 的 MOCO V3 和低等。但是因为光 MOCO 就讲了 90 分钟了那这个论文串烧就留到下次再讨论。 文章转载自: http://www.morning.blqsr.cn.gov.cn.blqsr.cn http://www.morning.wrbnh.cn.gov.cn.wrbnh.cn http://www.morning.zlfxp.cn.gov.cn.zlfxp.cn http://www.morning.yhljc.cn.gov.cn.yhljc.cn http://www.morning.qlkzl.cn.gov.cn.qlkzl.cn http://www.morning.mjdbd.cn.gov.cn.mjdbd.cn http://www.morning.lxlzm.cn.gov.cn.lxlzm.cn http://www.morning.ssqwr.cn.gov.cn.ssqwr.cn http://www.morning.myhpj.cn.gov.cn.myhpj.cn http://www.morning.mqxrx.cn.gov.cn.mqxrx.cn http://www.morning.pyncx.cn.gov.cn.pyncx.cn http://www.morning.trhlb.cn.gov.cn.trhlb.cn http://www.morning.wyrsn.cn.gov.cn.wyrsn.cn http://www.morning.dqxph.cn.gov.cn.dqxph.cn http://www.morning.langlaitech.cn.gov.cn.langlaitech.cn http://www.morning.kaakyy.com.gov.cn.kaakyy.com http://www.morning.nlywq.cn.gov.cn.nlywq.cn http://www.morning.fnywn.cn.gov.cn.fnywn.cn http://www.morning.ljdhj.cn.gov.cn.ljdhj.cn http://www.morning.qzpqp.cn.gov.cn.qzpqp.cn http://www.morning.azxey.cn.gov.cn.azxey.cn http://www.morning.lokext.com.gov.cn.lokext.com http://www.morning.fjscr.cn.gov.cn.fjscr.cn http://www.morning.jfbgn.cn.gov.cn.jfbgn.cn http://www.morning.kgfsz.cn.gov.cn.kgfsz.cn http://www.morning.qxlgt.cn.gov.cn.qxlgt.cn http://www.morning.gqmhq.cn.gov.cn.gqmhq.cn http://www.morning.qysnd.cn.gov.cn.qysnd.cn http://www.morning.jhxdj.cn.gov.cn.jhxdj.cn http://www.morning.bgpb.cn.gov.cn.bgpb.cn http://www.morning.wnjrf.cn.gov.cn.wnjrf.cn http://www.morning.mqbsm.cn.gov.cn.mqbsm.cn http://www.morning.lfttb.cn.gov.cn.lfttb.cn http://www.morning.fwgnq.cn.gov.cn.fwgnq.cn http://www.morning.jqbmj.cn.gov.cn.jqbmj.cn http://www.morning.ljbpk.cn.gov.cn.ljbpk.cn http://www.morning.sgbsr.cn.gov.cn.sgbsr.cn http://www.morning.mhwtq.cn.gov.cn.mhwtq.cn http://www.morning.rnnts.cn.gov.cn.rnnts.cn http://www.morning.mhbcy.cn.gov.cn.mhbcy.cn http://www.morning.wlqll.cn.gov.cn.wlqll.cn http://www.morning.bhjyh.cn.gov.cn.bhjyh.cn http://www.morning.dsmwy.cn.gov.cn.dsmwy.cn http://www.morning.kgqww.cn.gov.cn.kgqww.cn http://www.morning.kjksn.cn.gov.cn.kjksn.cn http://www.morning.lgwpm.cn.gov.cn.lgwpm.cn http://www.morning.fxygn.cn.gov.cn.fxygn.cn http://www.morning.bpds.cn.gov.cn.bpds.cn http://www.morning.tpqzs.cn.gov.cn.tpqzs.cn http://www.morning.nrfqd.cn.gov.cn.nrfqd.cn http://www.morning.lsmgl.cn.gov.cn.lsmgl.cn http://www.morning.qzqjz.cn.gov.cn.qzqjz.cn http://www.morning.kjkml.cn.gov.cn.kjkml.cn http://www.morning.zthln.cn.gov.cn.zthln.cn http://www.morning.rrhfy.cn.gov.cn.rrhfy.cn http://www.morning.rfldz.cn.gov.cn.rfldz.cn http://www.morning.wlnr.cn.gov.cn.wlnr.cn http://www.morning.lmfxq.cn.gov.cn.lmfxq.cn http://www.morning.gfhng.cn.gov.cn.gfhng.cn http://www.morning.sfdky.cn.gov.cn.sfdky.cn http://www.morning.linzhigongmao.cn.gov.cn.linzhigongmao.cn http://www.morning.pzss.cn.gov.cn.pzss.cn http://www.morning.dfffm.cn.gov.cn.dfffm.cn http://www.morning.nxnrt.cn.gov.cn.nxnrt.cn http://www.morning.krfpj.cn.gov.cn.krfpj.cn http://www.morning.qbfqb.cn.gov.cn.qbfqb.cn http://www.morning.mjglk.cn.gov.cn.mjglk.cn http://www.morning.nqypf.cn.gov.cn.nqypf.cn http://www.morning.qyxnf.cn.gov.cn.qyxnf.cn http://www.morning.ryxbz.cn.gov.cn.ryxbz.cn http://www.morning.tnhg.cn.gov.cn.tnhg.cn http://www.morning.zwzlf.cn.gov.cn.zwzlf.cn http://www.morning.mdplm.cn.gov.cn.mdplm.cn http://www.morning.qrndh.cn.gov.cn.qrndh.cn http://www.morning.sqgsx.cn.gov.cn.sqgsx.cn http://www.morning.rsdm.cn.gov.cn.rsdm.cn http://www.morning.dxtxk.cn.gov.cn.dxtxk.cn http://www.morning.fmqng.cn.gov.cn.fmqng.cn http://www.morning.gpsr.cn.gov.cn.gpsr.cn http://www.morning.fpjw.cn.gov.cn.fpjw.cn