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.
- If you like what you see on GitHub, give the project a star.
- Get started! We’ve made it easy to get up and running in a few minutes.
- Join the FiftyOne Slack community, we’re always happy to help.
Ok, let’s dive into this week’s tips and tricks!
Deleting specific labels in a dataset
Community Slack member ZKW asked,
“Is there a method for deleting labels with specific classes in a field? For example, in a prediction I have classes
['person', 'car', 'bus', 'bike'], but I want to delete all the labels with the class ‘
bus‘ and ‘
bike‘ and only leave
['person', 'car']. How can I delete them in the dataset, rather than creating a new view that omits them?”
If you want to omit certain classes from view, you can create a view using `filter_labels()`. For instance, we can use the negation operator ‘~` in conjunction with `is_in()` to filter our view to labels whose classes are not in a certain list:
from fiftyone import ViewField as F classes_to_omit = ['bus','bike'] view = dataset.filter_labels( 'ground_truth', ~F('label').is_in(classes_to_omit) )
To delete classes from the dataset entirely, you can use the `delete_labels()` method. One way to use this method is by passing in a list of label IDs that you want to delete. You can obtain the IDs of the labels you want to delete using `filter_labels()` as above, but without the negation operator, and then using the `values()` aggregation method (with `unwind = True` to flatten the list) to extract the IDs.
from fiftyone import ViewField as F classes_to_delete = ['bus','bike'] labels_to_delete = dataset.filter_labels( 'ground_truth', F('label').is_in(classes_to_delete) ) label_ids_to_delete = labels_to_delete.values( "ground_truth.detections.id", unwind=True ) dataset.delete_labels(ids = label_ids_to_delete)
For more information about the attributes of labels stored in dataset samples, check out the FiftyOne Docs.
Improving the performance of extracting and downloading of object patches
Community Slack member mserrari asked,
“I have images that are stored on a remote server that are about 60 MB. As I understand it, in order to generate a patch view and visualize it, I have to first download it into my browser. The patches are very small, less than 100KB. Is there a way to generate and fetch pre-generated patches from large images similar to the way thumbnails are generated, in order to reduce the time and overhead required to view them?
One possible solution is to use FiftyOne to generate the patches view on the same remote server where the dataset is located.
dataset.to_patches(my_field).export("/path/", dataset_type=fo.types.ImageClassificationDirectoryTree, label_field=my_field)
Learn more about object patches in the FiftyOne Docs.
Creating dataset views after filtering
Community Slack member Joy asked,
“How can I create a view of my dataset after a filtering operation?”
import fiftyone as fo dataset = fo.load_dataset("quickstart") # Retrieve a saved view cats_view = dataset.load_saved_view("cats-view") print(cats_view)
How to quickly load large thumbnails into the FiftyOne App
Community Slack member Alexey asked,
“I’m creating a dataset with very large image files using the FiftyOne app running on a Ubuntu host. On a remote MacOS host I have observed slow image loading in the FiftyOne App. It looks like the frontend downloads the entire image before any of the dataset manipulations take place. Is there a way to download only the thumbnail images that populate the grid in order to shorten the load time in the App?”
Yes! You can use multiple media fields to have lower-res thumbnails displayed in the Apps thumbnail grid. For example, here we create thumbnail images for use in the App’s grid view and store their paths in a
import fiftyone as fo import fiftyone.utils.image as foui import fiftyone.zoo as foz dataset = foz.load_zoo_dataset("quickstart") # Generate some thumbnail images foui.transform_images( dataset, size=(-1, 32), output_field="thumbnail_path", output_dir="/tmp/thumbnails", )
More specifically in the snippet above,
size=(-1, 32) is using
fiftyone.utils.image.transform_image to specify an optional (width, height) for the image. One dimension can be -1, in which case the aspect ratio is preserved.
For more information on FiftyOne App configuration changes you can make, check out the FiftyOne Docs.
Adding custom sidebar groups
Community Slack member Agfian asked,
“I want to make a custom sidebar group in the FiftyOne App to better organize my fields. Is it possible to add the sidebar group using code at the same time as creating my dataset?”
Yes! For example in the snippet we add
brightness to the
Meta Features sidebar group:
sidebar_groups = fo.DatasetAppConfig.default_sidebar_groups(dataset) features_sg = fo.SidebarGroupDocument(name="Meta Features") features_sg.paths = ["brightness"] # Add a new group sidebar_groups.append(features_sg) dataset.app_config.sidebar_groups = sidebar_groups dataset.save()
For more information about working with Sidebar Groups, check out the FiftyOne Docs.
Join the FiftyOne community!
Join the thousands of engineers and data scientists already using FiftyOne to solve some of the most challenging problems in computer vision today!
- 1,600+ FiftyOne Slack members
- 3,000+ stars on GitHub
- 4,000+ Meetup members
- Used by 266+ repositories
- 58+ contributors