diff --git a/external/mmdetection/detection_tasks/apis/detection/config_utils.py b/external/mmdetection/detection_tasks/apis/detection/config_utils.py index 3a8c59147b1..88cbad2c12f 100644 --- a/external/mmdetection/detection_tasks/apis/detection/config_utils.py +++ b/external/mmdetection/detection_tasks/apis/detection/config_utils.py @@ -18,12 +18,17 @@ import os import tempfile from collections import defaultdict -from typing import List, Optional +from typing import List, Optional, Union from mmcv import Config, ConfigDict from ote_sdk.entities.datasets import DatasetEntity from ote_sdk.entities.label import LabelEntity, Domain from ote_sdk.usecases.reporting.time_monitor_callback import TimeMonitorCallback +from ote_sdk.utils.argument_checks import ( + DatasetParamTypeCheck, + DirectoryPathCheck, + check_input_parameters_type +) from detection_tasks.extension.datasets.data_utils import get_anchor_boxes, \ get_sizes_from_dataset_entity, format_list_to_str @@ -42,14 +47,16 @@ logger = get_root_logger() +@check_input_parameters_type() def is_epoch_based_runner(runner_config: ConfigDict): return 'Epoch' in runner_config.type +@check_input_parameters_type({"work_dir": DirectoryPathCheck}) def patch_config(config: Config, work_dir: str, labels: List[LabelEntity], domain: Domain, random_seed: Optional[int] = None): # Set runner if not defined. if 'runner' not in config: - config.runner = {'type': 'EpochBasedRunner'} + config.runner = ConfigDict({'type': 'EpochBasedRunner'}) # Check that there is no conflict in specification of number of training epochs. # Move global definition of epochs inside runner config. @@ -105,6 +112,7 @@ def patch_config(config: Config, work_dir: str, labels: List[LabelEntity], domai config.seed = random_seed +@check_input_parameters_type() def set_hyperparams(config: Config, hyperparams: OTEDetectionConfig): config.optimizer.lr = float(hyperparams.learning_parameters.learning_rate) config.lr_config.warmup_iters = int(hyperparams.learning_parameters.learning_rate_warmup_iters) @@ -119,7 +127,8 @@ def set_hyperparams(config: Config, hyperparams: OTEDetectionConfig): config.runner.max_iters = total_iterations -def patch_adaptive_repeat_dataset(config: Config, num_samples: int, +@check_input_parameters_type() +def patch_adaptive_repeat_dataset(config: Union[Config, ConfigDict], num_samples: int, decay: float = -0.002, factor: float = 30): """ Patch the repeat times and training epochs adatively @@ -146,13 +155,16 @@ def patch_adaptive_repeat_dataset(config: Config, num_samples: int, config.data.train.times = new_repeat -def prepare_for_testing(config: Config, dataset: DatasetEntity) -> Config: +@check_input_parameters_type({"dataset": DatasetParamTypeCheck}) +def prepare_for_testing(config: Union[Config, ConfigDict], dataset: DatasetEntity) -> Config: config = copy.deepcopy(config) # FIXME. Should working directories be modified here? config.data.test.ote_dataset = dataset return config +@check_input_parameters_type({"train_dataset": DatasetParamTypeCheck, + "val_dataset": DatasetParamTypeCheck}) def prepare_for_training(config: Config, train_dataset: DatasetEntity, val_dataset: DatasetEntity, time_monitor: TimeMonitorCallback, learning_curves: defaultdict) -> Config: config = copy.deepcopy(config) @@ -168,7 +180,8 @@ def prepare_for_training(config: Config, train_dataset: DatasetEntity, val_datas return config -def config_to_string(config: Config) -> str: +@check_input_parameters_type() +def config_to_string(config: Union[Config, ConfigDict]) -> str: """ Convert a full mmdetection config to a string. @@ -190,6 +203,7 @@ def config_to_string(config: Config) -> str: return Config(config_copy).pretty_text +@check_input_parameters_type() def config_from_string(config_string: str) -> Config: """ Generate an mmdetection config dict object from a string. @@ -203,6 +217,7 @@ def config_from_string(config_string: str) -> Config: return Config.fromfile(temp_file.name) +@check_input_parameters_type() def save_config_to_file(config: Config): """ Dump the full config to a file. Filename is 'config.py', it is saved in the current work_dir. """ filepath = os.path.join(config.work_dir, 'config.py') @@ -211,7 +226,8 @@ def save_config_to_file(config: Config): f.write(config_string) -def prepare_work_dir(config: Config) -> str: +@check_input_parameters_type() +def prepare_work_dir(config: Union[Config, ConfigDict]) -> str: base_work_dir = config.work_dir checkpoint_dirs = glob.glob(os.path.join(base_work_dir, "checkpoints_round_*")) train_round_checkpoint_dir = os.path.join(base_work_dir, f"checkpoints_round_{len(checkpoint_dirs)}") @@ -226,6 +242,7 @@ def prepare_work_dir(config: Config) -> str: return train_round_checkpoint_dir +@check_input_parameters_type() def set_data_classes(config: Config, labels: List[LabelEntity]): # Save labels in data configs. for subset in ('train', 'val', 'test'): @@ -255,7 +272,8 @@ def set_data_classes(config: Config, labels: List[LabelEntity]): # self.config.model.CLASSES = label_names -def patch_datasets(config: Config, domain): +@check_input_parameters_type() +def patch_datasets(config: Config, domain: Domain): def patch_color_conversion(pipeline): # Default data format for OTE is RGB, while mmdet uses BGR, so negate the color conversion flag. @@ -290,7 +308,8 @@ def patch_color_conversion(pipeline): patch_color_conversion(cfg.pipeline) -def remove_from_config(config, key: str): +@check_input_parameters_type() +def remove_from_config(config: Union[Config, ConfigDict], key: str): if key in config: if isinstance(config, Config): del config._cfg_dict[key] @@ -299,6 +318,8 @@ def remove_from_config(config, key: str): else: raise ValueError(f'Unknown config type {type(config)}') + +@check_input_parameters_type({"dataset": DatasetParamTypeCheck}) def cluster_anchors(config: Config, dataset: DatasetEntity, model: BaseDetector): if not kmeans_import: raise ImportError('Sklearn package is not installed. To enable anchor boxes clustering, please install ' @@ -309,7 +330,7 @@ def cluster_anchors(config: Config, dataset: DatasetEntity, model: BaseDetector) if transforms.type == 'MultiScaleFlipAug'] prev_generator = config.model.bbox_head.anchor_generator group_as = [len(width) for width in prev_generator.widths] - wh_stats = get_sizes_from_dataset_entity(dataset, target_wh) + wh_stats = get_sizes_from_dataset_entity(dataset, list(target_wh)) if len(wh_stats) < sum(group_as): logger.warning(f'There are not enough objects to cluster: {len(wh_stats)} were detected, while it should be ' diff --git a/external/mmdetection/detection_tasks/apis/detection/inference_task.py b/external/mmdetection/detection_tasks/apis/detection/inference_task.py index 78dfabc0def..e82dad3b5d1 100644 --- a/external/mmdetection/detection_tasks/apis/detection/inference_task.py +++ b/external/mmdetection/detection_tasks/apis/detection/inference_task.py @@ -45,6 +45,10 @@ from ote_sdk.usecases.tasks.interfaces.inference_interface import IInferenceTask from ote_sdk.usecases.tasks.interfaces.unload_interface import IUnload from ote_sdk.serialization.label_mapper import label_schema_to_bytes +from ote_sdk.utils.argument_checks import ( + DatasetParamTypeCheck, + check_input_parameters_type, +) from mmdet.apis import export_model from detection_tasks.apis.detection.config_utils import patch_config, prepare_for_testing, set_hyperparams @@ -63,6 +67,7 @@ class OTEDetectionInferenceTask(IInferenceTask, IExportTask, IEvaluationTask, IU _task_environment: TaskEnvironment + @check_input_parameters_type() def __init__(self, task_environment: TaskEnvironment): """" Task for inference object detection models using OTEDetection. @@ -227,6 +232,7 @@ def _add_predictions_to_dataset(self, prediction_results, dataset, confidence_th dataset_item.append_metadata_item(active_score, model=self._task_environment.model) + @check_input_parameters_type({"dataset": DatasetParamTypeCheck}) def infer(self, dataset: DatasetEntity, inference_parameters: Optional[InferenceParameters] = None) -> DatasetEntity: """ Analyzes a dataset using the latest inference model. """ @@ -318,7 +324,7 @@ def dummy_dump_features_hook(mod, inp, out): eval_predictions = zip(eval_predictions, feature_vectors) return eval_predictions, metric - + @check_input_parameters_type() def evaluate(self, output_result_set: ResultSetEntity, evaluation_metric: Optional[str] = None): @@ -363,6 +369,7 @@ def unload(self): logger.warning(f"Done unloading. " f"Torch is still occupying {torch.cuda.memory_allocated()} bytes of GPU memory") + @check_input_parameters_type() def export(self, export_type: ExportType, output_model: ModelEntity): diff --git a/external/mmdetection/detection_tasks/apis/detection/nncf_task.py b/external/mmdetection/detection_tasks/apis/detection/nncf_task.py index 216bd3d0148..b0f295f7d7f 100644 --- a/external/mmdetection/detection_tasks/apis/detection/nncf_task.py +++ b/external/mmdetection/detection_tasks/apis/detection/nncf_task.py @@ -36,6 +36,10 @@ from ote_sdk.usecases.tasks.interfaces.export_interface import ExportType from ote_sdk.usecases.tasks.interfaces.optimization_interface import IOptimizationTask from ote_sdk.usecases.tasks.interfaces.optimization_interface import OptimizationType +from ote_sdk.utils.argument_checks import ( + DatasetParamTypeCheck, + check_input_parameters_type, +) from mmdet.apis import train_detector from mmdet.apis.fake_input import get_fake_input @@ -59,6 +63,7 @@ class OTEDetectionNNCFTask(OTEDetectionInferenceTask, IOptimizationTask): + @check_input_parameters_type() def __init__(self, task_environment: TaskEnvironment): """" Task for compressing object detection models using NNCF. @@ -177,12 +182,13 @@ def _create_compressed_model(self, dataset, config): get_fake_input_func=get_fake_input, is_accuracy_aware=is_acc_aware_training_set) + @check_input_parameters_type({"dataset": DatasetParamTypeCheck}) def optimize( self, optimization_type: OptimizationType, dataset: DatasetEntity, output_model: ModelEntity, - optimization_parameters: Optional[OptimizationParameters], + optimization_parameters: Optional[OptimizationParameters] = None, ): if optimization_type is not OptimizationType.NNCF: raise RuntimeError("NNCF is the only supported optimization") @@ -236,6 +242,7 @@ def optimize( self._is_training = False + @check_input_parameters_type() def export(self, export_type: ExportType, output_model: ModelEntity): if self._compression_ctrl is None: super().export(export_type, output_model) @@ -245,6 +252,7 @@ def export(self, export_type: ExportType, output_model: ModelEntity): super().export(export_type, output_model) self._model.enable_dynamic_graph_building() + @check_input_parameters_type() def save_model(self, output_model: ModelEntity): buffer = io.BytesIO() hyperparams = self._task_environment.get_hyper_parameters(OTEDetectionConfig) diff --git a/external/mmdetection/detection_tasks/apis/detection/openvino_task.py b/external/mmdetection/detection_tasks/apis/detection/openvino_task.py index b8dd5d3fa61..9ec75118924 100644 --- a/external/mmdetection/detection_tasks/apis/detection/openvino_task.py +++ b/external/mmdetection/detection_tasks/apis/detection/openvino_task.py @@ -50,6 +50,7 @@ from ote_sdk.usecases.exportable_code.inference import BaseInferencer from ote_sdk.usecases.exportable_code.prediction_to_annotation_converter import ( DetectionBoxToAnnotationConverter, + IPredictionToAnnotationConverter, MaskToAnnotationConverter, RotatedRectToAnnotationConverter, ) @@ -57,6 +58,10 @@ from ote_sdk.usecases.tasks.interfaces.evaluate_interface import IEvaluationTask from ote_sdk.usecases.tasks.interfaces.inference_interface import IInferenceTask from ote_sdk.usecases.tasks.interfaces.optimization_interface import IOptimizationTask, OptimizationType +from ote_sdk.utils.argument_checks import ( + DatasetParamTypeCheck, + check_input_parameters_type, +) from shutil import copyfile, copytree from typing import Any, Dict, List, Optional, Tuple, Union from zipfile import ZipFile @@ -70,24 +75,29 @@ class BaseInferencerWithConverter(BaseInferencer): - def __init__(self, configuration, model, converter) -> None: + @check_input_parameters_type() + def __init__(self, configuration: dict, model: Model, converter: IPredictionToAnnotationConverter) -> None: self.configuration = configuration self.model = model self.converter = converter + @check_input_parameters_type() def pre_process(self, image: np.ndarray) -> Tuple[Dict[str, np.ndarray], Dict[str, Any]]: return self.model.preprocess(image) + @check_input_parameters_type() def post_process(self, prediction: Dict[str, np.ndarray], metadata: Dict[str, Any]) -> AnnotationSceneEntity: detections = self.model.postprocess(prediction, metadata) return self.converter.convert_to_annotation(detections, metadata) + @check_input_parameters_type() def forward(self, inputs: Dict[str, np.ndarray]) -> Dict[str, np.ndarray]: return self.model.infer_sync(inputs) class OpenVINODetectionInferencer(BaseInferencerWithConverter): + @check_input_parameters_type() def __init__( self, hparams: OTEDetectionConfig, @@ -119,6 +129,7 @@ def __init__( class OpenVINOMaskInferencer(BaseInferencerWithConverter): + @check_input_parameters_type() def __init__( self, hparams: OTEDetectionConfig, @@ -153,6 +164,7 @@ def __init__( class OpenVINORotatedRectInferencer(BaseInferencerWithConverter): + @check_input_parameters_type() def __init__( self, hparams: OTEDetectionConfig, @@ -187,11 +199,13 @@ def __init__( class OTEOpenVinoDataLoader(DataLoader): + @check_input_parameters_type({"dataset": DatasetParamTypeCheck}) def __init__(self, dataset: DatasetEntity, inferencer: BaseInferencer): self.dataset = dataset self.inferencer = inferencer - def __getitem__(self, index): + @check_input_parameters_type() + def __getitem__(self, index: int): image = self.dataset[index].numpy annotation = self.dataset[index].annotation_scene inputs, metadata = self.inferencer.pre_process(image) @@ -203,6 +217,7 @@ def __len__(self): class OpenVINODetectionTask(IDeploymentTask, IInferenceTask, IEvaluationTask, IOptimizationTask): + @check_input_parameters_type() def __init__(self, task_environment: TaskEnvironment): logger.info('Loading OpenVINO OTEDetectionTask') self.task_environment = task_environment @@ -235,6 +250,7 @@ def load_inferencer(self) -> Union[OpenVINODetectionInferencer, OpenVINOMaskInfe return OpenVINORotatedRectInferencer(*args) raise RuntimeError(f"Unknown OpenVINO Inferencer TaskType: {self.task_type}") + @check_input_parameters_type({"dataset": DatasetParamTypeCheck}) def infer(self, dataset: DatasetEntity, inference_parameters: Optional[InferenceParameters] = None) -> DatasetEntity: logger.info('Start OpenVINO inference') update_progress_callback = default_progress_callback @@ -248,6 +264,7 @@ def infer(self, dataset: DatasetEntity, inference_parameters: Optional[Inference logger.info('OpenVINO inference completed') return dataset + @check_input_parameters_type() def evaluate(self, output_result_set: ResultSetEntity, evaluation_metric: Optional[str] = None): @@ -257,6 +274,7 @@ def evaluate(self, output_result_set.performance = MetricsHelper.compute_f_measure(output_result_set).get_performance() logger.info('OpenVINO metric evaluation completed') + @check_input_parameters_type() def deploy(self, output_model: ModelEntity) -> None: logger.info('Deploying the model') @@ -297,11 +315,12 @@ def deploy(self, output_model.exportable_code = file.read() logger.info('Deploying completed') + @check_input_parameters_type({"dataset": DatasetParamTypeCheck}) def optimize(self, optimization_type: OptimizationType, dataset: DatasetEntity, output_model: ModelEntity, - optimization_parameters: Optional[OptimizationParameters]): + optimization_parameters: Optional[OptimizationParameters] = None): logger.info('Start POT optimization') if optimization_type is not OptimizationType.POT: diff --git a/external/mmdetection/detection_tasks/apis/detection/ote_utils.py b/external/mmdetection/detection_tasks/apis/detection/ote_utils.py index 2def0949b45..89e94c00f80 100644 --- a/external/mmdetection/detection_tasks/apis/detection/ote_utils.py +++ b/external/mmdetection/detection_tasks/apis/detection/ote_utils.py @@ -16,7 +16,7 @@ import colorsys import importlib import random -from typing import Callable, Union +from typing import Callable, Optional, Sequence, Union import numpy as np import yaml @@ -26,10 +26,15 @@ from ote_sdk.entities.label_schema import LabelGroup, LabelGroupType, LabelSchemaEntity from ote_sdk.entities.train_parameters import UpdateProgressCallback from ote_sdk.usecases.reporting.time_monitor_callback import TimeMonitorCallback +from ote_sdk.utils.argument_checks import ( + YamlFilePathCheck, + check_input_parameters_type, +) class ColorPalette: - def __init__(self, n, rng=None): + @check_input_parameters_type() + def __init__(self, n: int, rng: Optional[random.Random] = None): assert n > 0 if rng is None: @@ -40,36 +45,38 @@ def __init__(self, n, rng=None): for _ in range(1, n): colors_candidates = [(rng.random(), rng.uniform(0.8, 1.0), rng.uniform(0.5, 1.0)) for _ in range(candidates_num)] - min_distances = [self.min_distance(hsv_colors, c) for c in colors_candidates] + min_distances = [self._min_distance(hsv_colors, c) for c in colors_candidates] arg_max = np.argmax(min_distances) hsv_colors.append(colors_candidates[arg_max]) - self.palette = [Color(*self.hsv2rgb(*hsv)) for hsv in hsv_colors] + self.palette = [Color(*self._hsv2rgb(*hsv)) for hsv in hsv_colors] @staticmethod - def dist(c1, c2): + def _dist(c1, c2): dh = min(abs(c1[0] - c2[0]), 1 - abs(c1[0] - c2[0])) * 2 ds = abs(c1[1] - c2[1]) dv = abs(c1[2] - c2[2]) return dh * dh + ds * ds + dv * dv @classmethod - def min_distance(cls, colors_set, color_candidate): - distances = [cls.dist(o, color_candidate) for o in colors_set] + def _min_distance(cls, colors_set, color_candidate): + distances = [cls._dist(o, color_candidate) for o in colors_set] return np.min(distances) @staticmethod - def hsv2rgb(h, s, v): + def _hsv2rgb(h, s, v): return tuple(round(c * 255) for c in colorsys.hsv_to_rgb(h, s, v)) - def __getitem__(self, n): + @check_input_parameters_type() + def __getitem__(self, n: int): return self.palette[n % len(self.palette)] def __len__(self): return len(self.palette) -def generate_label_schema(label_names, label_domain=Domain.DETECTION): +@check_input_parameters_type() +def generate_label_schema(label_names: Sequence[str], label_domain: Domain = Domain.DETECTION): colors = ColorPalette(len(label_names)) if len(label_names) > 0 else [] not_empty_labels = [LabelEntity(name=name, color=colors[i], domain=label_domain, id=ID(f"{i:08}")) for i, name in enumerate(label_names)] @@ -84,13 +91,15 @@ def generate_label_schema(label_names, label_domain=Domain.DETECTION): return label_schema +@check_input_parameters_type({"path": YamlFilePathCheck}) def load_template(path): with open(path) as f: template = yaml.full_load(f) return template -def get_task_class(path): +@check_input_parameters_type() +def get_task_class(path: str): module_name, class_name = path.rsplit('.', 1) module = importlib.import_module(module_name) return getattr(module, class_name) diff --git a/external/mmdetection/detection_tasks/apis/detection/train_task.py b/external/mmdetection/detection_tasks/apis/detection/train_task.py index 9d837cd2f82..fd36f887131 100644 --- a/external/mmdetection/detection_tasks/apis/detection/train_task.py +++ b/external/mmdetection/detection_tasks/apis/detection/train_task.py @@ -33,6 +33,10 @@ from ote_sdk.serialization.label_mapper import label_schema_to_bytes from ote_sdk.usecases.evaluation.metrics_helper import MetricsHelper from ote_sdk.usecases.tasks.interfaces.training_interface import ITrainingTask +from ote_sdk.utils.argument_checks import ( + DatasetParamTypeCheck, + check_input_parameters_type, +) from mmdet.apis import train_detector from detection_tasks.apis.detection.config_utils import cluster_anchors, prepare_for_training, set_hyperparams @@ -81,6 +85,7 @@ def _generate_training_metrics(self, learning_curves, map) -> Optional[List[Metr return output + @check_input_parameters_type({"dataset": DatasetParamTypeCheck}) def train(self, dataset: DatasetEntity, output_model: ModelEntity, train_parameters: Optional[TrainParameters] = None): """ Trains a model on a dataset """ @@ -191,6 +196,7 @@ def train(self, dataset: DatasetEntity, output_model: ModelEntity, train_paramet logger.info('Training the model [done]') + @check_input_parameters_type() def save_model(self, output_model: ModelEntity): buffer = io.BytesIO() hyperparams_str = ids_to_strings(cfg_helper.convert(self._hyperparams, dict, enum_to_str=True)) diff --git a/external/mmdetection/detection_tasks/extension/datasets/data_utils.py b/external/mmdetection/detection_tasks/extension/datasets/data_utils.py index ff38a3243af..e4a6ebefbd5 100644 --- a/external/mmdetection/detection_tasks/extension/datasets/data_utils.py +++ b/external/mmdetection/detection_tasks/extension/datasets/data_utils.py @@ -3,7 +3,7 @@ # import json import os.path as osp -from typing import List, Optional +from typing import Any, Dict, List, Optional, Sequence import numpy as np from ote_sdk.entities.annotation import Annotation, AnnotationSceneEntity, AnnotationSceneKind @@ -16,11 +16,19 @@ from ote_sdk.entities.shapes.polygon import Polygon, Point from ote_sdk.entities.shapes.rectangle import Rectangle from ote_sdk.entities.subset import Subset +from ote_sdk.utils.argument_checks import ( + DatasetParamTypeCheck, + DirectoryPathCheck, + OptionalDirectoryPathCheck, + JsonFilePathCheck, + check_input_parameters_type, +) from ote_sdk.utils.shape_factory import ShapeFactory from pycocotools.coco import COCO from mmdet.core import BitmapMasks, PolygonMasks +@check_input_parameters_type({"path": JsonFilePathCheck}) def get_classes_from_annotation(path): with open(path) as read_file: content = json.load(read_file) @@ -31,7 +39,8 @@ def get_classes_from_annotation(path): class LoadAnnotations: - def __init__(self, with_bbox=True, with_label=True, with_mask=False): + @check_input_parameters_type() + def __init__(self, with_bbox: bool = True, with_label: bool = True, with_mask: bool = False): self.with_bbox = with_bbox self.with_label = with_label self.with_mask = with_mask @@ -57,7 +66,8 @@ def _load_masks(self, results): results['mask_fields'].append('gt_masks') return results - def __call__(self, results): + @check_input_parameters_type() + def __call__(self, results: Dict[str, Any]): if self.with_bbox: results = self._load_bboxes(results) if results is None: @@ -77,16 +87,18 @@ def __repr__(self): class CocoDataset: + @check_input_parameters_type({"ann_file": JsonFilePathCheck, + "data_root": OptionalDirectoryPathCheck}) def __init__( self, - ann_file, - classes=None, - data_root=None, - img_prefix="", - test_mode=False, - filter_empty_gt=True, - min_size=None, - with_mask=False, + ann_file: str, + classes: Optional[Sequence[str]] = None, + data_root: Optional[str] = None, + img_prefix: str = "", + test_mode: bool = False, + filter_empty_gt: bool = True, + min_size: Optional[int] = None, + with_mask: bool = False, ): self.ann_file = ann_file self.data_root = data_root @@ -112,7 +124,8 @@ def __init__( def __len__(self): return len(self.data_infos) - def pre_pipeline(self, results): + @check_input_parameters_type() + def pre_pipeline(self, results: Dict[str, Any]): results["img_prefix"] = self.img_prefix results["bbox_fields"] = [] results["mask_fields"] = [] @@ -122,21 +135,24 @@ def _rand_another(self, idx): pool = np.where(self.flag == self.flag[idx])[0] return np.random.choice(pool) - def __getitem__(self, idx): + @check_input_parameters_type() + def __getitem__(self, idx: int): return self.prepare_img(idx) def __iter__(self): for i in range(len(self)): yield self[i] - def prepare_img(self, idx): + @check_input_parameters_type() + def prepare_img(self, idx: int): img_info = self.data_infos[idx] ann_info = self.get_ann_info(idx) results = dict(img_info=img_info, ann_info=ann_info) self.pre_pipeline(results) return LoadAnnotations(with_mask=self.with_mask)(results) - def get_classes(self, classes=None): + @check_input_parameters_type() + def get_classes(self, classes: Optional[Sequence[str]] = None): if classes is None: return get_classes_from_annotation(self.ann_file) @@ -145,6 +161,7 @@ def get_classes(self, classes=None): raise ValueError(f"Unsupported type {type(classes)} of classes.") + @check_input_parameters_type({"ann_file": JsonFilePathCheck}) def load_annotations(self, ann_file): self.coco = COCO(ann_file) self.cat_ids = self.coco.get_cat_ids(cat_names=self.classes) @@ -157,13 +174,15 @@ def load_annotations(self, ann_file): data_infos.append(info) return data_infos - def get_ann_info(self, idx): + @check_input_parameters_type() + def get_ann_info(self, idx: int): img_id = self.data_infos[idx]["id"] ann_ids = self.coco.get_ann_ids(img_ids=[img_id]) ann_info = self.coco.load_anns(ann_ids) return self._parse_ann_info(self.data_infos[idx], ann_info) - def get_cat_ids(self, idx): + @check_input_parameters_type() + def get_cat_ids(self, idx: int): img_id = self.data_infos[idx]["id"] ann_ids = self.coco.get_ann_ids(img_ids=[img_id]) ann_info = self.coco.load_anns(ann_ids) @@ -246,7 +265,8 @@ def _parse_ann_info(self, img_info, ann_info): return ann -def find_label_by_name(labels, name, domain): +@check_input_parameters_type() +def find_label_by_name(labels: Sequence[LabelEntity], name: str, domain: Domain): matching_labels = [label for label in labels if label.name == name] if len(matching_labels) == 1: return matching_labels[0] @@ -258,6 +278,8 @@ def find_label_by_name(labels, name, domain): raise ValueError("Found multiple matching labels") +@check_input_parameters_type({"ann_file_path": JsonFilePathCheck, + "data_root_dir": DirectoryPathCheck}) def load_dataset_items_coco_format( ann_file_path: str, data_root_dir: str, @@ -346,7 +368,8 @@ def create_gt_polygon(polygon_group, label_name): return dataset_items -def get_sizes_from_dataset_entity(dataset: DatasetEntity, target_wh: list): +@check_input_parameters_type({"dataset": DatasetParamTypeCheck}) +def get_sizes_from_dataset_entity(dataset: DatasetEntity, target_wh: List[int]): """ Function to get sizes of instances in DatasetEntity and to resize it to the target size. @@ -366,7 +389,8 @@ def get_sizes_from_dataset_entity(dataset: DatasetEntity, target_wh: list): return wh_stats -def get_anchor_boxes(wh_stats, group_as): +@check_input_parameters_type() +def get_anchor_boxes(wh_stats: List[tuple], group_as: List[int]): from sklearn.cluster import KMeans kmeans = KMeans(init='k-means++', n_clusters=sum(group_as), random_state=0).fit(wh_stats) centers = kmeans.cluster_centers_ @@ -382,6 +406,7 @@ def get_anchor_boxes(wh_stats, group_as): return widths, heights +@check_input_parameters_type() def format_list_to_str(value_lists): """ Decrease floating point digits in logs """ str_value = '' diff --git a/external/mmdetection/detection_tasks/extension/datasets/mmdataset.py b/external/mmdetection/detection_tasks/extension/datasets/mmdataset.py index ba7ef08c136..9f9ca5c8717 100644 --- a/external/mmdetection/detection_tasks/extension/datasets/mmdataset.py +++ b/external/mmdetection/detection_tasks/extension/datasets/mmdataset.py @@ -13,12 +13,16 @@ # and limitations under the License. from copy import deepcopy -from typing import List +from typing import Any, Dict, List, Sequence import numpy as np from ote_sdk.entities.dataset_item import DatasetItemEntity from ote_sdk.entities.datasets import DatasetEntity from ote_sdk.entities.label import Domain, LabelEntity +from ote_sdk.utils.argument_checks import ( + DatasetParamTypeCheck, + check_input_parameters_type, +) from ote_sdk.utils.shape_factory import ShapeFactory from mmdet.core import PolygonMasks @@ -27,6 +31,7 @@ from mmdet.datasets.pipelines import Compose +@check_input_parameters_type() def get_annotation_mmdet_format( dataset_item: DatasetItemEntity, labels: List[LabelEntity], @@ -130,7 +135,15 @@ def __getitem__(self, index): return data_info - def __init__(self, ote_dataset: DatasetEntity, labels: List[LabelEntity], pipeline, domain, test_mode: bool = False): + @check_input_parameters_type({"ote_dataset": DatasetParamTypeCheck}) + def __init__( + self, + ote_dataset: DatasetEntity, + labels: List[LabelEntity], + pipeline: Sequence[dict], + domain: Domain, + test_mode: bool = False, + ): self.ote_dataset = ote_dataset self.labels = labels self.CLASSES = list(label.name for label in labels) @@ -171,6 +184,7 @@ def _rand_another(self, idx): def _filter_imgs(self, min_size=32): raise NotImplementedError + @check_input_parameters_type() def prepare_train_img(self, idx: int) -> dict: """Get training data and annotations after pipeline. @@ -181,6 +195,7 @@ def prepare_train_img(self, idx: int) -> dict: self.pre_pipeline(item) return self.pipeline(item) + @check_input_parameters_type() def prepare_test_img(self, idx: int) -> dict: """Get testing data after pipeline. @@ -194,12 +209,14 @@ def prepare_test_img(self, idx: int) -> dict: return self.pipeline(item) @staticmethod - def pre_pipeline(results: dict): + @check_input_parameters_type() + def pre_pipeline(results: Dict[str, Any]): """Prepare results dict for pipeline. Add expected keys to the dict. """ results['bbox_fields'] = [] results['mask_fields'] = [] results['seg_fields'] = [] + @check_input_parameters_type() def get_ann_info(self, idx): """ This method is used for evaluation of predictions. The CustomDataset class implements a method diff --git a/external/mmdetection/detection_tasks/extension/utils/hooks.py b/external/mmdetection/detection_tasks/extension/utils/hooks.py index 3c6cc4846f9..7062206dabc 100644 --- a/external/mmdetection/detection_tasks/extension/utils/hooks.py +++ b/external/mmdetection/detection_tasks/extension/utils/hooks.py @@ -17,12 +17,15 @@ import os from math import inf, isnan from collections import defaultdict +from typing import Any, Dict, Optional from mmcv.runner.hooks import HOOKS, Hook, LoggerHook, LrUpdaterHook from mmcv.runner import BaseRunner, EpochBasedRunner from mmcv.runner.dist_utils import master_only from mmcv.utils import print_log +from ote_sdk.usecases.reporting.time_monitor_callback import TimeMonitorCallback +from ote_sdk.utils.argument_checks import check_input_parameters_type from mmdet.utils.logger import get_root_logger @@ -31,6 +34,7 @@ @HOOKS.register_module() class CancelTrainingHook(Hook): + @check_input_parameters_type() def __init__(self, interval: int = 5): """ Periodically check whether whether a stop signal is sent to the runner during model training. @@ -53,6 +57,7 @@ def _check_for_stop_signal(runner: BaseRunner): runner.should_stop = True # Set this flag to true to stop the current training epoch os.remove(stop_filepath) + @check_input_parameters_type() def after_train_iter(self, runner: BaseRunner): if not self.every_n_iters(runner, self.interval): return @@ -68,7 +73,8 @@ def __init__(self): """ pass - def before_run(self, runner): + @check_input_parameters_type() + def before_run(self, runner: BaseRunner): pass @@ -81,7 +87,8 @@ def __init__(self): """ pass - def after_run(self, runner): + @check_input_parameters_type() + def after_run(self, runner: BaseRunner): runner.call_hook('after_train_epoch') @@ -99,17 +106,19 @@ def __repr__(self): points.append(f'({x},{y})') return 'curve[' + ','.join(points) + ']' + @check_input_parameters_type() def __init__(self, - curves=None, - interval=10, - ignore_last=True, - reset_flag=True, - by_epoch=True): + curves: Optional[Dict[Any, Curve]] = None, + interval: int = 10, + ignore_last: bool = True, + reset_flag: bool = True, + by_epoch: bool = True): super().__init__(interval, ignore_last, reset_flag, by_epoch) self.curves = curves if curves is not None else defaultdict(self.Curve) @master_only - def log(self, runner): + @check_input_parameters_type() + def log(self, runner: BaseRunner): tags = self.get_loggable_tags(runner, allow_text=False) if runner.max_epochs is not None: normalized_iter = self.get_iter(runner) / runner.max_iters * runner.max_epochs @@ -124,7 +133,8 @@ def log(self, runner): curve.x.append(normalized_iter) curve.y.append(value) - def after_train_epoch(self, runner): + @check_input_parameters_type() + def after_train_epoch(self, runner: BaseRunner): # Iteration counter is increased right after the last iteration in the epoch, # temporarily decrease it back. runner._iter -= 1 @@ -134,13 +144,15 @@ def after_train_epoch(self, runner): @HOOKS.register_module() class OTEProgressHook(Hook): - def __init__(self, time_monitor, verbose=False): + @check_input_parameters_type() + def __init__(self, time_monitor: TimeMonitorCallback, verbose: bool = False): super().__init__() self.time_monitor = time_monitor self.verbose = verbose self.print_threshold = 1 - def before_run(self, runner): + @check_input_parameters_type() + def before_run(self, runner: BaseRunner): total_epochs = runner.max_epochs if runner.max_epochs is not None else 1 self.time_monitor.total_epochs = total_epochs self.time_monitor.train_steps = runner.max_iters // total_epochs if total_epochs else 1 @@ -149,16 +161,20 @@ def before_run(self, runner): self.time_monitor.current_step = 0 self.time_monitor.current_epoch = 0 - def before_epoch(self, runner): + @check_input_parameters_type() + def before_epoch(self, runner: BaseRunner): self.time_monitor.on_epoch_begin(runner.epoch) + @check_input_parameters_type() def after_epoch(self, runner): self.time_monitor.on_epoch_end(runner.epoch, runner.log_buffer.output) - def before_iter(self, runner): + @check_input_parameters_type() + def before_iter(self, runner: BaseRunner): self.time_monitor.on_train_batch_begin(1) - def after_iter(self, runner): + @check_input_parameters_type() + def after_iter(self, runner: BaseRunner): self.time_monitor.on_train_batch_end(1) if self.verbose: progress = self.progress @@ -166,13 +182,16 @@ def after_iter(self, runner): logger.warning(f'training progress {progress:.0f}%') self.print_threshold = (progress + 10) // 10 * 10 - def before_val_iter(self, runner): + @check_input_parameters_type() + def before_val_iter(self, runner: BaseRunner): self.time_monitor.on_test_batch_begin(1) - def after_val_iter(self, runner): + @check_input_parameters_type() + def after_val_iter(self, runner: BaseRunner): self.time_monitor.on_test_batch_end(1) - def after_run(self, runner): + @check_input_parameters_type() + def after_run(self, runner: BaseRunner): self.time_monitor.on_train_end(1) self.time_monitor.update_progress_callback(int(self.time_monitor.get_progress())) @@ -216,10 +235,11 @@ class EarlyStoppingHook(Hook): ] less_keys = ['loss'] + @check_input_parameters_type() def __init__(self, interval: int, metric: str = 'bbox_mAP', - rule: str = None, + rule: Optional[str] = None, patience: int = 5, iteration_patience: int = 500, min_delta: float = 0.0): @@ -273,19 +293,22 @@ def _init_rule(self, rule, key_indicator): self.key_indicator = key_indicator self.compare_func = self.rule_map[self.rule] - def before_run(self, runner): + @check_input_parameters_type() + def before_run(self, runner: BaseRunner): self.by_epoch = False if runner.max_epochs is None else True for hook in runner.hooks: if isinstance(hook, LrUpdaterHook): self.warmup_iters = hook.warmup_iters break - def after_train_iter(self, runner): + @check_input_parameters_type() + def after_train_iter(self, runner: BaseRunner): """Called after every training iter to evaluate the results.""" if not self.by_epoch: self._do_check_stopping(runner) - def after_train_epoch(self, runner): + @check_input_parameters_type() + def after_train_epoch(self, runner: BaseRunner): """Called after every training epoch to evaluate the results.""" if self.by_epoch: self._do_check_stopping(runner) @@ -370,14 +393,15 @@ class ReduceLROnPlateauLrUpdaterHook(LrUpdaterHook): ] less_keys = ['loss'] + @check_input_parameters_type() def __init__(self, - min_lr, - interval, - metric='bbox_mAP', - rule=None, - factor=0.1, - patience=3, - iteration_patience=300, + min_lr: float, + interval: int, + metric: str = 'bbox_mAP', + rule: Optional[str] = None, + factor: float = 0.1, + patience: int = 3, + iteration_patience: int = 300, **kwargs): super().__init__(**kwargs) self.interval = interval @@ -437,7 +461,8 @@ def _should_check_stopping(self, runner): return False return True - def get_lr(self, runner, base_lr): + @check_input_parameters_type() + def get_lr(self, runner: BaseRunner, base_lr: float): if not self._should_check_stopping( runner) or self.warmup_iters > runner.iter: return base_lr @@ -479,7 +504,8 @@ def get_lr(self, runner, base_lr): self.current_lr = max(self.current_lr * self.factor, self.min_lr) return self.current_lr - def before_run(self, runner): + @check_input_parameters_type() + def before_run(self, runner: BaseRunner): # TODO: remove overloaded method after fixing the issue # https://github.com/open-mmlab/mmdetection/issues/6572 for group in runner.optimizer.param_groups: @@ -496,7 +522,8 @@ def before_run(self, runner): @HOOKS.register_module() class StopLossNanTrainingHook(Hook): - def after_train_iter(self, runner): + @check_input_parameters_type() + def after_train_iter(self, runner: BaseRunner): if isnan(runner.outputs['loss'].item()): logger.warning(f"Early Stopping since loss is NaN") runner.should_stop = True diff --git a/external/mmdetection/detection_tasks/extension/utils/pipelines.py b/external/mmdetection/detection_tasks/extension/utils/pipelines.py index 82629e49973..dd18ee395cb 100644 --- a/external/mmdetection/detection_tasks/extension/utils/pipelines.py +++ b/external/mmdetection/detection_tasks/extension/utils/pipelines.py @@ -14,8 +14,12 @@ import copy +from typing import Dict, Any, Optional import numpy as np +from ote_sdk.entities.label import Domain +from ote_sdk.utils.argument_checks import check_input_parameters_type + from mmdet.datasets.builder import PIPELINES from ..datasets import get_annotation_mmdet_format @@ -34,10 +38,12 @@ class LoadImageFromOTEDataset: :param to_float32: optional bool, True to convert images to fp32. defaults to False """ + @check_input_parameters_type() def __init__(self, to_float32: bool = False): self.to_float32 = to_float32 - def __call__(self, results): + @check_input_parameters_type() + def __call__(self, results: Dict[str, Any]): dataset_item = results['dataset_item'] img = dataset_item.numpy shape = img.shape @@ -77,8 +83,9 @@ class LoadAnnotationFromOTEDataset: """ + @check_input_parameters_type() def __init__(self, min_size : int, with_bbox: bool = True, with_label: bool = True, with_mask: bool = False, with_seg: bool = False, - poly2mask: bool = True, with_text: bool = False, domain=None): + poly2mask: bool = True, with_text: bool = False, domain: Optional[Domain] = None): self.with_bbox = with_bbox self.with_label = with_label self.with_mask = with_mask @@ -105,7 +112,8 @@ def _load_masks(results, ann_info): results['gt_masks'] = copy.deepcopy(ann_info['masks']) return results - def __call__(self, results): + @check_input_parameters_type() + def __call__(self, results: Dict[str, Any]): dataset_item = results['dataset_item'] label_list = results['ann_info']['label_list'] ann_info = get_annotation_mmdet_format(dataset_item, label_list, self.domain, self.min_size) diff --git a/external/mmdetection/detection_tasks/extension/utils/runner.py b/external/mmdetection/detection_tasks/extension/utils/runner.py index 94889b2d1d2..a245d9c3779 100644 --- a/external/mmdetection/detection_tasks/extension/utils/runner.py +++ b/external/mmdetection/detection_tasks/extension/utils/runner.py @@ -11,11 +11,15 @@ import time import warnings +from typing import List, Sequence, Optional import mmcv import torch.distributed as dist from mmcv.runner.utils import get_host_info from mmcv.runner import RUNNERS, EpochBasedRunner, IterBasedRunner, IterLoader, get_dist_info +from torch.utils.data.dataloader import DataLoader + +from ote_sdk.utils.argument_checks import check_input_parameters_type @RUNNERS.register_module() @@ -46,7 +50,8 @@ def stop(self) -> bool: self._max_epochs = self.epoch return broadcast_obj[0] - def train(self, data_loader, **kwargs): + @check_input_parameters_type() + def train(self, data_loader: DataLoader, **kwargs): self.model.train() self.mode = 'train' self.data_loader = data_loader @@ -78,7 +83,8 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.should_stop = False - def main_loop(self, workflow, iter_loaders, **kwargs): + @check_input_parameters_type() + def main_loop(self, workflow: List[tuple], iter_loaders: Sequence[IterLoader], **kwargs): while self.iter < self._max_iters: for i, flow in enumerate(workflow): self._inner_iter = 0 @@ -95,7 +101,8 @@ def main_loop(self, workflow, iter_loaders, **kwargs): if self.should_stop: return - def run(self, data_loaders, workflow, max_iters=None, **kwargs): + @check_input_parameters_type() + def run(self, data_loaders: Sequence[DataLoader], workflow: List[tuple], max_iters: Optional[int] = None, **kwargs): assert isinstance(data_loaders, list) assert mmcv.is_list_of(workflow, tuple) assert len(data_loaders) == len(workflow) diff --git a/external/mmdetection/tests/ote_params_validation/test_ote_config_utils_params_validation.py b/external/mmdetection/tests/ote_params_validation/test_ote_config_utils_params_validation.py index 8f378452b93..5a2b5d11c12 100644 --- a/external/mmdetection/tests/ote_params_validation/test_ote_config_utils_params_validation.py +++ b/external/mmdetection/tests/ote_params_validation/test_ote_config_utils_params_validation.py @@ -6,7 +6,7 @@ import pytest from mmcv import Config -from mmdet.apis.ote.apis.detection.config_utils import ( +from detection_tasks.apis.detection.config_utils import ( cluster_anchors, config_from_string, config_to_string, @@ -22,7 +22,7 @@ set_data_classes, set_hyperparams, ) -from mmdet.apis.ote.apis.detection.configuration import OTEDetectionConfig +from detection_tasks.apis.detection.configuration import OTEDetectionConfig from ote_sdk.entities.datasets import DatasetEntity from ote_sdk.entities.label import Domain, LabelEntity diff --git a/external/mmdetection/tests/ote_params_validation/test_ote_data_utils_params_validation.py b/external/mmdetection/tests/ote_params_validation/test_ote_data_utils_params_validation.py index 2d861e9fdd3..4561e74ff14 100644 --- a/external/mmdetection/tests/ote_params_validation/test_ote_data_utils_params_validation.py +++ b/external/mmdetection/tests/ote_params_validation/test_ote_data_utils_params_validation.py @@ -6,7 +6,7 @@ import mmcv import pytest -from mmdet.apis.ote.extension.datasets.data_utils import ( +from detection_tasks.extension.datasets.data_utils import ( CocoDataset, LoadAnnotations, find_label_by_name, diff --git a/external/mmdetection/tests/ote_params_validation/test_ote_hooks_params_validation.py b/external/mmdetection/tests/ote_params_validation/test_ote_hooks_params_validation.py index 051247d0431..5a193161888 100644 --- a/external/mmdetection/tests/ote_params_validation/test_ote_hooks_params_validation.py +++ b/external/mmdetection/tests/ote_params_validation/test_ote_hooks_params_validation.py @@ -6,7 +6,7 @@ import pytest import torch.nn as nn from mmcv.runner import EpochBasedRunner -from mmdet.apis.ote.extension.utils.hooks import ( +from detection_tasks.extension.utils.hooks import ( CancelTrainingHook, EarlyStoppingHook, EnsureCorrectBestCheckpointHook, diff --git a/external/mmdetection/tests/ote_params_validation/test_ote_inference_task_params_validation.py b/external/mmdetection/tests/ote_params_validation/test_ote_inference_task_params_validation.py index 0f9097a6d1e..cbd76244a31 100644 --- a/external/mmdetection/tests/ote_params_validation/test_ote_inference_task_params_validation.py +++ b/external/mmdetection/tests/ote_params_validation/test_ote_inference_task_params_validation.py @@ -4,7 +4,7 @@ import pytest -from mmdet.apis.ote.apis.detection.inference_task import OTEDetectionInferenceTask +from detection_tasks.apis.detection.inference_task import OTEDetectionInferenceTask from ote_sdk.configuration.configurable_parameters import ConfigurableParameters from ote_sdk.entities.datasets import DatasetEntity from ote_sdk.entities.inference_parameters import InferenceParameters diff --git a/external/mmdetection/tests/ote_params_validation/test_ote_mmdataset_params_validation.py b/external/mmdetection/tests/ote_params_validation/test_ote_mmdataset_params_validation.py index 17b4d7fa77d..b35d2ab3e17 100644 --- a/external/mmdetection/tests/ote_params_validation/test_ote_mmdataset_params_validation.py +++ b/external/mmdetection/tests/ote_params_validation/test_ote_mmdataset_params_validation.py @@ -4,7 +4,7 @@ import numpy as np import pytest -from mmdet.apis.ote.extension.datasets.mmdataset import ( +from detection_tasks.extension.datasets.mmdataset import ( OTEDataset, get_annotation_mmdet_format, ) @@ -71,6 +71,8 @@ def test_get_annotation_mmdet_format_input_params_validation(self): ("labels", [label, unexpected_int]), # Unexpected integer is specified as "domain" parameter ("domain", unexpected_int), + # Unexpected string is specified as "min_size" parameter + ("min_size", "unexpected string"), ] check_value_error_exception_raised( correct_parameters=correct_values_dict, diff --git a/external/mmdetection/tests/ote_params_validation/test_ote_nncf_task_params_validation.py b/external/mmdetection/tests/ote_params_validation/test_ote_nncf_task_params_validation.py index 0802ae8fa5c..13d48024ab3 100644 --- a/external/mmdetection/tests/ote_params_validation/test_ote_nncf_task_params_validation.py +++ b/external/mmdetection/tests/ote_params_validation/test_ote_nncf_task_params_validation.py @@ -4,7 +4,7 @@ import pytest -from mmdet.apis.ote.apis.detection.nncf_task import OTEDetectionNNCFTask +from detection_tasks.apis.detection.nncf_task import OTEDetectionNNCFTask from ote_sdk.configuration.configurable_parameters import ConfigurableParameters from ote_sdk.entities.datasets import DatasetEntity from ote_sdk.entities.label_schema import LabelSchemaEntity @@ -69,7 +69,6 @@ def test_nncf_detection_task_optimize_params_validation(self): "optimization_type": OptimizationType.NNCF, "dataset": DatasetEntity(), "output_model": self.model(), - "optimization_parameters": None, } unexpected_str = "unexpected string" unexpected_values = [ diff --git a/external/mmdetection/tests/ote_params_validation/test_ote_openvino_task_params_validation.py b/external/mmdetection/tests/ote_params_validation/test_ote_openvino_task_params_validation.py index ead54bd4be1..a3633c2e731 100644 --- a/external/mmdetection/tests/ote_params_validation/test_ote_openvino_task_params_validation.py +++ b/external/mmdetection/tests/ote_params_validation/test_ote_openvino_task_params_validation.py @@ -6,8 +6,8 @@ import pytest from openvino.model_zoo.model_api.models import Model -from mmdet.apis.ote.apis.detection.configuration import OTEDetectionConfig -from mmdet.apis.ote.apis.detection.openvino_task import ( +from detection_tasks.apis.detection.configuration import OTEDetectionConfig +from detection_tasks.apis.detection.openvino_task import ( BaseInferencerWithConverter, OpenVINODetectionInferencer, OpenVINODetectionTask, @@ -101,7 +101,7 @@ def test_base_inferencer_with_converter_pre_process_params_validation(self): Check BaseInferencerWithConverter object "pre_process" method input parameters validation Input data: - BaseInferencerWithConverter object, "pre_process" method unexpected-type input parameters + BaseInferencerWithConverter object, "image" non-ndarray object Expected results: Test passes if ValueError exception is raised when unexpected type object is specified as @@ -109,7 +109,7 @@ def test_base_inferencer_with_converter_pre_process_params_validation(self): """ inferencer = MockBaseInferencer() with pytest.raises(ValueError): - inferencer.pre_process("unexpected string") # type: ignore + inferencer.pre_process(image="unexpected string") # type: ignore @e2e_pytest_unit def test_base_inferencer_with_converter_post_process_params_validation(self): @@ -155,7 +155,7 @@ def test_base_inferencer_with_converter_forward_params_validation(self): Check BaseInferencerWithConverter object "forward" method input parameters validation Input data: - BaseInferencerWithConverter object, "forward" method unexpected-type input parameters + BaseInferencerWithConverter object, "inputs" unexpected type object Expected results: Test passes if ValueError exception is raised when unexpected type object is specified as @@ -190,7 +190,7 @@ def test_openvino_detection_inferencer_init_params_validation(self): OpenVINODetectionInferencer object initialization parameter """ correct_values_dict = { - "hparams": OTEDetectionConfig(), + "hparams": OTEDetectionConfig("test header"), "label_schema": LabelSchemaEntity(), "model_file": "model data", } @@ -233,7 +233,7 @@ def test_openvino_mask_inferencer_init_params_validation(self): OpenVINOMaskInferencer object initialization parameter """ correct_values_dict = { - "hparams": OTEDetectionConfig(), + "hparams": OTEDetectionConfig("test header"), "label_schema": LabelSchemaEntity(), "model_file": "model data", } @@ -276,7 +276,7 @@ def test_openvino_rotated_rect_inferencer_init_params_validation(self): OpenVINORotatedRectInferencer object initialization parameter """ correct_values_dict = { - "hparams": OTEDetectionConfig(), + "hparams": OTEDetectionConfig("test header"), "label_schema": LabelSchemaEntity(), "model_file": "model data", } diff --git a/external/mmdetection/tests/ote_params_validation/test_ote_ote_utils_params_validation.py b/external/mmdetection/tests/ote_params_validation/test_ote_ote_utils_params_validation.py index 93ea4abb656..f0c73a72e85 100644 --- a/external/mmdetection/tests/ote_params_validation/test_ote_ote_utils_params_validation.py +++ b/external/mmdetection/tests/ote_params_validation/test_ote_ote_utils_params_validation.py @@ -3,7 +3,7 @@ # import pytest -from mmdet.apis.ote.apis.detection.ote_utils import ( +from detection_tasks.apis.detection.ote_utils import ( ColorPalette, generate_label_schema, get_task_class, @@ -108,7 +108,7 @@ def test_load_template_params_validation(self): Check "load_template" function input parameters validation Input data: - "load_template" function unexpected-type input parameters + "path" unexpected string with yaml file object Expected results: Test passes if ValueError exception is raised when unexpected type object is specified as @@ -138,7 +138,7 @@ def test_get_task_class_input_params_validation(self): Check "get_task_class" function input parameters validation Input data: - "get_task_class" function unexpected-type input parameters + "path" non string-type object Expected results: Test passes if ValueError exception is raised when unexpected type object is specified as diff --git a/external/mmdetection/tests/ote_params_validation/test_ote_pipelines_params_validation.py b/external/mmdetection/tests/ote_params_validation/test_ote_pipelines_params_validation.py index 295ef2d9e06..8ec743008c4 100644 --- a/external/mmdetection/tests/ote_params_validation/test_ote_pipelines_params_validation.py +++ b/external/mmdetection/tests/ote_params_validation/test_ote_pipelines_params_validation.py @@ -3,12 +3,15 @@ # import pytest -from mmdet.apis.ote.extension.utils.pipelines import ( +from detection_tasks.extension.utils.pipelines import ( LoadAnnotationFromOTEDataset, LoadImageFromOTEDataset, ) from ote_sdk.test_suite.e2e_test_system import e2e_pytest_unit +from ote_sdk.tests.parameters_validation.validation_helper import ( + check_value_error_exception_raised, +) class TestLoadImageFromOTEDatasetInputParamsValidation: @@ -67,18 +70,33 @@ def test_load_annotation_from_ote_dataset_init_params_validation(self): Test passes if ValueError exception is raised when unexpected type object is specified as LoadAnnotationFromOTEDataset object initialization parameter """ + correct_values_dict = { + "min_size": 1, + } unexpected_str = "unexpected string" - for parameter in [ - "with_bbox", - "with_label", - "with_mask", - "with_seg", - "poly2mask", - "with_text", - "domain" - ]: - with pytest.raises(ValueError): - LoadAnnotationFromOTEDataset(**{parameter: unexpected_str}) + unexpected_values = [ + # Unexpected string is specified as "min_size" parameter + ("min_size", unexpected_str), + # Unexpected string is specified as "with_bbox" parameter + ("with_bbox", unexpected_str), + # Unexpected string is specified as "with_label" parameter + ("with_label", unexpected_str), + # Unexpected string is specified as "with_mask" parameter + ("with_mask", unexpected_str), + # Unexpected string is specified as "with_seg" parameter + ("with_seg", unexpected_str), + # Unexpected string is specified as "poly2mask" parameter + ("poly2mask", unexpected_str), + # Unexpected string is specified as "with_text" parameter + ("with_text", unexpected_str), + # Unexpected string is specified as "domain" parameter + ("domain", unexpected_str), + ] + check_value_error_exception_raised( + correct_parameters=correct_values_dict, + unexpected_values=unexpected_values, + class_or_function=LoadAnnotationFromOTEDataset, + ) @e2e_pytest_unit def test_load_annotation_from_ote_dataset_call_params_validation(self): diff --git a/external/mmdetection/tests/ote_params_validation/test_ote_runner_params_validation.py b/external/mmdetection/tests/ote_params_validation/test_ote_runner_params_validation.py index 4430c9e102d..ceb56871d2b 100644 --- a/external/mmdetection/tests/ote_params_validation/test_ote_runner_params_validation.py +++ b/external/mmdetection/tests/ote_params_validation/test_ote_runner_params_validation.py @@ -6,7 +6,7 @@ import pytest import torch.nn as nn -from mmdet.apis.ote.extension.utils.runner import ( +from detection_tasks.extension.utils.runner import ( EpochRunnerWithCancel, IterBasedRunnerWithCancel, IterLoader, diff --git a/external/mmdetection/tests/ote_params_validation/test_ote_train_task_params_validation.py b/external/mmdetection/tests/ote_params_validation/test_ote_train_task_params_validation.py index 74addfe6e17..14d7a750fe6 100644 --- a/external/mmdetection/tests/ote_params_validation/test_ote_train_task_params_validation.py +++ b/external/mmdetection/tests/ote_params_validation/test_ote_train_task_params_validation.py @@ -4,7 +4,7 @@ import pytest -from mmdet.apis.ote.apis.detection.train_task import OTEDetectionTrainingTask +from detection_tasks.apis.detection.train_task import OTEDetectionTrainingTask from ote_sdk.configuration.configurable_parameters import ConfigurableParameters from ote_sdk.entities.datasets import DatasetEntity from ote_sdk.entities.label_schema import LabelSchemaEntity diff --git a/external/mmdetection/tests/test_ote_api.py b/external/mmdetection/tests/test_ote_api.py index ef3f0827a5f..016cc5f0a31 100644 --- a/external/mmdetection/tests/test_ote_api.py +++ b/external/mmdetection/tests/test_ote_api.py @@ -213,7 +213,7 @@ def test_cancel_training_detection(self): def progress_callback(progress: float, score: Optional[float] = None): training_progress_curve.append(progress) - train_parameters = TrainParameters + train_parameters = TrainParameters() train_parameters.update_progress = progress_callback # Test stopping after some time @@ -253,7 +253,7 @@ def test_training_progress_tracking(self): def progress_callback(progress: float, score: Optional[float] = None): training_progress_curve.append(progress) - train_parameters = TrainParameters + train_parameters = TrainParameters() train_parameters.update_progress = progress_callback output_model = ModelEntity( dataset, @@ -281,7 +281,7 @@ def test_nncf_optimize_progress_tracking(self): dataset, detection_environment.get_model_configuration(), ) - task.train(dataset, original_model, TrainParameters) + task.train(dataset, original_model, TrainParameters()) # Create NNCFTask detection_environment.model = original_model @@ -301,7 +301,7 @@ def progress_callback(progress: int): assert isinstance(progress, int) training_progress_curve.append(progress) - optimization_parameters = OptimizationParameters + optimization_parameters = OptimizationParameters() optimization_parameters.update_progress = progress_callback nncf_model = ModelEntity( dataset, @@ -329,7 +329,7 @@ def progress_callback(progress: int): assert isinstance(progress, int) inference_progress_curve.append(progress) - inference_parameters = InferenceParameters + inference_parameters = InferenceParameters() inference_parameters.update_progress = progress_callback task.infer(dataset.with_empty_annotations(), inference_parameters) @@ -352,7 +352,7 @@ def test_inference_task(self): dataset, detection_environment.get_model_configuration(), ) - train_task.train(dataset, trained_model, TrainParameters) + train_task.train(dataset, trained_model, TrainParameters()) performance_after_train = self.eval(train_task, trained_model, val_dataset) # Create InferenceTask