4.9 视觉自监督学习SimCLR、BYOL与MAE
1.为什么自监督:图那么多,标签那么贵
说起来,前面5.1 节我们聊过预训练这件事,那条思路是先在海量数据上把模型养大,再拿到下游任务上去微调。可视觉这边一直有个老问题,标注太贵了。检测里给一张图画框、标类别,一张图往往要花上几分钟的人工,要标到上百万张图,开销是相当惊人的。我记得看过一本书里讲,某家大厂为了训一个检测模型,光是标注费就花了小几百万,这还不算后续返工的成本。
可网上的图呢,到处都是,而且几乎都是无标注的。把这么一大堆便宜货白白浪费掉,未免太可惜了。于是自监督学习这条思路就冒了出来,它要做的事情说白了很简单,让模型从海量无标注图像里自己学一个还不错的表示,之后再拿这个表示去配各种下游任务。
这里我先把表示这个词讲清楚。一张图本身是成千上万个像素,模型把它压成一串数值 , 就叫这张图的表示,也叫特征向量。这串数要是学得好,猫的图和猫的图在表示空间里就该挨得近,猫的图和狗的图就该远一些。下游任务拿这串数去做分类、检测,就比直接啃像素轻松多了。
自监督的关键,是人为造一个监督信号出来。既然没有人工标签,那就从数据本身里挖一个。下面要讲的三种方法,SimCLR、BYOL和MAE,差别其实就在造监督信号这件事上各走各的路。说穿了,这三家各显神通,但目的都是一个,让模型学到一串能用的 。
2.SimCLR:同一张图的两个模样
我们先讲对比学习里最有代表性的SimCLR。它的核心想法特别好懂,让模型认出同一张图的不同样子是同一个东西。
具体怎么做呢,拿一张图 , 就是原图,对它做两次不同的数据增强,比如一次随机裁剪再加点颜色抖动,另一次也随机裁剪但裁的位置和颜色扰动不同,这样得到两个新图 和 , 读作x波浪,表示增强后的视图。这两个视图虽然长得不一样,但都来自同一张原图 ,我们管它们叫正样本对。
SimCLR的训练流程大致这么几步。先用一个编码器 把 和 各自压成表示,记作 和 , 是带参数 的编码网络, 就是网络里那些权重,括号里的点表示输入。然后再接一个小一些的投影头 ,把 和 再映射成 和 ,这个 才是真正参与损失计算的那一串数。投影头这一步看着多余,其实论文里实测发现加上它效果会明显好,所以才留着。
损失函数用的是InfoNCE。InfoNCE这个名字里NCE出自一种叫噪声对比估计的老方法,Info提醒我们它和信息论里的互信息有那么点关系。它的形式长这样:
我一个个符号解释一下。 是两个向量的余弦相似度,衡量两个向量方向有多接近,取值在 到 之间。 是温度系数,是个超参数,它控制分布的尖锐程度, 越小,模型越在意那个最难的负样本。 是批量大小,一个批量里有 张图,两张增强视图加起来就是 个视图。 是指数函数。 是指示函数, 不等于 时取 ,等于 时取 ,意思是把 自己排除掉,不和自己做相似度。 是自然对数。 分母那一长串,就是把批量里所有其他视图都当作负样本,全部加起来。 整体再添个负号,是因为我们要最小化损失,但希望分子那项越大越好。
这个损失要做的事情,直观上就是让正样本对 和 挨得近,同时把批量里其他图生成的视图都推开。打个比方,有点像班里分组游戏,老师让同一个同学的两张不同照片分到一组,再把别的同学的照片尽量推远,模型学着学着,就懂得哪些特征是同一个人共有的。小张之前跟我聊,说他第一次读这篇论文最直观的感受,就是这不就是把找不同反过来训成找相同嘛。
这里有个细节得提一下,SimCLR特别吃批量大小。批量越大,负样本越多,对比的效果就越好,原论文里批量开到了4096,普通实验室的显卡根本扛不住。这也是它后来被一些不用负样本的方法慢慢盖过风头的原因之一。
3.BYOL:没有负样本也行
SimCLR那么依赖负样本,工程上挺折腾的。于是有人就想,能不能干脆不要负样本呢。BYOL就是这么冒出来的,它给出一个挺让人意外的答案,能。
BYOL里有两个网络,一个叫在线网络,一个叫目标网络。在线网络和SimCLR那套很像,有编码器、投影头,还多了一个预测器 , 把在线网络的输出再做一次变换。目标网络只保留编码器和投影头,比在线网络少一个预测器,结构上少一截,参数也不靠梯度更新,而是把在线网络的参数慢慢地拷过来,用一个动量系数 控制这个拷贝的速度:
是一个很接近 的数,比如 ,所以目标网络更新得特别慢,像个走路慢悠悠的老先生。 和 分别是目标网络和在线网络的参数, 表示把右边的值赋给左边。
训练时,对一张原图 做两次增强得到 和 。在线网络拿 走一遍,得到预测 ,目标网络拿 走一遍,得到目标输出 。然后把这两边做余弦相似度,作为损失去最小化,让在线网络的预测去贴目标网络的输出。要注意目标网络是不回传梯度的,这叫stop-gradient,损失只通过在线网络那边反传。
最让人觉得玄妙的地方就在这,没有负样本去把它推开,模型凭什么不会塌缩到一个常数解呢。所谓塌缩,就是所有图都输出同一个表示,损失照样为零,但什么也没学到。这个问题当年讨论了很久。后来大家比较一致的看法是,stop-gradient加上那个慢更新的目标网络,组合在一起形成了一种隐式的约束,让模型不得不保留信息。说起来有点像打太极,一只手推、另一只手顺势带,看着没使劲,其实劲都在里头。我之前看过一部讲木匠手艺的纪录片,老师傅带徒弟时总说手要稳、节奏要慢,BYOL的目标网络就有点这个味道。
BYOL的好处很明显,不用挑负样本,批量大小也可以开得小一些,对显卡友好得多。代价是实现细节比较敏感,stop-gradient放错位置模型就立刻塌缩,得照着论文复现,不能凭感觉乱改。
4.MAE:遮住一大半,让它自己补
第三种思路跟前两种又不一样,它走的是生成路线,叫MAE(Masked Autoencoder,掩码自编码器)。这个思路其实在NLP里早就有了,BERT就是把句子里的词随机遮掉一些让模型去猜。MAE把类似的想法搬到了视觉这边。
MAE的做法非常直接。拿一张图,先切成一个个小块,patch,就像把一张照片剪成许多小方块。然后随机遮掉很大一部分,比如遮掉 ,只留 给模型看。模型(通常用ViT)只处理这剩下的可见小块,最后再用一个轻量的解码器去重建被遮住那部分的原始像素。损失就是重建像素和真实像素之间的均方误差,记作 , 是均方误差损失的常用记法,意思是重建像素和真实像素之差的平方取平均。
这里有两个细节特别值得说。一是为什么遮这么多。前两年大家觉得遮个 就够了,可MAE作者发现,视觉里图像的像素冗余度太高了,遮 模型靠周围像素插值就能蒙混过关,学不到什么。要遮到 这种极端比例,模型才会真正去理解整张图的全局结构。二是ViT(Vision Transformer,视觉Transformer)这种结构特别适合干这个,因为它本来就是按小块来处理的,遮掉一些小块对它来说特别自然。卷积网络就没这么方便,因为卷积的卷积核是个连在一起的小窗口,处理大量零散的可见小块会很别扭。
打个比方,MAE有点像让小张看一幅国画,把画的大半都用纸盖住,只露出零星几笔墨,让他猜整幅画的样子。要蒙住一大半才难,他才肯动脑子去想整体构图。只蒙一小块,他顺手就照着旁边的颜色填上了,根本不用过脑子。有个我挺喜欢的足球运动员叫梅西,他在场上经常只能看到球门的一角、对方后卫的一只手,但脑子里已经把整条进球路线补出来了,这种从局部推整体的能力,恰好是MAE想要模型学会的。
MAE的好处是简单、高效。因为它只对那 的可见小块做编码,编码阶段的计算量大幅下降,训练比前两种方法快不少。这一点对工程来说格外讨喜。
5.学到的表示能搬到哪儿
最后我们说说,费这么大劲自监督训出来的表示,到底能派什么用场。
答案是下游迁移。模型在自监督阶段学好之后,那个编码器 就是一个相当通用的特征提取器。把它接到下游任务上,比如目标检测、语义分割,只需要再喂一小部分有标注的数据做微调,就能拿到很不错的成绩。这正好接上5.1 节我们讲过的预训练范式,自监督把怎么造预训练数据这件事从靠人工标变成了靠数据本身,从根上把成本降了下来。
说起来,这条线其实是视觉走向基础模型的重要一步。再往大了讲,后来把图像和文本一起做的CLIP,把对比学习的思路用到了图文对上,让模型同时理解图和文字。MAE这种思路也被用到了各种视觉大模型预训练里。这些工作合在一起,才有了今天大家嘴里常说的视觉基础模型。1.4 节我们讲概率信息论时提到过,从数据里估计分布本身就含着一种理解,自监督学习恰好把这句话落到了工程上。
这一篇我们走了三家,SimCLR靠对比、BYOL靠预测、MAE靠重建,路子不一样,目的地都差不多,让模型自己从海量无标注图像里把世界看明白。下一章见。
练习
Q1. SimCLR、BYOL、MAE 这三家做自监督的思路分别是什么?它们造监督信号的方式有什么不同?
SimCLR 走对比路线:对同一张图做两次增强得到正样本对,用 InfoNCE 损失让正样本对的表示挨近、把批量里其他图的视图推开,靠"找相同"学表示。BYOL 走预测路线:有在线网络和目标网络,让在线网络的预测去贴目标网络的输出,靠 stop-gradient 和慢更新的目标网络形成隐式约束,不需要负样本。MAE 走生成路线:把图切成小块、随机遮掉一大半(如 75%),让模型(通常用 ViT)只看可见小块去重建被遮像素,靠"补全"学表示。三家各显神通,目的都是让模型从无标注图里学一串能用的表示。
Q2. MAE 为什么要把图遮掉高达 75%,而不是像 BERT 那样只遮 15%?
因为图像的像素冗余度太高了。只遮 15% 模型靠周围像素插值就能蒙混过关,学不到什么;要遮到 75% 这种极端比例,模型才会真正去理解整张图的全局结构、被迫动脑子补全。这也是 ViT 特别适合干这活的原因——它本来就按小块处理,遮掉一些小块很自然;卷积网络的卷积核是连在一起的小窗口,处理大量零散可见小块会很别扭。
Q3. BYOL 没有负样本,模型凭什么不会塌缩成所有图都输出同一个表示?SimCLR 又为什么特别吃批量大小?
BYOL 靠 stop-gradient(目标网络不回传梯度)加上那个用动量系数 慢更新(如 0.99)的目标网络,两者组合形成一种隐式约束,让模型不得不保留信息,不至于塌缩。但实现细节敏感,stop-gradient 放错位置就立刻塌缩。SimCLR 特别吃批量大小是因为它的对比效果依赖负样本:批量越大负样本越多,对比越有效,原论文批量开到 4096,普通实验室显卡根本扛不住,这也是它后来被不用负样本的方法慢慢盖过风头的原因之一。