ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

FiftyOne 核心概念入门:从 Dataset、Sample、Field 到视图与聚合的完整实战指南

FiftyOne 核心概念入门:从 Dataset、Sample、Field 到视图与聚合的完整实战指南 FiftyOne 核心概念入门从 Dataset、Sample、Field 到视图与聚合的完整实战指南【免费下载链接】fiftyoneRefine high-quality datasets and visual AI models项目地址: https://gitcode.com/GitHub_Trending/fi/fiftyone本篇技术指南以 FiftyOne 官方用户指南中的 FiftyOne Basics 为骨架系统讲解 FiftyOne 数据可视与数据集管理的基本概念Dataset数据集、Sample样本、Field字段、媒体类型、标签Tag、元数据Metadata、标注Label、DatasetView数据集视图与聚合框架。结合本仓库中 fiftyone/core 的实际源码实现你将掌握如何用 Python 快速建模自己的图像/视频数据、动态扩展 schema、按需筛选与排序样本并对整个数据集高效计算统计量为后续的数据导入、模型评估与可视化打下基础。总览FiftyOne 的基本数据模型FiftyOne 的基本数据模型由三层概念组成Dataset数据集有序的样本集合是核心数据结构通过 Python 库与 FiftyOne App 共同操作Sample样本数据集中的原子元素存储与某一份媒体数据如图像或视频相关的全部信息Field字段Sample实例的属性存储关于样本的可定制信息。把Dataset想象成一张表每一行是一个Sample每一列就是一个Field。这种表 行 列的心智模型贯穿整个 FiftyOne 的使用过程。从源码看三者分别定义于 fiftyone/core/dataset.pyDataset类第 278 行、fiftyone/core/sample.pySample类第 660 行与 fiftyone/core/view.pyDatasetView类第 34 行。Dataset数据集的创建与打印Dataset是 FiftyOne 的核心数据结构它允许你轻松地加载、修改、可视化与评估数据及其相关标注分类、检测框等并为把图像、视频、注释和模型预测加载成可在 FiftyOne App 中可视化、可与标注源同步、可与他人共享的格式提供了一致接口。对于自己的数据集合加载为Dataset后即可方便地搜索和排序样本识别独特样本以及标注中可能的错误对于训练模型而言模型的预测结果及 embeddings、logits 等关联数据都可以加载进Dataset借助 FiftyOne App 直观地调试模型学到了什么即使是多边形、分割掩码等复杂标注类型并据此把更具代表性、模型难以识别的样本补充进训练集。创建数据集只需一行代码import fiftyone as fo # Create an empty dataset dataset fo.Dataset(test-dataset) print(dataset)输出如下Name: test-dataset Media type: None Num samples: 0 Persistent: False Tags: [] Sample fields: id: fiftyone.core.fields.ObjectIdField filepath: fiftyone.core.fields.StringField tags: fiftyone.core.fields.ListField(fiftyone.core.fields.StringField) metadata: fiftyone.core.fields.EmbeddedDocumentField(fiftyone.core.metadata.Metadata) created_at: fiftyone.core.fields.DateTimeField last_modified_at: fiftyone.core.fields.DateTimeField可见一个新建数据集自带 6 个默认样本字段id、filepath、tags、metadata、created_at、last_modified_at。这些字段由 fiftyone/core/sample.py 中的get_default_sample_fields()定义对应到 fiftyone/core/fields.py 中的ObjectIdField、StringField、ListField、EmbeddedDocumentField与DateTimeField等字段类型。Dataset由多个Sample对象组成这些Sample包含Field属性所有属性都可以动态创建、修改和删除。FiftyOne 使用轻量级非关系型数据库存储数据集因此可以轻松扩展到任意大小的数据集而无需担心机器的内存RAM约束。数据集是有序的样本集合当一个Sample被添加到Dataset时它会被分配一个唯一 ID可用于从数据集中检索该样本。这一机制体现在 fiftyone/core/dataset.py 的Dataset.__init__与_create_dataset中——数据集通过DatasetSingleton元类保证同名数据集是单例对象且样本被赋予ObjectId形式的唯一id。注意Dataset(name, persistentFalse, overwriteFalse)构造函数支持三个参数name为数据集名称默认使用get_default_dataset_name()persistent决定会话结束后数据集是否保留在数据库中overwrite决定是否覆盖同名数据集。更多数据加载方式参见 导入数据集指南。数据集的切片及批量操作通过**数据集视图DatasetView**完成。DatasetView提供对Dataset的一个视图可沿各种轴过滤、排序、采样等以获得所需的样本子集。完整用法参见 使用数据集指南。Sample样本的创建Sample是Dataset的原子元素存储与给定数据如图像或视频相关的所有信息。所有Sample实例都在其filepath字段中存储源数据在磁盘上的路径也可以动态添加任意数量的字段来存储关于样本的额外自定义信息。import fiftyone as fo # An image sample sample fo.Sample(filepath/path/to/image.png) # A video sample sample fo.Sample(filepath/path/to/video.mp4)从 fiftyone/core/sample.py 的Sample.__init__可以看到Sample接受filepath、tags、metadata、media_reference等参数其余关键字参数会被动态设置为样本字段当媒体类型为视频时样本还会自动挂载一个Frames容器用于存放逐帧数据。样本在数据集内是单例singletondataset[sample_id]始终返回同一个Sample实例这保证了在同一个进程内对样本的修改是一致的。更多用法参见 使用数据集指南。Field字段与动态 SchemaField是Sample实例的属性存储关于样本的可定制信息。所有样本都必须填充filepath字段它指向磁盘上的源数据。默认情况下样本还带有id、media_type、tags、metadata、created_at和last_modified_at字段存储通用信息import fiftyone as fo sample fo.Sample(filepath/path/to/image.png) print(sample)Sample: { id: None, media_type: image, filepath: path/to/image.png, tags: [], metadata: None, created_at: None, last_modified_at: None, }自定义字段可以包含任意 Python 原始数据类型字段类型存储内容BooleanFieldPythonbool实例IntFieldPythonint实例FloatFieldPythonfloat实例StringFieldPythonstr实例DateFieldPythondate实例DateTimeFieldPythondatetime实例ListFieldPythonlist实例DictFieldPythondict实例这些字段类型都定义于 fiftyone/core/fields.pyBooleanField第 838 行、IntField第 745 行、FloatField第 949 行、StringField第 994 行、DateField第 867 行、DateTimeField第 917 行、ListField第 1036 行、DictField第 1121 行等。列表和字典字段的元素可以是同质或异质的甚至可以包含嵌套的列表和字典。字段还可以包含更复杂的数据类型如 Label 标注。字段可以动态创建、修改和删除当新的Field被赋给Dataset中的Sample或者带有新字段的Sample被添加到Dataset时相应的字段会自动添加到数据集的 schema 中从而对数据集中所有其他样本也可用。也就是说FiftyOne 的 schema 是由数据驱动的、自动扩展的。注意如果某个Field尚未在Dataset的某个Sample上设置其值为None。import fiftyone as fo sample fo.Sample(filepath/path/to/image.png) sample[quality] 89.7 sample[keypoints] [[31, 27], [63, 72]] sample[geo_json] { type: Feature, geometry: {type: Point, coordinates: [125.6, 10.1]}, properties: {name: camera}, } dataset fo.Dataset(fields-test) dataset.add_sample(sample) print(dataset)Name: fields-test Media type: image Num samples: 1 Persistent: False Tags: [] Sample fields: id: fiftyone.core.fields.ObjectIdField filepath: fiftyone.core.fields.StringField tags: fiftyone.core.fields.ListField(fiftyone.core.fields.StringField) metadata: fiftyone.core.fields.EmbeddedDocumentField(fiftyone.core.metadata.ImageMetadata) created_at: fiftyone.core.fields.DateTimeField last_modified_at: fiftyone.core.fields.DateTimeField quality: fiftyone.core.fields.FloatField keypoints: fiftyone.core.fields.ListField geo_json: fiftyone.core.fields.DictField注意当样本加入数据集后metadata字段的类型从泛化的Metadata具体化为了ImageMetadata因为媒体类型为图像同时新增的quality、keypoints、geo_json三个自定义字段自动进入了数据集的 schema。这背后对应 fiftyone/core/dataset.py 中的_expand_schema()与 fiftyone/core/fields.py 中的create_implied_field()机制根据样本实际值推断字段类型并合并进数据集 schema。Media type媒体类型的推断创建Sample时其媒体类型会根据filepath指向的源媒体推断出来并通过样本的media_type属性暴露。也可以显式提供media_type用于指定不受原生支持的媒体类型。推断逻辑位于 fiftyone/core/media.py 的get_media_type()函数根据 MIME 类型判断图像/视频根据扩展名判断点云.pcd、3D 场景.fo3d、多模态数据.mcap、.bag、.rrd无法识别时返回unknown。该文件中还定义了全部合法媒体类型常量image、video、point-cloud、3d、multimodal、unknown以及group与mixed两种特殊类型用于分组数据集。Tags样本标签所有Sample实例都有tags属性存储一个字符串列表可灵活地用于存储关于样本的信息。一个典型用途是标记样本所属的数据集划分test、train、validation但你可以按任何方式自由使用标签。import fiftyone as fo sample fo.Sample(filepath/path/to/image.png, tags[train]) sample.tags.append(my_favorite_samples) print(sample.tags) # [train, my_favorite_samples]标签在 fiftyone/core/sample.py 中由StringField列表承载默认字段tags: ListField(StringField)并可通过数据集上的tag_samples()、untag_samples()、count_sample_tags()等方法进行批量操作见 fiftyone/core/collections.py。更多信息参见 使用数据集指南。Metadata样本元数据所有Sample实例都有metadata属性存储关于样本源媒体的类型特定元数据。通过dataset.compute_metadata()可以批量填充数据集中所有样本的metadata字段import fiftyone as fo sample fo.Sample(filepath/path/to/image.png) dataset fo.Dataset() dataset.add_sample(sample) # Populate the metadata field of all samples in the dataset dataset.compute_metadata() print(dataset.first())Sample: { id: 60302b9dca4a8b5f74e84f16, media_type: image, filepath: /path/to/image.png, tags: [], metadata: ImageMetadata: { size_bytes: 544559, mime_type: image/png, width: 698, height: 664, num_channels: 3, }, created_at: datetime.datetime(2024, 7, 22, 5, 16, 10, 701907), last_modified_at: datetime.datetime(2024, 7, 22, 5, 16, 10, 701907), }元数据的类型体系定义于 fiftyone/core/metadata.py基类Metadata提供size_bytes文件字节数与mime_type两个字段ImageMetadata第 82 行在基类之上增加width、height、num_channelsVideoMetadata第 172 行则针对视频提供帧率、时长、编码等信息。compute_metadata()的实现位于 fiftyone/core/metadata.py支持通过num_workers参数并行计算并在 fiftyone/core/collections.py 的SampleCollection.compute_metadata()方法上暴露给数据集与视图统一调用。它同时支持本地路径与 URLbuild_for对http开头路径走_build_for_url分支。Labels标注类型Label存储关于样本的语义信息如地面真值标注ground annotations或模型预测。FiftyOne 为许多常见任务提供了现成的标注类全部定义于 fiftyone/core/labels.py包括标注类型用途Regression回归值Classification单标签分类结果Classifications分类结果列表典型用于多标签任务Detections/Detection目标检测框列表可带实例掩码Polylines/Polyline图像中的折线或多边形Cuboids图像中的 2D 立方体框Rotated bounding boxes图像中的旋转框Keypoints/Keypoint图像中的关键点列表Segmentation图像的语义分割掩码Heatmap图像的强度热力图TemporalDetection视频中带时间帧支持的事件3D detections场景中的 3D 检测框3D polylines场景中的 3D 折线或多边形GeoLocation地理定位点、线或面使用 FiftyOne 的Label类型即可在 FiftyOne App 中可视化你的标注。例如import fiftyone as fo sample fo.Sample(filepath/path/to/image.png) sample[weather] fo.Classification(labelsunny) sample[animals] fo.Detections( detections[ fo.Detection(labelcat, bounding_box[0.5, 0.5, 0.4, 0.3]), fo.Detection(labeldog, bounding_box[0.2, 0.2, 0.2, 0.4]), ] ) print(sample)Sample: { id: None, media_type: image, filepath: path/to/image.png, tags: [], metadata: None, created_at: None, last_modified_at: None, weather: Classification: {label: sunny, confidence: None, logits: None}, animals: Detections: { detections: [ Detection: { label: cat, bounding_box: [0.5, 0.5, 0.4, 0.3], confidence: None, attributes: {}, }, Detection: { label: dog, bounding_box: [0.2, 0.2, 0.2, 0.4], confidence: None, attributes: {}, }, ], }, }从源码看Detection.bounding_box使用相对坐标[x, y, w, h]左上角坐标与宽高取值 01而Regression、Classification等均继承自 fiftyone/core/labels.py 中的Label动态文档基类第 50 行因此可以像普通字段一样动态扩展。完整的标注存储与操作指南参见 使用数据集指南。DatasetViews数据集视图数据集视图是探索数据集的强大工具。你可以使用DatasetView实例来搜索、过滤、排序和操作数据集的子集从而完成所需的分析。import fiftyone as fo import fiftyone.zoo as foz import fiftyone.brain as fob from fiftyone import ViewField as F dataset foz.load_zoo_dataset(cifar10, splittest) cats dataset.match(F(ground_truth.label) cat) fob.compute_uniqueness(cats) similar_cats cats.sort_by(uniqueness, reverseFalse) session fo.launch_app(viewsimilar_cats)上面的示例演示了一条典型的视图工作流先用match()按ViewField表达式过滤出类别为cat的样本再用fob.compute_uniqueness()brain 方法为这些样本计算独特性分数最后用sort_by()按该分数升序排序得到最相似的猫样本视图并交给fo.launch_app()在 App 中可视化。DatasetView是惰性lazy的视图上的过滤、排序等操作match、sort_by、limit、skip、shuffle、select、exclude等只是记录了一系列 view stage真正的查询在迭代或聚合时才执行。每个 stage 在 fiftyone/core/stages.py 中都有对应实现类并最终编译为 MongoDB 聚合管道见 fiftyone/core/view.py 的_pipeline()与to_mongo()。ViewField表达式 API定义于 fiftyone/core/expressions.py支持算术、比较、逻辑、字符串、数组、日期等丰富操作符。视图的完整讲解参见 数据集视图指南。Aggregations聚合统计数据集视图用于搜索样本并过滤其内容与之互补我们常常需要计算数据集或视图的聚合统计量如标签计数、分布和范围。FiftyOne 提供了一个强大的聚合框架可高效地计算关于数据的统计信息。import fiftyone as fo import fiftyone.zoo as foz from fiftyone import ViewField as F dataset foz.load_zoo_dataset(quickstart) # Compute a histogram of the predicted labels in the predictions field print(dataset.count_values(predictions.detections.label)) # {bicycle: 13, hot dog: 8, ..., skis: 52} # Compute the range of confidences of cat predictions in the dataset print( dataset .filter_labels(predictions, F(label) cat) .bounds(predictions.detections.confidence) ) # (0.05223553627729416, 0.9965479969978333)上述示例中count_values(predictions.detections.label)沿点号路径逐层解开unwind标签列表统计每个预测类别出现的次数直方图filter_labels()先过滤出cat预测再由bounds()计算置信度的最小与最大值。聚合框架的核心实现位于 fiftyone/core/aggregations.py提供了Count、Bounds、CountValues、Distinct、HistogramValues、Sum、Mean、Std、Min、Max、Quantiles、Values、Schema等聚合类每个聚合类实现to_mongo()将其编译为 MongoDB 聚合管道并通过parse_result()解析结果。数据集与视图层面对应的便捷方法count、count_values、bounds、distinct、histogram_values、sum、mean、std、min、max、quantiles、values、schema等统一实现在 fiftyone/core/collections.py 的SampleCollection基类中因此对Dataset和DatasetView均可用。聚合的完整讲解参见 聚合指南。小结本文围绕 FiftyOne 的七组基本概念展开Dataset是有序样本集合与核心数据结构Sample是存储单一媒体数据相关信息的原子元素Field是可动态扩展的样本属性schema 由数据驱动media_type由文件路径自动推断tags是灵活的字符串标签列表metadata保存媒体文件的类型化元信息Label家族为回归、分类、检测、分割、关键点、地理信息等常见任务提供了标准化标注。在此基础上DatasetView提供惰性筛选/排序视图aggregations框架则在数据库端高效计算各类统计量。掌握这些基本概念之后即可顺畅地进入数据导入、数据集使用、视图操作与聚合统计等进阶主题。【免费下载链接】fiftyoneRefine high-quality datasets and visual AI models项目地址: https://gitcode.com/GitHub_Trending/fi/fiftyone创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表