-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Advanced constrained optimization #344
Advanced constrained optimization #344
Conversation
Please consider this a draft pull request as of now, I marked as ready to review to trigger the CI but apparently I need approval for that first. |
Codecov Report
@@ Coverage Diff @@
## master #344 +/- ##
==========================================
- Coverage 99.26% 99.25% -0.02%
==========================================
Files 7 8 +1
Lines 409 535 +126
Branches 58 81 +23
==========================================
+ Hits 406 531 +125
- Misses 1 2 +1
Partials 2 2
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
@bwheelz36 Could you run the workflow? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, thanks for this, it looks awesome.
So, am I correct in thinking that this is based off this work by gardner?
In that case, this handles situations where checking feasibility is just as expensive as assessing the objective function? It appears that the objective function is still assessed for unfeasible cases, but that the likelihood of probing these regions should decrease as the GP models get better?
What about the more common scenario where in/feasibility is known in advance? it seems like in that case, this is quite a complex and expensive approach to deal with constraints? Do you think there's an elegant way to handle both scenarios - the case where the feasible regions are known in advance and the case where they are only known retrospectively?
Sorry if these are dumb questions, I freely admit I don't entirely have my head around the complexity of constrained bayesian optimization!
Also, that plotting routine is a very nice visualization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, am I correct in thinking that this is based off this work by gardner?
Yes! This was the approach discussed in #326.
In that case, this handles situations where checking feasibility is just as expensive as assessing the objective function? It appears that the objective function is still assessed for unfeasible cases, but that the likelihood of probing these regions should decrease as the GP models get better?
Yes, or at least very expensive.
What about the more common scenario where in/feasibility is known in advance? it seems like in that case, this is quite a complex and expensive approach to deal with constraints?
I think you are right. The reason why I went for this approach was 1) the robustness/versatility and 2) because the paper seemed interesting. Nonetheless, it is probably unnecessarily complex for many usecases.
Do you think there's an elegant way to handle both scenarios - the case where the feasible regions are known in advance and the case where they are only known retrospectively?
It's probably feasible to add some kind of mode="simple"
or mode="gardner"
to the ConstraintModel
. How would you propose handling easy constraints in practice?
Also, that plotting routine is a very nice visualization.
Thanks, it took longer to write that than I'd like to admit ;)
I will update the internal documentation and add more comments to the notebook as well.
bayes_opt/bayesian_optimization.py
Outdated
self._space = TargetSpace(f, pbounds, random_state) | ||
else: | ||
self._space = ConstrainedTargetSpace(f, constraint, pbounds, random_state) | ||
self.constraint = constraint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I notice a lot of these properties are prepended with a _
and equipped with a separate method essentially acting as a getter
, presumably to avoid users setting these properties. Let me know which properties you want me to handle this way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hey, I might consider putting self.constraint as self._constraint - which would be consistent with how _gp is currently handled.
hey @till-m - can I suggest the following edits on the documentation:
"In some situations, certain regions of the solution domain mat be infeasible or not allowed. In addition, you may not know where these regions are until you have evaluated the objective function at these points. In other words, checking for feasibility is as expensive, or close to as expensive as evaluating the objective function. This notebook demonstrates how you can handle these situations by also modelling the constraints as a Gaussian process. This approach is based on this paer by gardner et. al.. Regarding your question above - how would we handle the case where the constraints are known in advance - good question! I have done this the way I suggested above. It worked pretty well for me. However, I guess the problem arises where the best value is right near the feasible/non-feasible split - depending on how well the GP is working, these boundary regions may not be well modeled. Therefore a more elegant solution would be to properly constrain the space in the first place - but I don't really know how to do that properly and I have to think about it some more! In the meantime - following the changes above this PR looks pretty ready to me, do you agree? |
Hi @bwheelz36, I think I misunderstood -- you intended for me to rename the notebook, not the If yes, I would suggest a slightly different approach: Retain the name Let me know what you think. I think your approach should definitely be illustrated somewhere if we decide to mention it in the notebook. |
I've implemented the changes as suggested above, but feel free to let me know if you'd prefer a different approach. If you can, please proofread the documentation and let me know if there is something that should be modified -- be it content-wise or with respect to grammar and spelling. I am somewhat tired so I likely messed up something somewhere 🙃. |
b1f1ad9
to
b751820
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks excellent, sorry I was slow to respond!
Main comment: should ConstraintModel be constructed by the user as it is now, ot should it be constructed when an optimizer is instantiated?
I think at the moment, we can have two different random_states set - it is probably cleaner if the constraint model gets the random state from the optimizer. In that case we would pass a dictionary of constraints and construct the model inside BayesianOptimization.
Another thought: we could have the user define their constraints using scipys nonlinear constraints. This would have the advantage that it's easier to switch into different algorithms, and thinking ahead, might make it easier for us to handle the simpler case of known constraints because the constraint can be directly passed to the acquisition function optimizer.
For the record I think this is excellent already and will merge as is, just let me know :-)
Agreed.
Sounds good to me. Your approach has the additional advantage of avoiding side effects that might occur with modifying the original (Another option would be to allow for both, a dict and an instance of
I like this! I wasn't aware that such a class existed within sklearn. I think especially looking towards the future, this seems like an excellent idea.
Thanks, I appreciate it! I should be able to get most of this done over the week-end, I think. |
In general the documentation for this code is all in the example notebooks and relies on the user to go look at the code to figure out other options. While this might not be ideal, it does mean that what you have already done is consistent with the other features of the code.
Yeah I agree, keep it simple :-) |
c0f6b03
to
3fab69d
Compare
…constructed and stored
3fab69d
to
1a49eb1
Compare
That should be all, I hope. I think #351 should be merged first since there might be conflicts. |
thanks @till-m - that one is merged now! |
thanks for this work @till-m! |
Model constraints using Gaussian Process Regression and incorporate them into the selection of new points to sample.
Cf. #326 #304 #266 #276 #190 (sort of) #189.
For examples on how to use, see
examples/constraints.ipynb
.I think some more documentation is necessary, but I would like to get feedback on the current state before I do that.