Enhanced Scatter Search (eSS) global optimization.
Scatter search is a meta-heuristic for global optimization. A set of points
(the reference set, RefSet) is iteratively adapted to explore the parameter
space and to follow promising directions.
This implementation is based on [1][2],
but does not implement any constraint handling beyond box constraints.
The basic steps of ESS are:
Initialization: Generate a diverse set of points (RefSet) in the
parameter space.
Recombination: Generate new points by recombining the RefSet points.
Improvement: Improve the RefSet by replacing points with better ones.
The steps are repeated until a stopping criterion is met.
ESS is gradient-free, unless a gradient-based local optimizer is used
(local_optimizer).
Variables:
history – History of the best values/parameters found so far.
(Monotonically decreasing objective values.)
Various hyperparameters control the behavior of eSS.
Initialization is controlled by dim_refset and n_diverse.
Local optimizations are controlled by local_optimizer, local_n1,
local_n2, and balance.
The optimization stops if any of the following criteria are met:
The maximum number of iterations is reached (max_iter).
The maximum number of objective function evaluations is reached
(max_eval).
The maximum wall-time is reached (max_walltime_s).
One of these criteria needs to be provided.
Note that the wall-time and function evaluation criteria are not checked
after every single function evaluation, and thus, the actual number of
function evaluations may slightly exceed the given value.
Objective function evaluations inside ESSOptimizer can be
parallelized using multiprocessing or multithreading by passing a value
>1 for n_procs or n_threads, respectively.
For plausible values of hyperparameters,
see Villaverde et al.[3].
Parameters:
dim_refset (int) – Size of the RefSet. Note that in every iteration at least
dim_refset**2-dim_refset function evaluations will occur.
max_iter (int) – Maximum number of eSS iterations.
local_n1 (int) – Minimum number of iterations before first local search.
Ignored if local_optimizer=None.
local_n2 (int) – Minimum number of iterations between consecutive local
searches. Maximally one local search per performed in each
iteration. Ignored if local_optimizer=None.
local_optimizer (Optimizer | OptimizerFactory | None) – Local optimizer for refinement, or a callable that creates an
pypesto.optimize.Optimizer or None to skip local
searches.
In case of a callable, it will be called with the keyword arguments
max_walltime_s and max_eval, which should be passed to the
optimizer (if supported) to honor the overall budget.
See SacessFidesFactory for an example.
n_diverse (int) – Number of samples to choose from to construct the initial RefSet
max_eval – Maximum number of objective functions allowed. This criterion is
only checked once per iteration, not after every objective
evaluation, so the actual number of function evaluations may exceed
this value.
max_walltime_s – Maximum walltime in seconds. Will only be checked between local
optimizations and other simulations, and thus, may be exceeded by
the duration of a local search.
balance (float) – Quality vs. diversity balancing factor with
\(0 \leq balance \leq 1\); 0 = only quality,
1 = only diversity.
Affects the choice of starting points for local searches. I.e.,
whether local optimization should focus on improving the best
solutions found so far (quality), or on exploring new regions of
the parameter space (diversity).
Ignored if local_optimizer=None.
n_procs – Number of parallel processes to use for parallel function
evaluation. Mutually exclusive with n_threads.
n_threads – Number of parallel threads to use for parallel function evaluation.
Mutually exclusive with n_procs.
result_includes_refset (bool) – Whether the minimize() result should include the final
RefSet.
result_includes_local_solutions (bool) – Whether the minimize() result should include the local search
results (if any).
The optimization result. Contains the overall best value found and,
depending on the settings, the final RefSet and local search
results.
Note that the number of gradient and Hessian evaluations is not
tracked and thus set to 0 in the result, even if a local optimizer
is used that performs gradient/Hessian evaluations.
Compute an index order for local-search start points that balances
solution quality and diversity.
The priority combines a quality ranking (better objective values are
preferred) and a diversity ranking (candidates further from known local
optima are preferred). The final priority is a weighted combination of
the two ranks.
See [PenasGon2017] Algorithm 2 L12-L18.
Parameters:
x_best_children (ndarray) – Array of candidate parameter vectors with shape
(n_candidates,problem_dim).
fx_best_children (ndarray) – Array of objective values for the candidates
with shape (n_candidates,).
local_solutions (Sequence[OptimizerResult]) – Sequence of existing local ``OptimizerResult``s
used to compute distances for diversity. May be empty.
selector (EvalSelectorBase) – Optional selector / handler for evaluations.
See TopKSelector and ThresholdSelector.
If not provided, all objective evaluations will be kept in memory.
Factory for CmaOptimizer instances for use with
SacessOptimizer.
__call__() will forward the walltime limit and function evaluation
limit imposed on SacessOptimizer to CmaOptimizer.
Besides that, default options are used.
Parameters:
options (dict[str, Any] | None) – Options as passed to CmaOptimizer.__init__().
See cma.CMAOptions() for available options.
Factory for FidesOptimizer instances for use with
SacessOptimizer.
__call__() will forward the walltime limit and function evaluation
limit imposed on SacessOptimizer to FidesOptimizer.
Besides that, default options are used.
Parameters:
fides_options (dict[str, Any] | None) – Options for the FidesOptimizer.
See fides.constants.Options.
fides_kwargs (dict[str, Any] | None) – Keyword arguments for the FidesOptimizer. See
FidesOptimizer.__init__(). Must not include options.
Factory for IpoptOptimizer instances for use with
SacessOptimizer.
__call__() will forward the walltime limit and function evaluation
limit imposed on SacessOptimizer to IpoptOptimizer.
Besides that, default options are used.
A shared-memory-based implementation of the
Self-Adaptive Cooperative Enhanced Scatter Search (SaCeSS) algorithm
presented in Penas et al.[4]. This is a meta-heuristic for
global optimization. Multiple processes (workers) run
enhancedscattersearches(eSSs) in parallel.
After each ESS iteration, depending on the outcome, there is a chance
of exchanging good parameters, and changing eSS hyperparameters to those of
the most promising worker. See Penas et al.[4] for details.
SacessOptimizer can be used with or without a local optimizer, but
it is highly recommended to use one.
Variables:
histories – List of the histories of the best values/parameters
found by each worker. (Monotonically decreasing objective values.)
See pyscat.plot.plot_sacess_history() for visualization.
problem (Problem) – The minimization problem.
Problem.startpoint_method() will be used to sample random
points. SacessOptimizer will deal with non-evaluable points.
Therefore, using pypesto.startpoint.CheckedStartpoints
with check_fval=True or check_grad=True is not recommended
since it would create significant overhead.
num_workers (int | None) – Number of workers to be used. A minimum of 2 workers is required.
If this argument is given,
(different) default eSS settings will be used for each worker.
Mutually exclusive with ess_init_args.
See get_default_ess_options() for details on the default
settings.
Currently, if problem.objective supports gradients,
the default local optimizer is FidesOptimizer.
Otherwise, no local optimizer is used by default.
This may be changed in future releases.
List of argument dictionaries passed to
ESSOptimizer.__init__(). Each entry corresponds to one worker
process. I.e., the length of this list is the number of eSSs.
Mutually exclusive with num_workers.
If not provided, default settings will be used,
see get_default_ess_options().
Ideally, this list contains some more conservative and some more
aggressive configurations.
Resource limits such as max_eval apply to a single eSS
iteration, not to the full search.
Mutually exclusive with num_workers.
max_walltime_s (float) – Maximum walltime in seconds. It will only be checked between local
optimizations and other simulations, and thus, may be exceeded by
the duration of a local search. Defaults to no limit.
Note that in order to impose the wall time limit also on the local
optimizer, the user has to provide a wrapper function similar to
SacessFidesFactory.__call__().
autosave_dir (Path | str) – Directory for storing intermediate results.
If not None, HDF5 files with intermediate results will be
saved in this directory during the optimization.
This can be used to monitor the optimization while it is running,
or to recover results if the optimization was interrupted.
When setting this option, make sure any optimizers running in
parallel have a unique tmpdir.
The directory is expected to be empty.
mp_start_method (str) – The start method for the multiprocessing context.
See multiprocessing for details. Running SacessOptimizer
under Jupyter may require mp_start_method="fork".
Note that if this function is called from a multithreaded program
(multiple threads running at the time of calling this function) and
the multiprocessing start method is set to fork, there is
a good chance for deadlocks. Postpone spawning threads until after
minimize or change the start method to spawn.
Result object with optimized parameters in
pypesto.Result.optimize_result.
Only the best solution found is returned.
To get the per-worker histories of the best values/parameters
found, use the histories attribute.
Note that the number of gradient and Hessian evaluations is not
tracked and thus set to 0 in the result, even if a local optimizer
is used that performs gradient/Hessian evaluations.
The local optimizer to use
(see same argument in ESSOptimizer):
a Optimizer instance,
a Callable returning an optimizer instance,
or None to disable local searches.
The callable can be used to propagate walltime limits to the local
optimizers. See SacessFidesFactory.__call__() for an example.
manager_minimum_rejection_threshold (float) – Initial and minimum threshold for relative objective improvements that
incoming solutions have to pass to be accepted. If the number of
rejected solutions exceeds the number of workers, the threshold is
halved until it reaches manager_minimum_rejection_threshold.
worker_acceptance_threshold (float) – Minimum relative improvement of the objective compared to the best
known value to be eligible for submission to the Manager.
Hyperparameters that control when the workers will adapt their settings
based on the performance of the other workers.
The adaptation step is performed if all the following conditions are
met:
The number of function evaluations since the last solution was sent
to the manager times the number of optimization parameters is greater
than adaptation_min_evals.
The number of solutions received by the worker since the last
solution it sent to the manager is greater than
adaptation_sent_coeff*n_sent_solutions+adaptation_sent_offset,
where n_sent_solutions is the number of solutions sent to the
manager by the given worker.
threshold (float) – Threshold for accepting new entries.
Interpreted according to mode.
mode (str) – ‘abs’ or ‘rel’ mode for thresholding.
If ‘abs’, new entries are accepted if
fx-best_fx<=threshold.
If ‘rel’, new entries are accepted if
|(fx-best_fx)/best_fx|<=threshold.
dtype – Numpy dtype used for internal numeric storage.
Returns settings for num_workers parallel scatter searches, combining
more aggressive and more conservative configurations. Mainly intended for
use with SacessOptimizer. For details on the different options,
see keyword arguments of ESSOptimizer.__init__().
Setting appropriate values for n_threads and local_optimizer is
left to the user. Defaults to single-threaded and no local optimizer.
num_workers (int) – Number of configurations to return.
dim (int) – Problem dimension (number of optimized parameters).
local_optimizer (bool | Optimizer | Callable[..., Optimizer]) – The local optimizer to use
(see same argument in ESSOptimizer), a boolean indicating
whether to set the default local optimizer
(currently FidesOptimizer), a Optimizer instance,
or a Callable returning an optimizer instance.
The latter can be used to propagate walltime limits to the local
optimizers. See SacessFidesFactory.__call__() for an example.
The current default optimizer assumes that the optimized objective
function can provide its gradient. If this is not the case, the user
should provide a different local optimizer or consider using
pypesto.objective.finite_difference.FD to approximate the
gradient using finite differences.