# base_predefined_model

Python API: `luxonis_train.config.predefined_models.base_predefined_model`

The base classes of the predefined models.

[BasePredefinedModel](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/predefined_models/base_predefined_model.md)
is the base of every predefined model.
[SimplePredefinedModel](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/predefined_models/base_predefined_model.md)
builds the usual backbone, neck, and head chain, so a concrete model only declares its components and its variants.
[PredefinedModelMeta](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/predefined_models/base_predefined_model.md)
registers each model under a versioned name.

## Classes

### BasePredefinedModel

The base class of a predefined model.

A subclass returns the node graph from
[nodes](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/predefined_models/base_predefined_model.md)
and declares its variants in
[get_variants](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/predefined_models/base_predefined_model.md).
[luxonis_train.config.config.ModelConfig.validate_predefined_model](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/config.md)
builds the model from the `model.predefined_model` section of a config and appends the result of
[generate_nodes](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/predefined_models/base_predefined_model.md)
to `model.nodes`. Subclass this class directly when the graph is not a plain backbone, neck, and head chain. Otherwise, subclass
[SimplePredefinedModel](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/predefined_models/base_predefined_model.md).

[PredefinedModelMeta](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/predefined_models/base_predefined_model.md)
registers every concrete subclass in the `MODELS` registry as `<name>:v<N>`. It also registers the highest version of a family as
`<name>` and as `<name>:latest`.

#### Methods

##### generate_nodes

```python
def generate_nodes(include_losses: bool = True, include_metrics: bool = True, include_visualizers: bool = True) -> list[NodeConfig]:
```

Return the node graph with the attached modules filtered.

[luxonis_train.config.config.ModelConfig.validate_predefined_model](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/config.md)
calls it with the `include_*` flags of the `predefined_model` section. A flag set to `False` empties the matching list on every
node. The method edits the configs from
[nodes](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/predefined_models/base_predefined_model.md)
in place.

> **Example**
> ```pycon
>>> from luxonis_train.config.predefined_models import (
...     ClassificationModel,
... )
>>> model = ClassificationModel(variant="light")
>>> head = model.generate_nodes(include_metrics=False)[-1]
>>> [loss.name for loss in head.losses]
['CrossEntropyLoss']
>>> head.metrics
[]
```

Parameters

 * `include_losses` (`bool`): Keep the losses of the nodes.
 * `include_metrics` (`bool`): Keep the metrics of the nodes.
 * `include_visualizers` (`bool`): Keep the visualizers of the nodes.

Returns

 * `list[NodeConfig]`: The configs from [nodes](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/predefined_models/base_predefined_model.md), filtered.

##### get_variants

```python
def get_variants() -> tuple[str, dict[str, Params]]:
```

Get the default variant name and the available variants.

The keys of the dictionary are the variant names. Each value holds keyword arguments for the constructor of the model. [VariantMeta](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/variants.md) passes the arguments of the selected variant to `__init__`, and `variant="default"` selects the default variant. An argument that the caller also gives replaces the variant value as a whole, so [VariantMeta](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/variants.md) does not merge a dictionary value.

Returns

 * `tuple[str, dict[str, Params]]`: The default variant name, and the variants with their constructor arguments.

#### Attributes

##### nodes

The node configs of the model graph.

An implementation must build new configs on each access, because [generate_nodes](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/predefined_models/base_predefined_model.md) edits the configs it receives. Each config holds the losses, the metrics, and the visualizers of its node.

### PredefinedModelMeta

Metaclass that registers the predefined models under versioned names.

The version comes from the `v<N>` package that defines the class. A `DetectionModel` class in `predefined_models/detection/v2/` registers as `DetectionModel:v2`, so every version of a model keeps the class name. A class outside such a package uses its `_VERSION` attribute. The metaclass also registers the highest version under the bare family name and under `<family>:latest`.

### SimplePredefinedModel

A predefined model with a backbone, an optional neck, and a head.

A subclass names its components and its variants. This class wires them into a chain and attaches the loss, the metrics, and the visualizer to the head. It also applies the freezing and the finetuning that a config asks for. The keys of `model.predefined_model.params` in a config are the keyword arguments of `__init__`. A `variant` key does not reach `__init__`. It selects the variant.

#### Methods

##### init

```python
def __init__(*, backbone: str, backbone_variant: str | None = None, head: str, head_variant: str | None = None, neck: str | None =
None, neck_variant: str | None = None, loss: str, metrics: str | list[str] | None, main_metric: str | None = None, visualizer: str
| None = None, confusion_matrix_available: bool = False, backbone_params: Params | None = None, neck_params: Params | None = None,
use_neck: bool = True, head_params: Params | None = None, loss_params: Params | None = None, metrics_params: Params | None = None,
visualizer_params: Params | None = None, enable_confusion_matrix: bool = True, confusion_matrix_params: Params | None = None,
task_name: str | None = None, torchmetrics_task: Literal['binary', 'multiclass', 'multilabel'] | None = None, per_class_metrics:
bool | None = None, finetuning: dict[Literal['backbone', 'neck', 'head'], list[Params]] | None = None):
```

Initialize the model from the names of its components.

All arguments are keyword-only. The `typechecked` decorator checks their types at run time.

> **Notes**
> A `freezing` key in `backbone_params`, `neck_params`, or `head_params` holds the [FreezingConfig](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/config.md) of that node, either as an instance or as a dictionary of its fields. A dictionary without `active` freezes the node. [nodes](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/predefined_models/base_predefined_model.md) removes the key when it builds the configs.

Parameters

 * `backbone` (`str`): The class name of the registered backbone node.
 * `backbone_variant` (`str | None`): The variant of the backbone. `None` builds the backbone without variant parameters.
 * `head` (`str`): The class name of the registered head node.
 * `head_variant` (`str | None`): The variant of the head. `None` builds the head without variant parameters.
 * `neck` (`str | None`): The class name of the registered neck node. `None` connects the head to the backbone.
 * `neck_variant` (`str | None`): The variant of the neck. `None` builds the neck without variant parameters.
 * `loss` (`str`): The class name of the registered loss. The model attaches it to the head with weight `1.0`.
 * `metrics` (`str | list[str] | None`): The class names of the registered metrics attached to the head. A string names one metric. `None` attaches no metric.
 * `main_metric` (`str | None`): The metric to mark as the main metric. The trainer keeps the checkpoints with the highest values of this metric in `best_val_metric`. `None` takes the only name in `metrics`, or no metric when `metrics` is empty. A name that is not in `metrics` marks no metric. When no metric of the config is marked, [ModelConfig.check_main_metric](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/config.md) marks the first one.
 * `visualizer` (`str | None`): The class name of the registered visualizer attached to the head. `None` attaches no visualizer.
 * `confusion_matrix_available` (`bool`): Whether the head supports the [ConfusionMatrix](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/metrics/confusion_matrix/confusion_matrix.md) metric. A subclass sets it for its head.
 * `backbone_params` (`Params | None`): The constructor parameters of the backbone. A `freezing` key does not reach the constructor. See the notes.
 * `neck_params` (`Params | None`): The constructor parameters of the neck, with the same `freezing` key.
 * `use_neck` (`bool`): Build the neck. `False` leaves the neck out even when `neck` is set, and the head reads from the backbone.
 * `head_params` (`Params | None`): The constructor parameters of the head, with the same `freezing` key.
 * `loss_params` (`Params | None`): The constructor parameters of the loss.
 * `metrics_params` (`Params | None`): The constructor parameters that every metric in `metrics` receives. The `ConfusionMatrix` metric that `enable_confusion_matrix` adds does not receive them.
 * `visualizer_params` (`Params | None`): The constructor parameters of the visualizer.
 * `enable_confusion_matrix` (`bool`): Attach the `ConfusionMatrix` metric to the head, without the main metric flag. It has no effect when `confusion_matrix_available` is `False`.
 * `confusion_matrix_params` (`Params | None`): The constructor parameters of the `ConfusionMatrix` metric.
 * `task_name` (`str | None`): The dataset task the head reads. It becomes the `task_name` of the head node.
 * `torchmetrics_task` (`Literal['binary', 'multiclass', 'multilabel'] | None`): A value for the `torchmetrics_task` key that every metric in `metrics` receives. `None` adds no key. The key goes into `metrics_params`, so a non-empty `metrics_params` dictionary changes in place. No metric of this package reads the key. The [TorchMetricWrapper](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/metrics/torchmetrics.md) metrics read `task` and pass `torchmetrics_task` on to `torchmetrics`, which raises `ValueError` for it. Set `task` in `metrics_params` for them instead.
 * `per_class_metrics` (`bool | None`): A value for the `per_class_metrics` key that every metric in `metrics` receives. `None` adds no key. When [LuxonisLightningModule](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/lightning/luxonis_lightning.md) builds a metric, the key becomes the per-class parameter that the metric class declares. When the class declares none, the module drops the key and logs a warning.
 * `finetuning` (`dict[Literal['backbone', 'neck', 'head'], list[Params]] | None`): The finetuning entries of each component. Each dictionary becomes a [FinetuningConfig](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/config/config.md) of that node.

Raises

 * `ValueError`: When `main_metric` is `None` and `metrics` names more than one metric.

#### Attributes

##### nodes

The backbone, the neck when used, and the head, as configs.

The backbone has no inputs, so it reads from the loader. The neck reads from the backbone. The head reads from the neck, or from the backbone when `use_neck` is `False` or `neck` is `None`. Each config carries the `params`, the `variant`, the `freezing`, and the `finetuning` of its node. The head also carries `task_name`, the loss with weight `1.0`, the metrics, the `ConfusionMatrix` metric when it is enabled, and the visualizer.

The property pops the `freezing` key from the stored parameter dictionaries of the nodes. A second access therefore builds nodes that are not frozen.

> **Example**
> ```pycon
>>> from luxonis_train.config.predefined_models import (
...     DetectionModel,
... )
>>> model = DetectionModel(variant="light")
>>> [(node.name, node.inputs) for node in model.nodes]
[('EfficientRep', []),
 ('RepPANNeck', ['EfficientRep']),
 ('EfficientBBoxHead', ['RepPANNeck'])]
>>> [metric.name for metric in model.nodes[-1].metrics]
['MeanAveragePrecision', 'ConfusionMatrix']
>>> model = DetectionModel(variant="light", use_neck=False)
>>> [(node.name, node.inputs) for node in model.nodes]
[('EfficientRep', []), ('EfficientBBoxHead', ['EfficientRep'])]
```
