Adding New Controls
Implementing new controls
There is no abstract control type; any object can be a control. Behavior is implemented using a functional style interface documented below. Only the first two methods below are compulsory.
Main methods:
IterationControl.update!(control, model, verbosity, n)-> state# initializationIterationControl.update!(control, model, verbosity, n, state)-> stateEarlyStopping.public_state(control, state)IterationControl.done(control, state)::BoolIterationControl.takedown(control, verbosity, state)-> message
Here n is the control cycle count, i.e., one more than the the number of completed control cycles.
Control traits (fallback to false):
IterationControl.needs_loss(control)IterationControl.needs_training_losses(control)IterationControl.needs_ingest(control)
Simplified version of how IterationControl.train! calls these methods:
function train!(model, controls...; verbosity::Int=1) control = composite(controls...) # first training event: n = 1 # counts control cycles state = update!(control, model, verbosity, n) finished = done(control, state) <code that initializes the control traces> <and writes to each trace the current public state> # subsequent training events: while !finished n += 1 state = update!(control, model, verbosity, n, state) finished = done(control, state) <code to update the traces with current public state> end <call `takedown(control, verbosity, state)` on each component control> <and store the the returned messages to the traces> <return the control traces>endIterationControl.update! — Function
IterationControl.update!(control, model, verbosity, n)Return initialized internal state for control, when controlling model. Here n is the current number of training iterations that have have been applied to model so far. (This needn't be one, as a previously applied Step(k) control may have k > 1).
The returned state, state, is not part of the public API. To inspect a user-facing form of state, as recorded in control traces, call IterationControl.public_state(control, state).
New control implementations
Compulsory for all new control types.
IterationControl.update!(control, model, verbosity, n, old_state)Return updated internal state for control, when controlling model. Here n is the current number of training iterations that have have been applied to model so far.
The returned state, state, is not part of the public API. To inspect a user-facing form of state, as recorded in control traces, call IterationControl.public_state(control, state).
New control implementations
May mutate state, but typically does not. A fallback returns old_state.
EarlyStopping.public_state — Function
EarlyStopping.public_state(criterion, state)Transform the state associated with some stopping criterion (or other control from IterationControl.jl) into a user-inspectable form. This form is stable, while state is private API.
New control implementations
This method must return a named tuple. A fallback returns state.
EarlyStopping.done — Function
IterationControl.done(control, state)Returns true if and only if the control wants to trigger a stop. Method belongs to EarlyStopping.jl, a dependency of IterationControl.
New control implementations
A fallback always returns false.
IterationControl.takedown — Function
takedown(control, verbosity, state) -> messageWith the understanding that all control updates are complete, log to Info or Warn a relevant message, and return the message as a string.
New control implementations
Typically the message is only logged to Info if non-empty and verbosity > 0 or, if it is a warning, logged to Warn if verbosity > -1. Irrespective of the verbosity level, the message should be returned, but can be "", the fallback value.
Ideally, the message should be brief. (The user can get detailed information about the final state of the control by inspecting the corresponding ControlTrace object.)
IterationControl.needs_loss — Function
IterationControl.needs_loss(control)Returns true if control is only supported for a model for which IterationControl.loss(model) is implemented.
IterationControl.needs_training_losses — Function
IterationControl.needs_training_losses(control)Returns true if control is only supported for a model for which IterationControl.training_losses(model) is implemented.
IterationControl.needs_ingest — Function
IterationControl.needs_ingest(control)Returns true if control is only supported for a model for which IterationControl.ingest!(model, datum) is implemented.