dgenerate-ultralytics-headless 8.3.190__py3-none-any.whl → 8.3.191__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dgenerate_ultralytics_headless-8.3.190.dist-info → dgenerate_ultralytics_headless-8.3.191.dist-info}/METADATA +1 -1
- {dgenerate_ultralytics_headless-8.3.190.dist-info → dgenerate_ultralytics_headless-8.3.191.dist-info}/RECORD +102 -101
- tests/test_cuda.py +6 -5
- tests/test_exports.py +1 -6
- tests/test_python.py +1 -4
- tests/test_solutions.py +1 -1
- ultralytics/__init__.py +1 -1
- ultralytics/cfg/__init__.py +16 -14
- ultralytics/cfg/datasets/VisDrone.yaml +4 -4
- ultralytics/data/annotator.py +6 -6
- ultralytics/data/augment.py +53 -51
- ultralytics/data/base.py +15 -13
- ultralytics/data/build.py +7 -4
- ultralytics/data/converter.py +9 -10
- ultralytics/data/dataset.py +24 -22
- ultralytics/data/loaders.py +13 -11
- ultralytics/data/split.py +4 -3
- ultralytics/data/split_dota.py +14 -12
- ultralytics/data/utils.py +29 -23
- ultralytics/engine/exporter.py +2 -2
- ultralytics/engine/model.py +16 -14
- ultralytics/engine/predictor.py +8 -6
- ultralytics/engine/results.py +54 -52
- ultralytics/engine/trainer.py +7 -2
- ultralytics/engine/tuner.py +4 -3
- ultralytics/hub/google/__init__.py +7 -6
- ultralytics/hub/session.py +8 -6
- ultralytics/hub/utils.py +3 -4
- ultralytics/models/fastsam/model.py +8 -6
- ultralytics/models/nas/model.py +5 -3
- ultralytics/models/rtdetr/train.py +4 -3
- ultralytics/models/rtdetr/val.py +6 -4
- ultralytics/models/sam/amg.py +13 -10
- ultralytics/models/sam/model.py +3 -2
- ultralytics/models/sam/modules/blocks.py +21 -21
- ultralytics/models/sam/modules/decoders.py +11 -11
- ultralytics/models/sam/modules/encoders.py +25 -25
- ultralytics/models/sam/modules/memory_attention.py +9 -8
- ultralytics/models/sam/modules/sam.py +8 -10
- ultralytics/models/sam/modules/tiny_encoder.py +21 -20
- ultralytics/models/sam/modules/transformer.py +6 -5
- ultralytics/models/sam/modules/utils.py +7 -5
- ultralytics/models/sam/predict.py +32 -31
- ultralytics/models/utils/loss.py +29 -27
- ultralytics/models/utils/ops.py +10 -8
- ultralytics/models/yolo/classify/train.py +7 -5
- ultralytics/models/yolo/classify/val.py +10 -8
- ultralytics/models/yolo/detect/predict.py +1 -1
- ultralytics/models/yolo/detect/train.py +8 -6
- ultralytics/models/yolo/detect/val.py +21 -19
- ultralytics/models/yolo/model.py +14 -14
- ultralytics/models/yolo/obb/train.py +5 -3
- ultralytics/models/yolo/obb/val.py +11 -9
- ultralytics/models/yolo/pose/train.py +7 -5
- ultralytics/models/yolo/pose/val.py +11 -9
- ultralytics/models/yolo/segment/train.py +4 -5
- ultralytics/models/yolo/segment/val.py +12 -10
- ultralytics/models/yolo/world/train.py +9 -7
- ultralytics/models/yolo/yoloe/train.py +7 -6
- ultralytics/models/yolo/yoloe/val.py +10 -8
- ultralytics/nn/autobackend.py +17 -19
- ultralytics/nn/modules/block.py +12 -12
- ultralytics/nn/modules/conv.py +4 -3
- ultralytics/nn/modules/head.py +41 -37
- ultralytics/nn/modules/transformer.py +22 -21
- ultralytics/nn/tasks.py +2 -2
- ultralytics/nn/text_model.py +6 -5
- ultralytics/solutions/analytics.py +7 -5
- ultralytics/solutions/config.py +12 -10
- ultralytics/solutions/distance_calculation.py +3 -3
- ultralytics/solutions/heatmap.py +4 -2
- ultralytics/solutions/object_counter.py +5 -3
- ultralytics/solutions/parking_management.py +4 -2
- ultralytics/solutions/region_counter.py +7 -5
- ultralytics/solutions/similarity_search.py +5 -3
- ultralytics/solutions/solutions.py +38 -36
- ultralytics/solutions/streamlit_inference.py +8 -7
- ultralytics/trackers/bot_sort.py +11 -9
- ultralytics/trackers/byte_tracker.py +17 -15
- ultralytics/trackers/utils/gmc.py +4 -3
- ultralytics/utils/__init__.py +16 -88
- ultralytics/utils/autobatch.py +3 -2
- ultralytics/utils/autodevice.py +10 -10
- ultralytics/utils/benchmarks.py +11 -10
- ultralytics/utils/callbacks/comet.py +9 -9
- ultralytics/utils/checks.py +17 -26
- ultralytics/utils/export.py +12 -11
- ultralytics/utils/files.py +8 -7
- ultralytics/utils/git.py +139 -0
- ultralytics/utils/instance.py +8 -7
- ultralytics/utils/loss.py +15 -13
- ultralytics/utils/metrics.py +62 -62
- ultralytics/utils/ops.py +3 -2
- ultralytics/utils/patches.py +6 -4
- ultralytics/utils/plotting.py +18 -16
- ultralytics/utils/torch_utils.py +4 -2
- ultralytics/utils/tqdm.py +15 -12
- ultralytics/utils/triton.py +3 -2
- {dgenerate_ultralytics_headless-8.3.190.dist-info → dgenerate_ultralytics_headless-8.3.191.dist-info}/WHEEL +0 -0
- {dgenerate_ultralytics_headless-8.3.190.dist-info → dgenerate_ultralytics_headless-8.3.191.dist-info}/entry_points.txt +0 -0
- {dgenerate_ultralytics_headless-8.3.190.dist-info → dgenerate_ultralytics_headless-8.3.191.dist-info}/licenses/LICENSE +0 -0
- {dgenerate_ultralytics_headless-8.3.190.dist-info → dgenerate_ultralytics_headless-8.3.191.dist-info}/top_level.txt +0 -0
ultralytics/models/utils/loss.py
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
-
from
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
from typing import Any
|
4
6
|
|
5
7
|
import torch
|
6
8
|
import torch.nn as nn
|
@@ -36,7 +38,7 @@ class DETRLoss(nn.Module):
|
|
36
38
|
def __init__(
|
37
39
|
self,
|
38
40
|
nc: int = 80,
|
39
|
-
loss_gain:
|
41
|
+
loss_gain: dict[str, float] | None = None,
|
40
42
|
aux_loss: bool = True,
|
41
43
|
use_fl: bool = True,
|
42
44
|
use_vfl: bool = False,
|
@@ -79,7 +81,7 @@ class DETRLoss(nn.Module):
|
|
79
81
|
|
80
82
|
def _get_loss_class(
|
81
83
|
self, pred_scores: torch.Tensor, targets: torch.Tensor, gt_scores: torch.Tensor, num_gts: int, postfix: str = ""
|
82
|
-
) ->
|
84
|
+
) -> dict[str, torch.Tensor]:
|
83
85
|
"""
|
84
86
|
Compute classification loss based on predictions, target values, and ground truth scores.
|
85
87
|
|
@@ -121,7 +123,7 @@ class DETRLoss(nn.Module):
|
|
121
123
|
|
122
124
|
def _get_loss_bbox(
|
123
125
|
self, pred_bboxes: torch.Tensor, gt_bboxes: torch.Tensor, postfix: str = ""
|
124
|
-
) ->
|
126
|
+
) -> dict[str, torch.Tensor]:
|
125
127
|
"""
|
126
128
|
Compute bounding box and GIoU losses for predicted and ground truth bounding boxes.
|
127
129
|
|
@@ -191,12 +193,12 @@ class DETRLoss(nn.Module):
|
|
191
193
|
pred_scores: torch.Tensor,
|
192
194
|
gt_bboxes: torch.Tensor,
|
193
195
|
gt_cls: torch.Tensor,
|
194
|
-
gt_groups:
|
195
|
-
match_indices:
|
196
|
+
gt_groups: list[int],
|
197
|
+
match_indices: list[tuple] | None = None,
|
196
198
|
postfix: str = "",
|
197
|
-
masks:
|
198
|
-
gt_mask:
|
199
|
-
) ->
|
199
|
+
masks: torch.Tensor | None = None,
|
200
|
+
gt_mask: torch.Tensor | None = None,
|
201
|
+
) -> dict[str, torch.Tensor]:
|
200
202
|
"""
|
201
203
|
Get auxiliary losses for intermediate decoder layers.
|
202
204
|
|
@@ -258,7 +260,7 @@ class DETRLoss(nn.Module):
|
|
258
260
|
return loss
|
259
261
|
|
260
262
|
@staticmethod
|
261
|
-
def _get_index(match_indices:
|
263
|
+
def _get_index(match_indices: list[tuple]) -> tuple[tuple[torch.Tensor, torch.Tensor], torch.Tensor]:
|
262
264
|
"""
|
263
265
|
Extract batch indices, source indices, and destination indices from match indices.
|
264
266
|
|
@@ -275,8 +277,8 @@ class DETRLoss(nn.Module):
|
|
275
277
|
return (batch_idx, src_idx), dst_idx
|
276
278
|
|
277
279
|
def _get_assigned_bboxes(
|
278
|
-
self, pred_bboxes: torch.Tensor, gt_bboxes: torch.Tensor, match_indices:
|
279
|
-
) ->
|
280
|
+
self, pred_bboxes: torch.Tensor, gt_bboxes: torch.Tensor, match_indices: list[tuple]
|
281
|
+
) -> tuple[torch.Tensor, torch.Tensor]:
|
280
282
|
"""
|
281
283
|
Assign predicted bounding boxes to ground truth bounding boxes based on match indices.
|
282
284
|
|
@@ -309,12 +311,12 @@ class DETRLoss(nn.Module):
|
|
309
311
|
pred_scores: torch.Tensor,
|
310
312
|
gt_bboxes: torch.Tensor,
|
311
313
|
gt_cls: torch.Tensor,
|
312
|
-
gt_groups:
|
313
|
-
masks:
|
314
|
-
gt_mask:
|
314
|
+
gt_groups: list[int],
|
315
|
+
masks: torch.Tensor | None = None,
|
316
|
+
gt_mask: torch.Tensor | None = None,
|
315
317
|
postfix: str = "",
|
316
|
-
match_indices:
|
317
|
-
) ->
|
318
|
+
match_indices: list[tuple] | None = None,
|
319
|
+
) -> dict[str, torch.Tensor]:
|
318
320
|
"""
|
319
321
|
Calculate losses for a single prediction layer.
|
320
322
|
|
@@ -358,10 +360,10 @@ class DETRLoss(nn.Module):
|
|
358
360
|
self,
|
359
361
|
pred_bboxes: torch.Tensor,
|
360
362
|
pred_scores: torch.Tensor,
|
361
|
-
batch:
|
363
|
+
batch: dict[str, Any],
|
362
364
|
postfix: str = "",
|
363
365
|
**kwargs: Any,
|
364
|
-
) ->
|
366
|
+
) -> dict[str, torch.Tensor]:
|
365
367
|
"""
|
366
368
|
Calculate loss for predicted bounding boxes and scores.
|
367
369
|
|
@@ -407,12 +409,12 @@ class RTDETRDetectionLoss(DETRLoss):
|
|
407
409
|
|
408
410
|
def forward(
|
409
411
|
self,
|
410
|
-
preds:
|
411
|
-
batch:
|
412
|
-
dn_bboxes:
|
413
|
-
dn_scores:
|
414
|
-
dn_meta:
|
415
|
-
) ->
|
412
|
+
preds: tuple[torch.Tensor, torch.Tensor],
|
413
|
+
batch: dict[str, Any],
|
414
|
+
dn_bboxes: torch.Tensor | None = None,
|
415
|
+
dn_scores: torch.Tensor | None = None,
|
416
|
+
dn_meta: dict[str, Any] | None = None,
|
417
|
+
) -> dict[str, torch.Tensor]:
|
416
418
|
"""
|
417
419
|
Forward pass to compute detection loss with optional denoising loss.
|
418
420
|
|
@@ -448,8 +450,8 @@ class RTDETRDetectionLoss(DETRLoss):
|
|
448
450
|
|
449
451
|
@staticmethod
|
450
452
|
def get_dn_match_indices(
|
451
|
-
dn_pos_idx:
|
452
|
-
) ->
|
453
|
+
dn_pos_idx: list[torch.Tensor], dn_num_group: int, gt_groups: list[int]
|
454
|
+
) -> list[tuple[torch.Tensor, torch.Tensor]]:
|
453
455
|
"""
|
454
456
|
Get match indices for denoising.
|
455
457
|
|
ultralytics/models/utils/ops.py
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
-
from
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
from typing import Any
|
4
6
|
|
5
7
|
import torch
|
6
8
|
import torch.nn as nn
|
@@ -47,7 +49,7 @@ class HungarianMatcher(nn.Module):
|
|
47
49
|
|
48
50
|
def __init__(
|
49
51
|
self,
|
50
|
-
cost_gain:
|
52
|
+
cost_gain: dict[str, float] | None = None,
|
51
53
|
use_fl: bool = True,
|
52
54
|
with_mask: bool = False,
|
53
55
|
num_sample_points: int = 12544,
|
@@ -82,10 +84,10 @@ class HungarianMatcher(nn.Module):
|
|
82
84
|
pred_scores: torch.Tensor,
|
83
85
|
gt_bboxes: torch.Tensor,
|
84
86
|
gt_cls: torch.Tensor,
|
85
|
-
gt_groups:
|
86
|
-
masks:
|
87
|
-
gt_mask:
|
88
|
-
) ->
|
87
|
+
gt_groups: list[int],
|
88
|
+
masks: torch.Tensor | None = None,
|
89
|
+
gt_mask: list[torch.Tensor] | None = None,
|
90
|
+
) -> list[tuple[torch.Tensor, torch.Tensor]]:
|
89
91
|
"""
|
90
92
|
Compute optimal assignment between predictions and ground truth using Hungarian algorithm.
|
91
93
|
|
@@ -187,7 +189,7 @@ class HungarianMatcher(nn.Module):
|
|
187
189
|
|
188
190
|
|
189
191
|
def get_cdn_group(
|
190
|
-
batch:
|
192
|
+
batch: dict[str, Any],
|
191
193
|
num_classes: int,
|
192
194
|
num_queries: int,
|
193
195
|
class_embed: torch.Tensor,
|
@@ -195,7 +197,7 @@ def get_cdn_group(
|
|
195
197
|
cls_noise_ratio: float = 0.5,
|
196
198
|
box_noise_scale: float = 1.0,
|
197
199
|
training: bool = False,
|
198
|
-
) ->
|
200
|
+
) -> tuple[torch.Tensor | None, torch.Tensor | None, torch.Tensor | None, dict[str, Any] | None]:
|
199
201
|
"""
|
200
202
|
Generate contrastive denoising training group with positive and negative samples from ground truths.
|
201
203
|
|
@@ -1,7 +1,9 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
+
from __future__ import annotations
|
4
|
+
|
3
5
|
from copy import copy
|
4
|
-
from typing import Any
|
6
|
+
from typing import Any
|
5
7
|
|
6
8
|
import torch
|
7
9
|
|
@@ -49,7 +51,7 @@ class ClassificationTrainer(BaseTrainer):
|
|
49
51
|
>>> trainer.train()
|
50
52
|
"""
|
51
53
|
|
52
|
-
def __init__(self, cfg=DEFAULT_CFG, overrides:
|
54
|
+
def __init__(self, cfg=DEFAULT_CFG, overrides: dict[str, Any] | None = None, _callbacks=None):
|
53
55
|
"""
|
54
56
|
Initialize a ClassificationTrainer object.
|
55
57
|
|
@@ -162,7 +164,7 @@ class ClassificationTrainer(BaseTrainer):
|
|
162
164
|
self.model.transforms = loader.dataset.torch_transforms
|
163
165
|
return loader
|
164
166
|
|
165
|
-
def preprocess_batch(self, batch:
|
167
|
+
def preprocess_batch(self, batch: dict[str, torch.Tensor]) -> dict[str, torch.Tensor]:
|
166
168
|
"""Preprocess a batch of images and classes."""
|
167
169
|
batch["img"] = batch["img"].to(self.device)
|
168
170
|
batch["cls"] = batch["cls"].to(self.device)
|
@@ -185,7 +187,7 @@ class ClassificationTrainer(BaseTrainer):
|
|
185
187
|
self.test_loader, self.save_dir, args=copy(self.args), _callbacks=self.callbacks
|
186
188
|
)
|
187
189
|
|
188
|
-
def label_loss_items(self, loss_items:
|
190
|
+
def label_loss_items(self, loss_items: torch.Tensor | None = None, prefix: str = "train"):
|
189
191
|
"""
|
190
192
|
Return a loss dict with labelled training loss items tensor.
|
191
193
|
|
@@ -220,7 +222,7 @@ class ClassificationTrainer(BaseTrainer):
|
|
220
222
|
self.metrics.pop("fitness", None)
|
221
223
|
self.run_callbacks("on_fit_epoch_end")
|
222
224
|
|
223
|
-
def plot_training_samples(self, batch:
|
225
|
+
def plot_training_samples(self, batch: dict[str, torch.Tensor], ni: int):
|
224
226
|
"""
|
225
227
|
Plot training samples with their annotations.
|
226
228
|
|
@@ -1,7 +1,9 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
+
from __future__ import annotations
|
4
|
+
|
3
5
|
from pathlib import Path
|
4
|
-
from typing import Any
|
6
|
+
from typing import Any
|
5
7
|
|
6
8
|
import torch
|
7
9
|
|
@@ -85,14 +87,14 @@ class ClassificationValidator(BaseValidator):
|
|
85
87
|
self.targets = []
|
86
88
|
self.confusion_matrix = ConfusionMatrix(names=model.names)
|
87
89
|
|
88
|
-
def preprocess(self, batch:
|
90
|
+
def preprocess(self, batch: dict[str, Any]) -> dict[str, Any]:
|
89
91
|
"""Preprocess input batch by moving data to device and converting to appropriate dtype."""
|
90
92
|
batch["img"] = batch["img"].to(self.device, non_blocking=True)
|
91
93
|
batch["img"] = batch["img"].half() if self.args.half else batch["img"].float()
|
92
94
|
batch["cls"] = batch["cls"].to(self.device)
|
93
95
|
return batch
|
94
96
|
|
95
|
-
def update_metrics(self, preds: torch.Tensor, batch:
|
97
|
+
def update_metrics(self, preds: torch.Tensor, batch: dict[str, Any]) -> None:
|
96
98
|
"""
|
97
99
|
Update running metrics with model predictions and batch targets.
|
98
100
|
|
@@ -131,11 +133,11 @@ class ClassificationValidator(BaseValidator):
|
|
131
133
|
self.metrics.save_dir = self.save_dir
|
132
134
|
self.metrics.confusion_matrix = self.confusion_matrix
|
133
135
|
|
134
|
-
def postprocess(self, preds:
|
136
|
+
def postprocess(self, preds: torch.Tensor | list[torch.Tensor] | tuple[torch.Tensor]) -> torch.Tensor:
|
135
137
|
"""Extract the primary prediction from model output if it's in a list or tuple format."""
|
136
138
|
return preds[0] if isinstance(preds, (list, tuple)) else preds
|
137
139
|
|
138
|
-
def get_stats(self) ->
|
140
|
+
def get_stats(self) -> dict[str, float]:
|
139
141
|
"""Calculate and return a dictionary of metrics by processing targets and predictions."""
|
140
142
|
self.metrics.process(self.targets, self.pred)
|
141
143
|
return self.metrics.results_dict
|
@@ -144,7 +146,7 @@ class ClassificationValidator(BaseValidator):
|
|
144
146
|
"""Create a ClassificationDataset instance for validation."""
|
145
147
|
return ClassificationDataset(root=img_path, args=self.args, augment=False, prefix=self.args.split)
|
146
148
|
|
147
|
-
def get_dataloader(self, dataset_path:
|
149
|
+
def get_dataloader(self, dataset_path: Path | str, batch_size: int) -> torch.utils.data.DataLoader:
|
148
150
|
"""
|
149
151
|
Build and return a data loader for classification validation.
|
150
152
|
|
@@ -163,7 +165,7 @@ class ClassificationValidator(BaseValidator):
|
|
163
165
|
pf = "%22s" + "%11.3g" * len(self.metrics.keys) # print format
|
164
166
|
LOGGER.info(pf % ("all", self.metrics.top1, self.metrics.top5))
|
165
167
|
|
166
|
-
def plot_val_samples(self, batch:
|
168
|
+
def plot_val_samples(self, batch: dict[str, Any], ni: int) -> None:
|
167
169
|
"""
|
168
170
|
Plot validation image samples with their ground truth labels.
|
169
171
|
|
@@ -184,7 +186,7 @@ class ClassificationValidator(BaseValidator):
|
|
184
186
|
on_plot=self.on_plot,
|
185
187
|
)
|
186
188
|
|
187
|
-
def plot_predictions(self, batch:
|
189
|
+
def plot_predictions(self, batch: dict[str, Any], preds: torch.Tensor, ni: int) -> None:
|
188
190
|
"""
|
189
191
|
Plot images with their predicted class labels and save the visualization.
|
190
192
|
|
@@ -85,7 +85,7 @@ class DetectionPredictor(BasePredictor):
|
|
85
85
|
"""Extract object features from the feature maps."""
|
86
86
|
import torch
|
87
87
|
|
88
|
-
s = min(
|
88
|
+
s = min(x.shape[1] for x in feat_maps) # find shortest vector length
|
89
89
|
obj_feats = torch.cat(
|
90
90
|
[x.permute(0, 2, 3, 1).reshape(x.shape[0], -1, s, x.shape[1] // s).mean(dim=-1) for x in feat_maps], dim=1
|
91
91
|
) # mean reduce all vectors to same length
|
@@ -1,9 +1,11 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
+
from __future__ import annotations
|
4
|
+
|
3
5
|
import math
|
4
6
|
import random
|
5
7
|
from copy import copy
|
6
|
-
from typing import Any
|
8
|
+
from typing import Any
|
7
9
|
|
8
10
|
import numpy as np
|
9
11
|
import torch.nn as nn
|
@@ -51,7 +53,7 @@ class DetectionTrainer(BaseTrainer):
|
|
51
53
|
>>> trainer.train()
|
52
54
|
"""
|
53
55
|
|
54
|
-
def build_dataset(self, img_path: str, mode: str = "train", batch:
|
56
|
+
def build_dataset(self, img_path: str, mode: str = "train", batch: int | None = None):
|
55
57
|
"""
|
56
58
|
Build YOLO Dataset for training or validation.
|
57
59
|
|
@@ -89,7 +91,7 @@ class DetectionTrainer(BaseTrainer):
|
|
89
91
|
workers = self.args.workers if mode == "train" else self.args.workers * 2
|
90
92
|
return build_dataloader(dataset, batch_size, workers, shuffle, rank) # return dataloader
|
91
93
|
|
92
|
-
def preprocess_batch(self, batch:
|
94
|
+
def preprocess_batch(self, batch: dict) -> dict:
|
93
95
|
"""
|
94
96
|
Preprocess a batch of images by scaling and converting to float.
|
95
97
|
|
@@ -127,7 +129,7 @@ class DetectionTrainer(BaseTrainer):
|
|
127
129
|
self.model.args = self.args # attach hyperparameters to model
|
128
130
|
# TODO: self.model.class_weights = labels_to_class_weights(dataset.labels, nc).to(device) * nc
|
129
131
|
|
130
|
-
def get_model(self, cfg:
|
132
|
+
def get_model(self, cfg: str | None = None, weights: str | None = None, verbose: bool = True):
|
131
133
|
"""
|
132
134
|
Return a YOLO detection model.
|
133
135
|
|
@@ -151,7 +153,7 @@ class DetectionTrainer(BaseTrainer):
|
|
151
153
|
self.test_loader, save_dir=self.save_dir, args=copy(self.args), _callbacks=self.callbacks
|
152
154
|
)
|
153
155
|
|
154
|
-
def label_loss_items(self, loss_items:
|
156
|
+
def label_loss_items(self, loss_items: list[float] | None = None, prefix: str = "train"):
|
155
157
|
"""
|
156
158
|
Return a loss dict with labeled training loss items tensor.
|
157
159
|
|
@@ -179,7 +181,7 @@ class DetectionTrainer(BaseTrainer):
|
|
179
181
|
"Size",
|
180
182
|
)
|
181
183
|
|
182
|
-
def plot_training_samples(self, batch:
|
184
|
+
def plot_training_samples(self, batch: dict[str, Any], ni: int) -> None:
|
183
185
|
"""
|
184
186
|
Plot training samples with their annotations.
|
185
187
|
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
+
from __future__ import annotations
|
4
|
+
|
3
5
|
import os
|
4
6
|
from pathlib import Path
|
5
|
-
from typing import Any
|
7
|
+
from typing import Any
|
6
8
|
|
7
9
|
import numpy as np
|
8
10
|
import torch
|
@@ -59,7 +61,7 @@ class DetectionValidator(BaseValidator):
|
|
59
61
|
self.niou = self.iouv.numel()
|
60
62
|
self.metrics = DetMetrics()
|
61
63
|
|
62
|
-
def preprocess(self, batch:
|
64
|
+
def preprocess(self, batch: dict[str, Any]) -> dict[str, Any]:
|
63
65
|
"""
|
64
66
|
Preprocess batch of images for YOLO validation.
|
65
67
|
|
@@ -104,7 +106,7 @@ class DetectionValidator(BaseValidator):
|
|
104
106
|
"""Return a formatted string summarizing class metrics of YOLO model."""
|
105
107
|
return ("%22s" + "%11s" * 6) % ("Class", "Images", "Instances", "Box(P", "R", "mAP50", "mAP50-95)")
|
106
108
|
|
107
|
-
def postprocess(self, preds: torch.Tensor) ->
|
109
|
+
def postprocess(self, preds: torch.Tensor) -> list[dict[str, torch.Tensor]]:
|
108
110
|
"""
|
109
111
|
Apply Non-maximum suppression to prediction outputs.
|
110
112
|
|
@@ -128,7 +130,7 @@ class DetectionValidator(BaseValidator):
|
|
128
130
|
)
|
129
131
|
return [{"bboxes": x[:, :4], "conf": x[:, 4], "cls": x[:, 5], "extra": x[:, 6:]} for x in outputs]
|
130
132
|
|
131
|
-
def _prepare_batch(self, si: int, batch:
|
133
|
+
def _prepare_batch(self, si: int, batch: dict[str, Any]) -> dict[str, Any]:
|
132
134
|
"""
|
133
135
|
Prepare a batch of images and annotations for validation.
|
134
136
|
|
@@ -156,7 +158,7 @@ class DetectionValidator(BaseValidator):
|
|
156
158
|
"im_file": batch["im_file"][si],
|
157
159
|
}
|
158
160
|
|
159
|
-
def _prepare_pred(self, pred:
|
161
|
+
def _prepare_pred(self, pred: dict[str, torch.Tensor]) -> dict[str, torch.Tensor]:
|
160
162
|
"""
|
161
163
|
Prepare predictions for evaluation against ground truth.
|
162
164
|
|
@@ -170,7 +172,7 @@ class DetectionValidator(BaseValidator):
|
|
170
172
|
pred["cls"] *= 0
|
171
173
|
return pred
|
172
174
|
|
173
|
-
def update_metrics(self, preds:
|
175
|
+
def update_metrics(self, preds: list[dict[str, torch.Tensor]], batch: dict[str, Any]) -> None:
|
174
176
|
"""
|
175
177
|
Update metrics with new predictions and ground truth.
|
176
178
|
|
@@ -225,7 +227,7 @@ class DetectionValidator(BaseValidator):
|
|
225
227
|
self.metrics.confusion_matrix = self.confusion_matrix
|
226
228
|
self.metrics.save_dir = self.save_dir
|
227
229
|
|
228
|
-
def get_stats(self) ->
|
230
|
+
def get_stats(self) -> dict[str, Any]:
|
229
231
|
"""
|
230
232
|
Calculate and return metrics statistics.
|
231
233
|
|
@@ -256,7 +258,7 @@ class DetectionValidator(BaseValidator):
|
|
256
258
|
)
|
257
259
|
)
|
258
260
|
|
259
|
-
def _process_batch(self, preds:
|
261
|
+
def _process_batch(self, preds: dict[str, torch.Tensor], batch: dict[str, Any]) -> dict[str, np.ndarray]:
|
260
262
|
"""
|
261
263
|
Return correct prediction matrix.
|
262
264
|
|
@@ -272,7 +274,7 @@ class DetectionValidator(BaseValidator):
|
|
272
274
|
iou = box_iou(batch["bboxes"], preds["bboxes"])
|
273
275
|
return {"tp": self.match_predictions(preds["cls"], batch["cls"], iou).cpu().numpy()}
|
274
276
|
|
275
|
-
def build_dataset(self, img_path: str, mode: str = "val", batch:
|
277
|
+
def build_dataset(self, img_path: str, mode: str = "val", batch: int | None = None) -> torch.utils.data.Dataset:
|
276
278
|
"""
|
277
279
|
Build YOLO Dataset.
|
278
280
|
|
@@ -300,7 +302,7 @@ class DetectionValidator(BaseValidator):
|
|
300
302
|
dataset = self.build_dataset(dataset_path, batch=batch_size, mode="val")
|
301
303
|
return build_dataloader(dataset, batch_size, self.args.workers, shuffle=False, rank=-1) # return dataloader
|
302
304
|
|
303
|
-
def plot_val_samples(self, batch:
|
305
|
+
def plot_val_samples(self, batch: dict[str, Any], ni: int) -> None:
|
304
306
|
"""
|
305
307
|
Plot validation image samples.
|
306
308
|
|
@@ -317,7 +319,7 @@ class DetectionValidator(BaseValidator):
|
|
317
319
|
)
|
318
320
|
|
319
321
|
def plot_predictions(
|
320
|
-
self, batch:
|
322
|
+
self, batch: dict[str, Any], preds: list[dict[str, torch.Tensor]], ni: int, max_det: int | None = None
|
321
323
|
) -> None:
|
322
324
|
"""
|
323
325
|
Plot predicted bounding boxes on input images and save the result.
|
@@ -345,7 +347,7 @@ class DetectionValidator(BaseValidator):
|
|
345
347
|
on_plot=self.on_plot,
|
346
348
|
) # pred
|
347
349
|
|
348
|
-
def save_one_txt(self, predn:
|
350
|
+
def save_one_txt(self, predn: dict[str, torch.Tensor], save_conf: bool, shape: tuple[int, int], file: Path) -> None:
|
349
351
|
"""
|
350
352
|
Save YOLO detections to a txt file in normalized coordinates in a specific format.
|
351
353
|
|
@@ -364,7 +366,7 @@ class DetectionValidator(BaseValidator):
|
|
364
366
|
boxes=torch.cat([predn["bboxes"], predn["conf"].unsqueeze(-1), predn["cls"].unsqueeze(-1)], dim=1),
|
365
367
|
).save_txt(file, save_conf=save_conf)
|
366
368
|
|
367
|
-
def pred_to_json(self, predn:
|
369
|
+
def pred_to_json(self, predn: dict[str, torch.Tensor], pbatch: dict[str, Any]) -> None:
|
368
370
|
"""
|
369
371
|
Serialize YOLO predictions to COCO json format.
|
370
372
|
|
@@ -398,7 +400,7 @@ class DetectionValidator(BaseValidator):
|
|
398
400
|
}
|
399
401
|
)
|
400
402
|
|
401
|
-
def scale_preds(self, predn:
|
403
|
+
def scale_preds(self, predn: dict[str, torch.Tensor], pbatch: dict[str, Any]) -> dict[str, torch.Tensor]:
|
402
404
|
"""Scales predictions to the original image size."""
|
403
405
|
return {
|
404
406
|
**predn,
|
@@ -410,7 +412,7 @@ class DetectionValidator(BaseValidator):
|
|
410
412
|
),
|
411
413
|
}
|
412
414
|
|
413
|
-
def eval_json(self, stats:
|
415
|
+
def eval_json(self, stats: dict[str, Any]) -> dict[str, Any]:
|
414
416
|
"""
|
415
417
|
Evaluate YOLO output in JSON format and return performance statistics.
|
416
418
|
|
@@ -430,12 +432,12 @@ class DetectionValidator(BaseValidator):
|
|
430
432
|
|
431
433
|
def coco_evaluate(
|
432
434
|
self,
|
433
|
-
stats:
|
435
|
+
stats: dict[str, Any],
|
434
436
|
pred_json: str,
|
435
437
|
anno_json: str,
|
436
|
-
iou_types:
|
437
|
-
suffix:
|
438
|
-
) ->
|
438
|
+
iou_types: str | list[str] = "bbox",
|
439
|
+
suffix: str | list[str] = "Box",
|
440
|
+
) -> dict[str, Any]:
|
439
441
|
"""
|
440
442
|
Evaluate COCO/LVIS metrics using faster-coco-eval library.
|
441
443
|
|
ultralytics/models/yolo/model.py
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
+
from __future__ import annotations
|
4
|
+
|
3
5
|
from pathlib import Path
|
4
|
-
from typing import Any
|
6
|
+
from typing import Any
|
5
7
|
|
6
8
|
import torch
|
7
9
|
|
@@ -49,7 +51,7 @@ class YOLO(Model):
|
|
49
51
|
>>> model = YOLO("yolo11n.yaml")
|
50
52
|
"""
|
51
53
|
|
52
|
-
def __init__(self, model:
|
54
|
+
def __init__(self, model: str | Path = "yolo11n.pt", task: str | None = None, verbose: bool = False):
|
53
55
|
"""
|
54
56
|
Initialize a YOLO model.
|
55
57
|
|
@@ -87,7 +89,7 @@ class YOLO(Model):
|
|
87
89
|
self.__dict__ = new_instance.__dict__
|
88
90
|
|
89
91
|
@property
|
90
|
-
def task_map(self) ->
|
92
|
+
def task_map(self) -> dict[str, dict[str, Any]]:
|
91
93
|
"""Map head to model, trainer, validator, and predictor classes."""
|
92
94
|
return {
|
93
95
|
"classify": {
|
@@ -149,7 +151,7 @@ class YOLOWorld(Model):
|
|
149
151
|
>>> model.set_classes(["person", "car", "bicycle"])
|
150
152
|
"""
|
151
153
|
|
152
|
-
def __init__(self, model:
|
154
|
+
def __init__(self, model: str | Path = "yolov8s-world.pt", verbose: bool = False) -> None:
|
153
155
|
"""
|
154
156
|
Initialize YOLOv8-World model with a pre-trained model file.
|
155
157
|
|
@@ -167,7 +169,7 @@ class YOLOWorld(Model):
|
|
167
169
|
self.model.names = YAML.load(ROOT / "cfg/datasets/coco8.yaml").get("names")
|
168
170
|
|
169
171
|
@property
|
170
|
-
def task_map(self) ->
|
172
|
+
def task_map(self) -> dict[str, dict[str, Any]]:
|
171
173
|
"""Map head to model, validator, and predictor classes."""
|
172
174
|
return {
|
173
175
|
"detect": {
|
@@ -178,7 +180,7 @@ class YOLOWorld(Model):
|
|
178
180
|
}
|
179
181
|
}
|
180
182
|
|
181
|
-
def set_classes(self, classes:
|
183
|
+
def set_classes(self, classes: list[str]) -> None:
|
182
184
|
"""
|
183
185
|
Set the model's class names for detection.
|
184
186
|
|
@@ -232,9 +234,7 @@ class YOLOE(Model):
|
|
232
234
|
>>> results = model.predict("image.jpg", visual_prompts=prompts)
|
233
235
|
"""
|
234
236
|
|
235
|
-
def __init__(
|
236
|
-
self, model: Union[str, Path] = "yoloe-11s-seg.pt", task: Optional[str] = None, verbose: bool = False
|
237
|
-
) -> None:
|
237
|
+
def __init__(self, model: str | Path = "yoloe-11s-seg.pt", task: str | None = None, verbose: bool = False) -> None:
|
238
238
|
"""
|
239
239
|
Initialize YOLOE model with a pre-trained model file.
|
240
240
|
|
@@ -246,7 +246,7 @@ class YOLOE(Model):
|
|
246
246
|
super().__init__(model=model, task=task, verbose=verbose)
|
247
247
|
|
248
248
|
@property
|
249
|
-
def task_map(self) ->
|
249
|
+
def task_map(self) -> dict[str, dict[str, Any]]:
|
250
250
|
"""Map head to model, validator, and predictor classes."""
|
251
251
|
return {
|
252
252
|
"detect": {
|
@@ -291,7 +291,7 @@ class YOLOE(Model):
|
|
291
291
|
assert isinstance(self.model, YOLOEModel)
|
292
292
|
return self.model.get_visual_pe(img, visual)
|
293
293
|
|
294
|
-
def set_vocab(self, vocab:
|
294
|
+
def set_vocab(self, vocab: list[str], names: list[str]) -> None:
|
295
295
|
"""
|
296
296
|
Set vocabulary and class names for the YOLOE model.
|
297
297
|
|
@@ -317,7 +317,7 @@ class YOLOE(Model):
|
|
317
317
|
assert isinstance(self.model, YOLOEModel)
|
318
318
|
return self.model.get_vocab(names)
|
319
319
|
|
320
|
-
def set_classes(self, classes:
|
320
|
+
def set_classes(self, classes: list[str], embeddings: torch.Tensor | None = None) -> None:
|
321
321
|
"""
|
322
322
|
Set the model's class names and embeddings for detection.
|
323
323
|
|
@@ -341,7 +341,7 @@ class YOLOE(Model):
|
|
341
341
|
self,
|
342
342
|
validator=None,
|
343
343
|
load_vp: bool = False,
|
344
|
-
refer_data:
|
344
|
+
refer_data: str | None = None,
|
345
345
|
**kwargs,
|
346
346
|
):
|
347
347
|
"""
|
@@ -368,7 +368,7 @@ class YOLOE(Model):
|
|
368
368
|
self,
|
369
369
|
source=None,
|
370
370
|
stream: bool = False,
|
371
|
-
visual_prompts:
|
371
|
+
visual_prompts: dict[str, list] = {},
|
372
372
|
refer_image=None,
|
373
373
|
predictor=yolo.yoloe.YOLOEVPDetectPredictor,
|
374
374
|
**kwargs,
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
+
from __future__ import annotations
|
4
|
+
|
3
5
|
from copy import copy
|
4
6
|
from pathlib import Path
|
5
|
-
from typing import Any
|
7
|
+
from typing import Any
|
6
8
|
|
7
9
|
from ultralytics.models import yolo
|
8
10
|
from ultralytics.nn.tasks import OBBModel
|
@@ -31,7 +33,7 @@ class OBBTrainer(yolo.detect.DetectionTrainer):
|
|
31
33
|
>>> trainer.train()
|
32
34
|
"""
|
33
35
|
|
34
|
-
def __init__(self, cfg=DEFAULT_CFG, overrides:
|
36
|
+
def __init__(self, cfg=DEFAULT_CFG, overrides: dict | None = None, _callbacks: list[Any] | None = None):
|
35
37
|
"""
|
36
38
|
Initialize an OBBTrainer object for training Oriented Bounding Box (OBB) models.
|
37
39
|
|
@@ -57,7 +59,7 @@ class OBBTrainer(yolo.detect.DetectionTrainer):
|
|
57
59
|
super().__init__(cfg, overrides, _callbacks)
|
58
60
|
|
59
61
|
def get_model(
|
60
|
-
self, cfg:
|
62
|
+
self, cfg: str | dict | None = None, weights: str | Path | None = None, verbose: bool = True
|
61
63
|
) -> OBBModel:
|
62
64
|
"""
|
63
65
|
Return OBBModel initialized with specified config and weights.
|