MoCo
提出背景
MoCo 是 Inst Disc 的改进工作,那我们自然要先看一下 Inst Disc 有什么不足
1.Memory Bank 过大,不能应用在更大的数据集上
因为其字典的数据类型,导致计算开销会加大
2. 动量更新并不能完全解决特征一致性差的问题
即使使用了动量更新的方式,同一个特征前后被调用的跨度也还是很长,一致性依旧不够
3.NCEloss 负样本分类不合理的问题
NCE 把所有负样本都视作一样的,但实际上负样本并不能被完全归为一类
举个例子:我现在的正样本是猫猫,然后有两个负样本是狗勾和汽车,那猫猫肯定跟狗勾更相近,跟汽车更不相似,也就是说狗的得分虽然低于猫,但是一定要高于汽车,而不是像 NCE 那样把狗和车打成一类,这样不利于模型学习。
并且它也不是很灵活,下文细讲
虽然大家应该都懂了(应该吧?),但还是贴一下模型总览图。
右边就是 memory bank 啦
MoCo 做出的改进
1. 针对 Memory Bank 过大
作者使用队列的数据结构去储存这个大字典,因为是先进先出,所以好处是新进来的特征可以把最老的特征替换掉。每次不用把整个字典全部载入,而是用队列形式即可。很简单地解决了这个问题。
2. 针对动量更新不能完全解决特征一致性差的问题
作者提出了一个新的动量编码器来替代动量更新。
动量编码器是独立于原编码器的一个编码器,它的参数是根据原编码器动量更新的,k 和 q 就是指代全部参数了
这样的话就是解码器在缓慢更新,比对特征使用动量更新要更有连续性。
3. 负样本分类不合理的问题通过替换 infoNCEloss 解决
下面是 infoNCE loss 的公式,它是 NCE 和交叉熵损失的结合体,长得就很像交叉熵,只是多了个 T。
q・k 其实就是各个特征(因为那时候用的都是 transformer 了,这里就是 trnasformer 里的 k 和 q)
这里分母级数上的k 是代表负样本的个数,也就是 k=batchsize-1(总样本 - 正样本)。其实就是对一个 batch 做 k+1 分类,并且引入了一个超参数 T。它的名字叫做温度参数,控制的是 softmax 后得分分布的平滑程度(直观理解,不是很严谨)
T 越大,损失函数就越对所有负样本一视同仁,退化为二分类的 NCEloss;T 越小,损失函数就越关注一些难分类的特征,但有时候会出现两张其实都是猫猫的图片,你硬要让模型说猫猫跟猫猫不一样,这也不太好,这个参数要根据数据集情况适中调整。
上面那张是 T 较大的情况,下面是 T 较小的情况(x 轴是各个类别,y 轴是分类得分)
所谓的灵活性就是指:infoNCE loss 引入了温度参数,这个参数可以帮我们调整训练的难度,T 越大,模型越关注类似的特征,训练也就越难,总之就是非常灵活。
总结
总而言之,MoCo 就是基于 Inst Disc 主要做了如上三点改进,模型和参数都是完全不变的。它的核心在于动量编码器和活动大字典。
能在 imagenet 上达到媲美甚至超越有监督学习的模型的结果,并且可以作为 backbone 很好的拓展应用到多个下游任务上。
另外
其实 MoCo 有两篇后续工作,MoCo v2 和 MoCo v3,v2 其实就是缝合了后面讲的 SimCLR 的方法,不展开了,V3 留到以后讲。