Skip to content

Commit

Permalink
Align label order between Geti and OTX (#2369)
Browse files Browse the repository at this point in the history
* align label order

* align with pre-commit

* update CHANGELOG.md

* deal with edge case

* update type hint
  • Loading branch information
eunwoosh authored Jul 19, 2023
1 parent 0c4be3c commit 85bfe9f
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ All notable changes to this project will be documented in this file.

- Fix the bug that auto adapt batch size is unavailable with IterBasedRunner (<https://github.com/openvinotoolkit/training_extensions/pull/2182>)
- Fix the bug that learning rate isn't scaled when multi-GPU trianing is enabled(<https://github.com/openvinotoolkit/training_extensions/pull/2254>)
- Fix the bug that label order is misaligned when model is deployed from Geti (<https://github.com/openvinotoolkit/training_extensions/pull/2369>)

### Known issues

Expand Down
10 changes: 5 additions & 5 deletions src/otx/api/entities/label_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
logger = logging.getLogger(__name__)


def natural_sort_label_id(target: Union[ID, LabelEntity, ScoredLabel]) -> List:
def natural_sort_label_id(target: Union[ID, LabelEntity, ScoredLabel]) -> List[Union[int, str]]:
"""Generates a natural sort key for a LabelEntity object based on its ID.
Args:
target (Union[ID, LabelEntity]): The ID or LabelEntity or ScoredLabel object to be sorted.
Returns:
List[int]: A list of integers representing the numeric substrings in the ID
List[Union[int, str]]: A list of integers representing the numeric substrings in the ID
in the order they appear.
Example:
Expand All @@ -41,9 +41,9 @@ def natural_sort_label_id(target: Union[ID, LabelEntity, ScoredLabel]) -> List:

if isinstance(target, (LabelEntity, ScoredLabel)):
target = target.id_
if isinstance(target, int):
return [target]
return [int(t) if t.isdigit() else t for t in re.split(r"(\d+)", target)]
if isinstance(target, str) and target.isdecimal():
return ["", int(target)] # "" is added for the case where id of some lables is None
return [target]


class LabelGroupExistsException(ValueError):
Expand Down
25 changes: 24 additions & 1 deletion tests/unit/api/entities/test_label_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#

import pytest
from networkx.classes.reportviews import EdgeDataView, NodeView, OutMultiEdgeDataView
from networkx.classes.reportviews import NodeView, OutMultiEdgeDataView

from otx.api.entities.color import Color
from otx.api.entities.id import ID
Expand All @@ -19,11 +19,34 @@
LabelSchemaEntity,
LabelTree,
ScoredLabel,
natural_sort_label_id,
)
from tests.unit.api.constants.components import OtxSdkComponent
from tests.unit.api.constants.requirements import Requirements


def get_label_entity(id_val: str):
return LabelEntity(name=id_val, domain=Domain.DETECTION, id=ID(id_val))


def get_scored_label(id_val: str):
return ScoredLabel(label=get_label_entity(id_val))


@pytest.mark.priority_medium
@pytest.mark.unit
@pytest.mark.reqids(Requirements.REQ_1)
@pytest.mark.parametrize("id_val", ["3", "fake1name2"])
@pytest.mark.parametrize("target_class", [ID, get_label_entity, get_scored_label])
def test_natural_sort_label_id(id_val: str, target_class):
target = target_class(id_val)

if id_val.isdecimal():
assert natural_sort_label_id(target) == ["", int(id_val)]
else:
assert natural_sort_label_id(target) == [id_val]


@pytest.mark.components(OtxSdkComponent.OTX_API)
class TestLabelSchema:
@pytest.mark.priority_medium
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,6 @@ def test_classification_to_annotation_init(self):
)
label_schema = LabelSchemaEntity(label_groups=[label_group, other_label_group])
converter = ClassificationToAnnotationConverter(label_schema=label_schema)
assert converter.labels == non_empty_labels + other_non_empty_labels
assert not converter.empty_label
assert converter.label_schema == label_schema
assert converter.hierarchical
Expand Down

0 comments on commit 85bfe9f

Please sign in to comment.