New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add IPOP-CMA-ES support in CmaEsSampler
.
#1548
Conversation
CmaEsSampler
.
|
||
if self._consider_pruned_trials: | ||
self._raise_experimental_warning_for_consider_pruned_trials() | ||
|
||
# TODO(c-bata): Support BIPOP-CMA-ES. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
optuna/samplers/_cmaes.py
Outdated
and ``high`` for each distribution is used. Note that x0 is sampled uniformly within | ||
the search space domain for each restart if you set ``restart_strategy`` argument. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
memo: I comment the reason why I choose this design here.
In pycma's implementation, x0
accepts not only the float values. It also accepts callable object (e.g. np.random.rand
) and string (e.g. "np.random.rand"
which is evaluated by eval()
). But I guess it's enough for almost every usecases to sample x0
uniformly at each restart.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update! LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for this very interesting PR.
The implementation is simple and the logic looks good for the most part. I left one question though regarding the system attribute if you could take a look.
Might be good for future record to leave a comment on why. 🙂 |
We set experimental decorator because there are some room for discussion about API (e.g. it might be better to make |
PTAL. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your update. I thought that it basically looked good but noticed that the current logic will when collecting previous trial history include trials from "previous restarts". This is because the generation count is reset on restart (since a CMA
object is re-instantiated) and we simply collect all trials belonging to the "same generation" and don't care if they stem from different restarts. Is this intended? Maybe we have to include the restart count after all and filter trials based on it in addition to the generation?
Oh, thanks. You are completely correct. It is not intended behavior. |
Co-authored-by: Hiroyuki Vincent Yamazaki <hiroyuki.vincent.yamazaki@gmail.com>
I'm really sorry after having asked you to remove |
No. It's not your fault. It's just my mistake.
Yeah, sounds reasonable. I'll fix the problem. Thank you! |
I fixed the bug at cd2e10c. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the quick fix and the long running effort. Changes LGTM!
Also leaving the results from a small experiment run locally. It's clear that the restart makes it more explorative escaping a local minimum.
Vanilla
IPOP
import optuna
# Himmelblau
def objective(trial):
x = trial.suggest_float("x", -6, 6)
y = trial.suggest_float("y", -6, 6)
return (x ** 2 + y - 11) ** 2 + (x + y ** 2 - 7) ** 2
if __name__ == "__main__":
study = optuna.create_study(sampler=optuna.samplers.CmaEsSampler(restart_strategy="ipop"))
study.optimize(objective, n_trials=1000)
optuna.visualization.plot_slice(study).show()
@HideakiImamura might want to have another look as well, so I'll leave the final word to him. |
I re-execute Rastrigin (2D) benchmark function at d35a3dc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all of your efforts. LGTM, again!
Thank you for your thorough review! |
Motivation
As the benchmark of two-dimensional Rastrigin function shows, IPOP-CMA-ES outperforms non-restarting CMA-ES on multimodal functions.
Auger, A., Hansen, N.: A restart CMA evolution strategy with increasing population size. In: Proceedings of the 2005 IEEE Congress on Evolutionary Computation (CEC’2005), pp. 1769–1776 (2005a)
Description of the changes
restart_strategy
argument. Currently acceptsipop
orNone
only. I will implement BIPOP-CMA-ES in the following pull request.optimizer.tell(solutions)
call, check whetheroptimizer.should_stop()
method returns True or not.inc_popsize
.inc_popsize
is 2 by default. According to the paper, it reveal similar performance for factors between 2 and 3.TODO:
This PR is ready for review.
BUDGET=2500 REPEATS=10 DIM=2 ./benchmark/runner.sh rastrigin ./kurobako-report.json
install_requires
.