上一讲第 11 讲:大规模分布式训练 下一讲第 13 讲:生成模型(一)

第 12 讲:自监督学习

Self-Supervised Learning —— 从"标注瓶颈"出发理解为什么需要自监督;掌握"代理任务 + 编码器 + 下游任务"的总体框架与评估维度;逐一拆解四个经典代理任务(旋转预测、拼图、图像补全、上色与 Split-Brain Autoencoder,以及上色引出的视频跟踪);深入当今预训练主力框架 MAE(掩码自编码器)的完整流程与消融实验;最后系统学习对比学习(contrastive learning):正负样本定义、InfoNCE 损失的推导与温度参数分析、互信息下界,以及 SimCLR、MoCo(含 MoCo v2/v3)、CPC、DINO 等代表方法

本讲概览:

本讲是课程今年新加入的主题,老师认为它"恰逢其时且非常重要"。讲座先快速回顾:上一讲讲了 GPU 与多卡大规模训练,再往前已经覆盖了分类、语义分割、目标检测、实例分割等所有关键视觉任务,也讲过如何可视化理解模型。随后指出核心矛盾:网络学到的特征(feature/embedding/latent space)对图像来说是极好的表示——在特征空间做最近邻、接一个线性层就能出类别——但要大规模训练出这样的网络,需要海量人工标注(分割甚至要逐像素标注)。于是引出本讲主线:能不能不靠人工标注,就训练出好的特征提取器?答案是自监督学习——在无标签数据上定义一个"代理任务"(pretext task),监督信号自动从数据本身生成。老师依次讲了四个经典代理任务:旋转预测(2018,4 分类 0/90/180/270 度)、拼图(2016,9 块打乱预测 64 种排列之一)、图像补全(掩码 + 重建,配合对抗损失)、上色(LAB 色彩空间,给 L 通道预测 A/B 通道;扩展为 Split-Brain Autoencoder 与 RGB↔深度;再延伸到视频上色并意外获得无标签跟踪能力)。之后用大篇幅讲解 2021 年的 MAE(Masked Autoencoder):非对称编码器-解码器、75% 高掩码率、共享 mask token、仅在掩码块上算 MSE、线性探查 vs 微调、随机掩码最优、性能超过 DINO 与 MoCo v3。最后进入对比学习:同一图像的两种变换互为正样本、批内其他图像为负样本,在表示空间"吸引正样本、排斥负样本";老师完整推导了 InfoNCE 损失(本质是多类交叉熵),讲解它作为互信息下界的理论与"负样本越多界越紧 → 需要超大 batch"的推论,然后介绍 SimCLR(双增强、2N 视图、投影头设计与大 batch 需求,成绩可比全监督)与 MoCo(负样本队列 + 动量编码器解决无法回传的问题,MoCo v2 融合两者优点大涨点),并简要点名 CPC、MoCo v3 与教师-学生结构的 DINO。因时间所剩不多,讲座在 DINO 处收尾。

一、开场与动机:好特征很贵,人工标注更贵

老师先用两分钟串起前情:本周二的上一讲介绍了 GPU 的使用,以及如何用多块 GPU 做更大规模(larger scaling)的训练——这是今年课程新增的内容,随着模型规模和应用的增长非常及时。再往前,课程已经覆盖了计算机视觉的所有关键任务:图像分类、语义分割(semantic segmentation)、目标检测(object detection)、实例分割(instance segmentation)等等,本讲后面还会回头 revisit 其中一些结果。

接着回顾了一个早期课堂上的老话题:最近邻(nearest neighbor)。在课程最初,我们在像素空间里做最近邻——用像素距离判断图像类别——并讨论过它为什么低效。当时的关键观察是:如果改用特征空间里的最近邻,即取卷积网络(或任何架构)某个全连接层输出的特征(feature),以 \(L_2\) 距离为度量,最近邻就变得非常有效。这说明一件事:这些特征对图像来说是很有意义的表示。老师借此梳理了同义词家族:学到的表示(learned representations)、特征(features)、嵌入(embeddings)、潜空间(latent space)——名字不同,指的都是网络中那些"能很好代表图像"的中间量。而且只要能拿到这些特征,再接一个简单的线性模型就能把类别标签取出来。

问题在于:把这样的网络大规模训练出来,始终是个挑战。为什么?老师向全班发问。答案是:规模一大,就需要海量的标注数据——网络从图像输入、到类别标签输出,端到端训练当然能得到对分类很有用的特征,但代价是要人工把图像一张张标出来;如果任务是分割,更要把每张图的每个像素逐一标注,极其费时费力。于是本讲的核心问题浮出水面:

有没有办法绕过人工标注,训练出一个能给我们很好特征的神经网络?手工标签是瓶颈;我们想找到一种绕开它的方式。这个方向就是自监督学习(Self-Supervised Learning)

老师特别强调了这个范式的影响力远不止计算机视觉:正是自监督学习造就了如今的大语言模型——GPT-4 等模型绝大部分是用没有任何人工标注的原始数据训练的。语音领域如此,如今机器人与强化学习领域也大量如此:一旦不需要人工标注,就可以直接采集原始数据来训练。一个生动的例子:湾区街上之所以跑着那么多自动驾驶测试车,就是在采集数据——拿到原始数据后不必逐帧标注,照样能据此训练模型。

二、自监督学习的总体框架:代理任务 + 编码器 + 下游迁移

自监督学习的设定是:手里有一大堆没有任何标签的图像,我们的假设(hypothesis)是——可以设计一个目标函数、一个代理任务(pretext task,又译前置任务),用它训练网络,从图像中学到好特征;等到真正关心的、只有少量标注数据的应用出现时,就把这个训练好的编码器(encoder)迁移过去,为下游任务(downstream task / downstream objective)提取特征。

一个典型场景:从互联网上下载海量自然图像,先在上面做自监督预训练;然后手头有一个小规模标注数据集——比如某个工业应用或医学应用只有少量标注图像——此时用迁移来的知识提特征、完成分类或任务。

框架的组成拆开看是这样的:

这样我们就有了目标函数、损失函数和一个可训练的神经网络。老师补充:当结构是"编码器 + 解码器"时,这更接近一种自编码(autoencoding)框架,后面会简短提到。预训练完成后,使用时把第二个模块撤掉,在编码器后面加一层(或一个线性函数、一个小的全连接网络)来预测真实标签——这些标签现在才来自数据集。

我们往往刻意选择很浅(shallow)的下游头:如果特征足够好,把类别从特征里"取出来"就不需要太多训练。这也是后面评估表示质量的一个朴素信号。

如何定义代理任务本身并不容易,存在很多种方式。老师给出两个必须满足的要求:其一,任务要足够通用(general enough),能学到好特征;其二,不需要人工标注——标签必须来自数据本身。随后预告了四个要快速过一遍的例子:

解决代理任务的过程会迫使模型学到好特征——这正是我们想要的;而且所有这些任务的标签都可以自动生成,满足上面两条标准。

三、如何评估一个自监督学习框架

在进入具体任务之前,老师给了一份"评估清单"。自监督框架有很多可观察的侧面:

四、旋转预测:从"视觉常识"出发

第一个正式讲解的代理任务是旋转预测(rotation prediction):把图像旋转一个角度(可以是任意度数),让模型以图像为输入、预测它被旋转的角度。整体结构是一叠卷积层,末端接全连接网络,视具体设定做回归或分类。训练完成后,把代理任务专属的 FC 层拆掉,换上一层或多层分类层,用真实的物体标签训练这个线性部分,就完成了迁移。

这个任务背后的假设是:一个模型只有具备了视觉常识(visual common sense)——知道物体不受扰动时"应该长什么样"——才能认出正确的旋转方向。而如果模型能捕捉到这一点,也就意味着它能把整张图像总结成一组有用的好特征。老师强调,这类模型基本都是围绕"视觉常识"这个概念设计的。

具体到一篇 2018 年的论文:作者只探索了四个角度——0、90、180、270 度——把图像按其中之一旋转,用 CNN 预测属于哪一种旋转。因为只有四种输出,这自然变成了一个4 分类任务(类别 0、1、2、3),不必预测角度的精确数值。靠这个任务学到的表示,作者做了下游迁移:冻结第一、第二层,只微调最后一个卷积层和线性分类层——不是整网微调,也拿到了非常好的结果。

4.1 CIFAR-10 上的观察:预训练改变的是起点

CIFAR-10(课程早前介绍过的数据集)上可以观察到:有预训练的模型初始准确率就很高——一上来就处于好状态,最初几个迭代里就已经对物体有了不错理解。但老师提醒:CIFAR-10 本身不算难训;如果任务足够简单,全监督版本和带预训练的版本最终往往收敛到相同的准确率。预训练的价值体现在难得多的应用上——那时若不做大规模预训练,纯监督框架往往得不到同样好的结果。

4.2 PASCAL VOC 与三组任务

论文还在 PASCAL VOC(老师口述为 2017 版)上做了实验,该基准涉及分类、检测、分割三组任务,作者对每组任务分别尝试"只训若干全连接层"或"所有层都训"等不同设定。要点有三:

4.3 注意力图对比:监督"聚焦",自监督"全局"

论文还按第二节的评估清单检查了特征质量:利用之前讲过的 Grad-CAM、各类基于注意力的方法,把特征投影回图像空间,看模型在"看哪里"。对比很有意思:监督模型的注意力图更聚焦——它只需要解决分类这一个任务,捕捉到眼睛及其周围形状就够了,不太关心其他区域;而自监督模型覆盖的区域更多——因为不知道下游任务是什么,它必须对图像有更整体(holistic)的理解,才能在很多可能的任务上都表现好。

五、从色块定位到拼图谜题

另一个流行的代理任务建立在 \(3 \times 3\) 网格上:给定某个补丁(patch),预测它相对于中心参考补丁的位置。课上举的例子:来自右上角位置的补丁,输出应为 3。因为 \(3 \times 3\) 网格去掉中心还剩 8 个位置,这构成一个8 分类任务

随后的跟进论文把它升级成真正的拼图(jigsaw puzzle)框架:不再问"这是 8 个位置中的哪一个",而是预测完整的排列(permutation)。做法是:同一个 \(3 \times 3\) 网格取全部 9 块补丁、随机打乱,让网络说出正确的排列是哪一种。老师当场提问:这种设定下排列数是多少?同学答对:9 的阶乘(\(9!\))——约 36 万(362,880),是个巨大的数字。作者的对策是建一张只含 64 种排列的查找表(lookup table):打乱时只从这 64 种里选,输出也就是一个 64 维向量——于是又回到了一个简单的64 分类任务。该工作发表于 2016 年,在相同数据集、与前面类似的任务和监督设定下,超越了此前的一系列框架。

答疑

课堂提问:为什么是 64?老师回答:这几乎是个任意的(arbitrary)选择。\(9!\) 太大,全部预测不现实;而且那 36 万种排列里很多只是交换了一块补丁、彼此差别太小。作者的做法是挑选相互之间距离(差异)最大的一批排列,从中取 64 种——目的是保证足够的变化度,同时把任务控制成一个规模合适的分类问题,而不是别的任务形式。

六、图像补全:带掩码的自编码器

第三个代理任务是补全/修复(inpainting)——预测缺失的内容。做法是一种简单的掩码(masking)策略:遮住图像的一部分,让模型补出被遮的部分。关键便利在于:因为完整图像我们本来就有,期望输出(真值)是现成的。流程上:编码器把被遮的输入映入特征空间,中间有若干全连接层,再由解码器解出缺失部分;损失函数将输出与真值做比较——本质上是学习重建缺失的像素。老师指出,这就是课程里反复出现过的自编码器(autoencoder)的一种形态:把输入编码成表示、再从表示解码出输出,只是这个自编码器是用掩码目标训练出来的。

损失函数的形式:对图像 x 与"编码再解码"后的输出做差,并与掩码做逐元素乘法(element-wise multiplication)——因为损失只应在被掩码的区域上计算:

$$L_{\mathrm{rec}}(x) = \left\Vert \bigl( x - \mathrm{Decoder}(\mathrm{Encoder}(x)) \bigr) \odot M \right\Vert$$  (\(M\) 为掩码,仅在缺失区域非零)

补全任务的评估本身有点微妙:一张图有很多种合理的补法,不存在唯一正确输出。而且早期的重建式框架生成结果往往又模糊又过度平滑(fuzzy and smooth)——因此这篇论文额外加了一个对抗目标函数(adversarial objective),保证生成结果看起来真实。老师卖了个关子:细节不展开,因为这是下一讲生成模型的主题。加上对抗损失后,重建区域的质量确实更好了;同样在分类、检测、分割基准上带来了收益。老师预告:这种"重建式 + 掩码"的思路后面还会回来——它是当下最常用的预训练方式(即后文的 MAE)。

七、上色、Split-Brain Autoencoder 与视频跟踪

7.1 LAB 色彩空间与上色任务

第四个代理任务是图像上色(colorization),设定同样简单:数据集本来是彩色图像,我们把它拆成若干通道(channels),把亮度/光照(lightness/illumination)与颜色本身分开。计算机视觉里最常用 RGB,但要做这种分离,有更合适的色彩空间——例如 LAB 色彩空间:一个通道 \(L\) 表示亮度,两个通道 \(A\)、\(B\) 定义实际颜色;三者合起来可以还原彩色图像。于是代理任务就是:给定 \(L\) 通道,预测 \(A\) 和 \(B\) 通道——不需要任何人工标注,答案已经在数据里。

7.2 Split-Brain Autoencoder:双向互推

一个自然的延伸是:为什么只做"给 \(L\) 预测 \(A\)、\(B\)"?反过来也可以。由此得到 Split-Brain Autoencoder(裂脑自编码器):把输入图像拆成亮度通道(1 个通道)与颜色通道(2 个通道),训练两个网络(两组层)互相预测对方;计算损失与回传时,把两路的输出合并还原出完整图像,用 \(L_2\) 损失(任何距离函数都行)训练。

更一般化的表述是:给定一组通道 \(X_1\) 预测另一组通道 \(X_2\),同时反向也做一遍,两个方向各对应一个神经网络 \(F_1\)、\(F_2\);合并输出得到图像,损失函数照旧。这个框架不限于颜色与亮度:还可以用在 RGBD 传感器数据上——RGB 通道 + 深度通道,比如机器学习中常用的 Kinect 类传感器——给定 RGB 预测深度,反之亦然。这在下游应用中被证明非常成功。性能上,Split-Brain 与上色模型学到的特征接上分类头后都有不错的类别预测准确率(用的是 \(F_1\)、\(F_2\) 拼接起来的特征),但仍不如监督学习——毕竟没有标签,只靠学到的特征。老师再次加了一句免责声明:这些方法都诞生于大语言模型、大视觉模型之前,只为特定任务训练,不指望它们解决一切

7.3 上色本身就有用:约塞米蒂的倒影

上色任务的有趣之处在于:它不仅可用于预训练,它自己就是个有用应用——可以给没有彩色版本的图像和视频上色。论文里一张经典结果是把约塞米蒂的半穹顶(Half Dome)照片上色:可以看到物体(半穹顶、树木、桥梁)与它们在水中的倒影颜色一致——模型在海量数据上训练后,隐式理解了"倒影应当保持原物体的颜色"这样的对应关系。

7.4 视频上色 = 隐式学习跟踪

上色还能扩展到视频:取一帧有颜色的参考帧(reference frame),为后续帧上色。这件事的深层意义在于:要给后续帧上色,模型必须在帧间追踪像素与物体,从而隐式学会了跟踪。由此提出假设:学习给视频帧上色,应当能让模型在无标签的情况下学会跟踪区域或物体

机制

参考帧上色的具体机制(注意力即相似度)。要给输入帧(目标帧)上色,需要为其中每个待上色的像素找到参考帧中对应物体/像素的位置,把那里的颜色拷贝过来作为目标颜色。实现方式与课程讲过的注意力(attention)非常类似:先用 CNN 提取两帧中每个像素周围的特征;对目标帧的每个像素,用其特征与参考帧所有像素的特征计算注意力(距离/相似度)——老师强调"注意力本质上就是两者的相似度";随后以注意力为权重对参考帧的颜色做加权平均,作为该像素的输出颜色。写成公式:

$$c_j = \sum_{i \in \mathrm{ref}} a_{ji} \cdot c_i^{\mathrm{ref}}, \qquad a_{ji} = \mathrm{softmax}_i\bigl( f(x_j) \cdot f(x_i^{\mathrm{ref}}) \bigr)$$

其中 \(f\) 为 CNN 提取的像素特征,\(a_{ji}\) 是目标帧像素 \(j\) 对参考帧像素 \(i\) 的注意力。由于数据里本来就有真实颜色,损失可以直接对颜色计算并回传。用参考帧约束后,上色在时间上高度一致;若逐帧独立上色、没有这种跨帧约束,常会看到人的衬衫或衣物逐帧变色

更妙的是副产物:既然已经算出了到参考帧的注意力,就能顺手跟踪视频中的物体、分割区域,甚至识别关键点(key points)——这些都是非常有意思的应用。

八、课堂问答:标签从哪里来?网络怎么搭?

讲完四个任务后老师停下来答疑,几个问答值得原样记录,因为它们澄清了自监督学习最容易被误解的地方。

问 1:编码器一开始并不"懂"数据,它是怎么学到好表示的?答:所有这些任务——解码、分类或回归——都在生成某种输出,训练正是通过预测这些输出来驱动编码器。如果预训练数据是从互联网或 ImageNet 拿来的自然图像,那么学到就是一个能从这类图像中提取特征的编码器;撤掉解码器、接上分类器后,只需训练分类器那部分,因为编码器早已在代理任务中被训练好了。

问 2:预训练编码器的"标签"是解码器提供的吗?答:是的——这正是定义代理任务的目的:我们要有某种标签/输出,在预测这些标签的过程中,编码器同时被训练。

问 3:编码器和解码器是一个大网络,还是两个网络?答:完全取决于具体工作。有些情形是一整个网络——例如旋转预测里,那几层 FC 就是"分类器",换掉它即可;有些情形是两个端到端训练的网络——例如"编码一张图、解码出另一张图"的自编码设定,因为要利用中间的表示空间;而在接下来要讲的掩码自编码器里,编码器与解码器甚至毫无对称性,可以是两个完全不同的框架/架构。它们可以同属一个架构家族(CNN、ResNet),也可以是完全不同的两个架构。

老师还回应了"旋转任务是否太局限"的疑问:这些是最早的一批自监督方法,本就不指望解决一切。假设是:模型若能说出"这是旋转了 90 度",就隐式理解了正确的方向与朝向,那么给它一张未旋转的图,它也能认出图中内容——但老师承认,这本身确实是个有限的任务

九、掩码自编码器 MAE:当今预训练的主力框架

接下来是本讲的重头戏之一:MAE(Masked Autoencoder,掩码自编码器),发表于 2021 年,此后跟进工作极多,是许多任务上表现优异的预训练框架——老师直言:如今想在原始数据集上做预训练时,我们经常就用 MAE 这个框架。它与第六节的"掩码 + 补全"同属重建式框架,但远为精细:不是只选一块掩码,而是在图像的大量补丁、大量位置上做掩码,采样率也激进得多——50% 甚至 75% 的掩码率。大规模训练下,MAE 不仅重建得出全部被掩区域,还训出了能把图像总结成好特征的非常好的编码器

9.1 整体流程:非对称的编码器与解码器

拆解

编码器:一个大型 ViT。与课程讲过的 ViT(Vision Transformer)一致:图像切成补丁(patch);对补丁做均匀随机采样(uniform sampling),实验表明 75% 的掩码率非常高效。也就是说,编码器只看 25% 的补丁。保留下来的补丁先经线性投影嵌入到嵌入空间,再加位置嵌入(positional embedding)——与 ViT 完全相同——然后经过一叠 Transformer 块。编码器本身很大(large ViT),这是 MAE 敢用高掩码率的前提之一。

高掩码率一举两得。其一,任务变得非常有挑战性——在自监督的语境里,"挑战大"意味着代理任务有意义:模型必须学到好特征才能完成重建。其二,等同于极强的数据增强:每次随机遮 75%,同一张图可以在训练中被反复复用很多次,等于凭空造出海量训练数据,足以喂饱那个巨大的编码器。

解码器:处理"完整序列"的 Transformer。编码器输出的是未掩码补丁的嵌入;对于被掩码的位置,MAE 放入一个共享的、可训练的 mask token——老师说它非常类似 ViT 里的 class token,可以理解成某种"平均补丁 / 平均表示",虽不可直接解读,但概念上就是个占位的平均量。把(未掩码嵌入 + mask token)拼成长序列喂给解码器——另一个 Transformer 框架(与编码器不对称,通常更浅更窄)——输出投影为整张图像所有补丁的像素值;重建目标是完整图像,但损失只算掩码块。

损失:仅在掩码补丁上的 MSE。

$$L_{\mathrm{MAE}}(x) = \frac{1}{|M|} \sum_{i \in M} \bigl\Vert x_i - \hat{x}_i \bigr\Vert_2^2$$  (\(M\) 为被掩码补丁集合,\(\hat{x}\) 为重建值)

与第六节的 inpainting 损失一样,通过只在掩码区域计算损失来聚焦"预测缺失"。

9.2 下游使用:线性探查 vs 微调

论文展示了两种迁移方式:线性探查(linear probing)——编码器冻结,在学到的表示上只训一个线性函数来完成最终任务;微调(fine-tuning)——预训练编码器也参与微调,可以是全部层,或只微调若干个 Transformer 块。两者的角色不同:线性探查度量的是表示质量本身(特征到底有多好),而微调挖掘的是模型适配新任务的潜力。老师建议有兴趣的同学去读原文与后续工作。

9.3 消融实验:MAE 为什么这样设计

论文围绕以下维度做了系统的消融(ablation):掩码率(75% 给出很高的准确率,故被选用)、解码器深度与宽度、mask token 的使用、重建目标的形式、数据增强的作用,以及掩码采样方法——到底该用随机掩码、块状(block)掩码还是网格(grid)型掩码?结论是随机掩码效果最好

最终结果:MAE 的表现显著优于当时更先进的对比学习框架——包括 DINOMoCo v3(两者下文都会讲到)。一个重建式的框架压过了对比学习的代表,这也是老师把 MAE 讲得格外细的原因。

答疑环节还有人追问 mask token 的细节,老师复述了一遍:编码器是 ViT 风格、每个输入补丁对应输出一个 token;被掩码的位置统一放入那个共享的、可学习的 mask token(类似平均 token),拼成长序列后由解码器 Transformer 输出并投影为像素值。

拓展

掩码建模的家谱:从 BERT 到 BEiT 与 VideoMAE。MAE 的"遮住-预测"思想与 NLP 中 BERT 的掩码语言模型一脉相承,是"BERT 之于图像"最成功的形态之一。同一时期还有 BEiT:不直接重建像素,而是先离线训练一个离散 VQ tokenizer,把图像块变成视觉词表索引,再让模型预测这些离散 token(类似 NLP 的分类式输出)。视频侧的 VideoMAE 则发现视频帧间冗余极高,需要高掩码率(90% 以上)+ tube masking(同一空间位置的掩码沿时间延伸成"管道")才够挑战性,说明掩码率的最优值与数据冗余度直接相关。此外,MAE 的"编码器只算 25% 补丁"带来的训练加速(约 3 倍以上)也是它流行的现实原因之一——这点与上一讲的大规模训练话题正好呼应。

十、阶段性小结:单一代理任务的局限

在进入对比学习之前,老师做了一次小结:代理任务非常重要,它们的核心是理解"视觉常识"。但与课堂提问相关的一个观察是:单独设计一个代理任务往往很困难,因为学到的表示可能不够通用——任务定义本身就限制了表示的泛化性。如果你用的是补全、旋转预测、拼图或上色,学到的表示擅长的是解这几个特定任务,未必对其他任务同样好。这就自然引出了下一类方法:与其依赖某一个具体任务,不如直接在表示空间的几何结构上做文章。

十一、对比学习:在表示空间中"吸引"与"排斥"

新的出发点建立在一个简单事实上:同一张图像经过各种变换(transformation)后,仍然是同一个对象、只是形式不同;而数据集里还存在长得完全不同的其他对象。于是可以定义这样的任务:

这就是对比学习(contrastive learning)/ 对比表示学习(contrastive representation learning)。这个方向在 2019—2020 年前后涌现了大量论文,老师点出的代表包括 SimCLRMoCoCPC,以及最终的 DINO——DINO 借用了对比学习的概念,但严格说并不是对比学习框架(见后文)。

形式化设定:定义参考图像 \(x\);它的各种变换版本是正样本(positive samples);数据集(或批次)里的其他对象是负样本(negative samples)。我们希望有一个评分函数(scoring function) \(S\),满足:参考图像特征与正样本特征的得分,大于参考图像与任何负样本的得分:

$$S\bigl( f(x),\, f(x^{+}) \bigr) \;\gt\; S\bigl( f(x),\, f(x^{-}) \bigr)$$

十二、InfoNCE 损失:推导、温度参数与互信息

推导

从评分函数到损失函数。要把"吸引正样本、排斥负样本"变成可优化的目标,做法是把得分放进一个 softmax 框架:用 exp 把得分变成概率值,分母汇总所有负样本。实现上采用批学习(batch learning):批次内其他对象的样本充当负样本,参考图像的一个变换充当正样本。于是损失形如:

$$\ell^{(i,j)} = -\log \, \frac{\exp\bigl( s(z_i, z_j) / \tau \bigr)}{\sum_{k=1}^{2N} \mathbf{1}_{[k \neq i]} \, \exp\bigl( s(z_i, z_k) / \tau \bigr)}$$

其中 \(s\) 通常取余弦相似度

$$s(u, v) = \frac{u \cdot v}{\lVert u \rVert_2 \; \lVert v \rVert_2}$$

这就是多类交叉熵。老师特别停下来问全班"这个函数像什么":它就是课程最早已讲过的多类交叉熵(cross-entropy)——softmax 想最大化 10 个输出中某一个的得分、压低其余;这里同理:最大化"参考-正样本"的得分,最小化"参考-负样本"的得分,只是把多类分类的公式套进了对比学习的表述里。这个损失有专门的名字:InfoNCE(Information Noise Contrastive Estimation,信息噪声对比估计),最早在提出 CPC(Contrastive Predictive Coding,对比预测编码)的论文中提出。

温度参数 \(\tau\) 的作用。公式中除在指数上的标量 \(\tau\)(temperature)控制 softmax 的"锐度":\(\tau\) 越小,指数项差异被放大,分布越尖锐,模型对难负样本(与正样本相似度高的负样本)的惩罚越重;\(\tau\) 越大,分布越平缓,梯度对负样本的区分度下降。由于 \(s\) 已被归一化到 \([-1, 1]\),若不加 \(\tau\),exp 的取值范围极窄(约 \([0.37, 2.72]\)),正负样本得分几乎无法拉开——因此实践中必须用一个小于 1 的 \(\tau\)(常见 0.1–0.5)来"放大分辨率"。\(\tau\) 是对比学习最敏感的超参数之一:过大导致难以区分,过小则训练不稳定、对噪声负样本过敏。

互信息下界。CPC 论文给出了理论解释(老师坦言完整讲需要半小时,建议读原文):InfoNCE 损失的负值是 \(x\) 与 \(x^{+}\) 之间互信息(mutual information)的一个下界。互信息度量两个变量之间的依赖性/共享信息——我们想最大化 \(x\) 与 \(x^{+}\) 的共享信息、最小化 \(x\) 与 \(x^{-}\) 的共享信息。因此最小化 InfoNCE,等价于最大化 \(x\) 与 \(x^{+}\) 互信息的一个下界(常用表述:\(I(x;\, x^{+}) \ge \log K - L_{\mathrm{InfoNCE}}\),\(K\) 为负样本数)。

推论:负样本越多,界越紧。论文的另一个理论结果是:负样本数量越大,下界越紧(tighter)。这正是对比学习需要超大 batch size 的原因——更多负样本带来更快、更好的训练收敛。这个约束直接催生了下文 MoCo 的设计。

十三、SimCLR:简单而强大的对比学习框架

SimCLR(A Simple Framework for Contrastive Learning)的流程一句话即可讲完:对每张图像做两次独立的数据增强,两个版本分别送入编码器得到表示 \(h\),再经过一个线性或非线性投影(projection head)得到特征 \(z\),在 \(z\) 空间上计算余弦相似度并施加 InfoNCE 损失。正样本对通过采样数据增强函数生成(各种变换都合理),损失逐对迭代计算。

13.1 批内 2N 个视图:正负样本怎么数

具体地:取 mini-batch 里的 \(N\) 张图,每张做两个增强,得到 \(2N\) 个视图;对其中任意一个视图而言,同源的另一个视图是它唯一的正样本,其余 \(2N-2\) 个全是负样本——第一个视图的正样本是第二个,第二个的正样本是第一个,依此类推遍历所有样本。老师还提醒:作业 3(Assignment 3)里有一道 SimCLR 相关的题目,但作业中的定义与课堂标准定义略有不同,务必按作业说明来做。

13.2 成绩与两个关键设计

SimCLR 非常成功:不用任何标签、只在特征上训一个线性分类器,就超越了以往所有工作,成绩可与全监督框架相当——代价是需要更大的网络,因为学到的是更通用的特征。老师花时间讲了两个最重要的设计选择:

十四、MoCo:负样本队列与动量编码器

MoCo(Momentum Contrast,动量对比学习)要解决的问题:SimCLR 的负样本被绑死在当前 batch 里,想要更多负样本就得开更大的 batch。MoCo 的做法是建一个队列(queue):跨 batch 地维护一份负样本历史,并随训练不断更新——这样负样本数量与 batch 大小解耦了。

但队列带来一个技术困难:队列里的样本不在当前 batch 中,无法对它们反向传播。为此 MoCo 把网络拆成两个编码器:查询编码器(query encoder)处理正样本/查询,键编码器(key encoder)处理负样本/键。训练只更新查询编码器;键编码器通过动量(momentum)方式缓慢跟随:

$$\theta_k \leftarrow m \cdot \theta_k + (1 - m) \cdot \theta_q$$

这个框架在工程实现与后续版本上都非常成功。MoCo v2 是一次有趣的"杂交":把 SimCLR 的非线性投影头与数据增强拿来,与 MoCo 的"batch 与负样本解耦"的队列机制结合,性能大幅提升。老师还提到 CPC(对比预测编码)作为另一个可参考的例子( slides 里有),以及 MoCo v3;最后是 DINO——它与 MoCo 架构相似(也是两个网络,即学生网络与教师网络(student & teacher networks),教师由动量更新),但严格说不是对比学习,因为它不需要负样本。DINO 也是当今广泛使用的特征提取框架之一,可用于图像、有时也包括视频。老师说到这里时间将尽,把 DINO 留作后续讨论。

拓展

DINO 与自蒸馏;DINOv2。字幕只点到"教师-学生、不是对比学习",这里补全思路:DINO(self-distillation with no labels)把两个视图分别喂给学生与教师网络,让学生的输出分布去逼近教师的(交叉熵/自蒸馏损失),教师用动量更新且输出做中心化与锐化——全程没有负样本,却学出了惊人的结构化表示:其注意力图会自发聚焦物体轮廓,甚至可以直接做无监督语义分割。同路线的还有 BYOL(Bootstrap Your Own Latent,靠 predictor + 动量 target 网络避免坍塌)。Meta 在 2023 年推出的 DINOv2 用 1.4 亿级 curated 图像把该配方规模化,得到的通用视觉特征无需微调即可在分类、深度估计、分割、检索等一系列任务上直接使用,成为"视觉基础模型特征"的常用选择——可以说印证了本讲"下游任务表现才是最终标准"的评估观。

拓展

JEPA:不重建像素,预测抽象表示。LeCun 提出的 JEPA(Joint-Embedding Predictive Architecture)代表了对比 MAE 的另一条路线:MAE 在像素空间重建,浪费容量去建模与语义无关的细节;JEPA 改为在嵌入空间中预测——编码器给出上下文部分的表示,预测器(predictor)去预测被掩区域在编码器输出空间中的表示,而非像素本身。I-JEPA(图像版,2023)证明这种"预测抽象表示"的方式比像素重建样本效率更高、学到的语义更抽象;V-JEPA 把同一思想用于视频。JEPA 与 BYOL/DINO 一样依赖非对称结构(如动量 target 编码器)来防止表示坍塌,是"免负样本"与"掩码建模"两条线索的合流,也被用于 Llama 3.2-Vision 等模型的视觉编码器预训练。

拓展

多模态对比学习:CLIP。本讲的对比学习把"同一图像的两种增强"配成正样本对;把"配对"的概念推广到跨模态,就是 CLIP(Contrastive Language-Image Pre-training,2021):从互联网收集数亿"图像-文本"对,在批内做双向对比学习——匹配的图文对为正样本、批内其余组合为负样本,训练图像编码器与文本编码器把匹配对拉进同一嵌入空间。由此得到的特征支持零样本分类:把类别名写成文本,比较图像嵌入与各文本嵌入的相似度即可,无需任何标注训练。CLIP 式的多模态对比预训练如今已是视觉-语言模型(如后续课程会讨论的多模态大模型)的视觉端标准组件——可以把它看作本讲 InfoNCE 框架在"图像 + 语言"上的一次极其成功的外推。

十五、本讲要点回顾

上一讲第 11 讲:大规模分布式训练 下一讲第 13 讲:生成模型(一)