Skip to content

Commit 85ce846

Browse files
sungmancjaegukhyun
andauthored
Add supcon seg for regression (#2177)
* Fix iseg e2e (#2173) * Add supcon seg for regression * Fix det e2e (#2176) * Fix det e2e * Fix mypy * Fix precommit * Update otx/algorithms/segmentation/configs/ocr_lite_hrnet_18/supcon/__init__.py * Update otx/algorithms/segmentation/configs/ocr_lite_hrnet_18/supcon/model.py --------- Co-authored-by: Jaeguk Hyun <[email protected]>
1 parent d506b00 commit 85ce846

File tree

6 files changed

+226
-0
lines changed

6 files changed

+226
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
"""Initialization of OCR-Lite-HRnet-18 model for SupCon Segmentation Task."""
2+
3+
# Copyright (C) 2022 Intel Corporation
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions
15+
# and limitations under the License.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""Data Pipeline of HR-Net model for Segmentation Task."""
2+
3+
# Copyright (C) 2023 Intel Corporation
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions
15+
# and limitations under the License.
16+
17+
# pylint: disable=invalid-name
18+
_base_ = ["../../base/data/supcon/data_pipeline.py"]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Hyperparameters.
2+
hyper_parameters:
3+
parameter_overrides:
4+
learning_parameters:
5+
enable_supcon:
6+
default_value: True
7+
learning_rate_warmup_iters:
8+
default_value: 50
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
"""Model configuration of OCR-Lite-HRnet-18 model for SupCon Segmentation Task."""
2+
3+
4+
# Copyright (C) 2022 Intel Corporation
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions
16+
# and limitations under the License.
17+
18+
# pylint: disable=invalid-name
19+
20+
_base_ = [
21+
"../../../../../recipes/stages/segmentation/supcon.py",
22+
"../../../../common/adapters/mmcv/configs/backbones/lite_hrnet_18.py",
23+
]
24+
25+
model = dict(
26+
type="SupConDetConB",
27+
pretrained=(
28+
"https://storage.openvinotoolkit.org/repositories/"
29+
"openvino_training_extensions/models/custom_semantic_segmentation/"
30+
"litehrnet18_imagenet1k_rsc.pth"
31+
),
32+
num_classes=256,
33+
num_samples=16,
34+
downsample=4,
35+
input_transform="resize_concat",
36+
in_index=[0, 1, 2, 3],
37+
neck=dict(
38+
type="SelfSLMLP",
39+
in_channels=600,
40+
hid_channels=256,
41+
out_channels=128,
42+
norm_cfg=dict(type="BN1d", requires_grad=True),
43+
with_avg_pool=False,
44+
),
45+
head=dict(
46+
type="DetConHead",
47+
predictor=dict(
48+
type="SelfSLMLP",
49+
in_channels=128,
50+
hid_channels=256,
51+
out_channels=128,
52+
norm_cfg=dict(type="BN1d", requires_grad=True),
53+
with_avg_pool=False,
54+
),
55+
loss_cfg=dict(type="DetConLoss", temperature=0.1),
56+
),
57+
decode_head=dict(
58+
type="FCNHead",
59+
in_channels=[40, 80, 160, 320],
60+
in_index=[0, 1, 2, 3],
61+
input_transform="multiple_select",
62+
channels=40,
63+
kernel_size=1,
64+
num_convs=1,
65+
concat_input=False,
66+
dropout_ratio=-1,
67+
num_classes=2,
68+
norm_cfg=dict(type="BN", requires_grad=True),
69+
align_corners=False,
70+
enable_aggregator=True,
71+
loss_decode=[
72+
dict(
73+
type="CrossEntropyLoss",
74+
use_sigmoid=False,
75+
loss_weight=1.0,
76+
),
77+
],
78+
),
79+
)
80+
81+
load_from = None
82+
83+
resume_from = None
84+
85+
fp16 = dict(loss_scale=512.0)

tests/regression/regression_config.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@
9292
"--val-data-roots": "segmentation/regression_voc_cls_decr/val",
9393
"--test-data-roots": "segmentation/regression_voc_cls_decr/test",
9494
"--input": "segmentation/regression_voc_cls_decr/test/images"
95+
},
96+
"supcon": {
97+
"--train-data-roots": "segmentation/regression_voc_cls_decr/train",
98+
"--val-data-roots": "segmentation/regression_voc_cls_decr/val",
99+
"--test-data-roots": "segmentation/regression_voc_cls_decr/test"
95100
}
96101
},
97102
"class_incr": {
@@ -425,6 +430,14 @@
425430
"Lite-HRNet-18": 0.302,
426431
"Lite-HRNet-x-mod3": 0.041
427432
}
433+
},
434+
"supcon": {
435+
"train": {
436+
"Lite-HRNet-s-mod2": 0.691,
437+
"Lite-HRNet-18-mod2": 0.676,
438+
"Lite-HRNet-18": 0.682,
439+
"Lite-HRNet-x-mod3": 0.698
440+
}
428441
}
429442
},
430443
"class_incr": {
@@ -1601,6 +1614,14 @@
16011614
"Lite-HRNet-18": 446.99,
16021615
"Lite-HRNet-x-mod3": 667.493
16031616
}
1617+
},
1618+
"supcon": {
1619+
"train": {
1620+
"Lite-HRNet-s-mod2": 241.88,
1621+
"Lite-HRNet-18-mod2": 279.19,
1622+
"Lite-HRNet-18": 279.71,
1623+
"Lite-HRNet-x-mod3": 454.31
1624+
}
16041625
}
16051626
},
16061627
"class_incr": {
@@ -1993,6 +2014,14 @@
19932014
"Lite-HRNet-18": 43.046,
19942015
"Lite-HRNet-x-mod3": 59.053
19952016
}
2017+
},
2018+
"supcon": {
2019+
"train": {
2020+
"Lite-HRNet-s-mod2": 13.835,
2021+
"Lite-HRNet-18-mod2": 16.39,
2022+
"Lite-HRNet-18": 16.23,
2023+
"Lite-HRNet-x-mod3": 26.549
2024+
}
19962025
}
19972026
},
19982027
"class_incr": {

tests/regression/semantic_segmentation/test_segmentation.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,3 +415,74 @@ def test_pot_optimize_eval(self, template, tmp_dir_path):
415415
result_dict[TASK_TYPE][self.label_type][TRAIN_TYPE]["pot"].append(self.performance)
416416

417417
assert test_result["passed"] is True, test_result["log"]
418+
419+
420+
class TestRegressionSupconSegmentation:
421+
def setup_method(self):
422+
self.label_type = "supcon"
423+
self.performance = {}
424+
425+
def teardown_method(self):
426+
with open(f"{result_dir}/result.json", "w") as result_file:
427+
json.dump(result_dict, result_file, indent=4)
428+
429+
@e2e_pytest_component
430+
@pytest.mark.parametrize("template", templates, ids=templates_ids)
431+
def test_otx_train(self, template, tmp_dir_path):
432+
self.performance[template.name] = {}
433+
434+
tmp_dir_path = tmp_dir_path / "supcon_seg"
435+
config_supcon = load_regression_configuration(otx_dir, TASK_TYPE, TRAIN_TYPE, self.label_type)
436+
args_supcon = config_supcon["data_path"]
437+
438+
args_supcon["train_params"] = [
439+
"params",
440+
"--learning_parameters.num_iters",
441+
REGRESSION_TEST_EPOCHS,
442+
"--learning_parameters.enable_supcon",
443+
"True",
444+
]
445+
# Supcon
446+
train_start_time = timer()
447+
otx_train_testing(template, tmp_dir_path, otx_dir, args_supcon)
448+
train_elapsed_time = timer() - train_start_time
449+
450+
# Evaluation with supcon + supervised training
451+
infer_start_time = timer()
452+
test_result = regression_eval_testing(
453+
template,
454+
tmp_dir_path,
455+
otx_dir,
456+
args_supcon,
457+
config_supcon["regression_criteria"]["train"],
458+
self.performance[template.name],
459+
)
460+
infer_elapsed_time = timer() - infer_start_time
461+
462+
self.performance[template.name][TIME_LOG["train_time"]] = round(train_elapsed_time, 3)
463+
self.performance[template.name][TIME_LOG["infer_time"]] = round(infer_elapsed_time, 3)
464+
result_dict[TASK_TYPE][self.label_type][TRAIN_TYPE]["train"].append(self.performance)
465+
466+
assert test_result["passed"] is True, test_result["log"]
467+
468+
@e2e_pytest_component
469+
@pytest.mark.parametrize("template", templates, ids=templates_ids)
470+
def test_otx_train_kpi_test(self, template):
471+
config_supcon = load_regression_configuration(otx_dir, TASK_TYPE, TRAIN_TYPE, self.label_type)
472+
results = result_dict[TASK_TYPE][self.label_type][TRAIN_TYPE]["train"]
473+
performance = get_template_performance(results, template)
474+
475+
kpi_train_result = regression_train_time_testing(
476+
train_time_criteria=config_supcon["kpi_e2e_train_time_criteria"]["train"],
477+
e2e_train_time=performance[template.name][TIME_LOG["train_time"]],
478+
template=template,
479+
)
480+
481+
kpi_eval_result = regression_eval_time_testing(
482+
eval_time_criteria=config_supcon["kpi_e2e_eval_time_criteria"]["train"],
483+
e2e_eval_time=performance[template.name][TIME_LOG["infer_time"]],
484+
template=template,
485+
)
486+
487+
assert kpi_train_result["passed"] is True, kpi_train_result["log"]
488+
assert kpi_eval_result["passed"] is True, kpi_eval_result["log"]

0 commit comments

Comments
 (0)