图片表征的 SOTA 模型:DINO 系列演进与原理剖析
本文主要对比了DINO系列(v1/v2/v3)和CLIP在图搜图任务上的表现。
本文的核心结论:CLIP是文搜图的标杆,DINO是图搜图的标杆——DINO系列因专注于图像自监督学习,更擅长图搜图;CLIP基于图文语义对齐,更适合文搜图。
一、背景
回顾一下,最近在做影视内容相关的建设—希望用户在看完一个视频后,能够自然找到下一集。这个任务经过拆解后,得到一个子问题:如何判断两张图片(或两个视频帧)在视觉上是相似的,或者说包含相似内容?
前序对比 模型参数量越大越好用?qwen-vl-embedding模型实践发现CLIP和 DINOv2的图片表征能力都比qwen-vl-embedding能力要强。那么CLIP和DINO系列模型在图片检索与分类(找相似)这个场景下究竟哪个更强一些?
二、方案设计
为了验证图搜图领域各个模型的能力,我设计了一个图搜图的检索实验。
2.1 数据准备
我使用了ImageNet的一个子集mini_imagenet,这个子集有100个类别、共 70000张图:其中60000张作为待检索的图片(100个类别,每个类别600张),10000张作为query图片进行查询(同样100个类别)。
评估方式是"同类即正确":query检索回来的邻居,类别和它一致就算命中。
2.2 模型选择
我选择了DINO系列3个模型 + CLIP进行对比,全部统一到ViT-B/16量级,保证骨干网络一致。
模型 | 模型卡 | VIT模型 | 向量维度 |
DINOv1 | facebook/dino-vitb16 | ViT-B/16 | 768 |
DINOv2 | facebook/dinov2-base | ViT-B/16 | 768 |
DINOv3 | facebook/dinov3-vitb16-pretrain-lvd1689m | ViT-B/16 | 768 |
CLIP | openai/clip-vit-base-patch16 | ViT-B/16 | 512 |
2.3 执行过程
整个实验流程不复杂,分四步走:
1、embedding计算:各模型用自带的encoder,把70000张图全部跑成向量,输出做L2归一化。
2、入库:每个模型单独存储到一个Milvus collection(gallery_dino、gallery_dinov2、gallery_dinov3、gallery_clip各一份),把60000张底库的向量灌进去,建HNSW索引。四个模型各自一套collection,不混用是为了避免不同模型的向量空间相互干扰,每个模型在自己的空间里被独立评估。
3、查询:10000 张query 各自跑一遍特征提取,到对应的collection里检索 top-100。
4、算指标:把top-100邻居的label和query的真实label一对比,分别算Recall@K和mAP@K,K取 1/5/10。
Recall@K和mAP@K是搜索场景比较标准的两个评估指标,这里简单解释一下:
Recall@K:top-K个邻居里,只要有一个和query同类,就算命中。衡量的是"能不能至少找到一张相似的"——一票通过制。
mAP@K:top-K里同类越靠前、越密集,分数越高。衡量的是"召回的这一批里,到底有多少是真相似的,而且排得有多靠前"——按比例打分。
三、效果对比
3.1 数据对比
四个模型在10000张query上的完整结果:
模型 | Recall@1 | Recall@5 | Recall@10 | mAP@10 |
DINOv1 | 86.7 | 93.4 | 95.2 | 65.1 |
DINOv2 | 90.2 | 95.7 | 97.0 | 75.5 |
DINOv3 | 91.8 | 96.6 | 97.8 | 77.7 |
CLIP | 87.4 | 94.9 | 96.6 | 65.4 |
两个核心结论:
1、在Recall和mAP两个指标表现上,DINOv3 > DINOv2 > CLIP > DINOv1。也就是说,在当前图搜图检索这个任务下,DINOv3模型是最强的。
2、mAP@10上 DINOv2/v3 把CLIP和DINOv1拉开了10个点(75–77 vs 65)。也就是说,让它们各自吐10个邻居出来,DINOv2/v3 这10个里同类的密度,比CLIP高得多。
3.2 主观评估
为了方便观察结果,我把query和四个模型召回的top5拼成了一张图,图片可以放大看:左1是query 图片,左2-6是DINOv1 检索结果,左7-11是DINOv2 检索结果,左12-16是DINOv3检索结果,最右侧5张是CLIP检索结果。绿色框召回正确,红色框为召回错误。
有些例子还是能看出一些问题的:
1、图片中是一个女生正在举杠铃锻炼。DINOv3召回的都是杠铃锻炼图片,而CLIP召回的除了杠铃,还有一些使用哑铃锻炼的图片。
query:
DINOv3召回:
CLIP召回:
2、query是一把类似剪刀的东西,明显由两个部分构成。DINOv3召回的都是画面上很接近的结果,而CLIP召回的很多是语义上的“刀”,而在视觉画面层面并不像。
query:
DINOv3召回:
CLIP召回:
不是说CLIP错了——它只是在按"语义"做事。后面讲对比的时候会回到这件事。
3.3 一个值得讲的坑:fp16把DINOv2拖到了67%
写完上面这一节,我插一个我自己踩过的坑——它对效果影响很大。
第一轮跑实验,我所有模型都用fp16(MPS 推理,省显存),结果DINOv2的 Recall@1只有67.2%,mAP@10只有26.3%。一开始我以为是DINOv2在这个数据集上水土不服,后来换成fp32重跑同一份代码,Recall@1直接从67.2跳到90.2,mAP@10从26.3跳到75.5。23个点的差距,全在数值精度。
DINOv1、DINOv3、CLIP在fp16下都没这个问题。下探了一下原因:DINOv2在每个transformer block里都加了一个叫LayerScale的模块——给通道乘一个可学习的小系数lambda1,初始化是1e-5,fp16 的相对精度只有10⁻³量级,乘上这么小的数再做残差连接,每一层都丢一点信息,12层transformer × 2次LayerScale,一路累积下来,最后CLS的方向就被噪声带歪了。
四、DINO 系列模型的原理解析
要讲清楚为什么DINO在图搜图上表变现更好,得回到它的原理和训练方式去看。
故事得从隔壁NLP说起。最近几年大模型的能力大爆发,回头看会发现有一个共同的起手式:自监督预训练。BERT、GPT系列做的事情其实是一样的——把一大堆没标注的文本扔进去,让模型自己跟自己玩"完形填空"或者"接下一个词",把语言的结构学进参数里。这条路被证明能work,然后大家就在想:图像能不能也这么干?
直接照搬很困难,图像没有"词"这种天然的离散单元,也没有"下一个token"这种天然的预测目标,自监督任务得自己造。从2018年到现在,图像领域在这条路上有过很多探索,DINO就是其中非常成功的一个方向。
4.1 DINOv1(2021年):基于VIT的自监督训练
DinoV1的训练方式用一句话来概括:对于同一张图片,让表征局部图片的embedding和表征全局图片的embedding距离无限缩小,从而让模型学到能够表征图片特点的特征。不用标签、不用文本,只靠图像自己跟自己学,是一种基于VIT的自监督学习模型。
(DINO 自监督学习模型结构)
4.1.1 模型结构
DINOv1的模型结构并不复杂:Student和 Teacher是同一个架构——ViT骨干网络 + 投影头。
Backbone(核心网络)是标准的 Vision Transformer(ViT),负责把图像切成 Patch,提取特征。最终输出使用 [CLS] 全局Token作为整张图的特征代表。
投影头是一个 3 层 MLP(768 → 2048 → 2048 → K),它的作用是把 Backbone 输出的 768 维通用特征,投影到 K 维(K=65536)的“虚拟类别空间”里,用来计算损失。
4.1.2 训练策略:Multi-crop
DINO 采用了一个叫Multi-crop的数据增强策略,这也是DINO能“无师自通”学会分割的关键设计之一。
对每一张输入图片,生成一组不同尺寸、不同覆盖范围的裁剪视图:
2个全局视图(Global Crops):覆盖原图面积的50%~100%。这两个大图包含了图片的绝大部分信息。
6到10个局部视图(Local Crops):覆盖原图面积的15%~50%。这些小图只覆盖图片的一小部分(比如只看到猫耳朵、猫尾巴,或者一块草地)。
这些视图怎么分配给Student和Teacher?
Teacher(老师):只看2个全局视图。它视野开阔,能看到整只猫的全貌。
Student(学生):看所有视图(2个全局+ 6~10 个局部)。它不仅要看大图,还要看大量的小碎片。
4.1.3 损失函数
DINO的损失函数本质上就一件事:让Student的输出去匹配Teacher的输出,用交叉熵算损失,从而让局部图片和全局图片注意到相同的特征。
对于一张图片,生成一组视图 V(2 个全局视图 + 若干个局部视图),损失函数定义为:
外层求和:Teacher只看那两张全局大图(Teacher不看局部小图)。
内层求和:Student 看所有视图(全局 + 局部)
交叉熵:计算Teacher输出的概率分布Pt和Student输出的概率分布Ps之间的差距。
4.1.4 EMA向量更新与模型防塌陷
EMA动量更新:Teacher 的参数不参与反向传播,而是 Student 的 EMA(指数滑动平均):由于Student和Teacher模型结构相同,每次模型训练反向传播更新的是Student模型的参数,然后按微小比例缓慢更新到Teacher模型上。
Centering(中心化):Teacher输出向量前减去一个历史均值,避免某一维度向量过于突出,防止学生和教师过渡依赖某一维度特征,学习不到真正的图片特征。
Sharpening(锐化):Teacher输出前除以一个极小的温度(如 0.07),把微小差异放大,避免教师和学生模型同时产出过于平均的向量导致学习不到真正的图片特征。
这三种处理可以说是DINO这种自蒸馏训练方式带来的独特的处理方式。
4.1.5 VIT自监督学习的“涌现”,物体的识别
DINOv1最让人印象深刻的结果,不是分类准确率,而是Attention Map可视化:把 [CLS] Token 对各个Patch的注意力分数铺回原图,能清晰看到物体的轮廓——猫从背景里被“抠”了出来。
(图片摘自论文,原图和[CLS] 可视化后的结果)
为什么会涌现出分割能力?
拆开来看:Student只看猫耳朵(局部),却要输出整只猫(全局)的特征。为了做到这一点,它必须通过自注意力机制,把“身体Patch”的信息聚合到“耳朵Patch”上。反向传播迫使它给同类Patch高权重、异类Patch低权重。训练完成后,高权重区域和低权重区域的边界,恰好就是物体的物理边缘。
监督学习的ViT做不出这件事,因为分类任务只需要区分猫和狗的整体特征,局部细节对Loss贡献小,会被模型主动忽略。DINO 的学生永远在看残缺的局部,为了活下去,被迫把局部细节和全局结构绑定。
一句话总结:DINO学到的不是“猫”这个标签,而是“哪些像素属于相同分类”的底层规则。 分割能力的涌现不是意外,而是“局部匹配全局”这个数学目标的最优解的自然结果。
4.2 DINOv2(2023):把规模化做完,让特征"开箱即用"
DINOv2 的工作可以理解成 v1 的"工业化升级",做的主要是三件事:
第一,更大的数据量。Meta 自己造了一份 LVD-142M——从一个 12 亿张的未标注图像池里,用一种基于聚类 + 相似度的自动 curation 方法挑出了 142M 张。挑数据的目标是"覆盖度够、冗余度低、质量不差"。这一步是 v2 比 v1 强的最主要原因,远比模型本身的改动重要。
第二,更大的参数量。模型扩到 ViT-g/14(10 亿参数级),加了一系列稳定训练的 trick——比如 KoLeo regularizer(让特征在 hypersphere 上分布更均匀,避免坍缩)、把高分辨率 finetune 单独拎出来作为一个阶段。最大的模型上 12.8 万亿 token 量级训练。
第三,损失函数更新。在 DINOv1的基础上,又加了 iBOT loss(patch-level,被 mask 掉的 patch 要预测原始 token)。这意味着模型不光要学"整张图代表什么",还要学"每个 patch 局部代表什么"。
(图片摘自论文,dinoV2的特征识别效果)
4.3 DINOv3(2025):把dense feature训练的同样稳定
第一:继续增加训练数据量:DINOv3进一步把训练数据从1.42亿张扩展到16.89亿张。
第二:继续增加模型参数量:从11 亿(1.1B)涨到67 亿(6.7B)
第三:避免 dense feature 的退化(核心改进):DINOv2训练里有个现象:模型跑得越久,图像分类等全局指标还在涨,但Patch级别的dense feature反而越来越“糊”——不同Patch之间的特征差异变小,做分割、深度估计时精度下降。DINOv3 引入了一个叫Gram Anchoring的损失函数来解决这个问题。简单说就是:在训练过程中,强制当前模型的Patch间相似度结构,去匹配早期训练阶段(dense feature 还很好时)的Patch间相似度结构,不让局部特征被全局优化目标“带歪”。
第四:其他特性。
蒸馏出一族小模型:用67亿参数的模型做Teacher,一次性蒸馏出ViT-S、B、L、H+ 等多个尺寸的Student,覆盖不同算力需求。其中ViT-H+(8.4 亿参数)在部分任务上接近Teacher水平,参数量却只有后者的1/8。
支持4K分辨率:得益于RoPE位置编码+高分辨率微调,DINOv3能在4096×4096 的输入下稳定输出清晰的特征图。
可选文本对齐:借鉴CLIP的方法,训练文本编码器与 DINOv3 视觉特征对齐,获得零样本分类和开放词汇分割能力。
五、与CLIP的应用对比:CLIP是文搜图的标杆,DINO是图搜图的标杆
讲完原理,回到CLIP和DINO的选型问题:
维度 | CLIP | DINO 系列 |
训练范式 | 图文对比学习 | 图像自监督(自蒸馏) |
监督信号 | 4 亿对 (image, text) | 纯图像,无任何文本/标签 |
学习目标 | 让"和文本描述匹配的图"在向量空间里靠近 | 让"同一张图的不同视角"在向量空间里靠近 |
表征性质 | 语义级、跨模态对齐 | 视觉级、单模态自洽 |
天然擅长 | 文本搜图、零样本分类、跨模态检索 | 图搜图、实例检索、密集预测(分割/深度) |
CLIP学的是"图配什么文字"。 它的向量空间是按"语义相似"对齐的——两张语义相近但视觉差很多的图(比如一只哈士奇和一只阿拉斯加),在CLIP空间里会很近,因为它们都被描述成"a dog in the snow"。反过来,两张视觉相近但语义可被不同描述的图(比如同一只哈士奇的两个不同角度),未必近,因为对应的"文本中心"不一样。
DINO 学的是"图自己长什么样"。 它根本不知道"哈士奇"这个词,但它知道同一只哈士奇换个角度、换个光照、裁一块出来,应该是同一个东西。它的向量空间是按"视觉相似"对齐的。
所以选型不是"哪个更强",是"哪个更对",CLIP是文搜图的标杆,DINO是图搜图的标杆。
用户给一段文字,找匹配的图/帧 → 选CLIP。
用户给一张图/一帧画面,找视觉上相似的图/帧 → 选DINO。
六、一些认知和思考
Yann LeCun 用一张图表达了他对不同学习范式的看法:强化学习是蛋糕上的樱桃,监督学习是糖霜,自监督学习才是真正的蛋糕。
核心差异在于信息量:
强化学习(樱桃):模型偶尔收到一个标量奖励。反馈信号稀疏,信息量极小。
监督学习(糖霜):模型预测人类提供的标签。每张图对应一个或多个类别,信息量在 10~10000 bits 之间。
自监督学习(蛋糕):模型预测输入本身的任意部分。每一张图都包含数百万比特的监督信号。
DINO 系列属于“蛋糕”那一层。它不依赖标签、不依赖文本,只靠图像本身——预测缺失的 Patch、匹配不同视角——来提供学习信号。正因为监督信号足够丰富,模型才能在没有任何人工标注的情况下,从像素中自然涌现出物体边缘、语义分割等中层视觉理解能力。
这张图也解释了为什么自监督学习近年来能快速追赶甚至超越监督学习:不是模型变聪明了,而是我们终于让它用上了输入数据里所有的信息。
