BayesianOptimization icon indicating copy to clipboard operation
BayesianOptimization copied to clipboard

Acquisition function API redesign

Open till-m opened this issue 2 years ago • 8 comments

Redesign the way acquisition functions work.

Content:

  • Deletes the UtilityFunction class and replaces it with a generic AcquisitionFunction base class
  • Delete acq_max, let each acquisition function handle the maximization itself
  • Adds UpperConfidenceBound, ProbabilityOfImprovement and ExpectedImprovement as possible utility functions
  • Adds wrapper acquisition function GPHedge to find which of (a combination of) UCB/PoI/EI are best suited for a problem #439
  • ~Adds wrapper acquisition function KrigingBeliever to allow for async optimization #347 #365~
  • Adds wrapper acquisition function ConstantLiar to allow for async optimization #347 #365. Strategies are min, max, mean and constant (latter chosen by supplying a number).
  • Disallow constrained optimization for UCB -- the constrained optimization relies on the acquisition function being lower-bounded by zero, otherwise the rescaling doesn't make so much sense. While the old implementation seems to have worked sufficiently well, this is more principled.
  • ~Sets default unconstrained acquisition function to GPHedge with base functions UCB(kappa=2.576), PoI(xi=0.01), EI(xi=0.01).~ Sets default unconstrained acquisition function to UCB(kappa=2.576)
  • ~Set GPHedge with base functions PoI(xi=0.01), EI(xi=0.01) as standard acquisition function for constrained improvement~ Sets default constrained acquisition function to EI(xi=0.01)
  • Make the acquisition function a property of the optimizer (this should mean the the optimizer as a whole is serializable, including the acquisition function, though I haven't actually tested this). This change is breaking as it means suggest, maximize etc. don't take an acquisition function argument anymore.

Why? The old UtilityFunction and acq_max were the most inflexible part of this package and their design was somewhat convoluted (e.g. providing a xi parameter when using UCB). Now it should be much easier to add custom acquisition functions.

till-m avatar Oct 22 '23 10:10 till-m

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 96.23%. Comparing base (f2c720e) to head (3d85734). Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #447      +/-   ##
==========================================
+ Coverage   94.68%   96.23%   +1.54%     
==========================================
  Files           9       10       +1     
  Lines         677      849     +172     
==========================================
+ Hits          641      817     +176     
+ Misses         36       32       -4     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

codecov[bot] avatar Oct 22 '23 10:10 codecov[bot]

Some more changes:

  • Add ConstantLiar
  • fix a bug in exploration_decay
  • fix a bug in KrigingBeliever, where the GP was fitted on the wrong data
  • Adapted the async_optimization.py script to showcase ConstantLiar
  • Reran some notebooks

@fmfn @bwheelz36 @leandrobbraga I will wait with merging this until the docstrings are finished, but if you'd like to give some feedback already, please do. @pfebrer this contains GPHedge, if you'd like to give some feedback on it. @rizhiy I added the constant liar and the kriging believer for async optimization, as well as a script based on your code in examples/async_optimization_dummies.py. Ideally this will eventually become a notebook. According to this, lying is the better strategy, but I wasn't sure whether it would make sense for constrained optimization, so I added the believer for that case.

till-m avatar Nov 23 '23 16:11 till-m

Wow this is a huge amount of work. Impressive! Before we start review can you resolve the merge conflicts and make sure all the tests pass?

bwheelz36 avatar Jan 24 '24 20:01 bwheelz36

Before we start review can you resolve the merge conflicts and make sure all the tests pass?

Will do 👍 ideally I want to wait until the docs are finished to only deal with one conflict. After that I will mark the PR as ready to review :)

till-m avatar Jan 24 '24 20:01 till-m

@till-m - will be a breaking redesign? Not necessarily against it, just want to be clear.

bwheelz36 avatar Mar 06 '24 05:03 bwheelz36

@till-m - will be a breaking redesign? Not necessarily against it, just want to be clear.

There will be some necessary breaking changes, primarily to workflows that change the acquisition function -- this is unavoidable, since the old UtilityFunction object has been replaced. I also (intentionally) modified the way the acquisition function is changed -- it is now a property of the optimizer (i.e. not an argument to maximize/suggest). I understand that this can be annoying for some users, but I think in the long run it will be exactly those users that will profit from this change.

If someone just calls .maximize nothing should change. Similarly, suggest-probe-register w/o messing with the acquisition function will not change either.

till-m avatar Mar 06 '24 08:03 till-m

@bwheelz36 I know this is a lot. I'm sorry about that 😬

till-m avatar Jun 29 '24 09:06 till-m

Coverage is fixed now! :)

Agree on all other points. Thanks for the review! :)

till-m avatar Jun 30 '24 14:06 till-m