WZMIAOMIAO/deep-learning-for-image-processing · error · ValueError
All bounding boxes should have positive height and width. Fo
Error message
All bounding boxes should have positive height and width. Found invalid box {} for target at index {}. What it means
During training forward, RetinaNet checks every target for degenerate boxes where x2 <= x1 or y2 <= y1 (non-positive width/height) and raises ValueError identifying the first invalid box and the target index. Degenerate boxes break IoU computation and anchor assignment downstream.
Source
Thrown at pytorch_object_detection/retinaNet/network_files/retinanet.py:490
for img in images:
val = img.shape[-2:]
assert len(val) == 2
original_img_sizes.append((val[0], val[1])) # h, w
# transform the input
images, targets = self.transform(images, targets)
# Check for degenerate boxes
# TODO: Move this to a function
if targets is not None:
for target_idx, target in enumerate(targets):
boxes = target["boxes"]
degenerate_boxes = boxes[:, 2:] <= boxes[:, :2]
if degenerate_boxes.any():
# print the first degenerate box
bb_idx = torch.where(degenerate_boxes.any(dim=1))[0][0]
degen_bb: List[float] = boxes[bb_idx].tolist()
raise ValueError("All bounding boxes should have positive height and width."
" Found invalid box {} for target at index {}."
.format(degen_bb, target_idx))
# get the features from the backbone
features = self.backbone(images.tensors)
if isinstance(features, torch.Tensor):
features = OrderedDict([("0", features)])
features = list(features.values())
# compute the retinanet heads outputs using the features
head_outputs = self.head(features)
# create the set of anchors
anchors = self.anchor_generator(images, features)
losses = {}
detections: List[Dict[str, Tensor]] = []View on GitHub (pinned to 1ec3fe6f37)
Solutions
- Sanitize annotations: drop or fix boxes where x2 <= x1 or y2 <= y1 before training.
- Verify coordinate format is xyxy (top-left, bottom-right), not xywh or cxcywh.
- Clip boxes then re-filter degenerates after clipping to image boundaries.
- Assert in the Dataset: assert (boxes[:, 2:] > boxes[:, :2]).all() before returning the target.
Example fix
// before
boxes = torch.as_tensor(raw_boxes, dtype=torch.float32)
target = {"boxes": boxes, "labels": labels}
// after
boxes = torch.as_tensor(raw_boxes, dtype=torch.float32)
keep = (boxes[:, 2:] > boxes[:, :2]).all(dim=1)
boxes, labels = boxes[keep], labels[keep] # drop degenerate boxes
target = {"boxes": boxes, "labels": labels} Defensive patterns
Strategy: validation
Validate before calling
import torch
for i, t in enumerate(targets):
boxes = t["boxes"]
if ((boxes[:, 2:] <= boxes[:, :2]).any()):
bad = boxes[(boxes[:, 2:] <= boxes[:, :2]).any(dim=1)]
print(f"target {i} has degenerate boxes: {bad.tolist()}") Type guard
def boxes_are_valid(boxes) -> bool:
import torch
if not isinstance(boxes, torch.Tensor) or boxes.numel() == 0:
return True
return bool((boxes[:, 2:] > boxes[:, :2]).all()) Try / catch
try:
outputs = model(images, targets)
except ValueError as e:
if "positive height and width" in str(e):
targets = [sanitize_boxes(t) for t in targets] # drop degenerate rows
outputs = model(images, targets)
else:
raise Prevention
- Sanitize annotations (drop zero/negative-area boxes) at dataset build time.
- Confirm the coordinate format is xyxy before inserting into targets.
- After clip-to-image, re-filter boxes collapsed to zero area.
- Assert box validity in __getitem__ so bad data fails early with context.
When it happens
Trigger: Annotations containing zero-area boxes (x1==x2 or y1==y2), negative width/height from wrong coordinate order (x_min > x_max), or boxes in [cx, cy, w, h] format passed as xyxy; coordinates flipped after resize/clipping transforms.
Common situations: Datasets converted between xyxy/xywh formats incorrectly; annotation tools exporting empty boxes for invisible objects; clip-to-image operations that collapse boxes to zero width at image borders; single-point objects (keypoints) labeled as boxes.
Related errors
- No ground-truth boxes available for one of the images during
- No proposal boxes available for one of the images during tra
- backbone should contain an attribute out_channels specifying
- In training mode, targets should be passed
- Expected target boxes to be a tensorof shape [N, 4], got {:}
AI-assisted analysis of WZMIAOMIAO/deep-learning-for-image-processing@1ec3fe6f37 (2026-08-30).
Data as JSON: /api/errors/80f57c8bf1e7b402.
Report an issue: GitHub.