Skip to content

Conversation

@kento031
Copy link
Contributor

This is the implementation of Safe CMA-ES [Uchida+, GECCO 2024].
https://arxiv.org/abs/2405.10534

@nomuramasahir0
Copy link
Contributor

@c-bata
This PR introduces a new method called SafeCMA, which will require gpytorch and torch (for Gaussian processes) when users choose to use it. I believe this PR won’t affect Optuna since SafeCMA is unrelated to Optuna, but could you please double-check to ensure there aren’t any issues?

and Noisy Problems?, GECCO, 2023.](https://arxiv.org/abs/2304.03473)
* [Nomura and Shibata 2024] [M. Nomura, M. Shibata, cmaes : A Simple yet Practical Python Library for CMA-ES, arXiv:2402.01373, 2024.](https://arxiv.org/abs/2402.01373)
* [Ros and Hansen 2008] [R. Ros, N. Hansen, A Simple Modification in CMA-ES Achieving Linear Time and Space Complexity, PPSN, 2008.](https://hal.inria.fr/inria-00287367/document)
* [Uchida et al. 2024] [K. Uchida, R. Hamano, M. Nomura, S. Saito, S. Shirakawa, CMA-ES for Safe Optimization, GECCO, 2024.](https://arxiv.org/abs/2405.10534)
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you provide a brief description and usage for SafeCMA (like LRA-CMA-ES)?

Copy link
Contributor

Choose a reason for hiding this comment

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

It would be clearer to explicitly state that the current implementation assumes no noise.

cov:
A covariance matrix (optional).
"""
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add the paper link like this.

assert c1 <= 1 - cmu, "invalid learning rate for the rank-one update"
assert cmu <= 1 - c1, "invalid learning rate for the rank-μ update"

cm = 1 # (eq. 54)
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest removing comments like eq. ~ (for Hansen's Tutorial paper) in this PR, as they could be confusing when compared with the equations in the SafeCMA paper.

Copy link
Contributor

Choose a reason for hiding this comment

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

On the other hand, adding equation numbers for SafeCMA-specific operations would improve clarity.

likelihood = gpytorch.likelihoods.GaussianLikelihood(
noise_constraint=gpytorch.constraints.GreaterThan(0)
)
likelihood.noise = 0
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm curious about the validity of this setting because, as mentioned in this thread:

Some small value, but don't make it too small or numerical performance will suffer. I recommend 1e-4.
cornellius-gp/gpytorch#1196 (comment)

This implies there's room for improvement in this setting, but I'm not sure for now, so let's see how it goes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This setting was used in some previous studies, including the followings.
https://link.springer.com/chapter/10.1007/978-3-030-58112-1_13
https://dl.acm.org/doi/10.1007/978-3-031-30229-9_51

In addition, I run the safe CMA-ES with likelihood.noise = 1e-4 on some benchmark functions. As a result, it occurred a few constraint violations that was not observed with likelihood.noise = 0. Therefore, I did not change it.

if out_scalar:
grad_norm = grad_norm.mean().to(torch.float64)

return -grad_norm
Copy link
Contributor

Choose a reason for hiding this comment

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

df is defined as # function that returns the norm of gradient, but it currently returns a negative value, which seems odd.
I understand this is intended for scipy.optimize.minimize, but it would be better to align it with the description.

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 changed the explanation of the function as # function that returns the negative norm of gradient.

safe_seeds = (np.random.rand(safe_seeds_num, dim) * 2 - 1) * 5
safe_seeds[:, 0] = - np.abs(safe_seeds[:, 0])
# evaluation of safe seeds (with multiple safety functions)
Copy link
Contributor

Choose a reason for hiding this comment

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

with multiple safety functions

with a single safety function?

safe_seeds = (np.random.rand(safe_seeds_num, dim) * 2 - 1) * 5
safe_seeds[:, 0] = -np.abs(safe_seeds[:, 0])

# evaluation of safe seeds (with multiple safety functions)
Copy link
Contributor

Choose a reason for hiding this comment

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

with multiple safety functions
with a single safety function?

@nomuramasahir0
Copy link
Contributor

@kento031
Thanks for the PR! I've left some comments. Could you take a look?

Comment on lines 9 to 13
try:
from ._safe_cma import SafeCMA # NOQA
except ImportError:
pass # Implementation of Safe CMA-ES requires scipy, gpytorch, and torch

Copy link
Collaborator

@c-bata c-bata Nov 12, 2024

Choose a reason for hiding this comment

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

It seems that the current approach is somewhat tricky, as users may be confused if cmaes.SafeCMA doesn’t exist in certain Python environments.

How about simply removing SafeCMA from __init__.py and renaming cmaes/_safe_cma.py to cmaes/safe_cma.py?

Suggested change
try:
from ._safe_cma import SafeCMA # NOQA
except ImportError:
pass # Implementation of Safe CMA-ES requires scipy, gpytorch, and torch

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the great suggestion! It looks good to me.

@kento031
Could you make this modification if it’s okay?

@kento031
Copy link
Contributor Author

@nomuramasahir0 @c-bata
Thank you for your kind comments. I will address them.

@kento031 kento031 force-pushed the main branch 2 times, most recently from bea9914 to f5e178a Compare February 4, 2025 04:49
@kento031
Copy link
Contributor Author

Sorry for being so late in addressing your comments.
I modified my implementation according to your comments.

I checked the code using act (https://github.com/nektos/act), and there remains an error when executing act -j lint (and when executing act pull_request). This error was caused at cmaes/_cma.py:480 by running mypy cmaes. I leave this error as is for now because I did not change cmaes/_cma.py.

@nomuramasahir0 We previously discussed about whether _safe_cma.py sould be contained in cmaes/__init__.py. However, at that time, I misunderstood how the workflow runs. Finally, I modified my implementation according to @c-bata 's comment.

@ha-mano
Copy link
Collaborator

ha-mano commented Mar 27, 2025

@kento031
I have fixed a mypy error that was causing in the workflow tests. The fix is included in this pull request.

@kento031
Copy link
Contributor Author

@ha-mano
Thank you for fixing the error. I have merged your fix.

Copy link
Collaborator

@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.

Thank you for the update. LGTM with a nit.

Copy link
Collaborator

@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.

LGTM after CI passes. Thank you for your contribution 💯

@kento031
Copy link
Contributor Author

kento031 commented Apr 4, 2025

Thank you for all your comments!

In the CI check, the lint job failed due to tools/cmaes_visualizer.py and tools/ws_cmaes_visualizer.py. However, I did not change these files.

Should I modify these codes to resolve the errors?

@c-bata
Copy link
Collaborator

c-bata commented Apr 4, 2025

@kento031 No, you don't need to fix that errors in this PR 👍

@c-bata c-bata merged commit f074908 into CyberAgentAILab:main Apr 4, 2025
13 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants