{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "0", "metadata": {}, "source": [ "# Preliminaries" ] }, { "cell_type": "markdown", "id": "1", "metadata": {}, "source": [ "## Imports" ] }, { "cell_type": "code", "execution_count": null, "id": "2", "metadata": {}, "outputs": [], "source": [ "from pathlib import Path\n", "\n", "import holoviews as hv\n", "import panel as pn\n", "\n", "hv.extension(\"bokeh\")\n", "pn.extension()\n", "# If in google colab, run hack that allows holoviews to work properly\n", "try:\n", " import google.colab # noqa\n", "\n", " def _render(self, **kwargs):\n", " hv.extension(\"bokeh\")\n", " return hv.Store.render(self)\n", "\n", " hv.core.Dimensioned._repr_mimebundle_ = _render\n", "except ModuleNotFoundError:\n", " pass\n", "\n", "TMP_NOTEBOOK_ROOT = Path(\"/tmp/bridge-ds/tutorials\")" ] }, { "cell_type": "markdown", "id": "3", "metadata": {}, "source": [ "## Loading a dataset" ] }, { "cell_type": "markdown", "id": "4", "metadata": {}, "source": [ "To create Dataset objects, it's recommended to utilize a **DatasetProvider**. In this instance, we'll employ the Coco2017Detection provider:" ] }, { "cell_type": "code", "execution_count": null, "id": "5", "metadata": {}, "outputs": [], "source": [ "from bridge.providers.vision import Coco2017Detection\n", "\n", "root_dir = TMP_NOTEBOOK_ROOT / \"coco\"\n", "\n", "provider = Coco2017Detection(root_dir)\n", "ds = provider.build_dataset()\n", "ds" ] }, { "cell_type": "markdown", "id": "6", "metadata": {}, "source": [ "\n", "# Sample API\n", "\n", "In BridgeDS, we use two complementing approaches to view datasets. We call them the **Sample API** and the **Table API**. This tutorial is about the former.\n", "\n", "Sample API can be loosely described as:\n", "\n", " A dataset can be viewed as a collection of samples, where each sample is a pythonic object (called Sample) that contains a collection of elements.\n", "\n", "In case any of the terms 'dataset', 'sample' or 'element' is foreign to you, we recommend you to first go back to the Key Concepts section.\n", "\n", "Let's demonstrate how to use the **Sample API**:" ] }, { "cell_type": "markdown", "id": "7", "metadata": {}, "source": [ "## Indexing\n", "\n", "`ds.iget / ds.get` are our equivalents of `df.iloc / df.loc`, used for fetching individual samples from the dataset:" ] }, { "cell_type": "code", "execution_count": null, "id": "8", "metadata": {}, "outputs": [], "source": [ "sample = ds.get(34) # get sample with index 34\n", "print(\"Sample ID:\", sample.id)\n", "sample = ds.iget(1) # get sample with positional index 1\n", "print(\"Sample ID:\", sample.id)" ] }, { "cell_type": "markdown", "id": "9", "metadata": {}, "source": [ "## Properties\n", "The sample object is fairly minimal, exposing only its _id_, _elements_, and _display_engine_ properties, with limited methods available. This design reflects its role as a container for elements rather than a data object itself.\n", "\n", "Now, let’s shift our focus to the elements:\n", "\n", "As a reminder, in BridgeDS, _elements_ can be any type of data—ranging from raw objects like images or text, to annotations like bounding boxes (bboxes), segmentation maps (segmaps), or class labels.\n", "\n", "Let’s take a look at the elements contained in our current sample:" ] }, { "cell_type": "code", "execution_count": null, "id": "10", "metadata": {}, "outputs": [], "source": [ "print(\"Sample ID:\", sample.id)\n", "print(\"Total num elements in sample:\", len(sample), \"\\n\")\n", "for etype, elist in sample.elements.items():\n", " print(f\"Num elements with etype={etype}:\", len(elist))" ] }, { "cell_type": "markdown", "id": "11", "metadata": {}, "source": [ "We observe one image element and two bbox elements. It's common to have samples compose of a single element representing raw data (the image) alongside multiple elements representing annotations. To accommodate this frequent use case, we implement COCO samples using a subclass of **Sample** called **SingularSample**. This subclass provides a more convenient API, where the main element is accessible via `sample.element`, and the remaining elements are organized under `sample.annotations`:" ] }, { "cell_type": "code", "execution_count": null, "id": "12", "metadata": {}, "outputs": [], "source": [ "print(\"The 'sample element' (the image):\")\n", "print(f\"class: {type(sample).__name__}\")\n", "print(f\"etype: {sample.element.etype}\")\n", "print(f\"image shape: {sample.element.data.shape}\")\n", "print(f\"element_id: {sample.element.id}\\n\")\n", "print(\"The annotation elements:\")\n", "print(f\"n_bboxes: {len(sample.annotations['bbox'])}\")\n", "[print(bb_element.data) for bb_element in sample.annotations[\"bbox\"]];" ] }, { "cell_type": "markdown", "id": "13", "metadata": {}, "source": [ "As you can see, **elements** are container objects of the actual data - they have the `.data` property. A **sample** is just a collection of **elements**, and is the representation of an individual example from the dataset." ] }, { "cell_type": "markdown", "id": "14", "metadata": {}, "source": [ "## The DisplayEngine\n", "We will elaborate on how the DisplayEngine works in a separate tutorial, but for basic usage it's worth noting that both the Dataset and the Sample objects expose a `.show()` method, which takes advantage of the DisplayEngine and produces the following:" ] }, { "cell_type": "code", "execution_count": null, "id": "15", "metadata": {}, "outputs": [], "source": [ "sample.show()" ] }, { "cell_type": "code", "execution_count": null, "id": "16", "metadata": {}, "outputs": [], "source": [ "# display entire dataset with interactive interface:\n", "ds.show()" ] }, { "cell_type": "markdown", "id": "17", "metadata": {}, "source": [ "As you can see, our class labels are represented as integers rather than strings. This is because the raw COCO dataset stores class labels in this format. If you'd like to learn how to convert these integers into readable strings, or explore how to perform operations across the entire dataset, check out our next tutorial on the **Table API**." ] } ], "metadata": { "kernelspec": { "display_name": "python3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.12" } }, "nbformat": 4, "nbformat_minor": 5 }