pycsamt.ai.losses.uncertainty#

Uncertainty-aware losses for calibrated inversion outputs.

These losses support the M9 uncertainty milestone in the AI-inversion plan: a heteroscedastic aleatoric training term (gaussian_nll_loss()) and a coverage-calibration diagnostic (calibration_loss()). The two are kept separate rather than fused into one combined call: the NLL is a per-cell term evaluated every training step, while calibration summarizes predictive intervals across many held-out realizations and is evaluated periodically, not differentiated through.

All functions operate on plain NumPy arrays so the module stays importable without an optional deep-learning backend.

Functions

calibration_loss(coverage, nominal_levels, *)

Penalize deviation between empirical and nominal coverage.

gaussian_nll_loss(y_pred, y_true, ...[, ...])

Compute a heteroscedastic Gaussian negative log-likelihood.

Classes

UncertaintyLoss([reduction])

Configurable, callable heteroscedastic Gaussian NLL loss.

UncertaintyLossResult(value, kind, ...)

Immutable scalar result of an uncertainty-aware loss.

class pycsamt.ai.losses.uncertainty.UncertaintyLossResult(value, kind, reduction, n_valid, weight_sum)[source]

Bases: object

Immutable scalar result of an uncertainty-aware loss.

Parameters:
  • value (float) – Reduced loss value. nan when no cell was included and reduction="mean".

  • kind ({"gaussian_nll", "calibration"}) – Loss family that produced value.

  • reduction ({"mean", "sum"}) – Reduction applied over valid, weighted cells.

  • n_valid (int) – Number of cells included after masking.

  • weight_sum (float) – Sum of weights over included cells. Equals n_valid when no explicit weights were supplied.

Examples

>>> import numpy as np
>>> pred = np.array([0.0, 1.0])
>>> true = np.array([0.0, 0.0])
>>> log_var = np.array([0.0, 0.0])
>>> result = gaussian_nll_loss(pred, true, log_var)
>>> result.kind, result.n_valid
('gaussian_nll', 2)
value: float
kind: str
reduction: str
n_valid: int
weight_sum: float
pycsamt.ai.losses.uncertainty.gaussian_nll_loss(y_pred, y_true, log_variance, *, valid=None, weights=None, reduction='mean')[source]

Compute a heteroscedastic Gaussian negative log-likelihood.

Each cell contributes 0.5 * ((y_pred - y_true)**2 / variance + log_variance + log(2*pi)) with variance = exp(log_variance). Parameterizing the log-variance rather than the variance itself keeps it unconstrained in sign while variance stays positive.

Parameters:
  • y_pred (array-like) – Predicted mean values.

  • y_true (array-like) – True values, same shape as y_pred.

  • log_variance (array-like) – Predicted log-variance, same shape as y_pred. Any finite real value is valid.

  • valid (array-like of bool or None, optional) – Explicit cell mask, combined with finite-value masking of all three inputs.

  • weights (array-like or None, optional) – Non-negative per-cell weights broadcastable to y_pred.

  • reduction ({"mean", "sum"}, default="mean") – Reduction applied over included cells.

Returns:

Reduced negative log-likelihood.

Return type:

UncertaintyLossResult

Examples

>>> import numpy as np
>>> pred = np.array([0.0, 1.0])
>>> true = np.array([0.0, 0.0])
>>> log_var = np.array([0.0, 0.0])
>>> round(gaussian_nll_loss(pred, true, log_var).value, 6)
1.168939
pycsamt.ai.losses.uncertainty.calibration_loss(coverage, nominal_levels, *, kind='l2', valid=None, weights=None, reduction='mean')[source]

Penalize deviation between empirical and nominal coverage.

Parameters:
  • coverage (array-like) – Empirical coverage observed at each nominal level, in [0, 1].

  • nominal_levels (array-like) – Declared confidence levels in [0, 1], same shape as coverage.

  • kind ({"l1", "l2"}, default="l2") – Elementwise penalty applied to each calibration residual.

  • valid (array-like of bool or None, optional) – Explicit level mask, combined with finite-value masking of both inputs.

  • weights (array-like or None, optional) – Non-negative per-level weights broadcastable to coverage.

  • reduction ({"mean", "sum"}, default="mean") – Reduction applied over included levels.

Returns:

Reduced calibration penalty.

Return type:

UncertaintyLossResult

Examples

>>> import numpy as np
>>> coverage = np.array([0.4, 0.9])
>>> nominal = np.array([0.5, 0.8])
>>> round(calibration_loss(coverage, nominal).value, 6)
0.01
class pycsamt.ai.losses.uncertainty.UncertaintyLoss(reduction='mean')[source]

Bases: object

Configurable, callable heteroscedastic Gaussian NLL loss.

Wraps gaussian_nll_loss() for reuse across training batches. Calibration is scored separately with calibration_loss() over binned coverage, since it summarizes predictive intervals across many held-out realizations rather than acting as a per-cell training term.

Parameters:

reduction ({"mean", "sum"}, default="mean") – Reduction applied over included cells.

Examples

>>> import numpy as np
>>> loss = UncertaintyLoss()
>>> pred = np.array([0.0, 1.0])
>>> true = np.array([0.0, 0.0])
>>> log_var = np.array([0.0, 0.0])
>>> round(loss(pred, true, log_var).value, 6)
1.168939
reduction: str = 'mean'