From fc97b9b6d05d88ae02552d9d00b3a24bb1a57980 Mon Sep 17 00:00:00 2001 From: "Kang, Harim" Date: Tue, 13 Feb 2024 12:02:56 +0900 Subject: [PATCH 01/10] Address Adaptive Setting issue --- src/otx/algo/callbacks/adaptive_train_scheduling.py | 5 +++-- .../classification/h_label_cls/efficientnet_b0_light.yaml | 5 +++++ .../classification/h_label_cls/efficientnet_v2_light.yaml | 5 +++++ .../h_label_cls/mobilenet_v3_large_light.yaml | 5 +++++ .../recipe/classification/h_label_cls/otx_deit_tiny.yaml | 5 +++++ .../multi_class_cls/efficientnet_b0_light.yaml | 7 +++++++ .../multi_class_cls/efficientnet_v2_light.yaml | 5 +++++ .../multi_class_cls/mobilenet_v3_large_light.yaml | 5 +++++ .../classification/multi_class_cls/otx_deit_tiny.yaml | 7 +++++++ .../recipe/classification/multi_class_cls/otx_dino_v2.yaml | 5 +++++ .../multi_class_cls/otx_dino_v2_linear_probe.yaml | 5 +++++ .../multi_class_cls/otx_efficientnet_b0.yaml | 7 +++++++ .../multi_class_cls/otx_efficientnet_v2.yaml | 5 +++++ .../multi_class_cls/otx_mobilenet_v3_large.yaml | 5 +++++ .../multi_label_cls/efficientnet_b0_light.yaml | 5 +++++ .../multi_label_cls/efficientnet_v2_light.yaml | 5 +++++ .../multi_label_cls/mobilenet_v3_large_light.yaml | 5 +++++ .../classification/multi_label_cls/otx_deit_tiny.yaml | 5 +++++ .../instance_segmentation/maskrcnn_efficientnetb2b.yaml | 1 + .../maskrcnn_efficientnetb2b_tile.yaml | 1 + src/otx/recipe/instance_segmentation/maskrcnn_r50.yaml | 1 + .../recipe/instance_segmentation/maskrcnn_r50_tile.yaml | 1 + src/otx/recipe/instance_segmentation/maskrcnn_swint.yaml | 1 + .../recipe/rotated_detection/maskrcnn_efficientnetb2b.yaml | 1 + src/otx/recipe/rotated_detection/maskrcnn_r50.yaml | 1 + src/otx/recipe/semantic_segmentation/litehrnet_18.yaml | 3 +++ src/otx/recipe/semantic_segmentation/litehrnet_s.yaml | 3 +++ src/otx/recipe/semantic_segmentation/litehrnet_x.yaml | 3 +++ src/otx/recipe/semantic_segmentation/segnext_b.yaml | 1 + src/otx/recipe/semantic_segmentation/segnext_s.yaml | 1 + src/otx/recipe/semantic_segmentation/segnext_t.yaml | 1 + 31 files changed, 113 insertions(+), 2 deletions(-) diff --git a/src/otx/algo/callbacks/adaptive_train_scheduling.py b/src/otx/algo/callbacks/adaptive_train_scheduling.py index ae63040f056..42a4f6d1045 100644 --- a/src/otx/algo/callbacks/adaptive_train_scheduling.py +++ b/src/otx/algo/callbacks/adaptive_train_scheduling.py @@ -104,9 +104,10 @@ def _revert_func(config: LRSchedulerConfig, saved_frequency: int) -> None: config.frequency = saved_frequency for config in lr_configs: - if hasattr(config, "frequency"): + if hasattr(config, "frequency") and hasattr(config, "interval") and config.interval == "epoch": + scheduler_name = config.scheduler.__class__.__name__ msg = ( - "The frequency of LRscheduler will be changed due to the effect of adaptive interval: " + f"The frequency of {scheduler_name} will be changed due to the effect of adaptive interval: " f"{config.frequency} --> {adaptive_interval}." ) log.warning(msg) diff --git a/src/otx/recipe/classification/h_label_cls/efficientnet_b0_light.yaml b/src/otx/recipe/classification/h_label_cls/efficientnet_b0_light.yaml index 6717202c843..8876829fac9 100644 --- a/src/otx/recipe/classification/h_label_cls/efficientnet_b0_light.yaml +++ b/src/otx/recipe/classification/h_label_cls/efficientnet_b0_light.yaml @@ -27,6 +27,11 @@ callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 data: task: H_LABEL_CLS config: diff --git a/src/otx/recipe/classification/h_label_cls/efficientnet_v2_light.yaml b/src/otx/recipe/classification/h_label_cls/efficientnet_v2_light.yaml index 6f63839aee3..53a4c4ce426 100644 --- a/src/otx/recipe/classification/h_label_cls/efficientnet_v2_light.yaml +++ b/src/otx/recipe/classification/h_label_cls/efficientnet_v2_light.yaml @@ -29,6 +29,11 @@ callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 data: task: H_LABEL_CLS config: diff --git a/src/otx/recipe/classification/h_label_cls/mobilenet_v3_large_light.yaml b/src/otx/recipe/classification/h_label_cls/mobilenet_v3_large_light.yaml index fb4e34bc725..245cbe76be1 100644 --- a/src/otx/recipe/classification/h_label_cls/mobilenet_v3_large_light.yaml +++ b/src/otx/recipe/classification/h_label_cls/mobilenet_v3_large_light.yaml @@ -29,6 +29,11 @@ callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 data: task: H_LABEL_CLS config: diff --git a/src/otx/recipe/classification/h_label_cls/otx_deit_tiny.yaml b/src/otx/recipe/classification/h_label_cls/otx_deit_tiny.yaml index d837293b0a3..90a2fda58f6 100644 --- a/src/otx/recipe/classification/h_label_cls/otx_deit_tiny.yaml +++ b/src/otx/recipe/classification/h_label_cls/otx_deit_tiny.yaml @@ -28,6 +28,11 @@ callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 data: task: H_LABEL_CLS config: diff --git a/src/otx/recipe/classification/multi_class_cls/efficientnet_b0_light.yaml b/src/otx/recipe/classification/multi_class_cls/efficientnet_b0_light.yaml index ec9309a707c..3cee731ae98 100644 --- a/src/otx/recipe/classification/multi_class_cls/efficientnet_b0_light.yaml +++ b/src/otx/recipe/classification/multi_class_cls/efficientnet_b0_light.yaml @@ -27,3 +27,10 @@ engine: callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml + +overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 diff --git a/src/otx/recipe/classification/multi_class_cls/efficientnet_v2_light.yaml b/src/otx/recipe/classification/multi_class_cls/efficientnet_v2_light.yaml index eb50774b193..8170ebde48c 100644 --- a/src/otx/recipe/classification/multi_class_cls/efficientnet_v2_light.yaml +++ b/src/otx/recipe/classification/multi_class_cls/efficientnet_v2_light.yaml @@ -28,6 +28,11 @@ callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 data: config: train_subset: diff --git a/src/otx/recipe/classification/multi_class_cls/mobilenet_v3_large_light.yaml b/src/otx/recipe/classification/multi_class_cls/mobilenet_v3_large_light.yaml index 200fe8b08cc..c00fe2536e9 100644 --- a/src/otx/recipe/classification/multi_class_cls/mobilenet_v3_large_light.yaml +++ b/src/otx/recipe/classification/multi_class_cls/mobilenet_v3_large_light.yaml @@ -28,6 +28,11 @@ callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 data: config: train_subset: diff --git a/src/otx/recipe/classification/multi_class_cls/otx_deit_tiny.yaml b/src/otx/recipe/classification/multi_class_cls/otx_deit_tiny.yaml index 5c3373ce98f..91453e10583 100644 --- a/src/otx/recipe/classification/multi_class_cls/otx_deit_tiny.yaml +++ b/src/otx/recipe/classification/multi_class_cls/otx_deit_tiny.yaml @@ -25,3 +25,10 @@ engine: callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml + +overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 diff --git a/src/otx/recipe/classification/multi_class_cls/otx_dino_v2.yaml b/src/otx/recipe/classification/multi_class_cls/otx_dino_v2.yaml index e911b5e06a2..e69f1e1aa8e 100644 --- a/src/otx/recipe/classification/multi_class_cls/otx_dino_v2.yaml +++ b/src/otx/recipe/classification/multi_class_cls/otx_dino_v2.yaml @@ -34,6 +34,11 @@ callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 data: config: train_subset: diff --git a/src/otx/recipe/classification/multi_class_cls/otx_dino_v2_linear_probe.yaml b/src/otx/recipe/classification/multi_class_cls/otx_dino_v2_linear_probe.yaml index 4ea1f2d67bf..3aaba0b25bd 100644 --- a/src/otx/recipe/classification/multi_class_cls/otx_dino_v2_linear_probe.yaml +++ b/src/otx/recipe/classification/multi_class_cls/otx_dino_v2_linear_probe.yaml @@ -36,6 +36,11 @@ callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 data: config: train_subset: diff --git a/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_b0.yaml b/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_b0.yaml index 8526dc42b0d..62e21491124 100644 --- a/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_b0.yaml +++ b/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_b0.yaml @@ -26,3 +26,10 @@ engine: callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml + +overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 diff --git a/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_v2.yaml b/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_v2.yaml index 1dee8cd1331..f348b84945b 100644 --- a/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_v2.yaml +++ b/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_v2.yaml @@ -27,6 +27,11 @@ callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 data: config: train_subset: diff --git a/src/otx/recipe/classification/multi_class_cls/otx_mobilenet_v3_large.yaml b/src/otx/recipe/classification/multi_class_cls/otx_mobilenet_v3_large.yaml index 5c280d6b397..4596010459f 100644 --- a/src/otx/recipe/classification/multi_class_cls/otx_mobilenet_v3_large.yaml +++ b/src/otx/recipe/classification/multi_class_cls/otx_mobilenet_v3_large.yaml @@ -27,6 +27,11 @@ callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 data: config: train_subset: diff --git a/src/otx/recipe/classification/multi_label_cls/efficientnet_b0_light.yaml b/src/otx/recipe/classification/multi_label_cls/efficientnet_b0_light.yaml index 7b055bb74d7..d3632d4cad4 100644 --- a/src/otx/recipe/classification/multi_label_cls/efficientnet_b0_light.yaml +++ b/src/otx/recipe/classification/multi_label_cls/efficientnet_b0_light.yaml @@ -25,6 +25,11 @@ callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 data: task: MULTI_LABEL_CLS config: diff --git a/src/otx/recipe/classification/multi_label_cls/efficientnet_v2_light.yaml b/src/otx/recipe/classification/multi_label_cls/efficientnet_v2_light.yaml index 7517e625995..4e6f625f98b 100644 --- a/src/otx/recipe/classification/multi_label_cls/efficientnet_v2_light.yaml +++ b/src/otx/recipe/classification/multi_label_cls/efficientnet_v2_light.yaml @@ -27,6 +27,11 @@ callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 data: task: MULTI_LABEL_CLS config: diff --git a/src/otx/recipe/classification/multi_label_cls/mobilenet_v3_large_light.yaml b/src/otx/recipe/classification/multi_label_cls/mobilenet_v3_large_light.yaml index 78f34991e0d..f8468b4fd49 100644 --- a/src/otx/recipe/classification/multi_label_cls/mobilenet_v3_large_light.yaml +++ b/src/otx/recipe/classification/multi_label_cls/mobilenet_v3_large_light.yaml @@ -27,6 +27,11 @@ callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 data: task: MULTI_LABEL_CLS config: diff --git a/src/otx/recipe/classification/multi_label_cls/otx_deit_tiny.yaml b/src/otx/recipe/classification/multi_label_cls/otx_deit_tiny.yaml index 2c1b64e8452..8a38e647ce1 100644 --- a/src/otx/recipe/classification/multi_label_cls/otx_deit_tiny.yaml +++ b/src/otx/recipe/classification/multi_label_cls/otx_deit_tiny.yaml @@ -26,6 +26,11 @@ callback_monitor: val/accuracy data: ../../_base_/data/mmpretrain_base.yaml overrides: + max_epochs: 90 + callbacks: + - class_path: lightning.pytorch.callbacks.EarlyStopping + init_args: + patience: 3 data: task: MULTI_LABEL_CLS config: diff --git a/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b.yaml b/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b.yaml index 4a207a8f4b6..4bf7e0ca358 100644 --- a/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b.yaml +++ b/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b.yaml @@ -28,6 +28,7 @@ callback_monitor: val/map_50 data: ../_base_/data/mmdet_base.yaml overrides: + max_epochs: 100 data: task: INSTANCE_SEGMENTATION config: diff --git a/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b_tile.yaml b/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b_tile.yaml index aab00bcca18..e4ba52e5a4b 100644 --- a/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b_tile.yaml +++ b/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b_tile.yaml @@ -28,6 +28,7 @@ callback_monitor: val/map_50 data: ../_base_/data/mmdet_base.yaml overrides: + max_epochs: 100 gradient_clip_val: 35.0 data: task: INSTANCE_SEGMENTATION diff --git a/src/otx/recipe/instance_segmentation/maskrcnn_r50.yaml b/src/otx/recipe/instance_segmentation/maskrcnn_r50.yaml index 56cdb8cd1d2..1cd08c0f711 100644 --- a/src/otx/recipe/instance_segmentation/maskrcnn_r50.yaml +++ b/src/otx/recipe/instance_segmentation/maskrcnn_r50.yaml @@ -28,6 +28,7 @@ callback_monitor: val/map_50 data: ../_base_/data/mmdet_base.yaml overrides: + max_epochs: 100 gradient_clip_val: 35.0 data: task: INSTANCE_SEGMENTATION diff --git a/src/otx/recipe/instance_segmentation/maskrcnn_r50_tile.yaml b/src/otx/recipe/instance_segmentation/maskrcnn_r50_tile.yaml index 9375bfff69e..bc4abe0bb8a 100644 --- a/src/otx/recipe/instance_segmentation/maskrcnn_r50_tile.yaml +++ b/src/otx/recipe/instance_segmentation/maskrcnn_r50_tile.yaml @@ -28,6 +28,7 @@ callback_monitor: val/map_50 data: ../_base_/data/mmdet_base.yaml overrides: + max_epochs: 100 gradient_clip_val: 35.0 data: task: INSTANCE_SEGMENTATION diff --git a/src/otx/recipe/instance_segmentation/maskrcnn_swint.yaml b/src/otx/recipe/instance_segmentation/maskrcnn_swint.yaml index 5a8a7ddf3e8..426c043537e 100644 --- a/src/otx/recipe/instance_segmentation/maskrcnn_swint.yaml +++ b/src/otx/recipe/instance_segmentation/maskrcnn_swint.yaml @@ -26,6 +26,7 @@ callback_monitor: val/map_50 data: ../_base_/data/mmdet_base.yaml overrides: + max_epochs: 100 data: task: INSTANCE_SEGMENTATION config: diff --git a/src/otx/recipe/rotated_detection/maskrcnn_efficientnetb2b.yaml b/src/otx/recipe/rotated_detection/maskrcnn_efficientnetb2b.yaml index 64e89e0850a..a04641fefa9 100644 --- a/src/otx/recipe/rotated_detection/maskrcnn_efficientnetb2b.yaml +++ b/src/otx/recipe/rotated_detection/maskrcnn_efficientnetb2b.yaml @@ -27,6 +27,7 @@ callback_monitor: val/map_50 data: ../_base_/data/mmdet_base.yaml overrides: + max_epochs: 100 data: task: ROTATED_DETECTION config: diff --git a/src/otx/recipe/rotated_detection/maskrcnn_r50.yaml b/src/otx/recipe/rotated_detection/maskrcnn_r50.yaml index 20bdc6c4ec2..7bf948ff143 100644 --- a/src/otx/recipe/rotated_detection/maskrcnn_r50.yaml +++ b/src/otx/recipe/rotated_detection/maskrcnn_r50.yaml @@ -27,6 +27,7 @@ callback_monitor: val/map_50 data: ../_base_/data/mmdet_base.yaml overrides: + max_epochs: 100 data: task: ROTATED_DETECTION config: diff --git a/src/otx/recipe/semantic_segmentation/litehrnet_18.yaml b/src/otx/recipe/semantic_segmentation/litehrnet_18.yaml index b4215984175..c9abaca29ab 100644 --- a/src/otx/recipe/semantic_segmentation/litehrnet_18.yaml +++ b/src/otx/recipe/semantic_segmentation/litehrnet_18.yaml @@ -29,3 +29,6 @@ engine: callback_monitor: val/mIoU data: ../_base_/data/mmseg_base.yaml + +overrides: + max_epochs: 300 diff --git a/src/otx/recipe/semantic_segmentation/litehrnet_s.yaml b/src/otx/recipe/semantic_segmentation/litehrnet_s.yaml index f0b575b4a0d..b87558ef1c8 100644 --- a/src/otx/recipe/semantic_segmentation/litehrnet_s.yaml +++ b/src/otx/recipe/semantic_segmentation/litehrnet_s.yaml @@ -29,3 +29,6 @@ engine: callback_monitor: val/mIoU data: ../_base_/data/mmseg_base.yaml + +overrides: + max_epochs: 300 diff --git a/src/otx/recipe/semantic_segmentation/litehrnet_x.yaml b/src/otx/recipe/semantic_segmentation/litehrnet_x.yaml index 115c655df0e..3110e01d895 100644 --- a/src/otx/recipe/semantic_segmentation/litehrnet_x.yaml +++ b/src/otx/recipe/semantic_segmentation/litehrnet_x.yaml @@ -29,3 +29,6 @@ engine: callback_monitor: val/mIoU data: ../_base_/data/mmseg_base.yaml + +overrides: + max_epochs: 300 diff --git a/src/otx/recipe/semantic_segmentation/segnext_b.yaml b/src/otx/recipe/semantic_segmentation/segnext_b.yaml index 8655921665f..2e4b2a92540 100644 --- a/src/otx/recipe/semantic_segmentation/segnext_b.yaml +++ b/src/otx/recipe/semantic_segmentation/segnext_b.yaml @@ -29,6 +29,7 @@ callback_monitor: val/mIoU data: ../_base_/data/mmseg_base.yaml overrides: + max_epochs: 150 data: config: train_subset: diff --git a/src/otx/recipe/semantic_segmentation/segnext_s.yaml b/src/otx/recipe/semantic_segmentation/segnext_s.yaml index 7c1faa86567..c03511307c1 100644 --- a/src/otx/recipe/semantic_segmentation/segnext_s.yaml +++ b/src/otx/recipe/semantic_segmentation/segnext_s.yaml @@ -29,6 +29,7 @@ callback_monitor: val/mIoU data: ../_base_/data/mmseg_base.yaml overrides: + max_epochs: 150 data: config: train_subset: diff --git a/src/otx/recipe/semantic_segmentation/segnext_t.yaml b/src/otx/recipe/semantic_segmentation/segnext_t.yaml index 11c78833275..901af6c7647 100644 --- a/src/otx/recipe/semantic_segmentation/segnext_t.yaml +++ b/src/otx/recipe/semantic_segmentation/segnext_t.yaml @@ -29,6 +29,7 @@ callback_monitor: val/mIoU data: ../_base_/data/mmseg_base.yaml overrides: + max_epochs: 150 data: config: train_subset: From ad8b8159c17c4b6c2474574d970166f27e29ed69 Mon Sep 17 00:00:00 2001 From: "Kang, Harim" Date: Tue, 13 Feb 2024 14:41:44 +0900 Subject: [PATCH 02/10] Fix to receive optimizers and schedulers as a list --- .../callbacks/adaptive_train_scheduling.py | 3 +- src/otx/cli/cli.py | 20 ++++--- .../model/module/action_classification.py | 4 +- src/otx/core/model/module/action_detection.py | 4 +- src/otx/core/model/module/base.py | 53 ++++++++----------- src/otx/core/model/module/classification.py | 12 ++--- src/otx/core/model/module/detection.py | 4 +- .../model/module/instance_segmentation.py | 4 +- .../core/model/module/rotated_detection.py | 4 +- src/otx/core/model/module/segmentation.py | 4 +- src/otx/core/model/module/visual_prompting.py | 4 +- src/otx/engine/engine.py | 12 ++--- src/otx/engine/utils/auto_configurator.py | 10 +++- .../action/action_classification/x3d.yaml | 16 +++--- .../action/action_detection/x3d_fastrcnn.yaml | 16 +++--- .../h_label_cls/efficientnet_b0_light.yaml | 16 +++--- .../h_label_cls/efficientnet_v2_light.yaml | 16 +++--- .../h_label_cls/mobilenet_v3_large_light.yaml | 16 +++--- .../h_label_cls/otx_deit_tiny.yaml | 16 +++--- .../efficientnet_b0_light.yaml | 16 +++--- .../efficientnet_v2_light.yaml | 16 +++--- .../mobilenet_v3_large_light.yaml | 16 +++--- .../multi_class_cls/otx_deit_tiny.yaml | 16 +++--- .../multi_class_cls/otx_efficientnet_b0.yaml | 15 +++--- .../multi_class_cls/otx_efficientnet_v2.yaml | 15 +++--- .../otx_mobilenet_v3_large.yaml | 15 +++--- .../efficientnet_b0_light.yaml | 16 +++--- .../efficientnet_v2_light.yaml | 16 +++--- .../mobilenet_v3_large_light.yaml | 16 +++--- .../multi_label_cls/otx_deit_tiny.yaml | 16 +++--- .../recipe/detection/atss_mobilenetv2.yaml | 16 +++--- src/otx/recipe/detection/atss_r50_fpn.yaml | 16 +++--- src/otx/recipe/detection/atss_resnext101.yaml | 16 +++--- src/otx/recipe/detection/ssd_mobilenetv2.yaml | 16 +++--- src/otx/recipe/detection/yolox_l.yaml | 16 +++--- src/otx/recipe/detection/yolox_l_tile.yaml | 16 +++--- src/otx/recipe/detection/yolox_s.yaml | 16 +++--- src/otx/recipe/detection/yolox_s_tile.yaml | 16 +++--- src/otx/recipe/detection/yolox_tiny.yaml | 16 +++--- src/otx/recipe/detection/yolox_tiny_tile.yaml | 16 +++--- src/otx/recipe/detection/yolox_x.yaml | 16 +++--- src/otx/recipe/detection/yolox_x_tile.yaml | 16 +++--- .../maskrcnn_efficientnetb2b.yaml | 16 +++--- .../maskrcnn_efficientnetb2b_tile.yaml | 16 +++--- .../instance_segmentation/maskrcnn_r50.yaml | 16 +++--- .../maskrcnn_r50_tile.yaml | 16 +++--- .../instance_segmentation/maskrcnn_swint.yaml | 16 +++--- .../maskrcnn_efficientnetb2b.yaml | 15 +++--- .../rotated_detection/maskrcnn_r50.yaml | 15 +++--- .../semantic_segmentation/litehrnet_18.yaml | 16 +++--- .../semantic_segmentation/litehrnet_s.yaml | 16 +++--- .../semantic_segmentation/litehrnet_x.yaml | 16 +++--- .../semantic_segmentation/segnext_b.yaml | 16 +++--- .../semantic_segmentation/segnext_s.yaml | 16 +++--- .../semantic_segmentation/segnext_t.yaml | 16 +++--- .../test_adaptive_train_scheduling.py | 1 + tests/unit/core/model/module/test_base.py | 23 ++++---- .../engine/utils/test_auto_configurator.py | 14 ++++- 58 files changed, 475 insertions(+), 368 deletions(-) diff --git a/src/otx/algo/callbacks/adaptive_train_scheduling.py b/src/otx/algo/callbacks/adaptive_train_scheduling.py index 42a4f6d1045..afeeaa0bb35 100644 --- a/src/otx/algo/callbacks/adaptive_train_scheduling.py +++ b/src/otx/algo/callbacks/adaptive_train_scheduling.py @@ -105,9 +105,8 @@ def _revert_func(config: LRSchedulerConfig, saved_frequency: int) -> None: for config in lr_configs: if hasattr(config, "frequency") and hasattr(config, "interval") and config.interval == "epoch": - scheduler_name = config.scheduler.__class__.__name__ msg = ( - f"The frequency of {scheduler_name} will be changed due to the effect of adaptive interval: " + "The frequency of LRscheduler will be changed due to the effect of adaptive interval: " f"{config.frequency} --> {adaptive_interval}." ) log.warning(msg) diff --git a/src/otx/cli/cli.py b/src/otx/cli/cli.py index 2c7159f990a..1d7850d9b21 100644 --- a/src/otx/cli/cli.py +++ b/src/otx/cli/cli.py @@ -156,18 +156,20 @@ def engine_subcommand_parser(**kwargs) -> ArgumentParser: sub_configs=True, ) # Optimizer & Scheduler Settings - from lightning.pytorch.cli import LRSchedulerTypeTuple + from lightning.pytorch.cli import ReduceLROnPlateau from torch.optim import Optimizer + from torch.optim.lr_scheduler import LRScheduler optim_kwargs = {"instantiate": False, "fail_untyped": False, "skip": {"params"}} scheduler_kwargs = {"instantiate": False, "fail_untyped": False, "skip": {"optimizer"}} parser.add_subclass_arguments( - baseclass=(Optimizer,), + baseclass=(Optimizer, list[Optimizer]), nested_key="optimizer", **optim_kwargs, ) + scheduler_type = (LRScheduler, ReduceLROnPlateau, list[LRScheduler | ReduceLROnPlateau]) parser.add_subclass_arguments( - baseclass=LRSchedulerTypeTuple, + baseclass=scheduler_type, nested_key="scheduler", **scheduler_kwargs, ) @@ -341,11 +343,17 @@ def instantiate_model(self, model_config: Namespace) -> tuple: # Update self.config with model self.config[self.subcommand].update(Namespace(model=model_config)) - optimizer_kwargs = namespace_to_dict(self.get_config_value(self.config_init, "optimizer", Namespace())) - scheduler_kwargs = namespace_to_dict(self.get_config_value(self.config_init, "scheduler", Namespace())) from otx.core.utils.instantiators import partial_instantiate_class - return model, partial_instantiate_class(optimizer_kwargs), partial_instantiate_class(scheduler_kwargs) + optimizer_kwargs = self.get_config_value(self.config_init, "optimizer", Namespace()) + optimizer_kwargs = optimizer_kwargs if isinstance(optimizer_kwargs, list) else [optimizer_kwargs] + optimizers = [partial_instantiate_class(namespace_to_dict(_opt)) for _opt in optimizer_kwargs] + + scheduler_kwargs = self.get_config_value(self.config_init, "scheduler", Namespace()) + scheduler_kwargs = scheduler_kwargs if isinstance(scheduler_kwargs, list) else [scheduler_kwargs] + schedulers = [partial_instantiate_class(namespace_to_dict(_sch)) for _sch in scheduler_kwargs] + + return model, optimizers, schedulers def get_config_value(self, config: Namespace, key: str, default: Any = None) -> Any: # noqa: ANN401 """Retrieves the value of a configuration key from the given config object. diff --git a/src/otx/core/model/module/action_classification.py b/src/otx/core/model/module/action_classification.py index 867f7378283..cdc4d065982 100644 --- a/src/otx/core/model/module/action_classification.py +++ b/src/otx/core/model/module/action_classification.py @@ -28,8 +28,8 @@ def __init__( self, otx_model: OTXActionClsModel, torch_compile: bool, - optimizer: OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), - scheduler: LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, + optimizer: list[OptimizerCallable] | OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), + scheduler: list[LRSchedulerCallable] | LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, ): super().__init__( otx_model=otx_model, diff --git a/src/otx/core/model/module/action_detection.py b/src/otx/core/model/module/action_detection.py index cf9ff35baaf..3e5f0ba7d46 100644 --- a/src/otx/core/model/module/action_detection.py +++ b/src/otx/core/model/module/action_detection.py @@ -29,8 +29,8 @@ def __init__( self, otx_model: OTXActionDetModel, torch_compile: bool, - optimizer: OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), - scheduler: LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, + optimizer: list[OptimizerCallable] | OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), + scheduler: list[LRSchedulerCallable] | LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, ): super().__init__( otx_model=otx_model, diff --git a/src/otx/core/model/module/base.py b/src/otx/core/model/module/base.py index b0e90ef16c9..2c4a041a7f3 100644 --- a/src/otx/core/model/module/base.py +++ b/src/otx/core/model/module/base.py @@ -12,7 +12,6 @@ from lightning import LightningModule from torch import Tensor -from otx.algo.schedulers.warmup_schedulers import BaseWarmupScheduler from otx.core.data.entity.base import ( OTXBatchDataEntity, OTXBatchLossEntity, @@ -34,11 +33,13 @@ def __init__( self, optimizer: torch.optim.Optimizer, num_warmup_steps: int = 1000, + interval: str = "step", ): if num_warmup_steps > 0: msg = f"num_warmup_steps should be > 0, got {num_warmup_steps}" ValueError(msg) self.num_warmup_steps = num_warmup_steps + self.interval = interval super().__init__(optimizer, lambda step: min(step / num_warmup_steps, 1.0)) @@ -50,8 +51,8 @@ def __init__( *, otx_model: OTXModel, torch_compile: bool, - optimizer: OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), - scheduler: LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, + optimizer: list[OptimizerCallable] | OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), + scheduler: list[LRSchedulerCallable] | LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, ): super().__init__() @@ -110,7 +111,7 @@ def setup(self, stage: str) -> None: if self.torch_compile and stage == "fit": self.model = torch.compile(self.model) - def configure_optimizers(self) -> tuple[list[torch.optim.Optimizer], list[torch.optim.Optimizer]]: + def configure_optimizers(self) -> tuple[list[torch.optim.Optimizer], list[dict]]: """Choose what optimizers and learning-rate schedulers to use in your optimization. Normally you'd need one. But in the case of GANs or similar you might have multiple. @@ -120,34 +121,26 @@ def configure_optimizers(self) -> tuple[list[torch.optim.Optimizer], list[torch. :return: A dict containing the configured optimizers and learning-rate schedulers to be used for training. """ - optimizer = ( - self.hparams.optimizer(params=self.parameters()) - if callable(self.hparams.optimizer) - else self.hparams.optimizer - ) - - scheduler = ( - self.hparams.scheduler(optimizer=optimizer) if callable(self.hparams.scheduler) else self.hparams.scheduler - ) - - lr_scheduler_configs = [] - if isinstance(scheduler, BaseWarmupScheduler) and scheduler.warmup_steps > 0: - lr_scheduler_configs += [ - { - "scheduler": LinearWarmupScheduler(optimizer, num_warmup_steps=scheduler.warmup_steps), - "interval": "step", - }, - ] - lr_scheduler_configs += [ - { - "scheduler": scheduler, - "monitor": self.lr_scheduler_monitor_key, - "interval": "epoch", - "frequency": self.trainer.check_val_every_n_epoch, - }, + + def ensure_list(item: Any) -> list: # noqa: ANN401 + return item if isinstance(item, list) else [item] + + optimizers = [ + optimizer(params=self.parameters()) if callable(optimizer) else optimizer + for optimizer in ensure_list(self.hparams.optimizer) ] - return [optimizer], lr_scheduler_configs + lr_schedulers = [] + for scheduler_config in ensure_list(self.hparams.scheduler): + scheduler = scheduler_config(optimizers[0]) if callable(scheduler_config) else scheduler_config + lr_scheduler_config = {"scheduler": scheduler} + if hasattr(scheduler, "interval"): + lr_scheduler_config["interval"] = scheduler.interval + if hasattr(scheduler, "monitor"): + lr_scheduler_config["monitor"] = scheduler.monitor + lr_schedulers.append(lr_scheduler_config) + + return optimizers, lr_schedulers def register_load_state_dict_pre_hook(self, model_classes: list[str], ckpt_classes: list[str]) -> None: """Register self.model's load_state_dict_pre_hook. diff --git a/src/otx/core/model/module/classification.py b/src/otx/core/model/module/classification.py index 7505824b48c..fd1f9cf5431 100644 --- a/src/otx/core/model/module/classification.py +++ b/src/otx/core/model/module/classification.py @@ -37,8 +37,8 @@ def __init__( self, otx_model: OTXMulticlassClsModel, torch_compile: bool, - optimizer: OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), - scheduler: LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, + optimizer: list[OptimizerCallable] | OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), + scheduler: list[LRSchedulerCallable] | LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, ): super().__init__( otx_model=otx_model, @@ -130,8 +130,8 @@ def __init__( self, otx_model: OTXMultilabelClsModel, torch_compile: bool, - optimizer: OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), - scheduler: LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, + optimizer: list[OptimizerCallable] | OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), + scheduler: list[LRSchedulerCallable] | LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, ): super().__init__( otx_model=otx_model, @@ -218,8 +218,8 @@ def __init__( self, otx_model: OTXHlabelClsModel, torch_compile: bool, - optimizer: OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), - scheduler: LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, + optimizer: list[OptimizerCallable] | OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), + scheduler: list[LRSchedulerCallable] | LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, ): super().__init__( otx_model=otx_model, diff --git a/src/otx/core/model/module/detection.py b/src/otx/core/model/module/detection.py index 3869a5a798f..f2d9938874a 100644 --- a/src/otx/core/model/module/detection.py +++ b/src/otx/core/model/module/detection.py @@ -29,8 +29,8 @@ def __init__( self, otx_model: ExplainableOTXDetModel, torch_compile: bool, - optimizer: OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), - scheduler: LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, + optimizer: list[OptimizerCallable] | OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), + scheduler: list[LRSchedulerCallable] | LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, ): super().__init__( otx_model=otx_model, diff --git a/src/otx/core/model/module/instance_segmentation.py b/src/otx/core/model/module/instance_segmentation.py index 4d27ece3a4c..40bf4fb4fb3 100644 --- a/src/otx/core/model/module/instance_segmentation.py +++ b/src/otx/core/model/module/instance_segmentation.py @@ -32,8 +32,8 @@ def __init__( self, otx_model: ExplainableOTXInstanceSegModel, torch_compile: bool, - optimizer: OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), - scheduler: LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, + optimizer: list[OptimizerCallable] | OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), + scheduler: list[LRSchedulerCallable] | LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, ): super().__init__( otx_model=otx_model, diff --git a/src/otx/core/model/module/rotated_detection.py b/src/otx/core/model/module/rotated_detection.py index 84275563b2e..12bfd84d5a7 100644 --- a/src/otx/core/model/module/rotated_detection.py +++ b/src/otx/core/model/module/rotated_detection.py @@ -25,8 +25,8 @@ def __init__( self, otx_model: OTXRotatedDetModel, torch_compile: bool, - optimizer: OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), - scheduler: LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, + optimizer: list[OptimizerCallable] | OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), + scheduler: list[LRSchedulerCallable] | LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, ): super().__init__( otx_model=otx_model, diff --git a/src/otx/core/model/module/segmentation.py b/src/otx/core/model/module/segmentation.py index e294a09126f..9fc0c40de26 100644 --- a/src/otx/core/model/module/segmentation.py +++ b/src/otx/core/model/module/segmentation.py @@ -29,8 +29,8 @@ def __init__( self, otx_model: OTXSegmentationModel, torch_compile: bool, - optimizer: OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), - scheduler: LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, + optimizer: list[OptimizerCallable] | OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), + scheduler: list[LRSchedulerCallable] | LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, ): super().__init__( otx_model=otx_model, diff --git a/src/otx/core/model/module/visual_prompting.py b/src/otx/core/model/module/visual_prompting.py index 599f2a06c79..68a62ef8398 100644 --- a/src/otx/core/model/module/visual_prompting.py +++ b/src/otx/core/model/module/visual_prompting.py @@ -36,8 +36,8 @@ def __init__( self, otx_model: OTXVisualPromptingModel, torch_compile: bool, - optimizer: OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), - scheduler: LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, + optimizer: list[OptimizerCallable] | OptimizerCallable = lambda p: torch.optim.SGD(p, lr=0.01), + scheduler: list[LRSchedulerCallable] | LRSchedulerCallable = torch.optim.lr_scheduler.ConstantLR, ): super().__init__( otx_model=otx_model, diff --git a/src/otx/engine/engine.py b/src/otx/engine/engine.py index fffe06a1f23..c965c74744f 100644 --- a/src/otx/engine/engine.py +++ b/src/otx/engine/engine.py @@ -83,8 +83,8 @@ def __init__( work_dir: PathLike = "./otx-workspace", datamodule: OTXDataModule | None = None, model: OTXModel | str | None = None, - optimizer: OptimizerCallable | None = None, - scheduler: LRSchedulerCallable | None = None, + optimizer: list[OptimizerCallable] | OptimizerCallable | None = None, + scheduler: list[LRSchedulerCallable] | LRSchedulerCallable | None = None, checkpoint: PathLike | None = None, device: DeviceType = DeviceType.auto, **kwargs, @@ -132,10 +132,10 @@ def __init__( meta_info=self._datamodule.meta_info if self._datamodule is not None else None, ) ) - self.optimizer: OptimizerCallable | None = ( + self.optimizer: list[OptimizerCallable] | OptimizerCallable | None = ( optimizer if optimizer is not None else self._auto_configurator.get_optimizer() ) - self.scheduler: LRSchedulerCallable | None = ( + self.scheduler: list[LRSchedulerCallable] | LRSchedulerCallable | None = ( scheduler if scheduler is not None else self._auto_configurator.get_scheduler() ) @@ -668,8 +668,8 @@ def datamodule(self) -> OTXDataModule: def _build_lightning_module( self, model: OTXModel, - optimizer: OptimizerCallable, - scheduler: LRSchedulerCallable, + optimizer: list[OptimizerCallable] | OptimizerCallable | None, + scheduler: list[LRSchedulerCallable] | LRSchedulerCallable | None, ) -> OTXLitModule: """Builds a LightningModule for engine workflow. diff --git a/src/otx/engine/utils/auto_configurator.py b/src/otx/engine/utils/auto_configurator.py index 98f7f3506e1..b23185b48a7 100644 --- a/src/otx/engine/utils/auto_configurator.py +++ b/src/otx/engine/utils/auto_configurator.py @@ -249,7 +249,7 @@ def get_model(self, model_name: str | None = None, meta_info: LabelInfo | None = logger.warning(f"Set Default Model: {self.config['model']}") return instantiate_class(args=(), init=self.config["model"]) - def get_optimizer(self) -> OptimizerCallable | None: + def get_optimizer(self) -> list[OptimizerCallable] | OptimizerCallable | None: """Returns the optimizer callable based on the configuration. Returns: @@ -257,9 +257,12 @@ def get_optimizer(self) -> OptimizerCallable | None: """ optimizer_config = self.config.get("optimizer", None) logger.warning(f"Set Default Optimizer: {optimizer_config}") + if isinstance(optimizer_config, list): + optimizers = [partial_instantiate_class(init=_opt) for _opt in optimizer_config] + return [opt for opt in optimizers if opt is not None] return partial_instantiate_class(init=optimizer_config) - def get_scheduler(self) -> LRSchedulerCallable | None: + def get_scheduler(self) -> list[LRSchedulerCallable] | LRSchedulerCallable | None: """Returns the instantiated scheduler based on the configuration. Returns: @@ -267,6 +270,9 @@ def get_scheduler(self) -> LRSchedulerCallable | None: """ scheduler_config = self.config.get("scheduler", None) logger.warning(f"Set Default Scheduler: {scheduler_config}") + if isinstance(scheduler_config, list): + schedulers = [partial_instantiate_class(init=scheduler) for scheduler in scheduler_config] + return [scheduler for scheduler in schedulers if scheduler is not None] return partial_instantiate_class(init=scheduler_config) def get_ov_model(self, model_name: str, meta_info: LabelInfo) -> OVModel: diff --git a/src/otx/recipe/action/action_classification/x3d.yaml b/src/otx/recipe/action/action_classification/x3d.yaml index 98fa0340eae..e43d0b2c1e9 100644 --- a/src/otx/recipe/action/action_classification/x3d.yaml +++ b/src/otx/recipe/action/action_classification/x3d.yaml @@ -10,13 +10,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 100 - mode: max - factor: 0.5 - patience: 2 - monitor: val/accuracy + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 100 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 2 + monitor: val/accuracy engine: task: ACTION_CLASSIFICATION diff --git a/src/otx/recipe/action/action_detection/x3d_fastrcnn.yaml b/src/otx/recipe/action/action_detection/x3d_fastrcnn.yaml index f297429cce6..36c51f4247e 100644 --- a/src/otx/recipe/action/action_detection/x3d_fastrcnn.yaml +++ b/src/otx/recipe/action/action_detection/x3d_fastrcnn.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.00001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 100 - mode: max - factor: 0.5 - patience: 2 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 100 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 2 + monitor: val/map_50 engine: task: ACTION_DETECTION diff --git a/src/otx/recipe/classification/h_label_cls/efficientnet_b0_light.yaml b/src/otx/recipe/classification/h_label_cls/efficientnet_b0_light.yaml index 8876829fac9..cad82caff45 100644 --- a/src/otx/recipe/classification/h_label_cls/efficientnet_b0_light.yaml +++ b/src/otx/recipe/classification/h_label_cls/efficientnet_b0_light.yaml @@ -11,13 +11,15 @@ optimizer: lr: 0.0049 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 0 - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 0 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: H_LABEL_CLS diff --git a/src/otx/recipe/classification/h_label_cls/efficientnet_v2_light.yaml b/src/otx/recipe/classification/h_label_cls/efficientnet_v2_light.yaml index 53a4c4ce426..8cfdb4f566e 100644 --- a/src/otx/recipe/classification/h_label_cls/efficientnet_v2_light.yaml +++ b/src/otx/recipe/classification/h_label_cls/efficientnet_v2_light.yaml @@ -13,13 +13,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 0 - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 0 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: H_LABEL_CLS diff --git a/src/otx/recipe/classification/h_label_cls/mobilenet_v3_large_light.yaml b/src/otx/recipe/classification/h_label_cls/mobilenet_v3_large_light.yaml index 245cbe76be1..12f731da739 100644 --- a/src/otx/recipe/classification/h_label_cls/mobilenet_v3_large_light.yaml +++ b/src/otx/recipe/classification/h_label_cls/mobilenet_v3_large_light.yaml @@ -13,13 +13,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 10 - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 10 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: H_LABEL_CLS diff --git a/src/otx/recipe/classification/h_label_cls/otx_deit_tiny.yaml b/src/otx/recipe/classification/h_label_cls/otx_deit_tiny.yaml index 90a2fda58f6..a6d2e62b6a3 100644 --- a/src/otx/recipe/classification/h_label_cls/otx_deit_tiny.yaml +++ b/src/otx/recipe/classification/h_label_cls/otx_deit_tiny.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.05 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 10 - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 10 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: H_LABEL_CLS diff --git a/src/otx/recipe/classification/multi_class_cls/efficientnet_b0_light.yaml b/src/otx/recipe/classification/multi_class_cls/efficientnet_b0_light.yaml index 3cee731ae98..80cf82522c7 100644 --- a/src/otx/recipe/classification/multi_class_cls/efficientnet_b0_light.yaml +++ b/src/otx/recipe/classification/multi_class_cls/efficientnet_b0_light.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 0 - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 0 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_CLASS_CLS diff --git a/src/otx/recipe/classification/multi_class_cls/efficientnet_v2_light.yaml b/src/otx/recipe/classification/multi_class_cls/efficientnet_v2_light.yaml index 8170ebde48c..737853fe98c 100644 --- a/src/otx/recipe/classification/multi_class_cls/efficientnet_v2_light.yaml +++ b/src/otx/recipe/classification/multi_class_cls/efficientnet_v2_light.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 0 - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 0 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_CLASS_CLS diff --git a/src/otx/recipe/classification/multi_class_cls/mobilenet_v3_large_light.yaml b/src/otx/recipe/classification/multi_class_cls/mobilenet_v3_large_light.yaml index c00fe2536e9..080cc830be7 100644 --- a/src/otx/recipe/classification/multi_class_cls/mobilenet_v3_large_light.yaml +++ b/src/otx/recipe/classification/multi_class_cls/mobilenet_v3_large_light.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 10 - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 10 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_CLASS_CLS diff --git a/src/otx/recipe/classification/multi_class_cls/otx_deit_tiny.yaml b/src/otx/recipe/classification/multi_class_cls/otx_deit_tiny.yaml index 91453e10583..da0c5522854 100644 --- a/src/otx/recipe/classification/multi_class_cls/otx_deit_tiny.yaml +++ b/src/otx/recipe/classification/multi_class_cls/otx_deit_tiny.yaml @@ -10,13 +10,15 @@ optimizer: weight_decay: 0.05 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 10 - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 10 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_CLASS_CLS diff --git a/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_b0.yaml b/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_b0.yaml index 62e21491124..72cf9474656 100644 --- a/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_b0.yaml +++ b/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_b0.yaml @@ -12,12 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: lightning.pytorch.cli.ReduceLROnPlateau - init_args: - mode: min - factor: 0.5 - patience: 1 - monitor: train/loss + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 0 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_CLASS_CLS diff --git a/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_v2.yaml b/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_v2.yaml index f348b84945b..6c77bd352d7 100644 --- a/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_v2.yaml +++ b/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_v2.yaml @@ -12,12 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: lightning.pytorch.cli.ReduceLROnPlateau - init_args: - mode: min - factor: 0.5 - patience: 1 - monitor: train/loss + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 0 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_CLASS_CLS diff --git a/src/otx/recipe/classification/multi_class_cls/otx_mobilenet_v3_large.yaml b/src/otx/recipe/classification/multi_class_cls/otx_mobilenet_v3_large.yaml index 4596010459f..7058f87da0e 100644 --- a/src/otx/recipe/classification/multi_class_cls/otx_mobilenet_v3_large.yaml +++ b/src/otx/recipe/classification/multi_class_cls/otx_mobilenet_v3_large.yaml @@ -12,12 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: lightning.pytorch.cli.ReduceLROnPlateau - init_args: - mode: min - factor: 0.5 - patience: 1 - monitor: train/loss + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 10 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_CLASS_CLS diff --git a/src/otx/recipe/classification/multi_label_cls/efficientnet_b0_light.yaml b/src/otx/recipe/classification/multi_label_cls/efficientnet_b0_light.yaml index d3632d4cad4..4d728b86a43 100644 --- a/src/otx/recipe/classification/multi_label_cls/efficientnet_b0_light.yaml +++ b/src/otx/recipe/classification/multi_label_cls/efficientnet_b0_light.yaml @@ -9,13 +9,15 @@ optimizer: lr: 0.0049 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 0 - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 0 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_LABEL_CLS diff --git a/src/otx/recipe/classification/multi_label_cls/efficientnet_v2_light.yaml b/src/otx/recipe/classification/multi_label_cls/efficientnet_v2_light.yaml index 4e6f625f98b..4bdc086f65b 100644 --- a/src/otx/recipe/classification/multi_label_cls/efficientnet_v2_light.yaml +++ b/src/otx/recipe/classification/multi_label_cls/efficientnet_v2_light.yaml @@ -11,13 +11,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 0 - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 0 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_LABEL_CLS diff --git a/src/otx/recipe/classification/multi_label_cls/mobilenet_v3_large_light.yaml b/src/otx/recipe/classification/multi_label_cls/mobilenet_v3_large_light.yaml index f8468b4fd49..5f9f82ae0f8 100644 --- a/src/otx/recipe/classification/multi_label_cls/mobilenet_v3_large_light.yaml +++ b/src/otx/recipe/classification/multi_label_cls/mobilenet_v3_large_light.yaml @@ -11,13 +11,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 10 - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 10 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_LABEL_CLS diff --git a/src/otx/recipe/classification/multi_label_cls/otx_deit_tiny.yaml b/src/otx/recipe/classification/multi_label_cls/otx_deit_tiny.yaml index 8a38e647ce1..9e66ece0fbf 100644 --- a/src/otx/recipe/classification/multi_label_cls/otx_deit_tiny.yaml +++ b/src/otx/recipe/classification/multi_label_cls/otx_deit_tiny.yaml @@ -10,13 +10,15 @@ optimizer: weight_decay: 0.05 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 10 - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 10 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_LABEL_CLS diff --git a/src/otx/recipe/detection/atss_mobilenetv2.yaml b/src/otx/recipe/detection/atss_mobilenetv2.yaml index c35d5129bda..69d1cd52c7d 100644 --- a/src/otx/recipe/detection/atss_mobilenetv2.yaml +++ b/src/otx/recipe/detection/atss_mobilenetv2.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 3 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 3 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: DETECTION diff --git a/src/otx/recipe/detection/atss_r50_fpn.yaml b/src/otx/recipe/detection/atss_r50_fpn.yaml index 0f005a3b18d..43a20e292f4 100644 --- a/src/otx/recipe/detection/atss_r50_fpn.yaml +++ b/src/otx/recipe/detection/atss_r50_fpn.yaml @@ -10,13 +10,15 @@ optimizer: weight_decay: 0.0 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 3 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 3 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: DETECTION diff --git a/src/otx/recipe/detection/atss_resnext101.yaml b/src/otx/recipe/detection/atss_resnext101.yaml index f46baa1c21f..bb0a7b939f9 100644 --- a/src/otx/recipe/detection/atss_resnext101.yaml +++ b/src/otx/recipe/detection/atss_resnext101.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 3 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 3 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: DETECTION diff --git a/src/otx/recipe/detection/ssd_mobilenetv2.yaml b/src/otx/recipe/detection/ssd_mobilenetv2.yaml index 84350f1e232..09b10bc4eea 100644 --- a/src/otx/recipe/detection/ssd_mobilenetv2.yaml +++ b/src/otx/recipe/detection/ssd_mobilenetv2.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 3 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 3 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: DETECTION diff --git a/src/otx/recipe/detection/yolox_l.yaml b/src/otx/recipe/detection/yolox_l.yaml index 01c83b61e1d..690f7bfd4f4 100644 --- a/src/otx/recipe/detection/yolox_l.yaml +++ b/src/otx/recipe/detection/yolox_l.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 3 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 3 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: DETECTION diff --git a/src/otx/recipe/detection/yolox_l_tile.yaml b/src/otx/recipe/detection/yolox_l_tile.yaml index e49efa21de6..af45f977f3b 100644 --- a/src/otx/recipe/detection/yolox_l_tile.yaml +++ b/src/otx/recipe/detection/yolox_l_tile.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 3 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 3 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: DETECTION diff --git a/src/otx/recipe/detection/yolox_s.yaml b/src/otx/recipe/detection/yolox_s.yaml index c2b5878ad1d..0bf3a268446 100644 --- a/src/otx/recipe/detection/yolox_s.yaml +++ b/src/otx/recipe/detection/yolox_s.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 3 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 3 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: DETECTION diff --git a/src/otx/recipe/detection/yolox_s_tile.yaml b/src/otx/recipe/detection/yolox_s_tile.yaml index 21da346c6b9..5f44cbe8964 100644 --- a/src/otx/recipe/detection/yolox_s_tile.yaml +++ b/src/otx/recipe/detection/yolox_s_tile.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 3 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 3 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: DETECTION diff --git a/src/otx/recipe/detection/yolox_tiny.yaml b/src/otx/recipe/detection/yolox_tiny.yaml index fafc40e6bfc..9997a0022e8 100644 --- a/src/otx/recipe/detection/yolox_tiny.yaml +++ b/src/otx/recipe/detection/yolox_tiny.yaml @@ -11,13 +11,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 3 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 3 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: DETECTION diff --git a/src/otx/recipe/detection/yolox_tiny_tile.yaml b/src/otx/recipe/detection/yolox_tiny_tile.yaml index f3633769e81..54d37914817 100644 --- a/src/otx/recipe/detection/yolox_tiny_tile.yaml +++ b/src/otx/recipe/detection/yolox_tiny_tile.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 3 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 3 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: DETECTION diff --git a/src/otx/recipe/detection/yolox_x.yaml b/src/otx/recipe/detection/yolox_x.yaml index cb3496f9e2a..68162a0164d 100644 --- a/src/otx/recipe/detection/yolox_x.yaml +++ b/src/otx/recipe/detection/yolox_x.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 3 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 3 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: DETECTION diff --git a/src/otx/recipe/detection/yolox_x_tile.yaml b/src/otx/recipe/detection/yolox_x_tile.yaml index d7d23780abf..f5c74413cf8 100644 --- a/src/otx/recipe/detection/yolox_x_tile.yaml +++ b/src/otx/recipe/detection/yolox_x_tile.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.0001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 3 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 3 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: DETECTION diff --git a/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b.yaml b/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b.yaml index 4bf7e0ca358..7ecc713310a 100644 --- a/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b.yaml +++ b/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 100 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 0 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: INSTANCE_SEGMENTATION diff --git a/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b_tile.yaml b/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b_tile.yaml index e4ba52e5a4b..c795668081c 100644 --- a/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b_tile.yaml +++ b/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b_tile.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 100 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 100 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: INSTANCE_SEGMENTATION diff --git a/src/otx/recipe/instance_segmentation/maskrcnn_r50.yaml b/src/otx/recipe/instance_segmentation/maskrcnn_r50.yaml index 1cd08c0f711..2ea4a57884f 100644 --- a/src/otx/recipe/instance_segmentation/maskrcnn_r50.yaml +++ b/src/otx/recipe/instance_segmentation/maskrcnn_r50.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 100 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 100 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: INSTANCE_SEGMENTATION diff --git a/src/otx/recipe/instance_segmentation/maskrcnn_r50_tile.yaml b/src/otx/recipe/instance_segmentation/maskrcnn_r50_tile.yaml index bc4abe0bb8a..398943e1744 100644 --- a/src/otx/recipe/instance_segmentation/maskrcnn_r50_tile.yaml +++ b/src/otx/recipe/instance_segmentation/maskrcnn_r50_tile.yaml @@ -12,13 +12,15 @@ optimizer: weight_decay: 0.001 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 100 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 100 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: INSTANCE_SEGMENTATION diff --git a/src/otx/recipe/instance_segmentation/maskrcnn_swint.yaml b/src/otx/recipe/instance_segmentation/maskrcnn_swint.yaml index 426c043537e..8806f46b905 100644 --- a/src/otx/recipe/instance_segmentation/maskrcnn_swint.yaml +++ b/src/otx/recipe/instance_segmentation/maskrcnn_swint.yaml @@ -10,13 +10,15 @@ optimizer: weight_decay: 0.05 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 100 - mode: max - factor: 0.5 - patience: 5 - monitor: val/map_50 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 100 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/map_50 engine: task: INSTANCE_SEGMENTATION diff --git a/src/otx/recipe/rotated_detection/maskrcnn_efficientnetb2b.yaml b/src/otx/recipe/rotated_detection/maskrcnn_efficientnetb2b.yaml index a04641fefa9..b5f5a9a8cfe 100644 --- a/src/otx/recipe/rotated_detection/maskrcnn_efficientnetb2b.yaml +++ b/src/otx/recipe/rotated_detection/maskrcnn_efficientnetb2b.yaml @@ -12,12 +12,15 @@ optimizer: weight_decay: 0.001 scheduler: - class_path: lightning.pytorch.cli.ReduceLROnPlateau - init_args: - mode: min - factor: 0.1 - patience: 10 - monitor: train/loss + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 100 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.1 + patience: 10 + monitor: val/map_50 engine: task: ROTATED_DETECTION diff --git a/src/otx/recipe/rotated_detection/maskrcnn_r50.yaml b/src/otx/recipe/rotated_detection/maskrcnn_r50.yaml index 7bf948ff143..415e11b66fa 100644 --- a/src/otx/recipe/rotated_detection/maskrcnn_r50.yaml +++ b/src/otx/recipe/rotated_detection/maskrcnn_r50.yaml @@ -12,12 +12,15 @@ optimizer: weight_decay: 0.001 scheduler: - class_path: lightning.pytorch.cli.ReduceLROnPlateau - init_args: - mode: min - factor: 0.1 - patience: 10 - monitor: train/loss + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 100 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.1 + patience: 10 + monitor: val/map_50 engine: task: ROTATED_DETECTION diff --git a/src/otx/recipe/semantic_segmentation/litehrnet_18.yaml b/src/otx/recipe/semantic_segmentation/litehrnet_18.yaml index c9abaca29ab..7b9463aa43b 100644 --- a/src/otx/recipe/semantic_segmentation/litehrnet_18.yaml +++ b/src/otx/recipe/semantic_segmentation/litehrnet_18.yaml @@ -14,13 +14,15 @@ optimizer: weight_decay: 0.0 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 100 - mode: max - factor: 0.5 - patience: 5 - monitor: val/mIoU + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 100 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/mIoU engine: task: SEMANTIC_SEGMENTATION diff --git a/src/otx/recipe/semantic_segmentation/litehrnet_s.yaml b/src/otx/recipe/semantic_segmentation/litehrnet_s.yaml index b87558ef1c8..707acc80e4e 100644 --- a/src/otx/recipe/semantic_segmentation/litehrnet_s.yaml +++ b/src/otx/recipe/semantic_segmentation/litehrnet_s.yaml @@ -14,13 +14,15 @@ optimizer: weight_decay: 0.0 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 100 - mode: max - factor: 0.5 - patience: 5 - monitor: val/mIoU + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 100 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/mIoU engine: task: SEMANTIC_SEGMENTATION diff --git a/src/otx/recipe/semantic_segmentation/litehrnet_x.yaml b/src/otx/recipe/semantic_segmentation/litehrnet_x.yaml index 3110e01d895..f939fde9079 100644 --- a/src/otx/recipe/semantic_segmentation/litehrnet_x.yaml +++ b/src/otx/recipe/semantic_segmentation/litehrnet_x.yaml @@ -14,13 +14,15 @@ optimizer: weight_decay: 0.0 scheduler: - class_path: otx.algo.schedulers.WarmupReduceLROnPlateau - init_args: - warmup_steps: 100 - mode: max - factor: 0.5 - patience: 5 - monitor: val/mIoU + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 100 + - class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 5 + monitor: val/mIoU engine: task: SEMANTIC_SEGMENTATION diff --git a/src/otx/recipe/semantic_segmentation/segnext_b.yaml b/src/otx/recipe/semantic_segmentation/segnext_b.yaml index 2e4b2a92540..dc11fcc4b8a 100644 --- a/src/otx/recipe/semantic_segmentation/segnext_b.yaml +++ b/src/otx/recipe/semantic_segmentation/segnext_b.yaml @@ -14,12 +14,14 @@ optimizer: weight_decay: 0.01 scheduler: - class_path: otx.algo.schedulers.warmup_schedulers.WarmupPolynomialLR - init_args: - warmup_steps: 20 - total_iters: 100 - power: 0.9 - last_epoch: -1 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 20 + - class_path: torch.optim.lr_scheduler.PolynomialLR + init_args: + total_iters: 100 + power: 0.9 + last_epoch: -1 engine: task: SEMANTIC_SEGMENTATION @@ -29,7 +31,7 @@ callback_monitor: val/mIoU data: ../_base_/data/mmseg_base.yaml overrides: - max_epochs: 150 + max_epochs: 170 data: config: train_subset: diff --git a/src/otx/recipe/semantic_segmentation/segnext_s.yaml b/src/otx/recipe/semantic_segmentation/segnext_s.yaml index c03511307c1..d66c14636b2 100644 --- a/src/otx/recipe/semantic_segmentation/segnext_s.yaml +++ b/src/otx/recipe/semantic_segmentation/segnext_s.yaml @@ -14,12 +14,14 @@ optimizer: weight_decay: 0.01 scheduler: - class_path: otx.algo.schedulers.warmup_schedulers.WarmupPolynomialLR - init_args: - warmup_steps: 20 - total_iters: 100 - power: 0.9 - last_epoch: -1 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 20 + - class_path: torch.optim.lr_scheduler.PolynomialLR + init_args: + total_iters: 100 + power: 0.9 + last_epoch: -1 engine: task: SEMANTIC_SEGMENTATION @@ -29,7 +31,7 @@ callback_monitor: val/mIoU data: ../_base_/data/mmseg_base.yaml overrides: - max_epochs: 150 + max_epochs: 170 data: config: train_subset: diff --git a/src/otx/recipe/semantic_segmentation/segnext_t.yaml b/src/otx/recipe/semantic_segmentation/segnext_t.yaml index 901af6c7647..b35e9ec6144 100644 --- a/src/otx/recipe/semantic_segmentation/segnext_t.yaml +++ b/src/otx/recipe/semantic_segmentation/segnext_t.yaml @@ -14,12 +14,14 @@ optimizer: weight_decay: 0.01 scheduler: - class_path: otx.algo.schedulers.warmup_schedulers.WarmupPolynomialLR - init_args: - warmup_steps: 20 - total_iters: 100 - power: 0.9 - last_epoch: -1 + - class_path: otx.core.model.module.base.LinearWarmupScheduler + init_args: + num_warmup_steps: 20 + - class_path: torch.optim.lr_scheduler.PolynomialLR + init_args: + total_iters: 100 + power: 0.9 + last_epoch: -1 engine: task: SEMANTIC_SEGMENTATION @@ -29,7 +31,7 @@ callback_monitor: val/mIoU data: ../_base_/data/mmseg_base.yaml overrides: - max_epochs: 150 + max_epochs: 170 data: config: train_subset: diff --git a/tests/unit/algo/callbacks/test_adaptive_train_scheduling.py b/tests/unit/algo/callbacks/test_adaptive_train_scheduling.py index 0229ea0c2fa..9d019be0f0a 100644 --- a/tests/unit/algo/callbacks/test_adaptive_train_scheduling.py +++ b/tests/unit/algo/callbacks/test_adaptive_train_scheduling.py @@ -32,6 +32,7 @@ def test_callback(self, caplog) -> None: mock_lr_scheduler_config = MagicMock(spec=LRSchedulerConfig) mock_lr_scheduler_config.frequency = 1 + mock_lr_scheduler_config.interval = "epoch" mock_trainer.lr_scheduler_configs = [mock_lr_scheduler_config] with caplog.at_level(log.WARNING): diff --git a/tests/unit/core/model/module/test_base.py b/tests/unit/core/model/module/test_base.py index 7436a53a721..bf9961da165 100644 --- a/tests/unit/core/model/module/test_base.py +++ b/tests/unit/core/model/module/test_base.py @@ -8,8 +8,8 @@ from unittest.mock import MagicMock, create_autospec import pytest +from lightning.pytorch.cli import ReduceLROnPlateau from lightning.pytorch.trainer import Trainer -from otx.algo.schedulers.warmup_schedulers import WarmupReduceLROnPlateau from otx.core.model.entity.base import OTXModel from otx.core.model.module.base import LinearWarmupScheduler, OTXLitModule from torch.optim import Optimizer @@ -33,14 +33,19 @@ def optimizer_factory(*args, **kargs) -> Optimizer: # noqa: ARG001 return optimizer_factory @pytest.fixture() - def mock_scheduler(self) -> WarmupReduceLROnPlateau: - scheduler = MagicMock(spec=WarmupReduceLROnPlateau) - scheduler.warmup_steps = 10 + def mock_scheduler(self) -> list[LinearWarmupScheduler | ReduceLROnPlateau]: + scheduler_object_1 = MagicMock() + warmup_scheduler = MagicMock(spec=LinearWarmupScheduler) + warmup_scheduler.num_warmup_steps = 10 + warmup_scheduler.interval = "step" + scheduler_object_1.return_value = warmup_scheduler - def scheduler_factory(*args, **kargs) -> WarmupReduceLROnPlateau: # noqa: ARG001 - return scheduler + scheduler_object_2 = MagicMock() + lr_scheduler = MagicMock(spec=ReduceLROnPlateau) + lr_scheduler.monitor = "val/loss" + scheduler_object_2.return_value = lr_scheduler - return scheduler_factory + return [scheduler_object_1, scheduler_object_2] def test_configure_optimizers(self, mock_otx_model, mock_optimizer, mock_scheduler) -> None: module = OTXLitModule( @@ -61,7 +66,3 @@ def test_configure_optimizers(self, mock_otx_model, mock_optimizer, mock_schedul assert "scheduler" in lr_schedulers[1] assert "monitor" in lr_schedulers[1] - assert "interval" in lr_schedulers[1] - assert "frequency" in lr_schedulers[1] - - assert lr_schedulers[1]["frequency"] == 2 diff --git a/tests/unit/engine/utils/test_auto_configurator.py b/tests/unit/engine/utils/test_auto_configurator.py index aa65edf0a80..0abe3a77207 100644 --- a/tests/unit/engine/utils/test_auto_configurator.py +++ b/tests/unit/engine/utils/test_auto_configurator.py @@ -124,9 +124,19 @@ def test_get_model(self) -> None: def test_get_optimizer(self) -> None: task = OTXTaskType.SEMANTIC_SEGMENTATION auto_configurator = AutoConfigurator(task=task) - assert callable(auto_configurator.get_optimizer()) + optimizer = auto_configurator.get_optimizer() + if isinstance(optimizer, list): + for opt in optimizer: + assert callable(opt) + else: + assert callable(optimizer) def test_get_scheduler(self) -> None: task = OTXTaskType.INSTANCE_SEGMENTATION auto_configurator = AutoConfigurator(task=task) - assert callable(auto_configurator.get_scheduler()) + scheduler = auto_configurator.get_scheduler() + if isinstance(scheduler, list): + for sch in scheduler: + assert callable(sch) + else: + assert callable(scheduler) From afe88834cf31995d984709727f8f8fd381ebb1f7 Mon Sep 17 00:00:00 2001 From: "Kang, Harim" Date: Tue, 13 Feb 2024 14:48:05 +0900 Subject: [PATCH 03/10] Remove warmup 0 iter settings --- src/otx/core/model/module/base.py | 2 +- .../h_label_cls/efficientnet_b0_light.yaml | 15 ++++++--------- .../h_label_cls/efficientnet_v2_light.yaml | 15 ++++++--------- .../multi_class_cls/efficientnet_b0_light.yaml | 15 ++++++--------- .../multi_class_cls/efficientnet_v2_light.yaml | 15 ++++++--------- .../multi_class_cls/otx_efficientnet_b0.yaml | 15 ++++++--------- .../multi_class_cls/otx_efficientnet_v2.yaml | 15 ++++++--------- .../multi_label_cls/efficientnet_b0_light.yaml | 15 ++++++--------- .../multi_label_cls/efficientnet_v2_light.yaml | 15 ++++++--------- .../maskrcnn_efficientnetb2b.yaml | 2 +- 10 files changed, 50 insertions(+), 74 deletions(-) diff --git a/src/otx/core/model/module/base.py b/src/otx/core/model/module/base.py index 2c4a041a7f3..f2c782fd30f 100644 --- a/src/otx/core/model/module/base.py +++ b/src/otx/core/model/module/base.py @@ -37,7 +37,7 @@ def __init__( ): if num_warmup_steps > 0: msg = f"num_warmup_steps should be > 0, got {num_warmup_steps}" - ValueError(msg) + raise ValueError(msg) self.num_warmup_steps = num_warmup_steps self.interval = interval super().__init__(optimizer, lambda step: min(step / num_warmup_steps, 1.0)) diff --git a/src/otx/recipe/classification/h_label_cls/efficientnet_b0_light.yaml b/src/otx/recipe/classification/h_label_cls/efficientnet_b0_light.yaml index cad82caff45..a6b696b1497 100644 --- a/src/otx/recipe/classification/h_label_cls/efficientnet_b0_light.yaml +++ b/src/otx/recipe/classification/h_label_cls/efficientnet_b0_light.yaml @@ -11,15 +11,12 @@ optimizer: lr: 0.0049 scheduler: - - class_path: otx.core.model.module.base.LinearWarmupScheduler - init_args: - num_warmup_steps: 0 - - class_path: lightning.pytorch.cli.ReduceLROnPlateau - init_args: - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: H_LABEL_CLS diff --git a/src/otx/recipe/classification/h_label_cls/efficientnet_v2_light.yaml b/src/otx/recipe/classification/h_label_cls/efficientnet_v2_light.yaml index 8cfdb4f566e..9a12f9005e9 100644 --- a/src/otx/recipe/classification/h_label_cls/efficientnet_v2_light.yaml +++ b/src/otx/recipe/classification/h_label_cls/efficientnet_v2_light.yaml @@ -13,15 +13,12 @@ optimizer: weight_decay: 0.0001 scheduler: - - class_path: otx.core.model.module.base.LinearWarmupScheduler - init_args: - num_warmup_steps: 0 - - class_path: lightning.pytorch.cli.ReduceLROnPlateau - init_args: - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: H_LABEL_CLS diff --git a/src/otx/recipe/classification/multi_class_cls/efficientnet_b0_light.yaml b/src/otx/recipe/classification/multi_class_cls/efficientnet_b0_light.yaml index 80cf82522c7..7c7511b134b 100644 --- a/src/otx/recipe/classification/multi_class_cls/efficientnet_b0_light.yaml +++ b/src/otx/recipe/classification/multi_class_cls/efficientnet_b0_light.yaml @@ -12,15 +12,12 @@ optimizer: weight_decay: 0.0001 scheduler: - - class_path: otx.core.model.module.base.LinearWarmupScheduler - init_args: - num_warmup_steps: 0 - - class_path: lightning.pytorch.cli.ReduceLROnPlateau - init_args: - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_CLASS_CLS diff --git a/src/otx/recipe/classification/multi_class_cls/efficientnet_v2_light.yaml b/src/otx/recipe/classification/multi_class_cls/efficientnet_v2_light.yaml index 737853fe98c..c4402ac4810 100644 --- a/src/otx/recipe/classification/multi_class_cls/efficientnet_v2_light.yaml +++ b/src/otx/recipe/classification/multi_class_cls/efficientnet_v2_light.yaml @@ -12,15 +12,12 @@ optimizer: weight_decay: 0.0001 scheduler: - - class_path: otx.core.model.module.base.LinearWarmupScheduler - init_args: - num_warmup_steps: 0 - - class_path: lightning.pytorch.cli.ReduceLROnPlateau - init_args: - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_CLASS_CLS diff --git a/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_b0.yaml b/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_b0.yaml index 72cf9474656..678cf451556 100644 --- a/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_b0.yaml +++ b/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_b0.yaml @@ -12,15 +12,12 @@ optimizer: weight_decay: 0.0001 scheduler: - - class_path: otx.core.model.module.base.LinearWarmupScheduler - init_args: - num_warmup_steps: 0 - - class_path: lightning.pytorch.cli.ReduceLROnPlateau - init_args: - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_CLASS_CLS diff --git a/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_v2.yaml b/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_v2.yaml index 6c77bd352d7..e0a2db7f69b 100644 --- a/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_v2.yaml +++ b/src/otx/recipe/classification/multi_class_cls/otx_efficientnet_v2.yaml @@ -12,15 +12,12 @@ optimizer: weight_decay: 0.0001 scheduler: - - class_path: otx.core.model.module.base.LinearWarmupScheduler - init_args: - num_warmup_steps: 0 - - class_path: lightning.pytorch.cli.ReduceLROnPlateau - init_args: - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_CLASS_CLS diff --git a/src/otx/recipe/classification/multi_label_cls/efficientnet_b0_light.yaml b/src/otx/recipe/classification/multi_label_cls/efficientnet_b0_light.yaml index 4d728b86a43..e904e4bfe12 100644 --- a/src/otx/recipe/classification/multi_label_cls/efficientnet_b0_light.yaml +++ b/src/otx/recipe/classification/multi_label_cls/efficientnet_b0_light.yaml @@ -9,15 +9,12 @@ optimizer: lr: 0.0049 scheduler: - - class_path: otx.core.model.module.base.LinearWarmupScheduler - init_args: - num_warmup_steps: 0 - - class_path: lightning.pytorch.cli.ReduceLROnPlateau - init_args: - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_LABEL_CLS diff --git a/src/otx/recipe/classification/multi_label_cls/efficientnet_v2_light.yaml b/src/otx/recipe/classification/multi_label_cls/efficientnet_v2_light.yaml index 4bdc086f65b..ab0c328d6b2 100644 --- a/src/otx/recipe/classification/multi_label_cls/efficientnet_v2_light.yaml +++ b/src/otx/recipe/classification/multi_label_cls/efficientnet_v2_light.yaml @@ -11,15 +11,12 @@ optimizer: weight_decay: 0.0001 scheduler: - - class_path: otx.core.model.module.base.LinearWarmupScheduler - init_args: - num_warmup_steps: 0 - - class_path: lightning.pytorch.cli.ReduceLROnPlateau - init_args: - mode: max - factor: 0.5 - patience: 1 - monitor: val/accuracy + class_path: lightning.pytorch.cli.ReduceLROnPlateau + init_args: + mode: max + factor: 0.5 + patience: 1 + monitor: val/accuracy engine: task: MULTI_LABEL_CLS diff --git a/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b.yaml b/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b.yaml index 7ecc713310a..bdba41b089f 100644 --- a/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b.yaml +++ b/src/otx/recipe/instance_segmentation/maskrcnn_efficientnetb2b.yaml @@ -14,7 +14,7 @@ optimizer: scheduler: - class_path: otx.core.model.module.base.LinearWarmupScheduler init_args: - num_warmup_steps: 0 + num_warmup_steps: 100 - class_path: lightning.pytorch.cli.ReduceLROnPlateau init_args: mode: max From e2404b0a26ab0211d6853dae5ea63497a55e8ba1 Mon Sep 17 00:00:00 2001 From: "Kang, Harim" Date: Tue, 13 Feb 2024 15:00:18 +0900 Subject: [PATCH 04/10] Fix partial_instantiate_function --- src/otx/cli/cli.py | 4 ++-- src/otx/core/utils/instantiators.py | 23 ++++++++++++++--------- src/otx/engine/utils/auto_configurator.py | 14 ++++---------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/otx/cli/cli.py b/src/otx/cli/cli.py index 1d7850d9b21..382677f0759 100644 --- a/src/otx/cli/cli.py +++ b/src/otx/cli/cli.py @@ -347,11 +347,11 @@ def instantiate_model(self, model_config: Namespace) -> tuple: optimizer_kwargs = self.get_config_value(self.config_init, "optimizer", Namespace()) optimizer_kwargs = optimizer_kwargs if isinstance(optimizer_kwargs, list) else [optimizer_kwargs] - optimizers = [partial_instantiate_class(namespace_to_dict(_opt)) for _opt in optimizer_kwargs] + optimizers = partial_instantiate_class([namespace_to_dict(_opt) for _opt in optimizer_kwargs]) scheduler_kwargs = self.get_config_value(self.config_init, "scheduler", Namespace()) scheduler_kwargs = scheduler_kwargs if isinstance(scheduler_kwargs, list) else [scheduler_kwargs] - schedulers = [partial_instantiate_class(namespace_to_dict(_sch)) for _sch in scheduler_kwargs] + schedulers = partial_instantiate_class([namespace_to_dict(_sch) for _sch in scheduler_kwargs]) return model, optimizers, schedulers diff --git a/src/otx/core/utils/instantiators.py b/src/otx/core/utils/instantiators.py index b19f0105cea..5ca301b1163 100644 --- a/src/otx/core/utils/instantiators.py +++ b/src/otx/core/utils/instantiators.py @@ -66,24 +66,29 @@ def instantiate_loggers(logger_cfg: list | None) -> list[Logger]: return logger -def partial_instantiate_class(init: dict | None) -> partial | None: +def partial_instantiate_class(init: list | dict | None) -> list[partial] | None: """Partially instantiates a class with the given initialization arguments. Copy from lightning.pytorch.cli.instantiate_class and modify it to use partial. Args: - init (dict): A dictionary containing the initialization arguments. - It should have the following keys: + init (list | dict | None): A dictionary containing the initialization arguments. + It should have the following each keys: - "init_args" (dict): A dictionary of keyword arguments to be passed to the class constructor. - "class_path" (str): The fully qualified path of the class to be instantiated. Returns: - partial: A partial object representing the partially instantiated class. + list[partial] | None: A partial object representing the partially instantiated class. """ if not init: return None - kwargs = init.get("init_args", {}) - class_module, class_name = init["class_path"].rsplit(".", 1) - module = __import__(class_module, fromlist=[class_name]) - args_class = getattr(module, class_name) - return partial(args_class, **kwargs) + if not isinstance(init, list): + init = [init] + items: list[partial] = [] + for item in init: + kwargs = item.get("init_args", {}) + class_module, class_name = item["class_path"].rsplit(".", 1) + module = __import__(class_module, fromlist=[class_name]) + args_class = getattr(module, class_name) + items.append(partial(args_class, **kwargs)) + return items diff --git a/src/otx/engine/utils/auto_configurator.py b/src/otx/engine/utils/auto_configurator.py index b23185b48a7..edeceb9ce50 100644 --- a/src/otx/engine/utils/auto_configurator.py +++ b/src/otx/engine/utils/auto_configurator.py @@ -249,30 +249,24 @@ def get_model(self, model_name: str | None = None, meta_info: LabelInfo | None = logger.warning(f"Set Default Model: {self.config['model']}") return instantiate_class(args=(), init=self.config["model"]) - def get_optimizer(self) -> list[OptimizerCallable] | OptimizerCallable | None: + def get_optimizer(self) -> list[OptimizerCallable] | None: """Returns the optimizer callable based on the configuration. Returns: - OptimizerCallable | None: The optimizer callable. + list[OptimizerCallable] | None: The optimizer callable. """ optimizer_config = self.config.get("optimizer", None) logger.warning(f"Set Default Optimizer: {optimizer_config}") - if isinstance(optimizer_config, list): - optimizers = [partial_instantiate_class(init=_opt) for _opt in optimizer_config] - return [opt for opt in optimizers if opt is not None] return partial_instantiate_class(init=optimizer_config) - def get_scheduler(self) -> list[LRSchedulerCallable] | LRSchedulerCallable | None: + def get_scheduler(self) -> list[LRSchedulerCallable] | None: """Returns the instantiated scheduler based on the configuration. Returns: - LRSchedulerCallable | None: The instantiated scheduler. + list[LRSchedulerCallable] | None: The instantiated scheduler. """ scheduler_config = self.config.get("scheduler", None) logger.warning(f"Set Default Scheduler: {scheduler_config}") - if isinstance(scheduler_config, list): - schedulers = [partial_instantiate_class(init=scheduler) for scheduler in scheduler_config] - return [scheduler for scheduler in schedulers if scheduler is not None] return partial_instantiate_class(init=scheduler_config) def get_ov_model(self, model_name: str, meta_info: LabelInfo) -> OVModel: From ac3676b890c72cdc2998a7233a1e3315922696bd Mon Sep 17 00:00:00 2001 From: "Kang, Harim" Date: Tue, 13 Feb 2024 15:09:58 +0900 Subject: [PATCH 05/10] Fix minor issue --- src/otx/core/model/module/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/otx/core/model/module/base.py b/src/otx/core/model/module/base.py index f2c782fd30f..8dd4f0e5618 100644 --- a/src/otx/core/model/module/base.py +++ b/src/otx/core/model/module/base.py @@ -35,7 +35,7 @@ def __init__( num_warmup_steps: int = 1000, interval: str = "step", ): - if num_warmup_steps > 0: + if not num_warmup_steps > 0: msg = f"num_warmup_steps should be > 0, got {num_warmup_steps}" raise ValueError(msg) self.num_warmup_steps = num_warmup_steps From 10e68be5f292ae24edb5ebf7406f22d868caba34 Mon Sep 17 00:00:00 2001 From: "Kang, Harim" Date: Tue, 13 Feb 2024 15:26:52 +0900 Subject: [PATCH 06/10] Fix for other python version --- src/otx/cli/cli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/otx/cli/cli.py b/src/otx/cli/cli.py index 382677f0759..5d15cf13999 100644 --- a/src/otx/cli/cli.py +++ b/src/otx/cli/cli.py @@ -8,7 +8,7 @@ import sys from pathlib import Path -from typing import TYPE_CHECKING, Any, Optional +from typing import TYPE_CHECKING, Any, Optional, Union from warnings import warn import yaml @@ -167,7 +167,7 @@ def engine_subcommand_parser(**kwargs) -> ArgumentParser: nested_key="optimizer", **optim_kwargs, ) - scheduler_type = (LRScheduler, ReduceLROnPlateau, list[LRScheduler | ReduceLROnPlateau]) + scheduler_type = (LRScheduler, ReduceLROnPlateau, list[Union[LRScheduler, ReduceLROnPlateau]]) parser.add_subclass_arguments( baseclass=scheduler_type, nested_key="scheduler", From 264434be71c722660a078ae9a6ee1a6edbaeecc1 Mon Sep 17 00:00:00 2001 From: "Kang, Harim" Date: Tue, 13 Feb 2024 15:32:16 +0900 Subject: [PATCH 07/10] Fix minor empty issue --- src/otx/cli/cli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/otx/cli/cli.py b/src/otx/cli/cli.py index 5d15cf13999..f4baefb4d1f 100644 --- a/src/otx/cli/cli.py +++ b/src/otx/cli/cli.py @@ -347,11 +347,11 @@ def instantiate_model(self, model_config: Namespace) -> tuple: optimizer_kwargs = self.get_config_value(self.config_init, "optimizer", Namespace()) optimizer_kwargs = optimizer_kwargs if isinstance(optimizer_kwargs, list) else [optimizer_kwargs] - optimizers = partial_instantiate_class([namespace_to_dict(_opt) for _opt in optimizer_kwargs]) + optimizers = partial_instantiate_class([namespace_to_dict(_opt) for _opt in optimizer_kwargs if _opt]) scheduler_kwargs = self.get_config_value(self.config_init, "scheduler", Namespace()) scheduler_kwargs = scheduler_kwargs if isinstance(scheduler_kwargs, list) else [scheduler_kwargs] - schedulers = partial_instantiate_class([namespace_to_dict(_sch) for _sch in scheduler_kwargs]) + schedulers = partial_instantiate_class([namespace_to_dict(_sch) for _sch in scheduler_kwargs if _sch]) return model, optimizers, schedulers From d908650761b591b8b08615e694a5f81f85550f31 Mon Sep 17 00:00:00 2001 From: "Kang, Harim" Date: Tue, 13 Feb 2024 15:39:21 +0900 Subject: [PATCH 08/10] Fix docstring in Engine --- src/otx/engine/engine.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/otx/engine/engine.py b/src/otx/engine/engine.py index c965c74744f..ccea5845a7c 100644 --- a/src/otx/engine/engine.py +++ b/src/otx/engine/engine.py @@ -97,9 +97,10 @@ def __init__( work_dir (PathLike, optional): Working directory for the engine. Defaults to "./otx-workspace". datamodule (OTXDataModule | None, optional): The data module for the engine. Defaults to None. model (OTXModel | str | None, optional): The model for the engine. Defaults to None. - optimizer (OptimizerCallable | None, optional): The optimizer for the engine. Defaults to None. - scheduler (LRSchedulerCallable | None, optional): The learning rate scheduler for the engine. + optimizer (list[OptimizerCallable] | OptimizerCallable | None, optional): The optimizer for the engine. Defaults to None. + scheduler (list[LRSchedulerCallable] | LRSchedulerCallable | None, optional): + The learning rate scheduler for the engine. Defaults to None. checkpoint (PathLike | None, optional): Path to the checkpoint file. Defaults to None. device (DeviceType, optional): The device type to use. Defaults to DeviceType.auto. **kwargs: Additional keyword arguments for pl.Trainer. @@ -675,8 +676,8 @@ def _build_lightning_module( Args: model (OTXModel): The OTXModel instance. - optimizer (OptimizerCallable): The optimizer callable. - scheduler (LRSchedulerCallable): The learning rate scheduler callable. + optimizer (list[OptimizerCallable] | OptimizerCallable | None): The optimizer callable. + scheduler (list[LRSchedulerCallable] | LRSchedulerCallable | None): The learning rate scheduler callable. Returns: OTXLitModule: The built LightningModule instance. From 771e9cfa5a0e4a21ac6713c00e6d7795b9d6c147 Mon Sep 17 00:00:00 2001 From: "Kang, Harim" Date: Tue, 13 Feb 2024 16:29:40 +0900 Subject: [PATCH 09/10] Fix CLI type --- src/otx/cli/cli.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/otx/cli/cli.py b/src/otx/cli/cli.py index f4baefb4d1f..764e84794a8 100644 --- a/src/otx/cli/cli.py +++ b/src/otx/cli/cli.py @@ -8,7 +8,7 @@ import sys from pathlib import Path -from typing import TYPE_CHECKING, Any, Optional, Union +from typing import TYPE_CHECKING, Any, Optional from warnings import warn import yaml @@ -163,13 +163,12 @@ def engine_subcommand_parser(**kwargs) -> ArgumentParser: optim_kwargs = {"instantiate": False, "fail_untyped": False, "skip": {"params"}} scheduler_kwargs = {"instantiate": False, "fail_untyped": False, "skip": {"optimizer"}} parser.add_subclass_arguments( - baseclass=(Optimizer, list[Optimizer]), + baseclass=(Optimizer, list), nested_key="optimizer", **optim_kwargs, ) - scheduler_type = (LRScheduler, ReduceLROnPlateau, list[Union[LRScheduler, ReduceLROnPlateau]]) parser.add_subclass_arguments( - baseclass=scheduler_type, + baseclass=(LRScheduler, ReduceLROnPlateau, list), nested_key="scheduler", **scheduler_kwargs, ) @@ -345,13 +344,13 @@ def instantiate_model(self, model_config: Namespace) -> tuple: from otx.core.utils.instantiators import partial_instantiate_class - optimizer_kwargs = self.get_config_value(self.config_init, "optimizer", Namespace()) + optimizer_kwargs = self.get_config_value(self.config_init, "optimizer", {}) optimizer_kwargs = optimizer_kwargs if isinstance(optimizer_kwargs, list) else [optimizer_kwargs] - optimizers = partial_instantiate_class([namespace_to_dict(_opt) for _opt in optimizer_kwargs if _opt]) + optimizers = partial_instantiate_class([_opt for _opt in optimizer_kwargs if _opt]) - scheduler_kwargs = self.get_config_value(self.config_init, "scheduler", Namespace()) + scheduler_kwargs = self.get_config_value(self.config_init, "scheduler", {}) scheduler_kwargs = scheduler_kwargs if isinstance(scheduler_kwargs, list) else [scheduler_kwargs] - schedulers = partial_instantiate_class([namespace_to_dict(_sch) for _sch in scheduler_kwargs if _sch]) + schedulers = partial_instantiate_class([_sch for _sch in scheduler_kwargs if _sch]) return model, optimizers, schedulers @@ -365,8 +364,10 @@ def get_config_value(self, config: Namespace, key: str, default: Any = None) -> Returns: Any: The value of the configuration key, or the default value if the key is not found. + if the value is a Namespace, it is converted to a dictionary. """ - return config.get(str(self.subcommand), config).get(key, default) + result = config.get(str(self.subcommand), config).get(key, default) + return namespace_to_dict(result) if isinstance(result, Namespace) else result def get_subcommand_parser(self, subcommand: str | None) -> ArgumentParser: """Returns the argument parser for the specified subcommand. From 30d16828769350bec811523c8b20967fb44ed14e Mon Sep 17 00:00:00 2001 From: Harim Kang Date: Tue, 13 Feb 2024 17:25:29 +0900 Subject: [PATCH 10/10] Fix configs.callbacks is None --- src/otx/cli/utils/jsonargparse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/otx/cli/utils/jsonargparse.py b/src/otx/cli/utils/jsonargparse.py index d16a1a238c6..8ea735e9d07 100644 --- a/src/otx/cli/utils/jsonargparse.py +++ b/src/otx/cli/utils/jsonargparse.py @@ -178,7 +178,7 @@ def list_override(configs: Namespace, key: str, overrides: list) -> None: ... ... ... ] """ - if key not in configs: + if key not in configs or configs[key] is None: return for target in overrides: class_path = target.get("class_path", None)