AI-For-Beginners 多模态网络实战指南:从 CLIP 对比学习到 VQGAN+CLIP 与 DALL-E 图像生成
AI-For-Beginners 多模态网络实战指南:从 CLIP 对比学习到 VQGAN+CLIP 与 DALL-E 图像生成
导读
本文是 AI-For-Beginners 课程 X-Extras 扩展单元的配套技术指南,围绕 lessons/X-Extras/X1-MultiModal/README.md 展开,系统讲解多模态模型的三大核心主题:CLIP 的对比式图文预训练、VQGAN+CLIP 的文本引导图像生成,以及 DALL-E 系列图像生成模型。读者将掌握 CLIP 在零样本图像分类与基于文本的图像搜索两大任务上的完整代码用法,理解对比学习损失函数的原理,并能复现仓库中 Clip.ipynb 的全部实验,为后续接触多模态大模型打下扎实基础。
从 NLP 到多模态:为什么需要图文联合建模
Transformer 模型在自然语言处理(NLP)任务上取得成功后,相同或相近的架构被陆续应用到计算机视觉任务中。与此同时,业界对能够同时结合视觉与语言能力的模型产生了浓厚兴趣——这类模型被称为多模态模型。OpenAI 在这一方向上的代表性尝试就是 CLIP 与 DALL-E,二者正是本课程第 X1 课的核心内容。
课程索引:本课在 lessons/README.md 第 118 行的课程总表中被列为第 25 课,对应"Multi-Modal Networks, CLIP and VQGAN",并配有 Clip.ipynb 实践笔记本。
CLIP:对比式图像-文本预训练(Contrastive Image Pre-Training)
核心思想:衡量图文匹配程度
CLIP 的核心思想非常直观:将一段文本提示(text prompt)与一张图像进行比较,判断该图像与提示的匹配程度。
对比学习(Contrastive Learning)的损失设计
CLIP 使用从互联网抓取的图片及其配文(caption)作为训练数据。在每个批次中,取 N 对 (图像, 文本) 样本,分别转换为向量表示:
- 图像侧:I₁, ..., I_N
- 文本侧:T₁, ..., T_N
随后这些表示被相互配对计算损失。损失函数的定义目标是:
- 最大化成对样本(如 Iᵢ 与 Tᵢ)之间的余弦相似度;
- 最小化所有非成对样本之间的余弦相似度。
正因训练目标建立在"正样本对相似、负样本对不相似"的对比之上,这种方法被称为对比学习(contrastive)。CLIP 的模型与库可获取自 OpenAI 的 CLIP 开源仓库,方法细节参见 OpenAI 官方博客及论文 Learning Transferable Visual Models From Natural Language Supervision。
预训练之后能做什么
模型完成预训练后,给定一批图像和一批文本提示,它会返回一个包含匹配概率的张量。基于这一能力,CLIP 可以自然承接多种下游任务,而无需针对每个任务单独训练模型——这正是"零样本"能力的来源。
任务一:图像分类(Image Classification)
假设需要在"猫、狗、人类"之间对图像分类。做法是给模型一张图像和一组文本提示:
- "a picture of a cat"(一张猫的照片)
- "a picture of a dog"(一张狗的照片)
- "a picture of a human"(一张人的照片)
模型会输出一个包含 3 个概率的向量,只需取其中值最大的索引对应的类别即可完成分类。
任务二:基于文本的图像搜索(Text-Based Image Search)
反过来也可以:如果我们有一批图像集合,把整个集合和一条文本提示一起送入模型,CLIP 会返回与该提示最相似的图像。这一特性使图像检索从"标签匹配"升级为"语义匹配",甚至可以理解画面中物体的空间配置关系。
动手实验:用 Clip.ipynb 复现零样本分类与图像搜索
仓库在 Clip.ipynb 中给出了 CLIP 的完整可运行示例(该笔记本来自 AI for Beginners 课程)。以下代码均取自笔记本原始单元,可直接在 Jupyter 环境中执行。
第一步:安装与加载 CLIP
首先从 OpenAI 的 GitHub 仓库安装 CLIP 库:
import sys
!{sys.executable} -m pip install git+https://github.com/openai/CLIP.git
然后导入依赖、自动选择计算设备并加载预训练模型:
import torch
import clip
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import os
np.set_printoptions(precision=2, suppress=True)
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load("ViT-B/32", device=device)
关键 API 说明:
clip.load("ViT-B/32", device=device):加载以 ViT-B/32 视觉骨干为基础的预训练模型,同时返回配套的图像预处理管线preprocess;- 代码自动检测 GPU(
cuda),无 GPU 时回退到 CPU; - 笔记本中特别提示:CLIP 对资源(显存/内存)的消耗相当大,在资源受限环境需要注意。
第二步:准备猫图片数据集
实验使用 Oxford-IIIT 宠物数据集的一个子集(只保留猫的图片):
!wget https://mslearntensorflowlp.blob.core.windows.net/data/oxcats.tar.gz
!tar xfz oxcats.tar.gz
!rm oxcats.tar.gz
下载并解压后,当前目录会得到 oxcats/ 文件夹,内含若干猫的图像文件(如 Maine_Coon_1.jpg)。
第三步:零样本图像分类(Zero-Shot Image Classification)
CLIP 最核心的能力是"图像与文本提示匹配"。取一张猫的图片,分别与文本提示 "a penguin"、"a bear"、"a cat" 匹配——第一项(猫)理应得到最高概率。由于模型已在海量数据上完成预训练,无需再训练任何参数即可分类,因此被称为零样本(zero-shot):
image = preprocess(Image.open("oxcats/Maine_Coon_1.jpg")).unsqueeze(0).to(device)
text = clip.tokenize(["a penguin", "a bear", "a cat"]).to(device)
with torch.no_grad():
image_features = model.encode_image(image)
text_features = model.encode_text(text)
logits_per_image, logits_per_text = model(image, text)
probs = logits_per_image.softmax(dim=-1).cpu().numpy()
print("Label probs:", probs)
笔记本中的实际运行输出为:
Label probs: [[0. 0. 1.]]
即模型以接近 100% 的置信度把这张图判定为 "a cat"。这里需要注意数据流向:
model.encode_image(image)与model.encode_text(text)分别提取图像与文本的特征向量;model(image, text)返回logits_per_image与logits_per_text两个方向的对数几率;- 对
logits_per_image在最后一维做softmax,得到各文本提示的匹配概率。
第四步:智能图像搜索(Intelligent Image Search)
上一个例子是"单图像 × 多文本提示";本实验反过来,"多图像 × 单文本提示"——从一批猫图片中挑出最符合文字描述的那一张:
cats_img = [ Image.open(os.path.join("oxcats", x)) for x in os.listdir("oxcats") ]
cats = torch.cat([ preprocess(i).unsqueeze(0) for i in cats_img ]).to(device)
text = clip.tokenize(["a very fat gray cat"]).to(device)
with torch.no_grad():
logits_per_image, logits_per_text = model(cats, text)
res = logits_per_text.softmax(dim=-1).argmax().cpu().numpy()
print("Img Index:", res)
plt.imshow(cats_img[res])
笔记本中的实际运行输出为:
Img Index: 97
即模型在图片集合中检索出了索引为 97 的那张"很胖的灰猫",并用 matplotlib 展示结果。注意这里 softmax 与 argmax 作用在 logits_per_text 上,因为此时是"一条文本 vs 一批图像",我们需要找到与文本最匹配的图像位置。
实验结论(Takeaway)
笔记本末尾总结了两条要点:
- 预训练的 CLIP 模型无需领域特定训练,即可对常见物体执行图像分类等任务;
- 相比传统方法,CLIP 允许更灵活的分类与图像搜索——它能利用提示语的语义,从而考虑图片中物体的空间配置关系。
若想探索 CLIP 的另一个激动人心的用法,可进一步了解 VQGAN+CLIP。
从文本生成图像:VQGAN+CLIP 工作原理
CLIP 不仅可用于判别式任务,还可以参与图像生成。要从文本提示生成图像,需要有一个生成器模型,它能够基于某种输入向量生成图像。其中之一就是 VQGAN(Vector-Quantized GAN,向量量化 GAN)。
VQGAN 与普通 GAN 的区别
课程在 10-GANs 单元 中系统讲解过 GAN(生成对抗网络)。VQGAN 与普通 GAN 相比,有两点关键差异:
- 自回归 Transformer 架构:VQGAN 使用自回归 Transformer 架构,生成一系列"上下文丰富"的视觉片段(visual parts)来组成整幅图像;这些视觉片段反过来由 CNN(卷积神经网络,见 07-ConvNets 单元) 学习得到;
- 子图像判别器(sub-image discriminator):VQGAN 使用子图像判别器,判断图像的各个局部片段是"真实"还是"伪造",而非传统 GAN 中"全有或全无"的整图判别方式。
为什么需要 CLIP 引导
VQGAN 与传统 GAN 的一个重要区别在于:传统 GAN 从任意输入向量出发往往都能生成一张像样的图像,而 VQGAN 很可能生成**不连贯(incoherent)**的图像。因此,我们需要进一步"引导"图像创作过程——这正是 CLIP 的用武之地。
完整的生成流程
要生成一张与文本提示对应的图像,整体流程如下:
- 从一个随机的编码向量开始;
- 将该向量送入 VQGAN 生成一张图像;
- 用 CLIP 计算损失函数,评估"图像与文本提示的匹配程度";
- 目标是最小化该损失,通过**反向传播(back propagation)**调整输入向量的参数。
如此迭代,输入向量逐渐被"优化"为能够生成与提示语义一致图像的编码。一个实现了 VQGAN+CLIP 的优秀开源库是 Pixray。
仓库中收录了用 Pixray 基于三条提示生成的三张示例图(来自 Dmitry Soshnikov 的 Artificial Teachers(AI 教师)系列作品):
DALL-E 系列:以统一 Token 流生成图像
DALL-E 1
DALL-E 是 GPT-3 的一个变体,专门训练用于根据文本提示生成图像,参数量达到 120 亿(12-billion)。
与 CLIP 不同,DALL-E 将文本和图像作为单一的 Token 流输入——文本与图像共用同一套序列建模方式。因此,从多条文本提示出发,可以生成与文本内容对应的图像。
DALL-E 2
DALL-E 1 与 DALL-E 2 的主要区别在于:DALL-E 2 能生成更真实的图像与艺术作品。
仓库中同样收录了 DALL-E 生成的示例图,使用的是与 Pixray 示例完全相同的三条提示语:
| DALL-E 生成图像 | DALL-E 生成图像 | DALL-E 生成图像 |
|---|---|---|
| DALL-E 生成的图像:手持书本的年轻男文学教师水彩肖像 | DALL-E 生成的图像:使用电脑的年轻女计算机科学教师油画肖像 | DALL-E 生成的图像:黑板前的老年男数学教师油画肖像 |
| 提示语:a closeup watercolor portrait of young male teacher of literature with a book | 提示语:a closeup oil portrait of young female teacher of computer science with a computer | 提示语:a closeup oil portrait of old male teacher of mathematics in front of blackboard |
两条生成路线放在一起对比即可看出:CLIP 在此处充当"语义对齐器",VQGAN/DALL-E 充当"图像生成器"——前者保证语义匹配,后者保证画面质量。
延伸学习与参考文献
- 想深入了解 VQGAN,可阅读论文 Taming Transformers for High-Resolution Image Synthesis,并在其项目主页了解更多实现细节;
- 想深入理解 CLIP,可阅读论文 Learning Transferable Visual Models From Natural Language Supervision(即 OpenAI 官方博客所描述的对比预训练方法);
- 在课程内,可顺次学习前置单元:GAN 与对抗训练基础 与 卷积神经网络 CNN,它们分别是理解 VQGAN 与 CLIP 视觉编码器的基础。
配套资源:本课完整代码实验位于 Clip.ipynb,中文(西班牙语)翻译版文档位于 translations/es/lessons/X-Extras/X1-MultiModal/README.md,原始英文文档位于 lessons/X-Extras/X1-MultiModal/README.md。





