5个最流行的图像嵌入模型对比

news2024/10/22 13:07:52

最近需要研究图像相似性搜索。我想知道基于架构训练方法的嵌入之间是否存在差异。但是,很少有博客比较几种模型之间的嵌入。因此,在这篇博客中,我将使用 Flickr 数据集 [6] 比较 EfficientNet [1]、ViT [2]、DINO-v2 [3]、CLIP [4] 和 BLIP-2 [5] 的视觉嵌入进行图像相似性搜索。我将主要使用 Huggingface 和 Faiss 库进行实现。首先,我将简要介绍每个深度学习模型。接下来,我将向您展示代码实现和比较结果。

NSDT工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 - AI模型在线查看 - Three.js虚拟轴心开发包 - 3D模型在线减面 - STL模型在线切割 - 3D道路快速建模 

1、简介

在本节中,我将介绍几个用于实验的深度学习模型。请注意,我将使用具有相同含义的词,例如嵌入和特征。我只是为了符合论文的描述而使用它们。让我们深入研究它们吧!

1.1 EfficientNet

EfficientNet [1] 是一种卷积神经网络,专注于在保持计算效率的同时实现准确性。它被归类为监督学习。作者彻底研究了通道数(宽度)、总层数(深度)和输入分辨率,以解决模型大小、准确性和计算效率之间的权衡。与已经推出的计算机视觉模型(例如 ResNet)相比,它在 2019 年取得了最先进的成果。

论文 [1] 改编的 EfficientNet 架构插图

根据模型大小,有几种变体,分别表示为 B0 到 B7,如下所示。模型尺寸越大,准确率越高。

EfficientNet 信息表

如您所见,它们对 ImageNet 的准确率不错,但与最近的大型基础模型相比,模型尺寸非常紧凑。在这篇博客中,我将使用 EfficientNet-B7 进行实验。将要提取的嵌入是最后一个隐藏状态的输出,因为较深的层比浅层具有更多的语义信息。

1.2 Vision Transformer (ViT)

Vision Transformer [2] 是第一篇成功将 Transformer 架构改编到计算机视觉领域的论文,由 Google 开发。它也被归类为监督学习。它将输入图像分成几个补丁并将它们输入到 Transformer 编码器中。这些补丁相当于自然语言处理设置中的标记。对于分类任务,ViT 引入了一个名为 class-token 的 token,它在最后一个注意力层的输出中包含整个图像表示。架构图如下所示。

论文 [2] 中采用的架构说明

与 NLP Transformer 类似,它需要使用大型数据集进行预训练,并针对下游任务进行微调。与 CNN 相比,它的一个优点是,由于自注意力,它可以利用图像的全部信息。与 EfficientNet 一样,模型尺寸越大,能力就越强。

ViT 信息表

如您所见,较大的模型比 EfficientNet 更准确。在本博客中,我将使用 ViT-Large。将要提取的嵌入是类标记的输出,因为它具有整个图像语义信息。

1.3 DINO-v2

DINO-v2 [3] 是由 Meta 开发的用于生成计算机视觉中通用视觉特征的基础模型。作者将自监督方法应用于 ViT 架构,以了解图像和像素级别的图像特征;因此,DINO-v2 可以执行任何计算机视觉任务,例如分类或分割。在架构方面,DINO-v2 基于前身 DINO,即“无标签知识蒸馏”的缩写,如下所示。

论文 [3] 改编的 DINO-v2 架构

DINO 有两个网络:学生网络和教师网络。它采用共蒸馏,学生网络和教师网络具有相同的架构,并且在两个方向(教师到学生和学生到教师)的训练过程中都应用蒸馏。请注意,学生到教师的蒸馏使用学生网络输出的平均值。

对于 DINO-v2,作者更新了训练方法,增加了一些损失和正则化。此外,他们还策划了一个高质量的数据集,以获得更高质量的图像特征。

在实验中,我们将使用类标记的输出,因为它们具有完整的图像语义信息,例如 ViT。

1.4 CLIP

CLIP 是 OpenAI [4] 开发的改变游戏规则的多模态模型之一。它被归类为弱监督学习,基于 Transformer 架构。得益于其独特的架构,它能够进行零样本图像分类。架构如下所示。

本文改编的 CLIP 架构图 [4]

CLIP 架构包含文本和图像编码器。它通过对比损失对齐文本和图像特征并获得多模态能力。因此,它在文本和图像特征之间共享相同的特征空间,并且可以通过查找最相似的文本特征来实现零样本图像分类,如上图“(3) 用于零样本预测”。

CLIP 编码器基于 Transformer。因此,我们将在图像编码器中使用类标记的输出,同样 ViT 也是如此。

1.5 BLIP-2

BLIP-2 [5] 是 SalesForce 于 2023 年开发的开源多模态模型。它被归类为监督学习,基于 Transformer 架构。它专注于利用预训练的大型模型(例如 FlanT5 和 CLIP)来实现高效的训练(因为在典型的预算下从头开始训练大型模型很困难)。由于预训练的大型语言和视觉模型的训练方式不同,作者引入了 Q-Former 来对齐预训练模型之间的特征空间。

论文 [5] 改编的 BLIP2 架构插图

BLIP-2 包括两个阶段。第一阶段训练 Q-Former 以对齐来自预训练图像编码器的文本特征和图像特征,使用多种损失,例如图像-文本匹配、图像-文本对比损失和图像接地文本生成。第二阶段再次训练 Q-Former 以将其特征空间与大型语言模型(例如 FlanT5)对齐。因此,Q-Former 可以理解来自文本和图像源的特征。

顾名思义,Q-Former 架构基于 Transformer。我们将使用 Q-Former 的输出作为特征提取层。

2、比较

在本节中,我们将比较 EfficientNet、ViT、DINO-v2、CLIP 和 BLIP-2 的图像相似性搜索结果。这些模型具有不同的架构和训练损失。这会有什么不同?让我们从设置环境开始。

2.1 环境设置

我使用了带有 Python 3.10 的 conda 环境。我在 Ubuntu 20.04 上使用 cuda 11.0、16 GB GPU 和 16 GB RAM 进行了实验。

conda create -n transformers-env python=3.10 -y
conda activate transformers-env

接下来,我们需要通过 conda 和 pip 安装下面的库。

conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia
conda install -c pytorch faiss-cpu=1.8.0
conda install -c conda-forge pandas
pip install transformers

准备工作都完成了!现在,让我们实现代码。我们将使用 Faiss 库 [7] 来测量图像相似性以进行图像相似性搜索。Faiss 是一个基于近似最近邻搜索算法的高效相似性搜索库。此外,我们将使用 Flickr30k 数据集 [6] 进行实验。在直接深入研究图像相似性搜索之前,我们将探索如何从每个模型中提取嵌入(特征)。

2.2 提取特征

在这个实验中,我将使用 Huggingface transformer 库来提取嵌入。与简单的 Pytorch 实现相比,我们可以轻松提取隐藏状态。这一段代码检查了输入和输出的维度,所以我们会在CPU上运行它们。

  • EfficientNet

EfficientNet的特征提取的提取代码如下所示。

import torch
from transformers import AutoImageProcessor, EfficientNetModel

# load pre-trained image processor for efficientnet-b7 and model weight
image_processor = AutoImageProcessor.from_pretrained("google/efficientnet-b7")
model = EfficientNetModel.from_pretrained("google/efficientnet-b7")

# prepare input image
inputs = image_processor(test_image, return_tensors='pt')
print('input shape: ', inputs['pixel_values'].shape)

with torch.no_grad():
    outputs = model(**inputs, output_hidden_states=True)
    
embedding = outputs.hidden_states[-1]

print('embedding shape: ', embedding.shape)

embedding = torch.mean(embedding, dim=[2,3])
print('after reducing: ', embedding.shape)

### input shape:  torch.Size([1, 3, 600, 600])
### embedding shape:  torch.Size([1, 640, 19, 19])
### after reducing by taking mean:  torch.Size([1, 640])

首先,我们需要准备一个输入。预定义的 EfficientNet 图像处理器会自动将输入形状处理为 (batch_size, 3, 600, 600)。经过模型处理后,我们可以得到一个带有隐藏状态的输出。最后一个隐藏状态的维度为 (batch_size, 640, 19, 19),因此我们将降均值过程应用于获得的嵌入。

  • ViT

对于 ViT 的特征提取,提取代码如下所示。

# load pre-trained image processor for ViT-large and model weight
image_processor = AutoImageProcessor.from_pretrained("google/vit-large-patch16-224-in21k")
model = ViTModel.from_pretrained("google/vit-large-patch16-224-in21k")

# prepare input image
inputs = image_processor(test_image, return_tensors='pt')
print('input shape: ', inputs['pixel_values'].shape)

with torch.no_grad():
    outputs = model(**inputs)
    
embedding = outputs.last_hidden_state
embedding = embedding[:, 0, :].squeeze(1)
print('embedding shape: ', embedding.shape)

### input shape:  torch.Size([1, 3, 224, 224])
### embedding shape:  torch.Size([1, 1024])

同样,预定义的 ViT 图像处理器会自动将输入形状处理为 (batch_size, 3, 224, 224)。最后一个隐藏状态有 (batch_size, 197, 1024) 个维度,我们只需要类标记,因此提取第二个维度 (197) 的第一个索引。

  • DINO-v2

DINO-v2 基于 ViT,因此基本代码几乎相同。不同之处在于我们为 DINO-v2 加载图像处理器和模型。提取代码如下所示。

# load pre-trained image processor for DINO-v2 and model weight
image_processor = AutoImageProcessor.from_pretrained('facebook/dinov2-base')
model = AutoModel.from_pretrained('facebook/dinov2-base')

# prepare input image
inputs = image_processor(images=test_image, return_tensors='pt')
print('input shape: ', inputs['pixel_values'].shape)

with torch.no_grad():
    outputs = model(**inputs)
    
embedding = outputs.last_hidden_state
embedding = embedding[:, 0, :].squeeze(1)
print('embedding shape: ', embedding.shape)

### input shape:  torch.Size([1, 3, 224, 224])
### embedding shape:  torch.Size([1, 1024])

基本上,我们使用相同的图像处理器。预定义的 ViT 图像处理器会自动将输入形状处理为 (batch_size, 3, 224, 224)。最后一个隐藏状态有 (batch_size, 197, 1024) 个维度,我们只需要类标记,因此提取第二个维度 (197) 的第一个索引。

  • CLIP

CLIP 也是基于 ViT 的,因此流程相同。 huggingface transformers 库已经有 CLIP 的特征提取方法,因此实现更直接。

# load pre-trained image processor for CLIP and model weight
image_processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")

# prepare input image
inputs = image_processor(images=test_image, return_tensors='pt', padding=True)
print('input shape: ', inputs['pixel_values'].shape)

with torch.no_grad():
    outputs = model.get_image_features(**inputs)
    
print('embedding shape: ', outputs.shape)

### input shape:  torch.Size([1, 3, 224, 224])
### embedding shape:  torch.Size([1, 512])

我们使用相同的图像处理器。预定义的 ViT 图像处理器会自动将输入形状处理为 (batch_size, 3, 224, 224)。get_image_features 方法可以提取给定图像的嵌入,输出维度为 (batch_size, 512)。它与 ViT 和 DINO-v2 不同。

  • BLIP-2

我们可以从 ViT 和 Q-Former 输出中提取图像嵌入。在这种情况下,Q-Former 输出可以包含来自图像和文本视角的语义,因此我们将使用它。

processor = Blip2Processor.from_pretrained("Salesforce/blip2-opt-2.7b")
model = Blip2Model.from_pretrained("Salesforce/blip2-opt-2.7b", torch_dtype=torch.float16)

# prepare input image
inputs = processor(images=test_image, return_tensors='pt', padding=True)
print('input shape: ', inputs['pixel_values'].shape)

with torch.no_grad():
    outputs = model.get_qformer_features(**inputs)
    
print('embedding shape: ', outputs.shape)

我们使用可以处理图像和文本输入的 BLIP-2 处理器。它会自动将图像输入形状处理为 (batch_size, 3, 224, 224)。我们可以使用 get_qformer_features 提取 Q-Former 输出,输出维度为 (batch_size, 32, 768)。我们通过取平均值来减少输出,嵌入维度将为 (batch_size, 768)。

现在我们了解了如何从每个模型中提取嵌入。接下来,让我们检查使用 Faiss 实现的图像相似性搜索。

2.3 图像相似性搜索

我们只需几行代码即可使用 Faiss 接口轻松实现图像相似性搜索。我们假设有一个名为 features 的变量。过程如下。

  • 将输入特征类型转换为 numpy.float32。
  • 实例化 Faiss 向量存储并为其注册输入特征。
  • 通过调用方法搜索来搜索向量。

我们可以选择如何测量向量之间的距离,例如欧几里得距离或余弦相似度。在本博客中,我们使用余弦相似度。伪代码可以写成如下。

# convert features type to np.float32
features = features.astype(np.float32)

# get embedding dimension
vector_dim = features.shape[1]     
        
# register embedding to faiss vector store
index = faiss.IndexFlatIP(vector_dim)
faiss.normalize_L2(features)
index.add(features)

# For vector search, we just call search method. 
top_k = 5  
faiss.normalize_L2(embed)
distances, ann = index.search(embed, k=top_k)

现在,比较图像相似性搜索结果的所有先决条件都已完成。让我们从下一节开始查看具体结果。

2.4 图像相似性搜索结果比较

在本节中,我将使用五个模型比较图像相似性搜索结果。对于数据集,我使用从 Flickr30k 随机挑选的 10k 图像。我为每个模型实现了一个自定义管道,以实现批量特征提取。在本节后面,我将附上我用于此实验的笔记本。我选择了下面的图像来比较结果。

从 Flickr30k 数据集中选取的图像

“3637013.jpg”的结果如下所示。

对“3637013.jpg”进行的图像相似性搜索

此案例相对其他图像而言比较简单,因此所有模型都可以拾取具有相似语义的图像。

“3662865.jpg”的结果如下所示。

“3662865.jpg”进行的图像相似性搜索

在这种情况下,DINO-v2 和 CLIP 可以捕获“铲雪”的语义,但其他模型有时只能捕获“雪”。

“440375442.jpg”的结果如下所示。

“440375442.jpg”进行的图像相似性搜索

EfficientNet 和 ViT 可能会将工作服误解为手术服,因此无法捕捉目标图像的语义。DINO-v2 可以理解“垃圾和穿工作服的人”的语义,CLIP 关注穿工作服的人,BLIP2 关注垃圾。我认为 DINO-v2、CLIP 和 BLIP2 可以捕捉语义。

“1377428277.jpg”的结果如下所示。

“1377428277.jpg”进行的图像相似性搜索

此图像的语义为:“街上很多人在享受节日或街头表演。” EfficientNet 和 ViT 专注于雨伞,因此无法捕捉语义。另一方面,DINO 专注于婴儿车,在性能方面落后一步。 CLIP 试图捕捉节日和街道部分,但也落后一步。 BLIP2 可以捕捉街头表演和婴儿车。

“57193495.jpg”的结果如下所示。

“57193495.jpg”进行的图像相似性搜索

在本例中,EfficientNet、ViT 和 CLIP 有时可以捕捉到“女人穿着戏服并粉饰脸部”的语义。但是它们相对不足。相比之下,DINO-v2 和 BLIP2 可以捕捉到着装或戏服的语义。

“1393947190.jpg”的最后一个图像搜索结果如下所示。

“1393947190.jpg”进行的图像相似性搜索

结果不同,分别对应架构、CNN 和 Transformer。虽然 EfficientNet 可能专注于图像的白色和褐色,但其他模型可以捕捉“人正在缫丝”的语义。CLIP 可能专注于传统手工艺,但其他模型可以捕捉语义。

总之,我们有以下观察结果。

  • EfficientNet(CNN 架构)不擅长捕捉像素信息以外的语义。
  • Vision Transformer 比 CNN 更好,但仍然专注于像素信息而不是图像的含义。
  • DINO-v2 可以捕捉图像的语义,并且倾向于关注正面物体。
  • CLIP 可以捕捉语义,但有时可能会受到可以从图像中读取的语言信息的强烈影响。
  • BLIP2 可以捕捉语义,这是其他模型中最优秀的结果。

我认为,为了获得更好的图像相似性搜索结果,我们基本上应该使用 DINO-v2 或 BLIP2。至于使用上的差异,当我们关注图像中的对象时,我们应该使用 DINO-v2。同时,当我们关注像素信息以外的语义时,我们应该使用 BLIP2,就像这种情况。


原文链接:Top 5 图像嵌入模型比较 - BimAnt

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

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

相关文章

Matlab软件进行金融时间序列数据的描述性统计代码

1、数据S&P500的收盘价格,return100*log(pt/pt-1) 方法1:用python代码 import numpy as np import pandas as pddef calculate_log_returns(prices):"""计算价格序列的对数收益率。参数:prices (numpy.array): 价格序列。返回:log_…

Mongodb基础用法【总结】

关系型数据库和非关系型数据库的区别 关系型数据库 1.在关系型数据库中,数据都是存储在表中的,对存储的内容有严格的要求 2.因为我们在创建表的时候久已经规定了表中的字段 存储的数据类型 是否为空 唯一标识等规则 3.由于操作的都是结构化的数据&#…

家政小程序搭建,数字化市场发展下的意义

家政服务行业作为当下社会生活中不可或缺的行业,需求量在逐渐增加,行业发展也趋向多样化。 随着数字化的浪潮,家政行业逐渐向数字化、智能化升级发展,推动行业高质量发展,迎合现代化发展趋势,这一转型为行…

83.【C语言】数据结构之顺序表的尾部插入和删除

目录 3.操作顺序表 2."伪"插入顺序表的元素 分析尾部插入函数SLPushBack 代码示例 SeqList.h main.c free(指针)出错的几种可能的原因 3."伪"删除顺序表元素 2.分析尾部删除函数SLPopBack 代码示例 错误检查 两种解决办法 1.判断size是否为负…

004-按照指定功能模块名称分组

按照指定功能模块名称分组 一、说明1.现在有一个需求:2.具体做法 二、代码案例三、效果展示 一、说明 1.现在有一个需求: 需要把一个功能模块的几个功能点放在同一个文档目录下,这几个功能点分布在不同的 Controller 2.具体做法 需要把他…

如何将markdown文件转换为pdf

最近笔者在用vscode写markdown,但是提交时往往需要交pdf。所以就涉及到如何将markdown转化为pdf格式。 首先,需要在vscode上安装插件 markdown Preview Enhanced 之后在vscode的右上角即可看到下述图标,点击,vscode右半面就会显示…

C++数据结构-图的存储及邻接矩阵的代码实现

1. 什么是图 图论(graph theory) 是数学的一个分支,它以 图 为研究的对象。 图论本身是应用数学的一部分,历史上图论曾经被很多数学家各自独立建立过。关于图论的最早文字记载最早出现在欧拉 1736 年的论著中,也就是…

2024年有哪些开放式耳机值得入手?开放式耳机排行榜10强

随着技术的不断进步与消费者需求的日益多样化,开放式耳机凭借其独特的优势——如保持对周围环境的感知、减少对耳道的压力等,逐渐成为市场上的一大热点。尤其是在健康意识不断提升的今天,开放式耳机不仅为音乐爱好者提供了全新的聆听体验&…

【C++语言】全面掌握const的用法

一、const 需要怎么理解?? const修饰的变量不能够再作为左值,初始化完成之后,值不能被修改 1.1 C语言的const const 修饰的量,可以不用初始化,不叫常量,叫做常变量。 void main() {const int…

Windows git 配置

需要在git-bash的目录下,配置.ssh 的配置文件 要 .ssh 目录下的配置无法使用

Modbus TCP报错:Response length is only 0 bytes

问题描述: 使用modbus_tk库,通过Modbus tcp连接PLC时,python中的一个报错信息: Response length is only 0 bytes报错原因: 与Modbus TCP 服务端建立连接后没有断开,继续作为长连接使用,客户端…

一文掌握Cephadm部署Ceph存储集群

📚 博客主页: StevenZeng学堂 🎉 本文专栏: 一文读懂Kubernetes一文读懂Harbor云原生安全实战指南云原生存储实践指南 ❤️ 摘要:随着企业数据量的增长和存储需求的复杂化,Ceph因其高可扩展性和灵活性,能…

AI劳动力崛起:人将面临失业危机?

场景 第一眼看到这个网站的时候,AI员工官网(好像是部署在美国),我觉得很好奇,真的可以让AI替代人类完成工作吗?替代到什么程度呢?能以自然语言直接驱动吗? 正好手上在做爬虫项目&am…

HCIP-HarmonyOS Application Developer 习题(十六)

(判断)1、HiLink通过分布式软总线的方式连接所有设备,强能力设备可对弱能力设备进行设备虚拟化,将弱设备当做本机设备直接调用。 答案:错误 分析:HiLink 主要针对的是应用开发者与第三方设备开发者&#xf…

医院排队叫号系统

医院分诊排队叫号系统是一种广泛应用于服务行业的智能化管理系统,系统可有效地解决病人就诊时排队的无序、医生工作量的不平衡、就诊环境嘈杂等问题,它主要用于改善服务流程,提高服务效率,优化客户体验。这种系统通常包括以下几个…

HarmonyOS Next应用开发——多种方式实现图片解码

【高心星出品】 图片解码 图片处理就是将设备中保存的图片进行编辑处理然后再存储下来,整个过程需要先图片解码,图片处理,最后在图片编码保存。 图片解码指将所支持格式的存档图片解码成统一的PixelMap,以便在应用或系统中进行…

【贝加莱PLC基础教学】2.1 搜索并连接到对应的PLC(1)

【贝加莱PLC基础教学】目录大全_贝加莱plc p23 1361-CSDN博客 PLC其实和单片机差别不大,无非就是大一点的单片机。另外多加了一点点计算机网络和通讯知识,然而就是这一点点计算机网络知识让大家望而却步。 0.基础知识 在计算机网络中,我们通…

Notepad++通过自定义语言实现日志按照不同级别高亮

借助Notepad的自定义语言可以实现日志的按照不同级别的高亮&#xff1b; 参考&#xff1a; https://blog.csdn.net/commshare/article/details/131208656 在此基础上做了一点修改效果如下&#xff1a; xml文件&#xff1a; <NotepadPlus><UserLang name"Ansibl…

深度学习--CNN实现猫狗识别二分类(附带下载链接, 长期有效)

1. 代码实现(包含流程解释) 样本量: 8005 # # 1.导入数据集(加载图片)数据预处理# 进行图像增强, 通过对图像的旋转 ,缩放,剪切变换, 翻转, 平移等一系列操作来生成新样本, 进而增加样本容量, # 同时对图片数值进行归一化[0:1] from tensorflow.keras.preprocessing.image …

Altair官方教程——HyperMesh视觉控制

在HyperMesh中&#xff0c;模型视角控制可通过标准视图&#xff08;Standard Views&#xff09;工具栏、三维视图控制&#xff08;3D View Controls&#xff09;工具栏以及鼠标实现。 (1) 标准视图工具栏图标。 (2) 鼠标控制- 显示控制的推荐操作方法是使用鼠标。配合键盘上的 …