news 2026/9/16 16:46:05

Maths, CS AI Compendium:多模态表示——用 CLIP 式对比预训练构建视觉-语言联合嵌入空间

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Maths, CS AI Compendium:多模态表示——用 CLIP 式对比预训练构建视觉-语言联合嵌入空间

Maths, CS & AI Compendium:多模态表示——用 CLIP 式对比预训练构建视觉-语言联合嵌入空间

【免费下载链接】maths-cs-ai-compendiumBecome a cracked AI/ML researcher/engineer with this unconventional textbook covering maths, computing, and ML with intuition.项目地址: https://gitcode.com/GitHub_Trending/mat/maths-cs-ai-compendium

本篇技术指南对应《Maths, CS & AI Compendium》第 10 章的开篇文件,讲解多模态学习的表示层基础:早期/中期/晚期融合策略、联合嵌入空间的数学定义、CLIP / ALIGN / SigLIP 三类对比预训练模型、InfoNCE 与 NT-Xent 损失函数、零样本分类与检索评估体系。读完后,你将能独立推导 CLIP 的对称交叉熵损失、解释温度参数如何调控难负样本难度,并用 JAX 从零实现 CLIP 损失、玩具联合嵌入模型与零样本最近邻分类三个完整实验。

为什么需要多模态:模态互补与表示融合

在咖啡馆里,你看到桌上冒着热气的杯子、听到陶瓷轻碰声、闻到咖啡豆的香气、感到杯壁传来的温度。没有任何单一感官能告诉你"这是一杯热咖啡"——大脑把这些信号融合成一个统一知觉。多模态学习对机器做同样的事:融合来自多种模态(视觉、语言、音频等)的信息,构建比任何单一模态更丰富、更鲁棒的表示。

**模态(modality)**是一个独立的信息通道。机器学习中最常见的模态包括:

  • 图像(像素网格)——空间上一致连续;
  • 文本(token 序列)——顺序且离散;
  • 音频(波形或频谱图,见 第 9 章数字信号处理)——时间上连续;
  • 视频(帧序列)与结构化数据(表格、图)。

多模态学习的核心挑战在于桥接这些统计结构根本不同的数据类型。而把模态组合起来的动机在于互补性:一张狗的照片能告诉你品种和毛色,却不能告诉你它的名字;一句"我的金毛 Max"能告诉你名字和品种,却不能告诉你姿态。图文结合给出的信息大于二者之和。这种互补性正是多模态模型能回答问题、生成内容、做出单模态模型无法做出的决策的根本原因。

三种融合策略:早期、中期与晚期

把多模态融合想象成一个小组项目:要么所有人一开始就坐在同一间房里共享原始笔记(早期融合),要么每人独立写完自己的部分再合并终稿(晚期融合)。

**早期融合(early fusion,特征级融合)**在正式处理之前直接拼接或混合各模态的原始/低层特征。例如把图像像素特征与文本 token 嵌入拼接后送入同一个 Transformer。形式化地,设两个模态的特征向量 $x_{\text{img}} \in \mathbb{R}^{d_1}$ 与 $x_{\text{txt}} \in \mathbb{R}^{d_2}$,早期融合即:

$$x_{\text{fused}} = [x_{\text{img}}; x_{\text{txt}}] \in \mathbb{R}^{d_1 + d_2}$$

拼接后的向量由共享网络处理。优点是模型能在每一层发现跨模态相关性;缺点是输入空间庞大、计算成本高,且模型要同时应对统计性质差异极大的数据类型(稠密像素值 vs. 稀疏 token 索引)。

**晚期融合(late fusion,决策级融合)**让每个模态各走独立的编码器,分别产出高层表示甚至最终预测,然后再合并——通常是平均得分、投票或一个学习出的组合层。给定模态特定预测 $\hat{y}_1$ 与 $\hat{y}_2$,一个简单的晚期融合规则是:

$$\hat{y} = \alpha \hat{y}_1 + (1 - \alpha) \hat{y}_2$$

其中 $\alpha \in [0, 1]$ 是学习或手工调节的混合权重。晚期融合简单、可直接复用现成的单模态预训练模型,但各模态从未"看见"彼此的原始特征,无法捕获低层跨模态交互。

**中期融合(middle fusion,中间层融合)是现代大多数系统采用的务实折中:每个模态先由自己的编码器提取模态特定特征,然后编码后的表示在网络中途合并,通常通过交叉注意力(cross-attention)**层实现。这样每个编码器可以专精于自己的模态,同时仍支持丰富的跨模态交互。Flamingo、LLaVA 以及 第 10 章文件 02 的视觉语言模型大多采用中期融合。

策略选择取决于数据量、算力预算和任务:早期融合强但数据饥渴;晚期融合便宜但表达受限;带交叉注意力的中期融合因兼顾表达力与模块化,成为大规模多模态模型的主流。

联合嵌入空间:让图像和文本成为"同一种东西"

想象一个通用翻译器:任何语言的任何句子都能映射到同一共享"语义空间"中的同一点。"a dog on a beach" 用英语、法语或日语表达,都会落在同一坐标。**联合嵌入空间(joint embedding space)**做的是同一件事,但跨模态:一张"沙滩上的狗"的照片和文本"a dog on a beach"应映射到同一向量空间中的邻近点。

形式上,我们学习两个编码器函数:模态 1(如图像)的 $f_\theta : \mathcal{X}1 \to \mathbb{R}^d$ 与模态 2(如文本)的 $g\phi : \mathcal{X}2 \to \mathbb{R}^d$,二者都映射到同一个 $d$ 维空间。训练目标保证语义匹配对 $(x_1, x_2)$ 的嵌入 $f\theta(x_1)$ 与 $g_\phi(x_2)$ 彼此接近(高余弦相似度),而不匹配对相距甚远。

这是 第 7 章词嵌入思想的直接推广:Word2Vec 和 GloVe 把语义相近的词放在向量空间邻近处,联合嵌入空间则把"词对词的相似度"扩展为"图对文、音对文、甚至图对音频"的相似度。

相似度度量几乎总是余弦相似度

$$\text{sim}(u, v) = \frac{u \cdot v}{|u| |v|}$$

对所有嵌入做 $L_2$ 归一化到单位超球面后,余弦相似度退化为简单的点积 $u \cdot v$——计算极高效,还可以用近似最近邻(ANN)库进一步加速检索。

联合嵌入空间的力量在于它支持零样本迁移:一旦图像与文本嵌入对齐,你就能对从未训练过的类别做图像分类——只需把类别名嵌入为文本,然后找与图像嵌入最近的文本嵌入。无需任何任务特定的微调,这是 CLIP 及其后继者的关键洞见。

对比学习:多模态对齐的训练机制

想象一堂课堂练习:学生拿到打乱的"照片-标题"配对,要求把每张照片和它的正确标题对上。要做好这件事,你必须同时理解视觉内容与语言,并知道它们如何关联。对比学习正是这样训练模型的:给定一批(图像, 文本)对,模型必须判断哪张图配哪段文字。

如 第 8 章文件 04所述,单模态对比学习(SimCLR、MoCo)拉近同一图像的不同增强视图、推远不同图像的视图。多模态对比学习把"增强视图"换成"匹配模态":一张图与它的标题是正样本对;这张图与批内其他任何标题构成负样本对。

CLIP:N×N 相似度矩阵上的对称交叉熵

CLIP(Contrastive Language-Image Pre-training,Radford et al., 2021)是多模态对比学习的基础模型。它在一个从互联网抓取、规模达 4 亿(400M)(图像, 文本)对的数据集上,联合训练一个图像编码器(ViT 或 ResNet)和一个文本编码器(Transformer)。

给定 $N$ 个图文对的批次,CLIP 计算所有图像嵌入与所有文本嵌入之间的 $N \times N$ 余弦相似度矩阵。对角线元素是匹配对(正样本),所有非对角元素是未匹配对(负样本)。训练损失推动对角线元素升高、非对角元素降低。

损失是一个对称交叉熵。对与文本 $j = i$ 配对的图像 $i$,图到文损失为:

$$\mathcal{L}{i \to t} = -\frac{1}{N} \sum{i=1}^{N} \log \frac{\exp(\text{sim}(z_i^{\text{img}}, z_i^{\text{txt}}) / \tau)}{\sum_{k=1}^{N} \exp(\text{sim}(z_i^{\text{img}}, z_k^{\text{txt}}) / \tau)}$$

文到图损失同理(角色互换):

$$\mathcal{L}{t \to i} = -\frac{1}{N} \sum{i=1}^{N} \log \frac{\exp(\text{sim}(z_i^{\text{txt}}, z_i^{\text{img}}) / \tau)}{\sum_{k=1}^{N} \exp(\text{sim}(z_i^{\text{txt}}, z_k^{\text{img}}) / \tau)}$$

总损失取平均:

$$\mathcal{L}{\text{CLIP}} = \frac{1}{2}(\mathcal{L}{i \to t} + \mathcal{L}_{t \to i})$$

其中 $\tau$ 是学习得到的温度参数(初始值 $\tau = 0.07$)。温度控制 softmax 分布的锐度:$\tau$ 越小,模型越聚焦最接近的匹配;$\tau$ 越大,概率分布越均匀。CLIP 把 $\tau$ 与模型权重一起联合学习,而不是当作固定超参数。

CLIP 的典型图像编码器是 ViT-L/14(14×14 patch 的大规模视觉 Transformer,见 第 8 章文件 04),文本编码器是带因果掩码的 12 层 Transformer(类似 GPT)。两个编码器各自通过一个学习得到的线性投影把输出投射到共享的 512 或 768 维空间,随后做 $L_2$ 归一化。

CLIP 最突出的特性是零样本图像分类:把 $K$ 个类别名构造成形如 "a photo of a {class name}" 的文本提示,用文本编码器嵌入每个提示、用图像编码器嵌入图像,选出与图像嵌入余弦相似度最高的类别——全程从未见过任何 ImageNet 训练样本。

ALIGN:用规模抵消噪声

ALIGN(Jia et al., 2021)把 CLIP 的思路推到更嘈杂、更大的数据集上:18 亿(1.8B)图像-文本对,几乎不做过滤。CLIP 精心筛选数据,ALIGN 则证明规模可以补偿噪声:它使用 EfficientNet 图像编码器和 BERT 文本编码器,训练用同样的对比损失。关键发现是——数据足够多时,昂贵的数据清洗并非必需,因为对比目标会天然降权噪声对:噪声对产生不一致的梯度,其贡献自然被稀释。

SigLIP:用逐对 Sigmoid 取代全局 Softmax

SigLIP(Sigmoid Loss for Language-Image Pre-training,Zhai et al., 2023)用更简单的 sigmoid 损失替换 CLIP 的 softmax 对比损失。CLIP 把 $N \times N$ 相似度矩阵当作分类问题处理(每一行对列做 softmax);SigLIP 则把每个条目独立当作二分类:这个(图像, 文本)对是否匹配?

单对 $(i, j)$ 的 SigLIP 损失为:

$$\mathcal{L}{ij} = -y{ij} \log \sigma(z_i^{\text{img}} \cdot z_j^{\text{txt}} / \tau) - (1 - y_{ij}) \log(1 - \sigma(z_i^{\text{img}} \cdot z_j^{\text{txt}} / \tau))$$

其中 $y_{ij} = 1$($i = j$,匹配)或 $0$(不匹配),$\sigma$ 为 sigmoid 函数。

SigLIP 的关键优势是消除了跨整批的全局 softmax 归一化。CLIP 中 softmax 分母需要在所有设备间收集全部嵌入,这在分布式训练中是通信瓶颈;SigLIP 的逐对 sigmoid 损失可以完全本地计算,从而更高效地扩展到超大批次。结果:SigLIP 以更低的训练成本达到与 CLIP 相当的质量。

对比损失函数详解

对比学习的损失函数共享一个共同结构:让正样本对的相似度得分高于负样本对,并借助"间隔(margin)"或"温度"控制推离的力度。下面形式化几个关键变体。

InfoNCE

InfoNCE(Noise-Contrastive Estimation,van den Oord et al., 2018)是 CLIP 损失的理论基础。给定查询 $q$、一个正样本键 $k^+$ 和 $K$ 个负样本键 ${k_1^-, \ldots, k_K^-}$:

$$\mathcal{L}{\text{InfoNCE}} = -\log \frac{\exp(q \cdot k^+ / \tau)}{\exp(q \cdot k^+ / \tau) + \sum{j=1}^{K} \exp(q \cdot k_j^- / \tau)}$$

这是一个 $(K+1)$ 类分类问题:在 $K+1$ 个候选中识别出正样本。InfoNCE 是查询与正样本键之间互信息的下界,因此最大化它会对齐语义匹配输入的表示。下界随负样本数 $K$ 增加而收紧——这解释了为什么对比方法受益于大批次。

NT-Xent

NT-Xent(Normalised Temperature-scaled Cross-Entropy,Chen et al., 2020)是 SimCLR 使用的损失,本质是对批内对称施加的 InfoNCE。对 $N$ 个样本对的批次,$2N$ 个增强视图为每个锚点提供 $2N - 2$ 个负样本(除自己和其正样本外的所有视图)。正样本对 $(i, j)$ 的损失为:

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

NT-Xent 与 InfoNCE 是同一个数学公式,命名不同只源于提出场景不同(自监督视觉 vs. 表示学习理论)。

温度的作用

温度$\tau$ 是对比学习中最重要的超参数之一。用物理直觉理解:高温下分子随机运动(softmax 平坦,所有负样本"看起来一样差");低温下分子凝固成刚性结构(softmax 尖锐,只有最难的那个负样本重要)。

形式上,$\tau \to 0$ 时 softmax 逼近硬 argmax,只选单个最难负样本;$\tau \to \infty$ 时所有负样本等权贡献。实践中,对归一化嵌入 $\tau \in [0.01, 0.1]$ 效果良好:温度过低导致训练不稳定(难负样本产生极大的梯度),温度过高则损失对匹配错误的区分度钝化。

CLIP 以 $\tau = 0.07$ 初始化,并以对数参数化的标量 $\tau = \exp(t)$ 形式学习它——$t$ 与模型权重一起用梯度下降更新,让模型在训练中自动调节对比任务的难度。

三元组损失与负样本挖掘

在 InfoNCE 成为主流之前,**三元组损失(triplet loss)**是度量学习的标准。给定锚点 $a$、正样本 $p$、负样本 $n$:

$$\mathcal{L}_{\text{triplet}} = \max(0, |a - p|^2 - |a - n|^2 + m)$$

其中 $m$ 是间隔项,保证正样本至少比负样本近 $m$。三元组损失以单个三元组为单位操作,比批级 InfoNCE 样本效率低,且对挖掘策略敏感:随机负样本往往太简单(损失为零),因此难负样本挖掘(选最接近的错误匹配)或半难挖掘(选落在间隔内的负样本)至关重要。

InfoNCE 在整个批内隐式执行难负样本挖掘——这是它在大规模下胜过三元组损失的原因之一:softmax 归一化自动对与锚点高相似的负样本加权,提供了无需显式挖掘的自然课程学习。

图文检索与零样本分类

有了训练好的联合嵌入空间,就可以做图文检索:给定图像查询,从数据库中找最相关的文本(图到文);或给定文本查询,找最相关的图像(文到图)。这本质上就是共享嵌入空间中的最近邻搜索——像一个能在百万条目录中瞬时比较任意照片与任意标题的图书管理员,无需预先理解所有可能的类别,只需测量"接近度"。

零样本分类是文到图检索的特例。给定 $K$ 个类别名,构造文本提示 ${t_1, \ldots, t_K}$(如 "a photo of a cat"、"a photo of a dog")并嵌入。对新图像 $x$,预测类别为:

$$\hat{y} = \arg\max_{k} ; \text{sim}(f_\theta(x), g_\phi(t_k))$$

关键洞见:文本编码器充当了灵活的分类头。无需为每个下游任务训练新的线性层,只用自然语言描述任务即可。这正是 CLIP 泛化良好的原因——文本编码器在预训练中见过数百万条多样化描述。

提示工程(prompt engineering)很重要。仅把提示模板从 "{class name}" 改成 "a photo of a {class name}",CLIP 在 ImageNet 上的零样本精度就从 63.2% 提升到 68.4%。更进一步,**提示集成(prompt ensembling)**对多个模板("a photo of a {class name}"、"a good photo of a {class name}"、"a drawing of a {class name}")的文本嵌入取平均,得到更鲁棒的文本表示。

这种表示空间还直接支撑下游系统:第 10 章文件 04中,DALL-E 用 CLIP 对候选图重排序,CLIPScore 用 CLIP 嵌入余弦相似度度量生成图文对齐度;第 18 章文件 05的相似图片检索系统则把 CLIP 图像编码器作为查询嵌入模型接入 ANN 搜索。

视听对应:文本之外的下一个模态

闭眼听某人拍篮球——你能从有节奏的"咚咚"声判断球何时落地。睁眼一看,视觉弹跳与每次"咚咚"精确对齐。这种音视频事件间的紧密对应是机器可以无监督学习的免费监督信号。**视听对应学习(audio-visual correspondence learning)**训练模型把声音与视觉声源关联起来,全程无需人工标注。

思路与 CLIP 惊人地相似,只是用音频替代文本:给定配对的视频帧与音频片段,模型学习一个嵌入空间,使时间上对齐的视听对接近、错位的对远离。

**听觉-视觉嵌入(AVE,Audio-Visual Embedding,Arandjelovic and Zisserman, 2017)**方法在视频数据上用对比损失训练视觉编码器 $f$ 与音频编码器 $g$:正样本是(视频帧, 同时刻音频片段),负样本是其他视频或不同时段的音频片段。模型无需标签就学会"狗叫声配狗的图像""吉他声配吉他的图像"。

音频编码器通常用 CNN 或音频 Transformer 处理log-mel 频谱图(特征提取链路详见 第 9 章文件 01:16 kHz 采样 → 分帧 → FFT → mel 滤波器组 → 对数压缩),产出固定尺寸嵌入;视觉编码器用标准图像骨干(ResNet、ViT)处理视频帧。两者投射到共享 $d$ 维空间,训练使用与 CLIP 相同的 InfoNCE 损失:

$$\mathcal{L}{\text{AV}} = -\log \frac{\exp(\text{sim}(z^{\text{vis}}, z^{\text{aud}}) / \tau)}{\sum{k=1}^{N} \exp(\text{sim}(z^{\text{vis}}, z_k^{\text{aud}}) / \tau)}$$

视听学习的应用包括:声源定位(声音从图像哪个位置发出?)、视听语音识别(结合唇动与音频,见 第 9 章文件 02)、视听声源分离(看着某人的脸分离出他的声音,即 第 9 章文件 05中的"鸡尾酒会"问题)、以及以音频为条件的视频生成。

ImageBind(Girdhar et al., 2023)把这一思想扩展到六个模态:图像、文本、音频、深度、热成像与 IMU 数据。关键洞见是:不需要每个模态组合都有配对数据。把每个模态都对齐到图像(文本用图文对、音频用图音频对……),所有模态就通过共享的图像嵌入空间隐式对齐——这种经由公共"锚定模态"的绑定产生涌现对齐:音频与文本即便从未一起训练过也会变得相似。

评估:零样本基准与检索指标

评估多模态模型需要能刻画跨模态理解能力的指标,主流范式是零样本基准检索指标

零样本基准与线性探针

零样本评估衡量模型能否执行从未显式训练过的任务。最常用的是ImageNet 零样本精度:把全部 1,000 个 ImageNet 类别名嵌入为文本、嵌入每张测试图像,基于余弦相似度测 top-1 与 top-5 分类精度。CLIP ViT-L/14 零样本达到 75.5% top-1,与在 ImageNet 上监督训练的 ResNet-50 相当。

其他零样本基准包括 CIFAR-10/100、STL-10、Food-101、Oxford Pets 和 Flowers-102。跨多个数据集评估可检验模型是真正具备视觉理解,还是仅仅记住了预训练数据中的模式。

**线性探针(linear probe)**是互补测试:冻结预训练图像编码器,为带标签数据集提取特征,在其上训练一个简单线性分类器。这独立于零样本检索机制、单独度量学到的表示质量。CLIP 的特征是优秀的线性探针特征,常常匹敌甚至超过监督预训练。

检索指标:Recall@K 与超越检索

检索任务(图到文、文到图)的标准指标是Recall@K(R@K):正确匹配出现在检索结果前 $K$ 名中的查询占比,常用 R@1、R@5、R@10。形式上,对 $Q$ 个查询:

$$\text{R@}K = \frac{1}{Q} \sum_{q=1}^{Q} \mathbf{1}[\text{rank}(q) \leq K]$$

其中 $\text{rank}(q)$ 是正确匹配在查询 $q$ 排序检索列表中的位置。

标准检索基准包括Flickr30K(31,000 张图像,每张 5 条标题)与MS-COCO(123,000 张图像,每张 5 条标题)。评估在测试集上进行:给定图像,从整个测试集中检索正确标题,反之亦然。

**中位秩(Median Rank,MedR)**是互补指标:所有查询中正确匹配位置的中位数。完美模型 MedR = 1,越低越好。

检索之外,多模态模型还会在组合理解基准上受测:Winoground检验模型能否区分"a mug in a dog"与"a dog in a mug";ARO(属性、关系、顺序)检验模型是真正理解语言结构,还是仅仅匹配词袋。CLIP 类模型在这类基准上常常表现不佳,暴露了根本局限:对比预训练对齐的是全局语义,未必能捕获细粒度的组合结构。

动手实现:三个 JAX 实验

原文档附带三个完整的 JAX 编程任务(建议用 Colab 或本地 notebook 运行)。仓库的 javascripts/pyodide-runner.js 从源码结构看为站点挂载了一个基于 Pyodide(v0.27.7)的浏览器内 Python 运行器,默认预载numpymatplotlib并通过micropip可加装其他包;而本节的 JAX 代码更适合直接复制到 notebook 中运行。

任务 1:从零实现 CLIP 对称对比损失

创建随机图像与文本嵌入、计算相似度矩阵、计算对称交叉熵损失:

import jax import jax.numpy as jnp import matplotlib.pyplot as plt def clip_loss(image_embeds, text_embeds, temperature=0.07): """Compute symmetric CLIP contrastive loss.""" # L2 normalise embeddings image_embeds = image_embeds / jnp.linalg.norm(image_embeds, axis=1, keepdims=True) text_embeds = text_embeds / jnp.linalg.norm(text_embeds, axis=1, keepdims=True) # Compute cosine similarity matrix (N x N) logits = image_embeds @ text_embeds.T / temperature # (N, N) # Labels: the diagonal (i-th image matches i-th text) N = logits.shape[0] labels = jnp.arange(N) # Symmetric cross-entropy: image-to-text + text-to-image loss_i2t = -jnp.mean(jax.nn.log_softmax(logits, axis=1)[jnp.arange(N), labels]) loss_t2i = -jnp.mean(jax.nn.log_softmax(logits, axis=0)[labels, jnp.arange(N)]) return (loss_i2t + loss_t2i) / 2, logits * temperature # Simulate a batch of 8 image-text pairs in 64-dim space key = jax.random.PRNGKey(42) k1, k2 = jax.random.split(key) N, D = 8, 64 image_embeds = jax.random.normal(k1, (N, D)) text_embeds = jax.random.normal(k2, (N, D)) loss, sim_matrix = clip_loss(image_embeds, text_embeds) print(f"CLIP loss (random embeddings): {loss:.4f}") # Visualise the similarity matrix fig, ax = plt.subplots(figsize=(6, 5)) im = ax.imshow(sim_matrix, cmap='coolwarm', vmin=-1, vmax=1) ax.set_xlabel("Text index"); ax.set_ylabel("Image index") ax.set_title(f"Cosine Similarity Matrix (loss={loss:.3f})") plt.colorbar(im); plt.tight_layout(); plt.show() # Try changing temperature (0.01, 0.1, 1.0) and observe how loss changes # Try making matched pairs similar: set text_embeds = image_embeds + small noise

实验要点:随机嵌入下损失约在 $\log N$ 附近;把text_embeds = image_embeds + 小噪声后损失显著下降;温度从 0.01 到 1.0 会明显改变损失量级,直观印证温度章节的分析。

任务 2:玩具联合嵌入模型——用 InfoNCE 学习对齐

让一个可学习的投影层把"图像"(随机向量)与"标题"(另一组随机向量)对齐,观察损失从随机基线 $\log N$ 下降:

import jax import jax.numpy as jnp import matplotlib.pyplot as plt def info_nce_loss(img_enc, txt_enc, img_data, txt_data, tau=0.1): """InfoNCE over a batch of paired (image, text) data.""" z_img = img_data @ img_enc # (N, D) z_txt = txt_data @ txt_enc # (N, D) # L2 normalise z_img = z_img / jnp.linalg.norm(z_img, axis=1, keepdims=True) z_txt = z_txt / jnp.linalg.norm(z_txt, axis=1, keepdims=True) logits = z_img @ z_txt.T / tau labels = jnp.arange(logits.shape[0]) return -jnp.mean(jax.nn.log_softmax(logits, axis=1)[jnp.arange(len(labels)), labels]) # Create 32 paired samples: img in R^8, txt in R^6, embed into R^4 key = jax.random.PRNGKey(0) k1, k2, k3, k4 = jax.random.split(key, 4) N, d_img, d_txt, d_embed = 32, 8, 6, 4 img_data = jax.random.normal(k1, (N, d_img)) txt_data = jax.random.normal(k2, (N, d_txt)) # Learnable projection matrices img_enc = jax.random.normal(k3, (d_img, d_embed)) * 0.1 txt_enc = jax.random.normal(k4, (d_txt, d_embed)) * 0.1 grad_fn = jax.jit(jax.grad(info_nce_loss, argnums=(0, 1))) lr = 0.05 losses = [] for step in range(300): loss = info_nce_loss(img_enc, txt_enc, img_data, txt_data) losses.append(float(loss)) g_img, g_txt = grad_fn(img_enc, txt_enc, img_data, txt_data) img_enc = img_enc - lr * g_img txt_enc = txt_enc - lr * g_txt print(f"Initial loss: {losses[0]:.3f}, Final loss: {losses[-1]:.3f}") print(f"Random baseline (log N): {jnp.log(N):.3f}") plt.figure(figsize=(8, 4)) plt.plot(losses, color='#2c3e50') plt.axhline(y=0, color='green', linestyle='--', alpha=0.5, label='Perfect alignment') plt.axhline(y=float(jnp.log(N)), color='red', linestyle='--', alpha=0.5, label='Random (log N)') plt.xlabel("Step"); plt.ylabel("InfoNCE Loss") plt.title("Learning a Joint Embedding Space") plt.legend(); plt.grid(alpha=0.3); plt.tight_layout(); plt.show() # Modify d_embed (try 2, 4, 16) to see how embedding dimension affects alignment

两条参考线给出直观标尺:绿色虚线(0)是完美对齐,红色虚线($\log N$)是随机猜测基线。修改d_embed(试 2、4、16)可观察嵌入维度对对齐能力的影响——维度太低则容量不足。

任务 3:零样本分类模拟(预计算嵌入 + 最近邻)

用 5 个类别原型(模拟文本编码器输出)和 200 个带噪"图像嵌入"模拟零样本最近邻分类,并输出混淆矩阵:

import jax import jax.numpy as jnp import matplotlib.pyplot as plt # Simulate 5 classes, each with a prototype text embedding in R^32 key = jax.random.PRNGKey(42) n_classes, d = 5, 32 class_names = ["cat", "dog", "car", "plane", "ship"] # Class prototypes (imagine these came from a text encoder) k1, k2 = jax.random.split(key) class_prototypes = jax.random.normal(k1, (n_classes, d)) class_prototypes = class_prototypes / jnp.linalg.norm(class_prototypes, axis=1, keepdims=True) # Generate 200 test "images" (embeddings near their class prototype + noise) n_per_class = 40 true_labels = jnp.repeat(jnp.arange(n_classes), n_per_class) keys = jax.random.split(k2, n_classes * n_per_class) image_embeds = [] for i in range(n_classes): noise = jax.random.normal(keys[i], (n_per_class, d)) * 0.5 cluster = class_prototypes[i] + noise image_embeds.append(cluster) image_embeds = jnp.concatenate(image_embeds, axis=0) image_embeds = image_embeds / jnp.linalg.norm(image_embeds, axis=1, keepdims=True) # Zero-shot classification: cosine similarity with each prototype similarities = image_embeds @ class_prototypes.T # (200, 5) predicted_labels = jnp.argmax(similarities, axis=1) accuracy = jnp.mean(predicted_labels == true_labels) print(f"Zero-shot accuracy: {accuracy:.1%}") # Confusion matrix conf = jnp.zeros((n_classes, n_classes), dtype=jnp.int32) for true, pred in zip(true_labels, predicted_labels): conf = conf.at[true, pred].add(1) fig, ax = plt.subplots(figsize=(6, 5)) im = ax.imshow(conf, cmap='Blues') ax.set_xticks(range(n_classes)); ax.set_xticklabels(class_names, rotation=45) ax.set_yticks(range(n_classes)); ax.set_yticklabels(class_names) ax.set_xlabel("Predicted"); ax.set_ylabel("True") for i in range(n_classes): for j in range(n_classes): ax.text(j, i, int(conf[i, j]), ha='center', va='center', fontsize=11) ax.set_title(f"Zero-Shot Confusion Matrix (acc={accuracy:.1%})") plt.colorbar(im); plt.tight_layout(); plt.show() # Try increasing noise (0.5 -> 1.0 -> 2.0) to see accuracy degrade # Try adding prompt ensembling: average 3 noisy copies of each prototype

两个扩展实验对应正文章节:把噪声从 0.5 逐步加大到 2.0,观察精度退化——模拟"嵌入空间对齐质量差"的后果;对每个原型做"提示集成"(平均 3 份带噪副本),验证多模板平均能提升文本表示的鲁棒性。

本篇在 Compendium 中的位置与延伸学习

本章五个文件层层递进,本文件构建的联合嵌入空间是其余内容的"胶水":

  • 02. vision language models.md:视觉语言模型(VQA、图像描述、视觉定位)。LLaVA 正是把本文件的 CLIP ViT-L/14 作为视觉编码器,经投影层接入 LLM;其训练目标中的"图文对比损失(ITC)"直接复用本文件的 InfoNCE 公式。
  • 03. image and video tokenisation.md:图像与视频如何被 tokenize 后用于序列模型(VQ-VAE、VQ-GAN、残差量化)。
  • 04. cross-modal generation.md:跨模态生成(DALL-E、Stable Diffusion、文生视频)。文中 T5 替代 CLIP 作为文本编码器的对比(Imagen)、CLIPScore 对齐度指标,都建立在本文件的双编码器之上。
  • 05. unified multimodal architectures.md:统一多模态架构。其"阶段 2:跨模态对齐"正是把本文件的 CLIP 式对比目标折入统一模型。

前向依赖的章节基础:视觉 Transformer 与生成模型见 第 8 章文件 04,log-mel 频谱图与 mel 滤波器组链路见 第 9 章文件 01,Transformer 与词嵌入见 第 7 章。

对 Agent 与 LLM 而言,本仓库还内建了知识检索通道:mcp/src/index.ts 实现了一个 MCP 服务器,按正则^chapter (\d{2})(?::| -) (.+)$解析章节目录、解析 llms.txt 中每个文件的摘要(本文件对应条目为 "Fusion strategies, CLIP, ALIGN, SigLIP, contrastive learning, InfoNCE"),供 AI 助手把整个 Compendium 作为知识库调用;站点由 mkdocs.yml 以 Material 主题构建,公式通过 MathJax 渲染(pymdownx.arithmatex+ javascripts/mathjax.js),因此本文中的全部 $\LaTeX$ 公式在在线阅读时可直接渲染。

核心结论:在配对数据上做对比学习,得到的嵌入空间里不同模态是"可互换的"——图像嵌入和文本嵌入变成"同一种东西",从而支持零样本分类、检索与更大系统的无缝集成。这个想法的朴素程度——"拉近匹配对、推远未匹配对"——与其巨大的有效性形成鲜明对比。

【免费下载链接】maths-cs-ai-compendiumBecome a cracked AI/ML researcher/engineer with this unconventional textbook covering maths, computing, and ML with intuition.项目地址: https://gitcode.com/GitHub_Trending/mat/maths-cs-ai-compendium

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 16:45:57

Sentinel链路流控模式原理与实践指南

1. Sentinel链路流控模式深度解析作为一名长期使用Sentinel进行系统流量控制的开发者,我发现很多团队对链路流控模式的理解存在误区。今天我将结合实战经验,详细拆解这个功能的核心机制与配置细节。链路模式(Entry Limit)是Sentin…

作者头像 李华
网站建设 2026/9/16 16:43:57

STC15W408AS电流表设计:ADC采样、LCD1602显示与校准

简介:基于STC15W408AS的电流表设计是一份完整的软硬件工程资料,面向电子爱好者、单片机学习者及硬件工程师,解决电流测量与LCD1602实时显示问题。资源包共23个文件,约10.35MB,包含C语言源程序、A51启动文件、hex可执行…

作者头像 李华
网站建设 2026/9/16 16:42:42

PyTorch定制ResNet实现老虎细粒度识别

简介:本资源是一份面向深度学习初学者与计算机视觉实践者的PyTorch实战项目,聚焦于野生动物细粒度识别任务,提供完整的ResNet图像分类解决方案。项目基于PyTorch实现ResNet网络架构,专用于107类老虎品种(含东北虎、华南…

作者头像 李华
网站建设 2026/9/16 16:41:44

基于Vue+SpringBoot的健身房管理系统设计与实现指南

毕业设计做到健身房管理系统这个题目,在最近几年其实非常常见,但恰好也是“看起来简单、做起来容易翻车”的典型题目。很多同学一上来就急着写代码,结果做完才发现业务逻辑一团乱麻、答辩时讲不清楚、源码里还埋了不少自己都不知道的坑。我见…

作者头像 李华
网站建设 2026/9/16 16:41:44

51单片机闭环直流电机控制系统:从PWM到PID的完整实现

简介:基于51单片机的闭环直流电机控制系统资料包,面向电子设计学习者与竞赛选手,适合课程设计、毕业设计及项目入门。方案以AT89C51为核心,通过P1.0输出占空比可调PWM,用4个独立按键设定速度,并用两个4位共…

作者头像 李华