使用 Ultralytics Explorer API 深度探索 YOLO 数据集:语义搜索、SQL 查询与嵌入分析实战指南
【免费下载链接】yolov10YOLOv10: Real-Time End-to-End Object Detection [NeurIPS 2024]项目地址: https://gitcode.com/GitHub_Trending/yo/yolov10
本指南以 Ultralytics Explorer API 文档为主体,结合 yolov10 仓库中ultralytics/data/explorer/的源码实现,系统讲解如何在 YOLO 系列模型(检测 / 分割 / 姿态)数据集上使用语义相似度搜索、SQL 过滤、自然语言查询(Ask AI)与嵌入空间分析。读完本文,你将掌握Explorer类的完整 API 用法、底层嵌入表的存储原理(LanceDB 磁盘持久化),以及如何用相似度索引清洗与筛选训练数据。
一、Explorer API 是什么
Explorer API 是 Ultralytics 提供的一个 Python 数据集探索接口,面向计算机视觉(CV)数据集,提供以下三类核心能力:
- 向量相似度搜索:根据"图像嵌入(embedding)相近即语义相近"的思想,查找与给定图片或数据索引最相似的一批样本;
- SQL 查询:对嵌入表中的结构化元数据(类别标签、边界框、掩码、关键点等)执行 SQL 风格的过滤;
- 语义搜索 / 自然语言查询(Ask AI):用大白话描述过滤条件(例如"100 张恰好包含 1 个人和 2 条狗的图片"),由 LLM 自动翻译为 SQL 执行。
该 API 同时驱动了仓库内置的 GUI 探索工具(yolo explorer命令,详见 dash.py),你也可以基于它编写自己的 Jupyter Notebook 或脚本,产出数据集洞察报告。仓库还附带完整的交互式演示 explorer.ipynb,可供对照练习。
二、安装与依赖
Explorer 的部分功能依赖第三方库,这些库会在首次使用时自动安装。也可以手动安装全部可选依赖:
pip install ultralytics[explorer]从源码看,Explorer 的依赖被严格校验在 explorer.py 的构造函数中:
- lancedb >= 0.4.3:嵌入式向量数据库,负责嵌入表的持久化与向量检索;
- duckdb <= 0.9.2:SQL 查询引擎(源码注释明确提到
duckdb==0.10.0存在 bug,故锁定版本上限)。
此外,Ask AI 功能依赖openai >= 1.6.1(在 utils.py 的prompt_sql_query中动态校验),GUI 依赖streamlit >= 1.29.0与streamlit-select >= 0.3(见 dash.py)。
三、快速上手:核心工作流
Explorer 的使用分为三步:创建对象 → 构建嵌入表 → 执行查询。
from ultralytics import Explorer # 创建 Explorer 对象 explorer = Explorer(data='coco128.yaml', model='yolov8n.pt') # 为数据集创建嵌入表 explorer.create_embeddings_table() # 用图片路径搜索相似图片 dataframe = explorer.get_similar(img='path/to/image.jpg') # 或用数据集内的索引搜索 dataframe = explorer.get_similar(idx=0)3.1 关键参数说明(来自源码)
构造函数签名见 explorer.py:
| 参数 | 默认值 | 说明 |
|---|---|---|
data | coco128.yaml | 数据集配置文件,须位于 ultralytics/cfg/datasets/ 目录或可被check_det_dataset解析 |
model | yolov8n.pt | 用于生成嵌入的特征提取模型,支持检测 / 分割 / 姿态等各类 YOLO 模型 |
uri | 用户配置目录下的explorer文件夹 | LanceDB 数据库的存储位置,决定嵌入表落盘路径 |
嵌入表的命名规则为数据集配置名_小写 + "_" + 模型名_小写(源码 L67),例如coco128_yolov8n.pt。
3.2 嵌入表的构建与复用(重要机制)
create_embeddings_table(force=False, split='train')的行为如下(源码 L78-L128):
- 若同名表已存在且
force=False,直接复用,不重复计算(日志会提示Pass force=True to overwrite it); - 若
force=True,强制覆盖重建; - 首次构建时,遍历数据集(
split参数指定使用哪个划分,默认train),逐张图片用model.embed()提取特征,连同标签、边界框、掩码、关键点等元数据写入表。
LanceDB 采用磁盘持久化存储,因此即使 COCO 这样的大规模数据集,也不会因内存不足而失败;构建一次后即可反复复用。这正是"数据集 + 模型"配对只建一次表的官方设计意图。
3.3 嵌入是怎么来的
嵌入由 engine/model.py 的embed()方法生成,它是predict()的封装:默认提取模型倒数第二层(kwargs["embed"] = [len(self.model.model) - 2])的特征作为图片向量。也就是说,嵌入的语义质量与所选模型的表征能力直接相关,这也是 Explorer 允许为同一数据集搭配不同模型反复构建嵌入表的原因。
四、相似性搜索(Similarity Search)
相似性搜索基于"相似图片拥有相似嵌入"的假设。嵌入表构建完成后,可通过两种方式发起搜索:
- 按数据集索引:
exp.get_similar(idx=[1, 10], limit=10) - 按任意图片(可在数据集之外,支持 URL 或本地路径):
exp.get_similar(img=["path/to/img1", "path/to/img2"], limit=10)
传入多个输入时,会取其嵌入的均值作为查询向量(见 query 方法 L168-L171:torch.mean(torch.stack(embeds), 0)),相当于以"这批图片的共同语义"作为检索基准。
返回的是 pandas DataFrame,包含limit个最相似的数据点及其在嵌入空间中的距离,可在此基础上继续做二次过滤。
4.1 用图片搜索
from ultralytics import Explorer exp = Explorer(data='coco128.yaml', model='yolov8n.pt') exp.create_embeddings_table() # 单张图片搜索 similar = exp.get_similar(img='https://ultralytics.com/images/bus.jpg', limit=10) print(similar.head()) # 多张图片搜索(取均值) similar = exp.get_similar( img=['https://ultralytics.com/images/bus.jpg', 'https://ultralytics.com/images/bus.jpg'], limit=10 ) print(similar.head())4.2 用数据集索引搜索
from ultralytics import Explorer exp = Explorer(data='coco128.yaml', model='yolov8n.pt') exp.create_embeddings_table() similar = exp.get_similar(idx=1, limit=10) print(similar.head()) # 多个索引 similar = exp.get_similar(idx=[1, 10], limit=10) print(similar.head())get_similar的完整签名(源码 L244-L280):
img:图片路径 / URL 或路径列表(与idx二选一,源码_check_imgs_or_idxs会校验二者只能传其一,不能同时传、也不能都不传);idx:数据集内索引或索引列表;limit:返回结果条数,默认 25;return_type:'pandas'或'arrow',默认'pandas'。
4.3 绘制相似图片网格
plot_similar与get_similar参数一致,区别在于它会把相似结果渲染成网格图并返回 PIL.Image:
# 用图片 exp = Explorer(data='coco128.yaml', model='yolov8n.pt') exp.create_embeddings_table() plt = exp.plot_similar(img='https://ultralytics.com/images/bus.jpg', limit=10) plt.show() # 用索引 exp = Explorer(data='coco128.yaml', model='yolov8n.pt') exp.create_embeddings_table() plt = exp.plot_similar(idx=1, limit=10) plt.show()底层由 utils.py 的plot_query_result完成:按 640 边长做 LetterBox 缩放,并把边界框(bboxes)、掩码(masks)、关键点(kpts)等标注一并绘制到图上,便于直观对比候选样本的标注质量。
五、Ask AI:自然语言查询
Ask AI 允许用户用自然语言描述过滤条件,无需掌握 SQL。例如输入:"show me 100 images with exactly one person and 2 dogs. There can be other objects too",即可返回满足条件的图片。
from ultralytics import Explorer from ultralytics.data.explorer import plot_query_result exp = Explorer(data='coco128.yaml', model='yolov8n.pt') exp.create_embeddings_table() df = exp.ask_ai("show me 100 images with exactly one person and 2 dogs. There can be other objects too") print(df.head()) # 绘制结果 plt = plot_query_result(df) plt.show()5.1 实现原理与注意事项
从源码看(utils.py L112-L165),ask_ai的执行链路是:
prompt_sql_query(query)调用 OpenAI 的gpt-3.5-turbo模型,把嵌入表的字段 Schema(im_file、labels、cls、bboxes、masks、keypoints、vector)连同用户请求一起送入 System Prompt,要求 LLM 只输出一条SELECT * FROM 'table' WHERE ...形式的 SQL;ask_ai拿到生成的 SQL 后交给sql_query执行(explorer.py L431-L455);若生成的 SQL 非法,会打印错误日志并返回None。
因此 Ask AI 的结果是概率性的(官方文档明确提示),偶尔会出错,建议对结果做人工抽验。同时它依赖 OpenAI API:
- 需要配置 API Key,可通过
yolo settings openai_api_key="..."写入全局设置; - 未配置时,
prompt_sql_query会提示交互式输入 Key 并自动持久化到设置(utils.py L117-L120)。
六、SQL 查询
sql_query方法直接对嵌入表执行 SQL 风格查询,返回 pandas DataFrame(默认)或 pyarrow Table:
from ultralytics import Explorer exp = Explorer(data='coco128.yaml', model='yolov8n.pt') exp.create_embeddings_table() df = exp.sql_query("WHERE labels LIKE '%person%' AND labels LIKE '%dog%'") print(df.head())6.1 查询语法约定(源码强制校验)
见 sql_query 实现 L173-L217:
- 查询必须以
SELECT或WHERE开头,否则抛出ValueError; - 以
WHERE开头时,源码会自动补全为SELECT * FROM 'table' <你的 WHERE 子句>; - 查询引擎为 DuckDB,表结构即嵌入表 Schema,可直接使用
LIKE、ARRAY_LENGTH、FILTER等 DuckDB 支持的函数与数组操作。
6.2 绘制 SQL 查询结果
from ultralytics import Explorer exp = Explorer(data='coco128.yaml', model='yolov8n.pt') exp.create_embeddings_table() # 绘制 SQL 查询结果(网格图) exp.plot_sql_query("WHERE labels LIKE '%person%' AND labels LIKE '%dog%' LIMIT 10")plot_sql_query(query, labels=True)内部先以return_type='arrow'执行查询,再交给plot_query_result绘制;若结果为空,会打印No results found.并返回None(explorer.py L219-L242)。
6.3 嵌入表的字段 Schema
可查询的字段定义在 utils.py 的 get_table_schema L18-L31,随任务类型动态填充:
| 字段 | 类型 | 说明 |
|---|---|---|
im_file | string | 图片文件路径 |
labels | list<string> | 图片中所有目标的类别名(如'person'、'dog') |
cls | list<int> | 对应类别的整数 ID(与labels一一映射) |
bboxes | list<list<float>> | 各目标的边界框坐标 |
masks | list<list<list<int>>> | 分割掩码(仅分割模型) |
keypoints | list<list<list<float>>> | 姿态关键点(仅姿态模型) |
vector | 定长浮点向量 | 图片嵌入,维度由所选模型决定 |
这也是 Ask AI 的 System Prompt 中向 LLM 提供的完整表结构描述(utils.py L126-L159)。
七、高级:直接操作嵌入表
嵌入表一旦构建完成,可通过Explorer.table直接访问 LanceDB 表对象,执行原生查询、下推 pre/post 过滤等高级操作:
from ultralytics import Explorer exp = Explorer() exp.create_embeddings_table() table = exp.table提示:LanceDB 表同时支持
to_pandas()与to_arrow()两种结果形态,也支持 dict 转换,方便与现有数据分析流程衔接。
7.1 读取原始嵌入
from ultralytics import Explorer exp = Explorer() exp.create_embeddings_table() table = exp.table embeddings = table.to_pandas()["vector"] print(embeddings)7.2 带 pre / post 过滤的原生向量检索
可以直接用 LanceDB 的查询 API 做"向量检索 + 过滤 + 限量"的组合操作:
from ultralytics import Explorer exp = Explorer(model="yolov8n.pt") exp.create_embeddings_table() table = exp.table # 用一个 256 维的哑向量演示:指定余弦距离度量 + 空过滤条件 + 返回前 10 条 embedding = [i for i in range(256)] rs = table.search(embedding).metric("cosine").where("").limit(10)7.3 为大规模数据集创建向量索引
数据量大时,可为嵌入表建立专门的向量索引以加速查询,使用 LanceDB 表的create_index方法:
table.create_index(num_partitions=..., num_sub_vectors=...)num_partitions:划分的分区数;num_sub_vectors:每个向量的子向量数(PQ 量化相关)。
更完整的索引类型与参数说明可查阅 LanceDB 的 ANN 索引文档。仓库目前尚未在 Explorer API 层直接封装索引创建,需通过table对象调用(官方文档明确说明未来会加入 API 级支持)。
八、嵌入的应用:相似度索引与可视化
利用嵌入表可以做多种探索性分析。
8.1 相似度索引(Similarity Index)
similarity_index(max_dist=0.2, top_k=None, force=False)会估算每个数据点与数据集其余部分的相似程度:对每个图片,在嵌入空间中统计距离小于max_dist的邻居数量,每次最多考虑top_k个最近邻(源码 L315-L372)。
返回的 DataFrame 包含四列:
idx:图片在数据集中的索引;im_file:图片文件路径;count:与当前图片距离小于max_dist的图片数量;sim_im_files:这count张相似图片的路径列表。
参数校验规则(来自源码):top_k必须是0.0 ~ 1.0之间的小数(表示取最近邻的比例),max_dist必须非负。生成的结果表会以相似索引基名_thres_{max_dist}_top_{top_k}命名并持久化,同一(数据集, 模型, max_dist, top_k)组合只计算一次;数据集发生变化或需要重算时,传force=True即可。
from ultralytics import Explorer exp = Explorer() exp.create_embeddings_table() sim_idx = exp.similarity_index()典型应用:清洗离群样本。例如,过滤掉在数据集中找不到任何相似图片的"孤岛样本":
import numpy as np sim_count = np.array(sim_idx["count"]) sim_idx['im_file'][sim_count > 30]即只保留count > 30的图片,剔除那些与其余数据距离过远的异常样本。similarity_index还配套了plot_similarity_index方法,可一键绘制每张图片相似邻居数量的柱状图,直观定位分布(explorer.py L374-L416)。
8.2 可视化嵌入空间
可以借助任意绘图工具把高维嵌入降到低维后观察数据分布。下面是用 PCA 降到 3 维、再用 matplotlib 绘制 3D 散点图的示例:
import numpy as np from sklearn.decomposition import PCA import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # 用 PCA 将嵌入降到 3 维,便于 3D 可视化 pca = PCA(n_components=3) reduced_data = pca.fit_transform(embeddings) fig = plt.figure(figsize=(8, 6)) ax = fig.add_subplot(111, projection='3d') ax.scatter(reduced_data[:, 0], reduced_data[:, 1], reduced_data[:, 2], alpha=0.5) ax.set_title('3D Scatter Plot of Reduced 256-Dimensional Data (PCA)') ax.set_xlabel('Component 1') ax.set_ylabel('Component 2') ax.set_zlabel('Component 3') plt.show()这类降维可视化常用于:发现类别重叠、检查标注噪声、判断不同子集的分布差异,进而指导数据增补策略。
九、CLI 与 GUI:yolo explorer
Explorer API 也是仓库 GUI 探索工具的后端。在终端执行:
yolo explorer该命令由 cfg/init.py 的 handle_explorer L412-L416 实现,本质是streamlit run ultralytics/data/explorer/gui/dash.py,随后在浏览器中打开交互界面,可完成:选择数据集与模型、创建嵌入表(带进度条,见 dash.py 的 _get_explorer)、相似图片搜索、SQL 查询与语义搜索。
注意:GUI 中的 Ask AI 同样依赖 OpenAI,首次使用会被提示设置 API Key:
yolo settings openai_api_key="..."GUI 的完整使用说明见 docs/en/datasets/explorer/index.md。
十、多任务支持与测试验证
仓库测试 tests/test_explorer.py 对 Explorer 覆盖了四种任务场景,可直接作为 API 用法的权威示例:
test_similarity:默认数据集 + 模型下验证get_similar(索引 / 图片 / 多索引)返回条数、similarity_index与sql_query可用性;test_det(检测):data="coco8.yaml", model="yolov8n.pt",断言嵌入表含bboxes,plot_similar返回 PIL.Image;test_seg(分割):data="coco8-seg.yaml", model="yolov8n-seg.pt",断言表含masks;test_pose(姿态):data="coco8-pose.yaml", model="yolov8n-pose.pt",断言表含keypoints。
由此可见,Explorer 天然支持检测、分割、姿态三类任务,create_embeddings_table(force=True)在测试中被用于强制重建,验证了force参数的语义。对应数据集配置均位于 ultralytics/cfg/datasets/(如coco8.yaml、coco8-seg.yaml、coco8-pose.yaml)。
十一、官方规划中的功能
官方文档的 "Coming Soon" 部分列出了 Explorer 后续计划支持的能力,可据此规划自己的数据集工作流:
- 合并不同数据集的指定类别标签,例如把 COCO 的所有
person标签与 Cityscapes 的car标签导入同一数据集; - 按相似度阈值自动移除图片,即删除相似度指数高于给定阈值的样本;
- 合并 / 移除条目后自动持久化新数据集;
- 更高级的数据集可视化能力。
总结
Explorer API 为 YOLO 生态提供了开箱即用的数据集探索方案:create_embeddings_table构建 LanceDB 持久化嵌入表,get_similar/plot_similar完成向量相似检索,sql_query/plot_sql_query提供结构化过滤,ask_ai将自然语言翻译为 SQL,similarity_index支持离群样本清洗,而Explorer.table则把底层数据库完全开放给高级用户。无论你是要做训练前的数据质量审计、构建难例挖掘流水线,还是生成数据集洞察报告,都可以直接基于本仓库的 explorer.py 与配套测试示例快速落地。
【免费下载链接】yolov10YOLOv10: Real-Time End-to-End Object Detection [NeurIPS 2024]项目地址: https://gitcode.com/GitHub_Trending/yo/yolov10
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考