Skip to content

anchor

Anchor-based detection losses for the voxel detectors (SECOND, PointPillars).

  • AnchorLoss: the single-group head loss used by the KITTI SECOND / PointPillars detectors (focal cls, sine-difference smooth-\(L_1\) box, direction bin).
  • MultiHeadAnchorLoss: the separate-multihead loss used by the nuScenes detectors (per-head focal cls, sincos + velocity \(L_1\) box).

Classes:

  • AnchorLoss –

    Single-stage anchor detection loss (classification, box regression, direction).

  • MultiHeadAnchorLoss –

    Separate-multihead anchor detection loss (per-head classification, sincos + velocity box regression).

Functions:

  • sigmoid_focal_loss –

    Anchor-wise weighted sigmoid focal loss (no reduction).

  • one_hot_foreground –

    One-hot encode per-anchor class labels, dropping the background column.

AnchorLoss

AnchorLoss(
    num_classes: int,
    *,
    voxel_size: Sequence[float],
    point_cloud_range: Sequence[float],
    anchor_sizes: Sequence[Sequence[float]],
    anchor_bottom_heights: Sequence[float],
    feature_map_stride: int,
    matched_thresholds: Sequence[float],
    unmatched_thresholds: Sequence[float],
    anchor_rotations: Sequence[float] = (0.0, 1.57),
    code_weights: Sequence[float] = (
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
    ),
    cls_weight: float = 1.0,
    loc_weight: float = 2.0,
    dir_weight: float = 0.2,
    num_dir_bins: int = 2,
    dir_offset: float = 0.78539,
    dir_limit_offset: float = 0.0,
    focal_alpha: float = 0.25,
    focal_gamma: float = 2.0,
    smooth_l1_beta: float = 1.0 / 9.0,
    match_height: bool = False,
)

Bases: Module

Single-stage anchor detection loss (classification, box regression, direction).

Reference: Yan et al., 2018.

The loss of the single-group anchor head used by SECOND and PointPillars. Per scene each class's axis-aligned anchors are matched to that class's ground-truth boxes (assign_anchor_targets) using per-class IoU thresholds, giving per-anchor class labels (\(-1\) ignore, \(0\) background, \(\ge 1\) foreground) and residual box targets. Three terms are then summed:

  • Classification: sigmoid focal loss over one-hot foreground labels, weighted so ignored anchors contribute nothing and each scene is normalized by its positive count.
  • Box regression: code-weighted smooth-\(L_1\) of the residual encodings, with the heading channel replaced by the sine-difference encoding \(\sin(\theta_p)\cos(\theta_g)\) vs \(\cos(\theta_p)\sin(\theta_g)\) so the smooth-\(L_1\) acts on \(\sin(\theta_p - \theta_g)\).
  • Direction: weighted softmax cross-entropy over the discretized heading bin.

Anchors are rebuilt in the constructor from the same geometry the head uses (generate_anchors); the loss holds no reference to the model.

Parameters:

  • num_classes (int) –

    Number of foreground classes.

  • voxel_size (Sequence[float]) –

    Voxel size \((v_x, v_y, v_z)\) (used with point_cloud_range to size the anchor grid).

  • point_cloud_range (Sequence[float]) –

    Range \((x_\min, y_\min, z_\min, x_\max, y_\max, z_\max)\).

  • anchor_sizes (Sequence[Sequence[float]]) –

    Per-class box size \((d_x, d_y, d_z)\), one row per class.

  • anchor_bottom_heights (Sequence[float]) –

    Per-class anchor bottom \(z\), one per class.

  • feature_map_stride (int) –

    BEV feature-map stride of the head.

  • matched_thresholds (Sequence[float]) –

    Per-class IoU at or above which an anchor is a positive.

  • unmatched_thresholds (Sequence[float]) –

    Per-class IoU below which an anchor is background.

  • anchor_rotations (Sequence[float], default: (0.0, 1.57) ) –

    Yaw angles (radians) shared by all classes.

  • code_weights (Sequence[float], default: (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0) ) –

    Per-code regression weights, shape \((7,)\).

  • cls_weight (float, default: 1.0 ) –

    Weight of the classification term in the total.

  • loc_weight (float, default: 2.0 ) –

    Weight of the box-regression term in the total.

  • dir_weight (float, default: 0.2 ) –

    Weight of the direction term in the total.

  • num_dir_bins (int, default: 2 ) –

    Number of direction bins.

  • dir_offset (float, default: 0.78539 ) –

    Direction-target angle offset.

  • dir_limit_offset (float, default: 0.0 ) –

    Offset used when wrapping the heading before binning.

  • focal_alpha (float, default: 0.25 ) –

    Focal-loss positive/negative balance.

  • focal_gamma (float, default: 2.0 ) –

    Focal-loss focusing exponent.

  • smooth_l1_beta (float, default: 1.0 / 9.0 ) –

    Smooth-\(L_1\) transition point \(\beta\).

  • match_height (bool, default: False ) –

    Match anchors to boxes by 3D IoU when True, otherwise bird's-eye IoU.

Methods:

  • forward –

    Compute the anchor detection loss and its components.

forward

forward(
    output: Dict[str, Tensor], batch: Dict[str, Any]
) -> Dict[str, Tensor]

Compute the anchor detection loss and its components.

Parameters:

  • output (Dict[str, Tensor]) –

    The head's raw output: cls \((B, H, W, A_\text{loc} \cdot C)\), box \((B, H, W, A_\text{loc} \cdot 7)\) and dir_cls \((B, H, W, A_\text{loc} \cdot 2)\).

  • batch (Dict[str, Any]) –

    Ground truth: packed box \((K, 7)\) full-extent, label \((K,)\) (\(0\)-based classes) and batch_box \((K,)\) per-box scene index.

Returns:

  • Dict[str, Tensor] –

    A dict with the scalar loss (to backprop) and detached cls_loss, box_loss, dir_loss.

MultiHeadAnchorLoss

MultiHeadAnchorLoss(
    num_classes: int,
    *,
    class_groups: Sequence[Sequence[int]],
    voxel_size: Sequence[float],
    point_cloud_range: Sequence[float],
    anchor_sizes: Sequence[Sequence[float]],
    anchor_bottom_heights: Sequence[float],
    feature_map_stride: int,
    matched_thresholds: Sequence[float],
    unmatched_thresholds: Sequence[float],
    anchor_rotations: Sequence[float] = (0.0, 1.57),
    code_weights: Sequence[float] = (
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        1.0,
        0.0,
        0.0,
    ),
    cls_weight: float = 1.0,
    loc_weight: float = 0.25,
    pos_cls_weight: float = 1.0,
    neg_cls_weight: float = 2.0,
    focal_alpha: float = 0.25,
    focal_gamma: float = 2.0,
    match_height: bool = False,
    encode_angle_by_sincos: bool = True,
)

Bases: Module

Separate-multihead anchor detection loss (per-head classification, sincos + velocity box regression).

Reference: Zhu et al., 2019.

The loss of the separate-multihead anchor head used by the nuScenes SECOND and PointPillars detectors, where several RPN heads each own a disjoint class group over a shared feature map. Per scene each class's axis-aligned anchors are matched to that class's ground-truth boxes (assign_anchor_targets) using per-class IoU thresholds, giving per-anchor class labels (\(-1\) ignore, \(0\) background, \(\ge 1\) foreground) and residual box targets. Two terms are summed:

  • Classification: per head, sigmoid focal loss over the one-hot labels restricted to that head's class columns, with positive / negative anchors weighted by pos_cls_weight / neg_cls_weight and each scene normalized by its total positive count.
  • Box regression: per head, code-weighted \(L_1\) over the \(10\)-dim box code \((x, y, z, d_x, d_y, d_z, \cos\Delta\theta, \sin\Delta\theta, v_x, v_y)\). The heading is encoded as a \((\cos, \sin)\) residual, so no separate direction classifier is used.

Note

The nuScenes ground-truth boxes carry no velocity (\((K, 7)\)), so the velocity targets are zero. Set the last two code_weights entries to \(0\) to leave the velocity branch unsupervised; the default does so.

Anchors are rebuilt in the constructor from the same geometry the head uses (generate_anchors), in the head's class-group order; the loss holds no reference to the model.

Parameters:

  • num_classes (int) –

    Number of foreground classes (10 for nuScenes).

  • class_groups (Sequence[Sequence[int]]) –

    Class-index groups, one per RPN head (e.g. [[0], [1, 2], ...]), matching the head's head_class_groups; the classes in each group share one head, and the flattened groups must enumerate the classes \(0 \ldots C - 1\) in ascending order (the anchor / head layout).

  • voxel_size (Sequence[float]) –

    Voxel size \((v_x, v_y, v_z)\) (used with point_cloud_range to size the anchor grid).

  • point_cloud_range (Sequence[float]) –

    Range \((x_\min, y_\min, z_\min, x_\max, y_\max, z_\max)\).

  • anchor_sizes (Sequence[Sequence[float]]) –

    Per-class box size \((d_x, d_y, d_z)\), one row per class.

  • anchor_bottom_heights (Sequence[float]) –

    Per-class anchor bottom \(z\), one per class.

  • feature_map_stride (int) –

    BEV feature-map stride of the head.

  • matched_thresholds (Sequence[float]) –

    Per-class IoU at or above which an anchor is a positive.

  • unmatched_thresholds (Sequence[float]) –

    Per-class IoU below which an anchor is background.

  • anchor_rotations (Sequence[float], default: (0.0, 1.57) ) –

    Yaw angles (radians) shared by all classes.

  • code_weights (Sequence[float], default: (1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0) ) –

    Per-code regression weights, shape \((10,)\); the last two (velocity) default to \(0\).

  • cls_weight (float, default: 1.0 ) –

    Weight of the classification term in the total.

  • loc_weight (float, default: 0.25 ) –

    Weight of the box-regression term in the total.

  • pos_cls_weight (float, default: 1.0 ) –

    Classification weight of a positive anchor.

  • neg_cls_weight (float, default: 2.0 ) –

    Classification weight of a background anchor.

  • focal_alpha (float, default: 0.25 ) –

    Focal-loss positive/negative balance.

  • focal_gamma (float, default: 2.0 ) –

    Focal-loss focusing exponent.

  • match_height (bool, default: False ) –

    Match anchors to boxes by 3D IoU when True, otherwise bird's-eye IoU.

  • encode_angle_by_sincos (bool, default: True ) –

    Encode the heading residual as \((\cos, \sin)\) (always True for this head).

Methods:

  • forward –

    Compute the multihead anchor detection loss and its components.

forward

forward(
    output: AnchorHeadMultiOutput, batch: Dict[str, Any]
) -> Dict[str, Tensor]

Compute the multihead anchor detection loss and its components.

Parameters:

  • output (AnchorHeadMultiOutput) –

    The head's raw output: per-head cls \((B, A_g, C_g)\) and box \((B, A_g, 10)\) lists, plus multihead_label_mapping (per-head 1-based global class indices).

  • batch (Dict[str, Any]) –

    Ground truth: packed box \((K, 7)\) full-extent, label \((K,)\) (\(0\)-based classes) and batch_box \((K,)\) per-box scene index.

Returns:

  • Dict[str, Tensor] –

    A dict with the scalar loss (to backprop) and detached cls_loss, box_loss, dir_loss; the

  • Dict[str, Tensor] –

    separate-multihead head carries no direction classifier, so dir_loss is always zero.

sigmoid_focal_loss

sigmoid_focal_loss(
    preds: Tensor,
    targets: Tensor,
    weights: Tensor,
    *,
    alpha: float,
    gamma: float,
) -> Tensor

Anchor-wise weighted sigmoid focal loss (no reduction).

The classification primitive shared by the anchor heads: sigmoid focal cross-entropy between per-class logits and their one-hot targets, scaled by a per-anchor weight.

Parameters:

  • preds (Tensor) –

    Per-class logits, shape \((B, A, C)\).

  • targets (Tensor) –

    One-hot foreground targets, shape \((B, A, C)\).

  • weights (Tensor) –

    Per-anchor weights, shape \((B, A)\).

  • alpha (float) –

    Positive/negative balance.

  • gamma (float) –

    Focusing exponent.

Returns:

  • Tensor –

    The weighted per-element loss, shape \((B, A, C)\).

Shape
  • preds: \((B, A, C)\)
  • targets: \((B, A, C)\)
  • weights: \((B, A)\)
  • output: \((B, A, C)\)
Example
>>> preds = torch.zeros(1, 2, 3)
>>> targets = torch.tensor([[[1.0, 0.0, 0.0], [0.0, 0.0, 0.0]]])
>>> weights = torch.ones(1, 2)
>>> sigmoid_focal_loss(preds, targets, weights, alpha=0.25, gamma=2.0).shape
torch.Size([1, 2, 3])

one_hot_foreground

one_hot_foreground(
    box_cls_labels: Tensor, num_classes: int
) -> Tensor

One-hot encode per-anchor class labels, dropping the background column.

Ignored (\(-1\)) and background (\(0\)) anchors map to an all-zero row; a foreground anchor with label \(\ell \ge 1\) maps to a one-hot row on class \(\ell - 1\).

Parameters:

  • box_cls_labels (Tensor) –

    Per-anchor class labels (\(-1\) ignore, \(0\) background, \(\ge 1\) foreground), shape \((B, A)\).

  • num_classes (int) –

    Number of foreground classes.

Returns:

  • Tensor –

    One-hot foreground targets, shape \((B, A, C)\).

Shape
  • box_cls_labels: \((B, A)\)
  • output: \((B, A, C)\)
Example
>>> one_hot_foreground(torch.tensor([[2, 0, -1]]), 3).tolist()
[[[0.0, 1.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]]