dgenerate-ultralytics-headless 8.3.241__py3-none-any.whl → 8.3.243__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.241.dist-info → dgenerate_ultralytics_headless-8.3.243.dist-info}/METADATA +2 -2
- {dgenerate_ultralytics_headless-8.3.241.dist-info → dgenerate_ultralytics_headless-8.3.243.dist-info}/RECORD +30 -30
- tests/test_exports.py +1 -2
- ultralytics/__init__.py +1 -1
- ultralytics/cfg/__init__.py +1 -1
- ultralytics/data/augment.py +3 -2
- ultralytics/engine/exporter.py +16 -22
- ultralytics/engine/tuner.py +2 -1
- ultralytics/models/sam/predict.py +9 -6
- ultralytics/models/sam/sam3/encoder.py +0 -6
- ultralytics/models/sam/sam3/model_misc.py +2 -1
- ultralytics/models/sam/sam3/vitdet.py +2 -1
- ultralytics/models/yolo/detect/predict.py +2 -1
- ultralytics/nn/autobackend.py +3 -5
- ultralytics/nn/modules/block.py +7 -5
- ultralytics/nn/modules/head.py +3 -2
- ultralytics/trackers/utils/matching.py +1 -1
- ultralytics/utils/callbacks/platform.py +255 -38
- ultralytics/utils/checks.py +5 -0
- ultralytics/utils/export/imx.py +2 -2
- ultralytics/utils/git.py +2 -1
- ultralytics/utils/logger.py +131 -75
- ultralytics/utils/loss.py +6 -8
- ultralytics/utils/metrics.py +2 -1
- ultralytics/utils/ops.py +4 -3
- ultralytics/utils/tqdm.py +2 -1
- {dgenerate_ultralytics_headless-8.3.241.dist-info → dgenerate_ultralytics_headless-8.3.243.dist-info}/WHEEL +0 -0
- {dgenerate_ultralytics_headless-8.3.241.dist-info → dgenerate_ultralytics_headless-8.3.243.dist-info}/entry_points.txt +0 -0
- {dgenerate_ultralytics_headless-8.3.241.dist-info → dgenerate_ultralytics_headless-8.3.243.dist-info}/licenses/LICENSE +0 -0
- {dgenerate_ultralytics_headless-8.3.241.dist-info → dgenerate_ultralytics_headless-8.3.243.dist-info}/top_level.txt +0 -0
ultralytics/utils/loss.py
CHANGED
|
@@ -498,7 +498,7 @@ class v8PoseLoss(v8DetectionLoss):
|
|
|
498
498
|
|
|
499
499
|
def __call__(self, preds: Any, batch: dict[str, torch.Tensor]) -> tuple[torch.Tensor, torch.Tensor]:
|
|
500
500
|
"""Calculate the total loss and detach it for pose estimation."""
|
|
501
|
-
loss = torch.zeros(5, device=self.device) # box,
|
|
501
|
+
loss = torch.zeros(5, device=self.device) # box, pose, kobj, cls, dfl
|
|
502
502
|
feats, pred_kpts = preds if isinstance(preds[0], list) else preds[1]
|
|
503
503
|
pred_distri, pred_scores = torch.cat([xi.view(feats[0].shape[0], self.no, -1) for xi in feats], 2).split(
|
|
504
504
|
(self.reg_max * 4, self.nc), 1
|
|
@@ -560,7 +560,7 @@ class v8PoseLoss(v8DetectionLoss):
|
|
|
560
560
|
loss[3] *= self.hyp.cls # cls gain
|
|
561
561
|
loss[4] *= self.hyp.dfl # dfl gain
|
|
562
562
|
|
|
563
|
-
return loss * batch_size, loss.detach() # loss(box, cls, dfl)
|
|
563
|
+
return loss * batch_size, loss.detach() # loss(box, pose, kobj, cls, dfl)
|
|
564
564
|
|
|
565
565
|
@staticmethod
|
|
566
566
|
def kpts_decode(anchor_points: torch.Tensor, pred_kpts: torch.Tensor) -> torch.Tensor:
|
|
@@ -684,7 +684,7 @@ class v8OBBLoss(v8DetectionLoss):
|
|
|
684
684
|
"""Calculate and return the loss for oriented bounding box detection."""
|
|
685
685
|
loss = torch.zeros(3, device=self.device) # box, cls, dfl
|
|
686
686
|
feats, pred_angle = preds if isinstance(preds[0], list) else preds[1]
|
|
687
|
-
batch_size = pred_angle.shape[0] # batch size
|
|
687
|
+
batch_size = pred_angle.shape[0] # batch size
|
|
688
688
|
pred_distri, pred_scores = torch.cat([xi.view(feats[0].shape[0], self.no, -1) for xi in feats], 2).split(
|
|
689
689
|
(self.reg_max * 4, self.nc), 1
|
|
690
690
|
)
|
|
@@ -702,7 +702,7 @@ class v8OBBLoss(v8DetectionLoss):
|
|
|
702
702
|
try:
|
|
703
703
|
batch_idx = batch["batch_idx"].view(-1, 1)
|
|
704
704
|
targets = torch.cat((batch_idx, batch["cls"].view(-1, 1), batch["bboxes"].view(-1, 5)), 1)
|
|
705
|
-
rw, rh = targets[:, 4] * imgsz[
|
|
705
|
+
rw, rh = targets[:, 4] * float(imgsz[1]), targets[:, 5] * float(imgsz[0])
|
|
706
706
|
targets = targets[(rw >= 2) & (rh >= 2)] # filter rboxes of tiny size to stabilize training
|
|
707
707
|
targets = self.preprocess(targets, batch_size, scale_tensor=imgsz[[1, 0, 1, 0]])
|
|
708
708
|
gt_labels, gt_bboxes = targets.split((1, 5), 2) # cls, xywhr
|
|
@@ -803,7 +803,6 @@ class TVPDetectLoss:
|
|
|
803
803
|
def __call__(self, preds: Any, batch: dict[str, torch.Tensor]) -> tuple[torch.Tensor, torch.Tensor]:
|
|
804
804
|
"""Calculate the loss for text-visual prompt detection."""
|
|
805
805
|
feats = preds[1] if isinstance(preds, tuple) else preds
|
|
806
|
-
assert self.ori_reg_max == self.vp_criterion.reg_max # TODO: remove it
|
|
807
806
|
|
|
808
807
|
if self.ori_reg_max * 4 + self.ori_nc == feats[0].shape[1]:
|
|
809
808
|
loss = torch.zeros(3, device=self.vp_criterion.device, requires_grad=True)
|
|
@@ -811,8 +810,8 @@ class TVPDetectLoss:
|
|
|
811
810
|
|
|
812
811
|
vp_feats = self._get_vp_features(feats)
|
|
813
812
|
vp_loss = self.vp_criterion(vp_feats, batch)
|
|
814
|
-
|
|
815
|
-
return
|
|
813
|
+
cls_loss = vp_loss[0][1]
|
|
814
|
+
return cls_loss, vp_loss[1]
|
|
816
815
|
|
|
817
816
|
def _get_vp_features(self, feats: list[torch.Tensor]) -> list[torch.Tensor]:
|
|
818
817
|
"""Extract visual-prompt features from the model output."""
|
|
@@ -839,7 +838,6 @@ class TVPSegmentLoss(TVPDetectLoss):
|
|
|
839
838
|
def __call__(self, preds: Any, batch: dict[str, torch.Tensor]) -> tuple[torch.Tensor, torch.Tensor]:
|
|
840
839
|
"""Calculate the loss for text-visual prompt segmentation."""
|
|
841
840
|
feats, pred_masks, proto = preds if len(preds) == 3 else preds[1]
|
|
842
|
-
assert self.ori_reg_max == self.vp_criterion.reg_max # TODO: remove it
|
|
843
841
|
|
|
844
842
|
if self.ori_reg_max * 4 + self.ori_nc == feats[0].shape[1]:
|
|
845
843
|
loss = torch.zeros(4, device=self.vp_criterion.device, requires_grad=True)
|
ultralytics/utils/metrics.py
CHANGED
|
@@ -194,7 +194,8 @@ def _get_covariance_matrix(boxes: torch.Tensor) -> tuple[torch.Tensor, torch.Ten
|
|
|
194
194
|
boxes (torch.Tensor): A tensor of shape (N, 5) representing rotated bounding boxes, with xywhr format.
|
|
195
195
|
|
|
196
196
|
Returns:
|
|
197
|
-
(torch.Tensor): Covariance
|
|
197
|
+
(tuple[torch.Tensor, torch.Tensor, torch.Tensor]): Covariance matrix components (a, b, c) where the covariance
|
|
198
|
+
matrix is [[a, c], [c, b]], each of shape (N, 1).
|
|
198
199
|
"""
|
|
199
200
|
# Gaussian bounding boxes, ignore the center points (the first two columns) because they are not needed here.
|
|
200
201
|
gbbs = torch.cat((boxes[:, 2:4].pow(2) / 12, boxes[:, 4:]), dim=-1)
|
ultralytics/utils/ops.py
CHANGED
|
@@ -604,11 +604,11 @@ def regularize_rboxes(rboxes):
|
|
|
604
604
|
return torch.stack([x, y, w_, h_, t], dim=-1) # regularized boxes
|
|
605
605
|
|
|
606
606
|
|
|
607
|
-
def masks2segments(masks, strategy: str = "all"):
|
|
607
|
+
def masks2segments(masks: np.ndarray | torch.Tensor, strategy: str = "all") -> list[np.ndarray]:
|
|
608
608
|
"""Convert masks to segments using contour detection.
|
|
609
609
|
|
|
610
610
|
Args:
|
|
611
|
-
masks (torch.Tensor): Binary masks with shape (batch_size, 160, 160).
|
|
611
|
+
masks (np.ndarray | torch.Tensor): Binary masks with shape (batch_size, 160, 160).
|
|
612
612
|
strategy (str): Segmentation strategy, either 'all' or 'largest'.
|
|
613
613
|
|
|
614
614
|
Returns:
|
|
@@ -616,8 +616,9 @@ def masks2segments(masks, strategy: str = "all"):
|
|
|
616
616
|
"""
|
|
617
617
|
from ultralytics.data.converter import merge_multi_segment
|
|
618
618
|
|
|
619
|
+
masks = masks.astype("uint8") if isinstance(masks, np.ndarray) else masks.byte().cpu().numpy()
|
|
619
620
|
segments = []
|
|
620
|
-
for x in
|
|
621
|
+
for x in np.ascontiguousarray(masks):
|
|
621
622
|
c = cv2.findContours(x, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
|
|
622
623
|
if c:
|
|
623
624
|
if strategy == "all": # merge and concatenate all segments
|
ultralytics/utils/tqdm.py
CHANGED
|
@@ -179,7 +179,8 @@ class TQDM:
|
|
|
179
179
|
num /= self.unit_divisor
|
|
180
180
|
return f"{num:.1f}PB"
|
|
181
181
|
|
|
182
|
-
|
|
182
|
+
@staticmethod
|
|
183
|
+
def _format_time(seconds: float) -> str:
|
|
183
184
|
"""Format time duration."""
|
|
184
185
|
if seconds < 60:
|
|
185
186
|
return f"{seconds:.1f}s"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|