feat(yolo26-sem): binary (nc==1) post-process + register fine-tuned variants in core registry#2407
Draft
leeclemnet wants to merge 11 commits into
Draft
feat(yolo26-sem): binary (nc==1) post-process + register fine-tuned variants in core registry#2407leeclemnet wants to merge 11 commits into
leeclemnet wants to merge 11 commits into
Conversation
c23f550 to
ee29494
Compare
e47eebd to
c989129
Compare
…post-process A single foreground class trains as Ultralytics' nc==1 binary head, which emits one channel. softmax over a single channel is degenerate (1.0), so detect the 1-channel case and use the sigmoid foreground probability: every pixel is provisionally the lone foreground class (read from class_names [background,<fg>]) and sub-threshold pixels collapse to background via the existing threshold step. Shared by the ONNX, TorchScript and TRT backends. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…registry
The core ROBOFLOW_MODEL_TYPES only registered the family key
('semantic-segmentation', 'yolo26') — which pretrained/public models match (they
report modelArchitecture 'yolo26'). Fine-tuned versioned models report their ORT
modelType ('yolo26n-sem', ...), and get_model_type does no variant->family
normalization, so they hit ModelNotRecognisedError. Register the family alias
plus every trained variant, mirroring the YOLOLite registration.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…t load resolve_background_class_id now validates that a semantic-seg package declares background plus at least one foreground class (class_names >= 2), raising CorruptedModelPackageError otherwise — instead of failing silently downstream. This is the shared load-time gate for all three backends (ONNX/TorchScript/TRT), so the binary post-process can drop its background_class_id fallback and assume a foreground id exists. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…d_class_id stays pure Move the semantic-seg class-name contract (background + >=1 foreground) out of resolve_background_class_id into a dedicated validate_class_names utility, called at model load in the ONNX/TorchScript/TRT backends. resolve_background_class_id is now a pure index lookup that assumes a validated package. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ed module validate_class_names and resolve_background_class_id are semantic-segmentation specific and don't belong in the generic model_packages parsing module. Move them to common/roboflow/semantic_segmentation.py (shared by the DeepLabV3+ and YOLO26-sem backends) and repoint all six backend imports. Tests move to test_semantic_segmentation.py. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…anket +1 The K-foreground-channel layout shifted argmax ids by +1, which only maps correctly when background is at index 0. background_class_id is data-driven (resolve_background_class_id), so map channel j to the j-th non-background class id instead. Identical to +1 when background is at 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
a16e4f3 to
9cb1d95
Compare
Same semantic-seg class-name contract (background + >=1 foreground) applies to DeepLabV3+ packages; call validate_class_names at load in all three backends. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per project code style: self-documenting code over narration. Trim the explanatory inline comments and verbose docstrings added for the semantic-seg class-name helpers and post-process to terse WHY-only notes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ass-id mapping Both post-process branches (binary single-channel and multiclass K-foreground) mapped foreground channel indices back into the full class-id space inline. Extract insert_background_class (skips the background slot, data-driven id) and use it for both, unifying the mapping. resolve_background_class_id stays — the background id is also used by the sub-threshold collapse and letterbox pad. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Makes YOLO26 semantic-segmentation models (served via
inference_models) work end-to-end on the inference server, and tightens the semantic-seg class-name contract. Four changes:inference/models/utils.py):ROBOFLOW_MODEL_TYPESregistered only the family key("semantic-segmentation", "yolo26")— which pretrained/public models match (modelArchitecture = "yolo26"), but fine-tuned versioned models report their ORTmodelType("yolo26n-sem", …) with no variant→family normalization, raisingModelNotRecognisedError. Now registers the family alias plus every trained variant, mirroring the YOLOLite registration.nc==1) post-process: a single-foreground-class model trains as Ultralytics' native binary head → one output channel.softmaxover one channel is degenerate (≡1.0), so the single-channel case uses the sigmoid foreground probability; sub-threshold pixels collapse to background via the existing threshold step. Shared by ONNX/TorchScript/TRT; multi-channel (DeepLab + multiclass) is untouched (only triggers onshape[0] == 1).validate_class_namesrequires a semantic-seg package to declarebackground+ ≥1 foreground class (>= 2names), raisingCorruptedModelPackageErrorinstead of failing silently.resolve_background_class_idis now a pure lookup that assumes a validated package.model_packages.pyintocommon/roboflow/semantic_segmentation.py(shared by the DeepLabV3+ and YOLO26-sem backends).Related Issue(s): Builds on #2372 (YOLO26-sem ONNX/TorchScript/TRT backends). Pairs with roboflow-train #807.
Type of Change
Testing
Test details:
pytestover the semantic post-process,model_packages, and the newsemantic_segmentationtests → 53 passed. Binary tests verified meaningful by direct invocation (without the branch a sub-threshold pixel wrongly becomes foreground[1]; with it, background[0]). New tests:test_validate_class_names_*(valid binary/multiclass, missing background, missing foreground). Registry resolution of("semantic-segmentation", "yolo26n-sem")is covered by CI's full-deps import. E2E on staging (fine-tuned single-class model, paired with roboflow-train #807) pending.Checklist
Additional Context
Multi-channel/DeepLab behavior is unaffected throughout (binary branch only triggers on a single output channel).
post_process_semantic_segmentation_logitsintentionally stays inpost_processing.py(it's a post-processor); only the class-name validation/resolution helpers moved.