上一章《ViT 视觉 Transformer》把图片切块喂给注意力,靠的却是几亿张人工标注。 这一章讲一个更狠的思路:互联网上有几十亿张图,只是没有标签—— 那就想办法让图自己当自己的标签。
| 对照项 | ||
|---|---|---|
| 需要什么 | 人工标注的标签 | 只要原始数据,标签从数据里自己造 |
| 数据量上限 | 受限于你能标多少 | 互联网上有多少就能用多少 |
| 成本 | ImageNet 花了约两年、近 5 万名标注员 | 爬数据 + 显卡,不需要人 |
| 学到的 | 针对那个任务的判别能力 | 通用的表示,换个任务还能用 |
自监督的做法是人为地在数据里挖一个洞,然后让模型把它填上。 这个洞的答案本来就在数据里——所以不需要人来标。 但模型为了填对这个洞,被迫学会理解数据的内在结构。 把"预测标签"换成"预测数据的一部分",这就是全部的核心 trick。
像教小孩认字时用的填空练习。"小__在树上叫"——答案是"鸟",但这个答案
从句子本身就能推出来,不需要老师额外标注。
小孩做完一万道填空题,自然就学会了语法和常识——尽管从来没有人教过他"什么是主语"。
互动 · 同样干 90 天,人工标注 vs 一台爬虫
| 路线 | 造什么洞 | 代表 | 特点 |
|---|---|---|---|
| 生成式 Generative |
遮住一部分,让模型重建它 | MAE(掩码 |
直观,重建目标明确。但容易学成"抠图"—— 模型可能只学会了纹理补全,没学到语义 |
| 对比式 Contrastive |
不重建,只要求"同一张图的两种变换"在表示空间里靠近 | SimCLR、MoCo、CLIP | 学到的表示质量最高。 代价是需要大量负样本、极大 batch |
| 预测式 / 蒸馏式 | 让一个"学生"网络去预测"老师"网络的输出 | BYOL、DINO、data2vec | 不需要负样本,batch 可以小。但要小心"表示坍塌" |
两个词后面要反复用,先记住:正样本是同一张图的另一种变换(该拉近的),负样本是别的图(该推远的)。
三条路线挖的三个"洞"
互动 · 老师到底落后学生多少步
这三条路线其实都赢了,只是在不同的地方:生成式赢了语言——GPT 的"预测下一个词"就是最成功的自监督; 对比式赢了图文对齐——CLIP 是很多多模态模型的地基; 预测式在纯视觉里也一直有人用。 它们的思想是同一个:不需要人来标,让数据自己出题。
这是理解对比学习最直观的一句话: 把同一张图做两次随机增强,模型应该认为它们"是同一个东西"; 而把它和别的图放在一起,应该认为"不是同一个东西"。
互动 · 相似度矩阵与 InfoNCE 损失
上面那张相似度矩阵就是这一章的全部:每一行是一个视图,橙色格子是它该认出的"另一半",其余都是干扰项。 后面讲的温度、坍塌、五种防坍塌手段,都是在跟这张矩阵较劲。
sim 是余弦相似度——两根箭头夹角的余弦:同向时接近 1,垂直时接近 0,反向时接近 −1。 一个视图的表示记作 zi,它该认出的另一半记作 zi+; 分母里的 Σj 要对所有候选求和。
sim 就是两根箭头夹角的余弦
这一步最容易看漏的地方:N 张图进去,出来的是 2N 个东西
把鼠标停在下面公式里有下划线的符号上——上面「温度 τ」和「正负样本的分离度」两个滑块会分别亮起来。 公式里的符号,就是你拖的那个控件。
softmax 之前,相似度会先除以 τ。τ 越小,最像的那一个越突出——τ = 0.1 时,
一点点的相似度差异就被放大十倍,模型被逼着非常确定地区分正负样本。
τ 太大,所有样本的权重都差不多,负样本的区分作用就消失了,模型学不到细粒度特征。
SimCLR 论文里 τ = 0.1(很低),说明对比学习需要"严格"的判别压力。
这个超参数对结果影响很大,是当初一个真正的调参难点。
对比学习有一个极其诱人的作弊方案,而且模型真的会找到它:
如果模型把所有图片都编码成同一个向量——比如全都输出 [1, 0, 0, …]——
那么任何两张图的相似度都是 1,正样本的相似度当然是满分。
可负样本的相似度也一起变成 1 了——softmax 把概率平摊,损失卡在 ln(2N−1) 的瞎猜水平,降不下去。模型什么都没学到。
(每个视图被编码成一个向量,这些向量所在的地方就叫表示空间。)
互动 · 坍塌长什么样
| 防坍塌手段 | 怎么起作用 |
|---|---|
| 负样本 | 最直接。如果所有样本都挤在一起,负样本的相似度也会变成 1, 分母变大,损失反而升高。所以负样本天然地排斥坍塌 |
| 超大 batch | SimCLR 用 4096 的 batch,就是为了让每个正样本有足够多的负样本可对比。 这是它最大的工程代价 |
| 动量 |
MoCo 的解法:用一个动量更新的慢 |
| 停止梯度 + 预测头 | BYOL 的做法,完全不用负样本。 靠"学生预测老师、老师用学生参数的滑动平均更新"打破对称性 |
| 居中 + 锐化 | DINO 的做法:居中防止某个维度主导(抗坍塌), 锐化防止输出太均匀(会引入坍塌)。两者必须同时用,缺一个就崩 |
BYOL 为什么不用负样本也不坍塌?如果学生和老师一模一样、又都只求"两边输出一样",
最省事的解就是都输出同一个常数。让老师慢半拍(滑动平均)、学生比老师多一层预测头,
两边就不再完全对称,这个偷懒解不再是最省事的。停止梯度是指老师那一边不往回传梯度。
DINO 用的是另一对反向的力:居中把每个维度的均值拉回 0,防某一维独大;
锐化让输出别太均匀。两者必须同时用,缺一个就崩。
投影头是接在编码器后面的一个小网络,损失在它的输出上算。 它替编码器吸收掉只对这个出题游戏有用的信息——所以训完就扔掉,下游只用编码器(SimCLR 发现这样下游更好)。
监督学习里,标签是外部给的、固定的,模型没有作弊空间。
自监督里,目标是自己定的——所以你一旦把目标设得不够严谨,
模型就会找到那个"最低成本满足目标"的退化解,也就是坍塌。
设计一个好的自监督任务,比设计网络结构难得多。
互动 · 自监督方法进化时间轴
| 方法 | 核心机制 | 解决了什么 |
|---|---|---|
| SimCLR 2020 | 大批量 + 强增强 + 投影头 | 证明了对比学习可以追平监督学习。但需要 4096 的 batch |
| MoCo 2019 | 动量 |
小 batch 下也有竞争力,把对比学习从大厂门槛变成了小实验室也能做的 |
| BYOL 2020 | 不用负样本,学生预测老师 | 推翻了"必须有负样本"的共识。但为什么不坍塌,至今仍在研究 |
| DINO(自监督) 2021 | 自蒸馏(老师和学生来自同一个网络)+ 居中锐化 | 注意力图自己就浮现出了物体轮廓—— 完全不用标注,也不做分割任务,模型却学会了"哪里是物体"。这是当年最惊人的发现之一 |
| MAE(掩码 |
遮住 75% 的图块,重建 | 训练效率极高——只对可见的 25% 做编码,
比对比学习快 3 倍以上。成了 ViT |
| CLIP 2021 | 4 亿对图文对比学习 | 零样本分类(zero-shot transfer)——给一个新类别的名字就能认,不需要该类的训练样本。
它的图像 |
CLIP 把对比学习的两端换成了一张图和它配的那句话:正样本是配对的图文,负样本是同一批里别的图文。 损失还是这套 InfoNCE,只是两边一边是图、一边是文字。
互动 · 这条谱系的真正分水岭:负样本从哪来
第 3 节那个损失函数只有一个动作:在一排"有多像"里,给"自己"那一项算出一个概率。 下面这张图把这一步摊开——左半边进、右半边出,三个数字全部真算。
数学节 · 一行损失怎么算(拖两个滑块,每一步都跟着变)
互动 · 每个符号管图上的哪一块(卡片下面那张画的是「分子只要一项、分母要全部」)
老师手里有一张全班名单。点名时他要回答的只有一个问题:
"在所有人里,我敢不敢保证站起来的是这个人?"
分子 = 这个人自己有多像他;分母 = 全班所有人"像他"的程度加起来。
所以这个损失不关心"像不像",它只关心"他敢不敢保证"——
这也正是温度 τ 那么要紧的原因:它决定这场点名有多严。
把「温度 τ」从 0.1 拖到 0.5 再拖回来:左半边那一排相似度一个数字都没变,
变的只有右半边的概率形状。这就是第 3 节说的"τ 是个很敏感的旋钮"——
它不改数据,只改判罚的严不严。
再回头看第 3 节那张相似度矩阵:上面这张图是它的一个小例子——那里每行有 7 个候选,
这里简化成 6 个。一行变成一个损失,2N 行取平均,就是这一章从头到尾在做的事。
| 成本 | 具体表现 | 什么时候真的会痛 → 换什么 |
|---|---|---|
| SimCLR 要一整个 TPU(Google 的训练芯片)集群——4096 的 batch 至少要 32 块 TPU v3。MoCo 的存在意义就是把门槛降下来 | 只有一两张卡、还要快速迭代 → 先用现成的预训练模型微调;一定要自己预训练,就选 MoCo 这类小 batch 的做法 | |
| 没有统一的好坏标准 | 监督学习看准确率就行。自监督的" |
要在一堆方法里选型 → 固定一种下游协议(通常线性探测),别拿不同协议的数字横着比 |
| 学到的表示有偏 | 增强策略里有"颜色抖动",模型就会忽略颜色——
这在"区分香蕉和柠檬"的任务上是灾难。增强策略隐含了"什么是不重要的"这个假设,
而这个假设会写进表示里。任何自监督方法都带着一条这样的
|
下游任务依赖被抖掉的那个属性(颜色、方向、尺度)→ 改增强策略,或直接换成监督预训练 |
| 对超参极其敏感 | 温度 τ、增强强度、投影头维度、学习率—— 任何一项设置不当都会显著影响结果。复现别人的自监督结果通常比监督学习更难 | 换了数据或规模 → 得重新扫一遍 τ 和增强强度;照抄别人的配置通常不灵 |
| 数据里的偏见会被放大 | 自监督学的是"数据里有什么"。 数据里如果 90% 的医生是男性,学到的表示就会把"医生"和"男性"绑在一起—— 而且没有任何标签能让你发现这件事 | 数据本身有系统性偏见 → 先查数据构成,再决定要不要自监督;没有标签能替你兜底 |
三个量各一句:线性探测把编码器冻住、只训最后一层线性分类器;微调是整个网络接着训; KNN 干脆不训练,直接按表示找最近的邻居投票。它们经常给出不一致的排名—— 线性探测只看表示能不能被一刀切开,微调还能顺手把表示改掉,量的不是同一件事。
互动 · 那张相似度矩阵,比模型本身还大
互动 · 你写进增强策略里的那句话,模型会当真的
自监督听起来像一句工程口诀("没有标签就自己造"),但它其实站在七条线里的 一条上——而且这条线在这一章露出了一条很锋利的边界。
回到第 4 节那张图(标题是「坍塌长什么样」)。 把「表示的分散程度」这个滑块一路拖到 0——8 个点会全部挤到圆心, 两两平均相似度升到接近 1。
那个瞬间你看到的就是「压缩过头」:模型把每张图的信息都压没了, 只剩下一个所有输入都一样的向量——你再也分不出第 3 张和第 7 张。 所以"压缩"和"压缩过头"之间没有一条公式能替你划线。 第 4 节那张表里的五种手段,都是在替你守这条线。
这一章整件事,就是在这条轴上找一个没人能替你划的位置
| 暗线 | 这一章的回答 |
|---|---|
| 信息流动 | 数据形状:一张图 [3,224,224] → [2048] → 投影头 → [128];
和别的章不同的一步是 batch 翻倍:N 张图各做两次增强 →
[2N, 128] → 相似度矩阵 [2N, 2N] → 一个标量损失。唯一留下来的东西是 |
| 什么被牺牲了 | 牺牲了目标函数的客观性。监督学习的损失是数据给的,你改不了;
自监督的损失是你编的——编错了没有报错,只有坍塌。
另外还牺牲了可评估性: |
| 参数账本 | ResNet-50 主干 23.5M 参数,外面再挂一个投影头
(2048→2048→128,约 4.5M)——投影头训完就扔,不传给下游。 batch 4096 → 两个视图共 8192 个样本 → 一张 8192×8192 的相似度矩阵 (约 6700 万个浮点数)。MoCo 反过来:batch 只要 256, 但维护一个 65536 个负样本的队列。 图文对比的规模:CLIP 用了 4 亿对图文 |
| 它假设了什么 | 假设"增强之后的东西语义不变"——翻转、裁剪、调色不改变"这是什么"。
这是对世界的一个断言,不是数学结论。 它还假设"不同图之间应该有区别"——这一条更隐蔽,但它就是负样本的来源。 两个假设只要有一个不成立(比如你要辨认的是"同一件商品的哪个颜色"), 学到的东西就是错的 |
| 违背了哪个直觉 | "损失降下来了就学到了"——错的。坍塌会卡住损失:所有表示挤成一团,
负样本也成了满分,损失卡住降不下去。 第二个反直觉:训练时做的事(认出自己的另一个视图)可以和你想要的能力 (识别物体种类)毫无关系,但它仍然有用。 代理任务和下游任务之间没有逻辑联系,只有统计联系 |
它接住了上一章《ViT 视觉 Transformer》的什么:那一章 把图片切块喂给注意力,代价是海量人工标注。这一章把标签来源换掉—— 增强不再只是训练技巧,它直接定义了"什么是本质"。
它给下一章留了什么:自监督解决了"没有标签",但它连"怎么切数据"都还没问。 文字进来之前,得先切成模型认得的单位——这就是 《分词与子词》要回答的问题。
自监督 = 把数据本身变成标签,用法是"挖个洞让模型填"。
三条路线:生成式(重建)、对比式(拉近正样本、推远负样本)、预测式(学生猜老师)。
对比学习的核心是 InfoNCE——本质上是"从一堆候选里认出自己"的分类问题,
温度 τ 控制判别压力。
最大的坑是表示坍塌:模型把所有东西编码成同一个向量,损失卡在 ln(2N−1) 的瞎猜水平,降不下去。
防它的手段有负样本、大 batch、动量队列、停止梯度、居中锐化。
它比监督学习更难设计,因为目标是自己定的——
你一旦没把目标定严,模型就会找到那个最偷懒的退化解。
上面讲的都是「够用」的版本。想往下挖,这里有三个入口—— 它们不是必修内容,是给想再往前走一步的读者准备的。