Coverage Control & Rejection Loss (v0.6.0 SCM)

In v0.6.0, singularities are represented by (bottom). Training must balance: - fit quality on finite regions, and - coverage (how often the model produces a finite output instead of )

ZeroProofML provides: - a coverage metric (zeroproofml.losses.coverage) - a rejection loss (zeroproofml.losses.rejection_loss) - an aggregate objective (zeroproofml.losses.SCMTrainingLoss)

Coverage metric

Coverage is the fraction of samples that are not bottom:

import torch
from zeroproofml.losses import coverage

# bottom_mask: True means ⊥
bottom_mask = torch.tensor([False, True, False])
cov = coverage(outputs=torch.empty(3), is_bottom=bottom_mask)

In Torch SCM layers, the mask often comes directly from the model (e.g. SCMRationalLayer).

Rejection loss

rejection_loss penalises measured coverage falling below a target:

from zeroproofml.losses import rejection_loss

rej = rejection_loss(bottom_mask, target_coverage=0.95)

This hard path uses an already-thresholded bottom mask. It is detached before the squared hinge on (target_coverage - actual_coverage) is computed, so treat it as metric-style penalty accounting rather than a differentiable signal for training the denominator gate.

Using SCMTrainingLoss

SCMTrainingLoss mixes: - implicit fit loss (division-free) - margin loss on denominators - sign consistency (singular/projective orientation) - rejection loss (coverage control)

from zeroproofml.losses import LossConfig, SCMTrainingLoss

loss_fn = SCMTrainingLoss(LossConfig(target_coverage=0.95, lambda_rej=0.01))
# total, breakdown = loss_fn(fit_loss, P, Q, Y_n, Y_d, is_bottom=bottom_mask, ...)

When lambda_sign > 0, omitting mask_singular restricts sign supervision to targets with abs(Y_d) <= epsilon_sing. Pass mask_singular explicitly to supervise finite orientations or another signed task domain; use the implicit fit term for generic finite regression.

Notes

  • v0.6.0 does not ship an “adaptive λ” controller in the core. If you want a true Lagrange-multiplier style update, implement it outside the library by adjusting lambda_rej over time based on observed coverage.
  • For training loops, SCMTrainer can early-stop when coverage remains below a threshold (TrainingConfig.coverage_threshold and coverage_patience).