Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapt input size automatically based on dataset statistics #2499

Merged
merged 34 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
85c12b7
tmp
Sep 4, 2023
407df1b
Merge remote-tracking branch 'origin/develop' into feat/auto-input-si…
Sep 7, 2023
7dcb9ee
Refactor robust stat functions for common use
Sep 7, 2023
ebd6268
Implement parse helper for InputSizePreset
Sep 7, 2023
bff9415
Implement input size preset selection
Sep 8, 2023
53b1a32
Implement common adaptive input size logic
Sep 8, 2023
02e743a
Merge remote-tracking branch 'origin/develop' into feat/auto-input-size
Sep 8, 2023
65b569f
Minor fix
Sep 12, 2023
7c4f914
Refine parse() & tuple attr for InputSizePreset
Sep 12, 2023
69d31f3
Implement input size adaptation logic in InputSizeManager
Sep 12, 2023
68ea497
Adapt input size based on dataset stat in BaseConfigurer
Sep 12, 2023
773a286
Implement auto input size for classification
Sep 12, 2023
a82dd21
Implement auto input size for segmentation
Sep 12, 2023
c07598a
Implement auto input size for detection
Sep 12, 2023
905987b
Merge remote-tracking branch 'origin/develop' into feat/auto-input-size
Sep 12, 2023
c55adc9
Enable 'Auto' input size via CLI
Sep 12, 2023
0c0a979
Fix pre-commit
Sep 13, 2023
61c5e8d
Subsample for dataset stat compute
Sep 13, 2023
1144187
Fix pre-commit
Sep 13, 2023
7e4bf30
Set 'Auto' as the default input size setting
Sep 13, 2023
2eb4798
Fix unit test failures
Sep 15, 2023
07e7e67
Merge remote-tracking branch 'origin/develop' into feat/auto-input-size
Sep 15, 2023
448b72b
Update changelog.md
Sep 15, 2023
43cad8d
Fix Self-SL pipeline issue
Sep 18, 2023
6232ea3
Merge remote-tracking branch 'origin/develop' into feat/auto-input-size
Sep 18, 2023
a245f24
Diable Auto mode test for DINO variants temporarily
Sep 18, 2023
8510299
Fix pre-commit
Sep 19, 2023
6d76217
Fix integration test failure
Sep 19, 2023
18e50c9
Merge remote-tracking branch 'origin/develop' into feat/auto-input-size
Sep 19, 2023
913c272
Merge remote-tracking branch 'origin/develop' into feat/auto-input-size
Sep 20, 2023
e137dca
Address code review suggestions
Sep 20, 2023
4446935
Fix pre-commit
Sep 20, 2023
43c8723
'Default' as default mode of input size config
Sep 20, 2023
2cb5e15
Update document
Sep 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ All notable changes to this project will be documented in this file.
- Add a new object detector Lite-DINO(<https://github.com/openvinotoolkit/training_extensions/pull/2457>)
- Add Semi-SL Mean Teacher algorithm for Instance Segmentation task(<https://github.com/openvinotoolkit/training_extensions/pull/2444>)
- Official supports for YOLOX-X, YOLOX-L, YOLOX-S, ResNeXt101-ATSS (<https://github.com/openvinotoolkit/training_extensions/pull/2485>)
- Add new argument to track resource usage in train command(<https://github.com/openvinotoolkit/training_extensions/pull/2500>)
- Add new argument to track resource usage in train command (<https://github.com/openvinotoolkit/training_extensions/pull/2500>)
- Adapt input size automatically based on dataset statistics (<https://github.com/openvinotoolkit/training_extensions/pull/2499>)

### Enhancements

Expand Down
13 changes: 9 additions & 4 deletions src/otx/algorithms/classification/adapters/mmcls/configurer.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from otx.algorithms.common.adapters.mmcv.semisl_mixin import SemiSLConfigurerMixin
from otx.algorithms.common.adapters.mmcv.utils.config_utils import (
InputSizeManager,
get_configured_input_size,
recursively_update_cfg,
update_or_add_custom_hook,
)
Expand Down Expand Up @@ -166,11 +165,17 @@ def configure_input_size(
cfg, input_size_config: InputSizePreset = InputSizePreset.DEFAULT, model_ckpt_path: Optional[str] = None
):
"""Change input size if necessary."""
input_size = get_configured_input_size(input_size_config, model_ckpt_path)
if input_size is None:
manager = InputSizeManager(cfg)
input_size = manager.get_configured_input_size(input_size_config, model_ckpt_path)
if input_size is None: # InputSizePreset.DEFAULT
return

InputSizeManager(cfg.data).set_input_size(input_size)
if input_size == (0, 0): # InputSizePreset.AUTO
input_size = BaseConfigurer.adapt_input_size_to_dataset(cfg, manager)
if input_size is None:
return

manager.set_input_size(input_size)
logger.info("Input size is changed to {}".format(input_size))


Expand Down
2 changes: 1 addition & 1 deletion src/otx/algorithms/classification/adapters/mmcls/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ def patch_input_preprocessing(deploy_cfg):
mo_options.flags = list(set(mo_options.flags))

def patch_input_shape(deploy_cfg):
input_size_manager = InputSizeManager(cfg.data)
input_size_manager = InputSizeManager(cfg)
size = input_size_manager.get_input_size_from_cfg("test")
assert all(isinstance(i, int) and i > 0 for i in size)
# default is static shape to prevent an unexpected error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,18 +277,20 @@ learning_parameters:
warning: null
input_size:
affects_outcome_of: INFERENCE
default_value: Default
default_value: Auto
description:
The input size of the given model could be configured to one of the predefined resolutions.
Reduced training and inference time could be expected by using smaller input size.
Defaults to per-model default resolution.
Defaults to Auto, in which input size is automatically determined based on dataset statistics.
editable: true
enum_name: InputSizePreset
header: Configure model input size.
options:
DEFAULT: "Default"
AUTO: "Auto"
_64x64: "64x64"
_128x128: "128x128"
_224x224: "224x224"
_256x256: "256x256"
_384x384: "384x384"
_512x512: "512x512"
Expand Down
43 changes: 42 additions & 1 deletion src/otx/algorithms/common/adapters/mmcv/configurer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
# SPDX-License-Identifier: Apache-2.0
#

import json
import os
from typing import Any, Dict, List, Optional
from typing import Any, Dict, List, Optional, Tuple

import numpy as np
import torch
Expand All @@ -18,6 +19,7 @@
patch_persistent_workers,
)
from otx.algorithms.common.adapters.mmcv.utils.config_utils import (
InputSizeManager,
patch_color_conversion,
patch_from_hyperparams,
recursively_update_cfg,
Expand All @@ -26,6 +28,7 @@
from otx.algorithms.common.configs.configuration_enums import InputSizePreset
from otx.algorithms.common.tasks.base_task import OnHookInitialized
from otx.algorithms.common.utils import UncopiableDefaultDict, append_dist_rank_suffix
from otx.algorithms.common.utils.data import compute_robust_dataset_statistics
from otx.algorithms.common.utils.logger import get_logger
from otx.api.usecases.reporting.time_monitor_callback import TimeMonitorCallback
from otx.core.data import caching
Expand Down Expand Up @@ -492,3 +495,41 @@ def get_data_cfg(cfg, subset):
dataset = dataset.dataset
return dataset
return cfg.data[subset]

@staticmethod
def adapt_input_size_to_dataset(
cfg, input_size_manager: InputSizeManager, downscale_only: bool = True, use_annotations: bool = False
) -> Optional[Tuple[int, int]]:
"""Compute appropriate model input size w.r.t. dataset statistics.

Args:
cfg (Dict): Global configuration.
input_size_manager: (InputSizeManager): Pre-configured input size manager
downscale_only (bool) : Whether to allow only smaller size than default setting. Defaults to True.
use_annotations (bool): Whether to consider annotation shapes to compute input size. Defaults to False.

Returns:
Tuple[int, int]: (width, height) or None
"""

data_cfg = BaseConfigurer.get_data_cfg(cfg, "train")
dataset = data_cfg.get("otx_dataset", None)
if dataset is None:
return None

stat = compute_robust_dataset_statistics(dataset, use_annotations)
if not stat:
return None
logger.info(f"Dataset stat: {json.dumps(stat, indent=4)}")

# Fit to typical large image size (conservative)
# -> "avg" size might be preferrable for efficiency
image_size = stat["image"]["robust_max"]
object_size = None
if use_annotations and stat["annotation"]:
# Refine using annotation shape size stat
# Fit to typical small object size (conservative)
# -> "avg" size might be preferrable for efficiency
object_size = stat["annotation"].get("size_of_shape", {}).get("robust_min", None)

return input_size_manager.adapt_input_size_to_dataset(image_size, object_size, downscale_only)
Loading