CMA-ES (evolution strategy), the main sub-module of cma implementing
in particular CMAEvolutionStrategy, fmin2 and further fmin_*
functions.
| Class | |
CMA-ES stochastic optimizer class with ask-and-tell interface. |
| Class | |
A results tuple from CMAEvolutionStrategy property result. |
| Exception | |
Injected solutions are not passed to tell as expected |
| Function | fmin |
DEPRECATED: use fmin2 instead. |
| Function | fmin2 |
functional interface to the stochastic optimizer CMA-ES for non-convex function minimization. |
| Function | fmin |
DEPRECATED: use cma.ConstrainedFitnessAL or cma.fmin_con2 instead. |
| Function | fmin |
optimize f with inequality constraints g. |
| Function | fmin |
minimize objective_function with lq-CMA-ES. |
| Function | fmin |
minimize objective_function with lq-CMA-ES. |
| Function | get_ |
return a functional or a template "empty" class. |
| Function | no |
Undocumented |
| Variable | all |
Undocumented |
| Variable | archive |
None ==> active when popsize < 33, for historical reasons, not really useful? |
| Variable | archive |
If cma.evolution_strategy.archive_sent_solutions, save the genotype in ask before the gp-transformation. This can be a considerable speed up with a large population size because it allows to bypass the inverse gp-transformation... |
| Variable | ask |
When detected, ignore inplace changes of solutions delivered by ask for updating in tell. Currently, solutions are (only) archived in _ask_phenotype_archive when integer variables were rounded at the end of ... |
| Variable | round |
round integer variables of sampled candidate solutions (at the end of ask) for the evaluation on the objective function. This takes about 15% CPU time with option verbose=-9, partly due to array copies?... |
| Variable | use |
Undocumented |
| Class | _ |
A results tuple from CMAEvolutionStrategy property result. |
| Class | _ |
a hack to get most code examples running |
| Class | _ |
No class docstring; 0/2 instance variable, 1/2 method documented |
| Class | _ |
keep and update a termination condition dictionary. |
| Class | _ |
Provide a termination signal depending on how much a vector has changed, |
| Function | _al |
try to figure a good logging value from various verbosity options |
| Function | _callable |
A callable is wrapped and None defaults to the empty list. |
| Function | _pass |
a callable that does nothing and return args[0] in case |
| Variable | _assertions |
Undocumented |
| Variable | _assertions |
Undocumented |
| Variable | _debugging |
Undocumented |
| Variable | _depreciated |
Undocumented |
| Variable | _new |
Undocumented |
DEPRECATED: use fmin2 instead.
fmin will remain fully functional and be maintained in the foreseeable future.
Return
Return the list provided in CMAEvolutionStrategy.result appended
with termination conditions, an OOOptimizer and a BaseDataLogger:
res = es.result + (es.stop(), es, logger)
- where
- res[0] (xbest) -- best evaluated solution
- res[1] (fbest) -- respective function value
- res[2] (evals_best) -- respective number of function evaluations
- res[3] (evaluations) -- number of overall conducted objective function evaluations
- res[4] (iterations) -- number of overall conducted iterations
- res[5] (xfavorite) -- mean of the final sample distribution
- res[6] (stds) -- effective stds of the final sample distribution
- res[-3] (stop) -- termination condition(s) in a dictionary
- res[-2] (es) -- class
CMAEvolutionStrategyinstance - res[-1] (logger) -- class
CMADataLoggerinstance == es.logger
The successor fmin2 is an alias for:
res = fmin(...) return res[0], res[-2]
For descriptions of the input arguments see fmin2.
For completness, recovering the output of fmin from fmin2:
es = fmin2(...)[1] # fmin2(...)[0] is es.result.xbest return es.result + (es.stop(), es, es.logger)
The best found solution is equally available under:
fmin(...)[0] fmin2(...)[0] fmin2(...)[1].result[0] fmin2(...)[1].result.xbest fmin2(...)[1].best.x
The incumbent, current estimate for the optimum is available under:
fmin(...)[5] fmin2(...)[1].result[5] fmin2(...)[1].result.xfavorite
Examples
The following example calls fmin optimizing the Rosenbrock function
in 10-D with initial solution 0.1 and initial step-size 0.5. The
options are specified for the usage with the doctest module.
>>> import cma >>> # cma.CMAOptions() # returns all possible options >>> options = {'CMA_diagonal':100, 'seed':1234, 'verb_time':0} >>> >>> res = cma.fmin(cma.ff.rosen, [0.1] * 10, 0.3, options) #doctest: +ELLIPSIS (5_w,10)-aCMA-ES (mu_w=3.2,w_1=45%) in dimension 10 (seed=1234...) Covariance matrix is diagonal for 100 iterations (1/ccov=26... Iterat #Fevals function value axis ratio sigma ... 1 10 ... termination on tolfun=1e-11 ... final/bestever f-value = ... >>> assert res[1] < 1e-12 # f-value of best found solution >>> assert res[2] < 8000 # evaluations
The above call is pretty much equivalent with the slightly more verbose call:
res = cma.CMAEvolutionStrategy([0.1] * 10, 0.3,
options=options).optimize(cma.ff.rosen).result
where optimize returns a CMAEvolutionStrategy instance. The
following example calls fmin optimizing the Rastrigin function
in 3-D with random initial solution in [-2,2], initial step-size 0.5
and the BIPOP restart strategy (that progressively increases population).
The options are specified for the usage with the doctest module.
>>> import cma >>> # cma.CMAOptions() # returns all possible options >>> options = {'seed':12345, 'verb_time':0, 'ftarget': 1e-8} >>> >>> res = cma.fmin(cma.ff.rastrigin, lambda : 2. * np.random.rand(3) - 1, 0.5, ... options, restarts=9, bipop=True) #doctest: +ELLIPSIS (3_w,7)-aCMA-ES (mu_w=2.3,w_1=58%) in dimension 3 (seed=12345...
In either case, the method:
cma.plot();
(based on matplotlib.pyplot) produces a plot of the run and, if
necessary:
cma.s.figshow()
shows the plot in a window. Finally:
cma.s.figsave('myfirstrun') # figsave from matplotlib.pyplot
will save the figure in a png.
We can use the gradient like
>>> import cma >>> res = cma.fmin(cma.ff.rosen, np.zeros(10), 0.1, ... options = {'ftarget':1e-8,}, ... gradf=cma.ff.grad_rosen, ... ) #doctest: +ELLIPSIS (5_w,... >>> assert cma.ff.rosen(res[0]) < 1e-8 >>> assert res[2] < 3600 # 1% are > 3300 >>> assert res[3] < 3600 # 1% are > 3300
If solution can only be comparatively ranked, either use
CMAEvolutionStrategy directly or the objective accepts a list
of solutions as input:
>>> def parallel_sphere(X): return [cma.ff.sphere(x) for x in X] >>> x, es = cma.fmin2(None, 3 * [0], 0.1, {'verbose': -9}, ... parallel_objective=parallel_sphere) >>> assert es.result[1] < 1e-9
| See Also | |
CMAEvolutionStrategy, OOOptimizer.optimize, plot,
CMAOptions, scipy.optimize.fmin |
functional interface to the stochastic optimizer CMA-ES for non-convex function minimization.
Return the tuple (xbest, es) where es is a
CMAEvolutionStrategy instance, see in particular es.result and
es.result_pretty() for detailed results.
Calling Sequences
- x, es = fmin2(objective_function, x0, sigma0)
- minimizes objective_function starting at x0 and with standard deviation sigma0 (step-size)
- x, es = fmin2(objective_function, x0, sigma0, options={'ftarget': 1e-5})
- minimizes objective_function up to target function value 1e-5, which is typically useful for benchmarking.
- x, es = fmin2(objective_function, x0, sigma0, args=('f',))
- minimizes objective_function called with an additional argument 'f'.
- x, es = fmin2(objective_function, x0, sigma0, options={'ftarget':1e-5, 'popsize':40})
- uses additional options ftarget and popsize
- x, es = fmin2(objective_function, esobj, None, options={'maxfevals': 1e5})
- uses the
CMAEvolutionStrategyobject instance esobj to optimize objective_function, similar to esobj.optimize().
Less recommended calling patterns are:
es = cma.fmin2(...)[1] # `es` contains all available information x = cma.fmin2(...)[0] # keep only the best evaluated solution
Arguments
- objective_function
- called as objective_function(x, *args) to be minimized.
x is a one-dimensional
numpy.ndarray. See also theparallel_objectiveargument. objective_function can returnnumpy.NaN, which is interpreted as outright rejection of solution x and invokes an immediate resampling and (re-)evaluation of a new solution not counting as function evaluation. The attribute variable_annotations is passed into the CMADataLogger.persistent_communication_dict. - x0
- list or
numpy.ndarray, initial guess of minimum solution before the application of the geno-phenotype transformation according to the transformation option. It can also be a callable that is called (without input argument) before each restart to yield the initial guess such that each restart may start from a different place. Otherwise, x0 can also be acma.CMAEvolutionStrategyobject instance, in that case sigma0 can be None. - sigma0
- scalar, initial standard deviation in each coordinate.
sigma0 should be about 1/4th of the search domain width
(where the optimum is to be expected). The variables in
objective_function should be scaled such that they
presumably have similar sensitivity.
See also
ScaleCoordinates. - options
- a dictionary with additional options passed to the constructor of class CMAEvolutionStrategy, see cma.CMAOptions () for a list of available options.
- args=()
- arguments to be used to call the objective_function
- gradf=None
- gradient of f, where len(gradf(x, *args)) == len(x). gradf is called once in each iteration if gradf is not None.
- restarts=0
- number of restarts with increasing population size, see also
parameter incpopsize. For the time being (this may change in
future) restarts can also be a
dictwhere the keys maxrestarts=9 and maxfevals=np.inf are interpreted. An emptydictis interpreted as restarts=0. An IPOP-CMA-ES restart is invoked if restarts > 0 or restarts['maxrestarts'] > 0 and if current_evals < min((restarts['maxfevals'], options['maxfevals'])) and neither the 'ftarget' nor the termination_callback option was triggered; restarts['maxfevals'] does not terminate during the run or restart; to restart from different points (recommended), pass x0 as acallable; see also parameter bipop. - restart_from_best=False
- which point to restart from
- incpopsize=2
- multiplier for increasing the population size popsize before each restart
- parallel_objective
- an objective function that accepts a list of
numpy.ndarrayas input and returns alist, which is mostly used instead ofobjective_function, but for the initial (also initial elitist) and the final evaluations unless not callable(objective_function). If parallel_objective is given, the objective_function (first argument) may be None. - eval_initial_x=None
- evaluate initial solution, for None only with elitist option
- noise_handler=None
- must be
Trueor acma.NoiseHandlerclass or instance to invoke noise handling. The latter gives control over the specific settings for the noise handling, see help(cma.NoiseHandler). - noise_change_sigma_exponent=1
- exponent for the sigma increment provided by the noise handler for additional noise treatment. 0 means no sigma change.
- noise_evaluations_as_kappa=0
- instead of applying reevaluations, the "number of evaluations" is (ab)used as scaling factor kappa (experimental).
- bipop=False
- if bool(bipop) is True, run as BIPOP-CMA-ES; BIPOP is a special
restart strategy switching between two population sizings - small
(relative to the large population size and with varying initial
sigma, the first run is accounted on the "small" budget) and large
(progressively increased as in IPOP). This makes the algorithm
potentially solve both, functions with many regularly or
irregularly arranged local optima (the latter by frequently
restarting with small populations). Small populations are
(re-)started as long as the cumulated budget_small is smaller than
bipopx max(1, budget_large). For thebipopparameter to actually conduct restarts also with the larger population size, select a non-zero number of (IPOP) restarts; the recommended setting is restarts <= 9 andx0passed as acallablethat generates randomized initial solutions. Small-population restarts do not count into the total restart count. - callback=None
callableor list of callables called at the end of each iteration with the currentCMAEvolutionStrategyinstance as argument.- init_callback=None
callableor list of callables called at the end of initialization of theCMAEvolutionStrategyinstance with this instance as argument (likecallback). This allows to reassign attributes without a correspondingCMAOption. For example, es.integer_centering = lambda *args: None disables integer centering (which is enabled by default when integer_variables are given in theoptions) or es.integer_centering = cma.integer_centering.IntCentering(es, correct_bias=False) disables its bias correction.
Optional Arguments
All values in the options dictionary are evaluated if they are of
type str, besides verb_filenameprefix, see class CMAOptions for
details. The full list is available by calling cma.CMAOptions().
>>> import cma >>> cma.CMAOptions() #doctest: +ELLIPSIS {...
Subsets of options can be displayed, for example like
cma.CMAOptions('tol'), or cma.CMAOptions('bound'),
see also class CMAOptions.
Details
This function is an interface to the class CMAEvolutionStrategy. The
latter class should be used when full control over the iteration loop
of the optimizer is desired.
Examples
The following example calls fmin2 optimizing the Rosenbrock function
in 10-D with initial solution 0.1 and initial step-size 0.5. The
options are specified for the usage with the doctest module.
>>> import cma >>> # cma.CMAOptions() # returns all possible options >>> options = {'CMA_diagonal':100, 'seed':1234, 'verb_time':0} >>> >>> x, es = cma.fmin2(cma.ff.rosen, [0.1] * 10, 0.3, options) #doctest: +ELLIPSIS (5_w,10)-aCMA-ES (mu_w=3.2,w_1=45%) in dimension 10 (seed=1234...) Covariance matrix is diagonal for 100 iterations (1/ccov=26... Iterat #Fevals function value axis ratio sigma ... 1 10 ... termination on tolfun=1e-11 ... final/bestever f-value = ... >>> assert es.result.fbest < 1e-12 # f-value of best found solution >>> assert es.result.evaluations < 8000 # evaluations
The above call is pretty much equivalent with the slightly more verbose call:
es = cma.CMAEvolutionStrategy([0.1] * 10, 0.3,
options=options).optimize(cma.ff.rosen)
x = es.result.xbest
where optimize returns the CMAEvolutionStrategy instance. The
following example calls fmin2 optimizing the Rastrigin function
in 3-D with random initial solution in [-2,2], initial step-size 0.5
and the BIPOP restart strategy (that progressively increases population).
The options are specified for the usage with the doctest module.
>>> import cma >>> # cma.CMAOptions() # returns all possible options >>> options = {'seed':12345, 'verb_time':0, 'ftarget': 1e-8} >>> >>> x, es = cma.fmin2(cma.ff.rastrigin, lambda : 2. * np.random.rand(3) - 1, 0.5, ... options, restarts=9, bipop=True) #doctest: +ELLIPSIS (3_w,7)-aCMA-ES (mu_w=2.3,w_1=58%) in dimension 3 (seed=12345...
In either case, the method:
cma.plot();
(based on matplotlib.pyplot) produces a plot of the run and, if
necessary:
cma.s.figshow()
shows the plot in a window. Finally:
cma.s.figsave('myfirstrun') # figsave from matplotlib.pyplot
will save the figure in a png. The figure data can be saved like:
es.logger.zip()
We can use the gradient like
>>> import cma >>> x, es = cma.fmin2(cma.ff.rosen, np.zeros(10), 0.1, ... options = {'ftarget':1e-8,}, ... gradf=cma.ff.grad_rosen, ... ) #doctest: +ELLIPSIS (5_w,... >>> assert cma.ff.rosen(es.result.xbest) < 1e-8 >>> assert es.result.evals_best < 3600 # 1% are > 3300 >>> assert es.result.evaluations < 3600 # 1% are > 3300
If solutions can only be comparatively ranked, either use
CMAEvolutionStrategy directly via ask and tell or a "parallel"
objective function accepting a list of solutions as input which
returns, for example, the solution ranks:
>>> def parallel_sphere(X): return [cma.ff.sphere(x) for x in X] >>> x, es = cma.fmin2(None, 3 * [0], 0.1, {'verbose': -9}, ... parallel_objective=parallel_sphere) >>> assert es.result.fbest < 1e-9
| See Also | |
CMAEvolutionStrategy, OOOptimizer.optimize, plot,
CMAOptions, scipy.optimize.fmin |
DEPRECATED: use cma.ConstrainedFitnessAL or cma.fmin_con2 instead.
Optimize f with constraints g (inequalities) and h (equalities).
Construct an Augmented Lagrangian instance f_aug_lag of the type
cma.constraints_handler.AugmentedLagrangian from objective_function
and g and h.
Equality constraints should preferably be passed as two inequality constraints like [h - eps, -h - eps], with eps >= 0. When eps > 0, also feasible solution tracking can succeed.
Return a tuple es.results.xfavorite:numpy.array, es:CMAEvolutionStrategy,
where es == cma.fmin2(f_aug_lag, x0, sigma0, **kwargs)[1].
Depending on kwargs['logging'] and on the verbosity settings in
kwargs['options'], the AugmentedLagrangian writes (hidden)
logging files.
The second return value:CMAEvolutionStrategy has an (additional)
attribute best_feasible which contains the information about the
best feasible solution in the best_feasible.info dictionary, given
any feasible solution was found. This only works with inequality
constraints (equality constraints are wrongly interpreted as inequality
constraints).
If post_optimization is set to True, then the attribute best_feasible
of the second return value will be updated with the best feasible solution obtained by
optimizing the sum of the positive constraints squared starting from
the point es.results.xfavorite. Additionally, the first return value will
be the best feasible solution obtained in post-optimization.
In case when equality constraints are present and a "feasible" solution is requested,
then post_optimization must be a strictly positive float indicating the error
on the inequality constraints.
The second return value:CMAEvolutionStrategy has also a
con_archives attribute which is nonempty if archiving. The last
element of each archive is the best feasible solution if there was any.
See cma.fmin2 for the further parameters **kwargs.
>>> import cma >>> x, es = cma.evolution_strategy.fmin_con( ... cma.ff.sphere, 3 * [0], 1, g=lambda x: [1 - x[0]**2, -(1 - x[0]**2) - 1e-6], ... options={'termination_callback': lambda es: -1e-5 < sum(es.mean**2) - 1 < 1e-5, ... 'verbose':-9}) >>> assert 'callback' in es.stop() >>> assert es.result.evaluations < 1500 # 10%-ish above 1000, 1%-ish above 1300 >>> assert (sum(es.mean**2) - 1)**2 < 1e-9, es.mean
>>> x, es = cma.evolution_strategy.fmin_con( ... cma.ff.sphere, 2 * [0], 1, g=lambda x: [1 - x[0]**2], ... options={'termination_callback': lambda es: -1e-8 < sum(es.mean**2) - 1 < 1e-8, ... 'seed':1, 'verbose':-9}) >>> assert es.best_feasible.f < 1 + 1e-5, es.best_feasible.f >>> ".info attribute dictionary keys: {0}".format(sorted(es.best_feasible.info)) ".info attribute dictionary keys: ['f', 'g', 'g_al', 'x']"
Details: this is a versatile function subject to changes. It is possible to access
the AugmentedLagrangian instance like
>>> al = es.augmented_lagrangian >>> isinstance(al, cma.constraints_handler.AugmentedLagrangian) True >>> # al.logger.plot() # plots the evolution of AL coefficients
>>> x, es = cma.evolution_strategy.fmin_con( ... cma.ff.sphere, 2 * [0], 1, g=lambda x: [y+1 for y in x], ... post_optimization=True, options={"verbose": -9}) >>> assert all(y <= -1 for y in x) # assert feasibility of x
optimize f with inequality constraints g.
constraints is a function that returns a list of constraints values,
where feasibility means <= 0. An equality constraint h(x) == 0 can
be expressed as two inequality constraints like [h(x) - eps, -h(x) -
eps] with eps >= 0.
find_feasible_... arguments toggle to search for a feasible solution
before and after the constrained problem is optimized. Because this can
not work with equality constraints, where the feasible domain has zero
volume, find-feasible arguments are False by default.
kwargs_confit are keyword arguments to instantiate
constraints_handler.ConstrainedFitnessAL which is optimized and
returned as objective_function attribute in the second return
argument (type CMAEvolutionStrategy).
Other and further keyword arguments are passed (in **kwargs_fmin)
to cma.fmin2.
Consider using ConstrainedFitnessAL directly instead of fmin_con2.
minimize objective_function with lq-CMA-ES.
See help(cma.fmin) for the input parameter descriptions where
parallel_objective is not available and noise-related options may
fail.
Returns the tuple xbest, es similar to fmin2, however xbest
takes into account only some of the recent history and not all
evaluations. es.result is partly based on surrogate f-values and may
hence be confusing. In particular, es.best contains the solution with
the best _surrogate_ value (which is usually of little interest). See
fmin_lq_surr2 for a fix.
As in general, es.result.xfavorite is considered the best available
estimate of the optimal solution.
Example code
>>> import cma >>> x, es = cma.fmin_lq_surr(cma.ff.rosen, 2 * [0], 0.1, ... {'verbose':-9, # verbosity for doctesting ... 'ftarget':1e-2, 'seed':11}) >>> assert 'ftarget' in es.stop(), (es.stop(), es.result_pretty()) >>> assert es.result.evaluations < 90, es.result.evaluations # can be 137 depending on seed
Details
lq-CMA-ES builds a linear or quadratic (global) model as a surrogate to try to circumvent evaluations of the objective function, see link below.
This function calls fmin2 with a surrogate as parallel_objective
argument. The model is kept the same for each restart. Use
fmin_lq_surr2 if this is not desirable.
kwargs['callback'] is modified by appending a callable that injects
model.xopt. This can be prevented by passing callback=False or
adding False as an element of the callback list (see also cma.fmin).
parallel_objective is assigned to a surrogate model instance of cma.fitness_models.SurrogatePopulation.
es.countevals is updated from the evaluations attribute of the
constructed surrogate to count only "true" evaluations.
See https://cma-es.github.io/lq-cma for references and details about the algorithm.
minimize objective_function with lq-CMA-ES.
x0 is the initial solution or can be a callable that returns an
initial solution (different for each restarted run). See cma.fmin
for further input documentations and cma.CMAOptions() for the
available options.
inject determines whether the best solution of the model is
reinjected in each iteration. By default, a new surrogate model is used
after each restart (keep_model=False) and the population size is
multiplied by a factor of two (incpopsize=2) like in IPOP-CMA-ES
(see also help(cma.fmin)).
Returns the tuple xbest, es like fmin2. As in general,
es.result.xfavorite (and es.mean as genotype) is considered the
best available estimate of the optimal solution.
Example code
>>> import cma >>> x, es = cma.fmin_lq_surr2(cma.ff.rosen, 2 * [0], 0.1, ... {'verbose':-9, # verbosity for doctesting ... 'ftarget':1e-2, 'seed':3}) >>> assert 'ftarget' in es.stop(), (es.stop(), es.result_pretty()) >>> assert es.result.evaluations < 90, es.result.evaluations # can be >130? depending on seed >>> assert es.countiter < 60, es.countiter
Details
lq-CMA-ES builds a linear or quadratic (global) model as a surrogate to circumvent evaluations of the objective function, see link below.
This code uses the ask-and-tell interface to CMA-ES via the class
CMAEvolutionStrategy to the options dict is passed.
To pass additional arguments to the objective function use
functools.partial.
not_evaluated must return True if a value indicates (by convention
of cma.fitness_models.SurrogatePopulation.EvaluationManager.fvalues)
a missing "true" evaluation of the objective_function.
See https://cma-es.github.io/lq-cma for references and details about the algorithm.
None ==> active when popsize < 33, for historical reasons, not really useful?
If cma.evolution_strategy.archive_sent_solutions, save the genotype in
ask before the gp-transformation. This can be a considerable speed up
with a large population size because it allows to bypass the inverse
gp-transformation. When False, some unit tests fail, namely of
boundary_handler, evolution_strategy, fitness_models,
optimization_tools, restricted_gaussian_sampler, transformations
When detected, ignore inplace changes of solutions delivered by ask
for updating in tell. Currently, solutions are (only) archived in
_ask_phenotype_archive when integer variables were rounded at the end
of ask.
round integer variables of sampled candidate solutions (at the end of
ask) for the evaluation on the objective function. This takes about
15% CPU time with option verbose=-9, partly due to array copies?