朱毅大佬视频讲解笔记
对比学习论文综述【论文精读】_哔哩哔哩_bilibili
把全部图像的特征存在Memory Bank中,每个epoch中,有mini-batch个正样本,Memory Bank容量(4096)个负样本,每个Mini-Batch更新一次Memory Bank。
相似的物体有相似的特征,不相似的物体的特征也不同
在一个MiniBatch中构造正负样本,正样本为1个,负样本为(256-1)*2,正负样本使用同一个CNN进行特征抽取
已audio为例,信号通过encoder后喂给自回归模型(LSTM等),用最后时刻的输出(包含上下文信息)预测未来时刻的特征输出。
正样本是未来时刻的输入通过encoder后得到的特征,负样本的选取可以很广泛,比如可以任意选取输入通过encoder的输出作为负样本
一张图像的不同view(比如灰度图、语义分割图 、深度图等)表示同一张图,应该互为正样本;其他在view上不匹配的图像作为负样本
局限性:不同的view要配不同的编码器,在计算成本上不够友好
[CVPR2020] (MoCo)Momentum Contrast for Unsupervised Visual Representation Learning
一张图像经过两个不同的变换,通过同一个encoder(Res50)得到 h h h,再经过一个Projection head(FC+ReLu),得到 z z z,结果互为正样本,负样本是其他图像和他们的变换结果。
Projection head只在训练时使用,做下游任务时使用encoder(Res50)的输出 h h h。
假设 b a t c h s i z e = N batchsize=N batchsize=N,则正样本: 1 1 1个,负样本: 2 ∗ ( N − 1 ) 2*(N-1) 2∗(N−1)个
衡量正样本之间的一致性(Normalized temperature-scaled loss)
最有效的两个数据增强是crop和color
受SimCLR启发,在MoCo的基础上加入了Projection head和更多的图像增强
1、更换更大的backbone,Res50→Res152(3x+SK)(selective kernels)
2、Projection head 1层fc→2层fc
3、加入了MoCo中的动量编码器,但是提升不大,因为batchsize够大,已经包含了足够多的负样本
用cluster的方法做对比学习
原先的工作都是直接在特征上做对比学习,SwAv引入了 K K K个聚类中心 C C C,如果两个是正样本,应该得到的 Q Q Q比较相似,那就可以用 c ∗ z 1 c*z_1 c∗z1去预测 Q 2 Q_2 Q2,反之亦然
BYOL为什么厉害呢?因为在之前的方法里,负样本充当着一种约束的作用,如果只有正样本,模型只会拉近正样本之间的距离,那么可能会导致modal collapse,即无论输入什么,都是一样的输出。
上下两个 f f f和 g g g网络结构相同,但参数不共享,上面用梯度更新,下面用动量更新(详见MoCo),上面网络还在特征后加入了一个prediction head q q q,也是个MLP,用得到的结果来预测下面的特征。
这样,把一个配对的问题转化为了预测的问题。
直接用MSE进行训练
博客地址
在Projection head 和 Prediction head中是否加入BN,会对结果造成很大的差别。博客的解释是BN会造成minibatch特征泄露(因为要算running mean和running variance),所以BYOL其实是一种隐式的对比学习,是正样本与平均图像在做对比学习
做了充分的ablation,发现BN确实有用,但是模型的成功不全是因为BN而导致的隐式的对比学习,因为在最后一列中,当SimCLR(显示的对比学习)不适用BN时,也失效了:
将BN替换为GN(GroupNorm),用WS(weight stardard)初始化后,此时不会引入batch内的数据,也得到了73.9%的top1结果,由此证明BYOL是真的好
不需要 负样本、大batchsize、动量encoder
结构和BYOL非常相似,区别在于没有使用动量encoder,使用了stop-grad
这一阶段主要是把CNN变成了ViT,但是发现训练不稳定,于是各自在提出了方法解决这个方法。
MoCo v3把projection layer冻住,DINO使用了centering做归一化。
MoCo v2 + SimSiam 很自然的延伸工作
将backbone换成了ViT,发现一个现象:随着batchsize的增大,训练曲线会每隔一段时间崩一次,在ViT的初始阶段(Tokenization阶段)的projection的梯度也会达到一个峰值,于是提出一个trick:将token projection层随机初始化后冻住,不进行训练,这样解决了这个问题。
这次trick在BYOL和其他许多任务中也都有效,非常好用
centering:在一个minibatch里求均值,然后在用样本减去这个均值,作用 类似于BYOL中BN的操作