numericalalgorithmsgroup / pybobyqa

Python-based Derivative-Free Optimization with Bound Constraints
https://numericalalgorithmsgroup.github.io/pybobyqa/
GNU General Public License v3.0
77 stars 18 forks source link

Handling crashes while optimizing #31

Open oarcelus opened 3 months ago

oarcelus commented 3 months ago

Which is the best strategy to handle a model crashing upon evaluation while optimizing input parameters?

lindonroberts commented 3 months ago

I assume you mean that the objective function you provide as an input to Py-BOBYQA sometimes crashes for particular parameter combinations? Py-BOBYQA doesn't have the ability to explicitly handle nan/error values, so the best option when a crash occurs would be to return a large function value (e.g. at least 1 order of magnitude larger than the objective value at nearby points). That way, Py-BOBYQA will never return these parameters as a solution, and it will try to search for a solution away from parameter combinations close to where the crash occurred.

oarcelus commented 3 months ago

In that case my objective function should have access to the solution history, how should I do that? I could access the logging string and parse the evaluations but that solution is subpar imho. Is there a better way?

lindonroberts commented 3 months ago

You can either just pick a moderately large value arbitrarily, from just observing your problem in a few runs. Otherwise, you can wrap your function in a class which saves the values you've seen, something like:

class FunctionWrapper:
    def __init__(self, objfun):
        self.objfun = objfun
        self.history = []

    def __call__(self, x):
        try:
            f = self.objfun(x)
            self.history.append(f)
        except:
            f = 10 * self.history[-1]
        return f

myfun = FunctionWrapper(original_objfun)
soln = pybobyqa.solve(myfun, x0, ...)