# embedding_losses

Python API: `luxonis_train.attached_modules.losses.embedding_losses`

The `pytorch-metric-learning` losses, wrapped for the registry.

The module creates one
[EmbeddingLossWrapper](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/losses/embedding_losses.md)
class for each name in `EMBEDDING_LOSSES`. Each class registers in the
[LOSSES](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/registry.md)
registry under the name of its loss, so a config names the loss directly, such as `TripletMarginLoss`. Every class accepts a
miner, a distance, a reducer, and a regularizer.

## Classes

### EmbeddingLossWrapper

Wrapper of one `pytorch-metric-learning` embedding loss.

 * `Inputs:`: * `predictions` (`Tensor`): [B, D] embeddings
    * `target` (`Tensor`): [B] identity labels from `metadata/id`
 * `Outputs:`: * `Tensor`: scalar with the default reducer
 * `Formula:`: The wrapper returns the value of the `pytorch-metric-learning` loss with the registered name. With a miner, the
   wrapper also gives the loss the pairs or triplets that the miner selects in the batch. Each loss uses them in its own way. When
   the node sets `cross_batch_memory_size`, a `CrossBatchMemory` wrapper also compares the batch with a memory of the last
   `cross_batch_memory_size` embeddings.

> **References**
> * Source: Wraps [pytorch-metric-learning](https://github.com/KevinMusgrave/pytorch-metric-learning) (MIT).
 * License: Apache-2.0 (this project)

> **Notes**
> The module creates one class for each name in `EMBEDDING_LOSSES`. All classes have the name `EmbeddingLossWrapper`, and each registers under the name of its loss. The [name](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/losses/embedding_losses.md) property returns that loss name. `CrossBatchMemory` supports only some of the losses. For another loss, the wrapper logs a warning and ignores `cross_batch_memory_size`.

> **Example**
> Attached to a `GhostFaceNetHead` in `model.nodes`:

```yaml
- name: GhostFaceNetHead
  inputs: [GhostFaceNet]
  losses:
    - name: AngularLoss
```

 * `Compatible with:`: * Nodes:
   [GhostFaceNetHead](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/heads/ghostfacenet_head.md)
    * Registered under: * `AngularLoss`
       * `CircleLoss`
       * `ContrastiveLoss`
       * `DynamicSoftMarginLoss`
       * `FastAPLoss`
       * `GeneralizedLiftedStructureLoss`
       * `HistogramLoss`
       * `InstanceLoss`
       * `IntraPairVarianceLoss`
       * `LiftedStructureLoss`
       * `MarginLoss`
       * `MultiSimilarityLoss`
       * `NCALoss`
       * `NPairsLoss`
       * `NTXentLoss`
       * `PNPLoss`
       * `RankedListLoss`
       * `SignalToNoiseRatioContrastiveLoss`
       * `SupConLoss`
       * `ThresholdConsistentMarginLoss`
       * `TripletMarginLoss`
       * `TupletMarginLoss`

#### Methods

##### init

```python
def __init__(*, miner: str | None = None, miner_params: Params | None = None, distance: str | None = None, distance_params: Params | None = None, reducer: str | None = None, reducer_params: Params | None = None, regularizer: str | None = None, regularizer_params: Params | None = None, node: BaseNode | None = None, final_loss_weight: float = 1.0, _loss_name: str = _loss_name, **kwargs):
```

Create the wrapped loss and its optional components.

The method looks up each named component in the matching `pytorch-metric-learning` module. It creates the component with the
keyword arguments of its `*_params` argument. The wrapped loss receives the reducer as `reducer`, the regularizer as
`embedding_regularizer`, and the distance as `distance`, together with `**kwargs`.

When the node sets `cross_batch_memory_size` and `CrossBatchMemory` supports the loss, the method wraps the loss in
`CrossBatchMemory`. The wrapper gets the `embedding_size` and the `cross_batch_memory_size` of the node, and the miner. For a loss
that `CrossBatchMemory` does not support, the method logs a warning. The loss needs a node: without `node`,
[BaseAttachedModule.node](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/base_attached_module.md)
raises `RuntimeError`.

Parameters

 * `miner` (`str | None`): The name of a class in `pytorch_metric_learning.miners`, such as `"MultiSimilarityMiner"`. `None` uses
   no miner.
 * `miner_params` (`Params | None`): Keyword arguments of the miner. `None` passes no arguments.
 * `distance` (`str | None`): The name of a class in `pytorch_metric_learning.distances`, such as `"CosineSimilarity"`. `None`
   keeps the default distance of the loss.
 * `distance_params` (`Params | None`): Keyword arguments of the distance. `None` passes no arguments.
 * `reducer` (`str | None`): The name of a class in `pytorch_metric_learning.reducers`. `None` keeps the default reducer of the
   loss.
 * `reducer_params` (`Params | None`): Keyword arguments of the reducer. `None` passes no arguments.
 * `regularizer` (`str | None`): The name of a class in `pytorch_metric_learning.regularizers`, which the loss applies to the
   embeddings. `None` uses no regularizer.
 * `regularizer_params` (`Params | None`): Keyword arguments of the regularizer. `None` passes no arguments.
 * `node` (`BaseNode | None`): The
   [GhostFaceNetHead](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/heads/ghostfacenet_head.md)
   that the loss attaches to.
 * `final_loss_weight` (`float`): The factor by which
   [BaseLoss.run](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/losses/base_loss.md)
   multiplies the loss.
 * `_loss_name` (`str`): The name of the `pytorch-metric-learning` loss class. Its default is the registered name of this class.
 * `**kwargs`: Keyword arguments of the loss class, such as `margin` for `TripletMarginLoss`.

Raises

 * `ValueError`: When `pytorch-metric-learning` has no loss, miner, distance, reducer, or regularizer with the given name.

##### forward

```python
def forward(predictions: Tensor, target: Tensor) -> Tensor:
```

Compute the wrapped loss for a batch of embeddings.

With a miner, the method first mines the batch. It passes the mined indices to the wrapped loss as the third argument. Without a
miner, the wrapped loss receives only the embeddings and the labels. A `CrossBatchMemory` wrapper also adds the batch to its
memory.

> **Example**
> The example gets the `TripletMarginLoss` class from the [LOSSES](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/registry.md) registry. In `grouped`, the two embeddings of each identity are equal, so the loss is `0`. In `mixed`, each identity has two different embeddings, so the loss is positive:

```pycon
>>> import torch
>>> from torch import Size
>>> from luxonis_train.nodes import GhostFaceNetHead
>>> from luxonis_train.registry import LOSSES
>>> head = GhostFaceNetHead(
...     embedding_size=2,
...     input_shapes=[{"features": [Size([1, 8, 1, 1])]}],
...     original_in_shape=Size([3, 32, 32]),
... )
>>> loss = LOSSES.get("TripletMarginLoss")(node=head)
>>> target = torch.tensor([0, 0, 1, 1])
>>> grouped = torch.eye(2).repeat_interleave(2, dim=0)
>>> loss(grouped, target).item()
0.0
>>> mixed = torch.eye(2).repeat(2, 1)
>>> round(loss(mixed, target).item(), 4)
0.7571
```

Parameters

 * `predictions` (`Tensor`): The embeddings of shape `[B, D]`, the main output of the node.
 * `target` (`Tensor`): The identity labels of shape `[B]`, from the `metadata/id` label.

Returns

 * `Tensor`: The value of the wrapped loss, a scalar with the default reducer.

#### Attributes

##### loss

##### miner

##### name

The name of the wrapped `pytorch-metric-learning` loss.

The value is the `_loss_name` argument, such as `"TripletMarginLoss"`. By default, it is the registered name of the class.
[BaseAttachedModule.name](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/base_attached_module.md)
returns the class name, which is `EmbeddingLossWrapper` for every embedding loss. This override returns the name of the wrapped
loss instead. The error messages of
[BaseAttachedModule.get_parameters](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/attached_modules/base_attached_module.md)
use it.

##### node

##### supported_tasks

## Attributes

### EMBEDDING_LOSSES
