nvalchemi.training.PiecewiseWeight#

pydantic model nvalchemi.training.PiecewiseWeight[source]#

Step-function loss weight that switches value at fixed boundaries.

PiecewiseWeight holds a constant weight within each interval and jumps to the next value once the schedule index crosses a boundary. Given boundaries \(b_0 < b_1 < \dots < b_{k-1}\) and values \(v_0, \dots, v_k\), the weight at schedule index \(t\) is the value of the interval that contains \(t\):

\[\begin{split}w(t) = \begin{cases} v_0 & t < b_0, \\ v_j & b_{j-1} \le t < b_j \quad (1 \le j \le k-1), \\ v_k & t \ge b_{k-1}. \end{cases}\end{split}\]

Equivalently \(w(t) = v_j\) with \(j = \bigl|\{\, m : b_m \le t \,\}\bigr|\), the number of boundaries the index has reached or passed (each interval is closed on the left). Use it for stage-wise or curriculum-style training where a term should be on/off or held at discrete levels rather than ramped continuously – for example enabling a stress term only after a warm-up phase. The schedule index \(t\) is the global step when per_epoch=False (default) and the epoch when per_epoch=True.

Examples

>>> from nvalchemi.training.losses import PiecewiseWeight
>>> w = PiecewiseWeight(boundaries=(10, 20), values=(0.1, 0.5, 0.9))
>>> w(step=5, epoch=0), w(step=15, epoch=0), w(step=25, epoch=0)
(0.1, 0.5, 0.9)

Switch weights per epoch instead of per step:

>>> w = PiecewiseWeight(
...     boundaries=(5,), values=(0.0, 1.0), per_epoch=True
... )

Notes

values must have exactly len(boundaries) + 1 entries and boundaries must be strictly increasing and non-negative; an after validator raises ValueError otherwise. Fields are tuples (not lists) so instances stay hashable under the frozen model config.

field boundaries: tuple[int, ...] [Required]#

Strictly increasing, non-negative schedule-index boundaries.

field values: tuple[float, ...] [Required]#

Values for each interval; length len(boundaries) + 1.