{"record":{"id":"761f68ced99de61b","repo":"WZMIAOMIAO/deep-learning-for-image-processing","slug":"no-proposal-boxes-available-for-one-of-the-images-761f68","errorCode":null,"errorMessage":"No proposal boxes available for one of the images during training","messagePattern":"No proposal boxes available for one of the images during training","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pytorch_object_detection/retinaNet/network_files/det_utils.py","lineNumber":320,"sourceCode":"        计算anchors与每个gtboxes匹配的iou最大值，并记录索引，\n        iou<low_threshold索引值为-1， low_threshold<=iou<high_threshold索引值为-2\n        Args:\n            match_quality_matrix (Tensor[float]): an MxN tensor, containing the\n            pairwise quality between M ground-truth elements and N predicted elements.\n\n        Returns:\n            matches (Tensor[int64]): an N tensor where N[i] is a matched gt in\n            [0, M - 1] or a negative value indicating that prediction i could not\n            be matched.\n        \"\"\"\n        if match_quality_matrix.numel() == 0:\n            # empty targets or proposals not supported during training\n            if match_quality_matrix.shape[0] == 0:\n                raise ValueError(\n                    \"No ground-truth boxes available for one of the images \"\n                    \"during training\")\n            else:\n                raise ValueError(\n                    \"No proposal boxes available for one of the images \"\n                    \"during training\")\n\n        # match_quality_matrix is M (gt) x N (predicted)\n        # Max over gt elements (dim 0) to find best gt candidate for each prediction\n        # M x N 的每一列代表一个anchors与所有gt的匹配iou值\n        # matched_vals代表每列的最大值，即每个anchors与所有gt匹配的最大iou值\n        # matches对应最大值所在的索引\n        matched_vals, matches = match_quality_matrix.max(dim=0)  # the dimension to reduce.\n        if self.allow_low_quality_matches:\n            all_matches = matches.clone()\n        else:\n            all_matches = None\n\n        # Assign candidate matches with low quality to negative (unassigned) values\n        # 计算iou小于low_threshold的索引\n        below_low_threshold = matched_vals < self.low_threshold\n        # 计算iou在low_threshold与high_threshold之间的索引值","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/WZMIAOMIAO/deep-learning-for-image-processing/blob/1ec3fe6f374fc9969973a61f819de25658595afa/pytorch_object_detection/retinaNet/network_files/det_utils.py#L302-L338","documentation":"Same Matcher.__call__ guard as the empty ground-truth case, but the else branch: the IoU matrix is empty because there are zero columns, i.e. no proposal/anchor boxes were produced for one image during training. RetinaNet normally generates tens of thousands of anchors, so this usually means anchors were entirely filtered or input boxes were degenerate before anchor sampling.","triggerScenarios":"Training where proposed_boxes/anchors list is empty for an image (match_quality_matrix.shape[1]==0, shape[0]>0): typically downstream of all anchors being discarded by size/cropping filters after extreme resizes, or an empty proposals tensor passed to assign_targets_to_proposals.","commonSituations":"Extreme image sizes (e.g. tiny images after resize producing zero valid anchors); custom backbones/FPN changes dropping all feature-map anchors; feeding pre-computed proposals that ended up empty; corrupted boxes causing earlier filtering to remove everything.","solutions":["Check input image sizes; ensure min/max resize keeps spatial dimensions large enough to generate anchors.","Inspect the transform pipeline (GeneralizedRCNNTransform) so images are not resized to degenerate shapes.","If supplying custom anchors/proposals, verify each image contributes at least one box.","Confirm GT boxes are valid (non-degenerate) so downstream filtering does not wipe out all candidates."],"exampleFix":"// before\nfeatures = self.backbone(images.tensors)  # images may be tiny after bad resize\n// after\nassert all(min(s) >= 32 for s in images.tensors.shape[-2:]), \"image too small to generate anchors\"\nfeatures = self.backbone(images.tensors)","handlingStrategy":"validation","validationCode":"assert images.tensors.shape[-1] >= 32 and images.tensors.shape[-2] >= 32, \"image too small for anchor generation\"","typeGuard":"def anchors_available(model, images) -> bool:\n    features = model.backbone(images.tensors)\n    return any(f.shape[-1] > 0 and f.shape[-2] > 0 for f in (features.values() if isinstance(features, dict) else [features]))","tryCatchPattern":"try:\n    loss_dict = model(images, targets)\nexcept ValueError as e:\n    if \"No proposal boxes\" in str(e):\n        log.warning(\"no anchors/proposals for an image; check sizes\", exc_info=True)\n        continue\n    raise","preventionTips":["Keep min image size above the anchor stride (>= 32 px) after transforms.","Avoid custom transforms that can resize images to degenerate dimensions.","If injecting proposals manually, assert at least one per image.","Unit-test the transform pipeline on the smallest expected image size."],"tags":["pytorch","object-detection","training","anchors"],"backgroundTag":"empty-proposal-boxes","analyzedSha":"1ec3fe6f374fc9969973a61f819de25658595afa","analyzedAt":"2026-08-30T09:19:11.901Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}