✅
文章目录
关于自监督学习,在 CSDN 和知乎上已经有无数大佬开垦过,比如: 《Self-supervised Learning 再次入门》,作者:信息门下憨狗、《Self-Supervised Learning 入门介绍》,作者:Sherlock。笔者也是去年 4 月初才开始接触 Self-supervised Learning,断断续续研究到现在…目前是一名大三上的本科生,没有啥把握能写好这一篇…笔者尽力吧…因为已经有了『入门』和『再次入门』,那笔者这篇斗胆叫作『再再次入门』。
● 这部分是笔者所理解而写的,可能写得不是很好,专业人员可跳过 “一”,直接看 “二”。
一、监督学习、无监督学习和自监督学习的定义与关系——自己写的版本
● 想要了解自监督学习,就得了解一下它的前身和它的兄弟姐妹…
1.1 监督学习
● 在最开始产生的是监督学习(supervised learning):利用一组已知类别的样本调整分类器的参数,使其达到所要求的性能的过程。
◆ 我们将其定义划分,并依次进行解释:
监督学习(supervised learning):利用一组「已知类别的样本」调整「分类器」的「参数」,使其达到「所要求的性能」的过程。【来自百度百科】
① 已知类别的样本:比如说我们给了一位 1 岁的小朋友两堆猫和狗的图片,要让他来分类。前提是这位小朋友他还不认识猫和狗。这里的「已知」是对于我们来说是 “已知”,而对于这位小朋友是 “未知的”。这两堆猫和狗的图片就是「已知类别的样本」。(只不过我们训练的对象是 “计算机”,不是 1 岁的小朋友。)
② 分类器:每个 1 岁的小朋友都有自己的大脑,当他分正确或者分错的时候,我们在旁边就会告诉它答案,然后他就会慢慢 “学习” 到猫和狗的图像特征(比如:“原来猫和狗都是有 4 根腿的”、“猫的耳朵是向上的”、“狗会吐长石头”等等)。这些 “学习” 产生在这位 1 岁小朋友的大脑内部,或许是某些神经元之间建立了 “正确的连接”,或许是某些神经元弃置了某些 “突触” ——> 以帮助他形成 “能够判断并分类猫与狗的思维体系”,也就是「分类器」。(只不过我们训练的对象是 “计算机”,不是 1 岁的小朋友。)
③ 参数:我们可以把这位 1 岁小朋友的大脑的某一个 “图像接收与分类脑区” 想象成一个庞大的非线性运算器,这两堆猫和狗的图片就是两类不同的 “输入”,经过小朋友大脑的运算,会得到答案——要么是猫、要么是狗。然后呢这个非线性运算器假设是 f ( x , y , z , . . . ) = 3 x 5 + 4 x + e y − 2 − z + . . . f(x,y,z,...)=3x^5+4x+e^{y-2}-z+... f(x,y,z,...)=3x5+4x+ey−2−z+... ,那么「参数」就是 “2、3、4、5、…” 这些系数,因为 “x、y、z、…” 是 “图片输入”,比如 x x x 是图片 (100,200) 坐标像素点的颜色。(只不过我们训练的对象是 “计算机”,不是 1 岁的小朋友。)
注:定义中用了 “调整” 这一个词,就说明这位 1 岁小朋友在 “学习” 猫和狗的图像特征,那是在什么时候学习的呢?很显然,是在我们告知他正确或错误的答案的时候,他才开始 “学习” 的,并更新他大脑中那个 “非线性运算器” 的 “系数” ——> 以优化他形成 “能够判断并分类猫与狗的思维体系”,也就是「分类器」。(只不过我们训练的对象是 “计算机”,不是 1 岁的小朋友。)
④ 所要求的性能:我们要这位 1 岁小朋友学习的目的是什么呢?不就是为了让他以后能在生活中、考试中能正确区分两类动物。而对于 “计算机” 而言,也就是希望它能在 “学习” 一定图片的基础上,在之后自动地帮人类分类图片。
● 通过对上诉定义的分析,相信大家已经对 “监督学习(supervised learning)” 有了一定的了解。接下来看 “无监督学习(Unsupervised Learning)”。
1.2 无监督学习
● 无监督学习(Unsupervised Learning):根据类别未知(没有被标记)的训练样本解决模式识别中的各种问题,称之为无监督学习。
◆ 同样地,我们对其定义划分,并依次进行解释:
无监督学习(Unsupervised Learning):根据「类别未知的样本」解决模式识别中的各种问题的过程。【来自百度百科】
◆ 详细定义阐释:现实生活中常常会有这样的问题:缺乏足够的先验知识,因此难以人工标注类别或进行人工类别标注的成本太高。很自然地,我们希望计算机能代我们完成这些工作,或至少提供一些帮助。根据类别未知(没有被标记)的训练样本解决模式识别中的各种问题,称之为无监督学习。
● “无监督学习” 与 “有监督学习” 的最大不同就是在与:前者是用「类别未知的样本」来训练「分类器」,后者是用类别已知的样本」来训练「分类器」。
● 对于 “无监督学习” ,就相当于说,我们给了这位 1 岁小朋友两堆猫和狗的图片,然后呢,他开始分,当分好了 1 张图片时,我们不告诉他答案;当他分好了 2 张时也不告诉。而让他自己做决定。他分着分着时,可能会发现这两种动物有那么些 “不同点”或者“共同点”,比如 “这一类动物它的脸比较圆”、“这一类动物它的舌头比较长”。然后他就会自行对之前分好的图片重新分一次,经过很多轮 “分类” 后,他就会分出 “两堆图片”。最后,这位 1 岁小朋友就学到了 “这两类动物的特征”,只是我们没有告诉他。(只不过我们训练的对象是 “计算机”,不是 1 岁的小朋友。)
1.3 自监督学习
● 自监督学习(self-supervised learning):利用辅助任务从类别未知的样本中进行学习,解决模式识别中的各种问题的过程。
◆ 同样地,我们对其定义划分,并依次进行解释:
自监督学习(self-supervised learning):利用「辅助任务」从「类别未知的样本」中进行学习,解决模式识别中的各种问题的过程。【非官方定义】
● “自监督学习” 是 “无监督学习” 中的一种,都是基于图像原始数据出发的。
● 自监督学习的核心:在于如何自动为数据产生标签。例如输入一张图片,把图片随机旋转一个角度,然后把“旋转后的图片”作为输入
,“随机旋转的角度”作为标签
。再例如,把输入的图片均匀分割成 3 × 3
的格子,每个格子里面的内容作为一个 patch
,随机打乱 patch
的排列顺序,然后把“打乱顺序的 patch
”作为输入
,正确的排列顺序作为label
。类似这种自动产生的标注,完全无需人工参与。引自《自监督学习》,作者:不知道叫什么好
● 这里的 “辅助任务” 即是 “自监督学习” 与 “无监督学习” 最大的不同,它能自行对一张图片或者 “多方位的学习”。
二、监督学习、无监督学习和自监督学习的定义与关系——大佬版
● 以下大部分内容转自《Self-supervised Learning 再次入门》,作者:信息门下憨狗,部分内容笔者有做修改和强调。 [发布于 2020-02-24 22:43]
2.1 学习的范式
● 我们首先来回顾下机器学习中两种基本的学习范式,如图所示,一种是监督学习,一种是无监督学习。
● 监督学习利用大量的标注数据来训练模型,「模型的预测」和「数据的真实标签」产生损失后进行反向传播,通过不断的学习,最终可以获得识别新样本的能力。而无监督学习不依赖任何标签值,通过对数据「内在特征」进行挖掘,找到样本间的关系,比如聚类相关的任务。有监督和无监督最主要的区别在于:模型在训练时是否需要人工标注的标签信息。
● 无监督学习中被广泛采用的方式是自动编码器(autoencoder):
● 编码器(Encoder):可将输入的样本映射到隐层向量。解码器(Decoder):可将这个隐层向量映射回样本空间。我们期待网络的输入和输出可以保持一致(理想情况,无损重构),同时隐层向量的维度大大小于输入样本的维度,以此达到了降维的目的,利用学习到的隐层向量再进行聚类等任务时将更加的简单高效。对于「如何学习隐层向量」的研究,可以称之为表征学习(Representation Learning)。
● 但这种简单的 “编码-解码” 结构仍然存在很多问题,基于像素的重构损失通常假设每个像素之间都是独立的,从而降低了它们对相关性或复杂结构进行建模的能力。尤其使用 L1 或 L2 损失来衡量输入和输出之间的差距其实是不存在语义信息的,而过分的关注「像素级别的细节」而忽略了「更为重要的语义特征」。
● 对于自动编码器,可能仅仅是做了维度的降低而已,我们希望学习的目的不仅仅是维度更低,还可以包含更多的语义特征,让模型懂的输入究竟是什么,从而帮助「下游任务」。而自监督学习最主要的目的:就是学习到更丰富的语义表征。
2.2 什么是自监督学习
● 自监督学习主要是利用 辅助任务(pretext) 从大规模的无监督数据中挖掘自身的监督信息,通过这种构造的监督信息对网络进行训练,从而可以学习到对下游任务有价值的表征。
● 所以对于自监督学习来说,存在三个挑战:
① 对于大量的无标签数据,如何进行表征学习(Representation Learning)?
② 从数据的本身出发,如何设计有效的辅助任务(pretext)?
③ 对于自监督学习到的表征,如何来评测它的有效性?
● 对于第三点,评测自监督学习的能力,主要是通过 Pretrain-Fintune 的模式。
● 我们首先回顾下「监督学习」中的 Pretrain - Finetune 流程:我们首先从大量的有标签数据上进行训练,得到预训练的模型,然后对于新的下游任务(Downstream task),我们将学习到的参数进行 迁移(Transform) ,在新的有标签任务上进行 微调(Finetune) ,从而得到一个能适应新任务的网络。
● 而自监督的 Pretrain - Finetune 流程:首先从大量的无标签数据中通过 辅助任务(pretext) 来训练网络,得到预训练的模型,然后对于新的下游任务,和监督学习一样,迁移学习到的参数后 微调(Finetune) 即可。所以自监督学习的能力主要由下游任务的性能来体现。【下图所示】
2.3 自监督学习的主要方法
● 自监督学习的方法主要可以分为 3 类:基于上下文(Context based)、 基于时序(Temporal Based)、基于对比(Contrastive Based)。
2.3.1 基于上下文(Context Based)
● 基于数据本身的上下文信息,我们其实可以构造很多任务,比如在 NLP 领域中最重要的算法 Word2vec 。 Word2vec 主要是「利用语句的顺序」,例如 CBOW 通过前后的词来预测中间的词,而 Skip-Gram 通过中间的词来预测前后的词。【下图所示】
● 而在图像中,研究人员通过一种名为 Jigsaw(拼图)的方式来构造 辅助任务(pretext) 。我们可以将一张图分成 9
个部分,然后通过预测这几个部分的相对位置来产生损失。比如我们输入这张图中的小猫的眼睛和右耳朵,期待让模型学习到猫的右耳朵是在脸部的右上方的,如果模型能很好的完成这个任务,那么我们就可以认为模型学习到的表征是具有语义信息的。【下图所示】
● 后续的工作中,人们又拓展了这种拼图的方式,设计了更加复杂的,或者说更难的任务。首先我们依然将图片分为 9
块,我们预先定义好 64
种排序方式。模型输入任意一种被打乱的序列,期待能够学习到这种序列的顺序属于哪个类,和上个工作相比,这个模型需要学习到更多的相对位置信息。这个工作带来的启发就是使用更强的监督信息,或者说辅助任务越难,最后的性能越好。【下图所示】
● 除了这种拼图的模式,还有一种是抠图。想法其实也很简单粗暴,就是我们随机的将图片中的一部分删掉,然后利用剩余的部分来预测扣掉的部分,只有模型真正读懂了这张图所代表的含义,才能有效的进行补全。这个工作表明自监督学习任务不仅仅可以做表征学习,还能同时完成一些神奇的任务。【下图所示】
● 而对于这种抠图的方式,其实和 nlp 中的 BERT 的 MASK LM 训练方式有异曲同工之妙,BERT 在训练时也可以是看做随机扣掉一些词,然后来预测扣掉的词,从而让模型读懂句子。【下图所示】
● 还有一种思路是通过图片的颜色信息,比如给模型输入图像的灰度图,来预测图片的色彩。只有模型可以理解图片中的「语义信息」才能得知哪些部分应该上怎样的颜色,比如天空是蓝色的,草地是绿色的,只有模型从海量的数据中学习到了这些语义概念,才能得知物体的具体颜色信息。同时这个模型在训练结束后就可以做这种图片上色的任务。【下图所示】
● 这种基于预测颜色的生成模型带给了人们新的启发,其实这种灰度图和 ab 域的信息我们可以当做是一张图片的解耦表达,所以只要是解耦的特征,我们都可以通过这种方式互相监督的学习表征,著名的 Split-Brain Autoencoders 就在做这样一件事情。对于原始数据,首先分成两部分,然后通过一部分的信息来预测另一部分,最后再合成完成的数据。和传统编码器不同的是,这种预测的方式可以促使模型真正读懂数据的语义信息才能够实现,所以相当于间接地约束编码器不单单靠 pixel-wise 层面来训练,而要同时考虑更多的语义信息。【下图所示】
● 最后我们要介绍的是根据类似「数据增广」的方式来寻找自监督上下文。ICLR 2018 的工作是给定一张输入的图片,我们对其进行不同角度的旋转,模型的目的是预测该图片的旋转角度。这种朴素的想法最后带来的增益竟然是非常巨大的,所以「数据增强」对于自监督学习也是非常有益处的,我个人的想法是「数据增强」不仅带来了更多的数据,还增加了「预训练」模型的鲁棒性(健壮性)。【下图所示】
● 自监督学习在「预训练」模型中的成功让研究人员觉得非常兴奋,同时也激发了更多的灵感。我们之前介绍的模型都是在专注如何寻找自监督信息,而自监督学习一定要脱离下游的具体任务吗?答案是否定的,越来越多的工作开始思考自监督学习和具体任务紧密结合的方法(Task Related Self-Supervised Learning)。【如下图所示】
● Lee, Hankook et al 探索了在「多任务学习」中增加自监督学习的可能,他们将普通的分类任务中嵌入了旋转预测任务。除了简单的多任务学习,也可以设计联合学习策略,直接预测两种监督信息。同样的想法也被用到了小样本学习中,一个分支进行传统的小样本分类,另一个分支来进行自监督旋转预测,虽然这篇文章的想法和设计不是很亮眼,但提升还是比较明显的。【如下图所示】
● 而自监督和半监督学习也可以进行结合,对于无标记的数据进行自监督学习(旋转预测),和对于有标记数据,在进行自监督学习的同时利用联合训练的想法进行有监督学习。通过对 imagenet 的半监督划分,利用 10% 或者 1% 的数据进行实验,最后分析了一些超参数对于最终性能的影响。【下图所示】
● 这两篇文章最后都中了 ICCV 2019,说明目前来说审稿人对于这类任务相关的自监督模型都是比较感兴趣的。
2.3.2 基于时序(Temporal Based)
● 之前介绍的方法大多是基于样本自身的信息,比如旋转、色彩、裁剪等。而样本间其实也是具有很多约束关系的,这里我们来介绍利用时序约束来进行自监督学习的方法。最能体现时序的数据类型就是视频了(video)。
● 第一种思想是基于帧的相似性,对于视频中的每一帧,其实存在着特征相似的概念,简单来说我们可以认为视频中的相邻帧特征是相似的,而相隔较远的视频帧是不相似的,通过构建这种相似(position)和不相似(negative)的样本来进行自监督约束。【如下图所示】
● 另外,对于同一个物体的拍摄是可能存在多个视角(multi-view),对于多个视角中的同一帧,可以认为特征是相似的,对于不同帧可以认为是不相似的。【如下图所示】
● 还有一种想法是来自 @Xiaolong Wang 大佬 ICCV 2015 的基于无监督追踪方法,首先在大量的无标签视频中进行无监督追踪,获取大量的物体追踪框。那么对于一个物体追踪框在不同帧的特征应该是相似的(positive),而对于不同物体的追踪框中的特征应该是不相似的(negative)。【下图所示】
● 除了基于特征相似性外,视频的先后顺序也是一种自监督信息。比如 ECCV 2016, Misra, I. 等人提出「基于顺序约束」的方法,可以从视频中采样出正确的视频序列和不正确的视频序列,构造成正负样本对然后进行训练。简而言之,就是设计一个模型,来判断当前的视频序列是否是正确的顺序。【下图所示】
● 基于顺序的约束还被应用了到了对话系统中,ACL 2019 提出的自监督对话学习就是基于这种思想。这篇文章主要是想解决对话系统中生成的话术连贯性的问题,期待机器生成的回复和人类交谈一样是符合之前说话的风格、习惯等等。从大量的历史预料中挖掘出顺序的序列(positive)和乱序的序列(negative),通过模型来预测是否符合正确的顺序来进行训练。训练完成后就拥有了一个可以判断连贯性的模型,从而可以嵌入到对话系统中,最后利用「对抗训练」的方式生成更加连贯的话术。【下图所示】
● 而 BERT 的另一种训练方式,Next Sentence Prediction 也可以看作是基于顺序的约束,通过构造大量的上下文样本,目的是让模型理解两个句子之间的联系。这一任务的训练语料可以从语料库中抽取句子对包括两个句子 A 和 B 来进行生成,其中 50% 的概率 B 是 A 的下一个句子,50% 的概率 B 是语料中的一个随机句子。该任务预测 B 是否是 A 的下一句。
2.3.3 基于对比(Contrastive Based)
● 第三类自监督学习的方法是基于对比约束,它通过学习对两个事物的相似或不相似进行编码来构建表征,这类方法的性能目前来说是非常强的,从最近的热度就可以看出,很多大牛的精力都放在这个方向上面。关于这个方向的方法,《Contrastive Self-Supervised Learning》总结的比较好。这里我们再简单的阐述一下,加上一些我个人的看法。
● 其实我们第二部分所介绍的基于时序的方法已经涉及到了这种基于对比的约束,通过构建正样本(positive)和负样本(negative),然后度量正负样本的距离来实现自监督学习。核心思想——>样本和正样本之间的相似度远远大于样本和负样本之间的相似度: s c o r e ( f ( x ) , f ( x + ) ) > > s c o r e ( f ( x ) , f ( x − ) ) score(f(x),f(x^{+}))>>score(f(x),f(x^-)) score(f(x),f(x+))>>score(f(x),f(x−))
● 这里的 x x x 通常也称为 「anchor」数据,为了优化 anchor 数据和其正负样本的关系,我们可以使用「点积」的方式构造「距离函数」,然后构造一个 softmax 分类器,以正确分类正样本和负样本。这应该鼓励「相似性度量函数(点积)」将较大的值分配给正例,将较小的值分配给负例: L N = − E X [ l o g e x p ( f ( x ) T f ( x + ) ) e x p ( f ( x ) T f ( x + ) ) + ∑ j = 1 N − 1 e x p ( f ( x ) T f ( x j ) ) ] \mathcal{L}_N=-\mathbb{E}_X[log\frac{exp(f(x)^Tf(x^+))}{exp(f(x)^Tf(x^+))+\sum_{j=1}^{N-1}exp(f(x)^Tf(x_j))}] LN=−EX[logexp(f(x)Tf(x+))+∑j=1N−1exp(f(x)Tf(xj))exp(f(x)Tf(x+))]
● 通常这个损失也被称为 InfoNCE (多么炫酷的名字啊),后面的所有工作也基本是围绕这个损失进行的。
● 我们首先介绍 ICLR 2019 的 DIM,DIM 的具体思想是对于隐层的表达,我们可以拥有全局的特征(编码器最终的输出)和局部特征(编码器中间层的特征),模型需要区分全局特征和局部特征是否来自同一图像。所以这里 x x x 是来自一幅图像的全局特征,「正样本」是该图像的局部特征,而「负样本」是其他图像的局部特征。这个工作的开创性很强,已经被应用到了其他领域,比如 graph。【如下图所示】
● CPC 同样是一个基于「对比约束」的自监督框架,主要是可以应用于能够以有序序列表示的任何形式的数据:文本、语音、视频、甚至图像(图像可以被视为像素或块的序列,后面作者也给出了具体的想法)。CPC 主要是利用「自回归」的想法,对相隔多个时间步长的数据点之间共享的信息进行编码来学习表示,这个表示 c t c_t ct 可以代表融合了过去的信息,而正样本就是这段序列 t t t 时刻后的输入,负样本是从其他序列中随机采样出的样本。CPC 的主要思想就是基于过去的信息预测的未来数据,通过采样的方式进行训练。【如下图所示】
● 所以基于对比约束的自监督方法主要围绕如何选取正负样本, @慕容腹黑 大佬提出了利用多模态(多视角)的信息来构造样本 ,一个样本的多个模态为正样本,其他样本的模态为负样本。我认为这个工作还是很有启发性的,很遗憾 ICCV2019 没有中,真心希望这篇文章能够有一个好的归宿。【下图所示】
● 对于具体的实现上,因为存在大量的样本,如何存取和高效的计算损失是急需解决的。研究人员提出了 memory bank 的概念,也就是说我们把之前模型产生样本特征全部存起来,当前计算损失的时候直接拿来用就可以了,每次模型更新完后将当前的特征重新更新到 memory bank 中,以便下一次使用。这个工作的缺点就在于每次需要将所有样本的特征全部存起来。后续 kaiming 大神提出的 Moco, 主要的贡献是 Momentum Update、 shuffleBN 等技术点来优化这个过程。关于 Moco 知乎上已经有了很多的解释了,推荐大家阅读 《无监督学习: Kaiming一作 动量对比(MoCO)论文笔记》,这里我们就不展开介绍了。【下图所示】
● 最近 hinton 组又放出了 SimCLR,这个工作主要是对于一个输入的样本,进行不同的「数据增广」方式,对于同一个样本的不同增广是正样本,对于不同样本的增广是负样本。整个过程比之前 kaiming 提出的动量对比(MoCo)更加的简单,同时省去了数据存储队列。这个工作的创新主要有两个:
- 在表征层和最后的损失层增加了一个非线性映射可以增加性能 (这个地方我比较好奇,希望能有大佬给出更直观的解释)。
- 数据增广对于自监督学习是有益的,不同数据增广方式的结合比单一增广更好。同时作者公布了非常多的实验经验,比如自监督学习需要更大的 batch 和更长的训练时间。
2.4 Discussion
● 通过阅读这些经典工作,我自己的思考主要如下:
- 找到合适的辅助任务(pretext)对于自监督学习是最需要解决的问题。
- 数据和资源越多,自监督预训练的效果会更好(Bert, MoCo, SimCLR)。
- 自监督直接和具体任务的结合(Task Related Self-Supervised Learning)是个可探索的方向,已经在很多任务中初露头角,也比较符合审稿人的口味。
● 以上大部分内容转自《Self-supervised Learning 再次入门》,作者:信息门下憨狗,部分内容笔者有做修改和强调。 [发布于 2020-02-24 22:43]
三、参考附录
[1] 主要参考:《Self-supervised Learning 再次入门》.
[2] 其他参考:《自监督学习》.
⭐️ ⭐️