Skip to content

Overview

Training criteria.

Generic losses are plain (input, target) modules, each next to its tensor function, which functional re-exports. The detection losses are named after the head (or model) whose output they read and assign their targets from the packed box / label / batch_box ground truth; their forward(output, data) returns a dict with the scalar loss to optimize plus its detached named terms (<term>_loss). The generic losses return a tensor; a training loop accepts either.

Modules:

  • anchor –

    Losses of the anchor-based BEV detection heads (SECOND, PointPillars and the multi-group nuScenes variants).

  • centerpoint –

    Losses of the center-based detection heads, dense (CenterHead) and fully sparse (VoxelNeXtHead).

  • chamfer –

    Chamfer distance between packed point sets.

  • corner –

    Corner loss of the box-refinement heads (PointRCNN).

  • focal –

    Focal losses: the sigmoid focal loss of the anchor / point / query heads, the Gaussian focal loss of the heatmap heads

  • functional –

    Functional API of the losses: the tensor function of every themed module, re-exported here in the spirit of

  • kpconv –

    Fitting and repulsive regularizer of deformable kernel point convolutions.

  • lovasz –

    LovΓ‘sz-Softmax loss.

  • matching –

    Set-prediction matching between predictions and ground-truth objects.

  • pointrcnn –

    Two-stage PointRCNN detection loss: stage-1 per-point head and stage-2 ROI refinement.

  • sum –

    Weighted sum of several (logits, target) losses.

  • threedetr –

    3DETR set-prediction detection loss: Hungarian query-to-object matching with per-layer aux losses.

  • tnet –

    Orthogonality regularizer of the T-Net transforms (PointNet's feature-transform regularization).

  • transfusion –

    Loss of the query-based TransFusionHead (LION): Hungarian-matched query targets and a dense center heatmap.

  • votenet –

    VoteNet detection loss: deep Hough voting target assignment and multi-task objective.

Classes:

Functions:

  • chamfer_distance –

    Symmetric Chamfer distance between packed point sets.

  • corner_loss –

    Per-box mean smooth-\(L_1\) distance between the eight corners of two box sets, robust to the heading flip.

  • gaussian_focal_loss –

    Penalty-reduced focal loss over a Gaussian heatmap, normalized by the number of peaks.

  • one_hot_foreground –

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

  • poly1_focal_loss –

    Poly-1 focal loss between per-class logits and binary targets (no reduction).

  • sigmoid_focal_loss –

    Sigmoid focal loss between per-class logits and binary targets (no reduction).

  • kpconv_deform_regularizer –

    Regularize the deformed kernel points of every deformable KPConv in module.

  • lovasz_softmax –

    Multi-class LovΓ‘sz-Softmax loss over per-point class probabilities.

  • hungarian_match –

    One-to-one assignment of predictions to targets minimizing the total cost (Hungarian algorithm).

  • hungarian_match_batched –

    One-to-one assignment of every scene's predictions to its targets, with a single device transfer.

  • tnet_orthogonality_regularizer –

    Pull the transforms predicted by every T-Net in module towards an orthogonal matrix.

AnchorHeadLoss [source] ΒΆ

AnchorHeadLoss(
    num_classes: int,
    *,
    point_cloud_range: Sequence[float],
    voxel_size: 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

Loss of the single-group AnchorHead (SECOND, PointPillars).

Reference: SECOND: Sparsely Embedded Convolutional Detection (Yan et al., 2018).

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 residual replaced by \(\sin(\theta_p - \theta_g)\) (the sine-difference encoding) so a half-turn error is not penalized as a position error.
  • 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.

  • point_cloud_range (Sequence[float]) –

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

  • voxel_size (Sequence[float]) –

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

  • 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 the rotated 3D IoU when True, otherwise by the bird's-eye IoU of the boxes snapped to their nearest axis-aligned orientation.

Methods:

  • forward –

    Compute the anchor detection loss and its terms.

forward [source] ΒΆ

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

Compute the anchor detection loss and its terms.

Parameters:

  • output (AnchorHeadOutput) –

    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)\).

  • data (Dict[str, Any]) –

    Ground truth: packed box \((K, 7)\) full-extent (the velocity columns of \((K, 9)\) boxes are ignored), label \((K,)\) (\(0\)-based classes) and batch_box \((K,)\) per-box scene index.

Returns:

  • Dict[str, Tensor] –

    A dict with the scalar loss and detached cls_loss, box_loss, dir_loss.

MultiGroupAnchorHeadLoss [source] ΒΆ

MultiGroupAnchorHeadLoss(
    num_classes: int,
    *,
    class_groups: Sequence[Sequence[int]],
    point_cloud_range: Sequence[float],
    voxel_size: 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

Loss of the MultiGroupAnchorHead (nuScenes SECOND, PointPillars).

Reference: Class-balanced Grouping and Sampling for Point Cloud 3D Object Detection (Zhu et al., 2019).

The separate-multihead anchor head has several RPN heads, each owning 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

Ground-truth boxes of \((K, 9)\) columns carry the velocity \((v_x, v_y)\) the last two codes regress; with \((K, 7)\) boxes those targets are zero, so leave the last two code_weights at their default \(0\) to keep the velocity branch unsupervised.

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).

  • point_cloud_range (Sequence[float]) –

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

  • voxel_size (Sequence[float]) –

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

  • 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 the rotated 3D IoU when True, otherwise by the bird's-eye IoU of the boxes snapped to their nearest axis-aligned orientation.

  • 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 terms.

forward [source] ΒΆ

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

Compute the multihead anchor detection loss and its terms.

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).

  • data (Dict[str, Any]) –

    Ground truth: packed box \((K, 7)\) full-extent, or \((K, 9)\) with the velocity in the last two columns, label \((K,)\) (\(0\)-based classes) and batch_box \((K,)\) per-box scene index.

Returns:

  • Dict[str, Tensor] –

    A dict with the scalar loss and detached cls_loss, box_loss.

CenterHeadLoss [source] ΒΆ

CenterHeadLoss(
    num_classes: int,
    *,
    point_cloud_range: Sequence[float],
    voxel_size: Sequence[float],
    feature_map_stride: int,
    code_weights: Sequence[float],
    cls_weight: float = 1.0,
    loc_weight: float = 0.25,
    iou_weight: float = 0.0,
    gaussian_overlap: float = 0.1,
    min_radius: int = 2,
    num_max_objs: int = 500,
)

Bases: Module

Loss of the dense CenterHead (CenterPoint, Voxel Mamba).

Reference: Center-based 3D Object Detection and Tracking (Yin et al., 2021).

Ground-truth boxes are splatted onto a per-class BEV Gaussian heatmap and their regression code (sub-cell center offset, \(z\), log extents and \((\cos\theta, \sin\theta)\)) is recorded at each peak cell. The heatmap is supervised by the penalty-reduced center focal loss and the regression maps by a masked, code-weighted \(L_1\) read back at those cells. When the head emits an iou map an optional \(L_1\) term regresses it toward the 3D IoU (rescaled to \([-1, 1]\)) between the decoded prediction and its matched box.

Parameters:

  • num_classes (int) –

    Number of heatmap channels.

  • point_cloud_range (Sequence[float]) –

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

  • voxel_size (Sequence[float]) –

    Voxel size \((v_x, v_y, v_z)\).

  • feature_map_stride (int) –

    Stride from the voxel grid to the BEV feature map.

  • code_weights (Sequence[float]) –

    Per-code regression weight, length \(8\) (the head predicts no velocity codes).

  • cls_weight (float, default: 1.0 ) –

    Multiplier on the heatmap focal loss.

  • loc_weight (float, default: 0.25 ) –

    Multiplier on the summed regression loss.

  • iou_weight (float, default: 0.0 ) –

    Multiplier on the optional IoU-branch loss (\(0\) disables it).

  • gaussian_overlap (float, default: 0.1 ) –

    Min-overlap passed to the Gaussian-radius solver.

  • min_radius (int, default: 2 ) –

    Lower clamp on the integer splat radius.

  • num_max_objs (int, default: 500 ) –

    Per-scene object-target capacity.

Methods:

  • forward –

    Compute the dense center loss and its terms.

forward [source] ΒΆ

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

Compute the dense center loss and its terms.

Parameters:

  • output (CenterHeadOutput) –

    Head maps heatmap \((B, C, H, W)\), center \((B, 2, H, W)\), center_z \((B, 1, H, W)\), dim \((B, 3, H, W)\), rot \((B, 2, H, W)\) and optionally iou \((B, 1, H, W)\).

  • data (Dict[str, Any]) –

    Packed GT (DataKeys.BOX, DataKeys.LABEL, DataKeys.BATCH_BOX).

Returns:

  • Dict[str, Tensor] –

    A dict with the scalar loss and detached heatmap_loss, box_loss (and iou_loss when enabled).

VoxelNeXtHeadLoss [source] ΒΆ

VoxelNeXtHeadLoss(
    class_groups: Sequence[Sequence[int]],
    *,
    point_cloud_range: Sequence[float],
    voxel_size: Sequence[float],
    feature_map_stride: int,
    code_weights: Sequence[float],
    cls_weight: float = 1.0,
    loc_weight: float = 0.25,
    gaussian_overlap: float = 0.1,
    min_radius: int = 2,
    num_max_objs: int = 500,
)

Bases: Module

Loss of the fully sparse VoxelNeXtHead.

Reference: VoxelNeXt: Fully Sparse VoxelNet for 3D Object Detection and Tracking (Chen et al., 2023).

The head predicts CenterPoint-style attributes directly on the occupied BEV voxels rather than a dense map, so targets are drawn only at those voxels: the per-class heatmap is a Gaussian in squared voxel distance and each object's regression code is anchored to its nearest occupied voxel. The heatmap is supervised by the penalty-reduced center focal loss and the gathered regression rows by a masked, code-weighted \(L_1\). Classes are split into groups, one sparse head each.

Parameters:

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

    Zero-based global class-index groups, one per head (e.g. [[0], [1, 2], ...]).

  • point_cloud_range (Sequence[float]) –

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

  • voxel_size (Sequence[float]) –

    Voxel size \((v_x, v_y, v_z)\).

  • feature_map_stride (int) –

    Stride from the voxel grid to the BEV feature map.

  • code_weights (Sequence[float]) –

    Per-code regression weight, length \(8 + \text{extra}\) (e.g. \(10\) with velocity).

  • cls_weight (float, default: 1.0 ) –

    Multiplier on the heatmap focal loss.

  • loc_weight (float, default: 0.25 ) –

    Multiplier on the summed regression loss.

  • gaussian_overlap (float, default: 0.1 ) –

    Min-overlap passed to the Gaussian-radius solver.

  • min_radius (int, default: 2 ) –

    Lower clamp on the integer splat radius.

  • num_max_objs (int, default: 500 ) –

    Per-scene object-target capacity.

Methods:

  • forward –

    Compute the sparse center loss summed over class groups.

forward [source] ΒΆ

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

Compute the sparse center loss summed over class groups.

Parameters:

  • output (VoxelNeXtHeadOutput) –

    A VoxelNeXtHeadOutput: per-group lists hm \((V, n_g)\), center \((V, 2)\), center_z \((V, 1)\), dim \((V, 3)\), rot \((V, 2)\), vel \((V, 2)\) and shared voxel_indices \((V, 3)\) with columns \((\text{batch}, y, x)\).

  • data (Dict[str, Any]) –

    Packed GT (DataKeys.BOX, DataKeys.LABEL, DataKeys.BATCH_BOX).

Returns:

  • Dict[str, Tensor] –

    A dict with the scalar loss and detached heatmap_loss, box_loss.

ChamferDistance [source] ΒΆ

ChamferDistance(norm: Literal['l1', 'l2'] = 'l2')

Bases: Module

Module form of chamfer_distance.

The reconstruction criterion of the masked point modeling models, whose pretraining forward returns the (pred, target, pred_batch, target_batch) tuple this module takes.

Parameters:

  • norm (Literal['l1', 'l2'], default: 'l2' ) –

    Distance variant, "l1" (euclidean) or "l2" (squared euclidean).

Example
import torch
from torch_pointcloud.losses import ChamferDistance

criterion = ChamferDistance(norm="l1")
criterion(torch.zeros(8, 3), torch.zeros(4, 3)).item()  # 0.0

Methods:

  • forward –

    Compute the Chamfer distance between the packed sets pred \((N, 3)\) and target \((M, 3)\).

forward [source] ΒΆ

forward(
    pred: Tensor,
    target: Tensor,
    pred_batch: Optional[Tensor] = None,
    target_batch: Optional[Tensor] = None,
) -> Tensor

Compute the Chamfer distance between the packed sets pred \((N, 3)\) and target \((M, 3)\).

CornerLoss [source] ΒΆ

CornerLoss(
    beta: float = 1.0,
    reduction: Literal["none", "sum", "mean"] = "mean",
)

Bases: Module

Module form of corner_loss.

Parameters:

  • beta (float, default: 1.0 ) –

    Smooth-\(L_1\) transition point.

  • reduction (Literal['none', 'sum', 'mean'], default: 'mean' ) –

    "none" returns the per-box loss, "sum" its sum, "mean" its mean.

Example
import torch
from torch_pointcloud.losses import CornerLoss

criterion = CornerLoss()
box = torch.tensor([[0.0, 0.0, 0.0, 4.0, 2.0, 1.5, 0.3]])
criterion(box, box).item()  # 0.0

Methods:

  • forward –

    Compute the corner loss between matched boxes pred_boxes \((N, 7)\) and gt_boxes \((N, 7)\).

forward [source] ΒΆ

forward(pred_boxes: Tensor, gt_boxes: Tensor) -> Tensor

Compute the corner loss between matched boxes pred_boxes \((N, 7)\) and gt_boxes \((N, 7)\).

GaussianFocalLoss [source] ΒΆ

GaussianFocalLoss(alpha: float = 2.0, gamma: float = 4.0)

Bases: Module

Module form of gaussian_focal_loss.

Takes heatmap logits and applies the sigmoid itself.

Parameters:

  • alpha (float, default: 2.0 ) –

    Focusing exponent on the prediction.

  • gamma (float, default: 4.0 ) –

    Down-weighting exponent on the soft negatives.

Example
import torch
from torch_pointcloud.losses import GaussianFocalLoss

criterion = GaussianFocalLoss()
criterion(torch.zeros(1, 2, 4, 4), torch.zeros(1, 2, 4, 4)).shape  # torch.Size([])

Methods:

  • forward –

    Compute the loss from heatmap logits and the Gaussian target of the same shape.

forward [source] ΒΆ

forward(logits: Tensor, target: Tensor) -> Tensor

Compute the loss from heatmap logits and the Gaussian target of the same shape.

Poly1FocalLoss [source] ΒΆ

Poly1FocalLoss(
    epsilon: float = 1.0,
    alpha: Optional[float] = 0.25,
    gamma: float = 2.0,
    reduction: Literal["none", "sum", "mean"] = "mean",
)

Bases: Module

Module form of poly1_focal_loss, taking class indices.

The targets are either class indices \((\ldots)\), one-hot encoded over the \(C\) logits, or binary targets of the logits' shape. reduction="mean" averages over every element of the \((\ldots, C)\) loss.

Parameters:

  • epsilon (float, default: 1.0 ) –

    Weight \(\epsilon\) of the Poly-1 term.

  • alpha (Optional[float], default: 0.25 ) –

    Positive/negative balance \(\alpha\); None disables it.

  • gamma (float, default: 2.0 ) –

    Focusing exponent \(\gamma\).

  • reduction (Literal['none', 'sum', 'mean'], default: 'mean' ) –

    "none" returns the per-element loss, "sum" its sum, "mean" its mean.

Example
import torch
from torch_pointcloud.losses import Poly1FocalLoss

criterion = Poly1FocalLoss()
criterion(torch.zeros(4, 3), torch.tensor([0, 1, 2, 0])).shape  # torch.Size([])

Methods:

  • forward –

    Compute the loss from logits \((\ldots, C)\) and class indices \((\ldots)\) or binary targets \((\ldots, C)\).

forward [source] ΒΆ

forward(logits: Tensor, targets: Tensor) -> Tensor

Compute the loss from logits \((\ldots, C)\) and class indices \((\ldots)\) or binary targets \((\ldots, C)\).

SigmoidFocalLoss [source] ΒΆ

SigmoidFocalLoss(
    alpha: float = 0.25,
    gamma: float = 2.0,
    reduction: Literal["none", "sum", "mean"] = "mean",
)

Bases: Module

Module form of sigmoid_focal_loss.

Parameters:

  • alpha (float, default: 0.25 ) –

    Positive/negative balance \(\alpha\).

  • gamma (float, default: 2.0 ) –

    Focusing exponent \(\gamma\).

  • reduction (Literal['none', 'sum', 'mean'], default: 'mean' ) –

    "none" returns the per-element loss, "sum" its sum, "mean" its mean.

Example
import torch
from torch_pointcloud.losses import SigmoidFocalLoss

criterion = SigmoidFocalLoss(reduction="sum")
criterion(torch.zeros(4, 3), torch.zeros(4, 3)).shape  # torch.Size([])

Methods:

  • forward –

    Compute the focal loss from logits \((\ldots, C)\), binary targets \((\ldots, C)\) and row weights \((\ldots)\).

forward [source] ΒΆ

forward(
    logits: Tensor,
    targets: Tensor,
    weights: Optional[Tensor] = None,
) -> Tensor

Compute the focal loss from logits \((\ldots, C)\), binary targets \((\ldots, C)\) and row weights \((\ldots)\).

KPConvDeformRegularizer [source] ΒΆ

KPConvDeformRegularizer(
    fitting_power: float = 1.0, repulse_extent: float = 1.0
)

Bases: Module

Module form of kpconv_deform_regularizer.

Parameters:

  • fitting_power (float, default: 1.0 ) –

    Weight of the whole term.

  • repulse_extent (float, default: 1.0 ) –

    Distance, in units of kp_sigma, below which kernel points repel each other.

Example
import torch
from torch_pointcloud.layers import KPConv
from torch_pointcloud.losses import KPConvDeformRegularizer
conv = KPConv(spatial_dim=3, in_channels=4, out_channels=8, kernel_size=15, kp_radius=1.0, kp_sigma=1.0, deformable=True)
pos = torch.rand(32, 3)
edge_index = torch.stack([torch.arange(32).repeat_interleave(4), torch.randint(0, 32, (128,))])
out = conv(torch.randn(32, 4), pos, edge_index)
KPConvDeformRegularizer(repulse_extent=1.2)(conv).shape  # torch.Size([])

LovaszLoss [source] ΒΆ

LovaszLoss(
    ignore_index: int = -1,
    classes: Literal["present", "all"] = "present",
)

Bases: Module

LovΓ‘sz-Softmax loss: a smooth surrogate for the mean-IoU objective.

Optimizes segmentation overlap directly, and is typically summed with cross-entropy. See The LovΓ‘sz-Softmax loss: A tractable surrogate for the optimization of the intersection-over-union measure in neural networks (Berman et al., 2018). The function form on probabilities is lovasz_softmax.

Parameters:

  • ignore_index (int, default: -1 ) –

    Label value excluded from the loss.

  • classes (Literal['present', 'all'], default: 'present' ) –

    "present" averages only classes present in the targets; "all" averages every class.

Methods:

  • forward –

    Compute the loss from per-point logits \((N, C)\) and labels \((N,)\).

forward [source] ΒΆ

forward(logits: Tensor, labels: Tensor) -> Tensor

Compute the loss from per-point logits \((N, C)\) and labels \((N,)\).

PointRCNNLoss [source] ΒΆ

PointRCNNLoss(
    num_classes: int,
    *,
    mean_sizes: Union[Tensor, Sequence[Sequence[float]]],
    gt_extra_width: Sequence[float] = (0.2, 0.2, 0.2),
    point_cls_weight: float = 1.0,
    point_box_weight: float = 1.0,
    point_code_weights: Sequence[float] = (1.0,) * 8,
    reg_fg_thresh: float = 0.55,
    cls_fg_thresh: float = 0.6,
    cls_bg_thresh: float = 0.45,
    rcnn_cls_weight: float = 1.0,
    rcnn_reg_weight: float = 1.0,
    rcnn_corner_weight: float = 1.0,
    rcnn_code_weights: Sequence[float] = (1.0,) * 7,
    focal_alpha: float = 0.25,
    focal_gamma: float = 2.0,
    smooth_l1_beta: float = 1.0 / 9.0,
)

Bases: Module

Two-stage PointRCNN detection loss (per-point proposal head + ROI refinement head).

Reference: PointRCNN: 3D Object Proposal Generation and Detection from Point Cloud (Shi et al., 2019).

Stage 1 supervises the per-point head that generates proposals: every point inside a ground-truth box is foreground (points in the gap between a box and its enlarged copy are ignored), driving a sigmoid focal classification loss over the per-point class logits and a code-weighted smooth-\(L_1\) over the residual box encoding (center offset normalized by the class mean-size diagonal, log extents, \((\cos, \sin)\) heading). Stage 2 supervises the refinement head on the sampled ROIs the model forward produces: a binary cross-entropy on the confidence logit against an IoU-thresholded label, a code-weighted smooth-\(L_1\) on the ROI-canonical box residual, and an optional corner regularization (the mean smooth-\(L_1\) over the eight box corners, robust to the heading flip).

The stage-1 point targets are assigned inside the loss (points-in-box matching + mean-size residual encoding) from the packed ground truth; the stage-2 ROI-to-ground-truth matching (which is random) is done by the model forward, which passes the per-ROI max IoU and the canonically transformed matched box in its training-mode output. The loss holds no reference to the model.

Parameters:

  • num_classes (int) –

    Number of foreground classes.

  • mean_sizes (Union[Tensor, Sequence[Sequence[float]]]) –

    Per-class mean box size \((d_x, d_y, d_z)\), shape \((\text{num\_classes}, 3)\).

  • gt_extra_width (Sequence[float], default: (0.2, 0.2, 0.2) ) –

    Per-axis enlargement of a box when marking ignored points around it.

  • point_cls_weight (float, default: 1.0 ) –

    Weight of the stage-1 classification term.

  • point_box_weight (float, default: 1.0 ) –

    Weight of the stage-1 box-regression term.

  • point_code_weights (Sequence[float], default: (1.0,) * 8 ) –

    Per-code stage-1 regression weights, shape \((8,)\).

  • reg_fg_thresh (float, default: 0.55 ) –

    ROI-to-GT IoU at or above which a ROI's box regression is supervised.

  • cls_fg_thresh (float, default: 0.6 ) –

    ROI-to-GT IoU above which a ROI's confidence label is \(1\).

  • cls_bg_thresh (float, default: 0.45 ) –

    ROI-to-GT IoU below which a ROI's confidence label is \(0\); the band between cls_bg_thresh and cls_fg_thresh is ignored.

  • rcnn_cls_weight (float, default: 1.0 ) –

    Weight of the stage-2 confidence term.

  • rcnn_reg_weight (float, default: 1.0 ) –

    Weight of the stage-2 box-regression term.

  • rcnn_corner_weight (float, default: 1.0 ) –

    Weight of the stage-2 corner regularization (\(0\) disables it).

  • rcnn_code_weights (Sequence[float], default: (1.0,) * 7 ) –

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

  • focal_alpha (float, default: 0.25 ) –

    Stage-1 focal-loss positive/negative balance.

  • focal_gamma (float, default: 2.0 ) –

    Stage-1 focal-loss focusing exponent.

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

    Smooth-\(L_1\) transition point \(\beta\) for both regression terms.

Methods:

  • forward –

    Compute the two-stage PointRCNN loss and its terms.

forward [source] ΒΆ

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

Compute the two-stage PointRCNN loss and its terms.

Parameters:

  • output (PointRCNNTrainOutput) –

    The model's training-mode output: stage-1 point_cls_preds \((N, C)\), point_box_preds \((N, 8)\), point_pos \((N, 3)\), point_batch \((N,)\); stage-2 rcnn_cls \((M, 1)\), rcnn_reg \((M, 7)\), rcnn_boxes \((M, 7)\), rois \((M, 7)\), gt_of_rois \((M, 7)\) (ROI-canonical matched box), gt_of_rois_src \((M, 7)\) (lidar-frame matched box) and roi_ious \((M,)\).

  • data (Dict[str, Any]) –

    Packed ground truth: DataKeys.BOX \((K, 7)\) full-extent, DataKeys.LABEL \((K,)\) (\(0\)-based classes) and DataKeys.BATCH_BOX \((K,)\) per-box scene index.

Returns:

  • Dict[str, Tensor] –

    A dict with the scalar loss and detached point_cls_loss, point_box_loss, rcnn_cls_loss,

  • Dict[str, Tensor] –

    rcnn_box_loss.

SumLoss [source] ΒΆ

SumLoss(
    losses: Sequence[Module],
    weights: Optional[Sequence[float]] = None,
)

Bases: Module

Weighted sum of several loss modules sharing a (logits, target) signature.

Each sub-loss is evaluated on the same inputs and the results are added (e.g. cross-entropy plus LovΓ‘sz), each scaled by its weight when weights is given.

Parameters:

  • losses (Sequence[Module]) –

    The loss modules to sum.

  • weights (Optional[Sequence[float]], default: None ) –

    One scalar per loss; None adds them as they are.

Methods:

  • forward –

    Compute the weighted sum of the sub-losses.

forward [source] ΒΆ

forward(logits: Tensor, target: Tensor) -> Tensor

Compute the weighted sum of the sub-losses.

ThreeDETRLoss [source] ΒΆ

ThreeDETRLoss(
    num_classes: int,
    *,
    num_heading_bins: int,
    matcher_cls_cost: float = 1.0,
    matcher_giou_cost: float = 2.0,
    matcher_center_cost: float = 0.0,
    matcher_objectness_cost: float = 0.0,
    giou_weight: float = 0.0,
    sem_cls_weight: float = 1.0,
    no_object_weight: float = 0.2,
    angle_cls_weight: float = 0.1,
    angle_reg_weight: float = 0.5,
    center_weight: float = 5.0,
    size_weight: float = 1.0,
)

Bases: Module

3DETR Hungarian set-prediction detection loss.

Reference: An End-to-End Transformer Model for 3D Object Detection (Misra et al., 2021).

Object queries are matched to ground-truth boxes one-to-one per scene by a Hungarian assignment whose cost combines the negative predicted class probability, the negative generalized 3D IoU, the \(L_1\) center distance (in the per-scene min-max normalized frame) and the negative objectness. Every decoder layer is supervised (the last layer plus the intermediate layers as auxiliary outputs), each with the same weighted objective, and the per-layer losses are summed:

  • Semantic classification: per-query weighted cross-entropy over the \(C + 1\) class logits, with unmatched queries assigned the background slot and that slot down-weighted by no_object_weight.
  • Center: \(L_1\) distance between matched query and box centers in the normalized frame.
  • Size: \(L_1\) distance between matched query and box sizes in the normalized frame.
  • Angle: cross-entropy on the heading bin plus a Huber loss on the in-bin residual, over matches.
  • GIoU: \(1 - \text{gIoU}_{3D}\) between matched query and box, over matches.
  • Cardinality: the \(L_1\) error between the count of non-background queries and the object count (logged only, never optimized).

Ground truth is read packed from the batch (full-extent \((K, 7)\) boxes with counter-clockwise headings, plus per-box classes) and densified per scene; the headings are negated into the model's native heading space before binning. The normalization uses the model's point_cloud_dims, so the loss holds no reference to the model.

Parameters:

  • num_classes (int) –

    Number of semantic classes (the class head predicts one extra background slot).

  • num_heading_bins (int) –

    Heading-angle bins (\(1\) for axis-aligned ScanNet, \(12\) for oriented SUN RGB-D).

  • matcher_cls_cost (float, default: 1.0 ) –

    Matcher weight on the negative class probability.

  • matcher_giou_cost (float, default: 2.0 ) –

    Matcher weight on the negative generalized 3D IoU.

  • matcher_center_cost (float, default: 0.0 ) –

    Matcher weight on the normalized-center \(L_1\) distance.

  • matcher_objectness_cost (float, default: 0.0 ) –

    Matcher weight on the negative objectness.

  • giou_weight (float, default: 0.0 ) –

    Weight of the GIoU term in the total; \(0\) (the published recipe) keeps the GIoU in the matcher only. The rotated-box GIoU (scenes with non-zero headings) is computed without gradients, so a non-zero weight trains only axis-aligned scenes. Its values differ slightly from implementations that skip the polygon intersection of box pairs whose corner-spanned axis-aligned rectangles do not overlap: box3d_overlap intersects every pair exactly.

  • sem_cls_weight (float, default: 1.0 ) –

    Weight of the semantic-classification term in the total.

  • no_object_weight (float, default: 0.2 ) –

    Cross-entropy weight of the background class.

  • angle_cls_weight (float, default: 0.1 ) –

    Weight of the heading-bin classification term in the total.

  • angle_reg_weight (float, default: 0.5 ) –

    Weight of the heading-residual regression term in the total.

  • center_weight (float, default: 5.0 ) –

    Weight of the center term in the total.

  • size_weight (float, default: 1.0 ) –

    Weight of the size term in the total.

Methods:

  • forward –

    Compute the 3DETR set-prediction loss and its terms.

forward [source] ΒΆ

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

Compute the 3DETR set-prediction loss and its terms.

Parameters:

  • output (ThreeDETRTrainOutput) –

    A training-mode ThreeDETRTrainOutput: aux_outputs (a per-decoder-layer list of head dicts with sem_cls_logits, sem_cls_prob, objectness_prob, center_normalized, center_unnormalized, size_normalized, size_unnormalized, angle_logits, angle_residual_normalized, angle_continuous) and point_cloud_dims.

  • data (Dict[str, Any]) –

    Packed ground truth: DataKeys.BOX \((K, 7)\) full-extent boxes with counter-clockwise headings, DataKeys.LABEL \((K,)\) per-box classes and DataKeys.BATCH_BOX \((K,)\) per-box scene index.

Returns:

  • Dict[str, Tensor] –

    A dict with the scalar loss (summed over decoder layers) and detached sem_cls_loss,

  • Dict[str, Tensor] –

    center_loss, size_loss, angle_cls_loss, angle_reg_loss, giou_loss and the

  • Dict[str, Tensor] –

    cardinality_error diagnostic (each summed over decoder layers).

TNetOrthogonalityRegularizer [source] ΒΆ

Bases: Module

Module form of tnet_orthogonality_regularizer.

Example
import torch
from torch_pointcloud.layers import TNet
from torch_pointcloud.losses import TNetOrthogonalityRegularizer
ftnet = TNet(local_channels=[32, 64], global_channels=[32], k=16)
out = ftnet(torch.randn(10, 16), torch.arange(2).repeat_interleave(5))
TNetOrthogonalityRegularizer()(ftnet).shape  # torch.Size([])

TransFusionHeadLoss [source] ΒΆ

TransFusionHeadLoss(
    num_classes: int,
    *,
    point_cloud_range: Sequence[float],
    voxel_size: Sequence[float],
    feature_map_stride: int,
    num_proposals: int = 200,
    gaussian_overlap: float = 0.1,
    min_radius: int = 2,
    matcher_cls_cost: float = 0.15,
    matcher_reg_cost: float = 0.25,
    matcher_iou_cost: float = 0.25,
    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,
    heatmap_weight: float = 1.0,
    iou_weight: float = 0.5,
    focal_alpha: float = 0.25,
    focal_gamma: float = 2.0,
)

Bases: Module

Loss of the TransFusionHead (dense heatmap, matched classification, box, IoU rescore).

Reference: TransFusion: Robust LiDAR-Camera Fusion for 3D Object Detection with Transformers (Bai et al., 2022).

The head predicts a dense per-class BEV heatmap plus a fixed set of object queries, each carrying a class logit vector and a box code. Four terms are summed:

  • Heatmap: the ground-truth box centers are splatted onto a per-class BEV Gaussian map and the dense heatmap is supervised by the penalty-reduced center focal loss.
  • Classification: every scene's queries are decoded to boxes and matched to the ground truth by a per-scene Hungarian assignment (cost: focal classification + normalized center \(L_1\) + 3D IoU). The per-query class logits are then trained by sigmoid focal loss over one-hot targets (background for unmatched queries), normalized by the positive count.
  • Box regression: code-weighted \(L_1\) over the \(10\)-dim box code \((x, y, z + d_z / 2, \log d_x, \log d_y, \log d_z, \sin\theta, \cos\theta, v_x, v_y)\) at the matched queries.
  • IoU rescore: an \(L_1\) term regressing the per-query iou branch toward \(2 \cdot \text{IoU}_{3D} - 1\) between each matched query's decoded box and its ground-truth box.

The loss holds no reference to the model: the grid geometry is rebuilt from the constructor params.

Parameters:

  • num_classes (int) –

    Number of foreground classes (heatmap channels and query logits).

  • point_cloud_range (Sequence[float]) –

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

  • voxel_size (Sequence[float]) –

    Voxel size \((v_x, v_y, v_z)\).

  • feature_map_stride (int) –

    Stride from the voxel grid to the BEV feature map.

  • num_proposals (int, default: 200 ) –

    Number of object queries per scene.

  • gaussian_overlap (float, default: 0.1 ) –

    Min-overlap passed to the Gaussian-radius solver.

  • min_radius (int, default: 2 ) –

    Lower clamp on the integer splat radius.

  • matcher_cls_cost (float, default: 0.15 ) –

    Weight of the focal classification term in the matching cost.

  • matcher_reg_cost (float, default: 0.25 ) –

    Weight of the normalized center-\(L_1\) term in the matching cost.

  • matcher_iou_cost (float, default: 0.25 ) –

    Weight of the 3D-IoU term in the matching cost.

  • 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 weight, length \(10\); the last two (velocity) default to \(0\).

  • cls_weight (float, default: 1.0 ) –

    Multiplier on the classification term.

  • loc_weight (float, default: 0.25 ) –

    Multiplier on the box-regression term.

  • heatmap_weight (float, default: 1.0 ) –

    Multiplier on the heatmap term.

  • iou_weight (float, default: 0.5 ) –

    Multiplier on the IoU-rescore term.

  • focal_alpha (float, default: 0.25 ) –

    Focal positive/negative balance (classification loss and matching cost).

  • focal_gamma (float, default: 2.0 ) –

    Focal focusing exponent (classification loss and matching cost).

Methods:

  • forward –

    Compute the TransFusion loss and its terms.

forward [source] ΒΆ

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

Compute the TransFusion loss and its terms.

Parameters:

  • output (TransFusionHeadOutput) –

    The head's raw output: per-query center \((B, 2, Q)\), height \((B, 1, Q)\), dim \((B, 3, Q)\), rot \((B, 2, Q)\), vel \((B, 2, Q)\), iou \((B, 1, Q)\) and heatmap \((B, C, Q)\) class logits, plus the dense dense_heatmap \((B, C, H, W)\).

  • data (Dict[str, Any]) –

    Packed ground truth (DataKeys.BOX \((K, 7)\) full-extent, or \((K, 9)\) with the velocity in the last two columns, DataKeys.LABEL \((K,)\) \(0\)-based, DataKeys.BATCH_BOX \((K,)\) per-box scene index).

Returns:

  • Dict[str, Tensor] –

    A dict with the scalar loss and detached heatmap_loss, cls_loss, box_loss, iou_loss.

VoteNetLoss [source] ΒΆ

VoteNetLoss(
    num_classes: int,
    *,
    num_heading_bins: int,
    num_size_clusters: int,
    mean_sizes: Union[Tensor, List[List[float]]],
    near_threshold: float = 0.3,
    far_threshold: float = 0.6,
    objectness_weights: Tuple[float, float] = (0.2, 0.8),
    gt_vote_factor: int = 3,
    loss_weight: float = 10.0,
)

Bases: Module

Loss of VoteNetDetection (vote, objectness, box, semantic).

Reference: Deep Hough Voting for 3D Object Detection in Point Clouds (Qi et al., 2019).

Every target is assigned inside the loss from the packed ground-truth boxes:

  • Vote: each seed point inside a box votes for its center. A seed collects the centers of the first gt_vote_factor boxes containing it (repeating the first when inside fewer), and the smooth-\(L_1\) distance of its closest predicted vote to its closest target vote is averaged over the seeds inside a box.
  • Objectness: proposals are matched to objects by nearest center. A proposal is positive when its nearest center is within near_threshold, negative beyond far_threshold, and ignored in the band between; a weighted two-way cross-entropy supervises the objectness logits.
  • Box and semantic: positives drive the center (symmetric Chamfer between proposal and object centers), heading (bin cross-entropy + normalized residual smooth-\(L_1\)), size (class cross-entropy + normalized residual smooth-\(L_1\)) and semantic-class terms, each averaged over the positives.

The library heading is counter-clockwise about \(+z\) while the heading head predicts the negated angle, so the heading bins are computed from \(-\theta\). Scenes are padded to a common object count with zero centers that take part in the proposal-to-object matching.

Parameters:

  • num_classes (int) –

    Number of semantic classes.

  • num_heading_bins (int) –

    Number of heading-angle bins (\(1\) for axis-aligned ScanNet, \(12\) for SUN RGB-D).

  • num_size_clusters (int) –

    Number of size templates (the size class is the semantic class).

  • mean_sizes (Union[Tensor, List[List[float]]]) –

    Per-template mean box size, shape \((\text{num\_size\_clusters}, 3)\).

  • near_threshold (float, default: 0.3 ) –

    Distance (meters) below which a proposal is a positive object match.

  • far_threshold (float, default: 0.6 ) –

    Distance (meters) above which a proposal is a negative match.

  • objectness_weights (Tuple[float, float], default: (0.2, 0.8) ) –

    Cross-entropy class weights \([\text{negative}, \text{positive}]\).

  • gt_vote_factor (int, default: 3 ) –

    Number of target votes (containing-box centers) collected per seed.

  • loss_weight (float, default: 10.0 ) –

    Global multiplier applied to the summed loss.

Methods:

  • forward –

    Compute the VoteNet loss and its terms.

forward [source] ΒΆ

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

Compute the VoteNet loss and its terms.

Parameters:

  • output (VoteNetOutput) –

    The model's raw output: dense head tensors (objectness_scores, center, heading_scores, heading_residuals_normalized, size_scores, size_residuals_normalized, sem_cls_scores, pos_vote_aggr) as \((B, K, \cdot)\), plus the packed seeds pos_seed \((S, 3)\), batch_seed \((S,)\) and their votes pos_vote \((S \cdot \text{vote\_factor}, 3)\).

  • data (Dict[str, Any]) –

    Packed ground truth: DataKeys.BOX \((K, 7)\) full-extent boxes with counter-clockwise headings, DataKeys.LABEL \((K,)\) per-box classes and DataKeys.BATCH_BOX \((K,)\) per-box scene index.

Returns:

  • Dict[str, Tensor] –

    A dict with the scalar loss and detached vote_loss, objectness_loss, box_loss,

  • Dict[str, Tensor] –

    center_loss, heading_cls_loss, heading_res_loss, size_cls_loss, size_res_loss,

  • Dict[str, Tensor] –

    sem_cls_loss and the obj_acc diagnostic.

chamfer_distance [source] ΒΆ

chamfer_distance(
    pred: Tensor,
    target: Tensor,
    *,
    pred_batch: Optional[Tensor] = None,
    target_batch: Optional[Tensor] = None,
    norm: Literal["l1", "l2"] = "l2",
) -> Tensor

Symmetric Chamfer distance between packed point sets.

Set-to-set reconstruction objective introduced for point cloud generation in A Point Set Generation Network for 3D Object Reconstruction from a Single Image (Fan et al., 2017) and standard for masked point modeling pretraining. Every point is matched to its nearest neighbor in the other set of the same index (its group, its scene), and the squared euclidean distances are averaged over all points:

\[\text{CD}_{\ell_2} = \frac{1}{N} \sum_i \min_j \lVert p_i - q_j \rVert_2^2 + \frac{1}{M} \sum_j \min_i \lVert p_i - q_j \rVert_2^2\]
\[\text{CD}_{\ell_1} = \frac{1}{2} \Big( \frac{1}{N} \sum_i \min_j \lVert p_i - q_j \rVert_2 + \frac{1}{M} \sum_j \min_i \lVert p_i - q_j \rVert_2 \Big)\]

The "l2" variant sums the two directed means of squared distances (no square root, no halving); the "l1" variant averages the two directed means of euclidean distances. Both follow the reference pretraining convention, so losses are comparable with published values.

The nearest neighbors come from the sided_distance kernel of kaolin when it is installed and the points are on CUDA, otherwise from the kNN kernel of torch_geometric (pyg-lib); either way without autograd, and only the matched pairs are differentiated, so the memory grows with \(N + M\) rather than \(N \cdot M\) and whole clouds fit. Without either kernel the search falls back to the dense distance matrix.

Parameters:

  • pred (Tensor) –

    Predicted points of every set, packed, shape \((N, 3)\).

  • target (Tensor) –

    Target points of every set, packed, shape \((M, 3)\).

  • pred_batch (Optional[Tensor], default: None ) –

    Set index of every predicted point (sorted), shape \((N,)\); None for a single set.

  • target_batch (Optional[Tensor], default: None ) –

    Set index of every target point (sorted), shape \((M,)\); None for a single set.

  • norm (Literal['l1', 'l2'], default: 'l2' ) –

    Distance variant, "l1" (euclidean) or "l2" (squared euclidean).

Returns:

  • Tensor –

    Scalar Chamfer distance averaged over all points.

Shape
  • pred: \((N, 3)\)
  • target: \((M, 3)\)
  • pred_batch: \((N,)\)
  • target_batch: \((M,)\)
  • output: scalar
Example
import torch
from torch_pointcloud.losses import chamfer_distance

pred = torch.randn(64 * 32, 3, requires_grad=True)
target = torch.randn(64 * 32, 3)
batch = torch.arange(64).repeat_interleave(32)
loss = chamfer_distance(pred, target, pred_batch=batch, target_batch=batch)
loss.backward()
print(loss.shape)

corner_loss [source] ΒΆ

corner_loss(
    pred_boxes: Tensor,
    gt_boxes: Tensor,
    *,
    beta: float = 1.0,
) -> Tensor

Per-box mean smooth-\(L_1\) distance between the eight corners of two box sets, robust to the heading flip.

The corner regularization of PointRCNN: 3D Object Proposal Generation and Detection from Point Cloud (Shi et al., 2019): each predicted corner is compared with the matching corner of the ground-truth box and of that box rotated by \(\pi\), and the closer of the two distances is penalized, so a heading off by half a turn is not punished as a position error.

Parameters:

  • pred_boxes (Tensor) –

    Predicted boxes \((c_x, c_y, c_z, d_x, d_y, d_z, \theta)\), shape \((N, 7)\).

  • gt_boxes (Tensor) –

    Matched ground-truth boxes, shape \((N, 7)\).

  • beta (float, default: 1.0 ) –

    Smooth-\(L_1\) transition point.

Returns:

  • Tensor –

    The per-box loss, shape \((N,)\).

Shape
  • pred_boxes: \((N, 7)\)
  • gt_boxes: \((N, 7)\)
  • output: \((N,)\)
Example
>>> box = torch.tensor([[0.0, 0.0, 0.0, 4.0, 2.0, 1.5, 0.3]])
>>> corner_loss(box, box).tolist()
[0.0]
>>> flipped = box.clone()
>>> flipped[:, 6] += math.pi
>>> corner_loss(box, flipped).abs().max().item() < 1e-5
True

gaussian_focal_loss [source] ΒΆ

gaussian_focal_loss(
    pred: Tensor,
    target: Tensor,
    *,
    alpha: float = 2.0,
    gamma: float = 4.0,
    eps: float = 0.0001,
) -> Tensor

Penalty-reduced focal loss over a Gaussian heatmap, normalized by the number of peaks.

The heatmap objective of Objects as Points (Zhou et al., 2019), used by the center-based detection heads (CenterPoint, VoxelNeXt, TransFusion). Cells whose target is exactly \(1\) are positives with the \((1 - p)^\alpha \log p\) term; every other cell is a soft negative whose \(p^\alpha \log(1 - p)\) term is down-weighted by \((1 - y)^\gamma\), so cells near a peak barely count. The sum is divided by the number of positives (or left as is when there is none).

Parameters:

  • pred (Tensor) –

    Predicted probabilities (post-sigmoid) of any shape; clamped to \([\varepsilon, 1 - \varepsilon]\).

  • target (Tensor) –

    Gaussian heatmap target of the same shape, values in \([0, 1]\).

  • alpha (float, default: 2.0 ) –

    Focusing exponent on the prediction.

  • gamma (float, default: 4.0 ) –

    Down-weighting exponent on the soft negatives.

  • eps (float, default: 0.0001 ) –

    Clamp keeping the logarithms finite.

Returns:

  • Tensor –

    The scalar loss.

Shape
  • pred: \((\ldots)\)
  • target: \((\ldots)\)
  • output: scalar
Example
>>> target = torch.tensor([[1.0, 0.5], [0.0, 0.0]])
>>> gaussian_focal_loss(torch.full((2, 2), 0.5), target).shape
torch.Size([])

one_hot_foreground [source] ΒΆ

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

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

Ignored (\(-1\)) and background (\(0\)) rows map to an all-zero row; a foreground row with label \(\ell \ge 1\) maps to a one-hot row on class \(\ell - 1\). The target format of sigmoid_focal_loss for the anchor and point heads.

Parameters:

  • labels (Tensor) –

    Class labels (\(-1\) ignore, \(0\) background, \(\ge 1\) foreground), shape \((\ldots)\).

  • num_classes (int) –

    Number of foreground classes \(C\).

Returns:

  • Tensor –

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

Shape
  • labels: \((\ldots)\)
  • output: \((\ldots, 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]]]

poly1_focal_loss [source] ΒΆ

poly1_focal_loss(
    logits: Tensor,
    targets: Tensor,
    *,
    epsilon: float = 1.0,
    alpha: Optional[float] = 0.25,
    gamma: float = 2.0,
) -> Tensor

Poly-1 focal loss between per-class logits and binary targets (no reduction).

The focal loss plus its first Poly-1 correction term of PolyLoss: A Polynomial Expansion Perspective of Classification Loss Functions (Leng et al., 2022), with \(p\) the sigmoid of the logit, \(p_t = p\) on the positive entries and \(1 - p\) elsewhere,

\[ \ell = \alpha_t\, (1 - p_t)^\gamma\, \mathrm{BCE}(\text{logit}, \text{target}) + \epsilon\, (1 - p_t)^{\gamma + 1} \]

Parameters:

  • logits (Tensor) –

    Per-class logits, shape \((\ldots, C)\).

  • targets (Tensor) –

    Binary (one-hot) targets of the same shape.

  • epsilon (float, default: 1.0 ) –

    Weight \(\epsilon\) of the Poly-1 term.

  • alpha (Optional[float], default: 0.25 ) –

    Positive/negative balance \(\alpha\); None disables it.

  • gamma (float, default: 2.0 ) –

    Focusing exponent \(\gamma\).

Returns:

  • Tensor –

    The per-element loss, shape \((\ldots, C)\).

Shape
  • logits: \((\ldots, C)\)
  • targets: \((\ldots, C)\)
  • output: \((\ldots, C)\)
Example
>>> logits = torch.zeros(2, 3)
>>> targets = torch.tensor([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
>>> poly1_focal_loss(logits, targets).shape
torch.Size([2, 3])

sigmoid_focal_loss [source] ΒΆ

sigmoid_focal_loss(
    logits: Tensor,
    targets: Tensor,
    weights: Optional[Tensor] = None,
    *,
    alpha: float = 0.25,
    gamma: float = 2.0,
) -> Tensor

Sigmoid focal loss between per-class logits and binary targets (no reduction).

The classification term of Focal Loss for Dense Object Detection (Lin et al., 2017), shared by the anchor, point and query heads: binary cross-entropy on the sigmoid of each logit, scaled by \(\alpha_t (1 - p_t)^\gamma\) so confident predictions contribute little. Same math as torchvision.ops.sigmoid_focal_loss, plus an optional per-row weight.

Parameters:

  • logits (Tensor) –

    Per-class logits, shape \((\ldots, C)\).

  • targets (Tensor) –

    Binary (one-hot) targets of the same shape.

  • weights (Optional[Tensor], default: None ) –

    Optional weight of every row, shape \((\ldots)\), broadcast over the class dimension.

  • alpha (float, default: 0.25 ) –

    Positive/negative balance \(\alpha\).

  • gamma (float, default: 2.0 ) –

    Focusing exponent \(\gamma\).

Returns:

  • Tensor –

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

Shape
  • logits: \((\ldots, C)\)
  • targets: \((\ldots, C)\)
  • weights: \((\ldots)\)
  • output: \((\ldots, C)\)
Example
>>> logits = torch.zeros(1, 2, 3)
>>> targets = torch.tensor([[[1.0, 0.0, 0.0], [0.0, 0.0, 0.0]]])
>>> sigmoid_focal_loss(logits, targets, torch.ones(1, 2)).shape
torch.Size([1, 2, 3])

kpconv_deform_regularizer [source] ΒΆ

kpconv_deform_regularizer(
    module: Module,
    fitting_power: float = 1.0,
    repulse_extent: float = 1.0,
) -> Tensor

Regularize the deformed kernel points of every deformable KPConv in module.

The point-to-point regularizer of KPConv: Flexible and Deformable Convolution for Point Clouds (Thomas et al., 2019): a fitting term pulls every deformed kernel point towards its closest input point, a repulsive term keeps the kernel points of one location further apart than repulse_extent. Both read the statistics the layers keep from their last forward pass (running_min_d2, running_deformed_kernel), so call it after the forward and before the backward of the same batch. Distances are expressed in units of each layer's kp_sigma.

Parameters:

  • module (Module) –

    Model holding the KPConv layers.

  • fitting_power (float, default: 1.0 ) –

    Weight of the whole term.

  • repulse_extent (float, default: 1.0 ) –

    Distance, in units of kp_sigma, below which kernel points repel each other.

Returns:

  • Tensor –

    A scalar, fitting_power * (2 * fitting + repulsive) summed over the deformable layers, zero when

  • Tensor –

    module has none.

Example
>>> import torch
>>> from torch_pointcloud.layers import KPConv
>>> from torch_pointcloud.losses import kpconv_deform_regularizer
>>> conv = KPConv(spatial_dim=3, in_channels=4, out_channels=8, kernel_size=15, kp_radius=1.0, kp_sigma=1.0, deformable=True)
>>> pos = torch.rand(32, 3)
>>> edge_index = torch.stack([torch.arange(32).repeat_interleave(4), torch.randint(0, 32, (128,))])
>>> out = conv(torch.randn(32, 4), pos, edge_index)
>>> kpconv_deform_regularizer(conv).shape
torch.Size([])

lovasz_softmax [source] ΒΆ

lovasz_softmax(
    probas: Tensor,
    labels: Tensor,
    *,
    classes: Literal["present", "all"] = "present",
    ignore_index: int = -1,
) -> Tensor

Multi-class LovΓ‘sz-Softmax loss over per-point class probabilities.

The smooth surrogate of the mean-IoU objective of The LovΓ‘sz-Softmax loss: A tractable surrogate for the optimization of the intersection-over-union measure in neural networks (Berman et al., 2018); the function form of LovaszLoss, which takes logits.

Parameters:

  • probas (Tensor) –

    Per-point class probabilities (post-softmax), shape \((N, C)\).

  • labels (Tensor) –

    Per-point ground-truth labels, shape \((N,)\).

  • classes (Literal['present', 'all'], default: 'present' ) –

    "present" averages only classes present in labels; "all" averages every class.

  • ignore_index (int, default: -1 ) –

    Label value excluded from the loss.

Returns:

  • Tensor –

    The scalar loss (zero when no point or no class contributes).

Shape
  • probas: \((N, C)\)
  • labels: \((N,)\)
  • output: scalar
Example
>>> labels = torch.tensor([0, 1, 2])
>>> probas = torch.nn.functional.one_hot(labels, 3).float()
>>> lovasz_softmax(probas, labels).item()
0.0

hungarian_match [source] ΒΆ

hungarian_match(cost: Tensor) -> Tuple[Tensor, Tensor]

One-to-one assignment of predictions to targets minimizing the total cost (Hungarian algorithm).

The matcher of the set-prediction detectors (3DETR, TransFusion): every target is matched to exactly one prediction and the sum of the matched costs is minimal. The cost matrix is built by the caller (e.g. a weighted sum of a classification, a center-distance and an IoU term) and must be finite.

Parameters:

  • cost (Tensor) –

    Pairwise cost of every prediction / target pair, shape \((Q, M)\).

Returns:

  • Tensor –

    A tuple (pred_indices, target_indices) of long tensors on cost.device, each of length

  • Tensor –

    \(\min(Q, M)\), such that pred_indices[i] is matched to target_indices[i]; both are empty when

  • Tuple[Tensor, Tensor] –

    either side is.

Shape
  • cost: \((Q, M)\)
  • pred_indices: \((\min(Q, M),)\)
  • target_indices: \((\min(Q, M),)\)
Example
>>> cost = torch.tensor([[0.9, 0.1], [0.2, 0.8], [0.5, 0.5]])
>>> pred, target = hungarian_match(cost)
>>> pred.tolist(), target.tolist()
([0, 1], [1, 0])

hungarian_match_batched [source] ΒΆ

hungarian_match_batched(
    cost: Tensor, num_targets: Sequence[int]
) -> Tensor

One-to-one assignment of every scene's predictions to its targets, with a single device transfer.

The batched form of hungarian_match for a padded cost tensor: scene \(i\) uses the first num_targets[i] target columns of cost[i]. The whole tensor is moved to the CPU once and every scene is solved there, so a loop over scenes (and decoder layers, when they are stacked along the batch dimension) costs one synchronization instead of one per scene.

Parameters:

  • cost (Tensor) –

    Pairwise costs, shape \((N, Q, M_\max)\); the columns beyond a scene's target count are ignored and may hold anything finite or not.

  • num_targets (Sequence[int]) –

    Number of valid target columns of each scene, length \(N\).

Returns:

  • Tensor –

    The matched target index of every prediction, shape \((N, Q)\) long on cost.device, \(-1\) where the

  • Tensor –

    prediction is unmatched.

Shape
  • cost: \((N, Q, M_\max)\)
  • output: \((N, Q)\)
Example
>>> cost = torch.tensor([[[0.9, 0.1], [0.2, 0.8], [0.5, 0.5]]])
>>> hungarian_match_batched(cost, [2]).tolist()
[[1, 0, -1]]

tnet_orthogonality_regularizer [source] ΒΆ

tnet_orthogonality_regularizer(module: Module) -> Tensor

Pull the transforms predicted by every T-Net in module towards an orthogonal matrix.

The feature-transform regularization of PointNet: Deep Learning on Point Sets for 3D Classification and Segmentation (Qi et al., 2017), \(\lVert I - A A^\top \rVert_F\) averaged over the samples of the batch and summed over the T-Nets found in module. Pass the T-Net (or the sub-module) to regularize, e.g. a PointNet's feature transform model.ftnet to leave its input transform free, as the PointNet paper does.

The matrices are read from the running_transform the layers keep from their last forward pass, so call it after the forward and before the backward of the same batch.

Parameters:

  • module (Module) –

    A TNet / DynamicTNet, or a module containing some.

Returns:

  • Tensor –

    The scalar regularizer (zero when module holds no T-Net).

Raises:

  • RuntimeError –

    If a T-Net has no stored transform (no forward pass yet, or track_running_stats=False).

Example
>>> from torch_pointcloud.layers.tnet import TNet
>>> tnet = TNet(local_channels=[32, 64], global_channels=[32], k=8)
>>> _ = tnet(torch.randn(6, 8), torch.tensor([0, 0, 0, 1, 1, 1]))
>>> tnet_orthogonality_regularizer(tnet).shape
torch.Size([])