Abstract
As the Optuna CMA-ES sampler does not support any flexible ways to initialize the parameters of the Gaussian distribution, so I created a workaround to do so.
Class or Function Names
- UserPriorCmaEsSampler
In principle, most arguments follow optuna.samplers.CmaEsSampler
, but some parts are modified.
For example, UserPriorCmaEsSampler
does not support source_trials
and use_separable_cma
due to their incompatibility.
Instead, we replaced x0
and sigma0
in CmaEsSampler
with mu0
and cov0
.
In CmaEsSampler
, we needed to provide x0
as dict
and sigma0
only as float
.
By adding param_names
to the requirement, we can now give mu0
(previously x0
) and cov0
(previously sigma0
) as np.ndarray
.
Note that the order of each dimension in mu0
and cov0
must be consistent with that in param_names
.
Installation
$ pip install optunahub cmaes
Example
The simplest code example is as follows:
import numpy as np
import optuna
import optunahub
def objective(trial: optuna.Trial) -> float:
x = trial.suggest_float("x", -50, -40)
y = trial.suggest_int("y", -5, 5)
return (x + 43)**2 + (y - 2)**2
if __name__ == "__main__":
module = optunahub.load_module(package="samplers/user_prior_cmaes")
# ``with_margin=True`` because the search space has an integer parameter.
sampler = module.UserPriorCmaEsSampler(
param_names=["x", "y"], mu0=np.array([-48., 3.]), cov0=np.diag([2., 0.2]), with_margin=True
)
study = optuna.create_study(sampler=sampler)
study.optimize(objective, n_trials=20)
print(study.best_trial.value, study.best_trial.params)
Although UserPriorCmaEsSampler
CANNOT support log scale from the sampler side, we have a workaround to do so:
import math
import numpy as np
import optuna
import optunahub
def objective(trial: optuna.Trial) -> float:
# For example, trial.suggest_float("x", 1e-5, 1.0, log=True) can be encoded as:
x = 10 ** trial.suggest_float("log10_x", -5, 0)
# trial.suggest_float("y", 2, 1024, log=True) can be encoded as:
y = 2 ** trial.suggest_float("log2_y", 1, 10)
# In general, trial.suggest_float("z", low, high, log=True) can be encoded as:
low, high = 3, 81
b = 3 # The base of log can be any positive number.
z = b ** trial.suggest_float("logb_z", math.log(low, b), math.log(high, b))
return x**2 + y**2 + z**2
if __name__ == "__main__":
module = optunahub.load_module(package="samplers/user_prior_cmaes")
sampler = module.UserPriorCmaEsSampler(
param_names=["log10_x", "log2_y", "logb_z"],
mu0=np.array([-4, 8, 3]),
cov0=np.diag([0.2, 1., 0.1]),
)
study = optuna.create_study(sampler=sampler)
study.optimize(objective, n_trials=20)
print(study.best_trial.value, study.best_trial.params)
- Package
- samplers/user_prior_cmaes
- Author
- Shuhei Watanabe
- License
- MIT License
- Verified Optuna version
- 4.0.0
- Last update
- 2024-10-02