/// <summary> /// Create an early stopper hook for a certain parameter that stops training if the parameter does not improve for <see cref="patience"/> time steps. /// Improve means reach a new <see cref="ExtremaTarget.Max"/> by default or a new <see cref="ExtremaTarget.Min"/> if specified in the <see cref="target"/>. /// </summary> /// <param name="parameter">The parameter identifier.</param> /// <param name="patience">The patience (number of sequential decreases of the parameter, i.e. how many times the training can let us down before we call it a day).</param> /// <param name="target">The target for the given value (i.e. should it be a big or a small value).</param> public EarlyStopperHook(string parameter, int patience, ExtremaTarget target = ExtremaTarget.Max) : base(new TimeStep(TimeScale.Epoch, 1)) { string accumulatedParameter = "shared." + parameter.Replace('.', '_') + "_accumulated"; NumberAccumulatorHook accumulator = new NumberAccumulatorHook(parameter, accumulatedParameter, Utils.TimeStep.Every(1, TimeScale.Iteration)); RequireHook(accumulator); On(new ExtremaCriteria(accumulatedParameter, target).Negate().Repeated(patience, withoutInterruption: true)); }
/// <summary> /// Create an extrema criteria that fires when a certain parameter is at a certain extrema (min / max). /// </summary> /// <param name="parameter">The parameter (identifier) to check.</param> /// <param name="target">The target extrema (min / max).</param> public ExtremaCriteria(string parameter, ExtremaTarget target) : base(parameter) { if (parameter == null) { throw new ArgumentNullException(nameof(parameter)); } if (!Enum.IsDefined(typeof(ExtremaTarget), target)) { throw new InvalidEnumArgumentException(nameof(target), (int)target, typeof(ExtremaTarget)); } ParameterRegistry["parameter_identifier"] = parameter; ParameterRegistry["target"] = target; ParameterRegistry["current_extremum"] = double.NaN; }
public override bool CheckCriteria(IRegistry registry, IRegistryResolver resolver) { ExtremaTarget target = ParameterRegistry.Get <ExtremaTarget>("target"); string parameter = ParameterRegistry.Get <string>("parameter_identifier"); double value = SimpleDirectEntries[0] ? registry.Get <double>(parameter) : resolver.ResolveGetSingle <double>(parameter); double currentExtremum = ParameterRegistry.Get <double>("current_extremum"); bool reachedExtremum = target == ExtremaTarget.Min && value <currentExtremum || target == ExtremaTarget.Max && value> currentExtremum; if (double.IsNaN(currentExtremum) || reachedExtremum) { ParameterRegistry["current_extremum"] = value; return(true); } return(false); }
/// <summary> /// Create a hook that conditionally (extrema criteria) fetches a given value (i.e. registry identifier) at a given <see cref="ITimeStep"/>. /// </summary> /// <param name="valueIdentifier">The value that will be fetched (i.e. registry identifier). E.g. <c>"optimiser.cost_total"</c></param> /// <param name="timestep">The <see cref="ITimeStep"/> the hook will executed on.</param> /// <param name="target">The extrema criteria target.</param> public AccumulatedValueReporter(string valueIdentifier, ITimeStep timestep, ExtremaTarget target) : this(new[] { valueIdentifier }, timestep) { On(new ExtremaCriteria(GetAccumulatedIdentifier(valueIdentifier), target)); }
/// <summary> /// Create a hook that conditionally (extrema criteria) fetches a given value (i.e. registry identifier) at a given <see cref="ITimeStep"/>. /// </summary> /// <param name="valueIdentifier">The value that will be fetched (i.e. registry identifier). E.g. <c>"optimiser.cost_total"</c></param> /// <param name="timestep">The <see cref="ITimeStep"/> the hook will executed on.</param> /// <param name="target">The extrema criteria target.</param> public ValueReporter(string valueIdentifier, ITimeStep timestep, ExtremaTarget target) : this(new[] { valueIdentifier }, timestep) { On(new ExtremaCriteria(valueIdentifier, target)); }