对比学习的里程碑式工作,简单好用强大
如果把机器学习比作一块蛋糕,那强化学习是上面的小樱桃,有监督学习是糖霜,自监督或者无监督学习才是本质
对比学习只需要学到同类别图片的特征就行了。就是说有两张增强后的人类图片,一张狗的图片,模型只需要学习到两张人类是一类的,跟狗不一样就行了。
surrogate task 代理任务涉及,认为定义一些规则,定义那些图片是相似哪些不是,从而产生监督信号去训练模型。
只要能找到怎么定义正样本和负样本,剩下就是同样的结构了,
摘要
把对比学习砍成一个字典查询的任务。动态字典两部分组成,一个是队列,一个是移动平均的编码器,让字典里特征尽可能一致。
Moco学到的特征能够很好迁移到下游任务。(最大的卖点)
引入
图片x1经过T1得到anchor x11,经过编码器得到特征f11,另一个经过T2变换得到x12 positive,经过编码器E12得到f12
其他x2,x3-xn都被称为negative 负样本
为什么能看成是字典查询的任务呢,因为f11好比query, f12,f2,f3-fn好比key,我希望查询Q尽可能跟f12key相似,跟其他远离
1 字典必须要大(表示的特征信息越丰富),2 特征要保持一致性(字典的key应该用相同或者相似的编码器得到)
训练过程要处理问题1,解决办法是用minibatch,每次只取队列头部一小部分数据更新,然后取出,再从尾部push进新的数据
无监督最重要的是预训练后能够迁移到下游的任务
Moco可以接受大规模图片集合,提升效果
相关工作
自监督学习可以从接下来两种方面入手
损失函数:对抗性目标函数和对比性目标函数
代理任务:生成一个自监督的信号,充当真实标签
方法
对比学习vs 字典查询
正样本q和 key相似loss低,和负样本形式loss高
noise contrastive estimation NCE: 只考虑数据样本和噪声样本,把超级多分类的问题转变为二分类问题,从而更好使用softmax操作
InfoNCE,对比学习中底下的K和指的是负样本的数量
Momentum Constrast
字典当成队列:
字典比minbatch大很多,先进先出,移出batch是最早计算的key(过时)
动量更新:
key编码器没办法通过梯度回传更新(没法对整个队列进行梯度回传,每个iteration只对一个mini-batch的负样本计算key,队列里其他的key都是过去之前时刻编码器计算的值,当然不能整个队列都梯度回传。)
使用端到端的学习,参数可以实时更新,但因为字典的大小,无法塞下
memory bank:一个特征只有128维, 在特征一致性上处理不是很好,但是方便存储特征
只要一个编码器,query插入一个编码器;在key上使用动量编码器
moco简单又高效,字典的设计也能存放很多特征
proximal optimization: 使得训练过程更平滑
# f_q, f_k: encoder networks for query and key
# queue: dictionary as a queue of K keys (CxK)
# m: momentum
# t: temperature
f_k.params = f_q.params # initialize
for x in loader:
# load a minibatch x with N samples
x_q = aug(x) # a randomly augmented version
x_k = aug(x) # another randomly augmented version
q = f_q.forward(x_q) # queries: NxC
k = f_k.forward(x_k) # keys: NxC
k = k.detach() # no gradient to keys
# positive logits: Nx1
l_pos = bmm(q.view(N, 1, C), k.view(N, C, 1))
# negative logits: NxK
l_neg = mm(q.view(N, C), queue.view(C, K))
# logits: Nx(1+K)
logits = cat((l_pos, l_neg), dim=1)
# contrastive loss, Eqn. (1)
labels = zeros(N) # positives are the 0-th
loss = CrossEntropyLoss(logits / t, labels)
# SGD update: query network
loss.backward()
update(f_q.params)
# momentum update: key network
f_k.params = m * f_k.params + (1 - m) * f_q.params
# update dictionary
enqueue(queue, k) # enqueue the current minibatch
dequeue(queue) # dequeue the earliest minibatch
没有使用BN层,因为害怕runningmean和runningvar会被模型捕获出关系从而破坏了一致性
科普
Instance Discrimination 是一种用于无监督学习中的对比学习(Contrastive Learning)的核心方法,旨在区分不同的样本个体(实例)并对其进行有效表示。在这种方法中,每个样本(图像或数据)都被视为一个独特的类,即每个样本都是自己的类别,模型的任务是通过最大化不同实例之间的差异,使得模型能够学习到更好的数据表示。
关键概念:
每个实例都是唯一的:在Instance Discrimination中,每个输入样本(例如图像)都被视为一个独特的类。模型的目标是区分不同的实例,即最大化不同实例之间的差异,同时最小化同一实例的变体(如图像增强、旋转等)之间的差异。
对比学习的使用:对比学习通过构建正样本和负样本对来学习表示。在 Instance Discrimination 中,一个正样本是从同一个实例生成的增强样本,而负样本则来自其他不同的实例。
无监督学习:Instance Discrimination 是一种无监督的表示学习方法,因为它不依赖人工标注的标签数据,而是通过自动化的样本对比学习来获取数据的有用表示。这对于处理大规模、无标签数据集非常有效。
方法流程:
数据增强:对输入数据进行不同形式的增强操作(如裁剪、翻转、颜色变化等),生成同一实例的多个变体。
对比损失:通过对比损失函数(例如InfoNCE Loss),模型学习将相同实例的不同增强表示得更相似,而将不同实例的表示区分开来。
应用:
Instance Discrimination 方法在计算机视觉中非常流行,尤其是自监督学习任务中。例如,通过这种方法,模型可以学习到对图像的通用表示,这些表示在迁移到下游任务(如分类、检测、分割)时表现良好。