Acquisition function API redesign
Redesign the way acquisition functions work.
Content:
- Deletes the
UtilityFunctionclass and replaces it with a genericAcquisitionFunctionbase class - Delete
acq_max, let each acquisition function handle the maximization itself - Adds
UpperConfidenceBound,ProbabilityOfImprovementandExpectedImprovementas possible utility functions - Adds wrapper acquisition function
GPHedgeto find which of (a combination of) UCB/PoI/EI are best suited for a problem #439 - ~Adds wrapper acquisition function
KrigingBelieverto allow for async optimization #347 #365~ - Adds wrapper acquisition function
ConstantLiarto allow for async optimization #347 #365. Strategies aremin,max,meanandconstant(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 toUCB(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 toEI(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,maximizeetc. 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.
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.
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.pyscript to showcaseConstantLiar - 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.
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?
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 - will be a breaking redesign? Not necessarily against it, just want to be clear.
@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.
@bwheelz36 I know this is a lot. I'm sorry about that 😬
Coverage is fixed now! :)
Agree on all other points. Thanks for the review! :)