MoCo 阅读笔记 | Momentum Contrast for Unsupervised Visual Representation Learning
背景 Contrast Learning
典型的自监督表征学习(Representation Learning),设计一些直观的任务来辅助表征学习,例如Rotate、InPainting、Colorization等。Contrast Learning出现之后,这种方法被证明效果有不错的提升,优于ImageNet的预训练任务。这也是自监督学习的一大目标——通过自监督的任务,对网络进行预训练,从而迁移到下游的任务,希望这种预训练的效果优于监督学习的。
Contrast Learning 的目的是:
- 1)一个样本在特征空间和同类样本接近
- 2)一个样本在特征空间和异类样本远离
那么,对于Contrast Learning 来说,Loss就非常直观,只需满足:
- 1)描述这样一个损失,样本X经过Encoder之后得到的特征向量(集)k_x和其余同类样本X'经Encoder后的特征向量(集)q_0的近似程度。越近似,loss越小。这一部分,使用Softmax Loss。对应目的1)。注:原始的样本X和X'可以是一个也可以是多个,也可以是同一个,x和x'所经过的Encoder也相同也可以不同。其中MoCo使用的Momentum Encoder便是文章的主要贡献之一。
- 2)描述这样一个损失,样本X经过Encoder之后的到的特征向量(集)k_x和其余不用类别的样本Q经过Encoder后的向量(集)q的差异程度。差异越大,loss越小。这一部分用Negative Log Liklihood,对应目的2)。注:原始样本X同上,Q的样本容量也可以是灵活的,几种不同的采用Contrast Learning的论文Instance Discrimination等,分别采用了不同的思路。
所以Contrast Learning的相关工作,都可以理解成有两个变量,X和Y,并且从相应的联合分布采集出一些列N长度的{x_i, y_i},给定一个x_i,在采样出的样本中,对应的y_i就是正样本,不对应的就是负样本。对每一个正样本都匹配N个负样本计算一个softmatx loss。
不同的工作中,有的将image patch作为x,context作为y,也有将样本本身的情态(modality)分别作为x和y的,例如RGB、光流等。
字典与动态字典 Dictionary & Dynamic Dictionaries
NLP任务中,通常会通过embedding将句子中的所有word嵌入成vector,穷举所有的词,获得一个有限的vector集合,这些所有的word组成的集合,我们称之为词典。
但是正在cv任务中,我们没有办法穷举所有的图片或是描述说组成图片的构件?显然不合理。所以我们要有一种新的办法来构筑图片词典。即稳重提出的Dynamic Dictionaries。
所谓的动态词典,作者文中说的是The dictionary is dynamic in the sense that the keys are randomly sampled. 这里的Key指的是字典中的元素。字典的作用主要是在训练过程中,作为一个比较或者预测的范围。既然没有办法穷举整个图片的取值,作者在这里就采用了randomly sampling的方式(实际上这里的sample是和mini batch时的sample是一样的)
总结一下就是,动态词典是在训练过程中,随机从所有图片中采样若干张图片,作为本次训练的词典。这是作者提出的一种handle高维连续数据的trick。
主要贡献 Momentum Encoder
实际上MoCo中所提出的key和query本质上就是取名而已,是一种伪概念,对应到x和y。
MoCo做出的主要贡献是,以低开销采集到大量负样本。如图,end-to-end方法,k的大小N收到限制,必须和batch size保持一致。memory bank虽然解决了这个问题,但是要将所有的数据集都存下来,所以无法处理极大数据集的时候。MoCo的做法是每次取一个q,然后存过去m个batch的sample,也就是q。这个思路其实比较直接,但实际上MoCo的关键,便是这个momentum encoder。
momentum encoder不需要单独的反向传播、梯度下降来更新参数,moentum encoder的参数更新,依赖了q的encoder的参数和他本身的参数:
可以看出,这个更新过程将q的encoder的参数当作了动量,用来作为更新方向,使用m来当前k的encoder本身的参数和更新的力度。这种做法和SGD momentum优化器中的动量概念相仿。
实际上这种做法是在更新encoder参数的同时,保留了他的一个历史参数版本的smooth。也就是说,右边的这个momentum encoder事实上=左边encoder的部分历史状态+更新状态。历史状态随着迭代次数的增加,越早版本的参数在当前momentum encoder中保留的越少。
本文 MoCo
变量定义
x^q:一张图片P_q的图像增强操作(Rotate、Crop、Flip等)后的矩阵。
x^k:图片集合P_K, 包含P_q,增强操后的矩阵集。
encoder:一个网络,通过反向传播梯度下降更新参数。
momentum encoder:和encoder结构相同,通过上面提到的momentum方法更新参数。
q:x^q经过encoder网络编码后的一个向量。
k:x^k经过momentum encoder网络编码后的向量。
contrastive loss
k:x^k经过momentum encoder网络后得到的特征向量集k,共K+1个。K个负样本,1个正样本。
k_+:k中和P_q对应的向量,1个,正样本。
k_i:k中除k_+外的其他向量,k个,负样本。
T:常数。
训练
0)初始化
准备一批图片Ps(如共1000000张图片,编号0~1000000)。创建encoder和momentum encoder,参数初始化相同。从Ps中选择前K张(如K=5000)进行数据增强操作得5000个矩阵,并将这些矩阵输入到momentum encoder生成5000个d维(如d=128)向量。
5000个128维的key vector集合为Queue(Queue将是动态更新的)。
1)准备q和k
从Ps中提取1张(第5001张)新图片p_i。
对p_i进行一次数据增强得矩阵x_q_i,shape=[1, 224, 224, 3]。
对p_i进行一次数据增强得矩阵集x_k_i,shape=[1, 224, 224,3]。
x_q_i和x_k_i是p_i的两次不同的增强。
将x_q_i输入到encoder网络得query vector,q_i,其shape=[1, 128]。
将x_k_i输入到momentum encoder网络得矩阵k_i,其shape=[1, 128]。
k:从Query中取出所有key vector,共N个,并将k_i合并,shape=[K+1, 128]
q:即q_i
2)更新encoder
使用Contrast Loss更新encoder。
使用momentum方法更新momentum encoder。
3)更新Queue
删除Queue的前部1个样本,将k_+追加在末尾。(队列的pop和push_back操作)。
实际上,训练以batch方式进行,batch size为N。共有N个q向量。所以每次pop N个,追加N个k_+。