自监督对比学习
对比学习(self-supervised learning)的应用场景是用无标记或者少标记的数据进行模型的预训练以得到一个较好的预训练模型,然后便可将该模型轻松的迁移到到下游任务上。显而易见的,对比学习的难点在于我们如何在没有标注的情况下来指导模型的训练,也就是如何设计pretext task。其中较为常用的一种就是实例自监督对比学习(instance-wise contrastive learning),这一场景下数据集中的所有的原始样本都被认为是彼此孤立的一类,而一张图片经过某种变换得到的新样本则被认为和原样本属于同类样本,这样原样本和变换后样本组成了一对正例、原样本和其他样本组成范例,网络训练的目的就变成了最大化反例对间的距离,同时最小化正例对间的距离。这一任务中三个要点:
- 反例的选取,由于每一个样本都被单独视作一类,均可构成反例,但全都用于训练训练开销过大,那么如何从中选取对于训练最有帮助的负类。
- 正例的构成,如何设计一个好的变换,使得变换后的样本和原始样本属于同类,但又不至于完全一致使得网络轻松过拟合。
- 损失函数的设计,问题的关键在于拉近正例对之间的距离,同时推开反例对,那么如何定义这一距离、如何实现这一目的就是损失函数应该考虑的部分。
无监督对比学习
无监督对比学习走的是最传统的对比学习路线,也就是构建正负样本对,在instance-wise的层面上优化特征空间。代表性的工作有simCLR, MOCO以及BYOL,其思路是大差不差的,只是在反例的选取机制上存在着差异。
simCLR
simCLR的整体思路就和之前介绍的一样,如下图所示
网络由四个部分组成,包括图像增强、编码器、映射头、损失函数,其中映射头在训练完成后会被舍弃,仅仅留下编码器模块用于下游任务。simCLR首先将一个BATCH中的
N
N
N张图片通过两种不同的变换得到
2
N
2N
2N张变换后图片,对于某一张图片而言,和它具有相同来源的图片构成正例,其余的
2
(
N
−
1
)
2(N-1)
2(N−1)张图片构成反例。由此,对于原始BATCH里的一张图片,我们可以得到1个正例和
2
(
N
−
1
)
2(N-1)
2(N−1)个反例。网络训练的损失函数使用了infoNCE如下:
l
i
,
j
=
−
l
o
g
e
x
p
(
s
i
m
(
z
i
,
z
j
)
/
τ
)
∑
k
=
1
2
N
l
k
≠
i
e
x
p
(
s
i
m
(
z
i
,
z
k
)
/
τ
)
l_{i,j}=-log\frac{exp(sim(z_i,z_j)/\tau)}{\sum_{k=1}^{2N}\mathbf{l}_{k\neq i}exp(sim(z_i,z_k)/\tau)}
li,j=−log∑k=12Nlk=iexp(sim(zi,zk)/τ)exp(sim(zi,zj)/τ)
其中
z
i
,
z
j
z_i,z_j
zi,zj即对应同一张图片经变换得到两张图片网络提取出的特征,
z
K
z_K
zK为其余图片经网络提取出的特征,
τ
\tau
τ为温度控制系数,,这里的
s
i
m
sim
sim函数使用了简单的余弦距离。这个infoNCE loss可以认为是交叉损失熵函数的变体,在对样本进行
2
N
−
1
2N-1
2N−1分类,也就是
∑
i
=
1
2
N
−
1
y
i
l
o
g
y
i
^
,
y
i
=
e
x
p
(
z
i
)
∑
k
=
1
2
N
−
1
e
x
p
(
z
k
)
\sum_{i=1}^{2N-1}y_ilog\hat{y_i},y_i=\frac{exp(z_i)}{\sum_{k=1}^{2N-1}exp(z_k)}
∑i=12N−1yilogyi^,yi=∑k=12N−1exp(zk)exp(zi),更为详细的解释参考1
simCLR整体而言非常的“朴素”,提出了一个基本的contrastive learning框架,论文主要关注的还是不同augment对于模型训练的影响。
MOCO
MOCO想要解决的问题是反例的选取,如同simCLR一样使用同一个BATCH的样本作为反例不是不可以,但infoNCE loss的天然属性决定了负样本越多,模型训练的越好,但简单的增大BATCH数目又会带来巨大的计算开销和训练成本。因此MOCO提出了一种渐进式更新的解决方案,具体机制分为memory bank和动量更新两个部分,如下图所示:
对于输入
N
N
N张图片,我们仍然是进行两种不同的变换得到了
2
N
2N
2N张变换后的图片,对于某一个样本而言,同样构成了1个正例,但反例的数目不再是
2
N
−
1
2N-1
2N−1,而是由memory bank所确定,memory bank是一个存有过去
K
(
K
>
>
N
)
K(K>>N)
K(K>>N)张图片的队列,由此可以形成
K
K
K个反例,经过这一个batch训练后,memory bank使用这一个batch的图片进行更新。
到此为止的话,我们解决了负例数目的问题,但是没有解决负例过多带来的开销问题。moco进一步固定住了momentum encoder的更新,禁止了momentum encoder中权重经过反向传播来更新,改为每个batch结束使用endoer的值(encoder和momentum encoder架构一致)进行动量更新:
θ
k
←
m
θ
k
+
(
1
−
m
)
θ
m
\theta_k\leftarrow m\theta_k+(1-m)\theta_m
θk←mθk+(1−m)θm
其背后的灵感是认为momentum encoder是在进行模版提取的工作,而模版提取应该是稳定的,不应该剧烈变化2,同时作为视觉特征提取模块,encoder和momnetum encoder的作用是一致的,因此可以用encoder的权重来对momentum encoder进行动量更新。
论文
A Simple Framework for Contrastive Learning of Visual Representations
Momentum Contrast for Unsupervised Visual Representation Learning
参考
对比学习损失(InfoNCE loss)与交叉熵损失的联系 ↩︎
Self-Supervised Learning 超详细解读 (四):MoCo系列解读 (1) ↩︎