基于CLIP和DINOv2实现图像相似性方面的比较

概述

在人工智能领域,CLIP和DINOv2是计算机视觉领域的两大巨头。CLIP彻底改变了图像理解,而DINOv2为自监督学习带来了新的方法。

在本文中,我们将踏上一段旅程,揭示定义CLIP和DINOv2的优势和微妙之处。我们的目标是发现这些模型中哪一个在图像相似性任务的世界中真正表现出色。让我们见证巨头的碰撞,看看哪个模型会脱颖而出。

1 使用CLIP计算图像相似性

使用CLIP计算两张图像之间的相似性是一个简单的过程,只需两步:首先,提取两张图像的特征,然后计算它们的余弦相似度。

首先,确保安装了必要的软件包。建议设置并使用虚拟环境:

# 首先设置虚拟环境
virtualenv venv-similarity
source venv-similarity/bin/activate
# 安装所需软件包
pip install transformers Pillow torch

接下来,计算图像相似性:

import torch
from PIL import Image
from transformers import AutoProcessor, CLIPModel
import torch.nn as nndevice = torch.device('cuda' if torch.cuda.is_available() else "cpu")
processor = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32")
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32").to(device)# 从image1中提取特征
image1 = Image.open('img1.jpg')
with torch.no_grad():inputs1 = processor(images=image1, return_tensors="pt").to(device)image_features1 = model.get_image_features(**inputs1)# 从image2中提取特征
image2 = Image.open('img2.jpg')
with torch.no_grad():inputs2 = processor(images=image2, return_tensors="pt").to(device)image_features2 = model.get_image_features(**inputs2)# 计算它们的余弦相似度并将其转换为0到1之间的分数
cos = nn.CosineSimilarity(dim=0)
sim = cos(image_features1[0],image_features2[0]).item()
sim = (sim + 1) / 2
print('Similarity:', sim)

使用提供的两张相似图像的示例,获得的相似度分数令人印象深刻,达到了96.4%。

2 使用DINOv2计算图像相似性

使用DINOv2计算两张图像之间的相似性过程与CLIP类似。用DINOv2需要与前面提到的相同的软件包集,无需额外安装:

from transformers import AutoImageProcessor, AutoModel
from PIL import Image
import torch.nn as nndevice = torch.device('cuda' if torch.cuda.is_available() else "cpu")
processor = AutoImageProcessor.from_pretrained('facebook/dinov2-base')
model = AutoModel.from_pretrained('facebook/dinov2-base').to(device)image1 = Image.open('img1.jpg')
with torch.no_grad():inputs1 = processor(images=image1, return_tensors="pt").to(device)outputs1 = model(**inputs1)image_features1 = outputs1.last_hidden_stateimage_features1 = image_features1.mean(dim=1)image2 = Image.open('img2.jpg')
with torch.no_grad():inputs2 = processor(images=image2, return_tensors="pt").to(device)outputs2 = model(**inputs2)image_features2 = outputs2.last_hidden_stateimage_features2 = image_features2.mean(dim=1)cos = nn.CosineSimilarity(dim=0)
sim = cos(image_features1[0],image_features2[0]).item()
sim = (sim + 1) / 2
print('Similarity:', sim)

使用与CLIP示例中相同的一对图像,DINOv2获得的相似度分数为96.4%:
在这里插入图片描述

3. 使用COCO数据集进行测试

在深入评估它们的性能之前,使用COCO数据集中的图像比较CLIP和DINOv2产生的结果。

实现流程:

  1. 遍历数据集以提取所有图像的特征。
  2. 将嵌入存储在FAISS索引中。
  3. 提取输入图像的特征。
  4. 检索最相似的三张图像。

3.1 特征提取和创建

import torch
from PIL import Image
from transformers import AutoProcessor, CLIPModel, AutoImageProcessor, AutoModel
import faiss
import os
import numpy as npdevice = torch.device('cuda' if torch.cuda.is_available() else "cpu")# 加载CLIP模型和处理器
processor_clip = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32")
model_clip = CLIPModel.from_pretrained("openai/clip-vit-base-patch32").to(device)# 加载DINOv2模型和处理器
processor_dino = AutoImageProcessor.from_pretrained('facebook/dinov2-base')
model_dino = AutoModel.from_pretrained('facebook/dinov2-base').to(device)# 获取所有文件名
images = []
for root, dirs, files in os.walk('./val2017/'):for file in files:if file.endswith('jpg'):images.append(root + '/' + file)# 定义一个函数,用于归一化嵌入并将其添加到索引中
def add_vector_to_index(embedding, index):# 将嵌入转换为numpy数组vector = embedding.detach().cpu().numpy()# 转换为float32 numpy数组vector = np.float32(vector)# 归一化向量:在搜索时避免错误结果很重要faiss.normalize_L2(vector)# 添加到索引中index.add(vector)def extract_features_clip(image):with torch.no_grad():inputs = processor_clip(images=image, return_tensors="pt").to(device)image_features = model_clip.get_image_features(**inputs)return image_featuresdef extract_features_dino(image):with torch.no_grad():inputs = processor_dino(images=image, return_tensors="pt").to(device)outputs = model_dino(**inputs)image_features = outputs.last_hidden_statereturn image_features.mean(dim=1)# 创建两个索引
index_clip = faiss.IndexFlatL2(512)
index_dino = faiss.IndexFlatL2(768)# 遍历数据集以提取特征X2并将特征存储在索引中
for image_path in images:img = Image.open(image_path).convert('RGB')clip_features = extract_features_clip(img)add_vector_to_index(clip_features, index_clip)dino_features = extract_features_dino(img)add_vector_to_index(dino_features, index_dino)# 将索引本地存储
faiss.write_index(index_clip, "clip.index")
faiss.write_index(index_dino, "dino.index")

3.2 图像相似性搜索

import faiss
import numpy as np
import torch
from transformers import AutoImageProcessor, AutoModel, AutoProcessor, CLIPModel
from PIL import Image
import os# 输入图像
source = 'laptop.jpg'
image = Image.open(source)
device = torch.device('cuda' if torch.cuda.is_available() else "cpu")# 加载DINOv2和CLIP的模型和处理器
processor_clip = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32")
model_clip = CLIPModel.from_pretrained("openai/clip-vit-base-patch32").to(device)
processor_dino = AutoImageProcessor.from_pretrained('facebook/dinov2-base')
model_dino = AutoModel.from_pretrained('facebook/dinov2-base').to(device)# 为CLIP提取特征
with torch.no_grad():inputs_clip = processor_clip(images=image, return_tensors="pt").to(device)image_features_clip = model_clip.get_image_features(**inputs_clip)# 为DINOv2提取特征
with torch.no_grad():inputs_dino = processor_dino(images=image, return_tensors="pt").to(device)outputs_dino = model_dino(**inputs_dino)image_features_dino = outputs_dino.last_hidden_stateimage_features_dino = image_features_dino.mean(dim=1)def normalizeL2(embeddings):vector = embeddings.detach().cpu().numpy()vector = np.float32(vector)faiss.normalize_L2(vector)return vectorimage_features_dino = normalizeL2(image_features_dino)
image_features_clip = normalizeL2(image_features_clip)# 搜索最相似的5张图像
index_clip = faiss.read_index("clip.index")
index_dino = faiss.read_index("dino.index")# 获取图像的距离和相关索引
d_dino, i_dino = index_dino.search(image_features_dino, 5)
d_clip, i_clip = index_clip.search(image_features_clip, 5)

结果

使用四张不同的图像作为输入,搜索产生了以下结果:
在这里插入图片描述

4. 在DISC21数据集上进行基准测试

为了比较它们的性能,我们将遵循这篇文章中描述的相同方法。我们还将重用上面的脚本提取特征,然后计算图像相似性。

4.1 数据集

为了对CLIP和DINOv2进行基准测试,我们选择了DISC21数据集,该数据集是专门为图像相似性搜索创建的。由于其大小为350GB,我们将使用其中150,000张图像的子集。

4.2 使用的指标

在指标方面,我们将计算:

  • 准确率:正确预测的图像与图像总数的比率。
  • 前3准确率:在前三张最相似图像中找到正确图像的次数与图像总数的比率。
  • 计算时间:处理整个数据集所需的时间。

4.3 基准测试结果

  • 特征提取

    • CLIP:每秒70.7张图像
    • DINOv2:每秒69.7张图像
  • 准确率和前3准确率
    在这里插入图片描述

  • 检查结果

    • 两个模型都正确预测图像
      在这里插入图片描述
    • 所有模型都未找到正确图像
      在这里插入图片描述
    • 只有CLIP预测正确图像,DINOv2在其前3中预测到
      在这里插入图片描述
    • 只有DINOv2预测正确图像

    在这里插入图片描述

5. 分析

DINOv2显然是领先者,在极具挑战性的数据集上实现了令人印象深刻的64%的准确率。相比之下,CLIP的准确率较为适中,达到28.45%。

关于计算效率,两个模型的特征提取时间非常相似。这种相似性使得在这方面没有一个模型具有明显优势。

5.1 局限性

虽然这个基准测试提供了有价值的见解,但认识到其局限性很重要。评估是在1448张图像的子集上进行的,而与之对比的是150,000张图像的池。考虑到整个数据集有210万张图像,这种缩小的范围是为了节省资源。

值得注意的是,MetaAI使用DISC21数据集作为其模型的基准,这可能使DINOv2具有有利优势。然而,我们在COCO数据集上的测试揭示了有趣的细微差别:DINOv2显示出更强的识别图像主要元素的能力,而CLIP则擅长关注输入图像中的特定细节(如公交车图像所示)。

最后,必须考虑CLIP和DINOv2之间嵌入维度的差异。CLIP使用的嵌入维度为512,而DINOv2使用的是768。虽然可以选择使用具有匹配嵌入维度的更大的CLIP模型,但值得注意的是,这是以速度为代价的。在一个小子集上的快速测试显示性能略有提升,但没有达到DINOv2所展示的水平。

5.2 结论

DINOv2在图像相似性任务中表现出更高的准确率,展示了其在实际应用中的潜力。CLIP虽然值得称赞,但相比之下有所不足。值得注意的是,CLIP在需要关注小细节的场景中可能特别有用。两个模型的计算效率相似,因此选择取决于具体任务。

原文地址:https://medium.com/aimonks/clip-vs-dinov2-in-image-similarity-6fa5aa7ed8c6

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/891927.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LS1046 XFI网口接近10Gbps

硬件平台: CPU LS1046A 1.8GHZ 软件平台: LINUX 4.19.32 BUILDROOT 测试软件: ipferf 整个过程比较曲折,网口默认不能达到这个速度,只有2Gbps以内。需要FMC配置后才能达到9.4Gbps。

一则问答:211集成电路专业,转互联网还是FPGA?

问: 我于2016年毕业于西安电子科技大学集成电路设计与集成系统专业。毕业后,我在一家不知名私企从事PCB绘制和单片机调试工作,持续了一年半。之后,我受律师职业光鲜外表的吸引,尝试了两年的司法考试,但未能…

嵌入式linux系统中QT信号与槽实现

第一:Qt中信号与槽简介 信号与槽是Qt编程的基础。因为有了信号与槽的编程机制,在Qt中处理界面各个组件的交互操作时变得更加直观和简单。 槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。 案例操作与实现: #ifndef …

Java Web开发进阶——Spring Boot基础

Spring Boot是基于Spring框架的新一代开发框架,旨在通过自动化配置和简化的开发方式提升生产效率。它将复杂的配置抽象化,让开发者专注于业务逻辑实现,而无需关注繁琐的基础配置。 1. Spring Boot简介与优势 Spring Boot 是 Spring 家族中的…

探索 ES6 Set:用法与实战

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

使用SSH建立内网穿透,能够访问内网的web服务器

搞了一个晚上,终于建立了一个内网穿透。和AI配合,还是得自己思考,AI配合才能搞定,不思考只依赖AI也不行。内网服务器只是简单地使用了python -m http.server 8899,但是对于Gradio建立的服务器好像不行,会出…

回归预测 | MATLAB实现CNN-BiLSTM-Attention多输入单输出回归预测

回归预测 | MATLAB实现CNN-BiLSTM-Attention多输入单输出回归预测 目录 回归预测 | MATLAB实现CNN-BiLSTM-Attention多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 一、方法概述 CNN-BiLSTM-Attention多输入单输出回归预测方法旨在通过融合CNN的局…

动态库dll与静态库lib编程4:MFC规则DLL讲解

文章目录 前言一、说明二、具体实现2.1新建项目2.2 模块切换的演示 总结 前言 动态库dll与静态库lib编程4:MFC规则DLL讲解。 一、说明 1.前面介绍的均为Win32DLL,即不使用MFC的DLL。 2.MFC规则DLL的特点:DLL内部可以使用MFC类库、可以被其他…

【JVM】总结篇-类的加载篇之 类的加载器 和ClassLoader分析

文章目录 类的加载器ClassLoader自定义类加载器双亲委派机制概念源码分析优势劣势如何打破Tomcat 沙箱安全机制JDK9 双亲委派机制变化 类的加载器 获得当前类的ClassLoader clazz.getClassLoader() 获得当前线程上下文的ClassLoader Thread.currentThread().getContextClassLoa…

数据挖掘——回归算法

数据挖掘——回归算法 回归算法线性回归最小二乘法优化求解——梯度下降法逻辑回归逻辑回归函数逻辑回归参数估计逻辑回归正则化 决策树回归小结 回归算法 回归分析 如果把其中的一些因素(房屋面积)作为自变量,而另一些随自变量的变化而变化…

前端如何从入门进阶到高级

在前端学习的道路上,我们将其划分为三个阶段:入门、实战和进阶。以下是各阶段的学习指南 一、入门阶段 在入门阶段,我们的目标是掌握前端的基本语法和知识,以便能够独立解决一些基础问题。这一阶段,我们建议通过视频…

Android14 CTS-R6和GTS-12-R2不能同时测试的解决方法

背景 Android14 CTS r6和GTS 12-r1之后,tf-console默认会带起OLC Server,看起来olc server可能是想适配ATS(android-test-station),一种网页版可视化、可配置的跑XTS的方式。这种网页版ATS对测试人员是比较友好的,网页上简单配置下…

Linux中的tcpdump抓包命令详解:抓取TCP和UDP数据包并按小时输出文件

Linux中的tcpdump抓包命令详解:抓取TCP和UDP数据包并按小时输出文件 一、tcpdump简介二、安装tcpdump三、抓取TCP和UDP数据包四、按小时输出文件五、tcpdump命令的常用选项和表达式六、总结在Linux系统中,tcpdump是一款强大的网络抓包工具,它基于libpcap库开发,可以捕获网络…

k8s基础(4)—Kubernetes-Service

Service概述 抽象层 ‌k8s的Service是一种抽象层,用于为一组具有相同功能的Pod提供一个统一的入口地址,并通过负载均衡将网络流量分发到这些Pod上。‌ Service解决了Pod动态变化的问题,例如Pod的IP地址和端口可能会发生变化,通过…

国内Ubuntu环境Docker部署CosyVoice

国内Ubuntu环境Docker部署CosyVoice 本文旨在记录在 国内 CosyVoice项目在 Ubuntu 环境下如何使用 dockermin-conda进行一键部署。 源项目地址: https://github.com/FunAudioLLM/CosyVoice 如果想要使用 dockerpython 进行部署,可以参考我另一篇博客中的…

基于 gitlab-runner 实现调度GPU的资源

本篇目录 1. 客户需求2. 需求调研3. 实践3.1 方案一:环境变量的方式3.2 方案二:k8s 自身的spec注入机制 4. 效果 该实践来自于客户的一个真实需求 1. 客户需求 客户的某些流水线需要使用GPU资源,但是对于GPU服务器而言,会有多张G…

计算机网络 —— 网络编程(TCP)

计算机网络 —— 网络编程(TCP) TCP和UDP的区别TCP (Transmission Control Protocol)UDP (User Datagram Protocol) 前期准备listen (服务端)函数原型返回值使用示例注意事项 accpect (服务端)函数原型返回…

模型 九屏幕分析法

系列文章 分享 模型,了解更多👉 模型_思维模型目录。九屏幕法:全方位分析问题的系统工具。 1 九屏幕分析法的应用 1.1 新产品研发的市场分析 一家科技公司计划开发一款新型智能手机,为了全面评估市场潜力和风险,他们…

Unity2D初级背包设计中篇 MVC分层撰写(万字详解)

本人能力有限,如有不足还请斧正,理论分析链接如下: Unity2D初级背包设计前篇 理论分析-CSDN博客 目录 1.M层:数据存储 物品 仓库容器 加载方式 2.M层:逻辑撰写 InventoryManager 仓库的管理 SlotData 物品的增…

深入理解 Linux 管道:创建与应用详解(匿名管道进程池)

在现代操作系统中,进程间通信(IPC)是实现多任务、多进程协作的关键技术之一。Linux 提供了多种 IPC 机制,本博客将帮助您详细的理解进程间通信的原理 首先,在学习管道之前,我们先理解一下管道的存在是为了什…