Diagnostics#
Every check in prophys reports its findings in one format, whether it concerns the layer widths of a network surrogate, the convergence of a training run, a licence limit, a symbolic surrogate or a physics primitive. A finding has a stable code, a severity, a location and a hint, and renders like a compiler message:
error[NN104] width 6 does not split into 4 heads
--> surrogate 'wake', layer L1 (SelfAttention)
= hint choose heads dividing 6 or change the previous layer width
Errors raise ProphysError, a ValueError
carrying every finding in diagnostics and their codes in codes.
Warnings are issued as ProphysWarning, whose
diagnostic attribute holds the finding. Reports keep their findings too:
PretrainResult.diagnostics and CalibrationResult.diagnostics list
them and converged summarises the convergence checks. Colour is used on
a terminal unless NO_COLOR is set.
from prophys.diagnostics import ProphysError
try:
nn.Surrogate("wake", ["x"], layers=[nn.Dense(6), nn.SelfAttention(4)])
except ProphysError as e:
e.codes # ["NN104"]
e.diagnostics # the findings
Convergence#
Training of surrogates and calibration of models are checked the same way.
A non finite loss is a divergence (NN202, CAL202). Otherwise the
loss slope over the first and the last quarter of the run is divided by the
step size in effect there, and when the final progress per unit step size is
still above a tenth of the initial one the run stopped while improving
(NN201, CAL201). Normalising by the step size keeps decaying
schedules, which flatten every curve at the end, from hiding unfinished
training.
A flat loss is not proof of convergence. On a plateau, a slope in a flat valley or before a sigmoid saturates, the loss barely moves while the parameters keep walking in one direction, and a larger drop can follow much later. The second check therefore watches the parameters over the last quarter of the run (at least six steps). It divides their net displacement by the length of the path they travelled. Around a minimum the optimiser oscillates and the ratio is small. On a plateau every step points the same way and the ratio stays near one. Above one half the run is reported as not converged, with the ratio in the message. The tracker keeps only the first and the latest parameters and the running path length, so it costs nothing in memory.
A calibration through a saturated sigmoid. Its loss is flat for the first forty steps and then falls by three orders of magnitude. A forty step run already reports ``CAL201`` because the parameter still drifts.
Pretraining adds overfitting (NN203), poor fit (NN204),
miscalibrated intervals (NN205), unrepresentative validation data
(NN206) and a vanishing initial gradient (NN207), and checks its data
for non finite values, constant columns and too few rows.
Symbolic surrogates#
prophys.Surrogate wraps any JAX function. Its validate() method
evaluates it once and reports whether the output broadcasts with the inputs
(SUR102) and is finite (SUR103).
Codes#
|
unknown or malformed layer argument |
|---|---|
|
network program rejected by the native planner |
|
layer input width mismatch |
|
attention width does not split into heads |
|
layer needs a context that the surrogate does not declare |
|
layer breaks a declared monotonicity guarantee |
|
layer breaks the convexity guarantee |
|
reshape changes the element count |
|
too many residual slots |
|
output head does not match the declared outputs |
|
program entry not exact in single precision |
|
physics layer did not compile to native code |
|
missing or unknown surrogate input |
|
input unit incompatible with the declared unit |
|
input shape does not match the surrogate |
|
data contain non finite values |
|
input column is constant in the training data |
|
few training samples relative to the parameter count |
|
inputs and targets differ in length |
|
loss or distribution targets do not suit the output head |
|
training did not converge |
|
training diverged |
|
validation loss rises, the model overfits |
|
poor fit on validation data |
|
prediction intervals are miscalibrated |
|
validation data lie outside the training support |
|
gradient vanished at initialisation |
|
no head posterior available |
|
no support region available |
|
surrogate exceeds the free tier |
|
licensed asset needs a valid license |
|
model exceeds the free tier |
|
license rejected |
|
invalid amortization envelope, statistic or query |
|
amortized attribute is not scalar |
|
operational surrogate misses its accuracy criterion |
|
operational surrogate is stale |
|
calibration did not converge |
|
calibration diverged |
|
parameters are not identified by the data |
|
surrogate function is not callable |
|
surrogate output shape does not broadcast with its inputs |
|
surrogate output is not finite |
|
physics primitive argument has the wrong shape |
|
physics primitive argument outside its valid range |
|
tree ensemble shape invalid |
|
imported booster not supported |
|
monotone constraint on a learned split feature |