Skip to content

Announcing FiftyOne 0.18 with App Performance Improvements, Sidebar Modes, and Custom Attributes

Voxel51 in conjunction with the FiftyOne community is excited to announce the general availability of FiftyOne 0.18!

Wait, what’s FiftyOne?

FiftyOne is an open source machine learning toolset that enables data science teams to improve the performance of their computer vision models by helping them curate high quality datasets, evaluate models, find mistakes, visualize embeddings, and get to production faster.

Get started with open source FiftyOne gif

Ok, let’s dive into the release!

tl;dr: What’s new in this release?

This release includes:

  • Significant performance improvements to the FiftyOne App
  • New sidebar modes to further optimize user experience for large datasets
  • The ability to declare and filter by custom label attributes
  • Support for storing and viewing field metadata in the App
  • A new light mode option

Check out the release notes for a full rundown of additional enhancements and bugfixes.

Join me for a live demo and AMA on December 1

You can see all of the new features in action in a live webinar and AMA on December 1, 2022 at 10 AM Pacific Time. I’ll be demoing all of the new features, followed by an open Q&A where you can get answers to any questions you might have. Register here.

Now, here’s a quick overview of some of the new features we packed into this release.

App performance improvements

FiftyOne 0.18 features major upgrades “under the hood” that have yielded significant performance improvements when working with large datasets with many samples and/or fields in the App.

For example, here’s a search across 185,000 objects in FiftyOne 0.17:

Searching across 185,000 objects in FiftyOne 0.17

The same search in FiftyOne 0.18 is now 10x faster!

Searching across 185,000 objects in FiftyOne 0.18 is 10x faster!

What key changes are driving these improvements?

  • Sidebar statistics are now lazily computed only for the currently visible fields, so only the data that you care about is loaded
  • Similarly-shaped data are optimized into faceted database aggregations
  • Improved request architecture ensuring that components load asynchronously without blocking

App sidebar modes

Another performance-oriented feature is the new configurable sidebar mode, including an updated default behavior that further optimizes the performance of the App for large datasets.

For context, each time you load a new dataset or view in the FiftyOne App, the sidebar updates to show statistics for the current collection. For large datasets with many samples or fields, this can involve substantial computation.

The App now supports three sidebar modes that you can choose between:

  • “all”: always compute counts for all visible fields and stats for all fields whose filter tray is expanded
  • “fast”: only compute counts and stats for fields whose filter tray is expanded
  • “best” (default): automatically choose between “all” and “fast” mode based on the size of the dataset

When the sidebar mode is “best”, the App will choose “fast” mode if any of the following conditions are met:

  • Any dataset with 10,000+ samples
  • Any dataset with 1,000+ samples and 15+ top-level fields in the sidebar
  • Any video dataset with frame-level label fields

You can toggle the sidebar mode dynamically for your current session via the App’s settings menu:

You can also permanently configure the default sidebar mode of a dataset by modifying the sidebar_mode property of the dataset’s App config:

# Set the default sidebar mode to "fast"
dataset.app_config.sidebar_mode = "fast"
dataset.save()  # must save after edits

session.refresh()

Check out the docs for more information about sidebar modes and how to configure them on a per-dataset basis.

Custom sidebar groups

If you’re an existing FiftyOne user, you may have discovered that you can customize the layout of the App’s sidebar by creating/renaming/deleting groups and dragging fields between groups directly in the App, with all changes you make automatically persisting between sessions.

Well, now you can programmatically modify your dataset’s sidebar groups by editing the sidebar_groups property of the dataset’s App config, including the ability to configure whether or not the group is expanded by default:

import fiftyone as fo
import fiftyone.zoo as foz

dataset = foz.load_zoo_dataset("quickstart")

# Get the default sidebar groups for the dataset
sidebar_groups = fo.DatasetAppConfig.default_sidebar_groups(dataset)

# Collapse the `metadata` section by default
print(sidebar_groups[2].name)  # metadata
sidebar_groups[2].expanded = False

# Modify the dataset's App config
dataset.app_config.sidebar_groups = sidebar_groups
dataset.save()

session = fo.launch_app(dataset)

Check out the docs to learn more about configuring your dataset’s sidebar groups via the App and the SDK.

Custom label attributes

Exciting news! A highly requested feature is finally available: you can now declare custom attributes on your label fields (or, in general, any embedded field) and filter by them in the FiftyOne App.

This can be achieved in a variety of ways, including:

1. Using add_sample_field() to directly declare a new label attribute:

# Declare a new `iscrowd` attribute on the `ground_truth` objects
dataset.add_sample_field("ground_truth.detections.iscrowd", fo.FloatField)

2. Providing the new dynamic=True option when adding samples to datasets using methods like add_samples() and from_dir() to automatically declare any dynamic attributes encountered while importing data:

# Automatically declare all new dynamic attributes
dataset.add_samples(samples, dynamic=True)

3. Using get_dynamic_field_schema() to detect the names and type(s) of any undeclared dynamic attributes, and then using add_dynamic_sample_fields() to automatically declare them:

# View any undeclared dynamic attributes
print(dataset.get_dynamic_field_schema())

# Declare them
dataset.add_dynamic_sample_fields()

Any dynamic attributes that you declare on your dataset’s schema are now exposed as filterable in the FiftyOne App!

Refer to the docs for plenty of additional information on custom attributes, including viewing, selecting, and excluding them from your dataset’s schema.

Storing and visualizing field metadata

You can now store metadata such as descriptions and other information like URLs on the fields of your dataset!

import fiftyone as fo
import fiftyone.zoo as foz

dataset = foz.load_zoo_dataset("quickstart")
dataset.add_dynamic_sample_fields()

field = dataset.get_field("ground_truth")
field.description = "Ground truth annotations"
field.info = {"url": "https://fiftyone.ai"}
field.save()

field = dataset.get_field("ground_truth.detections.area")
field.description = "Area of the box, in pixels^2"
field.info = {"url": "https://fiftyone.ai"}
field.save()

session = fo.launch_app(dataset)

Moreover, you can view this information in the FiftyOne App by hovering over field or attribute names in the App’s sidebar!

Check out the docs for more information about storing and viewing field metadata.

Now in light mode

Last but not least, FiftyOne now supports light mode! You can switch to light mode by clicking the sun/moon icon to the right of the Have a Team? button in the FiftyOne App:

By default, your browser will remember your last theme, but you can also store a default theme in your App config.

Community contributions

Shoutout to the following community members who contributed to this release!

FiftyOne community updates

The FiftyOne community continues to grow!

What’s next?