对比学习论文综述(part3不用负样本)

对比学习论文综述(part3:不用负样本)

其实第二阶段里讲的SwAV就已经有不用负样本的对比学习这个趋势了,它可以算是一个承上启下的工作,因为它也没有用负样本,它用的是聚类中心,但它毕竟还是有一个明确的对比的对象

接下来要讲的BYOLSimSiam其实就是正样本自己在玩,已经没有负样本或者聚类中心这样明确的一个对比的东西去做对比了

Boostrap Your Own Latent:A New approach to Self-Supervised Learning

BYOL其实就是这句话的头几个字母

  • Bootstrap就是说如果已经有什么东西了,然后在它之上进行改造

  • latent就是特征的意思(latent、hidden、feature、embedding其实都是特征的意思,就是各种花里胡哨的用法而已)

BYOL 的意思就是自己跟自己学,左脚踩右脚就上天了,所以说是一篇很有意思的论文

为什么作者很有自信说是a new approach to self supervised learning,因为它完全没有用任何形式的负样本

为什么不用负样本就这么新奇、这么吸引人注意?

  • 因为在对比学习中,负样本是一个约束,如果在算目标函数的时候只有正样本,其实目的就只有一个,那就是让所有相似的物体的特征也尽可能的相似,那这个时候就有一个很明显的捷径:如果一个模型不论给它什么输入,它都返回同样的输出,这样的话,它出来的所有的特征都是一模一样的,那拿这个去算对比学习的loss就都是零,意思就是模型直接就躺平了,它直接用这个捷径解就能完美解决问题loss永远是0模型根本都不用学

  • 只有加上负样本这个约束,就是说不光相似的物体要有相似的特征,然后不相似的物体也要有不相似的特征。这样模型才有动力去继续学,因为如果输出的所有特征都一样,那负样本的loss就无穷大,所以它必须想办法让正样本和负样本的loss都往下降,达到一个最优解

  • 所以说,负样本在对比学习里是个必须的东西,它能防止模型学到捷径,很多论文里也管这个叫model collapse或者learning collapse ,就是模型坍塌或者学习坍塌,说白了就是什么也没学到,负样本就是为了限制这种情况的发生

  • 但BYOL之所以神奇就是它没有用负样本,正样本自己跟自己学最后在ImageNet上也达到了74.3的top-1准确率,也是相当高了

  • 因为BYOL是20年6月份出来的,跟SwAV是同期的工作,所以它不用跟SwAV去比,那在这之前74.3就是最高的

BYOL为什么能够做到不需要负样本?

下图图 2是模型总览图

在这里插入图片描述

                                                        <u>模型总览图</u>

BYOL的前向过程:

  • 一个mini-batch的输入x经过两次数据增强以后,就得到了v和v’,然后图片通过编码器得到特征

  • 上面这一支通过的编码器叫fθ,下面这个通过的编码器呢叫fε,两个编码器使用是同样的网络架构,但是它们的参数不同

  • fθ是随着梯度更新而更新的,而这个fε跟MoCo一样是用moving average的形式去更新的,其实就是使用了动量编码器

  • 这里得到的特征,如果是res 50的话就是2048维的一个特征

  • 接下来跟SimCLR一样用了一个projection head,这里叫 projector,就是通过gθ这个函数得到zθ的特征,zθ在这里是256维,比之前的128大了一点,发现这个效果好一点

  • 同样地,gε其实跟gθ是一样的网络结构,但是参数不一样,也是通过动量的方式去更新的

  • 之前对比学习的方法,当得到这两个特征zθ和zε以后,就像SimCLR一样需要让它们尽可能接近,需要达到maximum agreement,但是BYOL没有这么做,它又加了新一层的一个叫predictor的东西qθ,qθ跟gθ的网络结构是完全一样的,也是一个mlp,然后就得到了一个新的特征q(zθ),为了让这个预测跟下面的zε尽可能一致,就把原来的匹配问题换成了现在的预测问题

  • 这个跟SwAV也有点像,因为SwAV也是把配对问题换成了预测问题,但是SwAV还是借助了一个聚类中心来帮助做这个预测任务的,但是BYOL真的是什么都没有,就是自己去预测自己,然后这个模型就学起来了

  • sg就是stop gradient,这里是没有梯度的,跟MoCo就很像,上面一支相当于是个query编码器,下面一支相当于是key的编码器,key的编码器都是query编码器的动量更新,但不一样的是它的代理任务不一样,它相当于是用自己一个视角的特征去预测另外一个视角的特征,通过这种预测型的任务完成模型的训练

这就是 BYOL 的训练过程,看起来相当简单,而且作者说跟别的工作一样,当训练完成以后只有这个编码器留下了,剩下所有的东西都被拿掉了,最后yθ,也就是这个2048维的特征去做下游任务

它训练网络的时候用的目标函数直接用的是mean square error(mse los)

  • 因为现在是两个向量,一个是预测的qθ(zθ),一个是target zε,现在是想让它们尽可能的接近,所以算一个mse loss就可以了

  • 这个跟之前对比学习用的那些目标函数全都不一样,所以说BYOL虽然看起来有SimCLR的影子,也有MoCo的影子,比如说SimCLR的projection head、MoCo的动量编码器,但是它用的目标函数不一样,而且也没有用负样本,就用这种自己预测自己的方式学到了很好的特征表示

  • 所以说在它放到arxiv之后,reddit、twitter、知乎全都引起了剧烈的讨论,因为大家都觉得很不可思议,不用负样本,模型的学习怎么能不坍塌,其实作者也觉得很神奇,所以它后面也提供了一些解释,但是它的解释比较中规中矩没有什么意思

我们来看一个有意思的博客

understanding self-supervised and contrasive learning with “Boostrap Your Own Latent”(BYOL)

“如何去理解 BYOL”

这篇博客的作者其实也是看到BYOL之后觉得非常有意思,所以就尝试复现了一下,结果在复现的时候遗漏了一个小细节,从而导致它的模型训练不动,出现了这个模型坍塌的现象

作者觉得毕竟这是在 DeepMind 的工作,可信度还是非常高的,应该不是论文的问题,肯定是它们自己复现的问题,所以自己就去仔细检查了

检查结果发现确实是遗漏了一个很小的细节,这个细节跟batch norm有关

在讲这个发现之前,先来看一下batch norm带来了什么麻烦,因为之前没有好好说projection head 里面具体的结构,所以先来复习一下

下图所示是SimCLR的结构图

在这里插入图片描述

                                                           *SimCLR结构图*

SimCLR就是说一个图片进了编码器以后就得到了这个embedding,就是特征y(2048 维),然后把它扔给gθ,就是一个projection head,也就是图中右侧的mlp

  • 这个mlp由一个全连接层、一个batch norm、一个ReLU 激活函数、一个全连接层、一个batch norm的结构组成

  • 第一个全连接层的维度是2048*2048

  • 第二个全连接层的维度是2048*128,就把维度降下去了,这个128的特征就是最后用来做对比学习的特征

  • 注意:这里面有两个batch norm 操作

接下来再看一下MoCo v2(MoCo v1没有用projection head),MoCo v2的模型结构如下图所示

在这里插入图片描述

                                            *MoCo v2结构图*

MoCo v2确实是用了projection head,就是gθ,但是它的 gθ 里面是没有batch norm的,就是直接全连接层、ReLU然后又全连接层

第一个全连接层还是2048×2048

第二个全连接层还是2048×128

再来看BYOL,模型结构如下图所示

在这里插入图片描述

                                                       *BYOL结构图* 
  • gθ、gε都是projection head、qθ也是prediction head

  • 这三个东西用的都是同样的结构,如图右侧紫色的mlp结构所示,这个结构里面是全连接层+batch norm+ReLU+全连接层 ,第二个全连接层后面没有 batch norm,但是第一个后面是有 batch norm

  • 也就是因为这点小小的差别造成了这个发现

  • 为什么呢?因为像MoCo v2的代码写的实在是太好了,而且又是基于 pytorch ,所以这篇博客的作者就是借鉴MoCo v2来复现的 BYOL ,但是因为MoCo v2里projection head没有batch norm,所以他们在复现BYOL的时候,这里也没有用batch norm,所以它的mlp就是全连接层+relu+全连接层,然后模型的学习就坍塌了。

然后这篇博客的作者就觉得实在是太奇怪了,所以赶紧又做了一些额外的实验,如下表所示

在这里插入图片描述

  • 实验结果
    第二列指的是projector里到底用不用batch norm,还是是用别的归一化方式

  • 第三列指的是prediction里到底用不用batch norm,还是是用别的归一化方式

  • 目标函数:对于对比学习的方式来说用的是交叉熵函数,对于 BYOL 来说都用的是 L2,也就是MSE loss

  • performance性能其实是在一个STL-10的数据集上做的,不是 ImageNet,但是衡量标准还是准确度

上表做了哪些实验

  • 最后一行random是说有一个随机初始化的残差网络,然后拿这个残差网络去抽特征,然后在这个特征上训练一个全连接层,最后的结果是28.8,这个就是随机结果,就是根本没有学习的结果

  • 第二行表示如果做的是正确的 BYOL,就是说在projection head和prediction head 里头都用了batch norm ,最后的结果是57.7,这个就是最高,也就是正确的结果

  • 但其实刚开始做的实验做的是倒数第三行(no normalization),就是没有归一化,既没有在projection head的里头用batch norm ,也没有在predictor用batch norm ,最后的结果只有28.3,跟随机的结果一模一样,也就是说模型坍塌了什么都没有学到

  • 然后作者就尝试了几种变体,做了消融实验:要么在projection head里用batch norm ,不在prediction里用,要么就是在projection里不用,在prediction里用,最后发现,只要哪块放一个batch norm,最后的结果就还行,就算48有点低,但至少说明模型在学习没有坍塌

  • 作者这时候就强烈怀疑,肯定是batch norm惹的事了,正常的想法很自然,下一步就说换一个归一化式行不行,就换成layer norm,作者就在projection head和prediction head里面都用了layer norm,然后发现性能确实就又掉下去了,又变成29.4,就跟随机一样了,也就是说模型又坍塌了,又什么都没学到

所以,作者最后总结说BYOL训练的时候不坍塌,肯定是跟batch norm有一点关系

那有什么关系呢?

  • 作者说现在有一个简单的结论:batch norm这个操作是把一个batch里所有样本的特征拿过来算一下它们的均值方差,也就是running mean /running variance,然后用整个batch算来的均值和方差做归一化,这也就意味着,当在算某个正样本的loss时,其实也看到了其它样本的特征,也就是说这里面是有信息泄露的,MoCo里有一个操作叫做 Shuffling BN ,也就是为了防止这种信息泄露的,博客的作者就说,因为有这种信息泄漏的存在,所以可以把这个batch里的其它样本想成是一种隐式的负样本

  • 换句话说,当有了batch norm的时候,BYOL其实并不光是正样本在自己跟自己学,它其实也在做对比,它做的对比任务就是说当前的正样本这个图片跟平均图片有什么差别,而这个平均图片就是batch norm产生的,还有之前很多图片的总结量,这就跟SwAV很像了,因为 SwAV 就是没有跟负样本去比,而是找了个聚类中心去比,而这里batch norm生成的平均图片,其实就相当是一种聚类中心的意思,也就这篇作者说的mode(众数),就是中值的意思

  • 所以说,这篇博客的作者认为batch norm是BYOL能够成功的关键,其实是做了一种隐式的对比学习,这个观点很快就被大家所接受了,因为听起来确实很合理,而且它后面做了很多实验,也全都验证了它的观点,batch norm确实至关重要,拿掉batch norm以后模型就是不好训练,对超参数的设置非常的敏感,稍有不慎它就啥也不学了

但是BYOL的作者看到这个以后就急了就觉得说如果真是这样的话,如果真的要用这种方式去解释的话,BYOL的创新性就大大降低了,因为它还是没有逃脱出对比学习的范畴,它还是找了一个东西去做对比,所以赶紧做实验看看能不能找到另外一种解释,为什么BYOL 能够不模型坍塌

BYOL的作者很快就找到了另外一种方式去解释这个现象,迅速写了一篇论文(BYOL works even without batch statistics)来做回应,它的题目上来就说BYOL即使在没有batch norm的时候照样能工作,而且它甚至把这个even斜体了,真的就是用来回应上面提到的那篇博客。因为BYOL 的作者不想让大家觉得BYOL 的成功是依赖于 batch norm,然后BYOL 的作者做了一系列非常详细的实验看看问题到底出在哪,实验结果如下表所示

在这里插入图片描述

实验结果
这个实验就是说在encoder编码器,就是Res50里到底用batch norm、layer norm,还是什么都不用,还有在projector里到底用batch norm、layer norm,还是什么都不用,或者说在predictor里到底用batch norm、layer norm,还是什么都不用

虽然就这么一个小小的表格,但其实里面的跑的实验是相当多的,做了一个非常完整的消融实验,而且这里还和SimCLR去比了,因为其实BYOL就是基于SimCLR做的,它跟SimCLR非常像

作者发现了几个现象

batch norm确实是比较关键,因为只要是没有batch norm的地方,SimCLR都工作的很好,可能有一些性能下降,但是都还在学,BYOL全都没有再学了,模型坍塌了

通过这个完整的消融实验,作者还发现了几个特例,正是这些特例帮助作者找到了另外一个可以解释的理由:

  • 即使当projector有 bn的时候,BYOL 还是训练失败了,这个就不能解释batch norm很关键了,因为如果batch norm真的很关键,如果真的能在这个隐式负样本提供对比学习的话,训练就不应该失败

  • 还有就是当编码器和project都没有用batch norm的时候,SimCLR也失败了,因为SimCLR没有predictor,所以说这里predictor就无所谓了,意思就是说当什么归一化都不用的时候,不光是BYOL,SimCLR 也不行,它即使用了负样本也训练不出来,所以这就再次证明了,batch norm不是提供了一个隐式的负样本,因为这里即使给它显式的负样本了,它还是训练不出来

  • 所以这时BYOL 的作者和原来博客的作者后来就达成了一个比较一致的结论,就是说batch norm跟它原来的设计初衷一样,它主要的作用就是能帮助这个模型稳定训练,它能提高模型的训练稳健性,从而不会导致模型坍塌,BYOL的作者又把这个结论进一步延伸,然后给出来了一个可以解释的理由,如果一开始就能让模型初始化的比较好,后面的训练即使离开了batch norm也没有问题

于是作者就做了另外一个实验,就是用group norm和weight standardization,group norm就是一种归一化的方式,而weight standardization就是一种模型初始化的方式,这一套方法其实是vit的原班作者在他们之前的论文 BEiT 里提出来了,也就是现在很多人说的ResNet v2就是用这种方式做训练,然后换上这种初始化方式以后,BYOL 的作者发现又能训练74左右的top-1准确率了,跟原来论文里用batch norm的那个74.3的结果非常接近

所以作者最后再次强调说group norm或者weight standardization都没有计算批统计量,所以说这个版本的 BYOL,也就是说这个73.9的 BYOL 是没有跟mini batch里其它的样本做对比的,意思就是说没有隐式的对比,也就意味着说BYOL 还是一个全新的方式,它就是很厉害,就是能自己跟自己学,模型就能学的很好,不需要这种假设batch norm提供的一个隐式的这个对比学习的项,就是说大家不要被那篇博客带跑偏了,赶紧来follow BYOL这个套路,这个套路没问题,别再去管负样本的事了

其实这篇论文也只有4页,因为它就是用来回应那个博客,也没想着说真的发论文,目的达到了就行

接下来就是SimSiam论文 Exploring Simple Siamese Representation Learning

就是simple Siamese network,其实在BYOL放到 arxiv 上之后,就已经有很多研究者在做对对比学习的分析性工作了,因为大家发现,对比学习的成功好像是被很多很小的点堆起来的性能,比如说我们一路走来可以看到用了新的projection head、训练的时间更长、用了更多的数据增强或者用动量编码器、用更大的 batch size,总之好像都缺一不可,对比学习的性能好像是一点一点被这么堆上去的

这样就不是很好,不方便分析,因为有太多点了,所以不知道从哪分析起,也不知道每个点到底带来了哪些贡献,所以凯明团队又再次出手,把整个过程化繁为简了一下,最后提出了SimSiam

这个结构有多简单,就是说不需要用负样本(因为它基本上是跟 BYOL是非常像的,所以说它不需要负样本)、不需要大的batch size,不需要动量编码器,然后即使在这种情况下,这个SimSiam不仅不模型坍塌

而且还能取得很好的结果

具体的模型总览图如下图所示

在这里插入图片描述

                                                 *SimSiam模型总览图*

之所以叫siamese network(孪生网络)是因为一般会有两个编码器,这两个编码器一般网络结构是一样的,而且一般是要共享参数的,所以才叫孪生网络

整体架构是跟BYOL 非常一样的:一个图片变成 x1、x2,然后经过过两个编码器,有一个predictor,其实predictor出来的就是要去预测另外一个编码器出来的特征

这里跟BYOL唯一的不一样就是它没有用动量编码器

如果我们简单看一下伪代码,如下图所示,就会发现是真的简单,整个前向过程其实就这么几行

在这里插入图片描述

  •                                                 *SimSiam伪代码*
    

    D函数就是怎么去算loss,算的是一个 negative cosine similarities loss,说白了就是一个MSE losss

  • 至于前向过程也跟上图中的一样,得到两个视角x1、x2以后,先过编码器去得到特征z1、z2,然后再通过predictor得到p1、p2的预测,因为有两个预测,所以这里也是一个对称性的loss,就是说,既可以做从p1预测z2,也可以做用p2预测z1的任务,但因为加了两次,所以说这里也要除以2

  • l就是最后的loss

  • 梯度回传更新网络

作者还做了很多实验,比如说batch size对模型训练的影响、还有 batch norm对模型训练的影响,而这些都跟BYOL非常像,这里就不一一展开了,最后作者得到一个结论:之所以SimSiam能够成功训练,不会有模型坍塌,主要是因为有stop gradient这个操作的存在

作者还提出了一个假设,而且在第五节里做了一个 hypothesis:因为有了stop gradient这个操作的存在,所以SimSiam这个结构是可以把它想象成一个EM(期望最大算法),EM 算法真是无所不在,感觉很多事情最后都可以归结到 EM 算法去解释,都有点量子力学那个意思

这里作者的意思是说因为有了stop gradient这个操作之后,这一个训练过程或者说这一套模型参数其实就被人为劈成了两份,就相当于在解决两个子问题一样,模型的更新其实也是在交替进行的,作者接下来又做了一些推导,写的非常好,推荐大家可以去看一下,其实到最后应该可以把它理解成是一个k-means这个聚类问题

k-means其实就是分两步走的,每次先要把所有的点分配给一些聚类中心,一旦分配好了以后,再去更新这个聚类中心,然后再周而复始地去做这个操作

从这个角度来说SimSiam又跟SwAV有点关系了,于是作者其实在最后还画了这么一张图如下图所示,这张图真的画的非常好,它把所有孪生网络的做法都归纳到在这里,然后做一下总结和对比

在这里插入图片描述

  • SimCLR:SimCLR因为是端到端的学习,所以说两边都有梯度回传,但是它还是做的一个对比任务

  • SwAV:做的也是一个对比任务,但它并没有跟负样本去比,而是跟聚类中心去比的,那聚类中心是通过SK算法得到的

  • BYOL:BYOL就有一个新的贡献(就是predictor,图中已经单独画出来了),它就不是一个对比任务,变成一个预测任务了,要用左边去预测右边,同时还使用了动量编码器

  • SimSiam: 整体跟BYOL非常像,左边其实就是一模一样,只不过右边没有用动量编码器,所以这个对比还是比较简洁明了的

最后再看一下结果如下表所示,之前BYOL也没有看结果,鉴于SimSiam是一个总结性的工作,它跟之前里程碑式的工作都有对比,所以看这个表格就足够了

  • 在 ImageNet 上linear classification的结果:这里比较的都是重量级工作,比如SimCLR、MoCo v2、BYOL

  • 从batch size来说,只有MoCo v2和SimSiam是可以用256的,其它工作都要用更大的batch size,所以说凯明大佬的工作真的是好follow

  • 前两项工作SimCLR和MoCo v2要用负样本,但是对于BYOL来说就完全没有用,SwAV用的是聚类中心

  • 对于动量编码器来说,SimCLR没有用,SimCLR v2用了,但是v1没有用,MoCo v2和 BYOL用了,SwAV没有用

总的来说,SimSiam就是这些都没有用

看结果的话发现在训练100个epochs的时候,SimSiam的结果是最好的,所以说明它学的非常快,但是随着训练的推进慢慢就不行了,涨幅比较慢,到最后也是有71.3,但是这个时候BYOL已经有74.3这么高了(其实我之前也有做过很多实验,发现动量编码器真的是很好用,也非常能提点的一个东西,所以可能这也是为什么BYOL能够训练的这么好)

当然作者在SimSiam这篇论文里,它只是想说把这些trick全拿掉照样能训练,所以说它没有用动量编码器

再来看SwAV,SwAV只有71.8,这个应该是没有用multi crop的技术,所以这就跟之前讲SwAV的时候说的一样,就是如果不用multi crop,SwAV 就跟MoCo v2差不多,还不如MoCo v2,所以说只从分类来说,最强的方法就是BYOL

下游任务如下表所示

在这里插入图片描述

下游任务对比
前面几个做的是物体检测,最后做的是一个实例分割,就是cv人必做的两个下游任务

这里可以看到有一个比较有趣的现象,就是说针对下游任务的transfer来说,MoCo v2和SimSiam其实是表现最好的,BYOL和SwAV也不错,但是跟MoCo v2和SimSiam比还都差了一到两个点,差距还是比较明显,所以说直到现在,如果想去尝试一些idea,或者说尝试去做一些对比学习的工作时,还是会用MoCo v2当基线模型,因为真的是训练快、训练的稳,而且下游任务迁移的好

当然还有一篇论文叫Barlow Twins,是Yann LeCun组的一篇论文,因为宣传的很厉害,所以说很多人也都知道,那篇论文就是把目标函数给换掉了,它既不是在做对比也不是在做预测,它是生成了一个关联矩阵叫 cross correlation matrix,然后它希望这个矩阵能跟一个identity matrix(就是对角线是1,其它部分都是0的矩阵)尽量相似,其实说白了也是一样的意思,就是它希望正样本相似性尽量都逼近于1,然后跟别的样本尽量的不相似,相似性尽可能是0,所以说就是换了个目标函数,其它的网络结构、训练方式都大同小异,而且他们放arxiv的时间也比较晚,已经是 21年的3月份了,这个时候对于 cv 来说,早都已经是Vision Transformer的时代了,所以很快呢就被淹没了

所以第四阶段就讲讲Transformer是怎么和对比学习有机的结合起来的。
atrix,然后它希望这个矩阵能跟一个identity matrix(就是对角线是1,其它部分都是0的矩阵)尽量相似,其实说白了也是一样的意思,就是它希望正样本相似性尽量都逼近于1,然后跟别的样本尽量的不相似,相似性尽可能是0,所以说就是换了个目标函数,其它的网络结构、训练方式都大同小异,而且他们放arxiv的时间也比较晚,已经是 21年的3月份了,这个时候对于 cv 来说,早都已经是Vision Transformer的时代了,所以很快呢就被淹没了

所以第四阶段就讲讲Transformer是怎么和对比学习有机的结合起来的。

猜你喜欢

转载自blog.csdn.net/qq_45807235/article/details/128294509