# dataset_metadata

Python API: `luxonis_train.utils.dataset_metadata`

The dataset metadata that the nodes read.

The metadata holds the class names, the keypoint counts, and the metadata label types that come from the loader.

## Classes

### DatasetMetadata

The class names, keypoint counts, and metadata types of a dataset.

A node reads its class count, class names, and keypoint count from this object, so the config does not have to set them.
[from_loader](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/utils/dataset_metadata.md)
creates the object from a loader.
[dump](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/utils/dataset_metadata.md)
returns a dictionary that a checkpoint stores and that the constructor accepts back as keyword arguments.

> **Example**
> ```pycon
>>> metadata = DatasetMetadata(
...     classes={"detection": {"car": 0, "person": 1}},
...     n_keypoints={"detection": 17},
... )
>>> metadata.n_classes("detection")
2
>>> metadata.classes().inverse[0]
'car'
>>> metadata.n_keypoints("segmentation")
0
```

#### Methods

##### init

```python
def __init__(*, classes: dict[str, dict[str, int]] | None = None, n_keypoints: dict[str, int] | None = None, metadata_types:
dict[str, type[int] | type[Category] | type[float] | type[str]] | None = None, loader: BaseLoaderTorch | None = None):
```

Initialize the metadata from plain dictionaries.

A value in `metadata_types` can also be a type name: one of `"int"`, `"float"`, `"str"`, or `"Category"`. The constructor converts the name to the type. This is the form [dump](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/utils/dataset_metadata.md) writes and a checkpoint stores.

Parameters

 * `classes` (`dict[str, dict[str, int]] | None`): Task names mapped to the class names of the task and their indices. `None` means no tasks.
 * `n_keypoints` (`dict[str, int] | None`): Task names mapped to the number of keypoints of the task. `None` means no keypoints.
 * `metadata_types` (`dict[str, type[int] | type[Category] | type[float] | type[str]] | None`): Metadata label names, such as `"<task>/metadata/<name>"`, mapped to the type of their values. `None` means no metadata labels.
 * `loader` (`BaseLoaderTorch | None`): The loader that gave the metadata. The object keeps a reference to it and does not use it.

Raises

 * `ValueError`: When a type name in `metadata_types` is not one of the four supported names.

##### classes

```python
def classes(task_name: str | None = None) -> bidict[str, int]:
```

Get the class names and indices of a task.

Parameters

 * `task_name` (`str | None`): The task to read. `None` means all tasks, which must then have the same classes.

Returns

 * `bidict[str, int]`: A new bidirectional dictionary that maps the class names to the class indices. Its `inverse` maps the indices back to the names.

Raises

 * `ValueError`: When `task_name` is not a task of the dataset.
 * `RuntimeError`: When `task_name` is `None` and the tasks have different classes.
 * `StopIteration`: When `task_name` is `None` and the metadata has no tasks.

##### dump

```python
def dump(self) -> dict[str, Any]:
```

Dump the metadata to a dictionary of plain values.

The constructor accepts the result back as keyword arguments. This is how a checkpoint stores and restores the metadata.

> **Example**
> ```pycon
>>> metadata = DatasetMetadata(
...     classes={"detection": {"car": 0}},
...     metadata_types={"color": str},
... )
>>> metadata.dump()
{'classes': {'detection': {'car': 0}},
 'n_keypoints': {},
 'metadata_types': {'color': 'str'}}
>>> DatasetMetadata(**metadata.dump()).metadata_types
{'color': <class 'str'>}
```

Returns

 * `dict[str, Any]`: A dictionary with the keys `"classes"`, `"n_keypoints"`, and `"metadata_types"`. The metadata types appear as
   type names, for example `"str"`.

##### from_loader

```python
def from_loader(loader: BaseLoaderTorch) -> DatasetMetadata:
```

Create the metadata from a loader.

The method reads `loader.get_classes()`, `loader.get_n_keypoints()`, and `loader.get_metadata_types()`. The new object keeps a
reference to `loader`.

Parameters

 * `loader` (`BaseLoaderTorch`): The loader to read.

Returns

 * `DatasetMetadata`: The metadata of the dataset of the loader.

##### n_classes

```python
def n_classes(task_name: str | None = None) -> int:
```

Get the number of classes of a task.

Parameters

 * `task_name` (`str | None`): The task to read. `None` means all tasks, which must then have the same number of classes.

Returns

 * `int`: The number of classes of the task.

Raises

 * `ValueError`: When `task_name` is not a task of the dataset.
 * `RuntimeError`: When `task_name` is `None` and the tasks have different numbers of classes.
 * `StopIteration`: When `task_name` is `None` and the metadata has no tasks.

##### n_keypoints

```python
def n_keypoints(task_name: str | None = None) -> int:
```

Get the number of keypoints of a task.

Parameters

 * `task_name` (`str | None`): The task to read. `None` means all tasks, which must then have the same number of keypoints.

Returns

 * `int`: The number of keypoints of the task. `0` when `task_name` has no keypoint count, for example a task that is not in the
   dataset.

Raises

 * `RuntimeError`: When `task_name` is `None` and the tasks have different numbers of keypoints.
 * `StopIteration`: When `task_name` is `None` and the metadata has no keypoint counts.

#### Attributes

##### metadata_types

The metadata label names mapped to the type of their values.

The dictionary is empty when the dataset has no metadata labels.

##### task_names

The names of all tasks in the class mapping.

A task with an empty class mapping is also in the set.
