如何对图像进行聚类

文章来源:https://medium.com/voxel51/how-to-cluster-images-6e09bdff7361

2024 年 4 月 10 日

使用 FiftyOne、Scikit-learn和特征嵌入

在 2024 年深度学习的计算密集型环境中,集群一词最常出现在讨论 GPU 集群时--高度优化的矩阵乘法机器的大规模集合,用于训练同样大规模的生成模型。每个人都专注于训练更大、更好的模型,挑战人工智能模型性能的极限,并将最新的架构进展应用于他们的数据。

8

在本文中,我们将介绍聚类的基础知识,并向你展示如何使用开源机器学习库 Scikit-learn 和 FiftyOne 来构建可视化数据!

什么是聚类?

9

集群的构建模块

想象一下,你有一大堆各种形状和大小的乐高积木散落在地板上。到了该把乐高积木收起来的时候,你却发现自己没有一个足够大的垃圾桶来存放所有的乐高积木。幸运的是,你找到了四个较小的垃圾桶,每个都能容纳大致相同数量的乐高积木。你可以把各种乐高积木随意扔进每个垃圾桶,然后就可以收工了。但这样一来,下次你再去找某个特定的乐高积木时,就得花很多时间四处寻找了。

相反,你有一个更好的主意:把相似的乐高积木放在同一个垃圾桶里,会为你节省很多时间和麻烦。但是,你打算用什么标准来把乐高积木放进垃圾桶呢?是给不同颜色的乐高积木分配不同的盒子?还是把所有的方形乐高积木放在一个盒子里,圆形乐高积木放在另一个盒子里?这真的取决于你有哪些乐高积木!简而言之,这就是聚类。

更正式地说,聚类或聚类分析是一套对数据点进行分组的技术。聚类算法接收一堆对象,然后为每个对象分配任务。不过,与分类法不同的是,聚类算法并不是从一个类别列表开始对对象进行分类,迫使对象落入预设的桶中。相反,聚类试图根据数据发现不同的类别。换句话说,聚类的目的是发现数据中的结构,而不是预测预先存在的结构中的标签。

最后一点值得重复:聚类不是预测标签。与分类、检测和分割任务不同,聚类任务没有基本真实标签。我们将这种算法称为无监督算法,与有监督和自监督学习任务形成鲜明对比。

更重要的是,聚类是无需训练的。聚类算法会吸收数据点(对象)的特征,并利用这些特征将对象分成若干组。一旦成功,这些组就会突出独特的特征,让你了解数据的结构。

聚类是如何工作的?

聚类是一个包含技术的总称!

聚类算法有多种类型,根据其用于分配聚类成员资格的标准而有所区别。最常见的几种聚类算法是:

基于中心点的聚类:例如 K-means 聚类和均值移动聚类等技术。这些方法试图找到中心点来定义每个聚类,这些中心点被称为 "中心点",其目的是最大限度地提高聚类内各点之间的一致性。这种聚类方法适用于大型数据集,但对异常值和随机初始化比较敏感。通常情况下,我们会进行多次运行,然后选出最好的一次。你可能会发现,像 K-means 这样的技术在处理高维数据(即 "维度诅咒")时很吃力,如果与均匀流形逼近与投影(UMAP)等降维技术搭配使用,就能更好地发现结构。

基于密度的聚类:DBSCAN、HDBSCAN 和 OPTICS 等技术根据特征空间的疏密程度来选择聚类。从概念上讲,这些算法将高密度区域视为聚类,当点在特征空间中足够分散时,就会将聚类分解。像 DBSCAN 这样基于密度的简单技术在处理高维数据时可能会遇到困难,因为在高维数据中,数据可能并不是密集分布的。不过,HDBSCAN 等更复杂的技术可以克服其中的一些限制,并从高维特征中发现显著的结构。

分层聚类: 这些技术旨在:

  1. 从单个点入手构建聚类,然后迭代地将聚类组合成更大的复合体,或
  2. 解构聚类,从一个聚类中的所有对象开始,反复将聚类分解成更小的组成部分。

随着数据集的增长,聚合聚类(Agglomerative Clustering)等构建技术的计算成本会变得越来越高,但对于中小型数据集和低维特征来说,其性能还是相当可观的。

我应该对哪些特征进行聚类?

对于我们开始讨论的乐高积木,特征(长度、宽度、高度、曲率等)是独立的实体,我们可以将其视为数据表中的列。在对这些数据进行归一化处理后,我们就可以将一行数值作为特征向量传入每个乐高积木块的聚类算法中。从历史上看,聚类技术有很多类似的应用,可以对数据表或时间序列中的数值进行简单的预处理。

由于一些简单的原因,图像等非结构化数据并不能很好地融入这一框架:

  1. 图像的大小(长宽比和分辨率)可能不同
  2. 原始像素值可能非常嘈杂
  3. 像素之间的相关性可能是高度非线性的

如果我们大费周章地调整和标准化所有图像的尺寸、归一化像素值、去噪并将多维数组扁平化为 "特征向量",那么将这些经过处理的像素数组视为特征将给无监督聚类算法带来巨大的压力,使其难以发现结构。这对于像 MNIST 这样的简单数据集来说是可行的,但在实际应用中却往往行不通。

幸运的是,我们拥有强大的非线性函数逼近工具--深度神经网络!将我们的注意力限制在图像领域,我们有 CLIP 和 DINOv2 这样的模型,它们的输出是输入数据的有意义表示,我们还有为图像分类等特定任务训练的模型,我们通常从中提取网络第二层到最后一层的输出。还有变异自动编码器(VAE)网络,通常从中提取中间层的表示!

不同的模型有不同的架构,并在不同的数据集上针对不同的任务进行训练。

使用 FiftyOne 和 Scikit-learn 对图像进行聚类

设置和安装

我们将利用两个开源机器学习库:Scikit-learn 和 fiftyone,前者预装了大多数常见聚类算法的实现,后者简化了非结构化数据的管理和可视化:

pip install -U scikit-learn fiftyone

FiftyOne 聚类插件让我们的生活更加轻松。它在 scikit-learn 的聚类算法和我们的图像之间提供了连接组织,并将所有这些都封装在 FiftyOne 应用程序的一个简单用户界面中。我们可以通过 CLI 安装该插件:

fiftyone plugins download https://github.com/jacobmarks/clustering-plugin

我们还需要另外两个库: OpenAI 的 CLIP GitHub repo 可以让我们使用 CLIP 模型生成图像特征,而 umap-learn 库则可以让我们对这些特征应用一种名为 "统一曲面逼近和投影(UMAP)"的降维技术,从而将其可视化为二维图像:

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

请注意,这两个库中的任何一个都不是严格意义上的必需库--你可以使用 FiftyOne Model Zoo 中暴露嵌入的任何模型生成特征,也可以使用 PCA 或 tSNE 等其他技术进行降维。

安装好所有必要的库后,在 Python 进程中导入相关的 FiftyOne 模块,然后从 FiftyOne Dataset Zoo 中加载一个数据集(如果你愿意,也可以加载你的数据!)。在本文中,我们将使用 MS COCO 数据集的验证分割(5000 个样本):

import fiftyone as fo
import fiftyone.brain as fob
import fiftyone.zoo as foz
from fiftyone import ViewField as F
# load dataset from the zoo
dataset = foz.load_zoo_dataset("coco-2017", split="validation")
# delete labels to simulate starting with unlabeled data
dataset.select_fields().keep_fields()
# rename and persist to database
dataset.name = "clustering-demo"
dataset.persistent = True
# launch the app to visualize the dataset
session = fo.launch_app(dataset)

如果你在 Jupyter Notebook 中工作,可以通过 auto=False,然后在浏览器中打开一个标签页,指向 session.url 指向的位置(通常是 http://localhost:5151/),以查看应用程序的全貌。

10

创建特征

现在我们有了数据,必须生成用于聚类的特征。在本演示中,我们将查看两种不同的特征:由 CLIP 视觉转换器生成的 512 维向量,以及通过 UMAP 降维例程运行这些高维向量生成的二维向量。

要在 FiftyOne 样本集上运行降维,我们将使用 FiftyOne Brain 的 compute_visualization() 函数,该函数通过方法关键字参数支持 UMAP、PCA 和 tSNE。我们可以使用数据集的 compute_embeddings() 方法生成 CLIP 嵌入,然后明确地将其传递到我们的降维例程中。不过,我们可以一石二鸟,隐式告诉 compute_visualization()使用 CLIP 计算内嵌,并将这些内嵌存储在字段 "clip_embeddings "中,然后使用这些内嵌获得二维表示:

res = fob.compute_visualization(dataset, model="clip-vit-base32-torch", "clip-vit-base32-torch", embeddings="clip_embeddings", method="umap", brain_key="clip_vis", batch_size=10
)
dataset.set_values("clip_umap", res.current_points)

有了 brain_key 参数,我们就可以通过程序或 FiftyOne 应用程序中的名称来访问这些结果。最后一行将我们生成的二维向量数组存储到数据集的新字段 "clip_umap "中。

刷新应用程序并打开嵌入式面板,我们就能看到数据集的二维表示,图中的每个点都对应一幅图像:

11

计算和可视化聚类

有了特征向量,我们就可以使用 FiftyOne 聚类插件为数据添加结构。在 FiftyOne 应用程序中,按下键盘上的回车键并输入 compute_clusters。点击下拉菜单中的条目,打开聚类模式。

12

输入 run_key(类似于上面的 brain_key),以访问聚类运行的结果。在此过程中,请注意输入表单的动态更新。此时,你需要做出两个关键决定:根据哪些特征进行聚类以及采用哪种聚类算法!

选择 "kmeans "作为聚类方法,"clip_umap "作为特征向量。将聚类数目设为 20,其他参数均使用默认值。点击回车,让聚类算法运行。应该只需要几秒钟。

计算完成后,请注意样本上的新字段包含整数的字符串表示,表示给定样本被分配到哪个聚类。你可以直接过滤这些值,并在样本网格中一次查看一个聚类:

13

更有趣的是,我们在嵌入图中用这些集群标签着色:

14

通过可视化聚类,你可以检查聚类例程是否正确,还可以直观地了解数据结构。在这个例子中,我们可以看到一个泰迪熊聚类,它与数据的其他部分分离得相当好。这个聚类例程还发现了农场动物与大象和斑马等外来动物之间的界限。

现在,创建一个新的聚类运行,将聚类数量增加到 30 个(别忘了在这个新字段中给嵌入着色)。根据随机性(所有例程的初始化都是随机的),大象和斑马现在很有可能占据它们自己的聚类。

回到初始聚类集,让我们来研究嵌入图中的最后一个区域。请注意,有几张踢足球的图片被归入了一个主要由网球图片组成的聚类中。这是因为我们在聚类过程中传递的是二维降维向量,而不是嵌入向量本身。虽然二维投影有助于可视化,UMAP 等技术也能很好地保留结构,但相对距离并没有完全保留,因此会丢失一些信息。

假设我们将 CLIP 内嵌直接输入聚类计算,并使用相同的超参数。在这种情况下,这些足球图像就会与其他足球图像以及飞盘和棒球等其他野外运动图像被分配到同一个聚类中。

15

关键的启示是,高维特征并不比低维特征好,反之亦然。每一种选择都需要权衡利弊。这就是为什么你应该尝试不同的技术、超参数和特征。

为了更清楚地说明这一点,我们使用 HDBSCAN 作为聚类算法,它不允许我们指定聚类的数量,取而代之的是 min_cluster_size 和 max_cluster_size 等参数,以及合并聚类的标准。我们将使用 CLIP 嵌入作为特征,作为一个粗略的起点,我们只希望聚类的元素数在 10 到 300 之间。如果聚类太大,可能没有帮助;如果聚类太小,可能会捕捉到噪音而不是信号。当然,具体数值取决于数据集!

当我们根据聚类标签着色时,结果看起来有点乱。不过,当我们单独查看每个聚类的图像时,就会发现我们在数据集中识别出了一些非常有趣的样本集合。

16

对于 HDBSCAN,所有背景图像的标签均为"-1"。这些图像不会合并到任何最终聚类中。

跟踪聚类运行

在测试特征、聚类技术和超参数的各种组合时,你可能会想记录下生成特定聚类所使用的 "配置"。幸运的是,FiftyOne 聚类插件可以使用自定义运行为你处理所有这些问题。该插件提供了一个操作符 get_clustering_run_info,让你可以通过 run_key 选择一个运行,并在应用程序中查看该运行的所有参数的格式化打印输出:

17

你也可以通过将 run_key 传递给数据集的 get_run_info()方法,以编程方式访问该信息!

用 GPT-4V 标记集群

到目前为止,我们的聚类只有数字,这只是一种美化的内务管理工具。但是,如果我们针对数据集中的某些特定特征进行聚类,我们应该能够识别出这些特征,并用它们来松散地标记我们的样本。天真地说,我们可以逐个查看我们的聚类,只选择特定聚类中的图像并将其可视化,然后尝试自己标记聚类。

或者......我们可以使用多模态大型语言模型来完成这项工作!FiftyOne 聚类插件提供了这一功能,它利用 GPT-4V 的多模态理解能力为每个聚类贴上概念标签。

要使用此功能,你必须拥有 OpenAI API 密钥环境变量(必要时创建账户),设置方法如下:

export OPENAI_API_KEY=sk-...

该功能通过标签簇(label_clusters_with_gpt4v)操作符提供,操作符会从每个簇中随机选取五幅图像,将它们输入 GPT-4V 并给出特定任务提示,然后处理结果。

根据集群的数量(GPT-4V 的速度可能较慢,这与集群数量成线性关系),你可能需要委托执行操作,方法是选中操作员模式对话框中的复选框,然后从命令行启动任务:

fiftyone delegated launch

17

结论

在本文中,我们介绍了如何使用 scikit-learn 和 FiftyOne 将深度神经网络与流行的聚类算法相结合,为非结构化数据提供结构。在这一过程中,我们看到了特征向量、算法和超参数的选择会对聚类计算的最终结果产生很大影响,无论是聚类选择的内容还是聚类识别数据结构的效果。

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

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

相关文章

海洋信息管理系统:守护蓝色星球,促进海洋经济新发展

海洋,覆盖地球表面超过七成的广阔水域,是生命之源,也是经济发展的重要空间。然而,随着人类活动的增加,海洋生态环境面临严峻挑战,海洋资源的可持续利用成为全球关注的焦点。在这样的背景下,构建…

数字IC/FPGA——亚稳态及跨时钟域

什么是亚稳态亚稳态会造成什么平均故障间隔时间如何解决亚稳态同步时钟和异步时钟单bit电平信号如何跨时钟域单bit脉冲信号如何跨时钟域多bit信号如何跨时钟域 目录 一、亚稳态1.基本概念2.危害3.平均故障时间4.解决亚稳态的方法 二、跨时钟域1.同步电路和异步电路(…

RNN知识体系构筑:详尽阐述其理论基础、技术架构及其在处理序列数据挑战中的创新应用

一、为什么需要RNN 尽管神经网络被视为一种强大且理论上能够近似任何连续函数的模型,尤其当训练数据充足时,它们能够在输入空间中的某个点( x )映射到输出空间的特定值( y ),然而,这并不能完全解释为何在众多应用场景中&#xff…

牛客2024【牛客赛文X】春招冲刺ONT61 每日温度【hard 单调栈 Java、Go、PHP】

题目 题目链接: https://www.nowcoder.com/practice/1f54e163e6944cc7b8759cc09e9c78d8 思路 单调栈最直接的应用就是获取数组中每个位置i,i的左边第一个比i大或者小的位置/数以及,i的右边第一个比i大或者小的位置/数不懂的同学看这里https://blog.csdn.net/Borsl…

String类中常见面试题

1.string类属于基本类型吗? string类不是基本类型;它属于引用数据类型 2.操作字符串的类有哪些?有什么区别? 有三种:string,stringBuilder,stringBuffer 区别: String:不可变类,字符串一旦被创建就不能…

Unity打包出来的apk安装时提示应用程式与手机不兼容,无法安装应用程式

1、遇到的问题 * 2、解决办法 这是因为你在Unity中导出来的apk手机安装包是32位的,才导致上述问题发生,要解决这个办法,需要在Unity中导出64位的手机安装包。 32位跟64位的区别,以及如何区分打出来的手机安装包是否是32位或者是…

腐蚀Rust 服务端搭建架设个人社区服务器Windows教程

腐蚀Rust 服务端搭建架设个人社区服务器Windows教程 大家好我是艾西,一个做服务器租用的网络架构师也是游戏热爱者。最近在steam发现rust腐蚀自建的服务器以及玩家还是非常多的,那么作为服务器供应商对这商机肯定是不会放过的哈哈哈! 艾西这…

Day:004(4) | Python爬虫:高效数据抓取的编程技术(数据解析)

XPath工具 浏览器-元素-CtrlF 浏览器-控制台- $x(表达式) Xpath helper (安装包需要科学上网) 问题 使用离线安装包 出现 程序包无效 解决方案 使用修改安装包的后缀名为 rar,解压文件到一个文件夹,再用 加载文件夹的方式安装即可 安装 python若使用…

2024年认证杯SPSSPRO杯数学建模D题(第一阶段)AI绘画带来的挑战全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 D题 AI绘画带来的挑战 原题再现: 2023 年开年,ChatGPT 作为一款聊天型 AI 工具,成为了超越疫情的热门词条;而在 AI 的另一个分支——绘图领域,一款名为 Midjourney(MJ&…

2024年认证杯数学建模挑战赛C题全解析

2024年认证杯C题的已经完成啦,包括参考论文,模型代码,分享给大家~ 问题分析 对于这些问题,我们首先需要确定影响日光辐射降低效应的关键参数,例如海盐气溶胶的浓度、粒子大小、分布以及喷洒高度和范围。同…

再写-全景拼接

全景拼接 1. 将读取进行灰度转化,并且输出图像,关键点和计算描述 import cv2 import numpy as np# 将读取进行灰度转化,并且输出图像,关键点和计算描述 image_left cv2.imread("C:\\Users\\HONOR\\Desktop\\image\\pinjie…

机器人坐标系转换之从世界坐标系到局部坐标系

三角函数实现 下面是代码c和python实现&#xff1a; #include <iostream> #include <cmath>struct Point {double x;double y; };class RobotCoordinateTransform { private:Point origin; // 局部坐标系的原点在世界坐标系中的坐标public:RobotCoordinateTransfo…

【深度学习】图像风格混合——StyleGAN2原理解析

1、前言 上一篇文章&#xff0c;我们详细讲解了StyleGAN的原理。这篇文章&#xff0c;我们就来讲解一下StyleGAN2&#xff0c;也就是StyleGAN的改进版。 原论文&#xff1a;Analyzing and Improving the Image Quality of StyleGAN 参考代码&#xff1a;①Pytorch版本&#…

【Godot4.2】CanvasItem绘图函数全解析 - 7.自定义节点TextBoard

概述 之前发布的几篇文章几乎阐述了CanvasItem绘图函数最基础的内容。 本篇结合draw_style_box()和TextParagraph类&#xff0c;自定义了一个可以自适应宽高显示多行文本&#xff0c;且带有一个样式盒作为背景的文字板节点TextBoard。 系列目录 0.概述1.绘制简单图形2.设定绘…

SPP论文笔记

这篇论文讨论了在深度卷积网络中引入空间金字塔池化&#xff08;SPP&#xff09;层的方法&#xff0c;以解决传统深度卷积网络需要固定图像尺寸的限制。以下是论文各部分的总结&#xff1a; 1. 引言 论文指出现有的深度卷积神经网络&#xff08;CNN&#xff09;需要固定大小的…

全景剖析SSD SLC Cache缓存设计原理-2

四、SLC缓存对SSD的寿命是否有优化&#xff1f; 当使用QLC或TLC NAND闪存并将其切换到SLC模式进行写入时&#xff0c;会对闪存的寿命产生以下影响&#xff1a; 短期寿命提升&#xff1a; SLC模式下&#xff0c;每个存储单元仅存储一个比特数据&#xff0c;相对于QLC或TLC来说…

前端vue: 使用ElementUI适配国际化

i18n介绍 i18n&#xff08;其来源是英文单词 internationalization的首末字符i和n&#xff0c;18为中间的字符数&#xff09;是“国际化”的简称。 前端国际化步骤 1、安装i18n插件 安装插件时候&#xff0c;注意必须指定版本号&#xff0c;不然安装会报错。 npm i vue-i1…

linux 部署安装mongodb教程

现在去官网下载mongodb的tar包,在本地创建文件夹 cd /home wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.2.17.tgz tar -zxvf mongodb-linux-x86_64-rhel70-4.2.17.tgz mv mongodb-linux-x86_64-rhel70-4.2.17 mongodb cd /home/mongodb mkdir log t…

GAN:对抗式生成网络之图片生成

对抗式生成网络(Adversarial Generative Network, AGN)这一术语在您提供的信息中并未直接出现。通常,在深度学习文献和实践中,与“对抗”和“生成”概念相结合的网络架构指的是生成式对抗网络(Generative Adversarial Networks, GANs)。GANs由Ian Goodfellow等人于2014年…

数据结构之单链表相关刷题

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构 数据结构之单链表的相关知识点及应用-CSDN博客 下面题目基于上面这篇文章&#xff1a; 下面有任何不懂的地方欢迎在评论区留言或…