Skip to content

Commit 7b07e6b

Browse files
authored
Update MRCNN model export to include feature vector and saliency map (#4056)
1 parent 63f71fb commit 7b07e6b

File tree

7 files changed

+47
-11
lines changed

7 files changed

+47
-11
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ All notable changes to this project will be documented in this file.
9090
(<https://github.com/openvinotoolkit/training_extensions/pull/4042>)
9191
- Fix wrong indices setting in HLabelInfo
9292
(<https://github.com/openvinotoolkit/training_extensions/pull/4044>)
93+
- Add legacy template LiteHRNet_18 template
94+
(<https://github.com/openvinotoolkit/training_extensions/pull/4049>)
95+
- Model templates: rename model_status value 'DISCONTINUED' to 'OBSOLETE'
96+
(<https://github.com/openvinotoolkit/training_extensions/pull/4051>)
97+
- Enable export of feature vectors for semantic segmentation task
98+
(<https://github.com/openvinotoolkit/training_extensions/pull/4055>)
99+
- Update MRCNN model export to include feature vector and saliency map
100+
(<https://github.com/openvinotoolkit/training_extensions/pull/4056>)
101+
- Upgrade MAPI in 2.2
102+
(<https://github.com/openvinotoolkit/training_extensions/pull/4052>)
93103

94104
## \[v2.1.0\]
95105

src/otx/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Copyright (C) 2024 Intel Corporation
44
# SPDX-License-Identifier: Apache-2.0
55

6-
__version__ = "2.2.0rc9"
6+
__version__ = "2.2.0rc10"
77

88
import os
99
from pathlib import Path

src/otx/algo/instance_segmentation/maskrcnn.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def _exporter(self) -> OTXModelExporter:
7070
"opset_version": 11,
7171
"autograd_inlining": False,
7272
},
73-
output_names=["bboxes", "labels", "masks"],
73+
output_names=["bboxes", "labels", "masks", "feature_vector", "saliency_map"] if self.explain_mode else None,
7474
)
7575

7676
def load_from_otx_v1_ckpt(self, state_dict: dict, add_prefix: str = "model.") -> dict:

src/otx/algo/instance_segmentation/rtmdet_inst.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ def _exporter(self) -> OTXModelExporter:
6868
"opset_version": 11,
6969
"autograd_inlining": False,
7070
},
71+
# TODO(Eugene): Add XAI support for RTMDetInst
7172
output_names=["bboxes", "labels", "masks", "feature_vector", "saliency_map"] if self.explain_mode else None,
7273
)
7374

src/otx/algo/instance_segmentation/two_stage.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,19 +210,44 @@ def export(
210210
self,
211211
batch_inputs: torch.Tensor,
212212
batch_img_metas: list[dict],
213-
) -> tuple[torch.Tensor, ...]:
214-
"""Export for two stage detectors."""
215-
x = self.extract_feat(batch_inputs)
213+
explain_mode: bool,
214+
) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor] | dict:
215+
"""Export the model for ONNX/OpenVINO.
216+
217+
Args:
218+
batch_inputs (torch.Tensor): image tensor with shape (N, C, H, W).
219+
batch_img_metas (list[dict]): image information.
220+
explain_mode (bool): whether to return feature vector.
216221
222+
Returns:
223+
tuple[torch.Tensor, torch.Tensor, torch.Tensor] | dict:
224+
- bboxes (torch.Tensor): bounding boxes.
225+
- labels (torch.Tensor): labels.
226+
- masks (torch.Tensor): masks.
227+
- feature_vector (torch.Tensor, optional): feature vector.
228+
- saliency_map (torch.Tensor, optional): saliency map.
229+
"""
230+
x = self.extract_feat(batch_inputs)
217231
rpn_results_list = self.rpn_head.export(
218232
x,
219233
batch_img_metas,
220234
rescale=False,
221235
)
222-
223-
return self.roi_head.export(
236+
bboxes, labels, masks = self.roi_head.export(
224237
x,
225238
rpn_results_list,
226239
batch_img_metas,
227240
rescale=False,
228241
)
242+
243+
if explain_mode:
244+
feature_vector = self.feature_vector_fn(x)
245+
return {
246+
"bboxes": bboxes,
247+
"labels": labels,
248+
"masks": masks,
249+
"feature_vector": feature_vector,
250+
# create dummy tensor as model API supports saliency_map
251+
"saliency_map": torch.zeros(1),
252+
}
253+
return bboxes, labels, masks

src/otx/core/model/instance_segmentation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ def forward_for_tracing(self, inputs: Tensor) -> tuple[Tensor, ...]:
252252
"scale_factor": (1.0, 1.0),
253253
}
254254
meta_info_list = [meta_info] * len(inputs)
255-
return self.model.export(inputs, meta_info_list)
255+
return self.model.export(inputs, meta_info_list, explain_mode=self.explain_mode)
256256

257257
@property
258258
def _export_parameters(self) -> TaskLevelExportParameters:

tests/integration/api/test_xai.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ def test_predict_with_explain(
110110
if "dino" in model_name:
111111
pytest.skip("DINO is not supported.")
112112

113-
if "instance_segmentation" in recipe:
114-
# TODO(Eugene): figure out why instance segmentation model fails after decoupling.
115-
pytest.skip("There's issue with instance segmentation model. Skip for now.")
113+
if any(keyword in recipe for keyword in ["rtmdet_inst_tiny", "maskdino", "maskrcnn_r50_tv"]):
114+
# TODO(Eugene): inst-seg models not fully support yet.
115+
pytest.skip(f"There's issue with inst-seg: {recipe}. Skip for now.")
116116

117117
if "rtmdet_tiny" in recipe:
118118
# TODO (sungchul): enable xai for rtmdet_tiny (CVS-142651)

0 commit comments

Comments
 (0)