Lightweight Covariance Matrix Adaptation Evolution Strategy (CMA-ES) [1] implementation.
These GIF animations are generated by visualizer.py.
Supported Python versions are 3.5 or later.
$ pip install cmaes
Or you can install via conda-forge.
$ conda install -c conda-forge cmaes
This library provides two interfaces that an Optuna's sampler interface and a low-level interface. I recommend you to use this library via Optuna.
Optuna [2] is an automatic hyperparameter optimization framework. A sampler based on this library is available from Optuna v1.3.0. Usage is like this:
import optuna
def objective(trial: optuna.Trial):
x1 = trial.suggest_uniform("x1", -4, 4)
x2 = trial.suggest_uniform("x2", -4, 4)
return (x1 - 3) ** 2 + (10 * (x2 + 2)) ** 2
if __name__ == "__main__":
sampler = optuna.samplers.CmaEsSampler()
study = optuna.create_study(sampler=sampler)
study.optimize(objective, n_trials=250)
See the documentation for more details.
Monkeypatch for faster CMA-ES sampler of Optuna v1.3.x.
If you are using Optuna v1.3.x, you can make optuna.samplers.CmaEsSampler
faster.
import optuna
from cmaes.monkeypatch import patch_fast_intersection_search_space
patch_fast_intersection_search_space()
def objective(trial: optuna.Trial):
x1 = trial.suggest_float("x1", -4, 4)
x2 = trial.suggest_float("x2", -4, 4)
return (x1 - 3) ** 2 + (10 * (x2 + 2)) ** 2
if __name__ == "__main__":
sampler = optuna.samplers.CmaEsSampler()
study = optuna.create_study(sampler=sampler)
study.optimize(objective, n_trials=250)
For older versions (Optuna v1.2.0 or older)
If you are using older versions, please use cmaes.samlper.CMASampler
.
import optuna
from cmaes.sampler import CMASampler
def objective(trial: optuna.Trial):
x1 = trial.suggest_uniform("x1", -4, 4)
x2 = trial.suggest_uniform("x2", -4, 4)
return (x1 - 3) ** 2 + (10 * (x2 + 2)) ** 2
if __name__ == "__main__":
sampler = CMASampler()
study = optuna.create_study(sampler=sampler)
study.optimize(objective, n_trials=250)
Note that CmaEsSampler doesn't support categorical distributions. If your search space contains a categorical distribution, please use TPESampler.
This library also provides an "ask-and-tell" style interface.
import numpy as np
from cmaes import CMA
def quadratic(x1, x2):
return (x1 - 3) ** 2 + (10 * (x2 + 2)) ** 2
if __name__ == "__main__":
cma_es = CMA(mean=np.zeros(2), sigma=1.3)
for generation in range(50):
solutions = []
for _ in range(cma_es.population_size):
x = cma_es.ask()
value = quadratic(x[0], x[1])
solutions.append((x, value))
print(f"#{generation} {value} (x1={x[0]}, x2 = {x[1]})")
cma_es.tell(solutions)
Rosenbrock function | Six-Hump Camel function |
---|---|
This implementation (green) stands comparison with pycma (blue). See benchmark for details.
Other libraries:
I respect all libraries involved in CMA-ES.
- pycma : Most famous CMA-ES implementation by Nikolaus Hansen.
- libcmaes: Multithreaded C++11 library with Python bindings.
- cma-es : A Tensorflow v2 implementation.
References:
- [1] N. Hansen, The CMA Evolution Strategy: A Tutorial. arXiv:1604.00772, 2016.
- [2] Takuya Akiba, Shotaro Sano, Toshihiko Yanase, Takeru Ohta, Masanori Koyama. 2019. Optuna: A Next-generation Hyperparameter Optimization Framework. In The 25th ACM SIGKDD Conference on Knowledge Discovery and Data Mining (KDD ’19), August 4–8, 2019.