拓冰建站拓冰建站
首页 / 资讯中心 / 正文

FiftyOne 相似度搜索实战指南:用 compute_similarity 与 sort_by_similarity 构建图像、对象与文本语义检索

FiftyOne 相似度搜索实战指南用 compute_similarity 与 sort_by_similarity 构建图像、对象与文本语义检索【免费下载链接】fiftyoneRefine high-quality datasets and visual AI models项目地址: https://gitcode.com/GitHub_Trending/fi/fiftyoneFiftyOne Brain 提供的compute_similarity()方法让你能够以极低门槛为数据集中的图像或对象补丁建立相似度索引随后通过sort_by_similarity()视图阶段对数据集按与任意查询的相似度排序。本文以官方用户指南 similarity.rst 为骨架结合仓库源码系统讲解索引的建立、十余种后端的选择与配置、图像/对象/文本三种查询方式以及索引的增删改查全生命周期管理读完即可在你的数据集上落地一套完整的相似度检索方案。相似度搜索的工作原理FiftyOne Brain 的相似度搜索基于深度嵌入deep embeddings实现与 embeddings 可视化 类似系统先为数据集中的每个样本图像或对象补丁生成一个特征向量再将这些向量存入向量索引查询时计算查询向量与索引向量的相似度并返回排序结果。整套机制围绕两个核心 API 展开compute_similarity()为数据集建立相似度索引是索引的创建者sort_by_similarity()以视图阶段view stage形式对数据集排序是索引的消费者。sort_by_similarity()的完整签名如下见 collections.pydef sort_by_similarity( self, query, kNone, reverseFalse, dist_fieldNone, brain_keyNone ):各参数含义参数说明query查询对象支持三种形式样本/对象的 ID 或 ID 列表、num_dims维向量或num_queries x num_dims向量数组、文本 prompt 或 prompt 列表需索引支持k返回的匹配数量默认对整个集合排序reverse是否按最不相似排序True默认False按最相似排序部分后端不支持该选项dist_field一个 float 字段名用于存储每个样本到查询的距离字段不存在时会自动创建brain_key已存在的compute_similarityrun 的 brain key不指定时数据集必须存在可用的默认 run该方法的实现实质是把参数包装成SortBySimilarity视图阶段见 stages.py在底层它会对查询做解析并区分ID 查询 / 向量查询 / prompt 查询三种模式因此你可以直接用 ID、手工算出的向量甚至一段自然语言作为query。Embedding 方法索引的数据来源compute_similarity()的embeddings与model参数提供了四种生成嵌入的方式按使用场景选择不提供任何参数系统使用默认的通用模型为数据建立索引默认模型为mobilenet-v2-imagenet-torch提供模型传入一个Model实例或 Model Zoo 中任意支持嵌入输出的模型名称如clip-vit-base32-torch提供预计算嵌入以数组形式直接传入你自己算好的嵌入提供字段名传入数据集内用于存放预计算嵌入的VectorField或ArrayField字段名。提示相似度索引同样支持自然语言搜索前提是索引由支持 prompt 的模型如 CLIP驱动详见下文文本相似度小节。相似度后端从 sklearn 到外部向量数据库默认情况下所有相似度索引都由内置的 scikit-learn 后端提供服务无需额外部署任何服务。你也可以通过compute_similarity()的backend参数切换到其他后端后端说明sklearn默认基于 scikit-learn 的本地后端开箱即用qdrantQdrant 向量数据库后端redisRedis 后端pineconePinecone 后端mongodbMongoDB 后端elasticsearchElasticsearch 后端pgvectorPostgreSQL Pgvector 后端mosaicDatabricks Mosaic AI 后端milvusMilvus 后端lancedbLanceDB 后端切换后端的最小示例import fiftyone.brain as fob results fob.compute_similarity( dataset, backendsklearn, # sklearn, qdrant, redis, etc brain_key..., ... )从源码结构看每个后端都有独立的*SimilarityConfig配置类与*SimilarityIndex实现类位于fiftyone.brain.internal.core.*模块例如 sklearn 后端对应 v0_20_0.py 迁移脚本中记录的fiftyone.brain.internal.core.sklearn.SklearnSimilarityConfig与SklearnSimilarityIndex。这些类实现了统一的索引读写接口因此切换后端不需要改动上层查询代码。各后端的独立集成指南见 docs/source/integrations/ 目录。图像相似度完整工作流本节演示图像相似度的基本流程为图像数据集建立索引、在 App 中通过界面按视觉相似度查询、以及用 SDK 程序化查询索引。建立索引并在 App 中查询把感兴趣的Dataset或DatasetView传给compute_similarity()同时通过brain_key为索引命名import fiftyone as fo import fiftyone.brain as fob import fiftyone.zoo as foz dataset foz.load_zoo_dataset(quickstart) # Index images by similarity fob.compute_similarity( dataset, modelclip-vit-base32-torch, brain_keyimg_sim, ) session fo.launch_app(dataset)在 App 中加载数据集后选中一张或多张图像——只要网格上方出现了相似度图标即可点击它按与当前选中的相似度排序。对于更高级的搜索选项、运行管理与搜索历史可以使用Similarity Search 面板。上例指定了 Model Zoo 中的模型来生成嵌入你也可以改用预计算嵌入见下文Similarity API。用 SDK 程序化查询不打开 App直接用sort_by_similarity()视图阶段构造包含排序结果的视图# Choose a random image from the dataset query_id dataset.take(1).first().id # Programmatically construct a view containing the 15 most similar images view dataset.sort_by_similarity(query_id, k15, brain_keyimg_sim) session.view view两个重要注意事项在 DatasetView 上搜索只会返回该视图内的结果如果视图包含未进入索引的样本它们永远不会出现在结果中。这意味着你可以只对完整Dataset建立一次索引然后通过构造视图在任意子集上反复搜索。首次加载较慢之后有缓存对大型数据集第一次在会话中使用某个相似度索引时加载时间较长后续搜索会使用缓存结果速度明显提升。对象相似度检索对象补丁对象相似度面向的是数据集中的对象补丁patches。凡是存储在Detection、Detections、Polyline或Polylines格式中的对象都可以被索引。建立对象索引并在 App 中查询与图像索引几乎一致只是额外传入patches_field指定对象所在的标签字段import fiftyone as fo import fiftyone.brain as fob import fiftyone.zoo as foz dataset foz.load_zoo_dataset(quickstart) # Index ground truth objects by similarity fob.compute_similarity( dataset, patches_fieldground_truth, modelclip-vit-base32-torch, brain_keygt_sim, ) session fo.launch_app(dataset)在 App 中点击网格上方的补丁图标并选择感兴趣的标签字段切换到对象补丁视图object patches view选中一个或多个补丁后相似度图标会出现点击即可按与当前选中补丁的相似度排序。同样可以使用Similarity Search 面板进行高级搜索。用 SDK 程序化查询对象程序化查询时先把数据集转换为 patches 视图再取一个 patch 的 ID 作为查询# Convert to patches view patches dataset.to_patches(ground_truth) # Choose a random patch object from the dataset query_id patches.take(1).first().id # Programmatically construct a view containing the 15 most similar objects view patches.sort_by_similarity(query_id, k15, brain_keygt_sim) session.view view对象相似度的两条注意事项与图像相似度相同在视图上搜索只返回视图内结果大型数据集首次加载较慢、后续有缓存。文本相似度用自然语言检索数据当你使用 CLIP 模型clip-vit-base32-torch建立相似度索引时可以直接在 App 中用任意自然语言查询进行搜索包括通过Similarity Search 面板。该能力自 OSS 0.20.0 / Enterprise 1.2 起提供。建立支持文本查询的索引图像与对象索引的建立方式与前面完全一致只需指定 CLIP 模型import fiftyone as fo import fiftyone.brain as fob import fiftyone.zoo as foz dataset foz.load_zoo_dataset(quickstart) # Index images by similarity image_index fob.compute_similarity( dataset, modelclip-vit-base32-torch, brain_keyimg_sim, ) session fo.launch_app(dataset)可以通过supports_prompts属性验证索引是否支持文本查询# If you have already loaded the index print(image_index.config.supports_prompts) # True # Without loading the index info dataset.get_brain_info(img_sim) print(info.config.supports_prompts) # True对象索引同理只需把patches_fieldground_truth一并传入brain_key 改为gt_sim验证方式完全相同。用 SDK 执行文本查询直接在sort_by_similarity()中传入 prompt 字符串即可# Perform a text query query kites high in the air view dataset.sort_by_similarity(query, k15, brain_keyimg_sim) session.view view对象文本查询需要先转换为 patches 视图# Convert to patches view patches dataset.to_patches(ground_truth) # Perform a text query query cute puppies view patches.sort_by_similarity(query, k15, brain_keygt_sim) session.view view文本查询的三条关键约束任何实现PromptMixin接口的模型都可以支持文本查询不只是 CLIP凡是通过 Model Zoo 接口docs/source/model_zoo/提供且实现了fiftyone.core.models.PromptMixin的自定义模型都能支持文本相似度查询。必须传模型名称而非模型实例想要支持文本查询的索引在创建时必须传模型的名称字符串。用Model实例创建的索引无法在之后重新加载该模型因此其文本查询在 App 中和后续 Python 会话中都无法工作# Text queries work in the App and in future sessions fob.compute_similarity( dataset, modelclip-vit-base32-torch, brain_keysim ) # Text queries work only in the current session model foz.load_zoo_model(clip-vit-base32-torch) fob.compute_similarity(dataset, modelmodel, brain_keysim)预计算嵌入 模型名称可以兼得你可以同时提供预计算的embeddings和model名称这样你自己生成的嵌入也能保留文本查询能力fob.compute_similarity( dataset, embeddingsembeddings, # precomputed modelclip-vit-base32-torch, brain_keysim, )这是对无法由模型直接作用于样本媒体而生成嵌入的数据例如媒体类型不属于Model声明的image或video的数据所支持的标准路径。Similarity API索引的完整生命周期本节详细说明如何设置、创建与管理相似度索引。切换相似度后端三种粒度逐级递进1. 单次索引指定后端通过backend参数index fob.compute_similarity(..., backendbackend, ...)2. 整个会话生效设置环境变量FIFTYONE_BRAIN_DEFAULT_SIMILARITY_BACKENDexport FIFTYONE_BRAIN_DEFAULT_SIMILARITY_BACKENDbackend3. 永久修改默认后端更新 brain 配置文件~/.fiftyone/brain_config.json中的default_similarity_backend键{ default_similarity_backend: backend, similarity_backends: { backend: {...}, ... } }配置后端参数每个后端都有专属的配置类均继承自统一的SimilarityConfig查看对应类的参数即可了解可配置项。内置后端的配置类分别是sklearn:fiftyone.brain.internal.core.sklearn.SklearnSimilarityConfigqdrant:fiftyone.brain.internal.core.qdrant.QdrantSimilarityConfigredis:fiftyone.brain.internal.core.redis.RedisSimilarityConfigpinecone:fiftyone.brain.internal.core.pinecone.PineconeSimilarityConfigmongodb:fiftyone.brain.internal.core.mongodb.MongoDBSimilarityConfigelasticsearch:fiftyone.brain.internal.core.elasticsearch.ElasticsearchSimilarityConfigpgvector:fiftyone.brain.internal.core.pgvector.PgVectorSimilarityConfigmosaic:fiftyone.brain.internal.core.mosaic.MosaicSimilarityConfigmilvus:fiftyone.brain.internal.core.milvus.MilvusSimilarityConfiglancedb:fiftyone.brain.internal.core.lancedb.LanceDBSimilarityConfig配置参数既可以在每次调用compute_similarity()时作为关键字参数传入临时生效index fob.compute_similarity( ... backendqdrant, urlhttp://localhost:6333, )也可以通过 brain 配置永久指定。创建索引的多种语法compute_similarity()提供了多种初始化语法以下均在 quickstart 数据集上演示。默认行为不传任何额外参数系统自动用默认模型为所有图像/补丁计算嵌入并加入默认后端的新索引tmp_index fob.compute_similarity(dataset, brain_keytmp) print(tmp_index.config.method) # sklearn print(tmp_index.config.model) # mobilenet-v2-imagenet-torch print(tmp_index.total_index_size) # 200 dataset.delete_brain_run(tmp)对象版本只需指定patches_fieldquickstart 的ground_truth字段有 1232 个对象tmp_index fob.compute_similarity( dataset, patches_fieldground_truth, # field containing objects of interest brain_keytmp, ) print(tmp_index.config.method) # sklearn print(tmp_index.config.model) # mobilenet-v2-imagenet-torch print(tmp_index.total_index_size) # 1232 dataset.delete_brain_run(tmp)自定义模型 自定义后端 延后添加嵌入embeddingsFalse表示只创建索引骨架、暂不加入任何嵌入image_index fob.compute_similarity( dataset, modelclip-vit-base32-torch, # custom model embeddingsFalse, # add embeddings later backendsklearn, # custom backend brain_keyimg_sim, ) print(image_index.total_index_size) # 0对象版本同样只需加上patches_fieldground_truth。预计算嵌入先用模型算好嵌入再传入embeddings参数。图像版本model foz.load_zoo_model(clip-vit-base32-torch) embeddings dataset.compute_embeddings(model) tmp_index fob.compute_similarity( dataset, modelclip-vit-base32-torch, # store models name for future use embeddingsembeddings, # precomputed image embeddings brain_keytmp, ) print(tmp_index.total_index_size) # 200 dataset.delete_brain_run(tmp)对象版本改用compute_patch_embeddingsmodel foz.load_zoo_model(clip-vit-base32-torch) embeddings dataset.compute_patch_embeddings(model, ground_truth) tmp_index fob.compute_similarity( dataset, patches_fieldground_truth, # field containing objects of interest modelclip-vit-base32-torch, # store models name for future use embeddingsembeddings, # precomputed patch embeddings brain_keytmp, ) print(tmp_index.total_index_size) # 1232 dataset.delete_brain_run(tmp)向索引添加嵌入add_to_index()可以在任意时刻向索引添加新嵌入或覆盖已有嵌入。两种方式让索引用自身模型计算嵌入或手动计算后传入。图像索引image_index通过dataset.load_brain_results(img_sim)加载image_index dataset.load_brain_results(img_sim) print(image_index.total_index_size) # 0 view1 dataset[:100] view2 dataset[100:] # # Approach 1: use the index to compute embeddings for view1 # embeddings, sample_ids, _ image_index.compute_embeddings(view1) image_index.add_to_index(embeddings, sample_ids) print(image_index.total_index_size) # 100 # # Approach 2: manually compute embeddings for view2 # model image_index.get_model() # the indexs model embeddings view2.compute_embeddings(model) sample_ids view2.values(id) image_index.add_to_index(embeddings, sample_ids) print(image_index.total_index_size) # 200 # Must save after edits when using the sklearn backend image_index.save()对象索引添加嵌入时必须为每条嵌入提供 sample ID 和 label IDimport numpy as np object_index dataset.load_brain_results(gt_sim) print(object_index.total_index_size) # 0 view1 dataset[:100] view2 dataset[100:] # # Approach 1: use the index to compute embeddings for view1 # embeddings, sample_ids, label_ids object_index.compute_embeddings(view1) object_index.add_to_index(embeddings, sample_ids, label_idslabel_ids) print(object_index.total_index_size) # 471 # # Approach 2: manually compute embeddings for view2 # # Manually load the indexs model model object_index.get_model() # Compute patch embeddings _embeddings view2.compute_patch_embeddings(model, ground_truth) _label_ids dict(zip(*view2.values([id, ground_truth.detections.id]))) # Organize into correct format embeddings [] sample_ids [] label_ids [] for sample_id, patch_embeddings in _embeddings.items(): patch_ids _label_ids[sample_id] if not patch_ids: continue for embedding, label_id in zip(patch_embeddings, patch_ids): embeddings.append(embedding) sample_ids.append(sample_id) label_ids.append(label_id) object_index.add_to_index( np.stack(embeddings), np.array(sample_ids), label_idsnp.array(label_ids), ) print(object_index.total_index_size) # 1232 # Must save after edits when using the sklearn backend object_index.save()重要使用默认的sklearn后端时添加或移除嵌入后必须手动调用save()才能将索引写入数据库使用 Qdrant 等外部向量数据库时则不需要。提示创建索引时如果提供了 Model Zoo 模型名称之后可用get_model()加载该模型也可以用compute_embeddings()方便地用索引的模型为新样本/对象生成嵌入。从索引检索嵌入get_embeddings()可按任意 ID 集合从现有索引中取回嵌入。图像索引按 sample ID 检索ids dataset.take(50).values(id) embeddings, sample_ids, _ image_index.get_embeddings(sample_idsids) print(embeddings.shape) # (50, 512) print(sample_ids.shape) # (50,)对象索引可提供 sample ID 或 label ID 检索例如用filter_labels筛选出所有person标签对应的对象from fiftyone import ViewField as F ids ( dataset .filter_labels(ground_truth, F(label) person) .values(ground_truth.detections.id, unwindTrue) ) embeddings, sample_ids, label_ids object_index.get_embeddings(label_idsids) print(embeddings.shape) # (378, 512) print(sample_ids.shape) # (378,) print(label_ids.shape) # (378,)从索引移除嵌入remove_from_index()按 ID 删除嵌入。图像索引按 sample ID 删除ids dataset.take(50).values(id) image_index.remove_from_index(sample_idsids) print(image_index.total_index_size) # 150 # Must save after edits when using the sklearn backend image_index.save()对象索引可传 sample ID 或 label IDfrom fiftyone import ViewField as F ids ( dataset .filter_labels(ground_truth, F(label) person) .values(ground_truth.detections.id, unwindTrue) ) object_index.remove_from_index(label_idsids) print(object_index.total_index_size) # 854 # Must save after edits when using the sklearn backend object_index.save()与添加嵌入相同sklearn 后端需要手动save()外部向量数据库无需此步。删除索引对于 Qdrant 这类使用外部向量数据库的后端先调用cleanup()删除外部索引/集合再从数据集删除 run# First delete the index from the backend (if applicable) image_index.cleanup() # Now delete the index from your dataset dataset.delete_brain_run(img_sim)对象版本同理object_index.cleanup()后dataset.delete_brain_run(gt_sim)。注意对默认的 sklearn 后端调用cleanup()没有任何效果索引只有在调用delete_brain_run()时才会被真正删除。典型应用场景相似度搜索最常见的落地模式是从数据集中挖掘与某些关键图像/对象补丁相似的样本例如模型在特定图像上出现失败模式failure mode需要深入研究或某些类别样本不足需要补充训练数据。文档中列举的典型应用包括从训练数据集中剔除近似重复图像near-duplicate识别模型的失败模式在数据湖data lake中寻找目标场景的样本为评估流水线挖掘困难样本hard examples为数据不足的类别从数据湖推荐候选样本。源码定位与延伸阅读索引生命周期 APIcompute_similarity、add_to_index、get_embeddings、remove_from_index、cleanup、save等方法定义于fiftyone.brain.similarity模块的SimilarityIndex类查询入口sort_by_similarity()视图方法见 fiftyone/core/collections.py对应的SortBySimilarity视图阶段实现见 fiftyone/core/stages.py运行框架brain run 的统一存储、信息与配置基类BrainMethod、BrainMethodConfig、BrainInfo、BrainResults见 fiftyone/core/brain.pyrun 的管理逻辑见 fiftyone/core/runs.py后端迁移记录sklearn 后端配置类从旧路径迁移到fiftyone.brain.internal.core.sklearn的细节见 fiftyone/migrations/revisions/v0_20_0.py完整指南原文docs/source/user_guide/similarity.rst各外部后端Qdrant、Redis、Pinecone、MongoDB、Elasticsearch、Pgvector、Milvus、LanceDB 等的独立集成文档见 docs/source/integrations/可用模型清单见 docs/source/model_zoo/。如需在本地复现本文示例可先克隆仓库git clone https://gitcode.com/GitHub_Trending/fi/fiftyone安装后运行fiftyone quickstart获取 quickstart 数据集再按上文代码建立索引并启动 App 体验三种查询方式。【免费下载链接】fiftyoneRefine high-quality datasets and visual AI models项目地址: https://gitcode.com/GitHub_Trending/fi/fiftyone创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门