Callback for Study.Optimize
A callback is invoked after every trial finishes, receiving the Study and the resulting
FrozenTrial. Use one to log to an experiment tracker, checkpoint state, or — as here — implement a
custom stopping rule. In OptunaSharp a callback is an Action<Study, FrozenTrial>, passed to
Optimize through the callbacks parameter.
Stop after N pruned trials in a row
This stateful callback counts consecutive pruned trials and calls study.Stop() once the count
reaches a threshold. Because it holds state across calls, model it as a small class and pass its
Invoke method:
using OptunaSharp;
// Stops the study once `threshold` trials are pruned back-to-back.
sealed class StopWhenTrialKeepBeingPrunedCallback
{
private readonly int _threshold;
private int _consecutivePrunedCount;
public StopWhenTrialKeepBeingPrunedCallback(int threshold) => _threshold = threshold;
// Signature matches Action<Study, FrozenTrial>: run after every finished trial.
public void Invoke(Study study, FrozenTrial trial)
{
if (trial.State == TrialState.Pruned)
_consecutivePrunedCount++; // another prune in the streak
else
_consecutivePrunedCount = 0; // a non-pruned trial resets the streak
if (_consecutivePrunedCount >= _threshold)
study.Stop(); // ask the optimize loop to exit after running trials finish
}
}
The objective prunes every trial after the first five (trial.Number is zero-based):
double Objective(Trial trial)
{
if (trial.Number > 4)
throw new TrialPruned(); // Optimize catches this and records the trial as Pruned
return trial.SuggestFloat("x", 0, 1);
}
Wire the callback in with a threshold of 2 — the study stops once two trials are pruned in a row, so
it finishes after 7 trials even though we asked for 10:
var callback = new StopWhenTrialKeepBeingPrunedCallback(2);
var study = Optuna.CreateStudy();
study.Optimize(Objective, nTrials: 10, callbacks: new Action<Study, FrozenTrial>[] { callback.Invoke });
study.Stop() only takes effect inside an objective or a callback; it lets the currently running
trials finish and then returns from Optimize. To stop a run from outside, such as from another thread
or on Ctrl+C, cancel the token passed as Optimize's ct instead. The run then ends the same way, and
Optimize throws OperationCanceledException (see
Easy parallelization).
Relationship to Optuna
| Optuna (Python) | OptunaSharp |
|---|---|
a callable callback(study, trial) |
an Action<Study, FrozenTrial> |
trial.state == TrialState.PRUNED |
trial.State == TrialState.Pruned |
study.stop() |
study.Stop() |
study.optimize(obj, n_trials=10, callbacks=[cb]) |
study.Optimize(obj, nTrials: 10, callbacks: new Action<Study, FrozenTrial>[] { cb.Invoke }) |
See also
Study and Trials · Pruners · Ask-and-tell interface · the API reference.