✅ 个人简介:
南京邮电大学,计算机科学与技术,在读本科
更新笔录:
2022/2/7 改动:文中的所有 “反向传播” 改成 “随机梯度下降算法(SGD)”。原因:当时把 “BP算法” 和 “SGD算法” 混淆成一个东西了。
2022/2/12 改动:又经历一段时间的学习后,发现 “SGD” 是一种 “优化器”,文中更新编码器的权重的方式还是通过 “反向传播”。
● 理论贡献: 提出用于无监督视觉表示学习的『动量对比度(Momentum Contrast)』,从作为『字典查找(dictionary look-up)』的『对比学习(Contrastive Learnin)』的角度来看,构建了带有『队列(queue)』和『移动平均编码器(moving-averaged encoder)』的动态字典,可以动态地构建大型且一致的词典,促进对比性无监督学习。
● 实验证明:
① MoCo 在 ImageNet 分类的线性分类问题上具有竞争力。
② MoCo 学习到的表示形式可以很好地转移到『下游任务(Downstream task)』中。
③ 在 PASCAL VOC,COCO 和其他数据集上的 7
个检测/细分任务中,MoCo 可以胜过其监督的预训练同类,有时甚至可以大大超过其性能。
● Introduction(前言) 是 Abstract(摘要) 的一个扩展。因为后面也要细读 MoCo v1,所以这里省去。
● 为了理解 MoCo 进行对比学习训练模型的意义,以下补充两个基本概念:『辅助任务(pretext task)』、『下游任务(downstream task)』。详见这篇前驱文章:《Self-supervised Learning 再次入门》.
●『辅助任务(pretext task)』可以理解为是一种为达到特定训练任务而设计的间接任务。比如,我们要训练一个网络来对 ImageNet 分类,可以表达为 f θ ( x ) : x → y f_θ(x):x → y fθ(x):x→y【其中 x x x 是图片输入, y y y 是分类结果输出, θ θ θ 是神经网络参数】。我们的目的其实是获得具有语义特征提取/推理能力的 θ θ θ。
● 我们假设有另外一个任务即『辅助任务(pretext task)』,它可以近似获得这样的 θ θ θ,比如,Auto-Encoder(AE),表示为: g θ ( x ) : x → x g_θ(x):x→x gθ(x):x→x【其中第一个 x x x 是原始图片输入, x x x 是重建的图片输出, θ θ θ 是神经网络参数】。为什么 AE 可以近似 θ θ θ 呢?因为 AE 要重建 x x x 就必须学习 x x x 中的内在关系,而这种内在关系的学习又是有利于我们学习 f θ ( x ) f_θ(x) fθ(x) 的。这种方式也叫做『预训练(pre-training)』,为了在目标任务上获得更好的泛化能力,一般还需要进行『微调(fine-tuning)』等操作。
● 因此,『辅助任务(pretext task)』的好处:就是为了简化原任务的求解,在深度学习里就是避免了人工标记样本,实现无监督的语义提取, 下面进一步解释。
●『辅助任务(pretext task)』任务可以进一步理解为:对目标任务有帮助的辅助任务。 而这种任务目前更多的用于所谓的『自监督学习(Self-Supervised learning)』,即一种更加宽泛的『无监督学习(Unsupervised Learning)』。这里面涉及到一个很强的动机:训练深度学习需要大量的人工标注的样本,这是费时耗力的。而自监督的提出就是为了打破这种人工标注样本的限制,目的是:在没有人工标注的条件下也能高效的训练网络,自监督的核心问题是:如何产生『伪标签(Pseudo label)』,而这种伪标签的产生是不涉及人工的, 比如上述的 AE 的伪标签就是 x x x 自身。这里举几个在视觉任务里常用的『辅助任务(pretext task)』的几种伪标签的产生方式:图片旋转、图片着色、图片补全、上下文关系预测。
●『下游任务(downstream task)』就是利用辅助任务所产生的『预训练模型(Pre-trained Models)』进行微调以实现具体网络功能的过程。在这一点上,可以把这当作一个『迁移学习(Transfer Learning)』的问题,因此应该小心不要损失预先训练的权重。
● 看一遍可能看不明白,笔者也是写了好多遍,以最好地顺序与阐释呈现。
● 我们都知道,有监督问题就是基于预测结果和监督信息设计一个『损失函数(loss function)』,但是无监督问题应该怎么设计损失函数呢?图片无监督问题的一个经典的方法是『对比学习(Contrastive Learning)』里的『实例识别任务(instance discrimination task)』。它的设计原理是:对一张图片中进行『数据增强(data augmentation)』(比如,『随机剪裁(Random Crop)』、『随机颜色失真(Random Color Distortion)』和『高斯模糊(Gaussian Blur)』等等),如果当前(经过数据增强的)图片与另外一张图片来源于同一张图片,那么该图片就被为当前图片的一个 正样本 ,否则则认为是 负样本 。
● “当前选择的图片集合” 我们称之为 q u e r y query query,而将 q u e r y query query 经过随机的数据增强得到的图片矩阵(即一维的向量矩阵)我们称之为 x q u e r y x^{query} xquery,其中从 x q u e r y x^{query} xquery 提取出来的特征下文中用的是 “ q q q” 来表示。
● 同时我们会将 “一系列” 的图片临时利用起来,形成一个图片集,并把这些图片的特征表示为这个动态字典( d i c t i o n a r y dictionary dictionary) 的 k e y key key,在下面的公式简写为了 k k k。【这里我没有展开说 “一系列” 是什么,怕的是概念太多,一开始会弄混淆,后面看完了就自然懂了】
● 基于上述的设计原理,可以设计一个『对比损失函数(contrastive loss function)』(下面这个叫 InfoNCE):
◆ 公式说明:【注,“对比损失函数” 也可以理解为 “相似度量函数”】
① 这里表达式的形式类似于一个 K + 1 K+1 K+1 分类的 s o f m a x sofmax sofmax 函数, K + 1 K+1 K+1 个样本中仅有 1
个正样本,其对应的特征记为 k + k+ k+(它在分子上),其余 K K K 个是负样本,这可以从 Σ \Sigma Σ 右下脚的 i = 0 i=0 i=0 看出。
② 两个特征的相似度量方式采用点积的形式 q • k q•k q•k(点积结果越大表示相似度越高)。
③ 超参数 τ τ τ:用于调整分类差异度。
④ 当 q q q 与正样本的差异越小的时候, l o g log log 的自变量趋于 1
,代价值趋于 0
,否则 l o g log log 的自变量趋于 0
,代价值趋与正无穷(很大)。
⑤ 分母上是一个正样本和其他所有个负样本与 q q q 的点积的和。
⑥ 这个『对比损失函数(contrastive loss function)』的本质就是希望网络对于相同图片 “处理” 出来的输入,得到的特征要尽可能的相似。怎么使得 “得到的特征要尽可能的相似呢?”,即是下面 “MoCo原理简述” 图中的 “gradient(梯度下降)” 所做的事情。
● MoCo原理简述:
【关键假设 → 字典需要具有两个特征:
① 大字典(large):包含越多的负样本则编码器越能学习到更好的特征。
② 一致性(consistent):编码器在更新的时候需要随着字典特征缓慢变化以保持特征的相对一致性。
】
● 符号解释:
① 编码器( e n c o d e r encoder encoder)和动量编码器( m o m e n t u m e n c o d e r momentum\,\,encoder momentumencoder):分别代表两个结构相同、参数不同的编码器,它们实质上是两个残差网络(ResNet)。
② x q x^{q} xq:即 x q u e r y x^{query} xquery,它是某一张图片 a a a 经过随机的『数据增强(data augmentation)』得到的一维向量(即一个“长队列”)。
③ x k x^{k} xk:即 x k e y x^{key} xkey,它是同一张图片 a a a 同样经过随机的『数据增强(data augmentation)』得到的一维向量(即也是一个“长队列”),注意在这里它是正样本。
④ q q q: x q u e r y x^{query} xquery 经过编码器 f q f_q fq 提取的特征。
⑤ k k k: x k e y x^{key} xkey 经过动量编码器 f k f_k fk 提取的特征(文中称为 keys in dictionary,存储在字典中数据集的特征),字典中仅有的一个正样本特征记为 k + k+ k+。
⑥ D y n a m i c d i c t i o n a r y Dynamic\,\, dictionary Dynamicdictionary:这个东西在图中未画出来,它是一个队列形式的 “动态词典”。在这个词典中存储着 x q u e r y x^{query} xquery 对应的正样本和已初始化的这一批数据中的所有负样本。每训练一次,队列就会将最新的一批键( x 0 k 、 x 1 k 、 x 2 k 、 . . . x_0^{k}、x_1^{k}、x_2^{k}、... x0k、x1k、x2k、...)加入队列(注意在这一批键中,只有 1
个键是正样本,其余的都是负样本),将最老的一批键出队列。如下图所示:
◆ 补充说明:在 MoCo v1 这篇论文中,关于原理的解释这上面的两张图,前面一张的 k k k 只有一个,这里的 k k k 要多一点。我的解释是:前一张原理图中每次加入 “动态词典” 的一批键中,全部都是正样本;而后一张原理图中每次加入 “动态词典” 的一批键中,只有一组是正样本,其余都是负样本。
● 本文主要是在前人的 “端到端(end-to-end)模型” 和 “存储器(memory bank)模型” 的基础上提出了两个重要的改进点:字典作为队列、动量更新(针对与蓝色模块的动量编码器)。
◆ 与同类对比学习方法的比较:
① 对比 ( a ) (a) (a) 和 ( c ) (c) (c): ( a ) (a) (a)是一种 end-to-end 形式【这里两个编码器可以 保持一致(identical)、部分参数共享(partially shared)、不同(different)】。[1]
( a ) (a) (a) 对左右两个编码器(encoder)更新参数的途径都是利用 “反向传播算法”,结合『随机梯度下降(Stochastic gradient descent,简称SGD)』优化器。而 ( c ) (c) (c) 对动量编码器(momentum encoder)采用了的是动量更新方式。[2]
( a ) (a) (a) 的 end-to-end 只能比较当前最新 mini-batch 提取出的特征,因此特征的变化可能不够平滑。 ( c ) (c) (c) 进行 SGD 时需要计算的梯度信息更少。
◇ 补充说明:也可以这样理解: ( a ) (a) (a) 的字典大小和 mini-batch 大小相同,受限于 GPU 显存,对大的 mini-batch 进行优化也是挑战,有些 pretexts 进行了一些调整,能够使用更大的字典,但是这样不方便进行迁移使用。
② 对比 ( b ) (b) (b) 和 ( c ) (c) (c): ( b ) (b) (b) 是从一个固定的 memory bank 中随机抽取一组特征, ( c ) (c) (c) 对字典中的特征【用来被对比的特征】的提取方式是随着训练过程不断变化的【因为动量编码器的参数会缓慢更新】。
◇ 补充说明: ( b ) (b) (b) 中的 Memory Bank 包含数据集所有数据的特征表示,从 Memory Bank 中采样数据不需要进行 “反向传播”,所以能支持比较大的字典,然而一个样本的特征表示只在它出现时才在 Memory Bank 更新,因此具有更少的一致性,而且它的更新只是进行特征表示的更新,不涉及 encoder (的参数更新)。
● 这样做的好处是:将 dictionary 的大小和 batch size 解耦出来,即 dictionary 的大小不需要受 batch size 的约束,可以设置成任意大小。这样 dictionary 的大小和 mini-batch 的大小就 decouple(二者相互独立)。具体有两个好处:[1]
字典可以变得很大,包含很多负样本,提高对比学习的效果。[2]
并且以新的 mini-batch 去替换队列最末的旧的 mini-batch 可以保证特征变化的平稳性。
● 论文中给的 Momentum update 公式原型如下:
● 其实在编码器( e n c o d e r encoder encoder)和动量编码器( m o m e n t u m e n c o d e r momentum\,\,encoder momentumencoder)之间有条掩藏的 “联络线”,如下图所示:
◆ 说明:注意第二项是 θ q θ_q θq。先看下面的 MoCo 原理图,图中只做了关于 x q → q x^q→q xq→q 的编码器 f q f_q fq 的反向传播,并没有做关于编码器 f k f_k fk 的反向传播。这样做有两个好处:[1]
如果对编码器 f k f_k fk 求梯度,由于其输入量( x 0 k 、 x 1 k 、 x 2 k 、 . . . x_0^{k}、x_1^{k}、x_2^{k}、... x0k、x1k、x2k、...)很多,运算量很大,对 GPU 要求很高,而只计算编码器 f q f_q fq 的梯度的运算开销就小很多。[2]
动量更新的方式【即上图那个公式】保持了编码器 f k f_k fk 的惯性(原有特征变化的平稳性),或者说对之前的特征具有相对的记忆性,这在后续实验中证明是有利于『对比学习(Contrastive Learnin)』的效果提升。
◆ 补充说明:另外在论文中提到,实验也发现,适当增加 m m m 会带来更好地效果,大的动量(例如0.999)往往效果好于小的动量(例如0.9)。因此本文中 m = 0.999 m = 0.999 m=0.999,意味着缓慢变化的 momentum encoder 是利用好动态词典的关键所在。这样不仅避免了因为 encoder 的剧烈变化导致特征丢失一致性,同时也保持 momentum encoder 一直处于被更新的状态。
● 算法流程:
① 对输入 x x x 进行数据増广分别得到 x q x^q xq 和 x k x^k xk(正样本)
② 卷积后提取特征 q 、 k q、k q、k
③ 将参数 k k k 从网络中隔离开,不参与参数更新(即不进行梯度下降)
④ l _ p o s l\_pos l_pos 和 l _ n e g l\_neg l_neg 分别是用来计算 q q q 分别与正样本、负样本之间的特征匹配度
⑤ 点积运算对比损失函数
⑥ 对编码器 q q q 的权值 f q f_q fq 进行反向传播(优化器是SGD) → 更新 f q f_q fq 的权值
⑦ 更新 f k f_k fk 权值
⑧ 用新的 m i n i _ b a t c h mini\_batch mini_batch 更新字典队列
● 以下在 ImageNet-1M (106张图片) 数据集上进行了三个方面的对比实验,证明了 MoCo v1 的优秀表现:
● end-to-end 虽然在 k k k(负样本个数)小的时候准确率高,但是由于算力开销大因此 k k k 不能取的很大。memory bank 虽然对负样本个数没有约束,但是准确率始终低于 MoCo。【注: K K K是样本大小,横坐标是“对数尺标”】
● 在上述 K = 4096 K=4096 K=4096 的情况下,尝试不同的动量系数,取 0.999 较为合适。
● 为了公平比较,考虑在模型参数数量相近的情况下进行比较。并要求自变量固定,纵向来看实验结果,发现 MoCo 的表现在和前人模型参数总量近似相等的情况下,准确率相对而言是最高的。
● 论文后面还进行了(1)PASCAL VOC 目标检测、(2)COCO 目标检测与分割、(3)其他 downstream tasks 实验,主要和监督学习方法进行对比。实验结果都很不错,这里就不一一例举了。
● 论文中的方法在各种计算机视觉任务和数据集中显示了无监督学习的积极结果。有几个有待解决的问题值得讨论。MoCo 从 I N − 1 M IN-1M IN−1M 到 I G − 1 B IG-1B IG−1B 的改进始终是明显的,但相对较小,这表明更大规模的数据可能没有得到充分利用。
● 他们希望有一个先进的『辅助任务(pretext task)』能改善这一状况。除了将其应用到本文简单的『实例识别任务(instance discrimination task)』之外,还可以在语言领域、其他视觉领域采用 MoCo 来进行(隐式的)自动编码等『辅助任务(pretext task)』。
● 何凯明团队也在最后提到,希望 MoCo 能在其他涉及『对比学习(Contrastive Learnin)』的『辅助任务(pretext task)』中有用。
MoCo v1原论文地址:https://arxiv.org/abs/1911.05722.
[1] MoCo:Momentum Contrast for Unsupervised Visual Representation Learning 论文笔记.
[2] 小全读论文《Momentum Contrast for Unsupervised Visual Representation Learning》(MoCo).
[3] 5. 无监督学习 MoCo: Momentum Contrast for Unsupervised Visual Representation Learning.
[4] Momentum Contrast for Unsupervised Visual Representation Learning无监督胜有监督,刷新检测分割任务.
[5] Momentum Contrast for Unsupervised Visual Representation Learning.
[6] CV中的无监督学习方法:MoCo.
[7] Momentum Contrast for Unsupervised Visual Representation Learning论文理解.
⭐️ ⭐️