
FiftyOne 与 Lightning Flash 集成实战在 FiftyOne 数据集上训练、推理与嵌入可视化【免费下载链接】fiftyoneRefine high-quality datasets and visual AI models项目地址: https://gitcode.com/GitHub_Trending/fi/fiftyoneFiftyOne 与 PyTorch Lightning 团队合作提供了 Lightning Flash 集成让开发者能够在自己的 FiftyOne 数据集上直接训练或微调 Flash 任务模型并将模型预测结果写回数据集用于可视化与分析——全程仅需几行代码。读完本文你将掌握 Flash 的安装配置、五种受支持任务的训练与微调流程、三种在 FiftyOne 数据集上生成预测的模式以及利用 Flash 图像嵌入器结合 FiftyOne 的降维与可视化能力开展聚类分析和相似性检索的完整方案。集成概览与受支持的 Flash 任务Lightning Flash 是 PyTorch Lightning 生态中面向快速实验的高层框架提供开箱即用的计算机视觉任务模型。FiftyOne 为以下 Flash 任务提供了原生支持图像分类Image classification目标检测Object detection语义分割Semantic segmentation视频分类Video classification图像嵌入Image embeddings当 Flash 后续新增其他计算机视觉任务时FiftyOne 也会通过该集成持续提供原生支持。集成实现的调用链可从 fiftyone/utils/flash.py 查看其中_SUPPORTED_MODELS与_MODEL_TO_DATAMODULE_MAP明确列出了受支持的任务类型与对应 DataModule 的映射关系ImageClassifier→ImageClassificationData、ObjectDetector→ObjectDetectionData、SemanticSegmentation→SemanticSegmentationData、VideoClassifier→VideoClassificationData。环境准备安装 Flash 与依赖包使用该集成前需要先安装 Lightning Flash 及其配套的 PyTorch Lightning# 该集成当前对以下版本有显式要求 pip install lightning-flash0.7.0dev pip install pytorch-lightning根据你要使用的 Flash 任务类型还需要安装对应的 extras# 图像类任务所需 pip install lightning-flash[image] # 视频类任务所需 pip install lightning-flash[video]即使暂时不安装这些 extras 也可以继续推进当你用到依赖它们的特性时FiftyOne 会提示你安装相应的 extras。在 fiftyone/utils/flash.py 的模块顶部fou.ensure_import(flash0.7dev)会在导入时校验 Flash 版本是否满足要求。在 FiftyOne 数据集上训练与微调 Flash 模型借助 Flash 为每个任务内置的DataModule.from_fiftyone()方法你可以用几行代码直接在 FiftyOne 数据集上训练或微调 Flash 任务模型。总体流程为加载数据集 → 划分 splits → 创建 DataModule → 构建模型 → 创建 Trainer → 微调 → 保存 checkpoint → 推理并写回预测 → 在 App 中分析。图像分类以下示例在带Classification标注的 FiftyOne 数据集以 CIFAR-10 为例上微调一个 Flash 图像分类任务from itertools import chain from flash.core.classification import FiftyOneLabelsOutput from flash.image import ImageClassificationData, ImageClassifier from flash import Trainer import fiftyone as fo import fiftyone.utils.random as four import fiftyone.zoo as foz # 1 加载你的 FiftyOne 数据集 dataset foz.load_zoo_dataset( cifar10, splittest, max_samples300 ) dataset.untag_samples(test) # 从数据集中创建 splits splits {train: 0.7, test: 0.1, val: 0.1, pred: 0.1} four.random_split(dataset, splits) # 这里使用同一个数据集的不同视图你也可以为每个 split 使用不同的数据集 train_dataset dataset.match_tags(train) test_dataset dataset.match_tags(test) val_dataset dataset.match_tags(val) predict_dataset dataset.match_tags(pred) # 2 创建 DataModule datamodule ImageClassificationData.from_fiftyone( train_datasettrain_dataset, test_datasettest_dataset, val_datasetval_dataset, predict_datasetpredict_dataset, label_fieldground_truth, batch_size4, num_workers4, ) # 3 构建模型 model ImageClassifier( backboneresnet18, labelsdatamodule.labels, ) # 4 创建 trainer trainer Trainer( max_epochs1, limit_train_batches10, limit_val_batches10, ) # 5 微调模型 trainer.finetune(model, datamoduledatamodule) # 6 保存模型 trainer.save_checkpoint(/tmp/image_classification_model.pt) # 7 生成预测 predictions trainer.predict( model, datamoduledatamodule, outputFiftyOneLabelsOutput(labelsdatamodule.labels), ) predictions list(chain.from_iterable(predictions)) # 展平批次 # 将 filepath 映射到预测结果 predictions {p[filepath]: p[predictions] for p in predictions} # 将预测结果写入 FiftyOne 数据集 predict_dataset.set_values( flash_predictions, predictions, key_fieldfilepath, ) # 8 在 App 中分析预测结果 session fo.launch_app(predict_dataset)要点说明fiftyone.utils.random.random_split用于按比例给样本打标签train/test/val/pred之后用match_tags得到对应的数据集视图label_field指定存放 ground truth 标注的字段Flash 会自动从 FiftyOne 样本中提取标注ImageClassifier(labelsdatamodule.labels)将 DataModule 解析出的类别列表直接注入模型保证训练与推理的类别空间一致trainer.finetune默认使用迁移学习进行微调训练结束后用FiftyOneLabelsOutput让预测以 FiftyOne 标签对象形式返回再通过set_values(..., key_fieldfilepath)按文件路径写回。目标检测以下示例在带Detections标注的数据集以 COCO-2017 的 person 子集为例上微调一个 Flash 目标检测任务from itertools import chain from flash import Trainer from flash.image import ObjectDetectionData, ObjectDetector from flash.image.detection.output import FiftyOneDetectionLabelsOutput import fiftyone as fo import fiftyone.utils.random as four import fiftyone.zoo as foz # 1 加载你的 FiftyOne 数据集 dataset foz.load_zoo_dataset( coco-2017, splitvalidation, max_samples100, classes[person], ) # 从数据集中创建 splits splits {train: 0.7, test: 0.1, val: 0.1} four.random_split(dataset, splits) # 这里使用同一个数据集的不同视图你也可以为每个 split 使用不同的数据集 train_dataset dataset.match_tags(train) test_dataset dataset.match_tags(test) val_dataset dataset.match_tags(val) predict_dataset train_dataset.take(5) # 移除背景类DataModule 会自动添加 dataset.default_classes.pop(0) # 2 创建 DataModule datamodule ObjectDetectionData.from_fiftyone( train_datasettrain_dataset, test_datasettest_dataset, val_datasetval_dataset, predict_datasetpredict_dataset, label_fieldground_truth, transform_kwargs{image_size: 512}, batch_size4, ) # 3 构建模型 model ObjectDetector( headefficientdet, backboned0, num_classesdatamodule.num_classes, image_size512, ) # 4 创建 trainer trainer Trainer(max_epochs1, limit_train_batches10) # 5 微调模型 trainer.finetune(model, datamoduledatamodule, strategyfreeze) # 6 保存模型 trainer.save_checkpoint(/tmp/object_detection_model.pt) # 7 生成预测 predictions trainer.predict( model, datamoduledatamodule, outputFiftyOneDetectionLabelsOutput(labelsdatamodule.labels), ) predictions list(chain.from_iterable(predictions)) # 展平批次 # 将 filepath 映射到预测结果 predictions {p[filepath]: p[predictions] for p in predictions} # 将预测结果写入 FiftyOne 数据集 dataset.set_values( flash_predictions, predictions, key_fieldfilepath, ) # 8 在 App 中分析预测结果 session fo.launch_app(predict_dataset)要点说明COCO 数据集的default_classes首位通常是背景类示例中通过dataset.default_classes.pop(0)将其移除因为 DataModule 会自动补齐背景类避免类别重复transform_kwargs{image_size: 512}与模型构建时的image_size512保持一致确保训练/推理时输入尺寸统一strategyfreeze表示冻结主干网络只微调检测头可显著降低训练成本目标检测任务需要专门的FiftyOneDetectionLabelsOutput输出预测结果以Detections标签写入。语义分割以下示例在带Segmentation标注的数据集以 Lyft Udacity 挑战赛的 CARLA 数据为例上微调一个 Flash 语义分割任务from itertools import chain from flash import Trainer from flash.core.data.utils import download_data from flash.image import SemanticSegmentation, SemanticSegmentationData from flash.image.segmentation.output import FiftyOneSegmentationLabelsOutput import fiftyone as fo import fiftyone.zoo as foz # 1 加载你的 FiftyOne 数据集 # 数据来源https://www.kaggle.com/kumaresanmanickavelu/lyft-udacity-challenge download_data( https://github.com/ongchinkiat/LyftPerceptionChallenge/releases/download/v0.1/carla-capture-20180513A.zip, /tmp/carla_data/, ) dataset fo.Dataset.from_dir( dataset_dir/tmp/carla_data, dataset_typefo.types.ImageSegmentationDirectory, data_pathCameraRGB, labels_pathCameraSeg, force_grayscaleTrue, shuffleTrue, ) # 本示例仅在训练集上使用 test 和 val predict_dataset dataset.take(5) # 2 创建 DataModule datamodule SemanticSegmentationData.from_fiftyone( train_datasetdataset, test_datasetdataset, val_datasetdataset, predict_datasetpredict_dataset, label_fieldground_truth, transform_kwargsdict(image_size(256, 256)), num_classes21, batch_size4, ) # 3 构建模型 model SemanticSegmentation( backbonemobilenetv3_large_100, headfpn, num_classesdatamodule.num_classes, ) # 4 创建 trainer trainer Trainer( max_epochs1, limit_train_batches10, limit_val_batches5 ) # 5 微调模型 trainer.finetune(model, datamoduledatamodule, strategyfreeze) # 6 保存模型 trainer.save_checkpoint(/tmp/semantic_segmentation_model.pt) # 7 生成预测 predictions trainer.predict( model, datamoduledatamodule, outputFiftyOneSegmentationLabelsOutput(), ) predictions list(chain.from_iterable(predictions)) # 展平批次 # 将 filepath 映射到预测结果 predictions {p[filepath]: p[predictions] for p in predictions} # 将预测结果写入 FiftyOne 数据集 dataset.set_values( flash_predictions, predictions, key_fieldfilepath, ) # 8 在 App 中分析预测结果 session fo.launch_app(predict_dataset)要点说明分割数据通过fo.Dataset.from_dir以ImageSegmentationDirectory类型导入data_path指向 RGB 图像目录、labels_path指向分割掩码目录force_grayscaleTrue将掩码读取为灰度num_classes需与数据集中分割掩码的类别数一致示例使用 21 类FiftyOneSegmentationLabelsOutput()输出的Segmentation标签会写入样本字段。视频分类以下示例在带Classification标注的视频数据集以 Kinetics-700 为例上微调一个 Flash 视频分类任务from itertools import chain from flash.core.classification import FiftyOneLabelsOutput from flash import Trainer from flash.video import VideoClassificationData, VideoClassifier import fiftyone as fo import fiftyone.utils.random as four import fiftyone.zoo as foz # 1 加载数据 dataset foz.load_zoo_dataset( kinetics-700-2020, splitvalidation, max_samples15, shuffleTrue, ) dataset.untag_samples(validation) # 将类名中的空格替换为下划线 labels dataset.distinct(ground_truth.label) labels_map {l: l.replace( , _) for l in labels} dataset dataset.map_labels(ground_truth, labels_map).clone() # 获取数据集中的标签列表 labels dataset.distinct(ground_truth.label) # 从数据集中创建 splits splits {train: 0.7, pred: 0.3} four.random_split(dataset, splits) # 这里使用同一个数据集的不同视图你也可以为每个 split 使用不同的数据集 train_dataset dataset.match_tags(train) predict_dataset dataset.match_tags(pred) # 2 创建 DataModule datamodule VideoClassificationData.from_fiftyone( train_datasetdataset, predict_datasetpredict_dataset, label_fieldground_truth, batch_size1, clip_sampleruniform, clip_duration1, decode_audioFalse, ) # 3 构建模型 model VideoClassifier( backbonex3d_xs, labelsdatamodule.labels, pretrainedFalse, ) # 4 创建 trainer trainer Trainer(max_epochs1, limit_train_batches5) # 5 微调模型 trainer.finetune(model, datamoduledatamodule, strategyfreeze) # 6 保存模型 trainer.save_checkpoint(/tmp/video_classification.pt) # 7 生成预测 predictions trainer.predict( model, datamoduledatamodule, outputFiftyOneLabelsOutput(labelsdatamodule.labels), ) predictions list(chain.from_iterable(predictions)) # 展平批次 # 将 filepath 映射到预测结果 predictions {p[filepath]: p[predictions] for p in predictions} # 将预测结果写入 FiftyOne 数据集 predict_dataset.set_values( flash_predictions, predictions, key_fieldfilepath, ) # 8 在 App 中分析预测结果 session fo.launch_app(predict_dataset)要点说明Kinetics 原始类名可能包含空格示例通过map_labels(...).clone()将类名中的空格替换为下划线避免类名解析问题clip_sampleruniform表示在视频中均匀采样片段clip_duration1表示每个片段时长 1 秒decode_audioFalse关闭音频解码以降低开销视频分类使用VideoClassificationData.from_fiftyone构建 DataModule预测结果同样通过FiftyOneLabelsOutput写回。在 FiftyOne 数据集上应用 Flash 模型生成预测训练完成后有两种主要方式可以给 FiftyOne 数据集或数据集视图添加 Flash 模型预测。方式一使用内置 apply_model()最简便的方式是使用 FiftyOne 内置的apply_model()方法它原生接受所有受支持类型的 Flash 模型。底层实现中FiftyOne 会自动构造合适的 FlashTrainer和 FiftyOne 风格的Output完成推理并将预测以Label实例形式写入数据集。相关分发逻辑可见 fiftyone/core/models.pyFlash 模型会被路由到fiftyone.utils.flash.apply_flash_model以及 fiftyone/core/collections.py 中apply_model的通用入口。from flash.core.classification import FiftyOneLabelsOutput from flash.image import ImageClassifier, ObjectDetector import fiftyone as fo import fiftyone.zoo as foz # 加载数据集 dataset foz.load_zoo_dataset(quickstart, max_samples5) num_classes len(dataset.distinct(ground_truth.detections.label)) # 加载 Flash 模型 cls_model ImageClassifier( backboneresnet18, num_classesnum_classes ) det_model ObjectDetector( headefficientdet, backboned0, num_classes91, image_size512, ) # 预测 dataset.apply_model( cls_model, label_fieldflash_classifications, ) # 部分模型需要传入 transform kwargs transform_kwargs {image_size: 512} dataset.apply_model( det_model, label_fieldflash_detections, transform_kwargstransform_kwargs, )使用 Flash 模型推理时还可以通过trainer_kwargs字典向apply_model()传入额外参数例如trainer_kwargs{gpus: 8}用于初始化 FlashTrainer以配置分布式/并行化推理。完整的参数支持情况包括confidence_thresh、store_logits、batch_size、num_workers、output_dir、rel_dir等可查阅 fiftyone/utils/flash.py 中apply_flash_model的签名与文档confidence_thresh对模型输出的适用标签应用置信度阈值分类模型会映射到 Output 的thresholdstore_logits是否存储模型的 logits仅当模型本身输出 logits 时可用output_dir/rel_dir将分割掩码或热力图导出为 PNG 文件时使用不传时分割结果直接存入数据库transform_kwargs传给 DataModule 的变换参数trainer_kwargs初始化 FlashTrainer的参数字典用于配置 GPU 数量等分布式推理参数。在 fiftyone/utils/flash.py 的_get_output实现中可以看到分类模型会构造FiftyOneLabelsOutput支持multi_label、store_logits、threshold等选项检测模型构造FiftyOneDetectionLabelsOutput(thresholdconfidence_thresh)分割模型构造FiftyOneSegmentationLabelsOutput——这就是apply_model()能自动适配不同任务类型的原因。方式二手动添加预测如果你已经将数据加载进 Flash 的DataModule未经过 FiftyOne仍可方便地使用 FiftyOne 分析模型预测在生成预测时指定对应类型的 FiftyOne 风格Output预测就会以Label对象形式返回再通过set_values()写入数据集。from itertools import chain from flash import Trainer from flash.core.classification import FiftyOneLabelsOutput from flash.image import ImageClassificationData, ImageClassifier import fiftyone as fo import fiftyone.zoo as foz # 加载数据集 dataset foz.load_zoo_dataset(quickstart, max_samples5) labels dataset.distinct(ground_truth.detections.label) # 加载 Flash 模型 model ImageClassifier(labelslabels) # 创建预测 DataModule datamodule ImageClassificationData.from_fiftyone( predict_datasetdataset, batch_size1, ) # 以 FiftyOne 格式输出 output FiftyOneLabelsOutput( return_filepathFalse, labelslabels ) # 用 trainer 进行预测 predictions Trainer().predict(model, datamoduledatamodule, outputoutput) predictions list(chain.from_iterable(predictions)) # 展平批次 # 由于 return_filepathFalsepredictions 是一组 Label 对象 # 其顺序与 predict_dataset 的样本顺序一一对应 # 将预测结果写入数据集 dataset.set_values(flash_predictions, predictions) # 在 App 中可视化 session fo.launch_app(dataset)FiftyOne 风格的 Output 提供了一个可选的return_filepathFalse参数当它为True默认时返回包含Label对象与媒体filepath的字典设为False时则直接返回与predict_dataset样本顺序一致的Label对象列表方便直接与set_values()配合使用。指定类别名称一般情况下 Flash 模型 checkpoint 中已包含类别字符串但必要时你也可以显式向大多数Output实例包括 FiftyOne 风格输出传入 labelsimport fiftyone as fo import fiftyone.zoo as foz from flash import Trainer from flash.image import ImageClassificationData, ImageClassifier from flash.core.classification import FiftyOneLabelsOutput # 加载数据集 dataset foz.load_zoo_dataset(quickstart, max_samples5) datamodule ImageClassificationData.from_fiftyone( predict_datasetdataset, batch_size1 ) # 加载 Flash 模型 num_classes 100 model ImageClassifier(backboneresnet18, num_classesnum_classes) # 使用类别标签配置 Output labels [ label_ str(i) for i in range(num_classes) ] # 示例类别标签 output FiftyOneLabelsOutput( labelslabels ) # 以 FiftyOne 格式输出 # 用模型进行预测 trainer Trainer() predictions trainer.predict( model, datamoduledatamodule, outputoutput ) predictions list(chain.from_iterable(predictions)) # 展平批次 # 将 filepath 映射到预测结果 predictions {p[filepath]: p[predictions] for p in predictions} # 将预测结果写入数据集 dataset.set_values( flash_predictions, predictions, key_fieldfilepath ) print(dataset.distinct(flash_predictions.label)) # [label_57, label_60] # 在 App 中可视化 session fo.launch_app(dataset)当模型以num_classes而非labels构建、checkpoint 中不包含类别名时这种显式传 labels 的方式尤其必要。图像嵌入生成特征向量并可视化使用 Flash 的图像嵌入任务ImageEmbedder为图像数据集生成特征向量后可以借助 FiftyOne 的降维可视化与交互式绘图能力对 Flash 模型的嵌入执行聚类分析和相似性搜索——同样只需要几行代码import numpy as np from flash.core.data.utils import download_data from flash.image import ImageClassificationData, ImageEmbedder from flash import Trainer import fiftyone as fo import fiftyone.brain as fob # 1 下载数据 download_data( https://pl-flash-data.s3.amazonaws.com/hymenoptera_data.zip, /tmp, ) # 2 将数据加载进 FiftyOne dataset fo.Dataset.from_dir( /tmp/hymenoptera_data/test/, fo.types.ImageClassificationDirectoryTree, ) datamodule ImageClassificationData.from_fiftyone( predict_datasetdataset, batch_size1, ) # 3 加载模型 embedder ImageEmbedder( backbonevision_transformer, training_strategybarlow_twins, headbarlow_twins_head, pretraining_transformbarlow_twins_transform, training_strategy_kwargs{latent_embedding_dim: 128}, pretraining_transform_kwargs{size_crops: [32]}, ) # 4 生成嵌入 trainer Trainer() embeddings trainer.predict(embedder, datamoduledatamodule) embeddings np.stack(sum(embedding_batches, [])) # 5 可视化图像 session fo.launch_app(dataset) # 6 可视化图像嵌入 results fob.compute_visualization(dataset, embeddingsembeddings) plot results.visualize(labelsground_truth.label) plot.show()要点说明示例使用 Barlow Twins 自监督训练策略的vision_transformer骨干training_strategy_kwargs与pretraining_transform_kwargs分别配置自监督头部与预训练变换如size_crops的参数生成的num_samples x num_dim嵌入矩阵直接传给fob.compute_visualization由 FiftyOne Brain 完成降维results.visualize(labelsground_truth.label)以 ground truth 类别着色渲染嵌入图可进一步执行聚类分析与相似性检索。你还可以直接把 Flash 嵌入模型传给 FiftyOne 的compute_embeddings()让 FiftyOne 负责推理。该能力由 fiftyone/utils/flash.py 中的compute_flash_embeddings实现它校验模型为ImageEmbedder后构建ImageClassificationData并执行推理若提供了embeddings_field则将嵌入存入该字段否则在内存中返回嵌入数组。对应地fiftyone/core/collections.py 中compute_embeddings是统一入口。例如# 直接由 FiftyOne 计算嵌入 embeddings dataset.compute_embeddings(embedder) # 或保存到指定字段 dataset.compute_embeddings(embedder, embeddings_fieldembeddings)源码层面的实现原理集成核心位于 fiftyone/utils/flash.py关键实现包括模型与 DataModule 映射_MODEL_TO_DATAMODULE_MAP将四种任务模型映射到对应的 Flash DataModule 类apply_flash_model据此自动调用from_fiftyone(predict_datasetsamples, ...)构建推理数据管道输出自动选择_get_output根据模型类型自动选择FiftyOneLabelsOutput/FiftyOneDetectionLabelsOutput/FiftyOneSegmentationLabelsOutput并透传confidence_thresh分类与检测任务与store_logits分类任务等参数结果写回推理结果按{filepath: predictions}组织通过samples.set_values(label_field, predictions, key_fieldfilepath)按文件路径写回样本因此标签字段可与媒体一一对应分割/热力图导出当指定output_dir时_export_arrays会将Segmentation与Heatmap标签导出为 PNG 掩码文件并更新标签的mask_path/map_path嵌入计算compute_flash_embeddings仅接受ImageEmbedder通过np.stack将各批次嵌入合并为num_samples x num_dim数组。上层入口方面fiftyone/core/models.py 会检测模型是否为 Flash 模型如通过类名识别flash.core.model.Task并将调用路由到fiftyone.utils.flash而 fiftyone/core/collections.py 中的apply_model/compute_embeddings是面向用户的统一 API因此同一个方法可以同时适配 FiftyOne 原生模型、Hugging Face Transformers 模型、Ultralytics 模型等。测试验证仓库提供了覆盖全部集成能力的交互式测试脚本 tests/intensive/lightning_flash_tests.py需按以下方式手动运行python tests/intensive/lightning_flash_tests.py该测试套件覆盖的场景与本文内容一一对应test_apply_model分类检测模型的apply_model推理、test_image_classifier、test_object_detector、test_semantic_segmentation含分割模型的apply_model路径、test_video_classification、test_manually_adding_predictionsreturn_filepathFalse场景、test_specifying_class_names显式 labels 场景以及test_image_embedder含compute_embeddings的两种调用方式。这些测试同时是对上文各代码示例可用性的直接验证可作为复现与二次开发的参考基线。【免费下载链接】fiftyoneRefine high-quality datasets and visual AI models项目地址: https://gitcode.com/GitHub_Trending/fi/fiftyone创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考