背景 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_+。