Skip to content
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 CMA-ES with user prior #160

Merged
merged 15 commits into from
Oct 2, 2024
Merged

Conversation

nabenabe0928
Copy link
Contributor

@nabenabe0928 nabenabe0928 commented Sep 30, 2024

Contributor Agreements

Please read the contributor agreements and if you agree, please click the checkbox below.

  • I agree to the contributor agreements.

Tip

Please follow the Quick TODO list to smoothly merge your PR.

Motivation

As the current CMA-ES implementation does not allow users to give an initial covariance matrix, I modified the CMA-ES so that we can provide a covariance matrix from the user side.

Description of the changes

  • Add the CMA-ES with user prior

TODO List towards PR Merge

Please remove this section if this PR is not an addition of a new package.
Otherwise, please check the following TODO list:

  • Copy ./template/ to create your package
  • Replace <COPYRIGHT HOLDER> in LICENSE of your package with your name
  • Fill out README.md in your package
  • Add import statements of your function or class names to be used in __init__.py
  • Apply the formatter based on the tips in README.md
  • Check whether your module works as intended based on the tips in README.md

@HideakiImamura
Copy link
Member

@c-bata Could you review this PR?

def _calculate_initial_params(
self, trans: _SearchSpaceTransform
) -> tuple[np.ndarray, float, np.ndarray]:
# NOTE(nabenabe): Except this method, everything is basically based on Optuna v4.0.0.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check the note here before the review 🙇

@c-bata c-bata added the new-package New packages label Oct 1, 2024
Comment on lines 37 to 53
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")
sampler = module.UserPriorCmaEsSampler(param_names=["x", "y"], mu0=np.array([3., -48.]), cov0=np.diag([0.2, 2.0]))
study = optuna.create_study(sampler=sampler)
study.optimize(objective, n_trials=20)
print(study.best_trial.value, study.best_trial.params)
Copy link
Member

@c-bata c-bata Oct 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to execute this example, but bumped into AssertionErrors as shown below. Is this problem reproducible in your environment?
https://gist.github.com/c-bata/d76d810ceffd5d83fd695d7d7f942bc3

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed this issue!
In principle, this was because the mean vector was out of bound of the parameter domain.

Copy link
Member

@c-bata c-bata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nabenabe0928 LGTM. Do you think we should use with_margin option in the example?


if __name__ == "__main__":
module = optunahub.load_module(package="samplers/user_prior_cmaes")
sampler = module.UserPriorCmaEsSampler(param_names=["x", "y"], mu0=np.array([-48., 3.]), cov0=np.diag([2., 0.2]))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: We might want to consider specifying with_margin=True since there is an integer parameter in the search space.

Suggested change
sampler = module.UserPriorCmaEsSampler(param_names=["x", "y"], mu0=np.array([-48., 3.]), cov0=np.diag([2., 0.2]))
sampler = module.UserPriorCmaEsSampler(param_names=["x", "y"], mu0=np.array([-48., 3.]), cov0=np.diag([2., 0.2]), with_margin=True)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the suggestion!
I addressed your comment and confirmed the new code works:)

@c-bata c-bata merged commit e127f7a into optuna:main Oct 2, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new-package New packages
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants