news 2026/9/16 11:38:18

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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.py(Dataset类,第 278 行)、fiftyone/core/sample.py(Sample类,第 660 行)与 fiftyone/core/view.py(DatasetView类,第 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 个默认样本字段:idfilepathtagsmetadatacreated_atlast_modified_at。这些字段由 fiftyone/core/sample.py 中的get_default_sample_fields()定义,对应到 fiftyone/core/fields.py 中的ObjectIdFieldStringFieldListFieldEmbeddedDocumentFieldDateTimeField等字段类型。

Dataset由多个Sample对象组成,这些Sample包含Field属性,所有属性都可以动态创建、修改和删除。FiftyOne 使用轻量级非关系型数据库存储数据集,因此可以轻松扩展到任意大小的数据集,而无需担心机器的内存(RAM)约束。数据集是有序的样本集合,当一个Sample被添加到Dataset时,它会被分配一个唯一 ID,可用于从数据集中检索该样本。这一机制体现在 fiftyone/core/dataset.py 的Dataset.__init___create_dataset中——数据集通过DatasetSingleton元类保证同名数据集是单例对象,且样本被赋予ObjectId形式的唯一id

注意:Dataset(name, persistent=False, overwrite=False)构造函数支持三个参数:name为数据集名称(默认使用get_default_dataset_name()),persistent决定会话结束后数据集是否保留在数据库中,overwrite决定是否覆盖同名数据集。更多数据加载方式参见 导入数据集指南。

数据集的切片及批量操作通过**数据集视图(DatasetView)**完成。DatasetView提供对Dataset的一个视图,可沿各种轴过滤、排序、采样等,以获得所需的样本子集。完整用法参见 使用数据集指南。

Sample:样本的创建

SampleDataset的原子元素,存储与给定数据(如图像或视频)相关的所有信息。所有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接受filepathtagsmetadatamedia_reference等参数,其余关键字参数会被动态设置为样本字段;当媒体类型为视频时,样本还会自动挂载一个Frames容器用于存放逐帧数据。

样本在数据集内是单例(singleton):dataset[sample_id]始终返回同一个Sample实例,这保证了在同一个进程内对样本的修改是一致的。更多用法参见 使用数据集指南。

Field:字段与动态 Schema

FieldSample实例的属性,存储关于样本的可定制信息。所有样本都必须填充filepath字段,它指向磁盘上的源数据。默认情况下,样本还带有idmedia_typetagsmetadatacreated_atlast_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.py:BooleanField(第 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(因为媒体类型为图像),同时新增的qualitykeypointsgeo_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。该文件中还定义了全部合法媒体类型常量:imagevideopoint-cloud3dmultimodalunknown,以及groupmixed两种特殊类型(用于分组数据集)。

Tags:样本标签

所有Sample实例都有tags属性,存储一个字符串列表,可灵活地用于存储关于样本的信息。一个典型用途是标记样本所属的数据集划分(testtrainvalidation),但你可以按任何方式自由使用标签。

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 行)在基类之上增加widthheightnum_channelsVideoMetadata(第 172 行)则针对视频提供帧率、时长、编码等信息。compute_metadata()的实现位于 fiftyone/core/metadata.py,支持通过num_workers参数并行计算,并在 fiftyone/core/collections.py 的SampleCollection.compute_metadata()方法上暴露给数据集与视图统一调用。它同时支持本地路径与 URL(build_forhttp开头路径走_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(label="sunny") sample["animals"] = fo.Detections( detections=[ fo.Detection(label="cat", bounding_box=[0.5, 0.5, 0.4, 0.3]), fo.Detection(label="dog", 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](左上角坐标与宽高,取值 0~1),而RegressionClassification等均继承自 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", split="test") cats = dataset.match(F("ground_truth.label") == "cat") fob.compute_uniqueness(cats) similar_cats = cats.sort_by("uniqueness", reverse=False) session = fo.launch_app(view=similar_cats)

上面的示例演示了一条典型的视图工作流:先用match()ViewField表达式过滤出类别为cat的样本,再用fob.compute_uniqueness()(brain 方法)为这些样本计算"独特性"分数,最后用sort_by()按该分数升序排序,得到"最相似"的猫样本视图并交给fo.launch_app()在 App 中可视化。

DatasetView是惰性(lazy)的:视图上的过滤、排序等操作(matchsort_bylimitskipshuffleselectexclude等)只是记录了一系列 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,提供了CountBoundsCountValuesDistinctHistogramValuesSumMeanStdMinMaxQuantilesValuesSchema等聚合类,每个聚合类实现to_mongo()将其编译为 MongoDB 聚合管道,并通过parse_result()解析结果。数据集与视图层面对应的便捷方法(countcount_valuesboundsdistincthistogram_valuessummeanstdminmaxquantilesvaluesschema等)统一实现在 fiftyone/core/collections.py 的SampleCollection基类中,因此对DatasetDatasetView均可用。聚合的完整讲解参见 聚合指南。

小结

本文围绕 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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 11:37:55

JavaScript与Flutter跨平台开发对比与实战指南

1. JavaScript与Flutter跨平台开发实战解析作为一名长期奋战在一线的全栈开发者&#xff0c;我经历过从纯原生开发到混合开发的完整技术演进历程。今天想和大家聊聊现代跨平台开发中的两个核心选项&#xff1a;JavaScript生态与Flutter框架。这两种技术栈在当下移动开发领域各占…

作者头像 李华
网站建设 2026/9/16 11:35:48

Buck电路调试四宗罪:电感饱和、振铃、环路补偿与PCB布局全解析

做电源调试这些年&#xff0c;Buck 电路是我见过翻车率最高的拓扑。原理图是参考原厂的&#xff0c;器件也照着 BOM 买&#xff0c;结果一上电&#xff0c;效率能掉到七十多&#xff0c;电感烫得不敢碰&#xff0c;运气差一点的&#xff0c;功率管直接炸。这些看起来各不相关的…

作者头像 李华
网站建设 2026/9/16 11:35:20

深圳雪茄柜哪家好 小容量家用雪茄柜推荐茄蕾

雪茄柜哪家好&#xff1f;新手茄客存茄数量不多&#xff0c;小容量家用雪茄柜性价比更高。深圳茄蕾小型雪茄柜&#xff0c;体积小巧不占地方&#xff0c;基础恒温恒湿、雪松木内胆配置齐全&#xff0c;适合书房、客厅摆放。很多入门用户测评&#xff0c;这款雪茄柜操作简单&…

作者头像 李华
网站建设 2026/9/16 11:34:34

Django选课系统开发:数据模型、事务锁与并发防超卖实战

简介&#xff1a;这是一份基于Django框架实现的学生选课管理系统源码&#xff0c;主要面向正在学习Web开发的人员、需要完成课程设计的在校生&#xff0c;以及希望在真实项目中理解Django用法的开发者。系统围绕学生选课场景&#xff0c;完整覆盖了数据建模、视图逻辑、模板渲染…

作者头像 李华
网站建设 2026/9/16 11:33:51

SpringBoot医疗就诊平台开发与架构设计实战

1. 项目概述&#xff1a;医疗就诊平台的SpringBoot实现这个基于SpringBoot的医疗就诊平台项目&#xff0c;是我在医疗信息化领域深耕多年后的一次技术实践总结。整套系统从门诊挂号、医生排班、电子病历到药品管理&#xff0c;完整覆盖了基层医疗机构的日常业务流程。采用当前主…

作者头像 李华
网站建设 2026/9/16 11:33:30

AI文档理解技术突破:DeepSeek-OCR 2实现92%准确率

1. 项目概述&#xff1a;当AI开始"真正理解"文档上周五深夜&#xff0c;当我第37次调整模型参数时&#xff0c;屏幕突然跳出准确率突破92%的提示——这个瞬间让我意识到&#xff0c;我们团队打磨两年的DeepSeek-OCR 2终于达到了商用级精度。与传统OCR仅能识别文字不同…

作者头像 李华