Add Constraint primitive; replace set_outcome_constraints string DSL#27
Conversation
|
Hey @499602D2 , Things seems to work on my end. I pushed two commits, one is making changes in session.py to print/log the scalarizedObjectives and constraints, the other one is changing the aerofoil tutorial to use a lift constraint. If you could test it on your end I think we can merge this PR alongside #26 . |
|
Having said that I do get a few warnings during the tutorial run, pasting them below. Any thoughts? |
|
I wonder if we should also add a random seed in the aerofoil tutorial, for better reproducibility? I had a test where I reached the best design by design 12, and current one is still stuck at a local maxima around design 20.. It just seems that the model is very big on exploitation, but exploration is secondary. Do you think this is due to non-deterministic seed values, or is there a way on Ax backend to prioritize exploration over exploitation, similar to e.g. GpyOPT?
The best design is somewhere along angleOfAttack ~10, but we are kinda stuck around 17. |
400f5ac to
b72c173
Compare
2614b20 to
d34b6f0
Compare
d34b6f0 to
c01b1d7
Compare

Replaces the
set_outcome_constraintsstring DSL with a properConstraintprimitive modeled as a peer ofObjective. Constraint metrics register as tracking metrics on the Ax experiment before theOutcomeConstraintreferences them, so their values flow throughraw_dataalongside objectives and Ax never silently marks a trial failed for "missing required metric". Bounds are absolute; Ax'sOutcomeConstraintdefaults to relative, which would silently change the meaning of everygte/ltesupplied.Addresses #24. The pattern Bulut tried in the comment thread (register a metric as both an objective and a constraint via the string DSL) crashed Ax with "Cannot constrain on objective metric", and the alternative of referencing an unregistered metric name silently marked every trial failed.
Constraintis the peer-of-Objectiveregistration asked for in the thread.Self-bounds on
Objective(Objective(..., lte=X)) as sketched in #24 are a follow-up.Migration
Validation
Constraint.__init__rejects at construction:gteorltemust be supplied)gte > lte)gte == lte): meaningless for a soft outcome constraint on a continuous GP surrogate; usegte=X-eps, lte=X+epsfor a tight toleranceNonefor "no bound on this side"Backend.set_constraintsrejects at registration:Constraint(anObjectivesmuggled in used to crash later withAttributeError; now rejects up front with a clearTypeError)Tests
Unit tests cover every validation branch. Three canaries drive real Ax end-to-end:
TestConstraintConvergenceCanary: BO on a 2D quadratic withx1 >= 2; asserts best feasible point is near the constrained optimum.TestMOOWithConstraint: twoObjectives in Pareto MOO mode plus oneConstraint. Asserts BO explores both ends of the feasible Pareto front.TestSessionLoopWithConstraint: drivesSession.local_optimizationend-to-end with a realAxBackendand aConstraint, staging cases in the archival dir between cycles. Catches orchestration bugs in theCasemetadata tobackend.tellhandoff.