⾃监督学习算法分为两种: 生成式自监督学习与对比式自监督学习:

  • 生成式:训练编码器将输入x编码成显式向量z,解码器从z重建x,最小化重建误差;

  • 对比式:编码器将输入x编码成显式向量z以度量相似性(例如互信息最大化)。(对⽐学习要做的就是学习⼀个编码器f,这个编码器f能够拉近x与其正样本间的距离,推远x与其负样本之间的距离。)

代理任务

自监督学习有一个非常强的动机:目前,大部分神经网络的训练仍然使用的是有监督范式,需要耗费大量的标注数据,标注这些数据是非常耗时费力的。而自监督的提出就是为了打破对人工标注的依赖,即使在没有标注数据的情况下,也可以高效地训练网络。众所周知,神经网络的训练需要任务来进行驱动,所以自监督学习的核心就是来合理构造有利于模型学习的任务。目前来说构造这些任务的方法大致可以划分为三个方面:

  1. 基于 pretext task ( 代理任务 ):是为了学习图片的语义信息

  2. 基于 contrastive learning ( 对比学习 )

  3. 基于 mask image modeling ( 掩码图像模型 )

1.图像相对位置预测

Context 信息蕴含着大量的监督信息, 目前自然语言处理大量使用这样的监督信息来完成大规模的自监督训练。无独有偶,视觉领域也可以利用图片的 context 信息来完成自监督训练。作者从一张图片中随机抽取两个 patches,然后让模型来预测一个 patch 相对于另外一个 patch 的位置。作者认为: 模型只有很好地理解到图片中的各种场景,物体,以及各部分之间的相互关系,模型才能够很好地完成这个相对位置预测任务。
image-1689038004680

2.图片着色

主要通过构造一个图片着色任务来让模型学习图片的语义信息。因为作者认为: 只有很好地理解到了各种场景的独立的语义信息,以及他们之间的联系,模型才能够很好完成这项任务。
image-1689038039446

3.上下文编码

与上面讲到的颜色重建 类似,Context Encoders 也是通过设计重建原图来使模型学习到图片的语义信息。但是与 Colorization 不同,Context Encoders 是从空间维度对图片进行重建,而 Colorization 是从图片的通道维度进行重建。作者认为:模型只有很好地理解到整张图片的语义信息,才能够很好地完成这个重建任务。
image-1689038110389

4.旋转预测

作者希望通过让模型去识别图片的旋转角度,让模型具有理解图片语义信息的能力。为了完成这个任务,作者认为:模型只有很好地识别并提取图片中的主要物体,并理解其和图片中其他景物的语义信息,才能够完成这个旋转角度识别任务。其具体操作如下:
image-1689038156553

对比学习

MoCo

image-1688607427924

  • 端到端模式(a)-InvaSpread
    image-1688607907415
    q和k都能同时更新,但是缺点就是样本量只有batchsize的大小,
    该模式存在的一个问题,就是负样本的数量受到batch size大小的限制,在没有庞大GPU集群的支持下,负样本的数量是不会特别多的。
    因此,接下来有了 Memory bank 来解决这个问题。

  • memory bank模式(b) -InstDisc
    image-1688607920414
    将所有的样本特征抽取出来放在memory bank中,,然后每个负样本都是从memory bank中随机抽取,这样一下子就可以取很多负样本了,不会对GPU造成很大负担(因为feature相比于每张图片的大小来说,是很小的)。
    缺点:每次更新时,q的值会随着队列的不同而变化 ,从而导致更新后的q,对于一整个数据中的k产生不一致的差别。

  • 动量编码器(c)-MoCo
    image-1688609107290
    MoCo与Memory Bank的区别就是新feature k1的获取不是通过encoder q,而是通过encoder q参数的历史组合得到(动量编码器),Momentum encoder和encoder q的网络结构完全相同,仅是参数不一样.。Momentum 参数的具体更新公式为 :
    image-1688608184406
    m的值会设置的很接近1,比如0.999,这样k的值主要取决与上一次的k,队列的影响很小

总结一下MoCo的两个主要创新点:
其一: dictionary队列化,把dictionary整成长度为K的队列,每次计算loss时就用K个负样本,然后将当前batch得到的特征 k(瞅好了,是k,不是q,k配合着创新二可以让key保持一致性) 入队,队头的batch出队,维持长度为K。
其二: Momentum update,因为dictionary的key来自于不同的mini-batch,通过这种方式缓慢更新(slowly progressing)key的encoder,使得key的特征保持一致性(解决了传统 Memory bank 的痛点)。实验发现,适当增加m会带来更好地效果,因此本文 m=0.999,也印证了缓慢更新key的encoder是使用队列dictionary的核心(如果更新太快的话,你想想,第一代encoder和第1000代的encoder的差距就会很大)。

SimCLR

image-1688610521921
假如有一个minibatch的图片,对整个minibatch的所有图片做数据增强,对图片 x 做不同的数据增强就会得到 xi 和 xj 。同一个图片延申得到的两个图片就是正样本,比如batchsize是n的话,那么正样本就是n,这个batchsize剩下的所有的样本以及其经过数据增强后得到的都是负样本,也就是2(n-1)。有了正负样本之后,对其进行编码,通过一个编码器 f() 得到正负样本的编码结果 hi 。simCLR的创新点就是在得到数据的编码之后在后面加了一个编码层 g() 投影函数,就是一个MLP层,得到较低维度的特征 zi 和 zj ,用其进行对比学习,拉近正例之间的距离,拉远负例之间的距离。但是需要注意的一点就是投影函数(g())仅仅在训练的时候才使用,在测试的时候是不使用的,测试的时候仅仅使用编码器 f() 。加上投影函数的目的也仅仅是想让模型训练的更好(这里解释一下,为什么测试的时候不用投影函数。训练时用投影函数的目的是使得训练更好,因为加上了一个投影层,必然将投影到更好地结果,训练时会取得更好地效果。在实际使用时,我们需要微调这一步,微调往往是MLP,因此不需要最后一个投影层了,微调的MLP其实本来就可以当做投影层)。

SWaV

以往的基于对比学习的方法都是将一个实例 x 通过两次数据增强变为 x1 和 x2 ,之后利用编码器对其进行编码,从而得到嵌入向量 z1 和 z2 ,之后使用对比学习的loss更新这个encoder。
  即使以往的工作是非常有效并且简洁的,但是负样本太多了,造成资源的浪费,即使是MOCO这样用近似的方式用6w个负样本,但是总共还是有128w个负样本的(以ImageNet为例)。所以SwAV的作者去想,可不可以使用先验信息,不去和大量的负样本对比,而是和一些更加简洁的东西去比呢? 所以SwAV的作者想,可以和聚类的中心进行对比,这个聚类中心就是 C ,维度是3000×向量维度,3000表示聚类中心的数量(这就是先验知识,可以通过一些方法使用K-means来求)。
image-1688613418205

SwAV的优势在于:

如果是和负例进行对比的话,需要和成千上万个负例进行对比,即使是MOCO中6w个负例,也只是一个近似的值,但是聚类的话,就仅仅需要和三千个聚类核心即可。 此外,这些聚类中心是有含义的,而如果像之前一样用负样本进行对比学习的话,有的负样本不均衡,有的还可能是正样本被错判为负样本,因此不如聚类中心有效。
第二个贡献就是multi-crop的思想, 以往的对比学习方法都是在一张256×256的图片上用两个224×224的crop求两个正样本,但是因为crop过大了,所选取的crop都是基于全局特征的。但是可能很多局部特征才是非常有价值的,SwAV使用了一种multi-crop的思路进行操作,即选择了两个160×160的crop去搞定全局特征,选择四个96×96的crop去搞定局部特征。这样在计算量变化不大的情况下,可以获取更多的正样本。

BYOL

image-1688612513577
之前使用负样本的学习方法相当于给模型提供一个约束。如果模型的输入只有正样本,那么模型需要让正样本之间的距离尽量的缩小,那么模型可能会想到一个捷径从而很好的解决这个问题,就是模型直接对所有样本的数据都是一致的,这样所有正样本之间的距离无限接近,但是模型这样躺平是学习不到实例的特征的,是无效的。 因此添加了负样本对模型造成一个约束,就是让正样本之间的距离接近,让负样本之间的距离拉远,这样可以对模型进行约束,不让模型躺平,所以负样本在模型中是一个必须的东西,可以防止模型躺平,防止模型学到捷径解。但是BYOL的神奇之处在于模型没有使用负样本,仅仅是模型自己和自己去学,但是也实现了很不错的效果。

让我们看看BYOL的前向过程,一个实例 X 经过两次数据增强得到 V 和 V hat,之后经过两个编码器 F1 和 F2 ,得到两个嵌入向量 y0 和 y1 ,其中两个编码器的模型架构一样,但是参数并不相同, y0 通过动量更新,而不是反向传播更新。得到的两个向量再经过两个投影层 g0 和 g1 ,同样的两个投影层也是架构一样,但是参数不一致,前者是通过梯度下降进行更新,后者是通过动量更新,得到两个嵌入向量 z0 和 z1 。之后将 z0 输入到一个预测层 q0 中,得到 q0(z0) ,让 q0(z0) 和 z0 无限接近,使用mean squared error进行参数更新,利用正样本对正样本的预测,实现模型的学习。其中表达层是用ResNet,projection和prediction层都是用MLP。

Siamese

  • 不需要大的batchsize
  • 不需要负样本
  • 不需要动量编码器
    有许多工作像是将参数、Memory bank、动量、预测层、projection层累加,然后一点点提升性能,但是不具有通用性,到底哪一种最好呢,如果我不用这些tricks能不能训练成功呢?于是何凯明团队又来拯救世界了。
      Siamese不需要用负样本,不需要大的batchsize,不需要动量编码器,即使在这种条件下,Siamese不仅没有模型谈谈,反而取得了很好的模型效果。
    image-1688612689798
    对比了不同的基于孪生网络的学习例子。SimCLR使用的是端到端的训练,两个encoder,SwAV是和聚类中心进行对比的,BYOL是一个预测任务,其使用的是动量编码器,SimSiam也是预测任务,但是使用的是stop gradiant的方式进行预测的(SmSiam与BYOL相比,主要是将动量编码器换成了普通编码器,也是不需要负样本学习)。
    image-1688613289260

DINO

image-1688612722922

这个和BOYL是有点像的,也是一个预测问题。为了避免模型坍塌,其在teacher中使用了一个centering操作,即对batch求均值,之后让batch中的所有实例减去这个均值,对batch中的样本求归一化的操作。