【计算机视觉】如何利用 CLIP 做简单的图像分类任务?(含源代码)

news2024/11/30 0:28:06

要使用 CLIP 模型进行预测,您可以按照以下步骤进行操作:

一、安装

安装依赖:首先,您需要安装相应的依赖项。您可以使用 Python 包管理器(如 pip )安装 OpenAICLIP 库。

pip install git+https://github.com/openai/CLIP.git

在这里插入图片描述

二、代码解读

2.1 代码逐行构建过程

import clip
import torch
from PIL import Image

导入所需的库,包括 clip(用于加载和使用 CLIP 模型)、torchPyTorch 框架)和 PIL(用于图像处理)。

img_pah = '1.png'
classes = ['person', 'not_person']

设置输入图像的路径 img_path 和标签类别列表 classes。在这个示例中,类别列表包含了两个类别:‘person’‘not_person’

device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load('ViT-B/32', device)

根据是否可用 GPU,将设备设置为 “cuda”“cpu” 。然后,使用 CLIP 库中的 clip.load() 方法加载预训练的 ViT-B/32 模型,并返回加载的模型 model 和预处理函数 preprocess

image = Image.open(img_pah)
image_input = preprocess(image).unsqueeze(0).to(device)
text_inputs = torch.cat([clip.tokenize(f"a photo of a {c}") for c in classes]).to(device)

打开图像文件并使用预处理函数 preprocess 对图像进行预处理。然后,将预处理后的图像转换为模型所需的格式,并将其移动到设备上(GPUCPU)。对于文本输入,使用类别列表 classes 生成对应的文字描述,并使用 clip.tokenize() 函数对文字描述进行处理。

with torch.no_grad():
    image_features = model.encode_image(image_input)
    text_features = model.encode_text(text_inputs)

在不进行梯度计算的上下文中,使用 CLIP 模型的 encode_image() 方法对图像进行特征编码,得到图像特征 image_features 。同时,使用 encode_text() 方法对文本进行特征编码,得到文本特征 text_features

image_features /= image_features.norm(dim=-1, keepdim=True)
text_features /= text_features.norm(dim=-1, keepdim=True)
similarity = (100.0 * image_features @ text_features.T).softmax(dim=-1)
values, indices = similarity[0].topk(1)

对图像特征和文本特征进行归一化处理,以便计算它们之间的相似度。然后,使用矩阵乘法计算图像特征和文本特征之间的相似度矩阵。接下来,对相似度矩阵进行 softmax 归一化处理,得到相似度分数。最后,找到相似度分数中最高的值和对应的索引。

print("\nTop predictions:\n")
print('classes:{} score:{:.2f}'.format(classes[indices.item()], values.item()))

打印输出结果,显示预测的最高分数和对应的类别标签。

2.2 源代码 + 运行结果

import clip
import torch
from PIL import Image

img_pah = '1.png'
classes = ['person', 'not_person']

# 加载模型
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load('ViT-B/32', device)


# 准备输入集
image = Image.open(img_pah)
image_input = preprocess(image).unsqueeze(0).to(device)
text_inputs = torch.cat([clip.tokenize(f"a photo of a {c}") for c in classes]).to(device) #生成文字描述

# 特征编码
with torch.no_grad():
    image_features = model.encode_image(image_input)
    text_features = model.encode_text(text_inputs)

# 选取参数最高的标签
image_features /= image_features.norm(dim=-1, keepdim=True)
text_features /= text_features.norm(dim=-1, keepdim=True)
similarity = (100.0 * image_features @ text_features.T).softmax(dim=-1) #对图像描述和图像特征  
values, indices = similarity[0].topk(1)

# 输出结果
print("\nTop predictions:\n")
print('classes:{} score:{:.2f}'.format(classes[indices.item()], values.item()))

运行结果为:

Top predictions:

classes:person score:0.81

2.3 细节补充

2.3.1 clip.load()

clip.load() 方法中,可以调用多个预训练的 CLIP 模型。以下是一些常用的 CLIP 模型名称:

  • ViT-B/32: Vision Transformer 模型,基于 ImageNet 预训练的 ViT-B/32
  • RN50: ResNet-50 模型,基于 ImageNet 预训练的 ResNet-50
  • RN101: ResNet-101 模型,基于 ImageNet 预训练的 ResNet-101
  • RN50x4: ResNet-50 模型的扩展版本,使用更大的 batch size 进行训练。
  • RN50x16: ResNet-50 模型的更大版本,使用更大的 batch size 进行训练。

以上列出的是一些常用的预训练模型,但并不是全部可用的模型列表。CLIP 库还提供其他模型和变体,您可以在官方文档中查找完整的模型列表,并根据您的需要选择适合的预训练模型。

请注意,选择不同的预训练模型可能会影响性能和计算资源的要求。较大的模型通常具有更多的参数和更高的计算成本,但可能具有更好的性能。因此,根据您的具体应用场景和可用资源,选择适当的预训练模型进行调用。

2.3.2 preprocess()

preprocessCLIP 库中提供的预处理函数之一,用于对图像进行预处理以符合 CLIP 模型的输入要求。下面是 preprocess 函数的一般步骤和说明:

  • 图像的缩放:首先,图像会被缩放到指定的大小。通常情况下,CLIP 模型要求输入图像的尺寸是正方形的,例如 224x224 像素。所以,在预处理过程中,图像会被调整为适当的尺寸。
  • 像素值归一化:接下来,图像的像素值会被归一化到特定的范围。CLIP 模型通常要求输入图像的像素值在 0 到 1 之间,因此预处理过程中会将像素值归一化到这个范围。
  • 通道的标准化:CLIP 模型对图像通道的顺序和均值标准差要求是固定的。因此,预处理过程中会对图像的通道进行重新排列,并进行标准化。具体来说,通常是将图像的通道顺序从 RGB(红绿蓝)调整为 BGR(蓝绿红),并对每个通道进行均值标准化。
  • 转换为张量:最后,经过预处理的图像会被转换为张量形式,以便于传递给 CLIP 模型进行计算。这通常涉及将图像的维度进行调整,例如从形状为 (H, W, C) 的图像转换为形状为 (C, H, W) 的张量。

总之,preprocess 函数负责将输入的图像进行缩放、归一化和格式转换,以使其符合 CLIP 模型的输入要求。具体的预处理操作可能因 CLIP 模型的不同版本而有所差异,建议参考 CLIP 库的官方文档或源代码以获得更详细的预处理细节。

2.3.3 unsqueeze

PyTorch 中,unsqueeze() 是一个张量的方法,用于在指定的维度上扩展维度。

具体而言,unsqueeze(dim) 的作用是在给定的 dim 维度上增加一个维度。这个操作会使得原始张量的形状发生变化。

以下是 unsqueeze(dim) 的详细解释:

  • 参数 dim:表示要在哪个维度上进行扩展。可以是一个整数或一个元组来指定多个维度。通常, dim 的取值范围是从 0 到 tensor.dim()(即张量的维度数)。
  • 返回值:返回一个新的张量,与原始张量共享数据内存,但形状发生了变化。

示例:

import torch

# 原始张量形状为 (2, 3)
x = torch.tensor([[1, 2, 3], [4, 5, 6]])

# 在维度0上扩展维度,结果形状为 (1, 2, 3)
y = x.unsqueeze(0)

# 在维度1上扩展维度,结果形状为 (2, 1, 3)
z = x.unsqueeze(1)

在上述示例中,原始张量 x 的形状为 (2, 3)。通过调用 unsqueeze() 方法并传递不同的维度参数,我们可以在指定的维度上扩展维度。结果张量 y 在维度0上扩展维度,形状变为 (1, 2, 3);结果张量 z 在维度1上扩展维度,形状变为 (2, 1, 3)。

通过使用 unsqueeze() 方法,我们可以改变张量的形状,以适应不同的计算需求和操作要求。

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

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

相关文章

2023年Android开发者路线-第1部分

2023年Android开发者路线-第1部分 2023年Android开发者路线-第2部分 2023年Android开发者路线-第3部分 2023年Android开发者路线-第4部分 2023年Android开发者路线-第1部分 Android 生态系统处于不断发展的状态:每天都会引入新的库和资料,旨在加快开…

linux常见指令以及权限理解

1.linux下基本指令: ls指令: 查看文件的属性 ls-l:文件的属性 ls-la:显示所有文件的属性 ls *: linux任何一个目录下面都有两个隐藏文件: ..:表示当前路径的上级路径,可以原路返回 .&…

分布式锁-01(单节点解决方案)

分布式锁概述 为什么需要分布式锁 在单机部署的系统中,使用线程锁来解决高并发的问题,多线程访问共享变量的问题达到数据一致性,如使用synchornized、 ReentrantLock等。 但是在后端集群部署的系统中,程序在不同的JVM虚拟机中运行…

可调整界面输出的桌面万年历设计

可调整界面输出的桌面万年历设计 本文主要介绍月历和生辰八字五行的界面输出方法。一个有趣的方法是可调整界面输出格式,显示几种屏幕排版的布局。本文示例了四个式样。算法的精髓是用一种简单的算法来设置调节屏幕打印输出。分三个显示内容,即月历、大字…

Docker入门实战---修改Docker镜像源

前言 现在大部分互联网公司在实施项目时几乎都会以微服务架构进行落地,那么微服务一旦多了之后就会面临一个如何友好的治理的问题,本人不会重点介绍治理的问题,而是会简单就治理的其中一个环节服务部署运维的问题进行介绍,服务部…

排序算法之桶排序

一、桶排序(BucketSort) 桶排序(Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶里。每个桶再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序…

[论文阅读] (28)李沐老师视频学习——1.研究的艺术·跟读者建立联系

《娜璋带你读论文》系列主要是督促自己阅读优秀论文及听取学术讲座,并分享给大家,希望您喜欢。由于作者的英文水平和学术能力不高,需要不断提升,所以还请大家批评指正,非常欢迎大家给我留言评论,学术路上期…

如何成功申请计算机软件著作权【流程完整记录】

致谢 :此博文的编写包括软著的申请,均借鉴了大佬【万里守约】的博客https://blog.csdn.net/qq_45625499/article/details/123463407 提示:此博文仅适合个人申请,因为我是自己一个人的项目,自己一个人申请软著 文章目录…

2023 Android开发者路线-第一部分

2023 Android开发者路线-第一部分 Android 生态系统处于不断发展的状态:每天都会引入新的库和资料,旨在加快开发速度并让我们作为开发人员的生活更轻松。 在这个由多个部分组成的系列中,您将按照我们的2023 年 Android 开发者路线图了解有关…

pyhton GUI编程之Tkinter美化皮肤ttkbootstrap

文章目录 pyhton GUI编程之Tkinter美化皮肤ttkbootstrap介绍 pyhton GUI编程之Tkinter美化皮肤ttkbootstrap介绍 tkinter 相对简单,学习入门很快,但是做出来的GUI界面不够美观,各个组件的外观都很老土,所谓 " 爱美之心&#…

发现一个国产BI软件,做财务数据分析效果绝了

如果是一般的财务数据分析,BI软件们都能做,但如果真要深入了解财务痛点,逐个击破财务数据分析难点,实现多维立体自助式的财务数据分析,那就难。就目前而言,财务数据分析做得好的国产BI软件也就一个奥威BI软…

使用docker构建ElasticSearch集群

目录 一、准备工作 二、编写docker-compose.yml 三、编写ElasticSearch和kibana的配置文件 四、执行构建ElasticSearch集群 五、验证结果: 六、可视化工具 ElasticSearch可视化工具介绍(elasticsearch-head、kibana、elasticHD) 一、e…

CTF权威指南 笔记 -第四章Linux安全机制-4.1-Stack Canaries

目录 Stack Canaries 简介 我们进行简单的例子 64 32 checksec Stack Canaries 是对抗栈溢出攻击的技术 SSP安全机制 Canary 的值 栈上的一个随机数 在程序启动时 随机生成并且保存在比返回地址更低值 栈溢出是从低地址向高地址进行溢出 如果攻击者要攻击 就一定要覆…

电动力学专题:圆柱形导体中趋肤效应

电动力学分析 金属导体内的电流密度方程 由Maxwell方程组导出Helmhltz方程 对于良导体,有\sigma/(\omega \eprsilon),因此有 圆柱形导线中电流密度分布 设电流沿Z轴方向流动,均匀导体,可简化为 通解: 安培环路定理 定态电磁波的Maxwell方程组 贝塞尔函数性质&…

【SQL】作为前端,应该了解的SQL知识(第三弹)

📑视图 使用表时,会将数据保存在存储设备(硬盘上) 而使用视图时,并不会将数据保存在存储设备上,也不会将数据保存在任何地方。 视图里面保存的是 从表中取出数据所使用的SELECT语句(视图中的…

zhangrelay博客置顶三篇点击量分析

230515只有三篇置顶,如下: 分别为: 20.03.13 : 901522.01.12 :1372923.04.15 :18836 熟悉zhangrelay博客风格的AI都清楚,他的博客内容都是筛选和设计过的。 置顶三篇阅读量差值为&#xff1…

C++--AVL树的插入,详解四种旋转规则(结尾附源代码链接)

AVL树的插入 前言左单旋右单旋左右双旋右左双旋检查是否这颗树是否是AVL树 前言 AVL树可以说是对二叉搜索树的优化,我们来看二叉树搜索树的下一面一种特殊情况: 当我们插入的数是上面的情况时,二叉树搜索树的特点就形同虚设了,这…

ChatGpt 2步制作流程图与思维导图,你确定不来看一下吗?

什么?你还不会使用ChatGpt。推荐下面这篇文章 ChatGPT保姆级教程,一分钟学会使用ChatGPT! - 掘金 (juejin.cn) 如果没有谷歌账号推荐直接买一个,因为你在中国注册谷歌账号,被谷歌查到,也是使用不了ChatGp…

企业数字化转型过程中面临最大的挑战和问题是什么?

无论组织规模如何,业务的敏捷性、弹性以及生产力的高低都是决定其发展运营成功与否的关键因素。而一个良好的数字化转型战略则是企业发展进步的有力助推器。 麦肯锡称,借助数字化转型,可以实现 20% 至 50% 的经济收益和 20% 至 30% 的客户满…

【Spring Cloud Alibaba】Nacos的安装与介绍以及Nacos集群的安装

欢迎来到 Nacos 的世界! Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性…