Skip to content

Add Classification and Semantic Segmentation tasks for Ultralytics#6941

Open
kprokofi wants to merge 19 commits into
developfrom
kprokofi/extend-yolo-tasks
Open

Add Classification and Semantic Segmentation tasks for Ultralytics#6941
kprokofi wants to merge 19 commits into
developfrom
kprokofi/extend-yolo-tasks

Conversation

@kprokofi

Copy link
Copy Markdown
Contributor

Summary

How to test

Checklist

  • The PR title and description are clear and descriptive
  • I have manually tested the changes
  • All changes are covered by automated tests
  • All related issues are linked to this PR (if applicable)
  • Documentation has been updated (if applicable)

@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown

⏱️ Backend import time — app.main

Accelerator Cumulative (s) Self (s)
cpu 3.917 0.003
xpu 4.689 0.004
cuda 5.052 0.004

@github-actions github-actions Bot added TEST Any changes in tests DOC Improvements or additions to documentation Geti Library Issues related to Geti Library (OTX) labels Jun 30, 2026
@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown

🐳 Docker image sizes

Device Size
cpu 4013.2 MB (3.92 GB)
xpu 10801.8 MB (10.55 GB)
cuda 10208.4 MB (9.97 GB)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the library/ Ultralytics backend integration to support classification (multi-class + multi-label) and semantic segmentation, aligning training/validation/export paths with GetiTune’s DataModule-driven workflow.

Changes:

  • Added Ultralytics trainers/validators/models for classification and semantic segmentation, plus torchmetrics-based evaluation for these tasks.
  • Refactored the Ultralytics dataset adapter/validator plumbing from include_masks to a more explicit task_kind dispatch (detect, segment, classify, multilabel, semantic).
  • Added new Ultralytics recipes for YOLO26 classification and semantic segmentation variants, and expanded unit tests for the new task support.

Reviewed changes

Copilot reviewed 43 out of 43 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
library/tests/unit/backend/ultralytics/test_models.py Adds unit tests for the semantic segmentation model wrapper.
library/tests/unit/backend/ultralytics/test_exporter.py Tests exporter metadata mapping for semantic segmentation.
library/tests/unit/backend/ultralytics/test_data_bridge.py Adds adapter/collate tests for semantic segmentation and segment-mode semantic masks.
library/tests/unit/backend/ultralytics/test_configurator.py Updates “unsupported task” expectations and validates semantic segmentation recipes load.
library/src/getitune/recipe/semantic_segmentation/yolo26_n_sem.yaml Adds YOLO26-N semantic segmentation recipe.
library/src/getitune/recipe/semantic_segmentation/yolo26_s_sem.yaml Adds YOLO26-S semantic segmentation recipe.
library/src/getitune/recipe/semantic_segmentation/yolo26_m_sem.yaml Adds YOLO26-M semantic segmentation recipe.
library/src/getitune/recipe/semantic_segmentation/yolo26_l_sem.yaml Adds YOLO26-L semantic segmentation recipe.
library/src/getitune/recipe/semantic_segmentation/yolo26_x_sem.yaml Adds YOLO26-X semantic segmentation recipe.
library/src/getitune/recipe/classification/multi_class_cls/yolo26_n_cls.yaml Adds YOLO26-N multi-class classification recipe.
library/src/getitune/recipe/classification/multi_class_cls/yolo26_s_cls.yaml Adds YOLO26-S multi-class classification recipe.
library/src/getitune/recipe/classification/multi_class_cls/yolo26_m_cls.yaml Adds YOLO26-M multi-class classification recipe.
library/src/getitune/recipe/classification/multi_class_cls/yolo26_l_cls.yaml Adds YOLO26-L multi-class classification recipe.
library/src/getitune/recipe/classification/multi_class_cls/yolo26_x_cls.yaml Adds YOLO26-X multi-class classification recipe.
library/src/getitune/recipe/classification/multi_label_cls/yolo26_n_cls.yaml Adds YOLO26-N multi-label classification recipe.
library/src/getitune/recipe/classification/multi_label_cls/yolo26_s_cls.yaml Adds YOLO26-S multi-label classification recipe.
library/src/getitune/recipe/classification/multi_label_cls/yolo26_m_cls.yaml Adds YOLO26-M multi-label classification recipe.
library/src/getitune/recipe/classification/multi_label_cls/yolo26_l_cls.yaml Adds YOLO26-L multi-label classification recipe.
library/src/getitune/recipe/classification/multi_label_cls/yolo26_x_cls.yaml Adds YOLO26-X multi-label classification recipe.
library/src/getitune/backend/ultralytics/validators/base.py Switches adapter dispatch from _include_masks to _task_kind.
library/src/getitune/backend/ultralytics/validators/detection.py Sets _task_kind for detection validator.
library/src/getitune/backend/ultralytics/validators/instance_segmentation.py Sets _task_kind for instance segmentation validator.
library/src/getitune/backend/ultralytics/validators/classification.py Adds classification and multi-label classification validators.
library/src/getitune/backend/ultralytics/validators/semantic_segmentation.py Adds semantic segmentation validator with mask-shape bookkeeping.
library/src/getitune/backend/ultralytics/validators/init.py Exposes new validators in the package API.
library/src/getitune/backend/ultralytics/trainers/base.py Switches adapter dispatch from _include_masks to _task_kind.
library/src/getitune/backend/ultralytics/trainers/detection.py Sets _task_kind for detection trainer.
library/src/getitune/backend/ultralytics/trainers/instance_segmentation.py Sets _task_kind for instance segmentation trainer.
library/src/getitune/backend/ultralytics/trainers/classification.py Adds classification and multi-label classification trainers.
library/src/getitune/backend/ultralytics/trainers/semantic_segmentation.py Adds semantic segmentation trainer.
library/src/getitune/backend/ultralytics/trainers/init.py Exposes new trainers in the package API.
library/src/getitune/backend/ultralytics/models/classification.py Adds Ultralytics model wrappers for multi-class and multi-label classification.
library/src/getitune/backend/ultralytics/models/criterion.py Adds BCE loss + sigmoid inference head wiring for multi-label classification.
library/src/getitune/backend/ultralytics/models/semantic_segmentation.py Adds Ultralytics semantic segmentation model wrapper.
library/src/getitune/backend/ultralytics/models/init.py Exposes new model wrappers in the package API.
library/src/getitune/backend/ultralytics/data/adapter.py Adds task-kind dispatch and per-task item builders, including semantic/classification support.
library/src/getitune/backend/ultralytics/data/collate.py Adds collate functions for classification, multi-label, and semantic segmentation.
library/src/getitune/backend/ultralytics/data/init.py Re-exports new collate utilities.
library/src/getitune/backend/ultralytics/exporter/exporter.py Extends task metadata mapping to classification + semantic segmentation.
library/src/getitune/backend/ultralytics/engine.py Adds classification/semantic torchmetrics evaluation paths and improves metric flattening.
library/src/getitune/backend/ultralytics/tools/utils.py Registers recipe subdirectories and supported task types for the new tasks.
library/src/getitune/backend/ultralytics/README.md Documents newly supported Ultralytics tasks/models (table needs follow-up tweaks).
library/src/getitune/backend/ultralytics/init.py Exposes new models at backend package level.
Comments suppressed due to low confidence (1)

library/src/getitune/backend/ultralytics/engine.py:1092

  • _format_torchmetrics_results() intends to skip auxiliary metric keys like classes/map_per_class, but the current check compares the full prefixed path (e.g. test/classes) against _skip_keys (e.g. classes), so the skip never triggers and the function relies on the non-scalar fallback/logging instead.
        Adds keys like ``val/precision/<ClassName>``, ``val/recall/<ClassName>``,
        ``val/map_50/<ClassName>``, ``val/map/<ClassName>`` to *metrics* in-place.
        """
        names = getattr(results, "names", None)

Comment thread library/src/getitune/backend/ultralytics/data/adapter.py Outdated
Comment thread library/src/getitune/backend/ultralytics/README.md
Comment thread library/src/getitune/backend/ultralytics/models/classification.py
kprokofi and others added 2 commits July 13, 2026 12:33
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Comment thread library/src/getitune/backend/ultralytics/data/adapter.py Outdated
Comment thread library/src/getitune/backend/ultralytics/data/adapter.py
Comment thread library/src/getitune/backend/ultralytics/models/criterion.py Outdated
@github-actions github-actions Bot added the Geti Backend Issues related to the Geti application server label Jul 14, 2026
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown

📊 Test coverage report

Metric Coverage
Lines 60.5%
Functions 57.0%
Branches 52.4%
Statements 60.1%

@kprokofi
kprokofi marked this pull request as ready for review July 15, 2026 08:10
@kprokofi
kprokofi requested review from a team as code owners July 15, 2026 08:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 69 out of 70 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (7)

library/tests/unit/backend/ultralytics/tools/test_configurator.py:107

  • This path points to library/tests/unit/assets/..., which does not exist in this repo; as a result the test will always skip instead of exercising the DataModule path. library/tests/assets/... is at Path(__file__).resolve().parents[4] / "assets".
    library/tests/unit/backend/ultralytics/tools/test_configurator.py:771
  • This path points to library/tests/unit/assets/..., which does not exist in this repo; as a result the test will always skip instead of exercising the DataModule path. library/tests/assets/... is at Path(__file__).resolve().parents[4] / "assets".
    library/tests/unit/backend/ultralytics/tools/test_configurator.py:792
  • This path points to library/tests/unit/assets/..., which does not exist in this repo; as a result the test will always skip instead of exercising the DataModule path. library/tests/assets/... is at Path(__file__).resolve().parents[4] / "assets".
    library/tests/unit/backend/ultralytics/tools/test_configurator.py:812
  • This path points to library/tests/unit/assets/..., which does not exist in this repo; as a result the test will always skip instead of exercising the DataModule path. library/tests/assets/... is at Path(__file__).resolve().parents[4] / "assets".
    library/tests/unit/backend/ultralytics/tools/test_configurator.py:829
  • This path points to library/tests/unit/assets/..., which does not exist in this repo; as a result the test will always skip instead of exercising the DataModule path. library/tests/assets/... is at Path(__file__).resolve().parents[4] / "assets".
    library/tests/unit/backend/ultralytics/tools/test_configurator.py:922
  • This path points to library/tests/unit/assets/..., which does not exist in this repo; as a result the test will always skip instead of exercising the DataModule path. library/tests/assets/... is at Path(__file__).resolve().parents[4] / "assets".
    library/tests/unit/backend/ultralytics/tools/test_configurator.py:952
  • This path points to library/tests/unit/assets/..., which does not exist in this repo; as a result the test will always skip instead of exercising the DataModule path. library/tests/assets/... is at Path(__file__).resolve().parents[4] / "assets".

Comment thread library/src/getitune/backend/ultralytics/engine.py Outdated
Comment thread library/src/getitune/backend/ultralytics/data/adapter.py Outdated
Comment thread library/Justfile
Comment thread library/src/getitune/backend/ultralytics/models/base.py
Comment thread library/src/getitune/backend/ultralytics/data/collate.py Outdated
Comment thread library/src/getitune/backend/ultralytics/models/classification.py
Comment thread library/src/getitune/backend/ultralytics/models/classification.py Outdated
Comment thread library/src/getitune/backend/ultralytics/validators/classification.py Outdated
Comment thread library/src/getitune/backend/ultralytics/trainers/classification.py Outdated
Comment thread library/src/getitune/backend/ultralytics/trainers/classification.py Outdated
@kprokofi
kprokofi requested a review from sys-geti as a code owner July 15, 2026 15:43
@github-actions github-actions Bot added DEPENDENCY Any changes in any dependencies (new dep or its version) should be produced via Change Request on PM BUILD labels Jul 15, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 75 out of 77 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

library/tests/unit/backend/ultralytics/exporter/test_exporter.py:643

  • This unit test uses task_type="semantic_segmentation", but the actual semantic-segmentation model wrapper exports with task_type="segmentation" (see UltralyticsSemanticSegModel._export_parameters). The test currently won't catch the real metadata mapping behavior for semantic segmentation.

Comment thread library/src/getitune/backend/ultralytics/exporter/exporter.py
Comment thread library/src/getitune/backend/ultralytics/data/adapter.py Outdated
kprokofi and others added 4 commits July 16, 2026 14:44
Comment on lines +49 to +51
def set_datamodule(self, datamodule: DataModule | None) -> None:
"""Bind a DataModule instance, overriding any class-level default."""
self._datamodule = datamodule

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pythonic way is to use property instead of setter method:

Suggested change
def set_datamodule(self, datamodule: DataModule | None) -> None:
"""Bind a DataModule instance, overriding any class-level default."""
self._datamodule = datamodule
@property
def datamodule(self) -> DataModule | None:
"""Get the bound DataModule instance."""
return self._datamodule
@datamodule.setter
def datamodule(self, value: DataModule | None) -> None:
"""Bind a DataModule instance, overriding any class-level default."""
self._datamodule = value

return self._getitem_detect(sample, img)
case _:
msg = f"Unknown task_kind: {self._task_kind}"
raise ValueError(msg)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since getter methods have the same semantics, it can be simplified with the class-level registry:

_GETITEM_MAPPING: ClassVar[dict[str, Callable]] = {
        "classify": _getitem_classify,
        "multilabel": _getitem_multilabel,
        "segment": _getitem_segment,
        "semantic": _getitem_semantic,
        "detect": _getitem_detect,
    }

...

# 1. Look up the method (returns unbound method)
get_item_fn = self._GETITEM_MAPPING.get(self._task_kind)

# 2. If not found, raise the error
if get_item_fn is None:
    msg = f"Unknown task_kind: {self._task_kind}"
    raise ValueError(msg)

# 3. Call it, explicitly passing 'self'
return get_item_fn(self, sample, img)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

BUILD DEPENDENCY Any changes in any dependencies (new dep or its version) should be produced via Change Request on PM DOC Improvements or additions to documentation Geti Backend Issues related to the Geti application server Geti Library Issues related to Geti Library (OTX) TEST Any changes in tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extend Ultralytics Backend with Additional Vision Tasks (Cls, SemSeg)

4 participants