diff --git a/src/otx/algorithms/common/configs/training_base.py b/src/otx/algorithms/common/configs/training_base.py index 20453acf72e..59d9084861a 100644 --- a/src/otx/algorithms/common/configs/training_base.py +++ b/src/otx/algorithms/common/configs/training_base.py @@ -409,7 +409,8 @@ class BaseTilingParameters(ParameterGroup): tile_max_number = configurable_integer( header="Max object per image", - description="Max object per image", + description="Maximum number of objects per tile. If set to 1500, the tile adaptor " + "will automatically determine the value. Otherwise, the manually set value will be used.", default_value=1500, min_value=1, max_value=5000, diff --git a/src/otx/algorithms/detection/configs/base/data/tiling/atss_tile_pipeline.py b/src/otx/algorithms/detection/configs/base/data/tiling/atss_tile_pipeline.py index 3a475dd45f0..1eac20921c4 100644 --- a/src/otx/algorithms/detection/configs/base/data/tiling/atss_tile_pipeline.py +++ b/src/otx/algorithms/detection/configs/base/data/tiling/atss_tile_pipeline.py @@ -14,15 +14,9 @@ img_norm_cfg = dict(mean=[0, 0, 0], std=[255, 255, 255], to_rgb=True) train_pipeline = [ - dict(type="MinIoURandomCrop", min_ious=(0.1, 0.3, 0.5, 0.7, 0.9), min_crop_size=0.3), - dict( - type="Resize", - img_scale=[(992, 736), (896, 736), (1088, 736), (992, 672), (992, 800)], - multiscale_mode="value", - keep_ratio=False, - ), - dict(type="RandomFlip", flip_ratio=0.5), + dict(type="Resize", img_scale=img_size, keep_ratio=False), dict(type="Normalize", **img_norm_cfg), + dict(type="RandomFlip", flip_ratio=0.5), dict(type="DefaultFormatBundle"), dict( type="Collect", diff --git a/src/otx/algorithms/detection/configs/base/data/tiling/yolox_tile_pipeline.py b/src/otx/algorithms/detection/configs/base/data/tiling/yolox_tile_pipeline.py index cfc768581f6..fb04edca91a 100644 --- a/src/otx/algorithms/detection/configs/base/data/tiling/yolox_tile_pipeline.py +++ b/src/otx/algorithms/detection/configs/base/data/tiling/yolox_tile_pipeline.py @@ -16,12 +16,6 @@ img_norm_cfg = dict(mean=[0.0, 0.0, 0.0], std=[1.0, 1.0, 1.0], to_rgb=False) train_pipeline = [ - dict( - type="RandomAffine", - scaling_ratio_range=(0.1, 2), - border=(-img_scale[0] // 2, -img_scale[1] // 2), - ), - dict(type="YOLOXHSVRandomAug"), dict(type="RandomFlip", flip_ratio=0.5), dict(type="Resize", img_scale=img_scale, keep_ratio=True), dict(type="Pad", pad_to_square=True, pad_val=dict(img=(114.0, 114.0, 114.0))), diff --git a/src/otx/algorithms/detection/configs/detection/configuration.yaml b/src/otx/algorithms/detection/configs/detection/configuration.yaml index 0be3ff8c8c3..8ecc77099c9 100644 --- a/src/otx/algorithms/detection/configs/detection/configuration.yaml +++ b/src/otx/algorithms/detection/configs/detection/configuration.yaml @@ -645,7 +645,7 @@ tiling_parameters: tile_max_number: header: Max object per tile - description: Maximum number of objects per tile + description: Maximum number of objects per tile. If set to 1500, the tile adaptor will automatically determine the value. Otherwise, the manually set value will be used. affects_outcome_of: TRAINING default_value: 1500 min_value: 1 diff --git a/src/otx/algorithms/detection/configs/detection/cspdarknet_yolox_tiny/tile_pipeline.py b/src/otx/algorithms/detection/configs/detection/cspdarknet_yolox_tiny/tile_pipeline.py index 1db558bbc60..3e25395c5ef 100644 --- a/src/otx/algorithms/detection/configs/detection/cspdarknet_yolox_tiny/tile_pipeline.py +++ b/src/otx/algorithms/detection/configs/detection/cspdarknet_yolox_tiny/tile_pipeline.py @@ -29,7 +29,6 @@ img_norm_cfg = dict(mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) train_pipeline = [ - dict(type="RandomAffine", scaling_ratio_range=(0.5, 1.5), border=(-img_scale[0] // 2, -img_scale[1] // 2)), dict( type="PhotoMetricDistortion", brightness_delta=32, @@ -62,12 +61,12 @@ test_pipeline = [ dict( type="MultiScaleFlipAug", - img_scale=(416, 416), + img_scale=img_scale, flip=False, transforms=[ dict(type="Resize", keep_ratio=False), dict(type="RandomFlip"), - dict(type="Pad", size=(416, 416), pad_val=114.0), + dict(type="Pad", size=img_scale, pad_val=114.0), dict(type="Normalize", **img_norm_cfg), dict(type="ImageToTensor", keys=["img"]), dict(type="Collect", keys=["img"]), diff --git a/src/otx/algorithms/detection/configs/instance_segmentation/configuration.yaml b/src/otx/algorithms/detection/configs/instance_segmentation/configuration.yaml index 2e562a74cfd..8e13c2a2084 100644 --- a/src/otx/algorithms/detection/configs/instance_segmentation/configuration.yaml +++ b/src/otx/algorithms/detection/configs/instance_segmentation/configuration.yaml @@ -646,7 +646,7 @@ tiling_parameters: tile_max_number: header: Max object per tile - description: Maximum number of objects per tile + description: Maximum number of objects per tile. If set to 1500, the tile adaptor will automatically determine the value. Otherwise, the manually set value will be used. affects_outcome_of: TRAINING default_value: 1500 min_value: 1 diff --git a/src/otx/algorithms/detection/configs/rotated_detection/configuration.yaml b/src/otx/algorithms/detection/configs/rotated_detection/configuration.yaml index c3884f97f6d..fb9b25325e0 100644 --- a/src/otx/algorithms/detection/configs/rotated_detection/configuration.yaml +++ b/src/otx/algorithms/detection/configs/rotated_detection/configuration.yaml @@ -631,7 +631,7 @@ tiling_parameters: tile_max_number: header: Max object per tile - description: Maximum number of objects per tile + description: Maximum number of objects per tile. If set to 1500, the tile adaptor will automatically determine the value. Otherwise, the manually set value will be used. affects_outcome_of: TRAINING default_value: 1500 min_value: 1 diff --git a/src/otx/algorithms/detection/utils/data.py b/src/otx/algorithms/detection/utils/data.py index 3dcd7a741af..69469f616ed 100644 --- a/src/otx/algorithms/detection/utils/data.py +++ b/src/otx/algorithms/detection/utils/data.py @@ -490,5 +490,12 @@ def adaptive_tile_params( ) tiling_parameters.tile_size = tile_size - tiling_parameters.tile_max_number = max_num_objects tiling_parameters.tile_overlap = tile_overlap + + if tiling_parameters.tile_max_number == 1500: + logger.info( + f"----> tile max number is set to default (1500), replace with adaptive max_num_objects: {max_num_objects}" + ) + tiling_parameters.tile_max_number = max_num_objects + else: + logger.info(f"----> tile max number is manually set to: {tiling_parameters.tile_max_number}") diff --git a/tests/unit/algorithms/detection/tiling/test_tiling_detection.py b/tests/unit/algorithms/detection/tiling/test_tiling_detection.py index d9c251d0c1b..c49e0ad0738 100644 --- a/tests/unit/algorithms/detection/tiling/test_tiling_detection.py +++ b/tests/unit/algorithms/detection/tiling/test_tiling_detection.py @@ -432,12 +432,15 @@ def test_max_annotation(self, max_annotation=200): assert len(data["gt_masks"].data[0][0]) <= max_annotation @e2e_pytest_unit - def test_adaptive_tile_parameters(self): + @pytest.mark.parametrize("max_num_img", [100, 300, 1500, 1501]) + def test_adaptive_tile_parameters(self, max_num_img): model_template = parse_model_template(os.path.join(DEFAULT_ISEG_TEMPLATE_DIR, "template.yaml")) hp = create(model_template.hyper_parameters.data) default_tile_size = hp.tiling_parameters.tile_size default_tile_overlap = hp.tiling_parameters.tile_overlap + # manually set tile max number + hp.tiling_parameters.tile_max_number = max_num_img default_tile_max_number = hp.tiling_parameters.tile_max_number adaptive_tile_params(hp.tiling_parameters, self.otx_dataset) @@ -448,5 +451,9 @@ def test_adaptive_tile_parameters(self): # check tile overlap is changed assert hp.tiling_parameters.tile_overlap != default_tile_overlap - # check max output prediction size is changed - assert hp.tiling_parameters.tile_max_number != default_tile_max_number + if default_tile_max_number == 1500: + # check tile max number is being set by adaptive_tile_params + assert hp.tiling_parameters.tile_max_number != default_tile_max_number + else: + # check tile max number is being manually set + assert hp.tiling_parameters.tile_max_number == default_tile_max_number