Controls

Controls are repeatedly applied in sequence until a control triggers a stop. Each control type has a detailed doc-string. Below is a short summary, with some advanced options omitted.

controldescriptionenabled if these are overloadedcan trigger a stopnotation in Prechelt
Step(n=1)Train model for n iterationstrain!no
Info(f=identity)Log to Info the value of f(model)train!no
Warn(predicate, f="")Log to Warn the value of f or f(model) if predicate(model) holdstrain!no
Error(predicate, f="")Log to Error the value of f or f(model) if predicate(model) holds and then stoptrain!yes
Callback(f=identity)Call f(model)train!yes
TimeLimit(t=0.5)Stop after t hourstrain!yes
NumberLimit(n=100)Stop after n applications of the controltrain!yes
NumberSinceBest(n=6)Stop when best loss occurred n control applications agotrain!yes
WithNumberDo(f=identity)Call f(n + 1) where n is the number of complete control cycles so fartrain!yes
WithLossDo(f=identity)Call f(loss) where loss is the current losstrain!, lossyes
WithTrainingLossesDo(f=identity)Call f(v) where v is the current batch of training lossestrain!, training_lossesyes
InvalidValue()Stop when NaN, Inf or -Inf loss/training loss encounteredtrain!yes
Threshold(value=0.0)Stop when loss < valuetrain!, lossyes
GL(alpha=2.0)Stop after "Generalization Loss" exceeds alphatrain!, lossyes$GL_α$
Patience(n=5)Stop after n consecutive loss increasestrain!, lossyes$UP_s$
PQ(alpha=0.75, k=5)Stop after "Progress-modified GL" exceeds alphatrain!, loss, training_lossesyes$PQ_α$
Warmup(c; n=1)Wait for n loss updates before checking criteria ctrain!no
Data(data)Call ingest!(model, datum) on the next item in the iterable data.train!, ingest!yes

Table 1. Atomic controls

Stopping option. All the following controls trigger a stop if the provided function f returns true and stop_if_true=true is specified in the constructor: Callback, WithNumberDo, WithLossDo, WithTrainingLossesDo.

There are also three control wrappers to modify a control's behavior:

wrapperdescription
IterationControl.skip(control; predicate=1)Apply control every predicate applications of the control wrapper (can also be a function; see doc-string)
IterationControl.louder(control; by=1)Increase the verbosity level of control by the specified value (negative values lower verbosity)
IterationControl.with_state_do(control; f=...)Apply control and call f(x) where x is the internal (public) state of control; useful for debugging. Default f logs state to Info.
IterationControl.composite(controls...)Apply each control in controls in sequence; mostly for internal use

Table 2. Wrapped controls

IterationControl.Step — Type
Step(; n=1)

An iteration control, as in, Step(2).

Train for n more iterations. Will never trigger a stop.

source
IterationControl.Info — Type
Info(f=identity)

An iteration control, as in, Info(my_loss_function).

Log to Info the value of f(m), where m is the object being iterated. If IterativeControl.expose(m) has been overloaded, then log f(expose(m)) instead.

Can be suppressed by setting the global verbosity level sufficiently low.

See also Warn, Error.

source
IterationControl.Warn — Type
Warn(predicate; f="")

An iteration control, as in, Warn(m -> length(m.cache) > 100, f="Memory low").

If predicate(m) is true, then log to Warn the value of f (or f(IterationControl.expose(m)) if f is a function). Here m is the object being iterated.

Can be suppressed by setting the global verbosity level sufficiently low.

See also Info, Error.

source
IterationControl.Error — Type
Error(predicate; f="", exception=nothing))

An iteration control, as in, Error(m -> isnan(m.bias), f="Bias overflow!").

If predicate(m) is true, then log at the Error level the value of f (or f(IterationControl.expose(m)) if f is a function) and stop iteration at the end of the current control cycle. Here m is the object being iterated.

Specify exception=... to throw an immediate exception, without waiting to the end of the control cycle.

See also Info, Warn.

source
IterationControl.Callback — Type
Callback(f=_->nothing, stop_if_true=false, stop_message=nothing, raw=false)

An iteration control, as in, Callback(m->put!(v, my_loss_function(m)).

Call f(IterationControl.expose(m)), where m is the object being iterated, unless raw=true, in which case call f(m) (guaranteed if expose has not been overloaded.) If stop_if_true is true, then trigger an early stop if the value returned by f is true, logging the stop_message if specified.

When using with MLJIteration.jl, Callback(f) is the same as WithMachineDo(f).

source
EarlyStopping.TimeLimit — Type
TimeLimit(; t=0.5)

An early stopping criterion for loss-reporting iterative algorithms.

Stopping is triggered after t hours have elapsed since the stopping criterion was initiated.

Any Julia built-in Real type can be used for t. Subtypes of Period may also be used, as in TimeLimit(t=Minute(30)).

Internally, t is rounded to nearest millisecond.

source
EarlyStopping.NumberLimit — Type
NumberLimit(; n=100)

An early stopping criterion for loss-reporting iterative algorithms.

A stop is triggered by n consecutive loss updates, excluding "training" loss updates.

If wrapped in a stopper::EarlyStopper, this is the number of calls to done!(stopper).

source
EarlyStopping.NumberSinceBest — Type
NumberSinceBest(; n=6)

An early stopping criterion for loss-reporting iterative algorithms.

A stop is triggered when the number of calls to the control, since the lowest value of the loss so far, is n.

If using IterationControl.jl, see also the cusstomizable loss-based stopping criterion, WithLossDo and WithTrainingLossesDo, which have anstopiftrue` option.

source
IterationControl.WithNumberDo — Type
WithNumberDo(f=identity, stop_if_true=false, stop_message=nothing)

An iteration control, as in, WithNumberDo(n->put!(my_channel, n)).

Call f(n + 1), where n is the number of already completed control cycles (so, n = 1, 2, 3, ..., unless control is wrapped in a IterationControl.skip).

If stop_if_true is true, then trigger an early stop if the value returned by f is true, logging the stop_message if specified.

source
IterationControl.WithLossDo — Type
WithLossDo(f=identity, stop_if_true=false, stop_message=nothing)

An iteration control, as in, WithLossDo(x->put!(my_losses, x)).

Call f(loss), where loss is current loss.

If stop_if_true is true, then trigger an early stop if the value returned by f is true, logging the stop_message if specified.

source
IterationControl.WithTrainingLossesDo — Type
WithTrainingLossesDo(f=identity, stop_if_true=false, stop_message=nothing)

An iteration control, as in, WithTrainingLossesDo(v->put!(my_losses, last(v)).

Call f(training_losses), where training_losses is the vector of most recent batch of training losses.

If stop_if_true is true, then trigger an early stop if the value returned by f is true, logging the stop_message if specified.

source
EarlyStopping.InvalidValue — Type
InvalidValue()

An early stopping criterion for loss-reporting iterative algorithms.

Stop if a loss (or training loss) is NaN, Inf or -Inf (or, more precisely, if isnan(loss) or isinf(loss) is true).

If using IterationControl.jl, see also the cusstomizable loss-based stopping criterion, WithLossDo and WithTrainingLossesDo, which have anstopiftrue` option.

source
EarlyStopping.Threshold — Type
Threshold(; value=0.0)

An early stopping criterion for loss-reporting iterative algorithms.

A stop is triggered as soon as the loss drops below value.

If using IterationControl.jl, see also the cusstomizable loss-based stopping criterion, WithLossDo and WithTrainingLossesDo, which have anstopiftrue` option.

source
EarlyStopping.GL — Type
GL(; alpha=2.0)

An early stopping criterion for loss-reporting iterative algorithms.

A stop is triggered when the (rescaled) generalization loss exceeds the threshold alpha.

Terminology. Suppose $E_1, E_2, ..., E_t$ are a sequence of losses, for example, out-of-sample estimates of the loss associated with some iterative machine learning algorithm. Then the generalization loss at time t, is given by

$GL_t = 100 (E_t - E_{opt}) \over |E_{opt}|$

where $E_{opt}$ is the minimum value of the sequence.

Reference: Prechelt, Lutz (1998): "Early Stopping- But When?", in Neural Networks: Tricks of the Trade, ed. G. Orr, Springer..

source
EarlyStopping.PQ — Type
PQ(; alpha=0.75, k=5, tol=eps(Float64))

A stopping criterion for training iterative supervised learners.

A stop is triggered when Prechelt's progress-modified generalization loss exceeds the threshold $PQ_T > alpha$, or if the training progress drops below $P_j ≤ tol$. Here k is the number of training (in-sample) losses used to estimate the training progress.

Context and explanation of terminology

The training progress at time $j$ is defined by

$P_j = 1000 |M - m|/|m|$

where $M$ is the mean of the last k training losses $F_1, F_2, …, F_k$ and $m$ is the minimum value of those losses.

The progress-modified generalization loss at time $t$ is then given by

$PQ_t = GL_t / P_t$

where $GL_t$ is the generalization loss at time $t$; see GL.

PQ will stop when the following are true:

  1. At least k training samples have been collected via done!(c::PQ, loss; training = true) or update_training(c::PQ, loss, state)
  2. The last update was an out-of-sample update. (done!(::PQ, loss; training=true) is always false)
  3. The progress-modified generalization loss exceeds the threshold $PQ_t > alpha$ OR the training progress stalls $P_j ≤ tol$.

Reference: Prechelt, Lutz (1998): "Early Stopping- But When?", in Neural Networks: Tricks of the Trade, ed. G. Orr, Springer..

source
EarlyStopping.Warmup — Type
Warmup(c::StoppingCriterion, n)

Wait for n updates before checking stopping criterion c for the first time.

source
IterationControl.Data — Type
Data(my_data; stop_when_exhausted=false)

An iteration control, as in, Data(rand(100)).

In each application of this control a new item from the iterable, data, is retrieved (using iterate) and IterationControl.ingest!(m, item) is called. Here m is the object being iteratively trained.

The control becomes passive once the data iterable is done. To trigger a stop after one passive application of the control, set stop_when_exhausted=true.

source
IterationControl.skip — Function
IterationControl.skip(control, predicate=1)

An iteration control wrapper.

If predicate is an integer, k: Apply control on every k calls to apply the wrapped control, starting with the kth call.

If predicate is a callable: Apply control as usual when predicate(n + 1) is true but otherwise skip. Here n is the number of control cycles applied so far.

While the application of the underlying control gets skipped, the (unchanged) internal state is nevertheless recorded to the corresponding ControlTrace, but this trace does not start recording until the first application of control:

using IterationControlmodel = IterationControl.SquareRooter(4)julia> traces = IC.train!(    m,    Step(1),    IterationControl.skip(WithNumberDo(x->(@info(x); x)), predicate=2),    NumberLimit(5),)[ Info: 2[ Info: 4[ Info: final loss: 0.0[ Info: final training loss: 0.0[ Info: Stop triggered by NumberLimit(5) stopping criterion.3-element Vector{Any}: ControlTrace{<:Step}, ending (new_iterations = 5, new_steps = 5) ControlTrace{<:Skip}, ending (number = 4, called_back = 4) ControlTrace{<:NumberLimit}, ending (number = 5,)julia> traces[2].number4-element Vector{Int64}: 2 2 4 4
source
IterationControl.louder — Function
IterationControl.louder(control, by=1)

Wrap control to make in more (or less) verbose. The same as control, but as if the global verbosity were increased by the value by.

source
IterationControl.with_state_do — Function
IterationControl.with_state_do(
    control,
    f=x->(@info "`$(typeof(control))` state: $x; x)",
    raw_state=false,
)

Wrap control to give access to the public form of its internal state (which is also the object accumulated by the corresponding ControlTrace returned by IterationControl.train!). Acts exactly like control except that f is called on current state. If f is not specified, the control type and state are logged to Info at every update. Useful for debugging custom controls.

If raw_state=true, then the raw internal state is accessed instead. Warning: The form of the raw state can change in any new release of IterationControls.jl.

source
IterationControl.composite — Function
composite(controls...)

Construct an iteration control that applies the specified controls in sequence. Mainly intended for internal use by IterationControls.jl.

source