From 95fab66f94fafc1fe7f9795f66ec323171b4f8c9 Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Thu, 3 Oct 2024 10:39:20 +0200 Subject: [PATCH 01/15] version bump --- luxonis_train/__init__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/luxonis_train/__init__.py b/luxonis_train/__init__.py index ab8417c0..95051659 100644 --- a/luxonis_train/__init__.py +++ b/luxonis_train/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.0.1" +__version__ = "0.1.0" import warnings diff --git a/pyproject.toml b/pyproject.toml index d65978d4..67dc3d16 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ keywords = ["ml", "training", "luxonis", "oak"] dynamic = ["dependencies", "optional-dependencies", "version"] classifiers = [ "License :: OSI Approved :: Apache Software License", - "Development Status :: 3 - Alpha", + "Development Status :: 4 - Beta", "Programming Language :: Python :: 3.10", "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Scientific/Engineering :: Image Processing", From 4791b78a8a81bf2c45b36cea23201e39237fd8e6 Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Thu, 3 Oct 2024 10:42:17 +0200 Subject: [PATCH 02/15] updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bda10c09..65b78d34 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Luxonis training framework (`luxonis-train`) is intended for training deep learning models that can run fast on OAK products. -**The project is in an alpha state - please report any feedback.** +**The project is in a beta state and might be unstable or contain bugs - please report any feedback.** ## Table Of Contents From 8316ea80530747995f436228f88853999227e45c Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Thu, 3 Oct 2024 11:03:59 +0200 Subject: [PATCH 03/15] fixed grammar and typos --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 65b78d34..2aab7d86 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ Registered components can be then referenced in the config file. Custom componen - Optimizer - [Optimizer from torch.optim](https://pytorch.org/docs/stable/optim.html#torch.optim.Optimizer) - Scheduler - [LRScheduler from torch.optim.lr_scheduler](https://pytorch.org/docs/stable/optim.html#how-to-adjust-learning-rate) -Here is an example of how to create a custom components: +Here is an example of how to create custom components: ```python from torch.optim import Optimizer @@ -168,8 +168,8 @@ Local use is supported by default. In addition, we also integrate some cloud ser You have these options how to set up the environment variables: - Using standard environment variables -- Specifying the variables in a `.env` file. If a variable is both in the environment and present in `.env` file, the exported variable takes precedense. -- Specifying the variables in the [ENVIRON](https://github.com/luxonis/luxonis-train/blob/main/configs/README.md#environ) section of the config file. Note that this is not a recommended way. Variables defined in config take precedense over environment and `.env` variables. +- Specifying the variables in a `.env` file. If a variable is both in the environment and present in `.env` file, the exported variable takes precedence. +- Specifying the variables in the [ENVIRON](https://github.com/luxonis/luxonis-train/blob/main/configs/README.md#environ) section of the config file. Note that this is not a recommended way. Variables defined in config take precedence over environment and `.env` variables. ### S3 @@ -191,13 +191,13 @@ MLFLOW_S3_ENDPOINT_URL=********** MLFLOW_TRACKING_URI=********** ``` -### WanDB +### WandB -If you are using WanDB for logging, you have to sign in first in your environment. +If you are using WandB for logging, you have to sign in first in your environment. ### POSTGRESS -There is an option for remote storage for [Tuning](#tuning). We use POSTGRES and to connect to the database you need to specify the folowing env variables: +There is an option for remote storage for [Tuning](#tuning). We use POSTGRES and to connect to the database you need to specify the following env variables: ```bash POSTGRES_USER=********** From a8dfba964a3498cae01cd1b63b378c3971984a3c Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Thu, 3 Oct 2024 20:05:56 +0200 Subject: [PATCH 04/15] updated readme --- README.md | 15 +++++++++++++++ pyproject.toml | 1 + 2 files changed, 16 insertions(+) diff --git a/README.md b/README.md index 2aab7d86..3c7b5c5f 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,22 @@ losses: - name: CustomLoss params: # additional parameters k_steps: 12 +``` + +The files containing the custom components must be sourced before the training script is run. To do that in CLI, you can use the `--source` argument: + +```bash +luxonis_train --source custom_components.py train --config config.yaml +``` + +You can also run the training from a python script: + +```python +from custom_components import * +from luxonis_train import LuxonisModel +model = LuxonisModel("config.yaml") +model.train() ``` For more information on how to define custom components, consult the respective in-source documentation. diff --git a/pyproject.toml b/pyproject.toml index 67dc3d16..4d04e71e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,6 +47,7 @@ select = ["E4", "E7", "E9", "F", "W", "B", "I"] [tool.docformatter] black = true +style = "epytext" wrap-summaries = 72 wrap-descriptions = 72 From 004d5bfbe9adb6ae730e392d5ed1386eb80c035f Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Sun, 6 Oct 2024 14:27:28 +0200 Subject: [PATCH 05/15] updated readme --- README.md | 162 ++++++++++++++++++++++++++++---- luxonis_train/loaders/README.md | 18 ++++ 2 files changed, 162 insertions(+), 18 deletions(-) create mode 100644 luxonis_train/loaders/README.md diff --git a/README.md b/README.md index 2aab7d86..3b55430e 100644 --- a/README.md +++ b/README.md @@ -42,13 +42,13 @@ The entire configuration is specified in a `yaml` file. This includes the model structure, used losses, metrics, optimizers etc. For specific instructions and example configuration files, see [Configuration](https://github.com/luxonis/luxonis-train/blob/main/configs/README.md). -### Data Preparation +## Data Loading -This library requires data to be in the Luxonis Dataset Format. +LuxonisTrain supports several ways of loading data: -For instructions on how to create a dataset in the LDF, follow the -[examples](https://github.com/luxonis/luxonis-ml/tree/main/examples) in -the [luxonis-ml](https://github.com/luxonis/luxonis-ml) repository. +- from an existing dataset in the Luxonis Dataset Format +- from a directory in one of the supported formats (_e.g._ COCO, VOC, _etc._) +- using a custom loader To inspect dataset images by split (train, val, test), use the command: @@ -56,6 +56,97 @@ To inspect dataset images by split (train, val, test), use the command: luxonis_train data inspect --config --view ``` +### Luxonis Dataset Format + +The default loader used with `LuxonisTrain` is `LuxonisLoaderTorch`. It can either load data from an already created dataset in the `LuxonisDataFormat` or create a new dataset automatically from a set of supported formats. + +For instructions on how to create a dataset in the LDF, follow the +[examples](https://github.com/luxonis/luxonis-ml/tree/main/examples) in +the [luxonis-ml](https://github.com/luxonis/luxonis-ml) repository. + +To use the Luxonis Dataset Loader, specify the following in the config file: + +```yaml + +loader: + params: + # name of the created dataset + dataset_name: dataset_name + # one of local (default), s3, gcs + bucket_storage: local +``` + +### Parsing from Directory + +The supported formats are: + +- COCO - We support COCO JSON format in two variants: + - [RoboFlow](https://roboflow.com/formats/coco-json) + - [FiveOne](https://docs.voxel51.com/user_guide/export_datasets.html#cocodetectiondataset-export) +- [Pascal VOC XML](https://roboflow.com/formats/pascal-voc-xml) +- [YOLO Darknet TXT](https://roboflow.com/formats/yolo-darknet-txt) +- [YOLOv4 PyTorch TXT](https://roboflow.com/formats/yolov4-pytorch-txt) +- [MT YOLOv6](https://roboflow.com/formats/mt-yolov6) +- [CreateML JSON](https://roboflow.com/formats/createml-json) +- [TensorFlow Object Detection CSV](https://roboflow.com/formats/tensorflow-object-detection-csv) +- Classification Directory - A directory with subdirectories for each class + ```plaintext + dataset_dir/ + ├── train/ + │ ├── class1/ + │ │ ├── img1.jpg + │ │ ├── img2.jpg + │ │ └── ... + │ ├── class2/ + │ └── ... + ├── valid/ + └── test/ + ``` +- Segmentation Mask Directory - A directory with images and corresponding masks. + ```plaintext + dataset_dir/ + ├── train/ + │ ├── img1.jpg + │ ├── img1_mask.png + │ ├── ... + │ └── _classes.csv + ├── valid/ + └── test/ + ``` + The masks are stored as grayscale PNG images where each pixel value corresponds to a class. + The mapping from pixel values to class is defined in the `_classes.csv` file. + ```csv + Pixel Value, Class + 0, background + 1, class1 + 2, class2 + 3, class3 + ``` + +To use a directory loader, specify the following in the config file: + +```yaml + +loader: + params: + dataset_dir: path/to/dataset + # one of voc, darknet, yolov4, yolov6, createml, tfcsv, clsdir, segmask + dataset_type: coco +``` + +### Custom Loader + +To learn how to implement and use a custom loader, see [customization](#customizations). + +The loader can be referenced in the configuration file using its class name: + +```yaml +loader: + name: CustomLoader + params: + # additional parameters to be passed to the loade constructor +``` + ## Training Once you've created your `config.yaml` file you can train the model using this command: @@ -72,12 +163,12 @@ luxonis_train train --config config.yaml trainer.batch_size 8 trainer.epochs 10 where key and value are space separated and sub-keys are dot (`.`) separated. If the configuration field is a list, then key/sub-key should be a number (e.g. `trainer.preprocessing.augmentations.0.name RotateCustom`). -## Evaluating +## Testing -To evaluate the model on a specific dataset split (train, test, or val), use the following command: +To test the model on a specific dataset view (train, test, or val), use the following command: ```bash -luxonis_train eval --config --view +luxonis_train test --config --view ``` ## Tuning @@ -97,19 +188,36 @@ You can see an example tuning configuration [here](https://github.com/luxonis/lu We support export to `ONNX`, and `DepthAI .blob format` which is used for OAK cameras. By default, we export to `ONNX` format. -To use the exporter, you have to specify the [exporter](https://github.com/luxonis/luxonis-train/blob/main/configs/README.md#exporter) section in the config file. +To configure the exporter, you can specify the [exporter](https://github.com/luxonis/luxonis-train/blob/main/configs/README.md#exporter) section in the config file. + +You can see an example export configuration [here](https://github.com/luxonis/luxonis-train/blob/main/configs/example_export.yaml). -Once you have the config file ready you can export the model using +To export the model, run ```bash -luxonis_train export --config config.yaml +luxonis_train export --config config.yaml model.weights path/to/weights.ckpt ``` -You can see an example export configuration [here](https://github.com/luxonis/luxonis-train/blob/main/configs/example_export.yaml). +The export process can be run automatically at the end of the training by using the `ExportOnTrainEnd` callback. + +To learn about callbacks, see [callbacks](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/callbacks/README.md). + +## NN Archive Support + +The models can also be exported to our custom NN Archive format. + +```bash +luxonis_train archive --executable path/to/exported_model.onnx --config config.yaml +``` + +This will create a `.tar.gz` file which can be used with the [DepthAI](https://github.com/luxonis/depthai) API. + +The archive can be created automatically at the end of the training by using the `ArchiveOnTrainEnd` callback. ## Customizations We provide a registry interface through which you can create new +[loaders](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/loaders/README.md), [nodes](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/nodes/README.md), [losses](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/attached_modules/losses/README.md), [metrics](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/attached_modules/metrics/README.md), @@ -120,15 +228,16 @@ and [schedulers](https://github.com/luxonis/luxonis-train/blob/main/configs/READ Registered components can be then referenced in the config file. Custom components need to inherit from their respective base classes: +- Loader - [BaseLoader](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/loaders/base_loader.py) - Node - [BaseNode](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/models/nodes/base_node.py) - Loss - [BaseLoss](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/attached_modules/losses/base_loss.py) - Metric - [BaseMetric](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/attached_modules/metrics/base_metric.py) - Visualizer - [BaseVisualizer](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/attached_modules/visualizers/base_visualizer.py) -- Callback - [Callback from lightning.pytorch.callbacks](lightning.pytorch.callbacks) -- Optimizer - [Optimizer from torch.optim](https://pytorch.org/docs/stable/optim.html#torch.optim.Optimizer) -- Scheduler - [LRScheduler from torch.optim.lr_scheduler](https://pytorch.org/docs/stable/optim.html#how-to-adjust-learning-rate) +- Callback - [Callback from lightning.pytorch.callbacks](https://lightning.ai/docs/pytorch/stable/extensions/callbacks.html), requires manual registration to the `CALLBACKS` registry +- Optimizer - [Optimizer from torch.optim](https://pytorch.org/docs/stable/optim.html#torch.optim.Optimizer), requires manual registration to the `OPTIMIZERS` registry +- Scheduler - [LRScheduler fro torch.optim.lr_scheduler](https://pytorch.org/docs/stable/optim.html#how-to-adjust-learning-rate), requires manual registration to the `SCHEDULERS` registry -Here is an example of how to create custom components: +Here is an example of how to create custom loss and optimizer: ```python from torch.optim import Optimizer @@ -141,7 +250,6 @@ class CustomOptimizer(Optimizer): # Subclasses of BaseNode, LuxonisLoss, LuxonisMetric # and BaseVisualizer are registered automatically. - class CustomLoss(BaseLoss): # This class is automatically registered under `CustomLoss` name. def __init__(self, k_steps: int, **kwargs): @@ -149,7 +257,7 @@ class CustomLoss(BaseLoss): ... ``` -And then in the config you reference this `CustomOptimizer` and `CustomLoss` by their names: +In the configuration file you reference the `CustomOptimizer` and `CustomLoss` by their names: ```yaml losses: @@ -159,6 +267,24 @@ losses: ``` +For `LuxonisTrain` to recognize the custom components, they need to be imported before the main training script is run. + +If you're using the CLI, you can import the custom components by specifying the `--source` flag: + +```bash +luxonis_train --source custom_components.py train --config config.yaml +``` + +Otherwise, you can import the custom components in your custom main script: + +```python +from custom_components import * +from luxonis_train import LuxonisModel + +model = LuxonisModel("config.yaml") +model.train() +``` + For more information on how to define custom components, consult the respective in-source documentation. ## Credentials diff --git a/luxonis_train/loaders/README.md b/luxonis_train/loaders/README.md new file mode 100644 index 00000000..6f21e1e1 --- /dev/null +++ b/luxonis_train/loaders/README.md @@ -0,0 +1,18 @@ +# Loaders + +## LuxonisLoaderTorch + +The default loader used with `LuxonisTrain`. It can either load data from an already created dataset in the `LuxonisDataFormat` or create a new dataset automatically from a set of supported formats. + +### Implementing a custom loader + +To implement a loader, you need to create a class that inherits from `BaseLoaderTorch` and implement the following methods: + +- `input_shapes(self) -> dict[str, torch.Size]`: Returns a dictionary with input shapes for each input image. +- `__len__(self) -> int`: Returns the number of samples in the dataset. +- `__getitem__(self, idx: int) -> tuple[dict[str, torch.Tensor], dict[str, tuple[torch.Tensor, luxonis_train.enums.TaskType]]`: Returns a dictionary with input tensors for each input image. +- `get_classes(self) -> dict[str, list[str]]`: Returns a dictionary with class names for each task in the dataset. + +For loaders yielding keypoint tasks, you also have to implement `get_n_keypoints(self) -> dict[str, int]` method. + +For more information, consult the in-source [documentation](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/loaders/base_loader.py). From 3d32cfcb80d48372e6010e3aeaeec465b4646a8a Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Sun, 6 Oct 2024 14:27:41 +0200 Subject: [PATCH 06/15] updated docstring --- luxonis_train/core/core.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/luxonis_train/core/core.py b/luxonis_train/core/core.py index fea53acc..8b8e24c6 100644 --- a/luxonis_train/core/core.py +++ b/luxonis_train/core/core.py @@ -291,10 +291,12 @@ def export( ) -> None: """Runs export. - @type onnx_path: str | None - @param onnx_path: Path to .onnx model. If not specified, model will be saved + @type onnx_save_path: str | None + @param onnx_save_path: Path to .onnx model. If not specified, model will be saved to export directory with name specified in config file. + @type weights: str | Path | None + @param weights: Path to the checkpoint from which to export the model. @raises RuntimeError: If `onnxsim` fails to simplify the model. """ From d77afcbade48ed0b9beef022d6ab23f73e6b7f3c Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Sun, 6 Oct 2024 15:22:31 +0200 Subject: [PATCH 07/15] simplified credentials --- README.md | 64 +++++++++++++++++++++++-------------------------------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 529fd144..8f57e38b 100644 --- a/README.md +++ b/README.md @@ -50,12 +50,6 @@ LuxonisTrain supports several ways of loading data: - from a directory in one of the supported formats (_e.g._ COCO, VOC, _etc._) - using a custom loader -To inspect dataset images by split (train, val, test), use the command: - -```bash -luxonis_train data inspect --config --view -``` - ### Luxonis Dataset Format The default loader used with `LuxonisTrain` is `LuxonisLoaderTorch`. It can either load data from an already created dataset in the `LuxonisDataFormat` or create a new dataset automatically from a set of supported formats. @@ -147,6 +141,12 @@ loader: # additional parameters to be passed to the loade constructor ``` +To inspect the loader output, use the `luxonis_train inspect` command: + +```bash +luxonis_train inspect --config --view +``` + ## Training Once you've created your `config.yaml` file you can train the model using this command: @@ -165,7 +165,7 @@ where key and value are space separated and sub-keys are dot (`.`) separated. If ## Testing -To test the model on a specific dataset view (train, test, or val), use the following command: +To test the model on a specific dataset view (`train`, `test`, or `val`), use the following command: ```bash luxonis_train test --config --view @@ -312,41 +312,31 @@ You have these options how to set up the environment variables: - Specifying the variables in a `.env` file. If a variable is both in the environment and present in `.env` file, the exported variable takes precedence. - Specifying the variables in the [ENVIRON](https://github.com/luxonis/luxonis-train/blob/main/configs/README.md#environ) section of the config file. Note that this is not a recommended way. Variables defined in config take precedence over environment and `.env` variables. -### S3 +The following storage services are supported: -If you are working with LuxonisDataset that is hosted on S3, you need to specify these env variables: +- AWS S3, requires the following environment variables: + - `AWS_ACCESS_KEY_ID` + - `AWS_SECRET_ACCESS_KEY` + - `AWS_S3_ENDPOINT_URL` +- Google Cloud Storage, requires the following environment variables: + - `GOOGLE_APPLICATION_CREDENTIALS` -```bash -AWS_ACCESS_KEY_ID=********** -AWS_SECRET_ACCESS_KEY=********** -AWS_S3_ENDPOINT_URL=********** -``` +For logging and tracking, we support: -### MLFlow +- MLFlow, requires the following environment variables: + - `MLFLOW_S3_BUCKET` + - `MLFLOW_S3_ENDPOINT_URL` + - `MLFLOW_TRACKING_URI` +- WandB, requires the following environment variables: + - `WANDB_API_KEY` -If you want to use MLFlow for logging and storing artifacts you also need to specify MLFlow-related env variables like this: +There is an option for remote `POSTGRESS` storage for [Tuning](#tuning). To connect to the database you need to specify the following env variables: -```bash -MLFLOW_S3_BUCKET=********** -MLFLOW_S3_ENDPOINT_URL=********** -MLFLOW_TRACKING_URI=********** -``` - -### WandB - -If you are using WandB for logging, you have to sign in first in your environment. - -### POSTGRESS - -There is an option for remote storage for [Tuning](#tuning). We use POSTGRES and to connect to the database you need to specify the following env variables: - -```bash -POSTGRES_USER=********** -POSTGRES_PASSWORD=********** -POSTGRES_HOST=********** -POSTGRES_PORT=********** -POSTGRES_DB=********** -``` +- `POSTGRES_USER` +- `POSTGRES_PASSWORD` +- `POSTGRES_HOST` +- `POSTGRES_PORT` +- `POSTGRES_DB` ## Contributing From 737c2cb148f3cbfec40ac1bd150e728c39f26762 Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Sun, 6 Oct 2024 15:25:44 +0200 Subject: [PATCH 08/15] changed types --- README.md | 6 +++--- luxonis_train/models/luxonis_lightning.py | 2 +- luxonis_train/utils/registry.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8f57e38b..9da10335 100644 --- a/README.md +++ b/README.md @@ -233,9 +233,9 @@ Registered components can be then referenced in the config file. Custom componen - Loss - [BaseLoss](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/attached_modules/losses/base_loss.py) - Metric - [BaseMetric](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/attached_modules/metrics/base_metric.py) - Visualizer - [BaseVisualizer](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/attached_modules/visualizers/base_visualizer.py) -- Callback - [Callback from lightning.pytorch.callbacks](https://lightning.ai/docs/pytorch/stable/extensions/callbacks.html), requires manual registration to the `CALLBACKS` registry -- Optimizer - [Optimizer from torch.optim](https://pytorch.org/docs/stable/optim.html#torch.optim.Optimizer), requires manual registration to the `OPTIMIZERS` registry -- Scheduler - [LRScheduler fro torch.optim.lr_scheduler](https://pytorch.org/docs/stable/optim.html#how-to-adjust-learning-rate), requires manual registration to the `SCHEDULERS` registry +- Callback - [lightning.pytorch.callbacks.Callback](https://lightning.ai/docs/pytorch/stable/extensions/callbacks.html), requires manual registration to the `CALLBACKS` registry +- Optimizer - [torch.optim.Optimizer](https://pytorch.org/docs/stable/optim.html#torch.optim.Optimizer), requires manual registration to the `OPTIMIZERS` registry +- Scheduler - [torch.optim.lr_scheduler.LRScheduler](https://pytorch.org/docs/stable/optim.html#how-to-adjust-learning-rate), requires manual registration to the `SCHEDULERS` registry Here is an example of how to create custom loss and optimizer: diff --git a/luxonis_train/models/luxonis_lightning.py b/luxonis_train/models/luxonis_lightning.py index 03d633c9..459b20d1 100644 --- a/luxonis_train/models/luxonis_lightning.py +++ b/luxonis_train/models/luxonis_lightning.py @@ -803,7 +803,7 @@ def configure_optimizers( self, ) -> tuple[ list[torch.optim.Optimizer], - list[torch.optim.lr_scheduler._LRScheduler], + list[torch.optim.lr_scheduler.LRScheduler], ]: """Configures model optimizers and schedulers.""" cfg_optimizer = self.cfg.trainer.optimizer diff --git a/luxonis_train/utils/registry.py b/luxonis_train/utils/registry.py index 57ca0066..8044f13c 100644 --- a/luxonis_train/utils/registry.py +++ b/luxonis_train/utils/registry.py @@ -3,7 +3,7 @@ import lightning.pytorch as pl from luxonis_ml.utils.registry import Registry -from torch.optim.lr_scheduler import _LRScheduler +from torch.optim.lr_scheduler import LRScheduler from torch.optim.optimizer import Optimizer import luxonis_train as lt @@ -32,7 +32,7 @@ OPTIMIZERS: Registry[type[Optimizer]] = Registry(name="optimizers") """Registry for all optimizers.""" -SCHEDULERS: Registry[type[_LRScheduler]] = Registry(name="schedulers") +SCHEDULERS: Registry[type[LRScheduler]] = Registry(name="schedulers") """Registry for all schedulers.""" VISUALIZERS: Registry[type["lt.visualizers.BaseVisualizer"]] = Registry( From e4f285080d036dee0c0bf7f56d5448d0aa717414 Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Mon, 7 Oct 2024 00:53:22 +0200 Subject: [PATCH 09/15] removed old badges --- README.md | 16 +++++++++++++++- media/coverage_badge.svg | 21 --------------------- media/pybadge.svg | 1 - 3 files changed, 15 insertions(+), 23 deletions(-) delete mode 100644 media/coverage_badge.svg delete mode 100644 media/pybadge.svg diff --git a/README.md b/README.md index 9da10335..d44a0fee 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ![MacOS](https://img.shields.io/badge/mac%20os-000000?style=for-the-badge&logo=apple&logoColor=white) [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) -![PyBadge](https://github.com/luxonis/luxonis-train/blob/main/media/pybadge.svg) +![PyBadge](https://img.shields.io/pypi/pyversions/luxonis-train?logo=data:image/svg+xml%3Bbase64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj4KICA8ZGVmcz4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0icHlZZWxsb3ciIGdyYWRpZW50VHJhbnNmb3JtPSJyb3RhdGUoNDUpIj4KICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iI2ZlNSIgb2Zmc2V0PSIwLjYiLz4KICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iI2RhMSIgb2Zmc2V0PSIxIi8+CiAgICA8L2xpbmVhckdyYWRpZW50PgogICAgPGxpbmVhckdyYWRpZW50IGlkPSJweUJsdWUiIGdyYWRpZW50VHJhbnNmb3JtPSJyb3RhdGUoNDUpIj4KICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzY5ZiIgb2Zmc2V0PSIwLjQiLz4KICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iIzQ2OCIgb2Zmc2V0PSIxIi8+CiAgICA8L2xpbmVhckdyYWRpZW50PgogIDwvZGVmcz4KCiAgPHBhdGggZD0iTTI3LDE2YzAtNyw5LTEzLDI0LTEzYzE1LDAsMjMsNiwyMywxM2wwLDIyYzAsNy01LDEyLTExLDEybC0yNCwwYy04LDAtMTQsNi0xNCwxNWwwLDEwbC05LDBjLTgsMC0xMy05LTEzLTI0YzAtMTQsNS0yMywxMy0yM2wzNSwwbDAtM2wtMjQsMGwwLTlsMCwweiBNODgsNTB2MSIgZmlsbD0idXJsKCNweUJsdWUpIi8+CiAgPHBhdGggZD0iTTc0LDg3YzAsNy04LDEzLTIzLDEzYy0xNSwwLTI0LTYtMjQtMTNsMC0yMmMwLTcsNi0xMiwxMi0xMmwyNCwwYzgsMCwxNC03LDE0LTE1bDAtMTBsOSwwYzcsMCwxMyw5LDEzLDIzYzAsMTUtNiwyNC0xMywyNGwtMzUsMGwwLDNsMjMsMGwwLDlsMCwweiBNMTQwLDUwdjEiIGZpbGw9InVybCgjcHlZZWxsb3cpIi8+CgogIDxjaXJjbGUgcj0iNCIgY3g9IjY0IiBjeT0iODgiIGZpbGw9IiNGRkYiLz4KICA8Y2lyY2xlIHI9IjQiIGN4PSIzNyIgY3k9IjE1IiBmaWxsPSIjRkZGIi8+Cjwvc3ZnPgo=) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) ![CI](https://github.com/luxonis/luxonis-train/actions/workflows/ci.yaml/badge.svg) ![Docs](https://github.com/luxonis/luxonis-train/actions/workflows/docs.yaml/badge.svg) @@ -214,6 +214,20 @@ This will create a `.tar.gz` file which can be used with the [DepthAI](https://g The archive can be created automatically at the end of the training by using the `ArchiveOnTrainEnd` callback. +## Usage in Scripts + +On top of the CLI, you can also use the `LuxonisModel` class to run the training from a Python script. + +```python +from luxonis_train import LuxonisModel + +model = LuxonisModel("config.yaml") +model.train() +results = model.test() +model.export() +model.archive() +``` + ## Customizations We provide a registry interface through which you can create new diff --git a/media/coverage_badge.svg b/media/coverage_badge.svg deleted file mode 100644 index ee07d4c2..00000000 --- a/media/coverage_badge.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - coverage - coverage - 96% - 96% - - diff --git a/media/pybadge.svg b/media/pybadge.svg deleted file mode 100644 index 983d6f42..00000000 --- a/media/pybadge.svg +++ /dev/null @@ -1 +0,0 @@ -pythonpython3.10 | 3.113.10 | 3.11 \ No newline at end of file From 0e6cd7fb8e7c3b5a218fdccda855aec23fb75f30 Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Mon, 7 Oct 2024 03:49:20 +0200 Subject: [PATCH 10/15] unified readme styles --- README.md | 60 +-- configs/README.md | 362 +++++++++--------- configs/complex_model.yaml | 36 +- .../attached_modules/losses/README.md | 126 +++--- .../attached_modules/metrics/README.md | 19 +- .../attached_modules/visualizers/README.md | 103 ++--- luxonis_train/callbacks/README.md | 66 ++-- .../config/predefined_models/README.md | 288 +++++++------- luxonis_train/loaders/README.md | 18 +- luxonis_train/nodes/README.md | 266 ++++++------- 10 files changed, 703 insertions(+), 641 deletions(-) diff --git a/README.md b/README.md index d44a0fee..e7ba822c 100644 --- a/README.md +++ b/README.md @@ -11,23 +11,34 @@ ![Docs](https://github.com/luxonis/luxonis-train/actions/workflows/docs.yaml/badge.svg) [![codecov](https://codecov.io/gh/luxonis/luxonis-train/graph/badge.svg?token=647MTHBYD5)](https://codecov.io/gh/luxonis/luxonis-train) -Luxonis training framework (`luxonis-train`) is intended for training deep learning models that can run fast on OAK products. +Luxonis Training Framework (`luxonis-train`) is intended to be a flexible and easy-to-use tool for training deep learning models. It is built on top of PyTorch Lightning and provides a simple interface for training, testing, and exporting models. -**The project is in a beta state and might be unstable or contain bugs - please report any feedback.** +It is made to be easily customizable and extendable, allowing you to create custom loaders, losses, metrics, visualizers, and more. + +> \[!WARNING\] +> **The project is in a beta state and might be unstable or contain bugs - please report any feedback.** ## Table Of Contents - [Installation](#installation) +- [Usage](#usage) +- [Data Loading](#data-loading) + - [Luxonis Dataset Format](#luxonis-dataset-format) + - [Parsing from Directory](#parsing-from-directory) + - [Custom Loader](#custom-loader) - [Training](#training) -- [Customizations](#customizations) +- [Testing](#testing) - [Tuning](#tuning) - [Exporting](#exporting) +- [`NN Archive` Support](#nn-archive-support) +- [Usage in Scripts](#usage-in-scripts) +- [Customizations](#customizations) - [Credentials](#credentials) - [Contributing](#contributing) ## Installation -`luxonis-train` is hosted on PyPi and can be installed with `pip` as: +`luxonis-train` is hosted on PyPI and can be installed with `pip` as: ```bash pip install luxonis-train @@ -44,7 +55,7 @@ configuration files, see [Configuration](https://github.com/luxonis/luxonis-trai ## Data Loading -LuxonisTrain supports several ways of loading data: +`LuxonisTrain` supports several ways of loading data: - from an existing dataset in the Luxonis Dataset Format - from a directory in one of the supported formats (_e.g._ COCO, VOC, _etc._) @@ -56,12 +67,11 @@ The default loader used with `LuxonisTrain` is `LuxonisLoaderTorch`. It can eith For instructions on how to create a dataset in the LDF, follow the [examples](https://github.com/luxonis/luxonis-ml/tree/main/examples) in -the [luxonis-ml](https://github.com/luxonis/luxonis-ml) repository. +the [`luxonis-ml`](https://github.com/luxonis/luxonis-ml) repository. -To use the Luxonis Dataset Loader, specify the following in the config file: +To use the default loader with LDF, specify the following in the config file: ```yaml - loader: params: # name of the created dataset @@ -161,7 +171,7 @@ If you wish to manually override some config parameters you can do this by provi luxonis_train train --config config.yaml trainer.batch_size 8 trainer.epochs 10 ``` -where key and value are space separated and sub-keys are dot (`.`) separated. If the configuration field is a list, then key/sub-key should be a number (e.g. `trainer.preprocessing.augmentations.0.name RotateCustom`). +Where key and value are space separated and sub-keys are dot (`.`) separated. If the configuration field is a list, then key/sub-key should be a number (e.g. `trainer.preprocessing.augmentations.0.name RotateCustom`). ## Testing @@ -173,10 +183,10 @@ luxonis_train test --config --view ## Tuning -To improve training performance you can use `Tuner` for hyperparameter optimization. +You can use `Tuner` for hyperparameter optimization to increase the model's performance. The tuning is powered by [`Optuna`](https://optuna.org/). To use tuning, you have to specify [tuner](https://github.com/luxonis/luxonis-train/blob/main/configs/README.md#tuner) section in the config file. -To start the tuning, run +Start the tuning process by running: ```bash luxonis_train tune --config config.yaml @@ -186,7 +196,7 @@ You can see an example tuning configuration [here](https://github.com/luxonis/lu ## Exporting -We support export to `ONNX`, and `DepthAI .blob format` which is used for OAK cameras. By default, we export to `ONNX` format. +We support export to `ONNX`, and `BLOB` format which is used for OAK cameras. By default, we export to `ONNX` format. To configure the exporter, you can specify the [exporter](https://github.com/luxonis/luxonis-train/blob/main/configs/README.md#exporter) section in the config file. @@ -202,15 +212,15 @@ The export process can be run automatically at the end of the training by using To learn about callbacks, see [callbacks](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/callbacks/README.md). -## NN Archive Support +## `NN Archive` Support -The models can also be exported to our custom NN Archive format. +The models can also be exported to our custom `NN Archive` format. ```bash luxonis_train archive --executable path/to/exported_model.onnx --config config.yaml ``` -This will create a `.tar.gz` file which can be used with the [DepthAI](https://github.com/luxonis/depthai) API. +This will create a `.tar.gz` file which can be used with the [`DepthAI`](https://github.com/luxonis/depthai) API. The archive can be created automatically at the end of the training by using the `ArchiveOnTrainEnd` callback. @@ -242,14 +252,14 @@ and [schedulers](https://github.com/luxonis/luxonis-train/blob/main/configs/READ Registered components can be then referenced in the config file. Custom components need to inherit from their respective base classes: -- Loader - [BaseLoader](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/loaders/base_loader.py) -- Node - [BaseNode](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/models/nodes/base_node.py) -- Loss - [BaseLoss](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/attached_modules/losses/base_loss.py) -- Metric - [BaseMetric](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/attached_modules/metrics/base_metric.py) -- Visualizer - [BaseVisualizer](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/attached_modules/visualizers/base_visualizer.py) -- Callback - [lightning.pytorch.callbacks.Callback](https://lightning.ai/docs/pytorch/stable/extensions/callbacks.html), requires manual registration to the `CALLBACKS` registry -- Optimizer - [torch.optim.Optimizer](https://pytorch.org/docs/stable/optim.html#torch.optim.Optimizer), requires manual registration to the `OPTIMIZERS` registry -- Scheduler - [torch.optim.lr_scheduler.LRScheduler](https://pytorch.org/docs/stable/optim.html#how-to-adjust-learning-rate), requires manual registration to the `SCHEDULERS` registry +- Loader - [`BaseLoader`](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/loaders/base_loader.py) +- Node - [`BaseNode`](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/models/nodes/base_node.py) +- Loss - [`BaseLoss`](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/attached_modules/losses/base_loss.py) +- Metric - [`BaseMetric`](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/attached_modules/metrics/base_metric.py) +- Visualizer - [`BaseVisualizer`](https://github.com/luxonis/luxonis-train/blob/main/luxonis_train/attached_modules/visualizers/base_visualizer.py) +- Callback - [`lightning.pytorch.callbacks.Callback`](https://lightning.ai/docs/pytorch/stable/extensions/callbacks.html), requires manual registration to the `CALLBACKS` registry +- Optimizer - [`torch.optim.Optimizer`](https://pytorch.org/docs/stable/optim.html#torch.optim.Optimizer), requires manual registration to the `OPTIMIZERS` registry +- Scheduler - [`torch.optim.lr_scheduler.LRScheduler`](https://pytorch.org/docs/stable/optim.html#how-to-adjust-learning-rate), requires manual registration to the `SCHEDULERS` registry Here is an example of how to create custom loss and optimizer: @@ -337,11 +347,11 @@ The following storage services are supported: For logging and tracking, we support: -- MLFlow, requires the following environment variables: +- `MLFlow`, requires the following environment variables: - `MLFLOW_S3_BUCKET` - `MLFLOW_S3_ENDPOINT_URL` - `MLFLOW_TRACKING_URI` -- WandB, requires the following environment variables: +- `WandB`, requires the following environment variables: - `WANDB_API_KEY` There is an option for remote `POSTGRESS` storage for [Tuning](#tuning). To connect to the database you need to specify the following env variables: diff --git a/configs/README.md b/configs/README.md index 384f6220..8a31a4f0 100644 --- a/configs/README.md +++ b/configs/README.md @@ -1,6 +1,6 @@ # Configuration -The configuration is defined in a yaml file, which you must provide. +The configuration is defined in a YAML file, which you must provide. The configuration file consists of a few major blocks that are described below. You can create your own config or use/edit one of the examples. @@ -9,19 +9,20 @@ You can create your own config or use/edit one of the examples. - [Top-level Options](#top-level-options) - [Model](#model) - [Nodes](#nodes) - - [Attached Modules](#attached-modules) - [Losses](#losses) - [Metrics](#metrics) - [Visualizers](#visualizers) - [Tracker](#tracker) - [Loader](#loader) -- [Trainer](#train) + - [`LuxonisLoaderTorch`](#luxonisloadertorch) +- [Trainer](#trainer) - [Preprocessing](#preprocessing) + - [Augmentations](#augmentations) - [Optimizer](#optimizer) - [Scheduler](#scheduler) - [Callbacks](#callbacks) - [Exporter](#exporter) - - [ONNX](#onnx) + - [`ONNX`](#onnx) - [Blob](#blob) - [Tuner](#tuner) - [Storage](#storage) @@ -29,245 +30,253 @@ You can create your own config or use/edit one of the examples. ## Top-level Options -| Key | Type | Default value | Description | -| -------- | --------------------- | ------------- | ---------------- | -| model | [Model](#model) | | Model section | -| loader | [loader](#loader) | | Loader section | -| train | [train](#train) | | Train section | -| tracker | [tracker](#tracker) | | Tracker section | -| trainer | [trainer](#trainer) | | Trainer section | -| exporter | [exporter](#exporter) | | Exporter section | -| tuner | [tuner](#tuner) | | Tuner section | +| Key | Type | Description | +| ---------- | ----------------------- | ---------------- | +| `model` | [`model`](#model) | Model section | +| `loader` | [`loader`](#loader) | Loader section | +| `train` | [`train`](#train) | Train section | +| `tracker` | [`tracker`](#tracker) | Tracker section | +| `trainer` | [`trainer`](#trainer) | Trainer section | +| `exporter` | [`exporter`](#exporter) | Exporter section | +| `tuner` | [`tuner`](#tuner) | Tuner section | ## Model This is the most important block, that **must be always defined by the user**. There are two different ways you can create the model. -| Key | Type | Default value | Description | -| ---------------- | ---- | ------------- | ---------------------------------------------------------- | -| name | str | "model" | Name of the model | -| weights | path | None | Path to weights to load | -| predefined_model | str | None | Name of a predefined model to use | -| params | dict | {} | Parameters for the predefined model | -| nodes | list | \[\] | List of nodes (see [nodes](#nodes) | -| losses | list | \[\] | lList of losses (see [losses](#losses) | -| metrics | list | \[\] | List of metrics (see [metrics](#metrics) | -| visualziers | list | \[\] | List of visualizers (see [visualizers](#visualizers) | -| outputs | list | \[\] | List of outputs nodes, inferred from nodes if not provided | +| Key | Type | Default value | Description | +| ------------------ | ------ | ------------- | ---------------------------------------------------------- | +| `name` | `str` | `"model"` | Name of the model | +| `weights` | `path` | `None` | Path to weights to load | +| `predefined_model` | `str` | `None` | Name of a predefined model to use | +| `params` | `dict` | `{}` | Parameters for the predefined model | +| `nodes` | `list` | `[]` | List of nodes (see [nodes](#nodes)) | +| `losses` | `list` | `[]` | List of losses (see [losses](#losses)) | +| `metrics` | `list` | `[]` | List of metrics (see [metrics](#metrics)) | +| `visualziers` | `list` | `[]` | List of visualizers (see [visualizers](#visualizers)) | +| `outputs` | `list` | `[]` | List of outputs nodes, inferred from nodes if not provided | ### Nodes For list of all nodes, see [nodes](../luxonis_train/nodes/README.md). -| Key | Type | Default value | Description | -| ----------------------- | -------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| name | str | | Name of the node | -| alias | str | None | Custom name for the node | -| params | dict | {} | Parameters for the node | -| inputs | list | \[\] | List of input nodes for this node, if empty, the node is understood to be an input node of the model | -| freezing.active | bool | False | whether to freeze the modules so the weights are not updated | -| freezing.unfreeze_after | int \| float \| None | None | After how many epochs should the modules be unfrozen, can be `int` for a specific number of epochs or `float` for a portion of the training | -| remove_on_export | bool | False | Whether the node should be removed when exporting | - -### Attached Modules - -Modules that are attached to a node. This include losses, metrics and visualziers. - -| Key | Type | Default value | Description | -| ----------- | ---- | ------------- | ------------------------------------------- | -| name | str | | Name of the module | -| attached_to | str | | Name of the node the module is attached to. | -| alias | str | None | Custom name for the module | -| params | dict | {} | Parameters of the module | +| Key | Type | Default value | Description | +| ------------------------- | ---------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | `str` | - | Name of the node | +| `alias` | `str` | `None` | Custom name for the node | +| `params` | `dict` | `{}` | Parameters for the node | +| `inputs` | `list` | `[]` | List of input nodes for this node, if empty, the node is understood to be an input node of the model | +| `freezing.active` | `bool` | `False` | whether to freeze the modules so the weights are not updated | +| `freezing.unfreeze_after` | `int \| float \| None` | `None` | After how many epochs should the modules be unfrozen, can be `int` for a specific number of epochs or `float` for a portion of the training | +| `remove_on_export` | `bool` | `False` | Whether the node should be removed when exporting | +| `losses` | `list` | `[]` | List of losses attached to this node | +| `metrics` | `list` | `[]` | List of metrics attached to this node | +| `visualizers` | `list` | `[]` | List of visualizers attached to this node | #### Losses At least one node must have a loss attached to it. You can see the list of all currently supported loss functions and their parameters [here](../luxonis_train/attached_modules/losses/README.md). -| Key | Type | Default value | Description | -| ------ | ----- | ------------- | ---------------------------------------- | -| weight | float | 1.0 | Weight of the loss used in the final sum | +| Key | Type | Default value | Description | +| -------- | ------- | ------------- | ---------------------------------------- | +| `weight` | `float` | `1.0` | Weight of the loss used in the final sum | +| `alias` | `str` | `None` | Custom name for the loss | +| `params` | `dict` | `{}` | Additional parameters for the loss | #### Metrics In this section, you configure which metrics should be used for which node. You can see the list of all currently supported metrics and their parameters [here](../luxonis_train/attached_modules/metrics/README.md). -| Key | Type | Default value | Description | -| -------------- | ---- | ------------- | --------------------------------------------------------------------------------------- | -| is_main_metric | bool | False | Marks this specific metric as the main one. Main metric is used for saving checkpoints. | +| Key | Type | Default value | Description | +| ---------------- | ------ | ------------- | -------------------------------------------------------------------------------------- | +| `is_main_metric` | `bool` | `False` | Marks this specific metric as the main one. Main metric is used for saving checkpoints | +| `alias` | `str` | `None` | Custom name for the metric | +| `params` | `dict` | `{}` | Additional parameters for the metric | #### Visualizers In this section, you configure which visualizers should be used for which node. Visualizers are responsible for creating images during training. You can see the list of all currently supported visualizers and their parameters [here](../luxonis_train/attached_modules/visualizers/README.md). -Visualizers have no specific configuration. +| Key | Type | Default value | Description | +| -------- | ------ | ------------- | ---------------------------------------- | +| `alias` | `str` | `None` | Custom name for the visualizer | +| `params` | `dict` | `{}` | Additional parameters for the visualizer | ## Tracker -This library uses [LuxonisTrackerPL](https://github.com/luxonis/luxonis-ml/blob/b2399335efa914ef142b1b1a5db52ad90985c539/src/luxonis_ml/ops/tracker.py#L152). +This library uses [`LuxonisTrackerPL`](https://github.com/luxonis/luxonis-ml/blob/b2399335efa914ef142b1b1a5db52ad90985c539/src/luxonis_ml/ops/tracker.py#L152). You can configure it like this: -| Key | Type | Default value | Description | -| -------------- | ----------- | ------------- | ---------------------------------------------------------- | -| project_name | str \| None | None | Name of the project used for logging. | -| project_id | str \| None | None | Id of the project used for logging (relevant for MLFlow). | -| run_name | str \| None | None | Name of the run. If empty, then it will be auto-generated. | -| run_id | str \| None | None | Id of an already created run (relevant for MLFLow.) | -| save_directory | str | "output" | Path to the save directory. | -| is_tensorboard | bool | True | Whether to use tensorboard. | -| is_wandb | bool | False | Whether to use WandB. | -| wandb_entity | str \| None | None | Name of WandB entity. | -| is_mlflow | bool | False | Whether to use MLFlow. | +| Key | Type | Default value | Description | +| ---------------- | ------------- | ------------- | ---------------------------------------------------------- | +| `project_name` | `str \| None` | `None` | Name of the project used for logging | +| `project_id` | `str \| None` | `None` | ID of the project used for logging (relevant for `MLFlow`) | +| `run_name` | `str \| None` | `None` | Name of the run. If empty, then it will be auto-generated | +| `run_id` | `str \| None` | `None` | ID of an already created run (relevant for `MLFLow`) | +| `save_directory` | `str` | `"output"` | Path to the save directory | +| `is_tensorboard` | `bool` | `True` | Whether to use `Tensorboard` | +| `is_wandb` | `bool` | `False` | Whether to use `WandB` | +| `wandb_entity` | `str \| None` | `None` | Name of `WandB` entity | +| `is_mlflow` | `bool` | `False` | Whether to use `MLFlow` | ## Loader This section controls the data loading process and parameters regarding the dataset. -To store and load the data we use LuxonisDataset and LuxonisLoader. For specific config parameters refer to [LuxonisML](https://github.com/luxonis/luxonis-ml). +To store and load the data we use `LuxonisDataset` and `LuxonisLoader.` For specific config parameters refer to [`LuxonisML`](https://github.com/luxonis/luxonis-ml). -| Key | Type | Default value | Description | -| ------------ | ------------------ | ------------------ | -------------------------------- | -| name | str | LuxonisLoaderTorch | Name of the Loader | -| image_source | str | image | Name of the input image group | -| train_view | str \| list\[str\] | train | splits to use for training | -| val_view | str \| list\[str\] | val | splits to use for validation | -| test_view | str \| list\[str\] | test | splits to use for testing | -| params | Dict\[str, Any\] | {} | Additional parameters for loader | +| Key | Type | Default value | Description | +| -------------- | ------------------ | ---------------------- | ------------------------------------ | +| `name` | `str` | `"LuxonisLoaderTorch"` | Name of the Loader | +| `image_source` | `str` | `"image"` | Name of the input image group | +| `train_view` | `str \| list[str]` | `"train"` | splits to use for training | +| `val_view` | `str \| list[str]` | `"val"` | splits to use for validation | +| `test_view` | `str \| list[str]` | `"test"` | splits to use for testing | +| `params` | `dict[str, Any]` | `{}` | Additional parameters for the loader | -### LuxonisLoaderTorch +### `LuxonisLoaderTorch` -By default LuxonisLoaderTorch which can either use an existing LuxonisDataset or create a new one if it can be parsed automatically by LuxonisParser (check [LuxonisML](https://github.com/luxonis/luxonis-ml) `data` subpackage for more info). +By default, `LuxonisLoaderTorch` can either use an existing `LuxonisDataset` or create a new one if it can be parsed automatically by `LuxonisParser` (check [`LuxonisML`](https://github.com/luxonis/luxonis-ml) `data` sub-package for more info). -In most cases you want to change one of the parameters below. You can check all the parameters in `LuxonisLoaderTorch` class itself. +In most cases you want to set one of the parameters below. You can check all the parameters in the `LuxonisLoaderTorch` class itself. -| dataset_name | str | None | None | Name of an existing LuxonisDataset. | -| dataset_dir | str | None | None | Location of the data from which new LuxonisDataset will be created | -| dataset_type | DatasetType | None | None | Can specify exact format of the data. If None and new dataset needs to be created then it will be infered automatically. | +| Key | Type | Default value | Description | +| -------------- | ----- | ------------- | -------------------------------------------------------------------- | +| `dataset_name` | `str` | `None` | Name of an existing `LuxonisDataset` | +| `dataset_dir` | `str` | `None` | Location of the data from which new `LuxonisDataset` will be created | ## Trainer Here you can change everything related to actual training of the model. -| Key | Type | Default value | Description | -| ----------------------- | ---------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| seed | int | None | Seed for reproducibility | -| deterministic | bool \| "warn" \| None | None | Whether pytorch should use deterministic backend | -| batch_size | int | 32 | Batch size used for training | -| accumulate_grad_batches | int | 1 | Number of batches for gradient accumulation | -| use_weighted_sampler | bool | False | Bool if use WeightedRandomSampler for training, only works with classification tasks | -| epochs | int | 100 | Number of training epochs | -| n_workers | int | 4 | Number of workers for data loading | -| validation_interval | int | 5 | Frequency of computing metrics on validation data | -| n_log_images | int | 4 | Maximum number of images to visualize and log | -| skip_last_batch | bool | True | Whether to skip last batch while training | -| accelerator | Literal\["auto", "cpu", "gpu"\] | "auto" | What accelerator to use for training. | -| devices | int \| list\[int\] \| str | "auto" | Either specify how many devices to use (int), list specific devices, or use "auto" for automatic configuration based on the selected accelerator | -| matmul_precision | Literal\["medium", "high", "highest"\] \| None | None | Sets the internal precision of float32 matrix multiplications. | -| strategy | Literal\["auto", "ddp"\] | "auto" | What strategy to use for training. | -| n_sanity_val_steps | int | 2 | Number of sanity validation steps performed before training. | -| profiler | Literal\["simple", "advanced"\] \| None | None | PL profiler for GPU/CPU/RAM utilization analysis | -| verbose | bool | True | Print all intermediate results to console. | -| pin_memory | bool | True | Whether to pin memory in the DataLoader | -| save_top_k | -1 \| NonNegativeInt | 3 | Save top K checkpoints based on validation loss when training. | +| Key | Type | Default value | Description | +| ------------------------- | ---------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | +| `seed` | `int` | `None` | Seed for reproducibility | +| `deterministic` | `bool \| "warn" \| None` | `None` | Whether PyTorch should use deterministic backend | +| `batch_size` | `int` | `32` | Batch size used for training | +| `accumulate_grad_batches` | `int` | `1` | Number of batches for gradient accumulation | +| `use_weighted_sampler` | `bool` | `False` | Whether to use `WeightedRandomSampler` for training, only works with classification tasks | +| `epochs` | `int` | `100` | Number of training epochs | +| `n_workers` | `int` | `4` | Number of workers for data loading | +| `validation_interval` | `int` | `5` | Frequency of computing metrics on validation data | +| `n_log_images` | `int` | `4` | Maximum number of images to visualize and log | +| `skip_last_batch` | `bool` | `True` | Whether to skip last batch while training | +| `accelerator` | `Literal["auto", "cpu", "gpu"]` | `"auto"` | What accelerator to use for training | +| `devices` | `int \| list[int] \| str` | `"auto"` | Either specify how many devices to use (int), list specific devices, or use "auto" for automatic configuration based on the selected accelerator | +| `matmul_precision` | `Literal["medium", "high", "highest"] \| None` | `None` | Sets the internal precision of float32 matrix multiplications | +| `strategy` | `Literal["auto", "ddp"]` | `"auto"` | What strategy to use for training | +| `n_sanity_val_steps` | `int` | `2` | Number of sanity validation steps performed before training | +| `profiler` | `Literal["simple", "advanced"] \| None` | `None` | PL profiler for GPU/CPU/RAM utilization analysis | +| `verbose` | `bool` | `True` | Print all intermediate results to console | +| `pin_memory` | `bool` | `True` | Whether to pin memory in the `DataLoader` | +| `save_top_k` | `-1 \| NonNegativeInt` | `3` | Save top K checkpoints based on validation loss when training | ### Preprocessing -We use [Albumentations](https://albumentations.ai/docs/) library for `augmentations`. [Here](https://albumentations.ai/docs/api_reference/full_reference/#pixel-level-transforms) you can see a list of all pixel level augmentations supported, and [here](https://albumentations.ai/docs/api_reference/full_reference/#spatial-level-transforms) you see all spatial level transformations. In config you can specify any augmentation from this lists and their params. +We use [`Albumentations`](https://albumentations.ai/docs/) library for `augmentations`. [Here](https://albumentations.ai/docs/api_reference/full_reference/#pixel-level-transforms) you can see a list of all pixel level augmentations supported, and [here](https://albumentations.ai/docs/api_reference/full_reference/#spatial-level-transforms) you see all spatial level transformations. In the configuration you can specify any augmentation from these lists and their parameters. + +Additionally, we support `Mosaic4` and `MixUp` batch augmentations and letterbox resizing if `keep_aspect_ratio: True`. + +| Key | Type | Default value | Description | +| ------------------- | ------------ | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `train_image_size` | `list[int]` | `[256, 256]` | Image size used for training as `[height, width]` | +| `keep_aspect_ratio` | `bool` | `True` | Whether to keep the aspect ratio while resizing | +| `train_rgb` | `bool` | `True` | Whether to train on RGB or BGR images | +| `normalize.active` | `bool` | `True` | Whether to use normalization | +| `normalize.params` | `dict` | `{}` | Parameters for normalization, see [Normalize](https://albumentations.ai/docs/api_reference/augmentations/transforms/#albumentations.augmentations.transforms.Normalize) | +| `augmentations` | `list[dict]` | `[]` | List of `Albumentations` augmentations | -Additionaly we support `Mosaic4` and `MixUp` batch augmentations and letterbox resizing if `keep_aspect_ratio: True`. +#### Augmentations -| Key | Type | Default value | Description | -| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| train_image_size | list\[int\] | \[256, 256\] | Image size used for training \[height, width\] | -| keep_aspect_ratio | bool | True | Bool if keep aspect ration while resizing | -| train_rgb | bool | True | Bool if train on rgb or bgr | -| normalize.active | bool | True | Bool if use normalization | -| normalize.params | dict | {} | Params for normalization, see [documentation](https://albumentations.ai/docs/api_reference/augmentations/transforms/#albumentations.augmentations.transforms.Normalize) | -| augmentations | list\[{"name": Name of the augmentation, "active": Bool if aug is active, by default set to True, "params": Parameters of the augmentation}\] | \[\] | List of Albumentations augmentations | +| Key | Type | Default value | Description | +| -------- | ------ | ------------------------ | ---------------------------------- | +| `name` | `str` | Name of the augmentation | | +| `active` | `bool` | `True` | Whether the augmentation is active | +| `params` | `dict` | `{}` | Parameters of the augmentation | ### Optimizer What optimizer to use for training. List of all optimizers can be found [here](https://pytorch.org/docs/stable/optim.html). -| Key | Type | Default value | Description | -| ------ | ---- | ------------- | ---------------------------- | -| name | str | "Adam" | Name of the optimizer. | -| params | dict | {} | Parameters of the optimizer. | +| Key | Type | Default value | Description | +| -------- | ------ | ------------- | --------------------------- | +| `name` | `str` | `"Adam"` | Name of the optimizer | +| `params` | `dict` | `{}` | Parameters of the optimizer | ### Scheduler What scheduler to use for training. List of all optimizers can be found [here](https://pytorch.org/docs/stable/optim.html#how-to-adjust-learning-rate). -| Key | Type | Default value | Description | -| ------ | ---- | ------------- | ---------------------------- | -| name | str | "ConstantLR" | Name of the scheduler. | -| params | dict | {} | Parameters of the scheduler. | +| Key | Type | Default value | Description | +| -------- | ------ | -------------- | --------------------------- | +| `name` | `str` | `"ConstantLR"` | Name of the scheduler | +| `params` | `dict` | `{}` | Parameters of the scheduler | ### Callbacks -Callbacks sections contains a list of callbacks. +Callbacks sections contain a list of callbacks. More information on callbacks and a list of available ones can be found [here](../luxonis_train/callbacks/README.md) Each callback is a dictionary with the following fields: -| Key | Type | Default value | Description | -| ------ | ---- | ------------- | --------------------------- | -| name | str | | Name of the callback. | -| active | bool | True | Whether calback is active. | -| params | dict | {} | Parameters of the callback. | +| Key | Type | Default value | Description | +| -------- | ------ | -------------------- | -------------------------- | +| `name` | `str` | Name of the callback | | +| `active` | `bool` | `True` | Whether callback is active | +| `params` | `dict` | `{}` | Parameters of the callback | ## Exporter Here you can define configuration for exporting. -| Key | Type | Default value | Description | -| ---------------------- | --------------------------------- | ------------- | ----------------------------------------------------------------------------------------------- | -| name | str \| None | None | Name of the exported model. | -| input_shape | list\[int\] \| None | None | Input shape of the model. If not provided, inferred from the dataset. | -| data_type | Literal\["INT8", "FP16", "FP32"\] | "FP16" | Data type of the exported model. Only used for conversion to BLOB. | -| reverse_input_channels | bool | True | Whether to reverse the image channels in the exported model. Relevant for `.blob` export | -| scale_values | list\[float\] \| None | None | What scale values to use for input normalization. If not provided, inferred from augmentations. | -| mean_values | list\[float\] \| None | None | What mean values to use for input normalizations. If not provided, inferred from augmentations. | -| upload_to_run | bool | True | Whether to upload the exported files to tracked run as artifact. | -| upload_url | str \| None | None | Exported model will be uploaded to this url if specified. | +| Key | Type | Default value | Description | +| ------------------------ | --------------------------------- | ------------- | ---------------------------------------------------------------------------------------------- | +| `name` | `str \| None` | `None` | Name of the exported model | +| `input_shape` | `list\[int\] \| None` | `None` | Input shape of the model. If not provided, inferred from the dataset | +| `data_type` | `Literal["INT8", "FP16", "FP32"]` | `"FP16"` | Data type of the exported model. Only used for conversion to BLOB | +| `reverse_input_channels` | `bool` | `True` | Whether to reverse the image channels in the exported model. Relevant for `.blob` export | +| `scale_values` | `list[float] \| None` | `None` | What scale values to use for input normalization. If not provided, inferred from augmentations | +| `mean_values` | `list[float] \| None` | `None` | What mean values to use for input normalization. If not provided, inferred from augmentations | +| `upload_to_run` | `bool` | `True` | Whether to upload the exported files to tracked run as artifact | +| `upload_url` | `str \| None` | `None` | Exported model will be uploaded to this URL if specified | -### ONNX +### `ONNX` -Option specific for ONNX export. +Option specific for `ONNX` export. -| Key | Type | Default value | Description | -| ------------- | ------------------------ | ------------- | -------------------------------- | -| opset_version | int | 12 | Which opset version to use. | -| dynamic_axes | dict\[str, Any\] \| None | None | Whether to specify dinamic axes. | +| Key | Type | Default value | Description | +| --------------- | ------------------------ | ------------- | --------------------------------- | +| `opset_version` | `int` | `12` | Which `ONNX` opset version to use | +| `dynamic_axes` | `dict[str, Any] \| None` | `None` | Whether to specify dynamic axes | ### Blob -| Key | Type | Default value | Description | -| ------- | ---------------------------------------------------------------- | ------------- | --------------------------------------- | -| active | bool | False | Whether to export to `.blob` format. | -| shaves | int | 6 | How many shaves. | -| version | Literal\["2021.2", "2021.3", "2021.4", "2022.1", "2022.3_RVC3"\] | "2022.1" | OpenVINO version to use for conversion. | +| Key | Type | Default value | Description | +| --------- | ---------------------------------------------------------------- | ------------- | ---------------------------------------- | +| `active` | `bool` | `False` | Whether to export to `BLOB` format | +| `shaves` | `int` | `6` | How many shaves | +| `version` | `Literal["2021.2", "2021.3", "2021.4", "2022.1", "2022.3_RVC3"]` | `"2022.1"` | `OpenVINO` version to use for conversion | ## Tuner Here you can specify options for tuning. -| Key | Type | Default value | Description | -| ---------------------- | ----------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| study_name | str | "test-study" | Name of the study. | -| continue_exising_study | bool | True | Whether to continue an existing study with this name. | -| use_pruner | bool | True | Whether to use the MedianPruner. | -| n_trials | int \| None | 15 | Number of trials for each process. `None` represents no limit in terms of numbner of trials. | -| timeout | int \| None | None | Stop study after the given number of seconds. | -| params | dict\[str, list\] | {} | Which parameters to tune. The keys should be in the format `key1.key2.key3_`. Type can be one of `[categorical, float, int, longuniform, uniform, subset]`. For more information about the types, visit [Optuna documentation](https://optuna.readthedocs.io/en/stable/reference/generated/optuna.trial.Trial.html). | +| Key | Type | Default value | Description | +| ------------------------ | ----------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `study_name` | `str` | `"test-study"` | Name of the study | +| `continue_exising_study` | `bool` | `True` | Whether to continue an existing study with this name | +| `use_pruner` | `bool` | `True` | Whether to use the `MedianPruner` | +| `n_trials` | `int \| None` | `15` | Number of trials for each process. `None` represents no limit in terms of number of trials | +| `timeout` | `int \| None` | `None` | Stop study after the given number of seconds | +| `params` | `dict[str, list]` | `{}` | Which parameters to tune. The keys should be in the format `key1.key2.key3_`. Type can be one of `[categorical, float, int, longuniform, uniform, subset]`. For more information about the types, visit [`Optuna` documentation](https://optuna.readthedocs.io/en/stable/reference/generated/optuna.trial.Trial.html) | **Note**: "subset" sampling is currently only supported for augmentations. You can specify a set of augmentations defined in `trainer` to choose from and every run subset of random N augmentations will be active (`is_active` parameter will be True for chosen ones and False for the rest in the set). -Example of params for tuner block: +Example of parameters for tuner block: ```yaml tuner: @@ -280,10 +289,10 @@ tuner: ### Storage -| Key | Type | Default value | Description | -| ------------ | ---------------------------- | ------------- | ---------------------------------------------------- | -| active | bool | True | Whether to use storage to make the study persistent. | -| storage_type | Literal\["local", "remote"\] | "local" | Type of the storage. | +| Key | Type | Default value | Description | +| -------------- | ---------------------------- | ------------- | --------------------------------------------------- | +| `active` | `bool` | `True` | Whether to use storage to make the study persistent | +| `storage_type` | `Literal["local", "remote"]` | `"local"` | Type of the storage | ## ENVIRON @@ -294,23 +303,22 @@ For more info on the variables, see [Credentials](../README.md#credentials). This is not a recommended way due to possible leakage of secrets. This section is intended for testing purposes only. -| Key | Type | Default value | Description | -| ------------------------ | ---------------------------------------------------------- | -------------- | ----------- | -| AWS_ACCESS_KEY_ID | str \| None | None | | -| AWS_SECRET_ACCESS_KEY | str \| None | None | | -| AWS_S3_ENDPOINT_URL | str \| None | None | | -| MLFLOW_CLOUDFLARE_ID | str \| None | None | | -| MLFLOW_CLOUDFLARE_SECRET | str \| None | None | | -| MLFLOW_S3_BUCKET | str \| None | None | | -| MLFLOW_S3_ENDPOINT_URL | str \| None | None | | -| MLFLOW_TRACKING_URI | str \| None | None | | -| POSTGRES_USER | str \| None | None | | -| POSTGRES_PASSWORD | str \| None | None | | -| POSTGRES_HOST | str \| None | None | | -| POSTGRES_PORT | str \| None | None | | -| POSTGRES_DB | str \| None | None | | -| LUXONISML_BUCKET | str \| None | None | | -| LUXONISML_BASE_PATH | str | "~/luxonis_ml" | | -| LUXONISML_TEAM_ID | str | "offline" | | -| LUXONISML_TEAM_NAME | str | "offline" | | -| LOG_LEVEL | Literal\["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"\] | "INFO" | | +| Key | Type | Default value | +| -------------------------- | ---------------------------------------------------------- | ---------------- | +| `AWS_ACCESS_KEY_ID` | `str \| None` | `None` | +| `AWS_SECRET_ACCESS_KEY` | `str \| None` | `None` | +| `AWS_S3_ENDPOINT_URL` | `str \| None` | `None` | +| `MLFLOW_CLOUDFLARE_ID` | `str \| None` | `None` | +| `MLFLOW_CLOUDFLARE_SECRET` | `str \| None` | `None` | +| `MLFLOW_S3_BUCKET` | `str \| None` | `None` | +| `MLFLOW_S3_ENDPOINT_URL` | `str \| None` | `None` | +| `MLFLOW_TRACKING_URI` | `str \| None` | `None` | +| `POSTGRES_USER` | `str \| None` | `None` | +| `POSTGRES_PASSWORD` | `str \| None` | `None` | +| `POSTGRES_HOST` | `str \| None` | `None` | +| `POSTGRES_PORT` | `str \| None` | `None` | +| `POSTGRES_DB` | `str \| None` | `None` | +| `LUXONISML_BUCKET` | `str \| None` | `None` | +| `LUXONISML_BASE_PATH` | `str` | `"~/luxonis_ml"` | +| `LUXONISML_TEAM_ID` | `str` | `"offline"` | +| `LOG_LEVEL` | `Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]` | `"INFO"` | diff --git a/configs/complex_model.yaml b/configs/complex_model.yaml index 1ba11dd1..b27a86ea 100644 --- a/configs/complex_model.yaml +++ b/configs/complex_model.yaml @@ -15,7 +15,7 @@ model: - RepPANNeck losses: - name: EfficientKeypointBboxLoss + - name: EfficientKeypointBboxLoss metrics: - name: ObjectKeypointSimilarity @@ -23,22 +23,22 @@ model: - name: MeanAveragePrecisionKeypoints visualizers: - name: MultiVisualizer - params: - visualizers: - - name: KeypointVisualizer - params: - nonvisible_color: blue - - name: BBoxVisualizer - params: - colors: - person: "#FF5055" + - name: MultiVisualizer + params: + visualizers: + - name: KeypointVisualizer + params: + nonvisible_color: blue + - name: BBoxVisualizer + params: + colors: + person: "#FF5055" - name: SegmentationHead inputs: - RepPANNeck losses: - name: BCEWithLogitsLoss + - name: BCEWithLogitsLoss metrics: - name: F1Score params: @@ -47,9 +47,9 @@ model: params: task: binary visualizers: - name: SegmentationVisualizer - params: - colors: "#FF5055" + - name: SegmentationVisualizer + params: + colors: "#FF5055" - name: EfficientBBoxHead inputs: @@ -58,11 +58,11 @@ model: conf_thres: 0.75 iou_thres: 0.45 losses: - name: AdaptiveDetectionLoss + - name: AdaptiveDetectionLoss metrics: - name: MeanAveragePrecision + - name: MeanAveragePrecision visualizers: - name: BBoxVisualizer + - name: BBoxVisualizer tracker: project_name: coco_test diff --git a/luxonis_train/attached_modules/losses/README.md b/luxonis_train/attached_modules/losses/README.md index a8a982ba..724174c7 100644 --- a/luxonis_train/attached_modules/losses/README.md +++ b/luxonis_train/attached_modules/losses/README.md @@ -4,97 +4,97 @@ List of all the available loss functions. ## Table Of Contents -- [CrossEntropyLoss](#crossentropyloss) -- [BCEWithLogitsLoss](#bcewithlogitsloss) -- [SmoothBCEWithLogitsLoss](#smoothbcewithlogitsloss) -- [SigmoidFocalLoss](#sigmoidfocalloss) -- [SoftmaxFocalLoss](#softmaxfocalloss) -- [AdaptiveDetectionLoss](#adaptivedetectionloss) -- [EfficientKeypointBBoxLoss](#efficientkeypointbboxloss) +- [`CrossEntropyLoss`](#crossentropyloss) +- [`BCEWithLogitsLoss`](#bcewithlogitsloss) +- [`SmoothBCEWithLogitsLoss`](#smoothbcewithlogitsloss) +- [`SigmoidFocalLoss`](#sigmoidfocalloss) +- [`SoftmaxFocalLoss`](#softmaxfocalloss) +- [`AdaptiveDetectionLoss`](#adaptivedetectionloss) +- [`EfficientKeypointBBoxLoss`](#efficientkeypointbboxloss) -## CrossEntropyLoss +## `CrossEntropyLoss` Adapted from [here](https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| --------------- | -------------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| weight | list\[float\] \| None | None | A manual rescaling weight given to each class. If given, it has to be a list of the same length as there are classes. | -| reduction | Literal\["none", "mean", "sum"\] | "mean" | Specifies the reduction to apply to the output. | -| label_smoothing | float\[0.0, 1.0\] | 0.0 | Specifies the amount of smoothing when computing the loss, where 0.0 means no smoothing. The targets become a mixture of the original ground truth and a uniform distribution as described in [Rethinking the Inception Architecture for Computer Vision](https://arxiv.org/abs/1512.00567). | +| Key | Type | Default value | Description | +| ----------------- | -------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `weight` | `list[float] \| None` | `None` | A manual rescaling weight given to each class. If given, it has to be a list of the same length as there are classes | +| `reduction` | `Literal["none", "mean", "sum"]` | `"mean"` | Specifies the reduction to apply to the output | +| `label_smoothing` | `float` $\\in \[0.0, 1.0\]$ | `0.0` | Specifies the amount of smoothing when computing the loss, where 0.0 means no smoothing. The targets become a mixture of the original ground truth and a uniform distribution as described in [Rethinking the Inception Architecture for Computer Vision](https://arxiv.org/abs/1512.00567) | -## BCEWithLogitsLoss +## `BCEWithLogitsLoss` Adapted from [here](https://pytorch.org/docs/stable/generated/torch.nn.BCEWithLogitsLoss.html). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ---------- | -------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------ | -| weight | list\[float\] \| None | None | A manual rescaling weight given to each class. If given, has to be a list of the same length as there are classes. | -| reduction | Literal\["none", "mean", "sum"\] | "mean" | Specifies the reduction to apply to the output. | -| pos_weight | Tensor \| None | None | A weight of positive examples to be broadcasted with target. | +| Key | Type | Default value | Description | +| ------------ | -------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------- | +| `weight` | `list[float] \| None` | `None` | A manual rescaling weight given to each class. If given, has to be a list of the same length as there are classes | +| `reduction` | `Literal["none", "mean", "sum"]` | `"mean"` | Specifies the reduction to apply to the output | +| `pos_weight` | `Tensor \| None` | `None` | A weight of positive examples to be broadcasted with target | -## SmoothBCEWithLogitsLoss +## `SmoothBCEWithLogitsLoss` -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| --------------- | -------------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| weight | list\[float\] \| None | None | A manual rescaling weight given to each class. If given, has to be a list of the same length as there are classes. | -| reduction | Literal\["none", "mean", "sum"\] | "mean" | Specifies the reduction to apply to the output. | -| label_smoothing | float\[0.0, 1.0\] | 0.0 | Specifies the amount of smoothing when computing the loss, where 0.0 means no smoothing. The targets become a mixture of the original ground truth and a uniform distribution as described in [Rethinking the Inception Architecture for Computer Vision](https://arxiv.org/abs/1512.00567). | -| bce_pow | float | 1.0 | Weight for the positive samples. | +| Key | Type | Default value | Description | +| ----------------- | -------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `weight` | `list[float] \| None` | `None` | A manual rescaling weight given to each class. If given, has to be a list of the same length as there are classes | +| `reduction` | `Literal["none", "mean", "sum"]` | `"mean"` | Specifies the reduction to apply to the output | +| `label_smoothing` | `float` $\\in \[0.0, 1.0\]$ | `0.0` | Specifies the amount of smoothing when computing the loss, where 0.0 means no smoothing. The targets become a mixture of the original ground truth and a uniform distribution as described in [Rethinking the Inception Architecture for Computer Vision](https://arxiv.org/abs/1512.00567) | +| `bce_pow` | `float` | `1.0` | Weight for the positive samples | -## SigmoidFocalLoss +## `SigmoidFocalLoss` Adapted from [here](https://pytorch.org/vision/stable/generated/torchvision.ops.sigmoid_focal_loss.html#torchvision.ops.sigmoid_focal_loss). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| --------- | -------------------------------- | ------------- | ------------------------------------------------------------------------------------------ | -| alpha | float | 0.25 | Weighting factor in range (0,1) to balance positive vs negative examples or -1 for ignore. | -| gamma | float | 2.0 | Exponent of the modulating factor $(1 - p_t)$ to balance easy vs hard examples | -| reduction | Literal\["none", "mean", "sum"\] | "mean" | Specifies the reduction to apply to the output. | +| Key | Type | Default value | Description | +| ----------- | -------------------------------- | ------------- | ------------------------------------------------------------------------------------------- | +| `alpha` | `float` | `0.25` | Weighting factor in range $(0,1)$ to balance positive vs negative examples or -1 for ignore | +| `gamma` | `float` | `2.0` | Exponent of the modulating factor $(1 - p_t)$ to balance easy vs hard examples | +| `reduction` | `Literal["none", "mean", "sum"]` | `"mean"` | Specifies the reduction to apply to the output | -## SoftmaxFocalLoss +## `SoftmaxFocalLoss` -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| --------- | -------------------------------- | ------------- | ----------------------------------------------------------------------------- | -| alpha | float \| list | 0.25 | Either a float for all channels or list of alphas for each channel. | -| gamma | float | 2.0 | Exponent of the modulating factor (1 - p_t) to balance easy vs hard examples. | -| reduction | Literal\["none", "mean", "sum"\] | "mean" | Specifies the reduction to apply to the output. | +| Key | Type | Default value | Description | +| ----------- | -------------------------------- | ------------- | ------------------------------------------------------------------------------ | +| `alpha` | `float \| list` | `0.25` | Either a float for all channels or list of alphas for each channel | +| `gamma` | `float` | `2.0` | Exponent of the modulating factor $(1 - p_t)$ to balance easy vs hard examples | +| `reduction` | `Literal["none", "mean", "sum"]` | `"mean"` | Specifies the reduction to apply to the output | -## AdaptiveDetectionLoss +## `AdaptiveDetectionLoss` Adapted from [here](https://arxiv.org/pdf/2209.02976.pdf). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ----------------- | ------------------------------------------------- | ------------- | ----------------------------------------------------------------------------------- | -| n_warmup_epochs | int | 4 | Number of epochs where ATSS assigner is used, after that we switch to TAL assigner. | -| iou_type | Literal\["none", "giou", "diou", "ciou", "siou"\] | "giou" | IoU type used for bbox regression loss. | -| class_loss_weight | float | 1.0 | Weight used for the classification part of the loss. | -| iou_loss_weight | float | 2.5 | Weight used for the IoU part of the loss. | +| Key | Type | Default value | Description | +| ------------------- | ------------------------------------------------- | ------------- | -------------------------------------------------------------------------------------- | +| `n_warmup_epochs` | `int` | `4` | Number of epochs where `ATSS` assigner is used, after that we switch to `TAL` assigner | +| `iou_type` | `Literal["none", "giou", "diou", "ciou", "siou"]` | `"giou"` | `IoU` type used for bounding box regression loss | +| `class_loss_weight` | `float` | `1.0` | Weight used for the classification part of the loss | +| `iou_loss_weight` | `float` | `2.5` | Weight used for the `IoU` part of the loss | -## EfficientKeypointBBoxLoss +## `EfficientKeypointBBoxLoss` Adapted from [YOLO-Pose: Enhancing YOLO for Multi Person Pose Estimation Using Object Keypoint Similarity Loss](https://arxiv.org/ftp/arxiv/papers/2204/2204.06806.pdf). -| Key | Type | Default value | Description | -| --------------------- | ------------------------------------------------- | ------------- | --------------------------------------------------------------------------------------------------- | -| n_warmup_epochs | int | 4 | Number of epochs where ATSS assigner is used, after that we switch to TAL assigner. | -| iou_type | Literal\["none", "giou", "diou", "ciou", "siou"\] | "giou" | IoU type used for bbox regression sub-loss | -| reduction | Literal\["mean", "sum"\] | "mean" | Specifies the reduction to apply to the output. | -| class_loss_weight | float | 1.0 | Weight used for the classification sub-loss. | -| iou_loss_weight | float | 2.5 | Weight used for the IoU sub-loss. | -| regr_kpts_loss_weight | float | 1.5 | Weight used for the OKS sub-loss. | -| vis_kpts_loss_weight | float | 1.0 | Weight used for the keypoint visibility sub-loss. | -| sigmas | list\[float\] \\ None | None | Sigmas used in KeypointLoss for OKS metric. If None then use COCO ones if possible or default ones. | -| area_factor | float \| None | None | Factor by which we multiply bbox area which is used in KeypointLoss. If None then use default one. | +| Key | Type | Default value | Description | +| ----------------------- | ------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------- | +| `n_warmup_epochs` | `int` | `4` | Number of epochs where `ATSS` assigner is used, after that we switch to `TAL` assigner | +| `iou_type` | `Literal["none", "giou", "diou", "ciou", "siou"]` | `"giou"` | `IoU` type used for bounding box regression sub-loss | +| `reduction` | `Literal["mean", "sum"]` | `"mean"` | Specifies the reduction to apply to the output | +| `class_loss_weight` | `float` | `1.0` | Weight used for the classification sub-loss | +| `iou_loss_weight` | `float` | `2.5` | Weight used for the `IoU` sub-loss | +| `regr_kpts_loss_weight` | `float` | `1.5` | Weight used for the `OKS` sub-loss | +| `vis_kpts_loss_weight` | `float` | `1.0` | Weight used for the keypoint visibility sub-loss | +| `sigmas` | `list[float] \ None` | `None` | Sigmas used in `KeypointLoss` for `OKS` metric. If `None` then use COCO ones if possible or default ones | +| `area_factor` | `float \| None` | `None` | Factor by which we multiply bounding box area which is used in `KeypointLoss.` If `None` then use default one | diff --git a/luxonis_train/attached_modules/metrics/README.md b/luxonis_train/attached_modules/metrics/README.md index 17735540..b61f4843 100644 --- a/luxonis_train/attached_modules/metrics/README.md +++ b/luxonis_train/attached_modules/metrics/README.md @@ -23,6 +23,14 @@ Metrics from the [`torchmetrics`](https://lightning.ai/docs/torchmetrics/stable/ For more information, see [object-keypoint-similarity](https://learnopencv.com/object-keypoint-similarity/). +**Params** + +| Key | Type | Default value | Description | +| ------------------ | --------------------- | ------------- | --------------------------------------------------------------------- | +| `sigmas` | `list[float] \| None` | `None` | List of sigmas for each keypoint. If `None`, the COCO sigmas are used | +| `area_factor` | `float` | `0.53` | Factor by which to multiply the bounding box area | +| `use_cocoeval_oks` | `bool` | `True` | Whether to use the same OKS formula as in COCO evaluation | + ## MeanAveragePrecision Compute the `Mean-Average-Precision (mAP) and Mean-Average-Recall (mAR)` for object detection predictions. @@ -43,4 +51,13 @@ boxes. Similar to [MeanAveragePrecision](#meanaverageprecision), but uses [OKS](#objectkeypointsimilarity) as `IoU` measure. For a deeper understanding of how OKS works, please refer to the detailed explanation provided [here](https://learnopencv.com/object-keypoint-similarity/). -Evaluation leverages COCO evaluation framework (COCOeval) to assess mAP performance. +Evaluation leverages COCO evaluation framework (COCOeval) to assess mAP performance. + +**Params** + +| Key | Type | Default value | Description | +| ------------- | ----------------------------------- | ------------- | --------------------------------------------------------------------- | +| `sigmas` | `list[float] \| None` | `None` | List of sigmas for each keypoint. If `None`, the COCO sigmas are used | +| `area_factor` | `float` | `0.53` | Factor by which to multiply the bounding box area | +| `max_dets` | `int` | `20` | Maximum number of detections per image | +| `box_fotmat` | `Literal["xyxy", "xywh", "cxcywh"]` | `"xyxy"` | Format of the bounding boxes | diff --git a/luxonis_train/attached_modules/visualizers/README.md b/luxonis_train/attached_modules/visualizers/README.md index 8bedaed9..1fca42e2 100644 --- a/luxonis_train/attached_modules/visualizers/README.md +++ b/luxonis_train/attached_modules/visualizers/README.md @@ -1,87 +1,88 @@ # Visualizers +Visualizers are used to render the output of a node. They are used in the `visualizers` field of the `Node` configuration. + ## Table Of Contents -- [BBoxVisualizer](#bboxvisualizer) -- [ClassificationVisualizer](#classificationvisualizer) -- [KeypointVisualizer](#keypointvisualizer) -- [SegmentationVisualizer](#segmentationvisualizer) -- [MultiVisualizer](#multivisualizer) +- [`BBoxVisualizer`](#bboxvisualizer) +- [`ClassificationVisualizer`](#classificationvisualizer) +- [`KeypointVisualizer`](#keypointvisualizer) +- [`MultiVisualizer`](#multivisualizer) -## BBoxVisualizer +## `BBoxVisualizer` Visualizer for bounding boxes. -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| --------- | ------------------------------------------------------------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| labels | dict\[int, str\] \| list\[str\] \| None | None | Either a dictionary mapping class indices to names, or a list of names. If list is provided, the label mapping is done by index. By default, no labels are drawn. | -| colors | dict\[int, tuple\[int, int, int\] \| str\] \| list\[tuple\[int, int, int\] \| str\] \| None | None | Colors to use for the boundig boxes. Either a dictionary mapping class names to colors, or a list of colors. | -| fill | bool | False | Whether or not to fill the bounding boxes. | -| width | int | 1 | The width of the bounding box lines. | -| font | str \| None | None | A filename containing a TrueType font. | -| font_size | int \| None | None | Font size used for the labels. | +| Key | Type | Default value | Description | +| ----------- | ------------------------------------------------------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `labels` | `dict[int, str] \| list[str] \| None` | `None` | Either a dictionary mapping class indices to names, or a list of names. If list is provided, the label mapping is done by index. By default, no labels are drawn | +| `colors` | `dict[int, tuple[int, int, int] \| str] \| list[tuple[int, int, int] \| str] \| None` | `None` | Colors to use for the bounding boxes. Either a dictionary mapping class names to colors, or a list of colors. Color can be either a tuple of RGB values or a hex string | +| `fill` | `bool` | `False` | Whether to fill the bounding boxes | +| `width` | `int` | `1` | The width of the bounding box lines | +| `font` | `str \| None` | `None` | A filename containing a `TrueType` font | +| `font_size` | `int \| None` | `None` | Font size used for the labels | -**Example** +**Example:** -![bbox_viz_example](https://github.com/luxonis/luxonis-train/blob/main/media/example_viz/bbox.png) +![bounding_box_viz_example](https://github.com/luxonis/luxonis-train/blob/main/media/example_viz/bbox.png) -## KeypointVisualizer +## `KeypointVisualizer` -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| -------------------- | -------------------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------- | -| visibility_threshold | float | 0.5 | Threshold for visibility of keypoints. If the visibility of a keypoint is below this threshold, it is considered as not visible. | -| connectivity | list\[tuple\[int, int\]\] \| None | None | List of tuples of keypoint indices that define the connections in the skeleton. | -| visible_color | str \| tuple\[int, int, int\] | "red" | Color of visible keypoints. | -| nonvisible_color | str \| tuple\[int, int, int \] \| None | None | Color of nonvisible keypoints. If None, nonvisible keypoints are not drawn. | +| Key | Type | Default value | Description | +| ---------------------- | -------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| `visibility_threshold` | `float` | `0.5` | Threshold for visibility of keypoints. If the visibility of a keypoint is below this threshold, it is considered as not visible | +| `connectivity` | `list[tuple[int, int]] \| None` | `None` | List of tuples of keypoint indices that define the connections in the skeleton | +| `visible_color` | `str \| tuple[int, int, int]` | `"red"` | Color of visible keypoints | +| `nonvisible_color` | `str \| tuple[int, int, int ] \| None` | `None` | Color of non-visible keypoints. If `None`, non-visible keypoints are not drawn | -**Example** +**Example:** -![kpt_viz_example](https://github.com/luxonis/luxonis-train/blob/main/media/example_viz/kpts.png) +![keypoints_viz_example](https://github.com/luxonis/luxonis-train/blob/main/media/example_viz/kpts.png) -## SegmentationVisualizer +## `SegmentationVisualizer` -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ----- | ----------------------------- | ------------- | -------------------------------------- | -| color | str \| tuple\[int, int, int\] | #5050FF | Color of the segmentation masks. | -| alpha | float | 0.6 | Alpha value of the segmentation masks. | +| Key | Type | Default value | Description | +| ------- | ----------------------------- | ------------- | ------------------------------------- | +| `color` | `str \| tuple[int, int, int]` | `"#5050FF"` | Color of the segmentation masks | +| `alpha` | `float` | `0.6` | Alpha value of the segmentation masks | -**Example** +**Example:** -![seg_viz_example](https://github.com/luxonis/luxonis-train/blob/main/media/example_viz/segmentation.png) +![segmentation_viz_example](https://github.com/luxonis/luxonis-train/blob/main/media/example_viz/segmentation.png) -## ClassificationVisualizer +## `ClassificationVisualizer` -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ------------ | ---------------------- | ------------- | -------------------------------------------------------------------------- | -| include_plot | bool | True | Whether to include a plot of the class probabilities in the visualization. | -| color | tuple\[int, int, int\] | (255, 0, 0) | Color of the text. | -| font_scale | float | 1.0 | Scale of the font. | -| thickness | int | 1 | Line thickness of the font. | +| Key | Type | Default value | Description | +| -------------- | ---------------------- | ------------- | ------------------------------------------------------------------------- | +| `include_plot` | `bool` | `True` | Whether to include a plot of the class probabilities in the visualization | +| `color` | `tuple[int, int, int]` | `(255, 0, 0)` | Color of the text | +| `font_scale` | `float` | `1.0` | Scale of the font | +| `thickness` | `int` | `1` | Line thickness of the font | -**Example** +**Example:** ![class_viz_example](https://github.com/luxonis/luxonis-train/blob/main/media/example_viz/class.png) -## MultiVisualizer +## `MultiVisualizer` Special type of meta-visualizer that combines several visualizers into one. The combined visualizers share canvas. -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ----------- | ------------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| visualizers | list\[dict\] | \[ \] | List of visualizers to combine. Each item in the list is a dictionary with the following keys:
- name (str): Name of the visualizer. Must be a key in the VISUALIZERS registry.
- params (dict): Parameters to pass to the visualizer. | +| Key | Type | Default value | Description | +| ------------- | ------------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `visualizers` | `list[dict]` | `[]` | List of visualizers to combine. Each item in the list is a dictionary with the following keys:
- `"name"` (`str`): Name of the visualizer. Must be a key in the `VISUALIZERS` registry.
- `"params"` (`dict`): Parameters to pass to the visualizer | -**Example** +**Example:** -Example of combining [KeypointVisualizer](#keypointvisualizer) and [BBoxVisualizer](#bboxvisualizer). +Example of combining [`KeypointVisualizer`](#keypointvisualizer) and [`BBoxVisualizer`](#bboxvisualizer). ![multi_viz_example](https://github.com/luxonis/luxonis-train/blob/main/media/example_viz/multi.png) diff --git a/luxonis_train/callbacks/README.md b/luxonis_train/callbacks/README.md index dc015ccd..64fbdf4f 100644 --- a/luxonis_train/callbacks/README.md +++ b/luxonis_train/callbacks/README.md @@ -4,54 +4,64 @@ List of all supported callbacks. ## Table Of Contents -- [PytorchLightning Callbacks](#pytorchlightning-callbacks) -- [ExportOnTrainEnd](#exportontrainend) -- [LuxonisProgressBar](#luxonisprogressbar) -- [MetadataLogger](#metadatalogger) -- [TestOnTrainEnd](#testontrainend) -- [UploadCheckpoint](#uploadcheckpoint) +- [`PytorchLightning` Callbacks](#pytorchlightning-callbacks) +- [`ExportOnTrainEnd`](#exportontrainend) +- [`ArchiveOnTrainEnd`](#archiveontrainend) +- [`MetadataLogger`](#metadatalogger) +- [`TestOnTrainEnd`](#testontrainend) +- [`UploadCheckpoint`](#uploadcheckpoint) -## PytorchLightning Callbacks +## `PytorchLightning` Callbacks List of supported callbacks from `lightning.pytorch`. -- [GPUStatsMonitor](https://pytorch-lightning.readthedocs.io/en/1.5.10/api/pytorch_lightning.callbacks.gpu_stats_monitor.html) -- [DeviceStatsMonitor](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.callbacks.DeviceStatsMonitor.html#lightning.pytorch.callbacks.DeviceStatsMonitor) -- [EarlyStopping](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.callbacks.EarlyStopping.html#lightning.pytorch.callbacks.EarlyStopping) -- [LearningRateMonitor](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.callbacks.LearningRateMonitor.html#lightning.pytorch.callbacks.LearningRateMonitor) -- [ModelCheckpoint](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.callbacks.ModelCheckpoint.html#lightning.pytorch.callbacks.ModelCheckpoint) -- [RichModelSummary](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.callbacks.RichModelSummary.html#lightning.pytorch.callbacks.RichModelSummary) +- [`GPUStatsMonitor`](https://pytorch-lightning.readthedocs.io/en/1.5.10/api/pytorch_lightning.callbacks.gpu_stats_monitor.html) +- [`DeviceStatsMonitor`](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.callbacks.DeviceStatsMonitor.html#lightning.pytorch.callbacks.DeviceStatsMonitor) +- [`EarlyStopping`](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.callbacks.EarlyStopping.html#lightning.pytorch.callbacks.EarlyStopping) +- [`LearningRateMonitor`](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.callbacks.LearningRateMonitor.html#lightning.pytorch.callbacks.LearningRateMonitor) +- [`ModelCheckpoint`](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.callbacks.ModelCheckpoint.html#lightning.pytorch.callbacks.ModelCheckpoint) +- [`RichModelSummary`](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.callbacks.RichModelSummary.html#lightning.pytorch.callbacks.RichModelSummary) +- [`GradientAccumulationScheduler`](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.callbacks.GradientAccumulationScheduler.html#lightning.pytorch.callbacks.GradientAccumulationScheduler) +- [`StochasticWeightAveraging`](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.callbacks.StochasticWeightAveraging.html#lightning.pytorch.callbacks.StochasticWeightAveraging) +- [`Timer`](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.callbacks.Timer.html#lightning.pytorch.callbacks.Timer) +- [`ModelPruning`](https://lightning.ai/docs/pytorch/stable/api/lightning.pytorch.callbacks.ModelPruning.html#lightning.pytorch.callbacks.ModelPruning) -## ExportOnTrainEnd +## `ExportOnTrainEnd` Performs export on train end with best weights. -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| -------------------- | --------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------- | -| preferred_checkpoint | Literal\["metric", "loss"\] | metric | Which checkpoint should we use. If preferred is not available then try to use the other one if its present. | +| Key | Type | Default value | Description | +| ---------------------- | --------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `preferred_checkpoint` | `Literal["metric", "loss"]` | `"metric"` | Which checkpoint should the callback use. If the preferred checkpoint is not available, the other option is used. If none is available, the callback is skipped | -## LuxonisProgressBar +## `ArchiveOnTrainEnd` -Custom rich text progress bar based on RichProgressBar from Pytorch Lightning. +Callback to create an `NN Archive` at the end of the training. -## MetadataLogger +**Parameters:** + +| Key | Type | Default value | Description | +| ---------------------- | --------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `preferred_checkpoint` | `Literal["metric", "loss"]` | `"metric"` | Which checkpoint should the callback use. If the preferred checkpoint is not available, the other option is used. If none is available, the callback is skipped | + +## `MetadataLogger` Callback that logs training metadata. Metadata include all defined hyperparameters together with git hashes of `luxonis-ml` and `luxonis-train` packages. Also stores this information locally. -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ----------- | ----------- | ------------- | ----------------------------------------------------------------------------------------------------------------------- | -| hyperparams | list\[str\] | \[\] | List of hyperparameters to log. The hyperparameters are provided as config keys in dot notation. E.g. "trainer.epochs". | +| Key | Type | Default value | Description | +| ------------- | ----------- | ------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `hyperparams` | `list[str]` | `[]` | List of hyperparameters to log. The hyperparameters are provided as config keys in dot notation. _E.g._ `"trainer.epochs"` | -## TestOnTrainEnd +## `TestOnTrainEnd` Callback to perform a test run at the end of the training. -## UploadCheckpoint +## `UploadCheckpoint` -Callback that uploads currently best checkpoint (based on validation loss) to the tracker location - where all other logs are stored. +Callback that uploads currently the best checkpoint (based on validation loss) to the tracker location - where all other logs are stored. diff --git a/luxonis_train/config/predefined_models/README.md b/luxonis_train/config/predefined_models/README.md index 3733534d..27976b3a 100644 --- a/luxonis_train/config/predefined_models/README.md +++ b/luxonis_train/config/predefined_models/README.md @@ -1,150 +1,150 @@ # Predefined models -In addition to definig the model by hand, we offer a list of simple predefined +In addition to defining the model by hand, we offer a list of simple predefined models which can be used instead. ## Table Of Contents -- [SegmentationModel](#segmentationmodel) -- [DetectionModel](#detectionmodel) -- [KeypointDetectionModel](#keypointdetectionmodel) -- [ClassificationModel](#classificationmodel) - -**Params** - -| Key | Type | Default value | Description | -| ------------------- | ---------------- | ------------- | --------------------------------------------------------------------- | -| name | str | | Name of the predefined architecture. See below the available options. | -| params | dict\[str, Any\] | {} | Additional parameters of the predefined model. | -| include_nodes | bool | True | Whether to include nodes of the model. | -| include_losses | bool | True | Whether to include loss functions. | -| include_metrics | bool | True | Whether to include metrics. | -| include_visualizers | bool | True | Whether to include visualizers. | - -## SegmentationModel - -The `SegmentationModel` allows for both "light" and "heavy" variants, where the "heavy" variant is more accurate, and the "light" variant is faster. - -See an example configuration file using this predefined model [here](../../../configs/segmentation_light_model.yaml) for the "light" variant, and [here](../../../configs/segmentation_heavy_model.yaml) for the "heavy" variant. - -**Components** - -| Name | Alias | Function | -| --------------------------------------------------------------------------------------------- | -------------------------- | -------------------------------------------------------------------------------------------- | -| [DDRNet](../../nodes/README.md#ddrnet) | segmentation_backbone | Backbone of the model. Available variants: "light" (DDRNet-23-slim) and "heavy" (DDRNet-23). | -| [SegmentationHead](../../nodes/README.md#segmentationhead) | segmentation_head | Head of the model. | -| [BCEWithLogitsLoss](../../attached_modules/losses/README.md#bcewithlogitsloss) | segmentation_loss | Loss of the model when the task is set to "binary". | -| [CrossEntropyLoss](../../attached_modules/losses/README.md#crossentropyloss) | segmentation_loss | Loss of the model when the task is set to "multiclass" or "multilabel". | -| [JaccardIndex](../../attached_modules/metrics/README.md#torchmetrics) | segmentation_jaccard_index | Main metric of the model. | -| [F1Score](../../attached_modules/metrics/README.md#torchmetrics) | segmentation_f1_score | Secondary metric of the model. | -| [SegmentationVisualizer](../../attached_modules/visualizers/README.md#segmentationvisualizer) | segmentation_visualizer | Visualizer of the `SegmentationHead`. | - -**Params** - -| Key | Type | Default value | Description | -| ----------------- | --------------------------------- | ------------- | ------------------------------------------------------------------------------------------------ | -| variant | Literal\["light", "heavy"\] | "light" | Defines the variant of the model. "light" uses DDRNet-23-slim, "heavy" uses DDRNet-23. | -| backbone | str | "DDRNet" | Name of the node to be used as a backbone. | -| backbone_params | dict | {} | Additional parameters for the backbone. If not provided, variant-specific defaults will be used. | -| head_params | dict | {} | Additional parameters for the head. | -| aux_head_params | dict | {} | Additional parameters for auxiliary heads. | -| loss_params | dict | {} | Additional parameters for the loss. | -| visualizer_params | dict | {} | Additional parameters for the visualizer. | -| task | Literal\["binary", "multiclass"\] | "binary" | Type of the task of the model. | -| task_name | str \| None | None | Custom task name for the head. | - -## DetectionModel - -The `DetectionModel` allows for both "light" and "heavy" variants, where the "heavy" variant is more accurate, and the "light" variant is faster. - -See an example configuration file using this predefined model [here](../../../configs/detection_light_model.yaml) for the "light" variant, and [here](../../../configs/detection_heavy_model.yaml) for the "heavy" variant. - -**Components** - -| Name | Alias | Function | -| -------------------------------------------------------------------------------------- | -------------------- | ------------------------------------------------------------------------------------------------- | -| [EfficientRep](../../nodes/README.md#efficientrep) | detection_backbone | Backbone of the model. Available variants: "light" (EfficientRep-N) and "heavy" (EfficientRep-L). | -| [RepPANNeck](../../nodes/README.md#reppanneck) | detection_neck | Neck of the model. | -| [EfficientBBoxHead](../../nodes/README.md#efficientbboxhead) | detection_head | Head of the model. | -| [AdaptiveDetectionLoss](../../attached_modules/losses/README.md#adaptivedetectionloss) | detection_loss | Loss of the model. | -| [MeanAveragePrecision](../../attached_modules/metrics/README.md#meanaverageprecision) | detection_map | Main metric of the model. | -| [BBoxVisualizer](../../attached_modules/visualizers/README.md#bboxvisualizer) | detection_visualizer | Visualizer of the `detection_head`. | - -**Params** - -| Key | Type | Default value | Description | -| ----------------- | --------------------------- | -------------- | ------------------------------------------------------------------------------------------- | -| variant | Literal\["light", "heavy"\] | "light" | Defines the variant of the model. "light" uses EfficientRep-N, "heavy" uses EfficientRep-L. | -| use_neck | bool | True | Whether to include the neck in the model. | -| backbone | str | "EfficientRep" | Name of the node to be used as a backbone. | -| backbone_params | dict | {} | Additional parameters to the backbone. | -| neck_params | dict | {} | Additional parameters to the neck. | -| head_params | dict | {} | Additional parameters to the head. | -| loss_params | dict | {} | Additional parameters to the loss. | -| visualizer_params | dict | {} | Additional parameters to the visualizer. | -| task_name | str \| None | None | Custom task name for the head. | - -## KeypointDetectionModel - -The `KeypointDetectionModel` allows for both "light" and "heavy" variants, where the "heavy" variant is more accurate, and the "light" variant is faster. - -See an example configuration file using this predefined model [here](../../../configs/keypoint_bbox_light_model.yaml) for the "light" variant, and [here](../../../configs/keypoint_bbox_heavy_model.yaml) for the "heavy" variant. - -**Components** - -| Name | Alias | Function | -| ------------------------------------------------------------------------------------------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -| [EfficientRep](../../nodes/README.md#efficientrep) | kpt_detection_backbone | Backbone of the model.. Available variants: "light" (EfficientRep-N) and "heavy" (EfficientRep-L). | -| [RepPANNeck](../../nodes/README.md#reppanneck) | kpt_detection_neck | Neck of the model. | -| [EfficientKeypointBBoxHead](../../nodes/README.md#efficientkeypointbboxhead) | kpt_detection_head | Head of the model. | -| [EfficientKeypointBBoxLoss](../../attached_modules/losses/README.md#efficientkeypointbboxloss) | kpt_detection_loss | Loss of the model. | -| [ObjectKeypointSimilarity](../../attached_modules/metrics/README.md#objectkeypointsimilarity) | kpt_detection_oks | Main metric of the model. | -| [MeanAveragePrecisionKeypoints](../../attached_modules/metrics/README.md#meanaverageprecisionkeypoints) | kpt_detection_map | Secondary metric of the model. | -| [BBoxVisualizer](../../attached_modules/visualizers/README.md#bboxvisualizer) | | Visualizer for bounding boxes. Combined with keypoint visualizer in [MultiVisualizer](../../attached_modules/visualizers/README.md#multivisualizer). | -| [KeypointVisualizer](../../attached_modules/visualizers/README.md#keypointvisualizer) | | Visualizer for keypoints. Combined with keypoint visualizer in [MultiVisualizer](../../attached_modules/visualizers/README.md#multivisualizer) | - -**Params** - -| Key | Type | Default value | Description | -| ---------------------- | --------------------------- | -------------- | ------------------------------------------------------------------------------------------- | -| variant | Literal\["light", "heavy"\] | "light" | Defines the variant of the model. "light" uses EfficientRep-N, "heavy" uses EfficientRep-L. | -| use_neck | bool | True | Whether to include the neck in the model. | -| backbone | str | "EfficientRep" | Name of the node to be used as a backbone. | -| backbone_params | dict | {} | Additional parameters to the backbone. | -| neck_params | dict | {} | Additional parameters to the neck. | -| head_params | dict | {} | Additional parameters to the head. | -| loss_params | dict | {} | Additional parameters to the loss. | -| kpt_visualizer_params | dict | {} | Additional parameters to the keypoint visualizer. | -| bbox_visualizer_params | dict | {} | Additional parameters to the bbox visualizer. | -| bbox_task_name | str \| None | None | Custom task name for the detection head. | -| kpt_task_name | str \| None | None | Custom task name for the keypoint head. | - -## ClassificationModel - -The `ClassificationModel` allows for both "light" and "heavy" variants, where the "heavy" variant is more accurate, and the "light" variant is faster. Can be used for multiclass and multilabel tasks. - -See an example configuration file using this predefined model [here](../../../configs/classification_light_model.yaml) for the "light" variant, and [here](../../../configs/classification_heavy_model.yaml) for the "heavy" variant. - -**Components** - -| Name | Alias | Function | -| ---------------------------------------------------------------------------- | ----------------------- | ----------------------------------------------------------------------------------------------------- | -| [ResNet](../../nodes/README.md#resnet) | classification_backbone | Backbone of the model. The "light" variant uses ResNet-18, while the "heavy" variant uses ResNet-101. | -| [ClassificationHead](../../nodes/README.md#classificationhead) | classification_head | Head of the model. | -| [CrossEntropyLoss](../../attached_modules/losses/README.md#crossentropyloss) | classification_loss | Loss of the model. | -| [F1Score](../../attached_modules/metrics/README.md#torchmetrics) | classification_f1_score | Main metric of the model. | -| [Accuracy](../../attached_modules/metrics/README.md#torchmetrics) | classification_accuracy | Secondary metric of the model. | -| [Recall](../../attached_modules/metrics/README.md#torchmetrics) | classification_recall | Secondary metric of the model. | - -**Params** - -| Key | Type | Default value | Description | -| ----------------- | ------------------------------------- | ------------- | ----------------------------------------------------------------------------------- | -| variant | Literal\["light", "heavy"\] | "light" | Defines the variant of the model. "light" uses ResNet-18, "heavy" uses ResNet-101. | -| backbone | str | "ResNet" | Name of the node to be used as a backbone. | -| backbone_params | dict | {} | Additional parameters to the backbone. | -| head_params | dict | {} | Additional parameters to the head. | -| loss_params | dict | {} | Additional parameters to the loss. | -| visualizer_params | dict | {} | Additional parameters to the visualizer. | -| task | Literal\["multiclass", "multilabel"\] | "multiclass" | Type of the task of the model. | -| task_name | str \| None | None | Custom task name for the head. | +- [`SegmentationModel`](#segmentationmodel) +- [`DetectionModel`](#detectionmodel) +- [`KeypointDetectionModel`](#keypointdetectionmodel) +- [`ClassificationModel`](#classificationmodel) + +**Parameters:** + +| Key | Type | Default value | Description | +| --------------------- | ---------------- | ------------- | -------------------------------------------------------------------- | +| `name` | `str` | - | Name of the predefined architecture. See below the available options | +| `params` | `dict[str, Any]` | `{}` | Additional parameters of the predefined model | +| `include_nodes` | `bool` | `True` | Whether to include nodes of the model | +| `include_losses` | `bool` | `True` | Whether to include loss functions | +| `include_metrics` | `bool` | `True` | Whether to include metrics | +| `include_visualizers` | `bool` | `True` | Whether to include visualizers | + +## `SegmentationModel` + +The `SegmentationModel` allows for both `"light"` and `"heavy"` variants, where the `"heavy"` variant is more accurate, and the `"light"` variant is faster. + +See an example configuration file using this predefined model [here](../../../configs/segmentation_light_model.yaml) for the `"light"` variant, and [here](../../../configs/segmentation_heavy_model.yaml) for the `"heavy"` variant. + +**Components:** + +| Name | Alias | Function | +| ----------------------------------------------------------------------------------------------- | ------------------------------ | --------------------------------------------------------------------------------------------------- | +| [`DDRNet`](../../nodes/README.md#ddrnet) | `"segmentation_backbone"` | Backbone of the model. Available variants: `"light"` (`DDRNet-23-slim`) and `"heavy"` (`DDRNet-23`) | +| [`SegmentationHead`](../../nodes/README.md#segmentationhead) | `"segmentation_head"` | Head of the model | +| [`BCEWithLogitsLoss`](../../attached_modules/losses/README.md#bcewithlogitsloss) | `"segmentation_loss"` | Loss of the model when the task is set to `"binary"` | +| [`CrossEntropyLoss`](../../attached_modules/losses/README.md#crossentropyloss) | `"segmentation_loss"` | Loss of the model when the task is set to `"multiclass"` or `"multilabel"` | +| [`JaccardIndex`](../../attached_modules/metrics/README.md#torchmetrics) | `"segmentation_jaccard_index"` | Main metric of the model | +| [`F1Score`](../../attached_modules/metrics/README.md#torchmetrics) | `"segmentation_f1_score"` | Secondary metric of the model | +| [`SegmentationVisualizer`](../../attached_modules/visualizers/README.md#segmentationvisualizer) | `"segmentation_visualizer"` | Visualizer of the `SegmentationHead` | + +**Parameters:** + +| Key | Type | Default value | Description | +| ------------------- | --------------------------------- | ------------- | ----------------------------------------------------------------------------------------------- | +| `variant` | `Literal["light", "heavy"]` | `"light"` | Defines the variant of the model. `"light"` uses `DDRNet-23-slim`, `"heavy"` uses `DDRNet-23` | +| `backbone` | `str` | `"DDRNet"` | Name of the node to be used as a backbone | +| `backbone_params` | `dict` | `{}` | Additional parameters for the backbone. If not provided, variant-specific defaults will be used | +| `head_params` | `dict` | `{}` | Additional parameters for the head | +| `aux_head_params` | `dict` | `{}` | Additional parameters for auxiliary heads | +| `loss_params` | `dict` | `{}` | Additional parameters for the loss | +| `visualizer_params` | `dict` | `{}` | Additional parameters for the visualizer | +| `task` | `Literal["binary", "multiclass"]` | `"binary"` | Type of the task of the model | +| `task_name` | `str \| None` | `None` | Custom task name for the head | + +## `DetectionModel` + +The `DetectionModel` allows for both `"light"` and `"heavy"` variants, where the `"heavy"` variant is more accurate, and the `"light"` variant is faster. + +See an example configuration file using this predefined model [here](../../../configs/detection_light_model.yaml) for the `"light"` variant, and [here](../../../configs/detection_heavy_model.yaml) for the `"heavy"` variant. + +**Components:** + +| Name | Alias | Function | +| ---------------------------------------------------------------------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------- | +| [`EfficientRep`](../../nodes/README.md#efficientrep) | `"detection_backbone"` | Backbone of the model. Available variants: `"light"` (`EfficientRep-N`) and `"heavy"` (`EfficientRep-L`) | +| [`RepPANNeck`](../../nodes/README.md#reppanneck) | `"detection_neck"` | Neck of the model | +| [`EfficientBBoxHead`](../../nodes/README.md#efficientbboxhead) | `"detection_head"` | Head of the model | +| [`AdaptiveDetectionLoss`](../../attached_modules/losses/README.md#adaptivedetectionloss) | `"detection_loss"` | Loss of the model | +| [`MeanAveragePrecision`](../../attached_modules/metrics/README.md#meanaverageprecision) | `"detection_map"` | Main metric of the model | +| [`BBoxVisualizer`](../../attached_modules/visualizers/README.md#bboxvisualizer) | `"detection_visualizer"` | Visualizer of the `detection_head` | + +**Parameters:** + +| Key | Type | Default value | Description | +| ------------------- | --------------------------- | ---------------- | -------------------------------------------------------------------------------------------------- | +| `variant` | `Literal["light", "heavy"]` | `"light"` | Defines the variant of the model. `"light"` uses `EfficientRep-N`, `"heavy"` uses `EfficientRep-L` | +| `use_neck` | `bool` | `True` | Whether to include the neck in the model | +| `backbone` | `str` | `"EfficientRep"` | Name of the node to be used as a backbone | +| `backbone_params` | `dict` | `{}` | Additional parameters to the backbone | +| `neck_params` | `dict` | `{}` | Additional parameters to the neck | +| `head_params` | `dict` | `{}` | Additional parameters to the head | +| `loss_params` | `dict` | `{}` | Additional parameters to the loss | +| `visualizer_params` | `dict` | `{}` | Additional parameters to the visualizer | +| `task_name` | `str \| None` | `None` | Custom task name for the head | + +## `KeypointDetectionModel` + +The `KeypointDetectionModel` allows for both `"light"` and `"heavy"` variants, where the `"heavy"` variant is more accurate, and the `"light"` variant is faster. + +See an example configuration file using this predefined model [here](../../../configs/keypoint_bbox_light_model.yaml) for the `"light"` variant, and [here](../../../configs/keypoint_bbox_heavy_model.yaml) for the `"heavy"` variant. + +**Components:** + +| Name | Alias | Function | +| --------------------------------------------------------------------------------------------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [`EfficientRep`](../../nodes/README.md#efficientrep) | `"kpt_detection_backbone"` | Backbone of the model. Available variants: `"light"` (`EfficientRep-N`) and `"heavy"` (`EfficientRep-L`) | +| [`RepPANNeck`](../../nodes/README.md#reppanneck) | `"kpt_detection_neck"` | Neck of the model | +| [`EfficientKeypointBBoxHead`](../../nodes/README.md#efficientkeypointbboxhead) | `"kpt_detection_head"` | Head of the model | +| [`EfficientKeypointBBoxLoss`](../../attached_modules/losses/README.md#efficientkeypointbboxloss) | `"kpt_detection_loss"` | Loss of the model | +| [`ObjectKeypointSimilarity`](../../attached_modules/metrics/README.md#objectkeypointsimilarity) | `"kpt_detection_oks"` | Main metric of the model | +| [`MeanAveragePrecisionKeypoints`](../../attached_modules/metrics/README.md#meanaverageprecisionkeypoints) | `"kpt_detection_map"` | Secondary metric of the model | +| [`BBoxVisualizer`](../../attached_modules/visualizers/README.md#bboxvisualizer) | `"kpt_detection_visualizer"` | Visualizer for bounding boxes. Combined with keypoint visualizer using [`MultiVisualizer`](../../attached_modules/visualizers/README.md#multivisualizer) | +| [`KeypointVisualizer`](../../attached_modules/visualizers/README.md#keypointvisualizer) | `"kpt_detection_visualizer"` | Visualizer for keypoints. Combined with keypoint visualizer using [`MultiVisualizer`](../../attached_modules/visualizers/README.md#multivisualizer) | + +**Parameters:** + +| Key | Type | Default value | Description | +| ------------------------ | --------------------------- | ---------------- | -------------------------------------------------------------------------------------------------- | +| `variant` | `Literal["light", "heavy"]` | `"light"` | Defines the variant of the model. `"light"` uses `EfficientRep-N`, `"heavy"` uses `EfficientRep-L` | +| `use_neck` | `bool` | `True` | Whether to include the neck in the model | +| `backbone` | `str` | `"EfficientRep"` | Name of the node to be used as a backbone | +| `backbone_params` | `dict` | `{}` | Additional parameters to the backbone | +| `neck_params` | `dict` | `{}` | Additional parameters to the neck | +| `head_params` | `dict` | `{}` | Additional parameters to the head | +| `loss_params` | `dict` | `{}` | Additional parameters to the loss | +| `kpt_visualizer_params` | `dict` | `{}` | Additional parameters to the keypoint visualizer | +| `bbox_visualizer_params` | `dict` | `{}` | Additional parameters to the bounding box visualizer | +| `bbox_task_name` | `str \| None` | `None` | Custom task name for the detection head | +| `kpt_task_name` | `str \| None` | `None` | Custom task name for the keypoint head | + +## `ClassificationModel` + +The `ClassificationModel` allows for both `"light"` and `"heavy"` variants, where the `"heavy"` variant is more accurate, and the `"light"` variant is faster. Can be used for multi-class and multi-label tasks. + +See an example configuration file using this predefined model [here](../../../configs/classification_light_model.yaml) for the `"light"` variant, and [here](../../../configs/classification_heavy_model.yaml) for the `"heavy"` variant. + +**Components:** + +| Name | Alias | Function | +| ------------------------------------------------------------------------------ | --------------------------- | ------------------------------------------------------------------------------------------------------------ | +| [`ResNet`](../../nodes/README.md#resnet) | `"classification_backbone"` | Backbone of the model. The `"light"` variant uses `ResNet-18`, while the `"heavy"` variant uses `ResNet-101` | +| [`ClassificationHead`](../../nodes/README.md#classificationhead) | `"classification_head"` | Head of the model | +| [`CrossEntropyLoss`](../../attached_modules/losses/README.md#crossentropyloss) | `"classification_loss"` | Loss of the model | +| [F1Score](../../attached_modules/metrics/README.md#torchmetrics) | `"classification_f1_score"` | Main metric of the model | +| [Accuracy](../../attached_modules/metrics/README.md#torchmetrics) | `"classification_accuracy"` | Secondary metric of the model | +| [Recall](../../attached_modules/metrics/README.md#torchmetrics) | `"classification_recall"` | Secondary metric of the model | + +**Parameters:** + +| Key | Type | Default value | Description | +| ------------------- | ------------------------------------- | -------------- | ----------------------------------------------------------------------------------------- | +| `variant` | `Literal["light", "heavy"]` | `"light"` | Defines the variant of the model. `"light"` uses `ResNet-18`, `"heavy"` uses `ResNet-101` | +| `backbone` | `str` | `"ResNet"` | Name of the node to be used as a backbone | +| `backbone_params` | `dict` | `{}` | Additional parameters to the backbone | +| `head_params` | `dict` | `{}` | Additional parameters to the head | +| `loss_params` | `dict` | `{}` | Additional parameters to the loss | +| `visualizer_params` | `dict` | `{}` | Additional parameters to the visualizer | +| `task` | `Literal["multiclass", "multilabel"]` | `"multiclass"` | Type of the task of the model | +| `task_name` | `str \| None` | `None` | Custom task name for the head | diff --git a/luxonis_train/loaders/README.md b/luxonis_train/loaders/README.md index 6f21e1e1..0a1a5bca 100644 --- a/luxonis_train/loaders/README.md +++ b/luxonis_train/loaders/README.md @@ -1,9 +1,25 @@ # Loaders -## LuxonisLoaderTorch +## Table Of Contents + +- [`LuxonisLoaderTorch`](#luxonisloadertorch) + - [Implementing a custom loader](#implementing-a-custom-loader) + +## `LuxonisLoaderTorch` The default loader used with `LuxonisTrain`. It can either load data from an already created dataset in the `LuxonisDataFormat` or create a new dataset automatically from a set of supported formats. +**Parameters:** + +| Key | Type | Default value | Description | +| ----------------- | --------------------------------------------------------------------------------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `dataset_name` | `str` | `None` | Name of the dataset to load. If not provided, the `dataset_dir` must be provided instead | +| `dataset_dir` | `str` | `None` | Path to the directory containing the dataset. If not provided, the `dataset_name` must be provided instead. Can be a path to a local directory or a URL. The data can be in a zip archive. New `LuxonisDataset` will be created using data from this directory and saved under the provided `dataset_name` | +| `dataset_type` | `Literal["coco", "voc", "darknet", "yolov6", "yolov4", "createml", "tfcsv", "clsdir", "segmask"] \| None` | `None` | Type of the dataset. If not provided, the type will be inferred from the directory structure | +| `team_id` | `str \| None` | `None` | Optional unique team identifier for the cloud | +| `bucket_storage` | `Literal["local", "s3", "gcs"]` | `"local"` | Type of the bucket storage | +| `delete_existing` | `bool` | `False` | Whether to delete the existing dataset with the same name. Only relevant if `dataset_dir` is provided. Use if you want to reparse the directory in case the data changed | + ### Implementing a custom loader To implement a loader, you need to create a class that inherits from `BaseLoaderTorch` and implement the following methods: diff --git a/luxonis_train/nodes/README.md b/luxonis_train/nodes/README.md index dad43921..9e561cc8 100644 --- a/luxonis_train/nodes/README.md +++ b/luxonis_train/nodes/README.md @@ -1,235 +1,235 @@ # Nodes Nodes are the basic building structures of the model. They can be connected together -arbitrarily as long as the two nodes are compatible with each other. We've grouped together nodes that are similar so it's easier to build an architecture that makes sense. +arbitrarily as long as the two nodes are compatible with each other. We've grouped together nodes that are similar, so it's easier to build an architecture that makes sense. ## Table Of Contents - [Backbones](#backbones) - - [ResNet](#resnet) - - [MicroNet](#micronet) - - [RepVGG](#repvgg) - - [EfficientRep](#efficientrep) - - [RexNetV1_lite](#rexnetv1_lite) - - [MobileOne](#mobileone) - - [MobileNetV2](#mobilenetv2) - - [EfficientNet](#efficientnet) - - [ContextSpatial](#contextspatial) - - [DDRNet](#ddrnet) + - [`ResNet`](#resnet) + - [`MicroNet`](#micronet) + - [`RepVGG`](#repvgg) + - [`EfficientRep`](#efficientrep) + - [`RexNetV1_lite`](#rexnetv1_lite) + - [`MobileOne`](#mobileone) + - [`MobileNetV2`](#mobilenetv2) + - [`EfficientNet`](#efficientnet) + - [`ContextSpatial`](#contextspatial) + - [`DDRNet`](#ddrnet) - [Necks](#necks) - - [RepPANNeck](#reppanneck) + - [`RepPANNeck`](#reppanneck) - [Heads](#heads) - - [ClassificationHead](#classificationhead) - - [SegmentationHead](#segmentationhead) - - [BiSeNetHead](#bisenethead) - - [EfficientBBoxHead](#efficientbboxhead) - - [EfficientKeypointBBoxHead](#efficientkeypointbboxhead) - - [DDRNetSegmentationHead](#ddrnetsegmentationhead) + - [`ClassificationHead`](#classificationhead) + - [`SegmentationHead`](#segmentationhead) + - [`BiSeNetHead`](#bisenethead) + - [`EfficientBBoxHead`](#efficientbboxhead) + - [`EfficientKeypointBBoxHead`](#efficientkeypointbboxhead) + - [`DDRNetSegmentationHead`](#ddrnetsegmentationhead) Every node takes these parameters: -| Key | Type | Default value | Description | -| ---------------- | ----------- | ------------- | ---------------------------------------------------------------------------- | -| n_classes | int \| None | None | Number of classes in the dataset. Inferred from the dataset if not provided. | -| remove_on_export | bool | False | Whether node should be removed when exporting the whole model. | +| Key | Type | Default value | Description | +| ------------------ | ------------- | ------------- | --------------------------------------------------------------------------- | +| `n_classes` | `int \| None` | `None` | Number of classes in the dataset. Inferred from the dataset if not provided | +| `remove_on_export` | `bool` | `False` | Whether node should be removed when exporting the whole model | -In addition, the following class attributes can be overriden: +In addition, the following class attributes can be overridden: -| Key | Type | Default value | Description | -| ------------ | ------------------------------------------------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -| attach_index | int \| "all" \| Tuple\[int, int\] \| Tuple\[int, int, int\] \| None | None | Index of previous output that the head attaches to. Each node has a sensible default. Usually should not be manually set in most cases. | -| tasks | List\[TaskType\] \| Dict\[TaskType, str\] \| None | None | Tasks supported by the node. Should be overriden for head nodes. Either a list of tasks or a dictionary mapping tasks to their default names. | +| Key | Type | Default value | Description | +| -------------- | ----------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `attach_index` | `int \| "all" \| tuple[int, int] \| tuple[int, int, int] \| None` | `None` | Index of previous output that the head attaches to. Each node has a sensible default. Usually should not be manually set in most cases. Can be either a single index, a slice (negative indexing is also supported), or `"all"` | +| `tasks` | `list[TaskType] \| Dict[TaskType, str] \| None` | `None` | Tasks supported by the node. Should be overridden for head nodes. Either a list of tasks or a dictionary mapping tasks to their default names | Additional parameters for specific nodes are listed below. ## Backbones -### ResNet +### `ResNet` Adapted from [here](https://pytorch.org/vision/main/models/resnet.html). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ---------------- | ----------------------------------------- | ------------- | -------------------------------------- | -| variant | Literal\["18", "34", "50", "101", "152"\] | "18" | Variant of the network. | -| download_weights | bool | False | If True download weights from imagenet | +| Key | Type | Default value | Description | +| ------------------ | ----------------------------------------- | ------------- | -------------------------------------- | +| `variant` | `Literal["18", "34", "50", "101", "152"]` | `"18"` | Variant of the network | +| `download_weights` | `bool` | `False` | If True download weights from ImageNet | -### MicroNet +### `MicroNet` Adapted from [here](https://github.com/liyunsheng13/micronet). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ------- | --------------------------- | ------------- | ----------------------- | -| variant | Literal\["M1", "M2", "M3"\] | "M1" | Variant of the network. | +| Key | Type | Default value | Description | +| --------- | --------------------------- | ------------- | ---------------------- | +| `variant` | `Literal["M1", "M2", "M3"]` | `"M1"` | Variant of the network | -### RepVGG +### `RepVGG` Adapted from [here](https://github.com/DingXiaoH/RepVGG). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ------- | --------------------------- | ------------- | ----------------------- | -| variant | Literal\["A0", "A1", "A2"\] | "A0" | Variant of the network. | +| Key | Type | Default value | Description | +| --------- | --------------------------- | ------------- | ---------------------- | +| `variant` | `Literal["A0", "A1", "A2"]` | `"A0"` | Variant of the network | -### EfficientRep +### `EfficientRep` Adapted from [here](https://arxiv.org/pdf/2209.02976.pdf). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ------------- | ----------------------------------------------------------------- | --------------------------- | --------------------------------------------------------------- | -| variant | Literal\["n", "nano", "s", "small", "m", "medium", "l", "large"\] | "nano" | Variant of the network | -| channels_list | List\[int\] | \[64, 128, 256, 512, 1024\] | List of number of channels for each block | -| n_repeats | List\[int\] | \[1, 6, 12, 18, 6\] | List of number of repeats of RepVGGBlock | -| depth_mul | float | 0.33 | Depth multiplier | -| width_mul | float | 0.25 | Width multiplier | -| block | Literal\["RepBlock", "CSPStackRepBlock"\] | "RepBlock" | Base block used | -| csp_e | float | 0.5 | Factor for intermediate channels when block=="CSPStackRepBlock" | +| Key | Type | Default value | Description | +| --------------- | ----------------------------------------------------------------- | --------------------------- | -------------------------------------------------------------------------- | +| `variant` | `Literal["n", "nano", "s", "small", "m", "medium", "l", "large"]` | `"nano"` | Variant of the network | +| `channels_list` | `list[int]` | \[64, 128, 256, 512, 1024\] | List of number of channels for each block | +| `n_repeats` | `list[int]` | \[1, 6, 12, 18, 6\] | List of number of repeats of `RepVGGBlock` | +| `depth_mul` | `float` | `0.33` | Depth multiplier | +| `width_mul` | `float` | `0.25` | Width multiplier | +| `block` | `Literal["RepBlock", "CSPStackRepBlock"]` | `"RepBlock"` | Base block used | +| `csp_e` | `float` | `0.5` | Factor for intermediate channels when block is set to `"CSPStackRepBlock"` | ### RexNetV1_lite -Adapted from ([here](https://github.com/clovaai/rexnet). +Adapted from [here](https://github.com/clovaai/rexnet) -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| --------------- | ------------------ | ------------- | ----------------------------- | -| fix_head_stem | bool | False | Whether to multiply head stem | -| divisible_value | int | 8 | Divisor used | -| input_ch | int | 16 | tarting channel dimension | -| final_ch | int | 164 | Final channel dimension | -| multiplier | float | 1.0 | Channel dimension multiplier | -| kernel_sizes | int \| list\[int\] | 3 | Kernel sizes | +| Key | Type | Default value | Description | +| ----------------- | ------------------ | ------------- | ----------------------------- | +| `fix_head_stem` | `bool` | `False` | Whether to multiply head stem | +| `divisible_value` | `int` | `8` | Divisor used | +| `input_ch` | `int` | `16` | tarting channel dimension | +| `final_ch` | `int` | `164` | Final channel dimension | +| `multiplier` | `float` | `1.0` | Channel dimension multiplier | +| `kernel_sizes` | `int \| list[int]` | `3` | Kernel sizes | -### MobileOne +### `MobileOne` Adapted from [here](https://github.com/apple/ml-mobileone). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ------- | --------------------------------------- | ------------- | ----------------------- | -| variant | Literal\["s0", "s1", "s2", "s3", "s4"\] | "s0" | Variant of the network. | +| Key | Type | Default value | Description | +| --------- | --------------------------------------- | ------------- | ---------------------- | +| `variant` | `Literal["s0", "s1", "s2", "s3", "s4"]` | `"s0"` | Variant of the network | -### MobileNetV2 +### `MobileNetV2` Adapted from [here](https://pytorch.org/vision/main/models/generated/torchvision.models.mobilenet_v2.html). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ---------------- | ---- | ------------- | -------------------------------------- | -| download_weights | bool | False | If True download weights from imagenet | +| Key | Type | Default value | Description | +| ------------------ | ------ | ------------- | -------------------------------------- | +| `download_weights` | `bool` | `False` | If True download weights from ImageNet | -### EfficientNet +### `EfficientNet` Adapted from [here](https://github.com/rwightman/gen-efficientnet-pytorch). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ---------------- | ---- | ------------- | --------------------------------------- | -| download_weights | bool | False | If True download weights from imagenet. | +| Key | Type | Default value | Description | +| ------------------ | ------ | ------------- | -------------------------------------- | +| `download_weights` | `bool` | `False` | If True download weights from ImageNet | -### ContextSpatial +### `ContextSpatial` Adapted from [here](https://github.com/taveraantonio/BiseNetv1). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ---------------- | ---- | ------------- | ------------- | -| context_backbone | str | "MobileNetV2" | Backbone used | +| Key | Type | Default value | Description | +| ------------------ | ----- | --------------- | ---------------------------------------------------------------------------------------------------- | +| `context_backbone` | `str` | `"MobileNetV2"` | Backbone used for the context path. Must be a reference to a node registered in the `NODES` registry | -### DDRNet +### `DDRNet` Adapted from [here](https://github.com/ydhongHIT/DDRNet) -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ------- | -------------------------- | ------------- | ----------------------- | -| variant | Literal\["23-slim", "23"\] | "23-slim" | Variant of the network. | +| Key | Type | Default value | Description | +| --------- | -------------------------- | ------------- | ---------------------- | +| `variant` | `Literal["23-slim", "23"]` | `"23-slim"` | Variant of the network | ## Neck -### RepPANNeck +### `RepPANNeck` Adapted from [here](https://arxiv.org/pdf/2209.02976.pdf). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ------------- | ----------------------------------------------------------------- | ------------------------------------------------------- | --------------------------------------------------------------- | -| variant | Literal\["n", "nano", "s", "small", "m", "medium", "l", "large"\] | "nano" | Variant of the network | -| n_heads | Literal\[2,3,4\] | 3 ***Note:** Should be same also on head in most cases* | Number of output heads | -| channels_list | List\[int\] | \[256, 128, 128, 256, 256, 512\] | List of number of channels for each block | -| n_repeats | List\[int\] | \[12, 12, 12, 12\] | List of number of repeats of RepVGGBlock | -| depth_mul | float | 0.33 | Depth multiplier | -| width_mul | float | 0.25 | Width multiplier | -| block | Literal\["RepBlock", "CSPStackRepBlock"\] | "RepBlock" | Base block used | -| csp_e | float | 0.5 | Factor for intermediate channels when block=="CSPStackRepBlock" | +| Key | Type | Default value | Description | +| --------------- | ----------------------------------------------------------------- | -------------------------------- | ------------------------------------------------------------------------------- | +| `variant` | `Literal["n", "nano", "s", "small", "m", "medium", "l", "large"]` | `"nano"` | Variant of the network | +| `n_heads` | `Literal[2,3,4]` | `3` | Number of output heads. Should be same also on the connected head in most cases | +| `channels_list` | `list[int]` | `[256, 128, 128, 256, 256, 512]` | List of number of channels for each block | +| `n_repeats` | `list[int]` | `[12, 12, 12, 12]` | List of number of repeats of `RepVGGBlock` | +| `depth_mul` | `float` | `0.33` | Depth multiplier | +| `width_mul` | `float` | `0.25` | Width multiplier | +| `block` | `Literal["RepBlock", "CSPStackRepBlock"]` | `"RepBlock"` | Base block used | +| `csp_e` | `float` | `0.5` | Factor for intermediate channels when block is set to `"CSPStackRepBlock"` | ## Heads -### ClassificationHead +### `ClassificationHead` -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ---------- | ----- | ------------- | --------------------------------------------- | -| fc_dropout | float | 0.2 | Dropout rate before last layer, range \[0,1\] | +| Key | Type | Default value | Description | +| ------------ | ------- | ------------- | ------------------------------------------------ | +| `fc_dropout` | `float` | `0.2` | Dropout rate before last layer, range $\[0, 1\]$ | -### SegmentationHead +### `SegmentationHead` Adapted from [here](https://github.com/pytorch/vision/blob/main/torchvision/models/segmentation/fcn.py). -### BiSeNetHead +### `BiSeNetHead` Adapted from [here](https://github.com/taveraantonio/BiseNetv1). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| --------------------- | ---- | ------------- | -------------------------------------- | -| intermediate_channels | int | 64 | How many intermediate channels to use. | +| Key | Type | Default value | Description | +| ----------------------- | ----- | ------------- | ------------------------------------- | +| `intermediate_channels` | `int` | `64` | How many intermediate channels to use | -### EfficientBBoxHead +### `EfficientBBoxHead` Adapted from [here](https://arxiv.org/pdf/2209.02976.pdf). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ---------- | ----- | ------------- | -------------------------------------------------- | -| n_heads | bool | 3 | Number of output heads | -| conf_thres | float | 0.25 | Confidence threshold for nms (used for evaluation) | -| iou_thres | float | 0.45 | Iou threshold for nms (used for evaluation) | +| Key | Type | Default value | Description | +| ------------ | ------- | ------------- | --------------------------------------------------------------------- | +| `n_heads` | `bool` | `3` | Number of output heads | +| `conf_thres` | `float` | `0.25` | Confidence threshold for non-maxima-suppression (used for evaluation) | +| `iou_thres` | `float` | `0.45` | `IoU` threshold for non-maxima-suppression (used for evaluation) | -### EfficientKeypointBBoxHead +### `EfficientKeypointBBoxHead` Adapted from [here](https://arxiv.org/pdf/2207.02696.pdf). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| ----------- | ----------- | ------------- | -------------------------------------------------- | -| n_keypoints | int \| None | None | Number of keypoints. | -| n_heads | int | 3 | Number of output heads | -| conf_thres | float | 0.25 | Confidence threshold for nms (used for evaluation) | -| iou_thres | float | 0.45 | Iou threshold for nms (used for evaluation) | +| Key | Type | Default value | Description | +| ------------- | -------------- | ------------- | --------------------------------------------------------------------- | +| `n_keypoints` | `int \| None ` | `None` | Number of keypoints | +| `n_heads` | `int` | `3` | Number of output heads | +| `conf_thres` | `float` | `0.25` | Confidence threshold for non-maxima-suppression (used for evaluation) | +| `iou_thres` | `float` | `0.45` | `IoU` threshold for non-maxima-suppression (used for evaluation) | -### DDRNetSegmentationHead +### `DDRNetSegmentationHead` Adapted from [here](https://github.com/ydhongHIT/DDRNet). -**Params** +**Parameters:** -| Key | Type | Default value | Description | -| -------------- | ---- | ------------- | ---------------------------------------------------------------------------------------------- | -| inter_channels | int | 64 | Width of internal conv. Must be a multiple of scale_factor^2 when inter_mode is pixel_shuffle. | -| inter_mode | str | "bilinear | Upsampling method. | +| Key | Type | Default value | Description | +| ---------------- | ----- | ------------- | ------------------------------------------------------------------------------------------------------------------------- | +| `inter_channels` | `int` | `64` | Width of internal convolutions | +| `inter_mode` | `str` | `"bilinear"` | Up-sampling method. One of `"nearest"`, `"linear"`, `"bilinear"`, `"bicubic"`, `"trilinear"`, `"area"`, `"pixel_shuffle"` | From d60361bf454f61f8d375e8c610083dfeb2bf1a8b Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Mon, 7 Oct 2024 03:49:34 +0200 Subject: [PATCH 11/15] updated pyproject.toml --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 4d04e71e..39c11a92 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,8 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Development Status :: 4 - Beta", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Scientific/Engineering :: Image Processing", "Topic :: Scientific/Engineering :: Image Recognition", From 8c1089c68cf9f8fca62b4849f82f33cc578ecd08 Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Mon, 7 Oct 2024 04:35:07 +0200 Subject: [PATCH 12/15] formatted configs --- configs/classification_heavy_model.yaml | 4 ++-- configs/classification_light_model.yaml | 4 ++-- configs/complex_model.yaml | 20 ++++++++++---------- configs/detection_heavy_model.yaml | 4 ++-- configs/detection_light_model.yaml | 4 ++-- configs/example_export.yaml | 6 +++--- configs/example_tuning.yaml | 4 ++-- configs/keypoint_bbox_heavy_model.yaml | 4 ++-- configs/keypoint_bbox_light_model.yaml | 4 ++-- configs/segmentation_heavy_model.yaml | 4 ++-- configs/segmentation_light_model.yaml | 4 ++-- tests/configs/ddrnet.yaml | 10 +++++----- tests/configs/parking_lot_config.yaml | 14 +++++++------- tests/configs/segmentation_parse_loader.yaml | 4 ++-- 14 files changed, 45 insertions(+), 45 deletions(-) diff --git a/configs/classification_heavy_model.yaml b/configs/classification_heavy_model.yaml index 22b590e6..6ef1f443 100644 --- a/configs/classification_heavy_model.yaml +++ b/configs/classification_heavy_model.yaml @@ -14,9 +14,9 @@ loader: trainer: preprocessing: train_image_size: [384, 512] - keep_aspect_ratio: True + keep_aspect_ratio: true normalize: - active: True + active: true batch_size: 8 epochs: 200 diff --git a/configs/classification_light_model.yaml b/configs/classification_light_model.yaml index 32f7d96b..6eeba5fd 100644 --- a/configs/classification_light_model.yaml +++ b/configs/classification_light_model.yaml @@ -14,9 +14,9 @@ loader: trainer: preprocessing: train_image_size: [384, 512] - keep_aspect_ratio: True + keep_aspect_ratio: true normalize: - active: True + active: true batch_size: 8 epochs: 200 diff --git a/configs/complex_model.yaml b/configs/complex_model.yaml index b27a86ea..7b2b909d 100644 --- a/configs/complex_model.yaml +++ b/configs/complex_model.yaml @@ -67,9 +67,9 @@ model: tracker: project_name: coco_test save_directory: output - is_tensorboard: True - is_wandb: False - is_mlflow: False + is_tensorboard: true + is_wandb: false + is_mlflow: false loader: train_view: train @@ -86,23 +86,23 @@ trainer: n_sanity_val_steps: 1 profiler: null - verbose: True + verbose: true batch_size: 8 accumulate_grad_batches: 1 epochs: &epochs 200 n_workers: 8 validation_interval: 10 n_log_images: 8 - skip_last_batch: True - log_sub_losses: True + skip_last_batch: true + log_sub_losses: true save_top_k: 3 preprocessing: train_image_size: [&height 384, &width 384] - keep_aspect_ratio: True - train_rgb: True + keep_aspect_ratio: true + train_rgb: true normalize: - active: True + active: true augmentations: - name: Defocus params: @@ -138,7 +138,7 @@ trainer: params: lr: 0.02 momentum: 0.937 - nesterov: True + nesterov: true weight_decay: 0.0005 scheduler: diff --git a/configs/detection_heavy_model.yaml b/configs/detection_heavy_model.yaml index f35c1ed3..294034c2 100644 --- a/configs/detection_heavy_model.yaml +++ b/configs/detection_heavy_model.yaml @@ -14,9 +14,9 @@ loader: trainer: preprocessing: train_image_size: [384, 512] - keep_aspect_ratio: True + keep_aspect_ratio: true normalize: - active: True + active: true batch_size: 8 epochs: &epochs 200 diff --git a/configs/detection_light_model.yaml b/configs/detection_light_model.yaml index 1f982d92..aca202bd 100644 --- a/configs/detection_light_model.yaml +++ b/configs/detection_light_model.yaml @@ -14,9 +14,9 @@ loader: trainer: preprocessing: train_image_size: [384, 512] - keep_aspect_ratio: True + keep_aspect_ratio: true normalize: - active: True + active: true batch_size: 8 epochs: &epochs 200 diff --git a/configs/example_export.yaml b/configs/example_export.yaml index 78f1c650..ff9b1f3d 100644 --- a/configs/example_export.yaml +++ b/configs/example_export.yaml @@ -15,9 +15,9 @@ loader: trainer: preprocessing: train_image_size: [384, 512] - keep_aspect_ratio: True + keep_aspect_ratio: true normalize: - active: True + active: true batch_size: 8 epochs: &epochs 200 @@ -46,5 +46,5 @@ exporter: onnx: opset_version: 11 blobconverter: - active: True + active: true shaves: 8 diff --git a/configs/example_tuning.yaml b/configs/example_tuning.yaml index 9e63c877..8e69f00b 100755 --- a/configs/example_tuning.yaml +++ b/configs/example_tuning.yaml @@ -15,9 +15,9 @@ loader: trainer: preprocessing: train_image_size: [384, 512] - keep_aspect_ratio: True + keep_aspect_ratio: true normalize: - active: True + active: true augmentations: - name: Defocus params: diff --git a/configs/keypoint_bbox_heavy_model.yaml b/configs/keypoint_bbox_heavy_model.yaml index c6b22f35..10527921 100644 --- a/configs/keypoint_bbox_heavy_model.yaml +++ b/configs/keypoint_bbox_heavy_model.yaml @@ -14,9 +14,9 @@ loader: trainer: preprocessing: train_image_size: [384, 512] - keep_aspect_ratio: True + keep_aspect_ratio: true normalize: - active: True + active: true batch_size: 8 epochs: &epochs 200 diff --git a/configs/keypoint_bbox_light_model.yaml b/configs/keypoint_bbox_light_model.yaml index a095a551..57042b04 100644 --- a/configs/keypoint_bbox_light_model.yaml +++ b/configs/keypoint_bbox_light_model.yaml @@ -14,9 +14,9 @@ loader: trainer: preprocessing: train_image_size: [384, 512] - keep_aspect_ratio: True + keep_aspect_ratio: true normalize: - active: True + active: true batch_size: 8 epochs: &epochs 200 diff --git a/configs/segmentation_heavy_model.yaml b/configs/segmentation_heavy_model.yaml index e9bc16d6..8da7eba8 100644 --- a/configs/segmentation_heavy_model.yaml +++ b/configs/segmentation_heavy_model.yaml @@ -14,9 +14,9 @@ loader: trainer: preprocessing: train_image_size: [384, 512] - keep_aspect_ratio: True + keep_aspect_ratio: true normalize: - active: True + active: true batch_size: 8 epochs: &epochs 200 diff --git a/configs/segmentation_light_model.yaml b/configs/segmentation_light_model.yaml index c03703f4..40d38595 100644 --- a/configs/segmentation_light_model.yaml +++ b/configs/segmentation_light_model.yaml @@ -14,9 +14,9 @@ loader: trainer: preprocessing: train_image_size: [384, 512] - keep_aspect_ratio: True + keep_aspect_ratio: true normalize: - active: True + active: true batch_size: 8 epochs: &epochs 200 diff --git a/tests/configs/ddrnet.yaml b/tests/configs/ddrnet.yaml index e5c7ea9f..542fc0f6 100644 --- a/tests/configs/ddrnet.yaml +++ b/tests/configs/ddrnet.yaml @@ -21,12 +21,12 @@ model: name: CrossEntropyLoss trainer: preprocessing: - train_image_size: - - &height 128 - - &width 128 - keep_aspect_ratio: False + train_image_size: + - 128 + - 128 + keep_aspect_ratio: false normalize: - active: True + active: true batch_size: 2 epochs: &epochs 1 diff --git a/tests/configs/parking_lot_config.yaml b/tests/configs/parking_lot_config.yaml index bf0b9da3..3d6bfbed 100644 --- a/tests/configs/parking_lot_config.yaml +++ b/tests/configs/parking_lot_config.yaml @@ -126,7 +126,7 @@ model: tracker: project_name: Parking_Lot - is_tensorboard: True + is_tensorboard: true loader: train_view: val @@ -140,23 +140,23 @@ trainer: n_sanity_val_steps: 1 profiler: null - verbose: True + verbose: true batch_size: 2 accumulate_grad_batches: 1 epochs: 200 n_workers: 8 validation_interval: 10 n_log_images: 8 - skip_last_batch: True - log_sub_losses: True + skip_last_batch: true + log_sub_losses: true save_top_k: 3 preprocessing: train_image_size: [256, 320] - keep_aspect_ratio: False - train_rgb: True + keep_aspect_ratio: false + train_rgb: true normalize: - active: True + active: true augmentations: - name: Defocus params: diff --git a/tests/configs/segmentation_parse_loader.yaml b/tests/configs/segmentation_parse_loader.yaml index 14814571..178a89cb 100644 --- a/tests/configs/segmentation_parse_loader.yaml +++ b/tests/configs/segmentation_parse_loader.yaml @@ -16,9 +16,9 @@ loader: trainer: preprocessing: train_image_size: [&height 128, &width 128] - keep_aspect_ratio: False + keep_aspect_ratio: false normalize: - active: True + active: true batch_size: 4 epochs: &epochs 1 From 70dcf6e6979cc281f6aa4c55759f54ae47ca8940 Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Mon, 7 Oct 2024 04:35:30 +0200 Subject: [PATCH 13/15] config examples --- configs/README.md | 231 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 199 insertions(+), 32 deletions(-) diff --git a/configs/README.md b/configs/README.md index 8a31a4f0..b06c9495 100644 --- a/configs/README.md +++ b/configs/README.md @@ -1,6 +1,6 @@ # Configuration -The configuration is defined in a YAML file, which you must provide. +The configuration is defined in a `YAML` file, which you must provide. The configuration file consists of a few major blocks that are described below. You can create your own config or use/edit one of the examples. @@ -18,9 +18,9 @@ You can create your own config or use/edit one of the examples. - [Trainer](#trainer) - [Preprocessing](#preprocessing) - [Augmentations](#augmentations) + - [Callbacks](#callbacks) - [Optimizer](#optimizer) - [Scheduler](#scheduler) - - [Callbacks](#callbacks) - [Exporter](#exporter) - [`ONNX`](#onnx) - [Blob](#blob) @@ -105,6 +105,27 @@ You can see the list of all currently supported visualizers and their parameters | `alias` | `str` | `None` | Custom name for the visualizer | | `params` | `dict` | `{}` | Additional parameters for the visualizer | +**Example:** + +```yaml +name: "SegmentationHead" +inputs: + - "RepPANNeck" +losses: + - name: "BCEWithLogitsLoss" +metrics: + - name: "F1Score" + params: + task: "binary" + - name: "JaccardIndex" + params: + task: "binary" +visualizers: + - name: "SegmentationVisualizer" + params: + colors: "#FF5055" +``` + ## Tracker This library uses [`LuxonisTrackerPL`](https://github.com/luxonis/luxonis-ml/blob/b2399335efa914ef142b1b1a5db52ad90985c539/src/luxonis_ml/ops/tracker.py#L152). @@ -122,6 +143,17 @@ You can configure it like this: | `wandb_entity` | `str \| None` | `None` | Name of `WandB` entity | | `is_mlflow` | `bool` | `False` | Whether to use `MLFlow` | +**Example:** + +```yaml +tracker: + project_name: "project_name" + save_directory: "output" + is_tensorboard: true + is_wandb: false + is_mlflow: false +``` + ## Loader This section controls the data loading process and parameters regarding the dataset. @@ -148,6 +180,23 @@ In most cases you want to set one of the parameters below. You can check all the | `dataset_name` | `str` | `None` | Name of an existing `LuxonisDataset` | | `dataset_dir` | `str` | `None` | Location of the data from which new `LuxonisDataset` will be created | +**Example:** + +```yaml +loader: + # using default loader with an existing dataset + params: + dataset_name: "dataset_name" +``` + +```yaml +loader: + # using default loader with a directory + params: + dataset_name: "dataset_name" + dataset_dir: "path/to/dataset" +``` + ## Trainer Here you can change everything related to actual training of the model. @@ -174,11 +223,34 @@ Here you can change everything related to actual training of the model. | `pin_memory` | `bool` | `True` | Whether to pin memory in the `DataLoader` | | `save_top_k` | `-1 \| NonNegativeInt` | `3` | Save top K checkpoints based on validation loss when training | +**Example:** + +```yaml + +trainer: + accelerator: "auto" + devices: "auto" + strategy: "auto" + + n_sanity_val_steps: 1 + profiler: null + verbose: true + batch_size: 8 + accumulate_grad_batches: 1 + epochs: 200 + n_workers: 8 + validation_interval: 10 + n_log_images: 8 + skip_last_batch: true + log_sub_losses: true + save_top_k: 3 +``` + ### Preprocessing We use [`Albumentations`](https://albumentations.ai/docs/) library for `augmentations`. [Here](https://albumentations.ai/docs/api_reference/full_reference/#pixel-level-transforms) you can see a list of all pixel level augmentations supported, and [here](https://albumentations.ai/docs/api_reference/full_reference/#spatial-level-transforms) you see all spatial level transformations. In the configuration you can specify any augmentation from these lists and their parameters. -Additionally, we support `Mosaic4` and `MixUp` batch augmentations and letterbox resizing if `keep_aspect_ratio: True`. +Additionally, we support `Mosaic4` and `MixUp` batch augmentations and letterbox resizing if `keep_aspect_ratio: true`. | Key | Type | Default value | Description | | ------------------- | ------------ | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -191,11 +263,73 @@ Additionally, we support `Mosaic4` and `MixUp` batch augmentations and letterbox #### Augmentations -| Key | Type | Default value | Description | -| -------- | ------ | ------------------------ | ---------------------------------- | -| `name` | `str` | Name of the augmentation | | -| `active` | `bool` | `True` | Whether the augmentation is active | -| `params` | `dict` | `{}` | Parameters of the augmentation | +| Key | Type | Default value | Description | +| -------- | ------ | ------------- | ---------------------------------- | +| `name` | `str` | - | Name of the augmentation | +| `active` | `bool` | `True` | Whether the augmentation is active | +| `params` | `dict` | `{}` | Parameters of the augmentation | + +**Example:** + +```yaml + +trainer: + preprocessing: + # using YAML capture to reuse the image size + train_image_size: [&height 384, &width 384] + keep_aspect_ratio: true + train_rgb: true + normalize: + active: true + augmentations: + - name: "Defocus" + params: + p: 0.1 + - name: "Sharpen" + params: + p: 0.1 + - name: "Flip" + - name: "RandomRotate90" + - name: "Mosaic4" + params: + out_width: *width + out_height: *height + +``` + +### Callbacks + +Callbacks sections contain a list of callbacks. +More information on callbacks and a list of available ones can be found [here](../luxonis_train/callbacks/README.md) +Each callback is a dictionary with the following fields: + +| Key | Type | Default value | Description | +| -------- | ------ | ------------- | -------------------------- | +| `name` | `str` | - | Name of the callback | +| `active` | `bool` | `True` | Whether callback is active | +| `params` | `dict` | `{}` | Parameters of the callback | + +**Example:** + +```yaml + +trainer: + callbacks: + - name: "LearningRateMonitor" + params: + logging_interval: "step" + - name: MetadataLogger + params: + hyperparams: ["trainer.epochs", "trainer.batch_size"] + - name: "EarlyStopping" + params: + patience: 3 + monitor: "val/loss" + mode: "min" + verbose: true + - name: "ExportOnTrainEnd" + - name: "TestOnTrainEnd" +``` ### Optimizer @@ -207,6 +341,18 @@ List of all optimizers can be found [here](https://pytorch.org/docs/stable/optim | `name` | `str` | `"Adam"` | Name of the optimizer | | `params` | `dict` | `{}` | Parameters of the optimizer | +**Example:** + +```yaml +optimizer: + name: "SGD" + params: + lr: 0.02 + momentum: 0.937 + nesterov: true + weight_decay: 0.0005 +``` + ### Scheduler What scheduler to use for training. @@ -217,17 +363,16 @@ List of all optimizers can be found [here](https://pytorch.org/docs/stable/optim | `name` | `str` | `"ConstantLR"` | Name of the scheduler | | `params` | `dict` | `{}` | Parameters of the scheduler | -### Callbacks +**Example:** -Callbacks sections contain a list of callbacks. -More information on callbacks and a list of available ones can be found [here](../luxonis_train/callbacks/README.md) -Each callback is a dictionary with the following fields: - -| Key | Type | Default value | Description | -| -------- | ------ | -------------------- | -------------------------- | -| `name` | `str` | Name of the callback | | -| `active` | `bool` | `True` | Whether callback is active | -| `params` | `dict` | `{}` | Parameters of the callback | +```yaml +trainer: + scheduler: + name: "CosineAnnealingLR" + params: + T_max: *epochs + eta_min: 0 +``` ## Exporter @@ -238,11 +383,12 @@ Here you can define configuration for exporting. | `name` | `str \| None` | `None` | Name of the exported model | | `input_shape` | `list\[int\] \| None` | `None` | Input shape of the model. If not provided, inferred from the dataset | | `data_type` | `Literal["INT8", "FP16", "FP32"]` | `"FP16"` | Data type of the exported model. Only used for conversion to BLOB | -| `reverse_input_channels` | `bool` | `True` | Whether to reverse the image channels in the exported model. Relevant for `.blob` export | +| `reverse_input_channels` | `bool` | `True` | Whether to reverse the image channels in the exported model. Relevant for `BLOB` export | | `scale_values` | `list[float] \| None` | `None` | What scale values to use for input normalization. If not provided, inferred from augmentations | | `mean_values` | `list[float] \| None` | `None` | What mean values to use for input normalization. If not provided, inferred from augmentations | | `upload_to_run` | `bool` | `True` | Whether to upload the exported files to tracked run as artifact | | `upload_url` | `str \| None` | `None` | Exported model will be uploaded to this URL if specified | +| `output_names` | `list[str] \| None` | `None` | Optional list of output names to override the default ones | ### `ONNX` @@ -261,6 +407,18 @@ Option specific for `ONNX` export. | `shaves` | `int` | `6` | How many shaves | | `version` | `Literal["2021.2", "2021.3", "2021.4", "2022.1", "2022.3_RVC3"]` | `"2022.1"` | `OpenVINO` version to use for conversion | +**Example:** + +```yaml +exporter: + output_names: ["output1", "output2"] + onnx: + opset_version: 11 + blobconverter: + active: true + shaves: 8 +``` + ## Tuner Here you can specify options for tuning. @@ -274,34 +432,43 @@ Here you can specify options for tuning. | `timeout` | `int \| None` | `None` | Stop study after the given number of seconds | | `params` | `dict[str, list]` | `{}` | Which parameters to tune. The keys should be in the format `key1.key2.key3_`. Type can be one of `[categorical, float, int, longuniform, uniform, subset]`. For more information about the types, visit [`Optuna` documentation](https://optuna.readthedocs.io/en/stable/reference/generated/optuna.trial.Trial.html) | -**Note**: "subset" sampling is currently only supported for augmentations. You can specify a set of augmentations defined in `trainer` to choose from and every run subset of random N augmentations will be active (`is_active` parameter will be True for chosen ones and False for the rest in the set). +> \[!NOTE\] +> `"subset"` sampling is currently only supported for augmentations. +> You can specify a set of augmentations defined in `trainer` to choose from. +> Every run, only a subset of random $N$ augmentations will be active (`is_active` parameter will be `True` for chosen ones and `False` for the rest in the set). + +### Storage + +| Key | Type | Default value | Description | +| -------------- | ---------------------------- | ------------- | --------------------------------------------------- | +| `active` | `bool` | `True` | Whether to use storage to make the study persistent | +| `storage_type` | `Literal["local", "remote"]` | `"local"` | Type of the storage | -Example of parameters for tuner block: +**Example:** ```yaml -tuner: +t uner: + study_name: "seg_study" + n_trials: 10 + storage: + storage_type: "local" params: trainer.optimizer.name_categorical: ["Adam", "SGD"] trainer.optimizer.params.lr_float: [0.0001, 0.001] trainer.batch_size_int: [4, 16, 4] + # each run will have 2 of the following augmentations active trainer.preprocessing.augmentations_subset: [["Defocus", "Sharpen", "Flip"], 2] ``` -### Storage - -| Key | Type | Default value | Description | -| -------------- | ---------------------------- | ------------- | --------------------------------------------------- | -| `active` | `bool` | `True` | Whether to use storage to make the study persistent | -| `storage_type` | `Literal["local", "remote"]` | `"local"` | Type of the storage | - ## ENVIRON A special section of the config file where you can specify environment variables. For more info on the variables, see [Credentials](../README.md#credentials). -**NOTE** - -This is not a recommended way due to possible leakage of secrets. This section is intended for testing purposes only. +> \[!WARNING\] +> This is not a recommended way due to possible leakage of secrets! +> This section is intended for testing purposes only! +> Use environment variables or `.env` files instead. | Key | Type | Default value | | -------------------------- | ---------------------------------------------------------- | ---------------- | From 260e020d3a024e8ccb4d2839331fb80f0a499f61 Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Mon, 7 Oct 2024 05:03:31 +0200 Subject: [PATCH 14/15] tutorials --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index e7ba822c..fc4cd396 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ It is made to be easily customizable and extendable, allowing you to create cust - [`NN Archive` Support](#nn-archive-support) - [Usage in Scripts](#usage-in-scripts) - [Customizations](#customizations) +- [Tutorials and Examples](#tutorials-and-examples) - [Credentials](#credentials) - [Contributing](#contributing) @@ -326,6 +327,10 @@ model.train() For more information on how to define custom components, consult the respective in-source documentation. +## Tutorials and Examples + +We are actively working on providing examples and tutorials for different parts of the library which will help you to start more easily. The tutorials can be found [here](https://github.com/luxonis/depthai-ml-training/tree/master) and will be updated regularly. + ## Credentials Local use is supported by default. In addition, we also integrate some cloud services which can be primarily used for logging and storing. When these are used, you need to load environment variables to set up the correct credentials. From ef65c48bdf958e7f59ae2375f9b5a65caf65aad5 Mon Sep 17 00:00:00 2001 From: Martin Kozlovsky Date: Mon, 7 Oct 2024 07:13:48 +0200 Subject: [PATCH 15/15] fixed typos --- luxonis_train/assigners/__init__.py | 2 +- .../{atts_assigner.py => atss_assigner.py} | 0 luxonis_train/assigners/tal_assigner.py | 4 +- luxonis_train/assigners/utils.py | 4 +- .../attached_modules/base_attached_module.py | 9 ++- .../losses/adaptive_detection_loss.py | 4 +- .../attached_modules/losses/base_loss.py | 4 +- .../losses/efficient_keypoint_bbox_loss.py | 5 +- .../losses/implicit_keypoint_bbox_loss.py | 17 ++-- .../attached_modules/losses/keypoint_loss.py | 2 +- .../attached_modules/metrics/base_metric.py | 4 +- .../mean_average_precision_keypoints.py | 9 ++- .../metrics/object_keypoint_similarity.py | 12 +-- .../attached_modules/visualizers/__init__.py | 8 +- .../attached_modules/visualizers/utils.py | 22 ++--- luxonis_train/config/config.py | 4 +- luxonis_train/core/core.py | 15 ++-- luxonis_train/core/utils/export_utils.py | 2 +- luxonis_train/core/utils/infer_utils.py | 6 +- luxonis_train/core/utils/tune_utils.py | 2 +- luxonis_train/models/luxonis_lightning.py | 12 +-- .../nodes/backbones/ddrnet/blocks.py | 9 ++- .../nodes/backbones/mobileone/blocks.py | 12 +-- .../nodes/backbones/mobileone/mobileone.py | 2 +- luxonis_train/nodes/base_node.py | 80 +++++++++---------- luxonis_train/utils/boundingbox.py | 6 +- ...atts_assigner.py => test_atss_assigner.py} | 0 27 files changed, 132 insertions(+), 124 deletions(-) rename luxonis_train/assigners/{atts_assigner.py => atss_assigner.py} (100%) rename tests/unittests/test_assigners/{test_atts_assigner.py => test_atss_assigner.py} (100%) diff --git a/luxonis_train/assigners/__init__.py b/luxonis_train/assigners/__init__.py index 4d9bec9f..0b8b074a 100644 --- a/luxonis_train/assigners/__init__.py +++ b/luxonis_train/assigners/__init__.py @@ -1,4 +1,4 @@ -from .atts_assigner import ATSSAssigner +from .atss_assigner import ATSSAssigner from .tal_assigner import TaskAlignedAssigner __all__ = ["ATSSAssigner", "TaskAlignedAssigner"] diff --git a/luxonis_train/assigners/atts_assigner.py b/luxonis_train/assigners/atss_assigner.py similarity index 100% rename from luxonis_train/assigners/atts_assigner.py rename to luxonis_train/assigners/atss_assigner.py diff --git a/luxonis_train/assigners/tal_assigner.py b/luxonis_train/assigners/tal_assigner.py index ea228eba..c9435afa 100644 --- a/luxonis_train/assigners/tal_assigner.py +++ b/luxonis_train/assigners/tal_assigner.py @@ -17,7 +17,7 @@ def __init__( """Task Aligned Assigner. Adapted from: U{TOOD: Task-aligned One-stage Object Detection}. - Cose is adapted from: U{https://github.com/Nioolek/PPYOLOE_pytorch/blob/master/ppyoloe/assigner/tal_assigner.py}. + Code is adapted from: U{https://github.com/Nioolek/PPYOLOE_pytorch/blob/master/ppyoloe/assigner/tal_assigner.py}. @license: U{Apache License, Version 2.0} @@ -25,7 +25,7 @@ def __init__( @type n_classes: int @param n_classes: Number of classes in the dataset. @type topk: int - @param topk: Number of anchors considere in selection. Defaults to 13. + @param topk: Number of anchors considered in selection. Defaults to 13. @type alpha: float @param alpha: Defaults to 1.0. @type beta: float diff --git a/luxonis_train/assigners/utils.py b/luxonis_train/assigners/utils.py index fe9fba4b..4c4a44b4 100644 --- a/luxonis_train/assigners/utils.py +++ b/luxonis_train/assigners/utils.py @@ -64,8 +64,8 @@ def fix_collisions( def batch_iou(batch1: Tensor, batch2: Tensor) -> Tensor: - """Calculates IoU for each pair of bboxes in the batch. Bboxes must - be in xyxy format. + """Calculates IoU for each pair of bounding boxes in the batch. + Bounding boxes must be in the "xyxy" format. @type batch1: Tensor @param batch1: Tensor of shape C{[bs, N, 4]} diff --git a/luxonis_train/attached_modules/base_attached_module.py b/luxonis_train/attached_modules/base_attached_module.py index a4ac8e8f..181abc35 100644 --- a/luxonis_train/attached_modules/base_attached_module.py +++ b/luxonis_train/attached_modules/base_attached_module.py @@ -27,9 +27,9 @@ class BaseAttachedModule( Attached modules include losses, metrics and visualizers. - This class contains a default implementation of `prepare` method, which + This class contains a default implementation of C{prepare} method, which should be sufficient for most simple cases. More complex modules should - override the `prepare` method. + override the C{prepare} method. When subclassing, the following methods can be overridden: - L{prepare}: Prepares node outputs for the forward pass of the module. @@ -163,7 +163,8 @@ def node_tasks(self) -> dict[TaskType, str]: """Getter for the tasks of the attached node. @type: dict[TaskType, str] - @raises RuntimeError: If the node does not have the `tasks` attribute set. + @raises RuntimeError: If the node does not have the C{tasks} + attribute set. """ if self.node._tasks is None: raise RuntimeError( @@ -250,7 +251,7 @@ def get_input_tensors( @raises IncompatibleException: If the task is not present in the inputs. @raises ValueError: If the module requires multiple labels. - For such cases, the `prepare` method should be overridden. + For such cases, the C{prepare} method should be overridden. """ if task_type is not None: if isinstance(task_type, TaskType): diff --git a/luxonis_train/attached_modules/losses/adaptive_detection_loss.py b/luxonis_train/attached_modules/losses/adaptive_detection_loss.py index c11aa878..32e25257 100644 --- a/luxonis_train/attached_modules/losses/adaptive_detection_loss.py +++ b/luxonis_train/attached_modules/losses/adaptive_detection_loss.py @@ -70,7 +70,7 @@ def __init__( self.original_img_size = self.original_in_shape[1:] self.n_warmup_epochs = n_warmup_epochs - self.atts_assigner = ATSSAssigner(topk=9, n_classes=self.n_classes) + self.atss_assigner = ATSSAssigner(topk=9, n_classes=self.n_classes) self.tal_assigner = TaskAlignedAssigner( topk=13, n_classes=self.n_classes, alpha=1.0, beta=6.0 ) @@ -197,7 +197,7 @@ def _run_assigner( pred_scores: Tensor, ) -> tuple[Tensor, Tensor, Tensor, Tensor, Tensor]: if self._epoch < self.n_warmup_epochs: - return self.atts_assigner( + return self.atss_assigner( self.anchors, self.n_anchors_list, gt_labels, diff --git a/luxonis_train/attached_modules/losses/base_loss.py b/luxonis_train/attached_modules/losses/base_loss.py index 7a69d0d8..440a79b0 100644 --- a/luxonis_train/attached_modules/losses/base_loss.py +++ b/luxonis_train/attached_modules/losses/base_loss.py @@ -31,7 +31,7 @@ def forward( @type args: Unpack[Ts] @param args: Prepared inputs from the L{prepare} method. @rtype: Tensor | tuple[Tensor, dict[str, Tensor]] - @return: The main loss and optional a dictionary of sublosses + @return: The main loss and optional a dictionary of sub-losses (for logging). Only the main loss is used for backpropagation. """ @@ -49,7 +49,7 @@ def run( @type labels: L{Labels} @param labels: Labels from the dataset. @rtype: Tensor | tuple[Tensor, dict[str, Tensor]] - @return: The main loss and optional a dictionary of sublosses + @return: The main loss and optional a dictionary of sub-losses (for logging). Only the main loss is used for backpropagation. @raises IncompatibleException: If the inputs are not compatible diff --git a/luxonis_train/attached_modules/losses/efficient_keypoint_bbox_loss.py b/luxonis_train/attached_modules/losses/efficient_keypoint_bbox_loss.py index 7d25a8d2..701a3c72 100644 --- a/luxonis_train/attached_modules/losses/efficient_keypoint_bbox_loss.py +++ b/luxonis_train/attached_modules/losses/efficient_keypoint_bbox_loss.py @@ -62,9 +62,10 @@ def __init__( @type iou_loss_weight: float @param iou_loss_weight: Weight of IoU loss. @type sigmas: list[float] | None - @param sigmas: Sigmas used in KeypointLoss for OKS metric. If None then use COCO ones if possible or default ones. Defaults to C{None}. + @param sigmas: Sigmas used in keypoint loss for OKS metric. If None then use COCO ones if possible or default ones. Defaults to C{None}. @type area_factor: float | None - @param area_factor: Factor by which we multiply bbox area which is used in KeypointLoss. If None then use default one. Defaults to C{None}. + @param area_factor: Factor by which we multiply bounding box area which is used in the keypoint loss. + If not set, the default factor of `0.53` is used. """ super().__init__( n_warmup_epochs=n_warmup_epochs, diff --git a/luxonis_train/attached_modules/losses/implicit_keypoint_bbox_loss.py b/luxonis_train/attached_modules/losses/implicit_keypoint_bbox_loss.py index 99eea6f3..aa47c29f 100644 --- a/luxonis_train/attached_modules/losses/implicit_keypoint_bbox_loss.py +++ b/luxonis_train/attached_modules/losses/implicit_keypoint_bbox_loss.py @@ -82,7 +82,8 @@ def __init__( @type sigmas: list[float] | None @param sigmas: Sigmas used in KeypointLoss for OKS metric. If None then use COCO ones if possible or default ones. Defaults to C{None}. @type area_factor: float | None - @param area_factor: Factor by which we multiply bbox area which is used in KeypointLoss. If None then use default one. Defaults to C{None}. + @param area_factor: Factor by which we multiply the bounding box area which is used in the keypoint loss. + If not set, the default value of C{0.53} is used. @type class_loss_weight: float @param class_loss_weight: Weight for the class loss. Defaults to C{0.6}. @type objectness_loss_weight: float @@ -152,14 +153,14 @@ def prepare( @return: Tuple containing the original output and the postprocessed labels. The processed labels are a tuple containing the class targets, box targets, keypoint targets, - indices and anchors. Indicies are a tuple containing vectors + indices and anchors. Indices are a tuple containing vectors of indices for batch, anchor, feature y and feature x - dimensions, respectively. They are all of shape - (n_targets,). The indices are used to index the output - tensors of shape (batch_size, n_anchors, feature_height, - feature_width, n_classes + box_offset + n_keypoints * 3) to - get a tensor of shape (n_targets, n_classes + box_offset + - n_keypoints * 3). + dimensions, respectively. They are all of the shape + C{(n_targets,)}. The indices are used to index the output + tensors of shape C{(batch_size, n_anchors, feature_height, + feature_width, n_classes + box_offset + n_keypoints * 3)} to + get a tensor of shape C{(n_targets, n_classes + box_offset + + n_keypoints * 3)}. """ predictions = self.get_input_tensors(outputs, "features") diff --git a/luxonis_train/attached_modules/losses/keypoint_loss.py b/luxonis_train/attached_modules/losses/keypoint_loss.py index 1327d460..c9e3b918 100644 --- a/luxonis_train/attached_modules/losses/keypoint_loss.py +++ b/luxonis_train/attached_modules/losses/keypoint_loss.py @@ -40,7 +40,7 @@ def __init__( if possible or default ones. Defaults to C{None}. @type area_factor: float | None @param area_factor: Factor by which we multiply bbox area. If - None then use default one. Defaults to C{None}. + not set, the default factor of C{0.53} is used. @type regression_loss_weight: float @param regression_loss_weight: Weight of regression loss. Defaults to C{1.0}. diff --git a/luxonis_train/attached_modules/metrics/base_metric.py b/luxonis_train/attached_modules/metrics/base_metric.py index a4109d2d..ad94c312 100644 --- a/luxonis_train/attached_modules/metrics/base_metric.py +++ b/luxonis_train/attached_modules/metrics/base_metric.py @@ -42,8 +42,8 @@ def compute( @rtype: Tensor | tuple[Tensor, dict[str, Tensor]] | dict[str, Tensor] @return: The computed metric. Can be one of: - A single Tensor. - - A tuple of a Tensor and a dictionary of submetrics. - - A dictionary of submetrics. If this is the case, then the metric + - A tuple of a Tensor and a dictionary of sub-metrics. + - A dictionary of sub-metrics. If this is the case, then the metric cannot be used as the main metric of the model. """ ... diff --git a/luxonis_train/attached_modules/metrics/mean_average_precision_keypoints.py b/luxonis_train/attached_modules/metrics/mean_average_precision_keypoints.py index f536956c..e086d6b5 100644 --- a/luxonis_train/attached_modules/metrics/mean_average_precision_keypoints.py +++ b/luxonis_train/attached_modules/metrics/mean_average_precision_keypoints.py @@ -66,11 +66,12 @@ def __init__( @param sigmas: Sigma for each keypoint to weigh its importance, if C{None}, then use COCO if possible otherwise defaults. Defaults to C{None}. @type area_factor: float | None - @param area_factor: Factor by which we multiply bbox area. If None then use default one. Defaults to C{None}. + @param area_factor: Factor by which we multiply the bounding box area. + If not set, the default factor of C{0.53} is used. @type max_dets: int, @param max_dets: Maximum number of detections to be considered per image. Defaults to C{20}. @type box_format: Literal["xyxy", "xywh", "cxcywh"] - @param box_format: Input bbox format. + @param box_format: Input bounding box format. Defaults to C{"xyxy"}. """ super().__init__(**kwargs) @@ -170,7 +171,7 @@ def update( - labels (tIntTensor): Tensor of shape C{(N)} containing 0-indexed detection classes for the boxes. - keypoints (FloatTensor): Tensor of shape C{(N, 3*K)} and in - format C{[x, y, vis, x, y, vis, ...]} where C{x} an C{y} are unnormalized + format C{[x, y, vis, x, y, vis, ...]} where C{x} an C{y} are absolute keypoint coordinates and C{vis} is keypoint visibility. @type target: list[dict[str, Tensor]] @@ -191,7 +192,7 @@ def update( based on the bounding box/masks provided. Only affects which samples contribute to the C{map_small}, C{map_medium}, C{map_large} values. - keypoints (FloatTensor): Tensor of shape C{(N, 3*K)} in format - C{[x, y, vis, x, y, vis, ...]} where C{x} an C{y} are unnormalized keypoint + C{[x, y, vis, x, y, vis, ...]} where C{x} an C{y} are absolute keypoint coordinates and `vis` is keypoint visibility. """ for item in preds: diff --git a/luxonis_train/attached_modules/metrics/object_keypoint_similarity.py b/luxonis_train/attached_modules/metrics/object_keypoint_similarity.py index 248ebe10..3c06e8ca 100644 --- a/luxonis_train/attached_modules/metrics/object_keypoint_similarity.py +++ b/luxonis_train/attached_modules/metrics/object_keypoint_similarity.py @@ -50,8 +50,8 @@ def __init__( if C{None}, then use COCO if possible otherwise defaults. Defaults to C{None}. @type area_factor: float | None - @param area_factor: Factor by which we multiply bbox area. If - None then use default one. Defaults to C{None}. + @param area_factor: Factor by which we multiply the bounding box + area. If not set, the default factor of C{0.53} is used. @type use_cocoeval_oks: bool @param use_cocoeval_oks: Whether to use same OKS formula as in COCOeval or use the one from definition. Defaults to @@ -125,7 +125,7 @@ def update( - keypoints (FloatTensor): Tensor of shape (N, 3*K) and in format [x, y, vis, x, y, vis, ...] where `x` an `y` - are unnormalized keypoint coordinates and `vis` is keypoint visibility. + are absolute keypoint coordinates and `vis` is keypoint visibility. @type target: list[dict[str, Tensor]] @param target: A list consisting of dictionaries each containing key-values for a single image. @@ -133,11 +133,11 @@ def update( - keypoints (FloatTensor): Tensor of shape (N, 3*K) and in format [x, y, vis, x, y, vis, ...] where `x` an `y` - are unnormalized keypoint coordinates and `vis` is keypoint visibility. + are absolute keypoint coordinates and `vis` is keypoint visibility. - scales (FloatTensor): Tensor of shape (N) where each value corresponds to scale of the bounding box. Scale of one bounding box is defined as sqrt(width*height) where - width and height are unnormalized. + width and height are not normalized. """ for item in preds: keypoints = self._fix_empty_tensors(item["keypoints"]) @@ -205,7 +205,7 @@ def compute_oks( @type pred: Tensor[N, K, 3] @param pred: Predicted keypoints. @type gt: Tensor[M, K, 3] - @param gt: Groundtruth keypoints. + @param gt: Ground truth keypoints. @type scales: Tensor[M] @param scales: Scales of the bounding boxes. @type sigmas: Tensor diff --git a/luxonis_train/attached_modules/visualizers/__init__.py b/luxonis_train/attached_modules/visualizers/__init__.py index a5652cb4..50b90471 100644 --- a/luxonis_train/attached_modules/visualizers/__init__.py +++ b/luxonis_train/attached_modules/visualizers/__init__.py @@ -6,14 +6,14 @@ from .segmentation_visualizer import SegmentationVisualizer from .utils import ( combine_visualizations, + denormalize, draw_bounding_box_labels, draw_keypoint_labels, draw_segmentation_labels, get_color, - get_unnormalized_images, + get_denormalized_images, preprocess_images, seg_output_to_bool, - unnormalize, ) __all__ = [ @@ -28,8 +28,8 @@ "draw_keypoint_labels", "draw_segmentation_labels", "get_color", - "get_unnormalized_images", + "get_denormalized_images", "preprocess_images", "seg_output_to_bool", - "unnormalize", + "denormalize", ] diff --git a/luxonis_train/attached_modules/visualizers/utils.py b/luxonis_train/attached_modules/visualizers/utils.py index 76478421..353aa8b0 100644 --- a/luxonis_train/attached_modules/visualizers/utils.py +++ b/luxonis_train/attached_modules/visualizers/utils.py @@ -77,14 +77,14 @@ def preprocess_images( ) -> Tensor: """Performs preprocessing on a batch of images. - Preprocessing includes unnormalizing and converting to uint8. + Preprocessing includes denormalizing and converting to uint8. @type imgs: Tensor @param imgs: Batch of images. @type mean: list[float] | float | None - @param mean: Mean used for unnormalization. Defaults to C{None}. + @param mean: Mean used for denormalization. Defaults to C{None}. @type std: list[float] | float | None - @param std: Std used for unnormalization. Defaults to C{None}. + @param std: Std used for denormalization. Defaults to C{None}. @rtype: Tensor @return: Batch of preprocessed images. """ @@ -92,7 +92,7 @@ def preprocess_images( for i in range(imgs.shape[0]): curr_img = imgs[i] if mean is not None or std is not None: - curr_img = unnormalize(curr_img, to_uint8=True, mean=mean, std=std) + curr_img = denormalize(curr_img, to_uint8=True, mean=mean, std=std) else: curr_img = curr_img.to(torch.uint8) @@ -187,25 +187,25 @@ def seg_output_to_bool(data: Tensor, binary_threshold: float = 0.5) -> Tensor: return masks -def unnormalize( +def denormalize( img: Tensor, mean: list[float] | float | None = None, std: list[float] | float | None = None, to_uint8: bool = False, ) -> Tensor: - """Unnormalizes an image back to original values, optionally + """Denormalizes an image back to original values, optionally converts it to uint8. @type img: Tensor - @param img: Image to unnormalize. + @param img: Image to denormalize. @type mean: list[float] | float | None - @param mean: Mean used for unnormalization. Defaults to C{None}. + @param mean: Mean used for denormalization. Defaults to C{None}. @type std: list[float] | float | None - @param std: Std used for unnormalization. Defaults to C{None}. + @param std: Std used for denormalization. Defaults to C{None}. @type to_uint8: bool @param to_uint8: Whether to convert to uint8. Defaults to C{False}. @rtype: Tensor - @return: Unnormalized image. + @return: denormalized image. """ mean = mean or 0 std = std or 1 @@ -223,7 +223,7 @@ def unnormalize( return out_img -def get_unnormalized_images(cfg: Config, inputs: dict[str, Tensor]) -> Tensor: +def get_denormalized_images(cfg: Config, inputs: dict[str, Tensor]) -> Tensor: # Get images from inputs according to config images = inputs[cfg.loader.image_source] diff --git a/luxonis_train/config/config.py b/luxonis_train/config/config.py index a37f1da9..a163e82c 100644 --- a/luxonis_train/config/config.py +++ b/luxonis_train/config/config.py @@ -384,7 +384,7 @@ class TrainerConfig(BaseModelExtraForbid): def validate_deterministic(self) -> Self: if self.seed is not None and self.deterministic is None: logger.warning( - "Setting `trainer.deterministic` to True because `trainer.seed` is set." + "Setting `trainer.deterministic` to True because `trainer.seed` is set. " "This can cause certain layers to fail. " "In such cases, set `trainer.deterministic` to `'warn'`." ) @@ -489,7 +489,7 @@ def check_environment(cls, data: Any) -> Any: if "ENVIRON" in data: logger.warning( "Specifying `ENVIRON` section in config file is not recommended. " - "Please use environment variables or .env file instead." + "Please use environment variables or `.env` file instead." ) return data diff --git a/luxonis_train/core/core.py b/luxonis_train/core/core.py index 8b8e24c6..ea2010bf 100644 --- a/luxonis_train/core/core.py +++ b/luxonis_train/core/core.py @@ -1,9 +1,10 @@ import os.path as osp import signal import threading +from collections.abc import Mapping from logging import getLogger from pathlib import Path -from typing import Any, Literal, Mapping, overload +from typing import Any, Literal, overload import lightning.pytorch as pl import lightning_utilities.core.rank_zero as rank_zero_module @@ -464,7 +465,7 @@ def infer( process_dataset_images(self, view, save_dir) def tune(self) -> None: - """Runs Optuna tunning of hyperparameters.""" + """Runs Optuna tuning of hyperparameters.""" import optuna from optuna.integration import PyTorchLightningPruningCallback @@ -734,8 +735,8 @@ def get_status(self) -> tuple[int, int]: """Get current status of training. @rtype: tuple[int, int] - @return: First element is current epoch, second element is total - number of epochs. + @return: First element is the current epoch, second element is + the total number of epochs. """ return self.lightning_module.get_status() @@ -765,7 +766,7 @@ def get_min_loss_checkpoint_path(self) -> str | None: validation loss. @rtype: str - @return: Path to best checkpoint with respect to minimal + @return: Path to the best checkpoint with respect to minimal validation loss """ if not self.pl_trainer.checkpoint_callbacks: @@ -778,8 +779,8 @@ def get_best_metric_checkpoint_path(self) -> str | None: metric. @rtype: str - @return: Path to best checkpoint with respect to best validation - metric + @return: Path to the best checkpoint with respect to best + validation metric """ if len(self.pl_trainer.checkpoint_callbacks) < 2: return None diff --git a/luxonis_train/core/utils/export_utils.py b/luxonis_train/core/utils/export_utils.py index fe94556f..25e1a3ff 100644 --- a/luxonis_train/core/utils/export_utils.py +++ b/luxonis_train/core/utils/export_utils.py @@ -25,7 +25,7 @@ def replace_weights( module.load_state_dict(old_weights) except RuntimeError: logger.error( - "Failed to strictly load old weights. The model likey underwent reparametrization, " + "Failed to strictly load old weights. The model likely underwent re-parametrization, " "which is a destructive operation. Loading old weights with strict=False." ) module.load_state_dict(old_weights, strict=False) diff --git a/luxonis_train/core/utils/infer_utils.py b/luxonis_train/core/utils/infer_utils.py index 0240e5fc..4cfd80c6 100644 --- a/luxonis_train/core/utils/infer_utils.py +++ b/luxonis_train/core/utils/infer_utils.py @@ -7,7 +7,7 @@ import tqdm from torch import Tensor -from luxonis_train.attached_modules.visualizers import get_unnormalized_images +from luxonis_train.attached_modules.visualizers import get_denormalized_images from luxonis_train.enums import TaskType IMAGE_FORMATS = { @@ -71,7 +71,7 @@ def prepare_and_infer_image(model, img: np.ndarray, labels: dict, view: str): inputs = { "image": torch.tensor(img).unsqueeze(0).permute(0, 3, 1, 2).float() } - images = get_unnormalized_images(model.cfg, inputs) + images = get_denormalized_images(model.cfg, inputs) outputs = model.lightning_module.forward( inputs, labels, images=images, compute_visualizations=True @@ -154,7 +154,7 @@ def process_dataset_images( ) -> None: """Handles the inference on dataset images.""" for inputs, labels in model.pytorch_loaders[view]: - images = get_unnormalized_images(model.cfg, inputs) + images = get_denormalized_images(model.cfg, inputs) outputs = model.lightning_module.forward( inputs, labels, images=images, compute_visualizations=True ) diff --git a/luxonis_train/core/utils/tune_utils.py b/luxonis_train/core/utils/tune_utils.py index d9d6c4c0..8e1c8443 100644 --- a/luxonis_train/core/utils/tune_utils.py +++ b/luxonis_train/core/utils/tune_utils.py @@ -30,7 +30,7 @@ def _augs_to_indices(all_augs: list[str], aug_names: list[str]) -> list[int]: def get_trial_params( all_augs: list[str], params: dict[str, Any], trial: optuna.trial.Trial ) -> dict[str, Any]: - """Get trial params based on specified config.""" + """Get trial parameters based on specified config.""" new_params = {} for key, value in params.items(): key_info = key.split("_") diff --git a/luxonis_train/models/luxonis_lightning.py b/luxonis_train/models/luxonis_lightning.py index 459b20d1..52f00e40 100644 --- a/luxonis_train/models/luxonis_lightning.py +++ b/luxonis_train/models/luxonis_lightning.py @@ -23,7 +23,7 @@ ) from luxonis_train.attached_modules.visualizers import ( combine_visualizations, - get_unnormalized_images, + get_denormalized_images, ) from luxonis_train.callbacks import BaseLuxonisProgressBar, ModuleFreezer from luxonis_train.config import AttachedModuleConfig, Config @@ -595,11 +595,11 @@ def process_losses( @param losses_dict: Dictionary of computed losses. Each node can have multiple losses attached. The first key identifies the node, the second key identifies the specific loss. Values - are either single tensors or tuples of tensors and - sublosses. + are either single tensors or tuples of tensors and sub- + losses. @rtype: tuple[Tensor, dict[str, Tensor]] - @return: Tuple of final loss and dictionary of processed - sublosses. The dictionary is in a format of {loss_name: + @return: Tuple of final loss and dictionary of processed sub- + losses. The dictionary is in a format of {loss_name: loss_value}. """ final_loss = torch.zeros(1, device=self.device) @@ -694,7 +694,7 @@ def _evaluation_step( inputs, labels = batch images = None if self._logged_images < self.cfg.trainer.n_log_images: - images = get_unnormalized_images(self.cfg, inputs) + images = get_denormalized_images(self.cfg, inputs) outputs = self.forward( inputs, labels, diff --git a/luxonis_train/nodes/backbones/ddrnet/blocks.py b/luxonis_train/nodes/backbones/ddrnet/blocks.py index 64804b0e..ce78503c 100644 --- a/luxonis_train/nodes/backbones/ddrnet/blocks.py +++ b/luxonis_train/nodes/backbones/ddrnet/blocks.py @@ -28,10 +28,11 @@ def __init__( parameter is omitted, and AdaptiveAvgPool2d over all the input is performed. @type stride: int - @param stride: Stride for the first convolution. When stride=0, - AdaptiveAvgPool2d over all the input is performed (output is - 1x1). When stride=1, nothing is performed. When stride>1, a - convolution with stride=stride is performed. + @param stride: Stride for the first convolution. When stride is + set to 0, C{AdaptiveAvgPool2d} over all the input is + performed (output is 1x1). When set to 1, no operation is + performed. When stride>1, a convolution with + C{stride=stride} is performed. @type in_channels: int @param in_channels: Number of input channels. @type branch_channels: int diff --git a/luxonis_train/nodes/backbones/mobileone/blocks.py b/luxonis_train/nodes/backbones/mobileone/blocks.py index 63e19eae..a9006c7e 100644 --- a/luxonis_train/nodes/backbones/mobileone/blocks.py +++ b/luxonis_train/nodes/backbones/mobileone/blocks.py @@ -50,8 +50,8 @@ def __init__( @param use_se: Whether to use SE-ReLU activations. Defaults to False. @type n_conv_branches: int - @param n_conv_branches: Number of linear conv branches. Defaults - to 1. + @param n_conv_branches: Number of convolutional branches. + Defaults to 1. """ super().__init__() @@ -168,8 +168,8 @@ def reparameterize(self): def _get_kernel_bias(self) -> tuple[Tensor, Tensor]: """Method to obtain re-parameterized kernel and bias. - Reference: U{https://github.com/DingXiaoH/RepVGG/blob/main/repvgg.py#L83} + @see: U{https://github.com/DingXiaoH/RepVGG/blob/main/repvgg.py#L83} @rtype: tuple[Tensor, Tensor] @return: Tuple of (kernel, bias) after re-parameterization. """ @@ -205,8 +205,10 @@ def _get_kernel_bias(self) -> tuple[Tensor, Tensor]: return kernel_final, bias_final def _fuse_bn_tensor(self, branch: nn.Module) -> tuple[Tensor, Tensor]: - """Method to fuse batchnorm layer with preceeding conv layer. - Reference: U{https://github.com/DingXiaoH/RepVGG/blob/main/repvgg.py#L95} + """Method to fuse batch normalization layer with preceding + convolutional layer. + + @see: U{https://github.com/DingXiaoH/RepVGG/blob/main/repvgg.py#L95} @rtype: tuple[Tensor, Tensor] @return: Tuple of (kernel, bias) after fusing batchnorm. diff --git a/luxonis_train/nodes/backbones/mobileone/mobileone.py b/luxonis_train/nodes/backbones/mobileone/mobileone.py index 8180f960..054ef381 100644 --- a/luxonis_train/nodes/backbones/mobileone/mobileone.py +++ b/luxonis_train/nodes/backbones/mobileone/mobileone.py @@ -130,7 +130,7 @@ def set_export_mode(self, mode: bool = True) -> None: Reparameterizes the model to obtain a plain CNN-like structure for inference. TODO: add more details - @warning: The reparametrization is destructive and cannot be reversed! + @warning: The re-parametrization is destructive and cannot be reversed! @type export: bool @param export: Whether to set the export mode to True or False. Defaults to True. diff --git a/luxonis_train/nodes/base_node.py b/luxonis_train/nodes/base_node.py index 966c89ae..44f2a69c 100644 --- a/luxonis_train/nodes/base_node.py +++ b/luxonis_train/nodes/base_node.py @@ -44,7 +44,7 @@ class BaseNode( When the node is called, the inputs are sent to the L{unwrap} method. The C{unwrap} method should return a valid input to the L{forward} method. - Outputs of the C{forward} method are then send to L{wrap} method, + Outputs of the C{forward} method are then sent to L{wrap} method, which wraps the output into a C{Packet}. The wrapped C{Packet} is the final output of the node. The L{run} method combines the C{unwrap}, C{forward} and C{wrap} methods @@ -53,9 +53,9 @@ class BaseNode( When subclassing, the following methods should be implemented: - L{forward}: Forward pass of the module. - L{unwrap}: Optional. Unwraps the inputs from the input packet. - The default implementation expects a single input with `features` key. + The default implementation expects a single input with C{features} key. - L{wrap}: Optional. Wraps the output of the forward pass - into a `Packet[Tensor]`. The default implementation expects wraps the output + into a C{Packet[Tensor]}. The default implementation expects wraps the output of the forward pass into a packet with either "features" or the task name as the key. Additionally, the following class attributes can be defined: @@ -64,7 +64,7 @@ class BaseNode( Example:: class MyNode(BaseNode): - # equivalent to `tasks = {TaskType.CLASSIFICATION: "classification"}` + # equivalent to C{tasks = {TaskType.CLASSIFICATION: "classification"}} tasks = [TaskType.CLASSIFICATION] def __init__(self, **kwargs): @@ -95,7 +95,7 @@ def wrap(output: Tensor) -> Packet[Tensor]: @type attach_index: AttachIndexType @ivar attach_index: Index of previous output that this node attaches to. Can be a single integer to specify a single output, a tuple of - two or three integers to specify a range of outputs or `"all"` to + two or three integers to specify a range of outputs or C{"all"} to specify all outputs. Defaults to "all". Python indexing conventions apply. @type tasks: list[TaskType] | dict[TaskType, str] | None @@ -122,37 +122,34 @@ def __init__( attach_index: AttachIndexType | None = None, _tasks: dict[TaskType, str] | None = None, ): - """Constructor for the BaseNode. + """Constructor for the C{BaseNode}. @type input_shapes: list[Packet[Size]] | None @param input_shapes: List of input shapes for the module. - @type original_in_shape: Size | None - @param original_in_shape: Original input shape of the model. Some - nodes won't function if not provided. - - @type dataset_metadata: L{DatasetMetadata} | None - @param dataset_metadata: Metadata of the dataset. + @param original_in_shape: Original input shape of the model. Some nodes won't function if not provided. - + @type dataset_metadata: L{DatasetMetadata} | None + @param dataset_metadata: Metadata of the dataset. Some nodes + won't function if not provided. @type n_classes: int | None @param n_classes: Number of classes in the dataset. Provide only - in case `dataset_metadata` is not provided. Defaults to None. - + in case C{dataset_metadata} is not provided. Defaults to + None. @type in_sizes: Size | list[Size] | None - @param in_sizes: List of input sizes for the node. - Provide only in case the `input_shapes` were not provided. - + @param in_sizes: List of input sizes for the node. Provide only + in case the C{input_shapes} were not provided. @type attach_index: AttachIndexType - @param attach_index: Index of previous output that this node attaches to. - Can be a single integer to specify a single output, a tuple of - two or three integers to specify a range of outputs or `"all"` to - specify all outputs. Defaults to "all". Python indexing conventions apply. If provided as a constructor argument, overrides the class attribute. - - + @param attach_index: Index of previous output that this node + attaches to. Can be a single integer to specify a single + output, a tuple of two or three integers to specify a range + of outputs or C{"all"} to specify all outputs. Defaults to + "all". Python indexing conventions apply. If provided as a + constructor argument, overrides the class attribute. @type _tasks: dict[TaskType, str] | None - @param _tasks: Dictionary of tasks that the node supports. Overrides the - class L{tasks} attribute. Shouldn't be provided by the user in most cases. + @param _tasks: Dictionary of tasks that the node supports. + Overrides the class L{tasks} attribute. Shouldn't be + provided by the user in most cases. """ super().__init__() @@ -423,10 +420,10 @@ def dataset_metadata(self) -> DatasetMetadata: def in_sizes(self) -> Size | list[Size]: """Simplified getter for the input shapes. - Should work out of the box for most cases where the `input_shapes` are - sufficiently simple. Otherwise the `input_shapes` should be used directly. + Should work out of the box for most cases where the C{input_shapes} are + sufficiently simple. Otherwise, the C{input_shapes} should be used directly. - In case `in_sizes` were provided during initialization, they are returned + In case C{in_sizes} were provided during initialization, they are returned directly. Example:: @@ -459,7 +456,7 @@ def in_channels(self) -> int | list[int]: """Simplified getter for the number of input channels. Should work out of the box for most cases where the - C{input_shapes} are sufficiently simple. Otherwise the + C{input_shapes} are sufficiently simple. Otherwise, the C{input_shapes} should be used directly. If C{attach_index} is set to "all" or is a slice, returns a list of input channels, otherwise returns a single value. @@ -474,12 +471,13 @@ def in_channels(self) -> int | list[int]: def in_height(self) -> int | list[int]: """Simplified getter for the input height. - Should work out of the box for most cases where the `input_shapes` are - sufficiently simple. Otherwise the `input_shapes` should be used directly. + Should work out of the box for most cases where the + C{input_shapes} are sufficiently simple. Otherwise, the + C{input_shapes} should be used directly. @type: int | list[int] - @raises RuntimeError: If the C{input_shapes} are too complicated for - the default implementation of C{in_sizes}. + @raises RuntimeError: If the C{input_shapes} are too complicated + for the default implementation of C{in_sizes}. """ return self._get_nth_size(-2) @@ -487,12 +485,13 @@ def in_height(self) -> int | list[int]: def in_width(self) -> int | list[int]: """Simplified getter for the input width. - Should work out of the box for most cases where the `input_shapes` are - sufficiently simple. Otherwise the `input_shapes` should be used directly. + Should work out of the box for most cases where the + C{input_shapes} are sufficiently simple. Otherwise, the + C{input_shapes} should be used directly. @type: int | list[int] - @raises RuntimeError: If the C{input_shapes} are too complicated for - the default implementation of C{in_sizes}. + @raises RuntimeError: If the C{input_shapes} are too complicated + for the default implementation of C{in_sizes}. """ return self._get_nth_size(-1) @@ -553,7 +552,8 @@ def forward(self, inputs: ForwardInputT) -> ForwardOutputT: ... def wrap(self, output: ForwardOutputT) -> Packet[Tensor]: - """Wraps the output of the forward pass into a `Packet[Tensor]`. + """Wraps the output of the forward pass into a + C{Packet[Tensor]}. The default implementation expects a single tensor or a list of tensors and wraps them into a Packet with either the node task as a key @@ -609,7 +609,7 @@ def run(self, inputs: list[Packet[Tensor]]) -> Packet[Tensor]: @rtype: L{Packet}[Tensor] @return: Outputs of the module as a dictionary of list of tensors: - `{"features": [Tensor, ...], "segmentation": [Tensor]}` + C{{"features": [Tensor, ...], "segmentation": [Tensor]}} @raises RuntimeError: If default L{wrap} or L{unwrap} methods are not sufficient. """ diff --git a/luxonis_train/utils/boundingbox.py b/luxonis_train/utils/boundingbox.py index 8c5a9d40..008ac4f6 100644 --- a/luxonis_train/utils/boundingbox.py +++ b/luxonis_train/utils/boundingbox.py @@ -162,7 +162,7 @@ def bbox_iou( @type bbox2: Tensor @param bbox2: Second set of bboxes [M, 4]. @type bbox_format: BBoxFormatType - @param bbox_format: Input bbox format. Defaults to "xyxy". + @param bbox_format: Input bounding box format. Defaults to C{"xyxy"}. @type iou_type: Literal["none", "giou", "diou", "ciou", "siou"] @param iou_type: IoU type. Defaults to "none". Possible values are: @@ -481,8 +481,8 @@ def calc_best_anchor_ratio(anchors: Tensor, wh: Tensor) -> Tensor: return best_anchor_ratio def calc_best_possible_recall(anchors: Tensor, wh: Tensor) -> Tensor: - """Calculate best possible recall if every bbox is matched to an - appropriate anchor.""" + """Calculate the best possible recall if every bbox is matched + to an appropriate anchor.""" best_anchor_ratio = calc_best_anchor_ratio(anchors, wh) best_possible_recall = ( (best_anchor_ratio > 1 / ratio_threshold).float().mean() diff --git a/tests/unittests/test_assigners/test_atts_assigner.py b/tests/unittests/test_assigners/test_atss_assigner.py similarity index 100% rename from tests/unittests/test_assigners/test_atts_assigner.py rename to tests/unittests/test_assigners/test_atss_assigner.py