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

Optimization over mixed spaces in optimize_acqf_homotopy #2639

Closed

Conversation

jduerholt
Copy link
Contributor

Motivation

So far, optimize_acqf_homotopy can only handle fixed_features but not fixed_features_list which is useful for optimization over mixed spaces. In the spirit of optimize_acqf_list, this PR adds the option for fixed_features_list by using optimize_acqf_mixed instead of optimize_acqf in optimize_acqf_homotopy, when fixed_features_list is provided.

Currently, it is not working as optimize_acqf_mixed has no option return_best_only=False like optimize_acqf. The easiest way to solve it (maybe not the best), would be to provide an option to return the candidates from all restarts for the finally picked fixed features combination in optimize_acqf_mixed. For the start, it would be sufficient to only implement it for q=1, and error out for the case of q>1.

What do you think?

Have you read the Contributing Guidelines on pull requests?

Yes.

Test Plan

Unit tests.

@facebook-github-bot facebook-github-bot added the CLA Signed Do not delete this pull request or issue due to inactivity. label Nov 27, 2024
@Balandat
Copy link
Contributor

Currently, it is not working as optimize_acqf_mixed has no option return_best_only=False like optimize_acqf. The easiest way to solve it (maybe not the best), would be to provide an option to return the candidates from all restarts for the finally picked fixed features combination in optimize_acqf_mixed. For the start, it would be sufficient to only implement it for q=1, and error out for the case of q>1. What do you think?

I think that makes sense. Starting with only supporting the q=1 case seems very reasonable (let's add the idea above in the comments though where we raise that UnsupportedError).

Comment on lines 163 to 166
if fixed_features and fixed_features_list:
raise ValueError(
"Èither `fixed_feature` or `fixed_features_list` can be provided, not both."
)
Copy link
Contributor

Choose a reason for hiding this comment

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

fixed_features as an arg seems redundant if we have fixed_features_list. We should probably deprecate the fixed_features arg and raise a warning when passed. And if fixed_features_list contains only one element we can just use that with optimize_acqf

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Raise a warning but still give the user the possibility to pass it for now? Should the same then also be done for optimize_acqf_list? There the same setup is used.

Copy link
Contributor

Choose a reason for hiding this comment

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

yes, that would be great

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 implemeted it now for optimize_acqf_homotopy, if it is fine for you how it looks there, I will port it to optimize_acqf_list.

test/optim/test_homotopy.py Outdated Show resolved Hide resolved
@jduerholt
Copy link
Contributor Author

I added the possibility return_best_only=False for q=1 in optimize_acqf_mixed and adapted the tests. Also optimize_acqf_homotopy works now with a fixed_features_list. For this, I had to remove the following options from optimize_acqf_homotopy as they are not available for optimize_acqf_mixed:

  • gen_candidates: would it make sense for you to add this option to optimize_acqf_mixed?
  • sequential: this keyword make for me no sense in the kontext of optimize_homotopy, as we are always using q=1 for the calls to optimize_acqf
  • return_full_tree: I am not sure about this as I do not exactly know what it does. Does it make sense in kontext of optimize_homotopy?

What do you think?

Copy link
Contributor

@Balandat Balandat left a comment

Choose a reason for hiding this comment

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

gen_candidates: would it make sense for you to add this option to optimize_acqf_mixed?

Yeah I think that would make sense. Inside of optimize_acqf_mixed we'd just pass this to optimize_acqf.

sequential: this keyword make for me no sense in the kontext of optimize_homotopy, as we are always using q=1 for the calls to optimize_acqf

True - I think we can remove this from optimize_acqf_homotopy.

return_full_tree: I am not sure about this as I do not exactly know what it does. Does it make sense in kontext of optimize_homotopy?

This is used by lookahead acquisition functions. I don't think we need to support this for optimize_acqf_homotopy.

botorch/optim/optimize.py Outdated Show resolved Hide resolved
botorch/optim/optimize.py Outdated Show resolved Hide resolved
botorch/optim/optimize.py Show resolved Hide resolved
botorch/optim/optimize.py Outdated Show resolved Hide resolved
botorch/optim/optimize.py Show resolved Hide resolved
botorch/optim/optimize_homotopy.py Outdated Show resolved Hide resolved
Comment on lines 163 to 166
if fixed_features and fixed_features_list:
raise ValueError(
"Èither `fixed_feature` or `fixed_features_list` can be provided, not both."
)
Copy link
Contributor

Choose a reason for hiding this comment

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

yes, that would be great

botorch/optim/optimize_homotopy.py Outdated Show resolved Hide resolved
botorch/optim/optimize_homotopy.py Outdated Show resolved Hide resolved
Copy link
Contributor

@Balandat Balandat left a comment

Choose a reason for hiding this comment

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

Thanks - largely nits except for the conditional when "Optimize one more time with the final options".

Also looks like you have a KeyError test failure as well as line length lint issue

botorch/optim/optimize.py Outdated Show resolved Hide resolved
botorch/optim/optimize_homotopy.py Outdated Show resolved Hide resolved
test/optim/test_homotopy.py Outdated Show resolved Hide resolved
test/optim/test_homotopy.py Outdated Show resolved Hide resolved
test/optim/test_optimize.py Outdated Show resolved Hide resolved
test/optim/test_optimize.py Outdated Show resolved Hide resolved
test/optim/test_optimize.py Outdated Show resolved Hide resolved
test/optim/test_optimize.py Outdated Show resolved Hide resolved
test/optim/test_optimize.py Outdated Show resolved Hide resolved
@jduerholt
Copy link
Contributor Author

jduerholt commented Dec 2, 2024

Hi @Balandat,

thanks for your review(s). I think, I have now implemented all the suggestions.

Could you have a look on the issue that I always have to wait for approval before the pipelines start? In the past, they were starting always automatically which helped me to faster finish the PRs ;) And maybe it is also less annoying for you ...

Best,

Johannes

@Balandat
Copy link
Contributor

Balandat commented Dec 2, 2024

Could you have a look on the issue that I always have to wait for approval before the pipelines start? In the past, they were starting always automatically which helped me to faster finish the PRs ;) And maybe it is also less annoying for you ...

Yeah I pinged some folks to understand if we can avoid this, let's see what they say.

@Balandat Balandat closed this Dec 2, 2024
Copy link

codecov bot commented Dec 2, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.98%. Comparing base (4190f74) to head (1c53e3d).
Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2639   +/-   ##
=======================================
  Coverage   99.98%   99.98%           
=======================================
  Files         196      196           
  Lines       17410    17431   +21     
=======================================
+ Hits        17408    17429   +21     
  Misses          2        2           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@Balandat Balandat reopened this Dec 2, 2024
@Balandat
Copy link
Contributor

Balandat commented Dec 2, 2024

Looks like you're missing a unit test for more than 1 elements in the fixed_features_list which seems important :)

@jduerholt
Copy link
Contributor Author

Looks like you're missing a unit test for more than 1 elements in the fixed_features_list which seems important :)

Ah, this is now a consequence of the new structure where we call optimize_acqf when fixed_features_list has only one element. Before it was also in this case going to òptimize_acqf_mixed. I will add a new test case.

@jduerholt
Copy link
Contributor Author

jduerholt commented Dec 2, 2024

Now, the test is there ;), But there is still something wrong. Need to fix it ;)

@jduerholt
Copy link
Contributor Author

But there is still something wrong. Need to fix it ;)

Not it is actually correct, I was overlooking something. Too late for coding ;)

Copy link
Contributor

@Balandat Balandat left a comment

Choose a reason for hiding this comment

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

Tutorial failure is unrelated (and will be fixed in #2641). Thanks!

@facebook-github-bot
Copy link
Contributor

@Balandat has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@@ -956,15 +979,18 @@ def optimize_acqf_mixed(
post_processing_func=post_processing_func,
batch_initial_conditions=batch_initial_conditions,
ic_generator=ic_generator,
return_best_only=True,
return_best_only=False,
Copy link
Member

@esantorella esantorella Dec 2, 2024

Choose a reason for hiding this comment

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

Why not return_best_only=return_best_only? (A comment would be helpful here)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We get here all candidates and then filter later based on the return_best_only argument. I will add a comment.

ic_generator=ic_generator,
ic_gen_kwargs=ic_gen_kwargs,
timeout_sec=timeout_sec,
retry_on_optimization_warning=retry_on_optimization_warning,
return_best_only=True,
Copy link
Member

Choose a reason for hiding this comment

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

Why True here and False earlier?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because, currently return_best_only is only implemented for q=1 and here we are in the loop for q>1.

@jduerholt
Copy link
Contributor Author

Thanks for the review @esantorella. I adressed your comments and resolved the merge conflicts with main. Best, Johannes

@facebook-github-bot
Copy link
Contributor

@Balandat has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@Balandat merged this pull request in 88f47bc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed Do not delete this pull request or issue due to inactivity. Merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants