pycsamt.ai.losses.model#
Masked, weighted data-fit losses on canonical resistivity grids.
These losses implement the L_model term of the staged inversion
objective in the AI-inversion plan:
L = w_m * L_model + lambda_x * L_grad_x + lambda_z * L_grad_z
+ lambda_tv * L_TV + lambda_d * L_response
Inputs are predicted and true model arrays that share one canonical
geological-grid shape, e.g. (z, x) or (z, y, x) from
GeologyGrid. Cells may be excluded with
an explicit boolean mask, a non-finite value in either array, or a
zero weight.
All functions operate on plain NumPy arrays so the module stays importable without an optional deep-learning backend. Differentiable use inside a training loop is left to the caller’s autograd tensors, which support the same elementwise arithmetic used here.
Functions
|
Return inverse-depth weights normalized to sum to one. |
|
Masked, weighted Huber loss, robust to outlier cells. |
|
Masked, weighted mean/summed absolute error. |
|
Masked, weighted mean/summed squared error. |
Classes
|
Configurable, callable masked model data-fit loss. |
|
Immutable scalar result of a model data-fit loss. |
- class pycsamt.ai.losses.model.ModelLossResult(value, kind, reduction, n_valid, weight_sum)[source]
Bases:
objectImmutable scalar result of a model data-fit loss.
- Parameters:
value (float) – Reduced loss value.
nanwhen no cell was included andreduction="mean".kind ({"l1", "l2", "huber"}) – Elementwise 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_validwhen no explicit weights were supplied.
Examples
>>> import numpy as np >>> result = model_l2_loss(np.array([1.0, 2.0]), np.array([1.0, 0.0])) >>> result.value, result.n_valid (2.0, 2)
- value: float
- kind: str
- reduction: str
- n_valid: int
- weight_sum: float
- class pycsamt.ai.losses.model.ModelLoss(kind='l2', delta=1.0, reduction='mean', weights=None)[source]
Bases:
objectConfigurable, callable masked model data-fit loss.
Bundles a loss family, reduction, and optional fixed per-cell weights so the same configuration can be reused across batches in a training loop.
- Parameters:
kind ({"l1", "l2", "huber"}, default="l2") – Elementwise loss family.
delta (float, default=1.0) – Huber transition point. Ignored unless
kind="huber".reduction ({"mean", "sum"}, default="mean") – Reduction applied over valid, weighted cells.
weights (ndarray or None, optional) – Fixed per-cell weights reused on every call, broadcastable to the input shape. A
weightsargument passed directly to__call__()overrides this default for that call only.
Examples
>>> import numpy as np >>> loss = ModelLoss(kind="l1") >>> loss(np.array([1.0, 3.0]), np.array([1.0, 1.0])).value 1.0
- kind: str = 'l2'
- delta: float = 1.0
- reduction: str = 'mean'
- classmethod with_depth_weights(n_depth, *, dimension=2, kind='l2', delta=1.0, reduction='mean')[source]
Build a loss weighted by inverse depth on the leading axis.
- Parameters:
n_depth (int) – Number of depth cells along the grid’s leading axis.
dimension ({2, 3}, default=2) – Grid rank, matching
dimension: 2 for(z, x)grids, 3 for(z, y, x)grids. Used only to reshape the depth weights for broadcasting.kind (str) – Forwarded to the constructor.
delta (float) – Forwarded to the constructor.
reduction (str) – Forwarded to the constructor.
- Returns:
Loss whose stored weights broadcast against grids shaped
(n_depth, ...).- Return type:
Examples
>>> loss = ModelLoss.with_depth_weights(3, dimension=2) >>> loss.weights.shape (3, 1)
- pycsamt.ai.losses.model.model_l1_loss(y_pred, y_true, *, valid=None, weights=None, reduction='mean')[source]
Masked, weighted mean/summed absolute error.
- Parameters:
y_pred (array-like) – Predicted and true model values sharing one shape, typically log-resistivity on a canonical geological grid.
y_true (array-like) – Predicted and true model values sharing one shape, typically log-resistivity on a canonical geological grid.
valid (array-like of bool or None, optional) – Explicit cell mask, combined with finite-value masking of both inputs.
weights (array-like or None, optional) – Non-negative per-cell weights broadcastable to the shared shape, e.g. from
depth_weights().reduction ({"mean", "sum"}, default="mean") – Whether to divide by the total weight or return the raw sum.
- Returns:
Reduced
L1loss with provenance.- Return type:
Examples
>>> import numpy as np >>> model_l1_loss(np.array([1.0, 3.0]), np.array([1.0, 1.0])).value 1.0
- pycsamt.ai.losses.model.model_l2_loss(y_pred, y_true, *, valid=None, weights=None, reduction='mean')[source]
Masked, weighted mean/summed squared error.
- Parameters:
y_pred (array-like) – Predicted and true model values sharing one shape.
y_true (array-like) – Predicted and true model values sharing one shape.
valid (array-like of bool or None, optional) – Explicit cell mask, combined with finite-value masking of both inputs.
weights (array-like or None, optional) – Non-negative per-cell weights broadcastable to the shared shape.
reduction ({"mean", "sum"}, default="mean") – Whether to divide by the total weight or return the raw sum.
- Returns:
Reduced
L2loss with provenance.- Return type:
Examples
>>> import numpy as np >>> model_l2_loss(np.array([1.0, 3.0]), np.array([1.0, 1.0])).value 2.0
- pycsamt.ai.losses.model.model_huber_loss(y_pred, y_true, *, delta=1.0, valid=None, weights=None, reduction='mean')[source]
Masked, weighted Huber loss, robust to outlier cells.
- Parameters:
y_pred (array-like) – Predicted and true model values sharing one shape.
y_true (array-like) – Predicted and true model values sharing one shape.
delta (float, default=1.0) – Positive transition point between the quadratic and linear regimes.
valid (array-like of bool or None, optional) – Explicit cell mask, combined with finite-value masking of both inputs.
weights (array-like or None, optional) – Non-negative per-cell weights broadcastable to the shared shape.
reduction ({"mean", "sum"}, default="mean") – Whether to divide by the total weight or return the raw sum.
- Returns:
Reduced Huber loss with provenance.
- Return type:
Examples
>>> import numpy as np >>> small = model_huber_loss( ... np.array([0.5]), np.array([0.0]), delta=1.0 ... ).value >>> large = model_huber_loss( ... np.array([5.0]), np.array([0.0]), delta=1.0 ... ).value >>> round(small, 3), round(large, 3) (0.125, 4.5)
- pycsamt.ai.losses.model.depth_weights(n_depth)[source]
Return inverse-depth weights normalized to sum to one.
Shallower cells (small index) receive more weight than deeper ones, matching the intuition that shallow structure is easier to recover and should not dominate a training loss.
- Parameters:
n_depth (int) – Number of depth cells, at least one.
- Returns:
Weights proportional to
1 / (1 + depth_index).- Return type:
ndarray, shape (n_depth,)
Examples
>>> import numpy as np >>> weights = depth_weights(2) >>> np.round(weights, 6) array([0.666667, 0.333333])