跳到主要内容

图和字进同一个空间 — 为什么分类从此不需要分类器

这一章讲三件事: 老办法教机器认东西为什么每加一个类别都要重训一次; CLIP 换成了什么出题法;以及为什么换完之后,分类这件事不再需要一个分类器它是全书的地基——后面 19 章,每一章开头那个「已经训好的模型」,说的都是这里造出来的东西。 不需要任何基础,遇到的生词都在当场解释。

1. 先看现象:老办法认东西,得先把名字变成号码

假设你想让程序看一张照片,说出里面是不是柯基。

十年前起,标准做法只有一条路:

① 先定一张名单:柯基、猫、飞机……一共 K 个类别,定死,不许多不许少
② 每个名字换成一个号码:柯基 = 3 号,猫 = 7 号,飞机 = 41 号
③ 收几万张标好号码的照片,训练模型:看到这张图,输出 3 号
④ 用的时候:输出哪个号码,就是哪一类

图说:名字里的意思在第 ② 步就被扔掉了。对模型来说,「柯基」和「3 号」完全等价。

第 ③ 步里那个「最后拿去判断是哪一类」的部件,有个专门的名字:分类器。 你可以把它想成 K 张评分表,每一类一张;来一张图,K 张表各打一个分,谁高算谁—— 这些评分表里的数,是从随机值开始一点点训出来的。

这条路有一个死穴:名单是封闭的。 书里的原话是,这种做法把识别系统限死在闭集概念里, 遇到新类别就没办法,除非再收一批数据、再训一个新的分类器1

所以「加一个类别」的代价是:重新标一批图 + 重新训一次。 你想让它认「柯基」,它就永远只认得那张名单上的东西。

换一种出题法:不问「这是什么」,只问「这两个是不是一对」

CLIP 走了另一条路,而这条路的起点是一个很省事的观察 (它发表于 2021 年——这个年份不在书里,是通用知识):

网上本来就有海量的「图 + 配这张图的那句话」。 谁也不用专门去标注。

它拿了 4 亿对这样的数据,只训一件事2:

给它一批(比如 4 对)图和句子,打乱摆开:

图1 🐕 图2 🍕 图3 ✈️ 图4 🏖️
句A「a photo of a corgi」
句B「a photo of a pizza」
句C「a photo of an airplane」
句D「a photo of a beach」

要它做的事:让「图1 ↔ 句A」这种真配对的更像,
让「图1 ↔ 句B」这种不配对的更不像。

图说:一批里有 4 个正确答案、12 个错误答案,同时被推开。
批大小 4 是为演示编的,真实训练用的批要大得多。

这种「把配成对的拉近、没配对的推远」的训练方式,叫对比学习。 这个名字是从视觉领域借来的:那边原本是让同一张照片的两种不同裁法产生相似的结果, CLIP 把「同一张照片的两个版本」换成了「一张图和它的那句配文」3

请注意这里发生了什么:它一个物体的名字都没有学过。 从头到尾没有人告诉它「这叫柯基」,只告诉它「这张图和这句话是一对」。

这一遍训练本身有个名字:预训练。 意思是先拿海量的通用数据把模型整个训一遍,不针对任何具体任务—— 训完这一遍,谁要拿它去认柯基、去找肿瘤、去数零件,再各自想办法。 「预」字指的就是「在你那个具体任务之前」。

这个词就是本书书名里的 pre-training,也是后面 19 章共同的起跑线: 每一章开头那句「已经训好的模型」,说的都是「预训练已经做完了」。 那 4 亿对数据全烧在这一遍上,而且只烧一次——之后所有人共用它的成果。 (这一遍到底有多贵、贵到什么程度逼出了整本书的问题,第 04 章第 2 节算这笔账。)

2. 顶层全景:一整章就是这一条链

一张柯基照片 ──→ [图像那半边] ──→ 一串数

├─→ 比夹角 ──→ 三个相似度分数
│ │
「a photo of a corgi」 ─┐ │ ├─ 除以一个温度
「a photo of a cat」 ─┼→ [文字那半边] ┘ │
「a photo of an airplane」┘ → 三串数 ▼
摊成三个百分比,取最大

图说:整条链上只有两个训练过的部件(左边那两个「半边」),
中间的比较和最后的换算都不含任何要训练的东西。
**这正是「不需要分类器」这句话的字面意思。**

这条链是本章的主走查。 下面每一节都会回到它: 第 3 节讲那两串数是什么、夹角怎么算,第 4 节讲三串数为什么能当分类器, 第 5 节讲最后那个温度。

3. 「拉近推远」不是比方:近和远是真能算出来的数

先说这两个部件:它们各自把一样东西压成一串数

CLIP 由两个独立的部件组成,一个管图、一个管字。它们各自的任务只有一个: 把输入压成一串固定长度的数。 书里管管图那个叫图像编码器, 它的职责是「把高维的图像数据转成一个紧凑的低维向量」4;管字那个叫文本编码器

这串数,就叫这个东西的嵌入。

为什么必须是一串数、而不是第 1 节那种一个号码? 因为号码是随便编的:3 号和 4 号之间没有任何关系,3 号和 300 号也没有。 一串数就不一样了——它可以让「意思相近」变成「这串数也相近」。 意思一旦变成距离,机器就有东西可算了。

这就是这本书的地基,也是「共享空间」这个说法的字面含义: 本来图和字是两种没法比较的东西,现在它们各自变成了同样长度的一串数, 住进了同一个空间,于是可以直接比。

「图」和「字」这种「输入的一种形式」,业内叫一个模态。 图是一个模态,字是另一个模态,声音、视频、立体的点各算一个。 本书书名里的 vision-language,指的就是「视觉」和「语言」这两个模态; 后面每一章讲的都是这两者之间的事,第 04 章还有整整一堵墙专门讲它们对不齐。

这个词还有两个到处会撞见的派生说法,说的都是同一件事,只是站的位置不同: 一个模型同时吃不止一种形式,这就叫多模态; 在两种形式之间来回——拿字去找图、拿图去配字——这就叫跨模态

怎么算「近」:比的是两串数的夹角

书里用的量法叫余弦相似度

一句话讲清:把每串数看成从原点射出去的一根箭头,余弦相似度就是这两根箭头夹角的余弦值—— 完全同向是 1,完全垂直是 0,完全反向是 −1。 它只管方向,不管箭头多长。(这个几何解释书里没写,是通用知识; 书里只写了训练时「让配对的余弦相似度最大、不配对的最小」5。)

走查第 ① 步:柯基照片进去,一串数出来

输入:一张 224×224 的柯基照片
过图像编码器
输出:[0.31, −0.08, 0.55, …] 一共 512 个数

图说:**这几个数值是为演示编的**;「512 个」这个长度也是通用知识——
CLIP 有好几个版本,常见的两个版本分别是 512 和 1024,**书里没有给这个数**。

记住这一串数的样子。 后面十九章里,凡是说「过一遍 CLIP」「取它的特征」, 拿到的都是这样一串数;而凡是说「冻住 CLIP」,冻的都是产生这串数的那两个部件。

4. 于是分类器不用训了:类名写成一句话,就是分类器的一行

这一节是全章的落点。

先看它怎么用

要认三个类别(corgi / cat / airplane),你不需要收集任何图片,只要写三句话:

类别写成的那句话过文本编码器之后
corgia photo of a corgi一串 512 个数
cata photo of a cat另一串 512 个数
airplanea photo of an airplane又一串 512 个数

这三串数,拿来就当第 1 节那三张评分表用。 原书第 7 章把这件事说得最直白:把类名嵌进一个模板,过一遍文本编码器, 得到的东西就是一个零样本分类器——K 个类别就是 K 行,每一行是这个类别的权重6

差别在这里: 第 1 节那 K 张评分表是从随机值训出来的; 这里的 K 行是写出来的——一次训练都没有。

这就叫零样本

零样本的意思是:这个类别的图片,模型一张都没专门见过,也没为它训练过。 你只是把类名写进一句话里,它就能认。

而且换一批类名,就等于换了一个分类器。 今天认三种狗,明天认三十种花, 中间不需要任何训练——改的只是你输进去的那几句话。

这一句要记住,因为它是后面十几章的共同前提: 「适配到新任务」这件事,在这套东西上第一次变得不需要训练。 后面所有方法都是在问同一个问题:除了改那句话,还能改哪儿、改多少、代价多大?

走查第 ② 步和第 ③ 步:三串数,三个夹角

② 三句话各过一遍文本编码器
corgi → [0.28, −0.11, 0.49, …]
cat → [0.19, 0.24, 0.30, …]
airplane → [−0.40, 0.62, 0.05, …]

③ 拿第 ① 步那张图的数,和这三串各算一次余弦相似度
图 ↔ corgi 0.31
图 ↔ cat 0.19
图 ↔ airplane 0.05

图说:**这三个相似度是为演示编的,不是真实数值。**
真实的余弦相似度通常挤在一个很窄的范围里——这正是下一节那个温度要处理的事。

5. 最后一步:除以一个温度,再摊成百分比

这一节回答:0.31 / 0.19 / 0.05 这三个数,怎么变成「92% 是柯基」这种话。

先看问题

上一步拿到的三个数是相似度,不是把握。它们不加起来等于 1, 而且彼此挨得很近——0.31 和 0.19 看起来差别不大,可你希望模型给出一个明确的判断。

两个动作:先除以温度,再摊平

书里给的算法是一个公式,拆开只有两步7:

  1. 三个相似度各除以一个数 τ(读作 tau),这个数叫温度;
  2. 再把结果摊成加起来正好是 1 的三个百分比(这一步的标准做法叫 softmax: 先各自取指数把负数变正、把差距拉大,再各除以总和)。

温度控制的是「这排数被拉多开」:

温度效果结果长什么样
小(比如 0.01)相似度被除大,差距被放大0.99 / 0.01 / 0.00 —— 非常笃定
适度拉开0.72 / 0.21 / 0.07
大(比如 10)差距被压平0.35 / 0.34 / 0.31 —— 等于没主意

关键的一句:这个温度不是人设的,是训练时学出来的8

书里对温度只说了这一句,没有交代它是怎么学的、最后学成了多少。 照实写在这儿。 (这个温度会在第 11 章重新出现:那一章发现,微调之后这个温度其实已经不合适了, 并且给出了一种按类别单独调它的办法。)

走查第 ④ 步:三个数变成三个百分比

③ 的三个相似度 0.31 / 0.19 / 0.05

├─ 各除以温度(把差距拉开)

这排还没摊平的数,有个名字:**logits**

├─ 摊成加起来 = 1

corgi 0.72 · cat 0.21 · airplane 0.07 → 判为 corgi

图说:**这四个数是为演示编的。** 「logits」这个名字要记一下——
你在任何一家模型接口的文档里都会撞见它,说的就是这里这排「还没摊平的分数」。

整章的主走查到此走完。 四步,两个训练过的部件,零个训练出来的分类器。

6. 这套本事不是天上掉的:三件事同时到位

这一节回答一个容易被忽略的问题:「共享空间」这个想法并不新,为什么 2021 年才成?

书里说得很清楚:共享表示空间这个思路,十多年前就有人研究过—— 2013 年就有工作试图用共享嵌入把图和字对齐,但那些模型规模上不去, 也吃不下大而杂的数据集9

作者把 CLIP 的成功归给同时到位的三件事10:

归因它解决了什么
一种能一次看完整段序列、而且能并行算的模型早先处理句子的做法必须一个词一个词按顺序过,慢、还记不住远处的词。这种新做法把整段一次摊开算,又快又能照顾到长距离的关系。它的名字叫 Transformer
对比学习提供了一种不需要人工标注就能出题的办法(第 1 节那种出题法)
网络规模的图文数据提供了 4 亿对现成的题目

「Transformer」这个名字必须留下,因为你出门就会撞见它: 后面十几章的模型、任何一份模型文档、任何一次技术讨论,都在用这个词。 它内部到底怎么算,第 02 章拆开讲。

数据这一项有个有意思的对照: 同期另一个模型 ALIGN 用了 18 亿对, 是 CLIP 的四倍多,但书里明说它筛得没那么严、噪声更大11—— 所以这条线从一开始就不是「越多越好」,而是「多」和「干净」之间的取舍。 (第 05 章那篇论文会把这笔账算到小数点后一位:60.3 亿对里只留 49.8 亿。)

7. 零样本不等于什么都认得:两条硬边界

这两条是后面 12、13、14 三章的共同起点,现在就要立住。

边界一:它认的是「像不像那句话」,不是「是什么」。 书里举的例子是 jaguar:这个词既是一种美洲豹,也是一个汽车品牌。 模型必须靠画面本身和语言线索去猜是哪一个,而它经常猜不对—— 书里把这类问题归为「模态鸿沟」,并说这是最根本的挑战之一12

边界二:它只见过「整张图配一句话」,所以它不知道东西在哪儿。 训练数据里从来没有「这个框里是猫」这种标注。 书里明说:这类模型训练时用的是图级别的粗标签,没有框、没有像素级标注, 所以直接拿去做需要定位的任务时,表现很差13

这两条不是缺陷清单,是路标。 边界一在第 08 章被处理成「那句话该怎么写」的问题; 边界二则直接催生了三章:检测(第 12 章)、分割(第 13 章)、3D(第 14 章)。

8. 作者的判断与证据

书里给了证据的:

说法证据
类名写成一句话就能当分类器,换类名就换分类器全书 16 篇论文里绝大多数都在这个前提上跑实验,数字贯穿始终
CLIP 的成功要归给三件事同时到位原书第 1 章和第 5 章两处独立列出,三项完全一致(Transformer / 对比学习 / 网络规模数据)
共享空间的想法十多年前就有点名了 2013 年那一代工作,并说明它们卡在规模上
只有图级标签,所以定位任务做不好第 10、11 章两整章的实验都建立在这个诊断上,并各自给出绕法

属于作者的推断、书里没有给证据的:

  • 「三件事同时到位」这个归因本身是事后归纳,不是对照实验。 书里没有做「去掉其中一件会怎样」的验证——那种实验成本太高,谁也做不起;
  • 「不同工作的表示空间是同质的」这类更强的说法出现在第 05 章, 那一章明确承认它是一个假设,只是实践上管用。

9. 边界与局限

① 这本书没有讲 CLIP 是怎么训出来的。 全书大部分章节把它当地基,却没有一章交代它的训练细节: 批量多大、温度怎么学、4 亿对数据是怎么筛的、两个编码器各用什么结构训了多久。 最详细的一处是原书第 5 章第 3 节,也只有三段。 我们这一章已经把书里散落在三章的说法拼齐了,但批量与温度的学法确实无从补起—— 需要的话要去查 CLIP 原论文(arXiv:2103.00020),我们没有在这一版里引它。

② 书里对 CLIP 的描述分散在三章,口径略有出入。 原书第 1 章说它是「两个模态各自的编码器,从零训练」; 原书第 5 章补了文本那半边的细节(切块方式、长度上限); 原书第 7 章补了「文本嵌入就是分类器权重」这个用法。 三处不矛盾,但都不完整——我们这一章的组织顺序是我们自己排的,不是原书的顺序。

③ 「共享空间的维数」这个数,书里没有。 我们在走查里用了 512,并当场标了是通用知识。 真要引用具体数字时,要按你用的那个具体版本去核。

10. 可带走的

  1. 老办法的死穴是「名单封闭」:类别名在训练前就被换成了号码,加一个新类别就要重训一次;
  2. CLIP 换了出题法:不问「这是什么」,只问「这张图和这句话是不是一对」, 于是不需要任何人工标注,网上现成的图文对就是题库;
  3. 它一个物体名字都没学过——所有的「认识」都是「像不像那句话」的副产品;
  4. 两个编码器各自把输入压成一串数(嵌入),长度相同,住进同一个空间,于是可以直接比;
  5. 比的是夹角(余弦相似度),只管方向、不管长短;
  6. 类名写成一句话过一遍文本编码器,那串数就是分类器的一行—— 这就是「零样本」,也是这本书全部方法的出发点;
  7. 换一批类名 = 换一个分类器,一次训练都不用做;
  8. 最后一步是「除以温度再摊平」,温度决定这排数被拉多开,而且它是训练时学出来的;
  9. 「logits」= 还没摊平的那排分数,出门一定会撞见这个名字;
  10. 两条边界要记住:它分不清 jaguar 是豹还是车(意思上的歧义), 它也不知道东西在图上的哪个位置(它只见过整张图配一句话)。

11. 原文地图

主题原书章原文位置
老办法把类名变成号码、闭集的死穴5. Differentiable Prompt Learningtext/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:77(搜「discrete labels」) · text/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:105(搜「closed-set visual concepts」)
4 亿对、对比学习、成功归因三件事1. Foundations of VLMstext/07-ch01-1-foundations-of-vision-language-models-concepts.txt:189(搜「400 million image–text pairs」)
三件事的另一处列举、ALIGN 的 18 亿对5. Differentiable Prompt Learningtext/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:53(搜「three fundamental areas」) · text/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:57(搜「1.8 billion image–text pairs」)
两个编码器、图像压成低维向量5. Differentiable Prompt Learningtext/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:83(搜「compact, low-dimensional vector」)
训练目标:配对的余弦最大、不配对的最小5. Differentiable Prompt Learningtext/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:89(搜「maximize the cosine similarity for matched pairs」)
零样本推理的公式、温度是学出来的5. Differentiable Prompt Learningtext/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:99(搜「a photo of a [CLASS]」) · text/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:103(搜「temperature parameter learned by CLIP」)
文本嵌入 = 分类器权重,每类一行7. Learning Efficient Feature Adapterstext/37-ch07-7-learning-efficient-feature-adapters-for-vision.txt:179(搜「zero-shot classifier, represented as」)
共享空间的想法十多年前就有1. Foundations of VLMstext/07-ch01-1-foundations-of-vision-language-models-concepts.txt:71(搜「DeViSE」)
jaguar 歧义、模态鸿沟1. Foundations of VLMstext/07-ch01-1-foundations-of-vision-language-models-concepts.txt:123(搜「jaguar」)
只有图级粗标签、缺定位能力1. Foundations of VLMstext/07-ch01-1-foundations-of-vision-language-models-concepts.txt:211(搜「dense annotations like bounding boxes」)

Footnotes

  1. 出处:「5. Differentiable Prompt Learning for Vision-Language Models」第 77 段(text/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:77,搜「discrete labels」)与第 105 段(text/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:105,搜「closed-set visual concepts」)。原文特别点出一件事:训练用的类别其实本来是有文字描述的(比如「goldfish」),但为了方便算损失,这些字被换成了离散标签——意思就是在这一步被扔掉的。

  2. 出处:「1. Foundations of Vision-Language Models: Concepts and Roadmap」第 189 段(text/07-ch01-1-foundations-of-vision-language-models-concepts.txt:189,搜「400 million image–text pairs」)。原文强调两个编码器都是从零开始训的,没有拿现成的模型来接。

  3. 出处:同上第 189 段(text/07-ch01-1-foundations-of-vision-language-models-concepts.txt:189,搜「different augmentations」)。原文说对比学习在视觉的自监督表示学习里早已被广泛研究,那边的主意是「让同一张图在不同变换下产生相似的特征」,这些前期工作为 CLIP 打了底。

  4. 出处:「5. Differentiable Prompt Learning for Vision-Language Models」第 83 段(text/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:83,搜「compact, low-dimensional vector」)。同一段说图像那半边可以是卷积网络(如 ResNet-50)也可以是 ViT,文字那半边用 Transformer——这两种结构的区别是第 02 章的内容。

  5. 出处:「5. Differentiable Prompt Learning for Vision-Language Models」第 89 段(text/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:89,搜「maximize the cosine similarity for matched pairs」)。「余弦相似度就是夹角的余弦」这个几何解释是补充(不在书里,来自通用知识)。

  6. 出处:「7. Learning Efficient Feature Adapters for Vision-Language Models」第 179 段(text/37-ch07-7-learning-efficient-feature-adapters-for-vision.txt:179,搜「zero-shot classifier, represented as」)。原文的写法是:K 个「没见过」的类别,把类名嵌进模板过文本编码器,得到一个 K 行的矩阵,每一行是这个类别的 C 维文本特征;分类分数就是图像特征与它相乘。

  7. 出处:「5. Differentiable Prompt Learning for Vision-Language Models」第 99 段(text/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:99,搜「a photo of a [CLASS]」)与第 103 段(text/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:103,搜「temperature parameter learned by CLIP」)。「softmax 先取指数再各除以总和」这一步的展开是补充(不在书里,来自通用知识);书里只写了公式本身。

  8. 出处:同上第 103 段(text/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:103,搜「temperature parameter learned by CLIP」)。书里对温度只有这一句,没有交代学法与最终取值。

  9. 出处:「1. Foundations of Vision-Language Models: Concepts and Roadmap」第 71 段(text/07-ch01-1-foundations-of-vision-language-models-concepts.txt:71,搜「DeViSE」)。原文说这些早期工作「受限于可扩展性,也缺乏吃下大而多样的数据集的能力」。第 5 章第 53 段(text/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:53,搜「nearly a decade ago」)给了同一件事的另一种说法,并列出了当时用的老办法:预训练词向量、手工的 TF-IDF 特征。

  10. 出处:「1. Foundations of Vision-Language Models: Concepts and Roadmap」第 189 段(text/07-ch01-1-foundations-of-vision-language-models-concepts.txt:189,搜「three advances in the field」)与「5. Differentiable Prompt Learning for Vision-Language Models」第 53 段(text/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:53,搜「three fundamental areas」)。两处独立列举,三项完全一致。原文对 Transformer 的说法是:相比循环结构,自注意力让序列数据可以并行处理,从而更容易学到带上下文的表示。

  11. 出处:「5. Differentiable Prompt Learning for Vision-Language Models」第 57 段(text/26-ch05-5-differentiable-prompt-learning-for-vision-lang.txt:57,搜「1.8 billion image–text pairs」)。原文的评价是 ALIGN 的数据「筛选没那么严格,因而噪声更大」。

  12. 出处:「1. Foundations of Vision-Language Models: Concepts and Roadmap」第 123 段(text/07-ch01-1-foundations-of-vision-language-models-concepts.txt:123,搜「jaguar」)。这一段属于原书 §1.3.1「算法挑战」的第一条,标题就叫「Bridging the Modality Gap」——第 04 章会把这一整节的十四条难题讲完。

  13. 出处:「1. Foundations of Vision-Language Models: Concepts and Roadmap」第 211 段(text/07-ch01-1-foundations-of-vision-language-models-concepts.txt:211,搜「dense annotations like bounding boxes」)。原文:这类模型通常训练在「有噪声的图级标签,比如粗略的图注」上,没有用到框这类稠密标注;而需要定位的任务要的是区域级或像素级的理解,所以直接套用效果很差。