A notebook of lq-CMA-ES related stuff¶

Links

  • Paper reference. Hansen (2019): A Global Surrogate Assisted CMA-ES. GECCO '19: Proceedings of the Genetic and Evolutionary Computation Conference, pages 664–672 [pdf].

  • Performance data (on COCO/bbob) for browsing

  • Performance data for downloading (57MB) (not needed when used with cocopp as below)

  • GitHub repository

bibtex entry (click to unfold)
@inproceedings{hansen2019global,
  title={A global surrogate assisted {CMA-ES}},
  author={Hansen, Nikolaus},
  booktitle={Proceedings of the Genetic and Evolutionary Computation Conference ({GECCO})},
  pages={664--672},
  year={2019},
  publisher = {Association for Computing Machinery},
  address = {New York, NY, USA},
  url = {https://doi.org/10.1145/3321707.3321842},
  doi = {10.1145/3321707.3321842}
}

Code to run the algorithm¶

In [1]:
%pylab widget
Populating the interactive namespace from numpy and matplotlib
In [2]:
import cma
import cma.fitness_models

fun = cma.ff.rosen
x0 = 10 * [0.1]
sigma0 = 0.1

surrogate = cma.fitness_models.SurrogatePopulation(fun)
x, es = cma.fmin2(None, x0, sigma0, {'ftarget':1e-11},
                  parallel_objective=surrogate,
                  callback=lambda es: es.inject([surrogate.model.xopt])  # not strictly necessary
                  )
(5_w,10)-aCMA-ES (mu_w=3.2,w_1=45%) in dimension 10 (seed=208382, Fri Jun 24 11:52:42 2022)
Iterat #Fevals   function value  axis ratio  sigma  min&max std  t[m:s]
    1      5 1.479377036182326e+01 1.0e+00 8.87e-02  8e-02  9e-02 0:00.0
    2      6 1.871070370715068e+01 1.1e+00 8.66e-02  8e-02  9e-02 0:00.0
    3      7 3.322371402321090e+01 1.2e+00 8.53e-02  8e-02  9e-02 0:00.0
  100    178 8.110580409919852e+00 6.3e+00 1.28e-02  5e-03  2e-02 0:00.6
  200    280 6.758028196627963e+00 8.8e+00 3.87e-02  8e-03  3e-02 0:01.2
  300    403 5.089204629827011e+00 1.5e+01 4.14e-02  6e-03  3e-02 0:01.8
  400    522 3.904369724728823e+00 1.5e+01 3.93e-02  5e-03  1e-02 0:02.4
  500    623 2.289953528925239e+00 1.6e+01 9.56e-02  5e-03  2e-02 0:03.0
  600    729 1.255185350230613e+00 1.9e+01 1.80e-01  6e-03  3e-02 0:03.6
  700    845 2.664262658579662e-01 2.6e+01 2.02e-01  3e-03  2e-02 0:04.2
  800    955 2.634089853744132e-02 4.7e+01 1.88e-01  2e-03  3e-02 0:04.9
  900   1069 5.902615654040821e-05 4.8e+01 2.19e-02  8e-05  2e-03 0:05.5
  977   1177 9.904521572736270e-12 7.1e+01 8.73e-05  1e-07  5e-06 0:06.0
termination on ftarget=1e-11 (Fri Jun 24 11:52:50 2022)
final/bestever f-value = 2.830974e-11 9.904522e-12
incumbent solution: [1.         0.99999986 0.99999988 0.99999984 0.99999984 0.99999962
 0.99999929 0.99999861 ...]
std deviations: [1.45985530e-07 1.42418465e-07 1.39364222e-07 1.43594760e-07
 1.82665963e-07 2.89894862e-07 5.88953019e-07 1.16610064e-06 ...]
In [3]:
cma.plot();
Figure

A more verbose code example for the same surrogate-based optimization:

In [ ]:
import cma  # to install the module: "pip install cma" or "pip install --upgrade cma"
import cma.fitness_models

fun = cma.fitness_transformations.Function(cma.ff.rosen)  # to count proper evaluations
x0 = 10 * [0.1]
sigma0 = 0.1


es = cma.CMAEvolutionStrategy(x0, sigma0, {'ftarget':1e-11})
surrogate = cma.fitness_models.SurrogatePopulation(fun)
# surrogate = fun  # without surrogate
while not es.stop():
    X = es.ask()  # sample a new population
    F = surrogate(X)  # see Algorithm 1 in the paper
    es.tell(X, F)  # update sample distribution
    if surrogate != fun:
        es.inject([surrogate.model.xopt])
    # the rest is bookkeeping
    es.countevals = fun.evaluations  # record only "true" evaluations
    es.disp()  # just checking what's going on
    es.logger.add()
    es.logger.plot()  # plot in above figure

Click to see output

(5_w,10)-aCMA-ES (mu_w=3.2,w_1=45%) in dimension 10 (seed=129407, Thu Apr 16 10:31:14 2020)
Iterat #Fevals   function value  axis ratio  sigma  min&max std  t[m:s]
    1      5 1.051825097054228e+01 1.0e+00 9.46e-02  9e-02  1e-01 0:00.0
    2      6 1.511256412052086e+01 1.2e+00 9.63e-02  9e-02  1e-01 0:00.0
    3      7 1.431117668012353e+01 1.2e+00 9.50e-02  9e-02  1e-01 0:00.0
  100    174 7.801168830152305e+00 6.4e+00 1.35e-02  6e-03  2e-02 0:00.4
  200    277 6.689641772270440e+00 7.7e+00 1.96e-02  6e-03  2e-02 0:00.8
  300    381 5.143203232106320e+00 9.2e+00 4.19e-02  8e-03  3e-02 0:01.1
  400    523 3.654699875855813e+00 1.4e+01 7.28e-02  9e-03  3e-02 0:01.6
  500    661 2.013631847120232e+00 1.5e+01 1.73e-01  1e-02  4e-02 0:02.0
  600    781 9.237980850510487e-01 1.8e+01 1.41e-01  5e-03  2e-02 0:02.4
  700    910 1.882447880758025e-01 2.7e+01 7.31e-02  2e-03  1e-02 0:02.8
  800   1020 1.476851240155228e-02 5.1e+01 5.16e-02  7e-04  1e-02 0:03.2
  900   1158 3.569407249208212e-07 7.6e+01 1.24e-03  8e-06  3e-04 0:03.6
  942   1214 4.132932439385136e-12 7.3e+01 3.92e-05  2e-07  7e-06 0:03.8

Python Script to Run the Benchmarking¶

example_experiment2_lq_cma.py

Overview Scaling Data¶

click to expand

Code to use data in cocopp¶

In [3]:
import cocopp
qarch = cocopp.archiving.get('http://cma-es.github.io/lq-cma/data-archives/lq-gecco2019')
qarch
Out[3]:
['CMA-ES__2019-gecco-surr.tgz',
 'SLSQP+CMA_2019-gecco-surr.tgz',
 'SLSQP-11_2019-gecco-surr.tgz',
 'lq-CMA-ES_2019-gecco-surr.tgz']
In [4]:
cocopp.main(qarch.get_all('') + ['lmm-CMA'])  # add any data from the "official" archive

Click to browse the result (also with additional data)

In [5]:
%%html
<iframe width="100%" height="570"
  src="http://cma-es.github.io/lq-cma/ppdata-archives/pap-gecco2019/figure5/index.html"></iframe>