Skip to content

Commit 2274cea

Browse files
Songki Choisungmancjaegukhyuneugene123twsungmanc
authored
Merge back 1.2.3 -> 1.3.1 (#2192)
* Optimize counting train & inference speed and memory consumption (#2172) * Do not skip full img tile classifier + Fix Sequencial Export Issue (#2174) * Add warning message to tiling parameter (#2193) * Change the way to pad for instance-segmentation * Hotfix: use 0 confidence threshold when computing best threshold based on F1 * Fix possible bw issue in exportable code (#2212) * Fix ellipse load (#2214) --------- Signed-off-by: Songki Choi <[email protected]> Co-authored-by: Sungman Cho <[email protected]> Co-authored-by: jaegukhyun <[email protected]> Co-authored-by: Eugene Liu <[email protected]> Co-authored-by: sungmanc <[email protected]> Co-authored-by: Vladislav Sovrasov <[email protected]>
1 parent 34ff412 commit 2274cea

File tree

41 files changed

+814
-317
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+814
-317
lines changed

CHANGELOG.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file.
66

77
### Enhancements
88

9-
-
9+
- n/a
1010

1111
### Bug fixes
1212

@@ -46,6 +46,23 @@ All notable changes to this project will be documented in this file.
4646

4747
### Known issues
4848

49+
- OpenVINO(==2022.3) IR inference is not working well on 2-stage models (e.g. Mask-RCNN) exported from torch==1.13.1
50+
(working well up to torch==1.12.1) (<https://github.com/openvinotoolkit/training_extensions/issues/1906>)
51+
52+
## \[v1.2.3\]
53+
54+
### Bug fixes
55+
56+
- Hotfix: use 0 confidence threshold when computing best threshold based on F1
57+
58+
## \[v1.2.2\]
59+
60+
### Enhancements
61+
62+
- Improve warning message for tiling configurable parameter
63+
64+
### Known issues
65+
4966
- OpenVINO(==2022.3) IR inference is not working well on 2-stage models (e.g. Mask-RCNN) exported from torch==1.13.1
5067
(working well up to torch==1.12.1) (<https://github.com/openvinotoolkit/training_extensions/issues/1906>)
5168

@@ -57,12 +74,14 @@ All notable changes to this project will be documented in this file.
5774
- Integrate new ignored loss in semantic segmentation (<https://github.com/openvinotoolkit/training_extensions/pull/2065>, <https://github.com/openvinotoolkit/training_extensions/pull/2111>)
5875
- Optimize YOLOX data pipeline (<https://github.com/openvinotoolkit/training_extensions/pull/2075>)
5976
- Tiling Spatial Concatenation for OpenVINO IR (<https://github.com/openvinotoolkit/training_extensions/pull/2052>)
77+
- Optimize counting train & inference speed and memory consumption (<https://github.com/openvinotoolkit/training_extensions/pull/2172>)
6078

6179
### Bug fixes
6280

6381
- Bug fix: value of validation variable is changed after auto decrease batch size (<https://github.com/openvinotoolkit/training_extensions/pull/2053>)
6482
- Fix tiling 0 stride issue in parameter adapter (<https://github.com/openvinotoolkit/training_extensions/pull/2078>)
6583
- Fix Tiling NNCF (<https://github.com/openvinotoolkit/training_extensions/pull/2081>)
84+
- Do not skip full img tile classifier + Fix Sequencial Export Issue (<https://github.com/openvinotoolkit/training_extensions/pull/2174>)
6685

6786
## \[v1.2.0\]
6887

docs/source/guide/release_notes/index.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
Releases
22
========
33

4+
***************
5+
[v1.3.0] (2Q23)
6+
***************
7+
8+
- Support direct annotation input for COCO format
9+
- Action task supports multi GPU training
10+
- Support storage cache in Apache Arrow using Datumaro for action tasks
11+
- Add a simplified greedy labels postprocessing for hierarchical classification
12+
- Support auto adapting batch size
13+
- Support auto adapting num_workers
14+
- Support noisy label detection for detection tasks
15+
416
*************
517
v1.2.0 (1Q23)
618
*************

otx/algorithms/common/adapters/mmcv/tasks/exporter.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ def run(self, cfg, **kwargs): # noqa: C901
3535
pipeline = dataset.get("pipeline", [])
3636
pipeline += cfg.data.test.get("pipeline", [])
3737
cfg.data.test.pipeline = pipeline
38+
for pipeline in cfg.data.test.pipeline:
39+
if pipeline.get("transforms", None):
40+
transforms = pipeline.transforms
41+
for transform in transforms:
42+
if transform.type == "Collect":
43+
for collect_key in transform["keys"]:
44+
if collect_key != "img":
45+
transform["keys"].remove(collect_key)
3846

3947
model_builder = kwargs.get("model_builder")
4048
try:

otx/algorithms/common/adapters/mmdeploy/apis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ def extract_partition(
261261
model_name: str = "model",
262262
):
263263
"""Function for extracting partition."""
264-
264+
reset_mark_function_count()
265265
model_onnx = MMdeployExporter.torch2onnx(
266266
output_dir,
267267
input_data,

otx/algorithms/common/configs/training_base.py

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,13 @@ class BasePostprocessing(ParameterGroup):
227227
affects_outcome_of=ModelLifecycle.INFERENCE,
228228
)
229229

230+
use_ellipse_shapes = configurable_boolean(
231+
default_value=False,
232+
header="Use ellipse shapes",
233+
description="Use direct ellipse shape in inference instead of polygon from mask",
234+
affects_outcome_of=ModelLifecycle.INFERENCE,
235+
)
236+
230237
@attrs
231238
class BaseNNCFOptimization(ParameterGroup):
232239
"""BaseNNCFOptimization for OTX Algorithms."""
@@ -328,7 +335,9 @@ class BaseTilingParameters(ParameterGroup):
328335
default_value=False,
329336
header="Enable tiling",
330337
description="Set to True to allow tiny objects to be better detected.",
331-
warning="Tiling trades off speed for accuracy as it increases the number of images to be processed.",
338+
warning="Tiling trades off speed for accuracy as it increases the number of images to be processed. "
339+
"Important: In the current version, depending on the dataset size and the available hardware resources, "
340+
"a model may not train successfully when tiling is enabled.",
332341
affects_outcome_of=ModelLifecycle.NONE,
333342
)
334343

@@ -357,7 +366,7 @@ class BaseTilingParameters(ParameterGroup):
357366
description="Tile Image Size",
358367
default_value=400,
359368
min_value=100,
360-
max_value=1024,
369+
max_value=4096,
361370
affects_outcome_of=ModelLifecycle.NONE,
362371
)
363372

@@ -375,7 +384,7 @@ class BaseTilingParameters(ParameterGroup):
375384
description="Max object per image",
376385
default_value=1500,
377386
min_value=1,
378-
max_value=10000,
387+
max_value=5000,
379388
affects_outcome_of=ModelLifecycle.NONE,
380389
)
381390

@@ -395,4 +404,26 @@ class BaseTilingParameters(ParameterGroup):
395404
affects_outcome_of=ModelLifecycle.NONE,
396405
)
397406

407+
tile_sampling_ratio = configurable_float(
408+
header="Sampling Ratio for entire tiling",
409+
description="Since tiling train and validation to all tile from large image, "
410+
"usually it takes lots of time than normal training."
411+
"The tile_sampling_ratio is ratio for sampling entire tile dataset."
412+
"Sampling tile dataset would save lots of time for training and validation time."
413+
"Note that sampling will be applied to training and validation dataset, not test dataset.",
414+
default_value=1.0,
415+
min_value=0.000001,
416+
max_value=1.0,
417+
affects_outcome_of=ModelLifecycle.NONE,
418+
)
419+
420+
object_tile_ratio = configurable_float(
421+
header="Object tile ratio",
422+
description="The desired ratio of min object size and tile size.",
423+
default_value=0.03,
424+
min_value=0.00,
425+
max_value=1.00,
426+
affects_outcome_of=ModelLifecycle.NONE,
427+
)
428+
398429
tiling_parameters = add_parameter_group(BaseTilingParameters)

otx/algorithms/detection/adapters/mmdet/datasets/dataset.py

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
# See the License for the specific language governing permissions
1515
# and limitations under the License.
1616

17-
import tempfile
1817
from collections import OrderedDict
1918
from copy import copy
2019
from typing import Any, Dict, List, Sequence, Tuple, Union
@@ -32,6 +31,7 @@
3231
from otx.api.entities.dataset_item import DatasetItemEntity
3332
from otx.api.entities.datasets import DatasetEntity
3433
from otx.api.entities.label import Domain, LabelEntity
34+
from otx.api.entities.subset import Subset
3535
from otx.api.utils.shape_factory import ShapeFactory
3636

3737
from .tiling import Tile
@@ -274,6 +274,7 @@ def evaluate( # pylint: disable=too-many-branches
274274
if metric not in allowed_metrics:
275275
raise KeyError(f"metric {metric} is not supported")
276276
annotations = [self.get_ann_info(i) for i in range(len(self))]
277+
assert len(annotations) == len(results), "annotation length does not match prediction results"
277278
iou_thrs = [iou_thr] if isinstance(iou_thr, float) else iou_thr
278279
if metric == "mAP":
279280
assert isinstance(iou_thrs, list)
@@ -306,7 +307,7 @@ def evaluate( # pylint: disable=too-many-branches
306307

307308
# pylint: disable=too-many-arguments
308309
@DATASETS.register_module()
309-
class ImageTilingDataset:
310+
class ImageTilingDataset(OTXDetDataset):
310311
"""A wrapper of tiling dataset.
311312
312313
Suitable for training small object dataset. This wrapper composed of `Tile`
@@ -330,6 +331,8 @@ class ImageTilingDataset:
330331
after NMS, only top max_per_img will be kept. Defaults to 200.
331332
max_annotation (int, optional): Limit the number of ground truth by
332333
randomly select 5000 due to RAM OOM. Defaults to 5000.
334+
sampling_ratio (flaot): Ratio for sampling entire tile dataset.
335+
include_full_img (bool): Whether to include full image in the dataset.
333336
"""
334337

335338
def __init__(
@@ -344,28 +347,29 @@ def __init__(
344347
max_annotation=5000,
345348
filter_empty_gt=True,
346349
test_mode=False,
350+
sampling_ratio=1.0,
351+
include_full_img=False,
347352
):
348353
self.dataset = build_dataset(dataset)
349354
self.CLASSES = self.dataset.CLASSES
350-
self.tmp_dir = tempfile.TemporaryDirectory() # pylint: disable=consider-using-with
351355

352356
self.tile_dataset = Tile(
353357
self.dataset,
354358
pipeline,
355-
tmp_dir=self.tmp_dir,
356359
tile_size=tile_size,
357360
overlap=overlap_ratio,
358361
min_area_ratio=min_area_ratio,
359362
iou_threshold=iou_threshold,
360363
max_per_img=max_per_img,
361364
max_annotation=max_annotation,
362-
filter_empty_gt=False if test_mode else filter_empty_gt,
365+
filter_empty_gt=filter_empty_gt if self.dataset.otx_dataset[0].subset != Subset.TESTING else False,
366+
sampling_ratio=sampling_ratio if self.dataset.otx_dataset[0].subset != Subset.TESTING else 1.0,
367+
include_full_img=include_full_img if self.dataset.otx_dataset[0].subset != Subset.TESTING else True,
363368
)
364369
self.flag = np.zeros(len(self), dtype=np.uint8)
365370
self.pipeline = Compose(pipeline)
366371
self.test_mode = test_mode
367372
self.num_samples = len(self.dataset) # number of original samples
368-
self.merged_results: Union[List[Tuple[np.ndarray, list]], List[np.ndarray]] = []
369373

370374
def __len__(self) -> int:
371375
"""Get the length of the dataset."""
@@ -383,18 +387,16 @@ def __getitem__(self, idx: int) -> Dict:
383387
"""
384388
return self.pipeline(self.tile_dataset[idx])
385389

386-
def evaluate(self, results, **kwargs) -> Dict[str, float]:
387-
"""Evaluation on Tile dataset.
390+
def get_ann_info(self, idx):
391+
"""Get annotation information of a tile.
388392
389393
Args:
390-
results (list[list | tuple]): Testing results of the dataset.
391-
**kwargs: Addition keyword arguments.
394+
idx (int): Index of data.
392395
393396
Returns:
394-
dict[str, float]: evaluation metric.
397+
dict: Annotation information of a tile.
395398
"""
396-
self.merged_results = self.tile_dataset.merge(results)
397-
return self.dataset.evaluate(self.merged_results, **kwargs)
399+
return self.tile_dataset.get_ann_info(idx)
398400

399401
def merge(self, results) -> Union[List[Tuple[np.ndarray, list]], List[np.ndarray]]:
400402
"""Merge tile-level results to image-level results.
@@ -405,10 +407,4 @@ def merge(self, results) -> Union[List[Tuple[np.ndarray, list]], List[np.ndarray
405407
Returns:
406408
merged_results (list[list | tuple]): Merged results of the dataset.
407409
"""
408-
self.merged_results = self.tile_dataset.merge(results)
409-
return self.merged_results
410-
411-
def __del__(self):
412-
"""Delete the temporary directory when the object is deleted."""
413-
if getattr(self, "tmp_dir", False):
414-
self.tmp_dir.cleanup()
410+
return self.tile_dataset.merge(results)

0 commit comments

Comments
 (0)