# tune_utils

Python API: `luxonis_train.core.utils.tune_utils`

Translation between the `tuner.params` of a config and the suggestions an Optuna trial makes.

## Functions

### get_trial_params

```python
def get_trial_params(all_augs: list[str], params: dict[str, Any], trial: optuna.trial.Trial) -> dict[str, Any]:
```

Sample the config overrides of one trial.

Each key of `params` is a dotted config key with a type suffix, such as `trainer.optimizer.params.lr_float`. The suffix after the
last `_` selects the sampling:

 * `categorical`: `trial.suggest_categorical` from a list.
 * `int`: `trial.suggest_int` from `[low, high]` or `[low, high, step]`, as integers. The default step is `1`.
 * `float`: `trial.suggest_float` from `[low, high]` or `[low, high, step]`, as floats.
 * `uniform`: `trial.suggest_float` from `[low, high]`, as floats.
 * `loguniform`: `trial.suggest_float` from `[low, high]`, as floats, with `log=True`.
 * `subset`: only for a key whose last dotted part is `augmentations`. The value is a list of augmentation names and a count. The
   function picks that many of the names at random with the `random` module, not with `trial`. It skips `Normalize` and unknown
   names with a warning.

The name of an Optuna parameter is the key without the suffix.

> **Example**
> ```pycon
>>> import optuna
>>> trial = optuna.trial.FixedTrial(
...     {"trainer.batch_size": 8, "trainer.optimizer.name": "SGD"}
... )
>>> params = {
...     "trainer.batch_size_int": [4, 16, 4],
...     "trainer.optimizer.name_categorical": ["Adam", "SGD"],
... }
>>> get_trial_params([], params, trial)
{'trainer.batch_size': 8, 'trainer.optimizer.name': 'SGD'}
```

Parameters

 * `all_augs` (`list[str]`): The names of the augmentations in `trainer.preprocessing.augmentations`, in config order. A `subset` key uses them to find the indices.
 * `params` (`dict[str, Any]`): The `tuner.params` section of the config.
 * `trial` (`optuna.trial.Trial`): The trial that samples the values.

Returns

 * `dict[str, Any]`: The sampled value of each key without the suffix. A `subset` key gives one boolean entry `<key>.<index>.active` for each kept augmentation name. `True` marks a picked augmentation.

Raises

 * `ValueError`: When the result has no entry, for example for an empty `params`. Also when the last dotted part of a `subset` key is not `augmentations`, when the count of a `subset` key is larger than the number of kept names, or when the step of a `float` key is not a float.
 * `TypeError`: When the step of an `int` key is not an integer.
 * `KeyError`: When a suffix is unknown, or when a value does not fit its suffix.

### rename_params_for_logging

```python
def rename_params_for_logging(params: dict, tuner_params: dict | None = None) -> dict:
```

Replace the augmentation indices in the keys with names, for logs.

The function reads the list of names of `trainer.preprocessing.augmentations_subset` in `tuner_params`. A key `trainer.preprocessing.augmentations.<index>.<field>` becomes `trainer.preprocessing.augmentations.<name>.active`, where `<name>` is the entry at `<index>` in that list. A key keeps its name when `<index>` is not an integer or is out of range for the list. The other keys keep their names too.

> **Example**
> ```pycon
>>> params = {
...     "trainer.preprocessing.augmentations.1.active": False,
...     "trainer.batch_size": 8,
... }
>>> tuner_params = {
...     "trainer.preprocessing.augmentations_subset": [
...         ["Defocus", "Sharpen"],
...         1,
...     ]
... }
>>> rename_params_for_logging(params, tuner_params)
{'trainer.preprocessing.augmentations.Sharpen.active': False,
 'trainer.batch_size': 8}
```

Parameters

 * `params` (`dict`): The sampled parameters of a trial, as
   [get_trial_params](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/core/utils/tune_utils.md)
   returns them.
 * `tuner_params` (`dict | None`): The `tuner.params` section of the config. Without a `subset` entry for the augmentations, the
   function changes no key.

Returns

 * `dict`: A new dictionary with the same values as `params`.
