feat: Feature/yolo#34
Merged
Merged
Conversation
…model support Signed-off-by: dronefreak <kumaar324@gmail.com>
…model support Signed-off-by: dronefreak <kumaar324@gmail.com>
Signed-off-by: dronefreak <kumaar324@gmail.com>
Signed-off-by: dronefreak <kumaar324@gmail.com>
Signed-off-by: dronefreak <kumaar324@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…dir symlinks
Ultralytics resolves directory-level symlinks before performing the
'images → labels' path substitution for label auto-discovery.
Previous approach:
images/train → symlink → /data/VisDrone2019-DET-train/images/
Ultralytics resolves symlink → /data/images/ → substitutes → /data/labels/
Labels NOT found (they were in /tmp/.../labels/train/ instead)
New approach:
images/train/ → real directory containing per-file symlinks
img001.jpg → /data/images/img001.jpg (symlink)
...
Ultralytics scans real dir → sees workspace/images/train/img001.jpg
Substitutes → workspace/labels/train/img001.txt ✓
File open() follows symlinks transparently ✓
Also adds _symlink_images() static method and _IMAGE_SUFFIXES class attribute.
Tests updated:
- test_images_train_is_real_directory: asserts NOT is_symlink()
- test_images_train_contains_file_symlinks: each child is a file symlink
- test_file_symlinks_resolve_to_source: resolved path == source file
- test_label_discovery_path_consistency: simulates img2label_paths substitution
- test_val_images_dir_is_real_directory: same check for val split
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds 10 new registered models (5 YOLO11 + 5 YOLO26), bringing the total
registered YOLO variants from 19 to 29 (33 including torchvision).
YOLO11 (2024 architecture):
- yolo11n: 2.6M params, ~5.4 MB, mAP 39.5%
- yolo11s: 9.5M params, ~18.4 MB, mAP 47.0%
- yolo11m: 20.1M params, ~38.8 MB, mAP 51.5%
- yolo11l: 25.4M params, ~49.0 MB, mAP 53.4%
- yolo11x: 57.0M params, ~109 MB, mAP 54.7%
Architecture: C3k2 blocks + C2PSA attention in neck
YOLO26 (2025 architecture):
- yolo26n: 2.6M params, ~5.3 MB
- yolo26s: 10.0M params, ~19.5 MB
- yolo26m: 21.9M params, ~42.2 MB
- yolo26l: 26.3M params, ~50.7 MB
- yolo26x: 59.0M params, ~113 MB
Architecture: improved efficiency over v11; better small-object detection
All variants verified to load and run with ultralytics 8.4.54.
_is_yolo_model() already handles yolo11/yolo26 via startswith('yolo').
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ript tests - yolo_trainer.py: use output_dir.resolve() (absolute path) so Ultralytics saves weights to output_dir/name/weights/ not runs/detect/... - trainer.py: save last.pt every epoch; rename best_model.pt to best.pt - evaluate.py: YOLO via Ultralytics val(), rich table output, COCO mAP, JSON export - inference.py: YOLO via ultralytics.predict(), video file support, dir creation fix - webcam_demo.py: --source flag (webcam/video/stream), YOLO support, no choices= - tests/test_scripts.py: 42 new tests covering all scripts Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: dronefreak <kumaar324@gmail.com>
Signed-off-by: dronefreak <kumaar324@gmail.com>
Signed-off-by: dronefreak <kumaar324@gmail.com>
Signed-off-by: dronefreak <kumaar324@gmail.com>
Signed-off-by: dronefreak <kumaar324@gmail.com>
Signed-off-by: dronefreak <kumaar324@gmail.com>
Signed-off-by: dronefreak <kumaar324@gmail.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.
Fixed
Empty annotation handling - Removed dummy box creation
[0,0,1,1]with pedestrian label from images with no annotations. The toolkit now correctly returns empty tensors(0, 4)and(0,)instead of poisoning training with fake ground truth. Expected 2-5% training accuracy improvement.Soft-NMS device compatibility - Fixed tensor-to-numpy conversion in
soft_nms_utils.pyto work on CPU and multi-GPU setups. Changed.cpu().numpy()to.detach().cpu().numpy()to properly detach tensors before conversion. Also fixedtorch.expbeing called on numpy values.Metrics documentation clarity - Expanded
compute_metricsdocstring with comprehensive warnings about limitations. The function uses simple TP/FP/FN matching at single IoU threshold (0.5) and is for training monitoring only. It does NOT match official VisDrone evaluation methodology (mAP@0.5, mAP@0.75, mAP@0.5:0.95). Added references to official evaluation code and pycocotools.YOLO
nc/namesmismatch crash — FixedSyntaxError: 'names' length 11 and 'nc: 12' must matchthat occurred when--num-classes 12(VisDrone's raw count including ignored-regions) was passed toYOLOTrainer. Ultralytics validatesnc == len(names)strictly at trainer startup. Root cause:_VISDRONE_CLASSEShas 11 entries (class 0 = ignored-regions is filtered byconvert_to_yolo) butncwas set fromself.num_classes(could be 12). Fix: derivencfromlen(names)in_prepare_dataset;scripts/train.pyalso clampsnum_classestolen(_VISDRONE_CLASSES)before constructingYOLOTrainer.YOLO
ncpassed tomodel.train()— FixedSyntaxError: 'nc' is not a valid YOLO argumentcrash.ncbelongs indataset.yamlonly; removed it from themodel.train()keyword arguments.YOLO fake training loop —
_training_forward()was returningtorch.tensor(0.0, requires_grad=True)— a dummy scalar with disconnected gradients and no real loss computation. Replaced with architectural separation: YOLO models useYOLOTrainer(delegates to Ultralytics engine);YOLOTrainingAdapter.training_step()raisesNotImplementedErrorto make the incorrect path explicit and detectable.Added
YOLO v8+ Integration (Phase 1-3 Complete) - Full support for YOLO v8, v9, v10, YOLO11, and YOLO26 alongside existing torchvision models:
DetectionModel) for unified APIYOLO11 support (2024 architecture) —
yolo11n/s/m/l/x:YOLO26 support (2025 architecture) —
yolo26n/s/m/l/x:YOLO Ultralytics training delegation (Phase 4 Critical Fix) - Replaced fake YOLO training loop with correct Ultralytics engine delegation:
YOLOTrainer(visdrone_toolkit/yolo_trainer.py) — wrapsultralytics.YOLO.train()for correct gradient flow, DFL/box/cls losses, TaskAlignedAssigner, and Mosaic augmentationYOLOTrainingAdapter.training_step()now raisesNotImplementedError(intentional) — YOLO training is routed throughYOLOTrainer, not the torchvision custom loopscripts/train.pyroutes YOLO models toYOLOTrainerand torchvision models toUnifiedTrainervia_is_yolo_model()YOLO dataset YAML pipeline — VisDrone-to-YOLO on-the-fly conversion:
.txtformat in a temporary directoryimages/trainandimages/valsymlinks (no data copy; avoids copying GBs)dataset.yamlconsumed directly by UltralyticsUnified Training Infrastructure (Phase 2) - Single training loop for all model types:
UnifiedTrainerclass with automatic adapter selectionTorchvision Model Wrappers (Phase 2) - Transparent wrappers for existing models:
YOLO Validation Tests (Phase 3) - Comprehensive test suite for new architecture:
test_yolo_validation.py- 18 test methodsYOLOTrainer unit tests (
tests/test_yolo_trainer.py) - 35 test methods covering:_VISDRONE_CLASSEScorrectness (11 classes, no ignored-regions, no duplicates)YOLOTrainer.__init__for all YOLO versions (v8, v9, v10)_prepare_datasetYAML consistency:nc == len(names)fornum_classesin {5, 11, 12}num_classes=12must not cause Ultralyticsnc/namesmismatch crashlabels/train,labels/valtrain()method with mocked Ultralytics: epochs, batch, lr0, noncinmodel.train(), extra kwargsComprehensive integration test suite (
tests/test_integration.py) - 18+ test methods across 6 test classes for regression protection of critical bug fixes:TestEmptyAnnotationHandling- Validates empty annotation handling after parsing and augmentationTestSoftNMSDeviceHandling- Ensures device compatibility across CPU/CUDATestMetricsComputation- Verifies metrics accuracy and docstring clarityTestMinimalTrainingPipeline- End-to-end training loop validationTestDatasetIntegration- Dataset integration with DataLoaderTestAugmentationIntegration- Augmentation pipeline validationChanged
Model factory refactoring (
utils.py) - Registry-first lookup with backward compatibility:get_model()now checks ModelRegistry first (YOLO, DETR, custom models)Training script refactor (
scripts/train.py) - 60% code reduction:UnifiedTrainerinstead of manual training loopInference script refactor (
scripts/inference.py) - 50% code reduction:Planned
Phase 4: DETR Integration - Detection Transformers support:
Phase 5: Advanced Features:
Phase 6: Documentation & Examples:
Video sequence support for temporal tasks
Integration with Weights & Biases for experiment tracking
TensorRT optimization for faster inference
Docker images for easy deployment
Mobile deployment guide (CoreML, TFLite)
Soft-NMS vectorization with torch.cdist for 10-50x inference speedup