<table class="fo-notebook-links" align="left">
    <td>
        <a target="_blank" href="https://colab.research.google.com/github/voxel51/fiftyone/blob/main/docs/source/recipes/torch-dataset-examples/basic_example.ipynb">
            <img src="https://cdn.voxel51.com/colab-logo-256px.png"> &nbsp; Run in Google Colab
        </a>
    </td>
    <td>
        <a target="_blank" href="https://github.com/voxel51/fiftyone/blob/main/docs/source/recipes/torch-dataset-examples/basic_example.ipynb">
            <img src="https://cdn.voxel51.com/github-logo-256px.png"> &nbsp; View source on GitHub
        </a>
    </td>
    <td>
        <a target="_blank" href="https://raw.githubusercontent.com/voxel51/fiftyone/main/docs/source/recipes/torch-dataset-examples/basic_example.ipynb" download>
            <img src="https://cdn.voxel51.com/cloud-icon-256px.png"> &nbsp; Download notebook
        </a>
    </td>
</table>

# Data Loading with FiftyOneTorchDataset

This recipe introduces [FiftyOneTorchDataset](https://docs.voxel51.com/api/fiftyone.utils.torch.html#fiftyone.utils.torch.FiftyOneTorchDataset), which lets you turn any FiftyOne dataset or view directly into a PyTorch-compatible dataset — no data copying, no format conversion. Specifically, it covers:

- Loading a dataset from the [Dataset Zoo](https://docs.voxel51.com/user_guide/dataset_zoo/index.html) and creating a view
- Converting a FiftyOne view to a [FiftyOneTorchDataset](https://docs.voxel51.com/api/fiftyone.utils.torch.html#fiftyone.utils.torch.FiftyOneTorchDataset) with a custom `get_item` function
- Visualizing samples from the dataset
- Wrapping the dataset in a `torch.utils.data.DataLoader` for use in a training loop

**API references:** [FiftyOneTorchDataset](https://docs.voxel51.com/api/fiftyone.utils.torch.html#fiftyone.utils.torch.FiftyOneTorchDataset) · [GetItem](https://docs.voxel51.com/api/fiftyone.utils.torch.html#fiftyone.utils.torch.GetItem)

## Setup

If you haven’t already, install FiftyOne:

In this tutorial, we’ll use [PyTorch](https://pytorch.org/) for working with tensors and inspecting sample data. To follow along, you’ll need to install `torch` and `torchvision`, if necessary:

This recipe requires a helper file, `utils.py`, which contains reusable functions for building `get_item` methods and creating dataloaders. The following cell downloads it into your working directory.

## Import Libraries

## Load Dataset

## Curate Your View

One of the key advantages of [FiftyOneTorchDataset](https://docs.voxel51.com/api/fiftyone.utils.torch.html#fiftyone.utils.torch.FiftyOneTorchDataset) is that you can pass any FiftyOne *view* — not just a full dataset. Here we take a 100-sample subset, but any filter, sort, or tag expression works equally well.

## Converting to a FiftyOneTorchDataset

To convert a view to a [FiftyOneTorchDataset](https://docs.voxel51.com/api/fiftyone.utils.torch.html#fiftyone.utils.torch.FiftyOneTorchDataset), call `.to_torch(get_item)` on any dataset or view. The `get_item` argument is a callable that receives a `fiftyone.core.sample.Sample` and returns whatever your model expects.

To best understand what’s happening, start with the identity function — this shows you exactly what [FiftyOneTorchDataset](https://docs.voxel51.com/api/fiftyone.utils.torch.html#fiftyone.utils.torch.FiftyOneTorchDataset) hands to your `get_item` callable:

The `get_item` callable can return anything — here’s a minimal example that returns just the sample ID:

## Writing a Real get_item

Here’s a detection-ready `get_item` that converts FiftyOne bounding boxes to `tv_tensors.BoundingBoxes` and applies augmentations:

## Visualizing Samples

This is also a good place to debug your `get_item` function before hooking it into a training loop:

## Creating a DataLoader

[FiftyOneTorchDataset](https://docs.voxel51.com/api/fiftyone.utils.torch.html#fiftyone.utils.torch.FiftyOneTorchDataset) is fully compatible with `torch.utils.data.DataLoader`, including multi-worker loading. The only required addition is `worker_init_fn=FiftyOneTorchDataset.worker_init`, which lets each worker process open its own FiftyOne database connection:

```python
def simple_collate_fn(batch):
    return tuple(zip(*batch))

dataloader = torch.utils.data.DataLoader(
    torch_dataset,
    batch_size=5,
    shuffle=True,
    num_workers=2,
    worker_init_fn=FiftyOneTorchDataset.worker_init,
    collate_fn=simple_collate_fn,
)
```

The cells below use `utils.create_dataloader_simple()`, which wraps this same pattern:
