CyberAgentAILab / cmaes

Python library for CMA Evolution Strategy.
https://arxiv.org/abs/2402.01373
MIT License
359 stars 62 forks source link

Are non-scalar values of a sigma supported? #173

Closed aschepelmann closed 5 months ago

aschepelmann commented 6 months ago

Are non-scalar values for an initial sigma supported by this implementation? I am interested in optimizing a problem where parameters have significantly different bounds and would like to specify a different initial sigma for each parameter via an array when I start the optimization. Thank you for your help!

nomuramasahir0 commented 6 months ago

Hi @aschepelmann ,

Yes, our library can handle the situation described above. It's important to note that the actual covariance matrix in CMA-ES is represented by sigma ** 2 * cov, where cov is a matrix typically initialized as identity matrix. Therefore, you can address the situation by setting the initial cov to a diagonal matrix, with elements having different values depending on the bounds. Another (and maybe more common) approach to handle this situation is to normalize the bounds of all parameters, and then adjust only the sigma value.

aschepelmann commented 5 months ago

Hi @nomuramasahir0,

Sorry for the delayed reply -- somehow this notification slipped through my inbox!

Thank you so much for this guidance. This sounds to be exactly what I am looking for. I will give this a shot and will report back if I run into any issues!

aschepelmann commented 5 months ago

Good morning @nomuramasahir0! Thank you again for your help. Normalizing the bounds of the parameters and then adjusting only the sigma value is a good suggestion.

For completeness, I also tried setting an initial cov to a diagonal matrix directly. I can confirm that this also works. For others who may run into this post in the future, here is an example code snippet of what this option looks like, where various arguments, including an initial diagonal covariance matrix, are set during optimizer initialization:

import numpy as np
from cmaes import CMA

param_vals = np.array([4.0, 10000.0])
bounds = np.array([[0.0, 10.0], [0.0, 20000.0]])
sigma0 = 1.0
cov0 = np.diag([0.1, 100.0])

optimizer = CMA(mean=param_vals, bounds=bounds, population_size=10, sigma=sigma0, cov=cov0)
# ... etc.

Thank you again for your help and suggestions!