instance_segmentation
Point-mask instance-segmentation metrics: per-scene instance matches and their average precision.
Classes:
-
InstanceMatchesβOne scene of predicted instance masks reduced against its ground truth (the output of
instance_matches).
Functions:
-
instance_matchesβReduce one scene's instance predictions to the compact match record scored by
instance_average_precision. -
instance_average_precisionβPoint-mask instance-segmentation average precision (AP) of matched instance predictions.
InstanceMatches [source] ΒΆ
Bases: TypedDict
One scene of predicted instance masks reduced against its ground truth (the output of instance_matches).
Holds per-instance counts and pairwise intersections only, nothing mask-sized: \(K\) predictions, \(I\) ground-truth instances (ordered by ascending id) and \(M\) same-class (prediction, instance) pairs with a nonzero intersection.
Attributes:
-
pred_labels(Tensor) βPer-prediction class, shape \((K,)\).
-
pred_scores(Tensor) βPer-prediction confidence score, shape \((K,)\).
-
pred_counts(Tensor) βPer-prediction point count, shape \((K,)\).
-
pred_void(Tensor) βPer-prediction count of void points (ignored label or no instance), shape \((K,)\).
-
gt_labels(Tensor) βPer-instance class, shape \((I,)\).
-
gt_counts(Tensor) βPer-instance point count, shape \((I,)\).
-
pair_pred(Tensor) βPrediction index of each overlapping pair, shape \((M,)\).
-
pair_gt(Tensor) βInstance index of each overlapping pair, shape \((M,)\).
-
pair_inter(Tensor) βNumber of points shared by each overlapping pair, shape \((M,)\).
instance_matches [source] ΒΆ
instance_matches(
pred_masks: Tensor,
pred_labels: Tensor,
pred_scores: Tensor,
gt_instance: Tensor,
gt_label: Tensor,
*,
ignore_index: int = -1,
) -> InstanceMatches
Reduce one scene's instance predictions to the compact match record scored by instance_average_precision.
Predicted masks are dense \((K, N)\) booleans: a few hundred masks over a \(\sim 50\text{k}\)-point scene is only tens of MB and intersections reduce to bincounts, while index lists would be ragged and no smaller. The returned record holds per-instance counts and pairwise intersections only, so nothing mask-sized outlives the call and a whole validation split can be accumulated scene by scene.
Ground truth instances are the unique gt_instance ids among points with a non-negative id and a valid semantic label; points whose gt_label equals ignore_index are void, and predictions overlapping them are excused accordingly during scoring. Each instance must carry a single semantic label. Intersections are recorded for same-class (prediction, instance) pairs only.
Parameters:
-
pred_masks(Tensor) βPer-instance point masks, shape \((K, N)\) bool.
-
pred_labels(Tensor) βPer-instance class indices, shape \((K,)\).
-
pred_scores(Tensor) βPer-instance confidences, shape \((K,)\).
-
gt_instance(Tensor) βPer-point ground-truth instance ids, shape \((N,)\); negative marks no instance.
-
gt_label(Tensor) βPer-point semantic labels in the instance-class space, shape \((N,)\).
-
ignore_index(int, default:-1) βSemantic label marking void points.
Returns:
-
InstanceMatchesβThe
InstanceMatchesrecord of the scene, as CPU tensors.
Example
>>> masks = torch.tensor([[True, True, True, True]])
>>> match = instance_matches(
... masks, torch.tensor([0]), torch.tensor([0.9]), torch.tensor([0, 0, 1, -1]), torch.tensor([0, 0, 0, -1])
... )
>>> match["gt_counts"].tolist(), match["pair_inter"].tolist(), match["pred_void"].tolist()
([2, 1], [2, 1], [1])
instance_average_precision [source] ΒΆ
instance_average_precision(
matches: Sequence[InstanceMatches],
*,
iou_threshold: Union[float, Sequence[float]] = ...,
average: Literal["macro"] = ...,
num_classes: Optional[int] = ...,
class_names: Optional[Sequence[str]] = ...,
min_points: int = ...,
) -> float
instance_average_precision(
matches: Sequence[InstanceMatches],
*,
iou_threshold: Union[float, Sequence[float]] = ...,
average: Literal["none"],
num_classes: Optional[int] = ...,
class_names: None = ...,
min_points: int = ...,
) -> Tensor
instance_average_precision(
matches: Sequence[InstanceMatches],
*,
iou_threshold: Union[float, Sequence[float]] = ...,
average: Literal["none"],
num_classes: Optional[int] = ...,
class_names: Sequence[str],
min_points: int = ...,
) -> Dict[str, float]
instance_average_precision(
matches: Sequence[InstanceMatches],
*,
iou_threshold: Union[float, Sequence[float]] = (
0.5,
0.55,
0.6,
0.65,
0.7,
0.75,
0.8,
0.85,
0.9,
),
average: Literal["macro", "none"] = "macro",
num_classes: Optional[int] = None,
class_names: Optional[Sequence[str]] = None,
min_points: int = 100,
) -> Union[float, Tensor, Dict[str, float]]
Point-mask instance-segmentation average precision (AP) of matched instance predictions.
Follows the standard indoor instance-segmentation protocol (the ScanNet benchmark): per class and IoU threshold, ground-truth instances greedily consume overlapping predicted masks above the threshold, duplicates on a matched instance count as false positives with the lower score, and an unmatched prediction whose void / small-instance point fraction exceeds the threshold is excused. The AP integrates the score-swept precision-recall curve with centered recall steps, and is averaged over the IoU thresholds: the default sweep \(0.5, 0.55, \ldots, 0.9\) is the benchmark's headline AP, iou_threshold=0.5 and 0.25 its AP50 and AP25. A class is scored when it has ground truth.
Parameters:
-
matches(Sequence[InstanceMatches]) βThe
instance_matchesrecord of every evaluated scene. -
iou_threshold(Union[float, Sequence[float]], default:(0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9)) βIoU a match must exceed, or a sequence of them to average the AP over.
-
average(Literal['macro', 'none'], default:'macro') β"macro"returns the mean AP (mAP) over the scored classes;"none"returns the per-class AP. -
num_classes(Optional[int], default:None) βNumber of instance classes, i.e. the length of the
average="none"output; defaults to the number ofclass_names, else to the largest class index met plus one. -
class_names(Optional[Sequence[str]], default:None) βName of each class index; with
average="none"the per-class AP comes back as a{name: ap}dict instead of a tensor. -
min_points(int, default:100) βMinimum point count for a prediction or ground-truth instance to be scored; smaller ground-truth instances count as ignore regions.
Returns:
-
Union[float, Tensor, Dict[str, float]]βThe mAP as a float with
average="macro"(\(0\) when no class is scored), or the per-class AP, shape -
Union[float, Tensor, Dict[str, float]]β\((C,)\) float64, with
average="none"(a{name: ap}dict whenclass_namesis given), holding NaN -
Union[float, Tensor, Dict[str, float]]βfor the classes without ground truth.
Shape
- output: scalar, or \((C,)\) with
average="none"
Example
>>> masks = torch.tensor([[True, True, True, False], [False, False, False, True]])
>>> match = instance_matches(
... masks,
... torch.tensor([0, 1]),
... torch.tensor([0.9, 0.8]),
... torch.tensor([0, 0, 0, 1]),
... torch.tensor([0, 0, 0, 1]),
... )
>>> instance_average_precision([match], min_points=1)
1.0
>>> instance_average_precision([match], iou_threshold=0.5, average="none", class_names=["chair", "table"], min_points=1)
{'chair': 1.0, 'table': 1.0}