深度学习算法应用实战 | 利用 CLIP 模型进行“零样本图像分类”

news2024/12/23 13:35:54

文章目录

    • 1. 零样本图像分类简介
      • 1.1 什么是零样本图像分类?
      • 1.2 通俗一点的解释
    • 2. 模型原理图
    • 3. 环境配置
    • 4. 代码实战
    • 5. Gradio前端页面
      • 5.1 什么是 Gradio ?
    • 6 进阶操作
    • 7. 总结


1. 零样本图像分类简介

在这里插入图片描述

1.1 什么是零样本图像分类?

“零样本图像分类”(Zero-shot image classification)指的是使用一个模型对图像进行分类,而这个模型并没有在包含那些特定类别的标记样本的数据上进行过显式训练。

传统的图像分类方法需要在一组特定的带标签的图像上训练模型。这个模型通过学习,将图像的某些特征与标签相对应。当需要使用这种模型来处理引入了新标签集的分类任务时,通常需要进行模型的微调,以适应新的标签。

与此相反,零样本或开放词汇的图像分类模型通常是多模态模型,这些模型在包含大量图像及其相关描述的数据集上进行训练。这些模型学习了视觉和语言之间对齐的表示方法,可以应用于包括零样本图像分类在内的许多下游任务。

这是一种更为灵活的图像分类方法,它允许模型在不需要额外训练数据的情况下,泛化到新的和未见过的类别。同时,它也使用户能够用自由形式的文本描述来查询他们目标对象的图像。


1.2 通俗一点的解释

上面的内容如果看不懂没关系,下面我来用通俗的语言解释这段话:

比如我们想让一个熊孩子能认识不同的图片(比如区分猫和狗),我们需要给这个熊孩子看很多标有“这是猫”、“这是狗”的图片来训练它。这就像是在教熊孩子“这些特征意味着猫,那些特征意味着狗”。但如果突然出现一个新的动物种类,比如浣熊,而熊孩子之前没有学习过浣熊的图片,它就不知道怎么识别了。这时,我们通常需要给熊孩子更多的浣熊图片来训练它识别浣熊。这就是我们上面提到的传统的图像分类

然而,“零样本图像分类”就像是给熊孩子一种超能力,让它能在没有直接学习过某个类别(比如浣熊)的情况下也能识别出来。这种方式是通过训练熊孩子理解图片和文字之间的关系来实现的。比如,熊孩子在学习的时候不仅看图片,还学习这些图片的描述。这样,当它遇到一个新的图片(比如浣熊),即使它之前没有直接学习过,它也可以通过理解图片的特征和之间学到的文字描述来猜测这可能是“浣熊”。

总的来说,这就是一种更聪明的方式,让熊孩子能够在没有被直接训练识别某些东西的情况下,也能识别出这些东西来。


那这篇博客, 我就教大家使用 CLIP 搭建一个零样本的分类模型!不需要任何的训练就可以实现你的分类需求!

教程使用 huggingfacetransformers 库来完成,这样方便我对整个专栏的代码教程进行维护,也方便我为大家分发模型(这种多模态的模型一般都很大,自己下载一次很麻烦,我会在博客中提供模型网盘地址)。


2. 模型原理图

论文地址:[paper] Learning Transferable Visual Models From Natural Language Supervision (arxiv.org)

论文摘要最近,在大量数据上进行模型预训练的自然语言处理领域取得的突破为计算机视觉领域的类似基础模型铺平了道路。这些模型可以通过生成通用视觉特征(即,适用于不同图像分布和任务且无需微调的特征)来大大简化任何系统中图像的使用。本研究表明,如果在来自不同来源的足够多的策划数据上训练,现有的预训练方法,特别是自监督方法,可以产生这样的特征。我们重新审视现有方法,并结合不同技术来扩展我们的预训练,包括数据和模型规模方面。大部分技术贡献旨在加速和稳定大规模训练。在数据方面,我们提出了一个自动化管道,用于构建专用的、多样化的、策划的图像数据集,而不是像自监督文献中通常做的那样使用未策划的数据。在模型方面,我们训练了一个拥有10亿参数的ViT模型,并将其蒸馏成一系列较小的模型,这些模型在大多数图像和像素级基准测试中超过了现有最佳的通用特征,即OpenCLIP

在这里插入图片描述


3. 环境配置

后续所有教程都使用conda环境,请大家自行配置好~

conda create --name huggingface-env python==3.8 -y

conda activate huggingface-env

pip install transformers

4. 代码实战

本次实战我们选择 openai 团队开源的 clip-vit-base-patch32 版本。借助 transformers 库 ,我们可以通过几行代码就完成一个零样本分类任务。

下载好我提供的模型后,修改以下两处就可以顺利运行代码:

  1. model路径和processor路径指定到你下载下来文件的位置。
  2. image_path路径换成本地图片路径。
# 导入Python图像库PIL和requests库
from PIL import Image
import requests

# 导入transformers库中的CLIP处理器和CLIP模型
from transformers import CLIPProcessor, CLIPModel

# 从预训练路径加载CLIP模型
model = CLIPModel.from_pretrained("/home/models/clip-vit-base-patch32")
# 从预训练路径加载CLIP处理器
processor = CLIPProcessor.from_pretrained("/home/models/clip-vit-base-patch32")

# 设置一个图像的路径
image_path = "000000039769.jpg"
# 使用PIL的Image打开它
image = Image.open(image_path)

# 使用处理器处理文本(这里有两个文本:猫和狗的照片)和图片,将它们转换为模型可以处理的格式
inputs = processor(text=["a photo of a cat", "a photo of a dog"], images=image, return_tensors="pt", padding=True)

# 将处理好的输入数据传递给模型并得到输出
outputs = model(**inputs)
# 从输出中获取图像与文本之间的相似性分数
logits_per_image = outputs.logits_per_image 
# 使用softmax函数计算标签的概率
probs = logits_per_image.softmax(dim=1) 
# 打印出概率
print(probs)
# tensor([[0.9949, 0.0051]], grad_fn=<SoftmaxBackward0>)

模型地址

链接:https://pan.baidu.com/s/1eg95QBmMOx9P0GvX-pshMg
提取码:hhze

小知识

如果你够细心,你就会发现打印出来的概率后面有一个grad_fn标识。

grad_fn=<SoftmaxBackward0> 是一个表示该张量是通过某个操作产生的,并且这个操作在PyTorch的自动微分系统中具有可微性(即可以进行梯度反向传播)的标识。

  • tensor([[0.9949, 0.0051]]:这是一个包含概率值的张量。在这个例子中,它表示图片被模型识别为第一个类别("a photo of a cat")的概率是99.49%,识别为第二个类别("a photo of a dog")的概率是0.51%
  • grad_fn:这是"gradient function"的缩写,意味着这个张量是作为一个计算结果产生的,而这个计算是可以进行梯度反向传播的。在这种情况下,<SoftmaxBackward0>是一个特定的梯度函数,它指的是这个张量是通过Softmax函数计算得到的,并且如果需要的话,可以通过这个函数来计算梯度。

我们这篇内容就是那模型进行推理,所以我们不需要关心这个grad_fn属性。


5. Gradio前端页面

每次都使用黑洞洞的终端推理图片是不是很无聊呢?下面为大家介绍一个工具,它可以快速的为算法实现一个前端页面,方便我们以图形化的方式推理图片。

5.1 什么是 Gradio ?

项目地址:gradio-app

文档地址:Gradio Interface Docs

Gradio 是一个开源库,旨在为机器学习模型提供快速且易于使用的网页界面。它允许开发者和研究人员轻松地为他们的模型创建交互式的演示,使得无论技术背景如何的人都可以方便地试用和理解这些模型。使用Gradio,你只需几行代码就可以生成一个网页应用程序,该应用程序可以接收输入(如图片、文本或音频等),并展示模型的输出。这对于测试、展示和获取模型反馈非常有用,特别是在协作、教育或研究的环境中。此外,它还提供了一系列用于增强用户体验的功能,如输入验证、自定义布局和分析工具,这些都使得Gradio成为机器学习领域中展示和共享模型的受欢迎工具。

安装方式很简单,一行指令搞定。

pip install gradio -i https://pypi.tuna.tsinghua.edu.cn/simple

下面是我基于这个库实现的 CLIP 零样本分类模型页面,同时为大家分别准备了一张猫一张狗的图片,以便大家能够更好地体验和使用这个工具。

请添加图片描述
请添加图片描述

import gradio as gr
from PIL import Image
from transformers import CLIPProcessor, CLIPModel
import torch
import requests

# 从预训练的路径中加载CLIP模型和处理器
model = CLIPModel.from_pretrained(
    "/home/models/clip-vit-base-patch32"
)
processor = CLIPProcessor.from_pretrained(
    "/home/models/clip-vit-base-patch32"
)


def classify_image_with_text(image, text):
    # 根据逗号分割输入文本,以处理多个标签
    labels = text.split(",")
    # 处理输入数据:将文本和图像转换为模型可以处理的格式
    inputs = processor(text=labels, images=image, return_tensors="pt", padding=True)

    # 获取模型的输出
    with torch.no_grad():
        outputs = model(**inputs)

    # 计算概率
    logits_per_image = outputs.logits_per_image  # 这是图像与文本之间的相似度分数
    probs = logits_per_image.softmax(dim=1).tolist()[0]  # 用softmax获取标签概率

    # 创建一个响应字典,用于输出每个标签的概率
    response = {label: prob for label, prob in zip(labels, probs)}
    return response


# 创建Gradio界面
# fn指定了要运行的函数,inputs定义了输入类型,outputs定义了输出类型
iface = gr.Interface(
    fn=classify_image_with_text,
    inputs=[gr.Image(type="pil"), gr.Textbox(label="Text Input")],  # 图片和文本框输入
    outputs="json",  # 输出为JSON格式
    examples=[
        [
            "https://gitee.com/diffiehellman/diffiehellman_personal_blog_gallery/raw/master/cdog.jpg",
            "dog, cat, tigers, lions, elephants, pandas, giraffes",
        ],
        [
            "https://gitee.com/diffiehellman/diffiehellman_personal_blog_gallery/raw/master/ccat.jpg",
            "dog, cat, tigers, lions, elephants, pandas, giraffes",
        ],
    ],
    title="CLIP零样本图像分类",
    description="上传一张图片获得json格式的零样本分类结果",
)

# 启动界面
iface.launch()

6 进阶操作

在我们学习了如何使用 CLIP 之后,接下来我们将利用这些知识来实施一个小型项目。这个项目的目的是通过实际操作来加强大家对 Python 中一些常用库的熟悉程度。

这一次,我们的项目相对简单:我们将从一个包含猫和狗图片的混合文件夹中,使用我们学习的算法自动区分并归类这两种图片。

这个案例不仅是一个很好的机器学习入门项目,也是一个非常实用的技能,可以应用于各种图片分类任务,用来清洗个数据集什么的非常的方便~

算法步骤

  1. 加载模型:使用transformers库加载预训练的 CLIP 模型和处理器。
  2. 读取图片:使用 PIL 读取图片。
  3. 图像预处理:使用 CLIP 的处理器对图片进行预处理。
  4. 模型预测:对每张处理过的图片使用 CLIP 模型,获取其与“猫”和“狗”文本描述的相似度。
  5. 分类和保存:根据模型的预测将图片分类为猫或狗,并保存到相应的文件夹。

使用到的Python库

  • PIL(Python Imaging Library):一个强大的图像处理库,可用于打开、操作和保存多种图像格式。
  • OS:用于与操作系统进行交互。它提供了丰富的方法来处理文件和文件夹。通过os库可以执行诸如创建、删除、移动文件和目录,以及获取文件属性等操作。
from PIL import Image
import requests
from transformers import CLIPProcessor, CLIPModel
import os

# 加载预训练的CLIP模型和处理器
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")

# 定义读取图片的文件夹路径
folder_path = "/path/to/your/folder"

# 定义保存分类后图片的路径
save_path_cats = "/path/to/save/cats"
save_path_dogs = "/path/to/save/dogs"

# 读取文件夹中的所有图片文件
for filename in os.listdir(folder_path):
    if filename.endswith(".jpg") or filename.endswith(".png"):  # 检查文件格式
        # 打开图片
        image = Image.open(os.path.join(folder_path, filename))

        # 使用处理器处理图片和文本
        inputs = processor(text=["a photo of a cat", "a photo of a dog"], images=image, return_tensors="pt", padding=True)

        # 模型预测
        outputs = model(**inputs)
        probs = outputs.logits_per_image.softmax(dim=1)

        # 根据预测结果分类图片
        if probs[0, 0] > probs[0, 1]:  # 如果“猫”的概率高于“狗”
            image.save(os.path.join(save_path_cats, filename))  # 保存到猫的文件夹
        else:
            image.save(os.path.join(save_path_dogs, filename))  # 保存到狗的文件夹

print("分类完成!")

7. 总结

这篇教程是我们系列文章的开篇之作。虽然内容相对简单,但我们实现的算法 CLIP 是一个在多模态领域极具影响力的模型。这个经典的模型不仅在本教程中发挥了重要作用,而且在后续的博客中,我们还将继续利用它来实施更多的有趣项目。

这个系列旨在逐步深入,让大家不仅了解算法的基础知识,还能学习如何将这些算法应用于实际的、有意义的项目中。每一篇教程都是精心设计的,以确保即使是初学者也能够跟上节奏,并逐步提升自己的技能。

我非常欢迎大家在评论区提出自己遇到的实际任务,或者对特定算法的疑问和讨论。

感谢大家的支持!

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

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

相关文章

NLP|LSTM+Attention文本分类

目录 一、Attention原理简介 二、LSTMAttention文本分类实战 1、数据读取及预处理 2、文本序列编码 3、LSTM文本分类 三、划重点 少走10年弯路 LSTM是一种特殊的循环神经网络&#xff08;RNN&#xff09;&#xff0c;用于处理序列数据和时间序列数据的建模和预测。而在N…

66、python - 代码仓库介绍

上一节,我们可以用自己手写的算法以及手动搭建的神经网络完成预测了,不知各位同学有没有自己尝试来预测一只猫或者一只狗,看看准确度如何? 本节应一位同学的建议,来介绍下 python 代码仓库的目录结构,以及每一部分是做什么? 我们这个小课的代码实战仓库链接为:cv_lea…

springboot医院信管系统源码和论文

随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&#xf…

【Linux 内核源码分析笔记】系统调用

在Linux内核中&#xff0c;系统调用是用户空间程序与内核之间的接口&#xff0c;它允许用户空间程序请求内核执行特权操作或访问受保护的内核资源。系统调用提供了一种安全可控的方式&#xff0c;使用户程序能够利用内核功能而不直接访问底层硬件。 系统调用&#xff1a; 通过…

代理IP连接不上/网速过慢?如何应对?

当您使用代理时&#xff0c;您可能会遇到不同的代理错误代码显示代理IP连不通、访问失败、网速过慢等种种问题。 在本文中中&#xff0c;我们将讨论您在使用代理IP时可能遇到的常见错误、发生这些错误的原因以及解决方法。 一、常见代理服务器错误 当您尝试访问网站时&#…

关于Geek软件的下载

直接百度搜geek出来的前几条似乎都是广告&#xff1a; 点进去之后是这个界面&#xff1a; 然后安装到最后一步提示要付费才能安装成功&#xff1a; 然后如果是用谷歌搜索&#xff1a; 有free版和pro版&#xff1a; free版下载之后压缩包解压就是exe不需要安装 综上&#xff0c…

金蝶EAS pdfviewlocal 任意文件读取漏洞

产品简介 金蝶EAS 为集团型企业提供功能全面、性能稳定、扩展性强的数字化平台&#xff0c;帮助企业链接外部产业链上下游&#xff0c;实现信息共享、风险共担&#xff0c;优化生态圈资源配置&#xff0c;构筑产业生态的护城河&#xff0c;同时打通企业内部价值链的数据链条&a…

【leetcode】力扣热门算法之K个一组翻转链表【困难】

题目描述 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保持原有顺序。 你不能只是单纯的改变节…

JS-基础语法(一)

JavaScript简单介绍 变量 常量 数据类型 类型转换 案例 1.JavaScript简单介绍 JavaScript 是什么&#xff1f; 是一种运行在客户端&#xff08;浏览器&#xff09;的编程语言&#xff0c;可以实现人机交互效果。 JS的作用 JavaScript的组成 JSECMAScript( 基础语法 )…

JavaSE 反射、枚举及Lambda的使用

目录 1 反射1.1 定义1.2 用途1.3 反射基本信息1.4 反射相关的类1.4.1 Class类(反射机制的起源 )1.4.1.1 Class类中的相关方法 1.4.2 反射示例1.4.2.1 获得Class对象的三种方式1.4.2.2 反射的使用 1.5 优缺点 2 枚举2.1 背景及定义2.2 使用2.3 优缺点2.4 枚举和反射2.5 总结2.6 …

调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配

作者推荐 【动态规划】C算法312 戳气球 关键字&#xff1a; 函数调用约定 混合编程 __stdcall c WINAPI APIENTRY _cdecl 调用方出错提示如下&#xff1a; 调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参…

C++qt-信号-信号槽

1、概念 信号和槽是两种函数&#xff0c;这是Qt在C基础上新增的特性&#xff0c;类似于其他技术中的回调的概念。 信号和槽通过程序员提前设定的“约定”&#xff0c;可以实现对象之间的通信&#xff0c;有两个先决的条件&#xff1a; 通信的对象必须都是从QObject类中派生出来…

threejs 光带扩散动画

目录 一、创建光带 (1) 设置光带顶点 (2) 设置光带顶点透明度属性 二、光带动画 完整代码 html文件代码 js文件代码 最后展示一下项目里的效果&#xff1a; 最近项目中要求做一段光带效果动画&#xff0c;尝试着写了一下&#xff0c;下面是本次分享光带扩散动画的效果预…

地铁判官(外包)

到处都是说外包不好不好的&#xff0c;从没有想过自身问题。 例如&#xff1a; 技术人员动不动就是说&#xff0c;进了外包三天&#xff0c;一年&#xff0c;三年之后技术退步很多。就算你这样的人进了甲方&#xff0c;也是个渣渣。(声明一下&#xff0c;我也是外包&#xff0…

CMU15-445-Spring-2023-Project #2 - 前置知识(lec07-010)

Lecture #07_ Hash Tables Data Structures Hash Table 哈希表将键映射到值。它提供平均 O (1) 的操作复杂度&#xff08;最坏情况下为 O (n)&#xff09;和 O (n) 的存储复杂度。 由两部分组成&#xff1a; Hash Function和Hashing Scheme&#xff08;发生冲突后的处理&…

阿里云99元一年2核2G3M云服务器值得买吗?

阿里云作为国内领先的云服务提供商&#xff0c;一直致力于为用户提供优质、高效的服务。目前&#xff0c;阿里云推出的99元一年2核2G3M云服务器&#xff0c;更是引发了广大用户的关注。本文将详细解析这款云服务器的特点、优势以及适用场景&#xff0c;为大家上云提供参考。 一…

Android逆向学习(六)绕过app签名校验,通过frida,io重定向(上)

Android逆向学习&#xff08;六&#xff09;绕过app签名校验&#xff0c;通过frida&#xff0c;io重定向&#xff08;上&#xff09; 一、写在前面 这是吾爱破解正己大大教程的第五个作业&#xff0c;然后我的系统还是ubuntu&#xff0c;建议先看一下上一个博客&#xff0c;关…

阿赵UE学习笔记——8、贴图导入设置

阿赵UE学习笔记目录 大家好&#xff0c;我是阿赵。   继续学习虚幻引擎的用法&#xff0c;这次来说一下贴图的导入设置。   在内容浏览器里面可以看到纹理类型的资源&#xff0c;就是贴图了&#xff0c;鼠标悬浮在上面可以看到这个纹理贴图的信息&#xff1a; 双击纹理贴图…

使用Scikit Learn 进行识别手写数字

使用Scikit Learn 进行识别手写数字 作者&#xff1a;i阿极 作者简介&#xff1a;数据分析领域优质创作者、多项比赛获奖者&#xff1a;博主个人首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可以点赞&#x1f44d;收藏&#x1f…

虽迟但到!MySQL 可以用 JavaScript 写存储过程了!

任何能用 JavaScript 来干的事情&#xff0c;最终都会用 JavaScript 来干 背景 不久前&#xff0c;Oracle 在 MySQL 官方博客官宣了在 MySQL 中支持用 JavaScript 来写存储过程。 最流行的编程语言 最流行的数据库。程序员不做选择&#xff0c;当然是全都要。 使用方法 用 J…