Some background:
I am using the Nelder-Mead simplex optimization algorithm from scipy.optimize.minimize
to do some hyperparameter optimization on a deep learning model. For an input x and a function f, minimize
is trying to optimize the function value f(x) by changing x. In my case, x are the hyperparameters of the model, f, which is making predictions for a constant set of training examples.
Because f is very large, and there are many training examples, each call f(x) takes about 10 minutes when the embarrassingly parallel problem of making predictions on all training examples is distributed among 20 rtx-2080 GPUs. So every step is expensive.
For one reason or another (crashing, running out of time on the GPUs) the script will stop in the middle of optimizing. It is therefore desirable for me to save the state of the optimization so I can continue it from where it left off. I am able to save the hyperparameter values x during every N.M. step, but this only goes so far. Even if you've recovered x (let's call the recovered version x'), the Nelder-Mead simplex is lost. If you restart optimization of f at x', minimize
has to rebuild the simplex by evaluating f(x' + p) N times, where p is some perturbation to one of the dimensions of x , and N is either dim(x) or dim(x) + 1. In my case, x is high dimensional (>20), so it takes ~3 hours just to recover the simplex.
The question:
I need a way to access the simplex at every step in case of a crash. Others have suggested using a callback to solve the problem of recovering parameter and function values during optimization with scipy.optimize.minimize
(not necessarily with Nelder-Mead). However, in the documentation for minimize
it states the only version of minimize
that can return both the current parameter values (x) and an OptimizeResult
object (an object which could contain the simplex in the case of N.M.) via a callback is the "trust_constr" method. In other words, I'm pretty sure using a callback with the "nelder_mead" version only gives you access to x.
The best solution we've come up with is to edit the _minimize_neldermead
function within the minimize
source code to save the simplex values after each step. Is there a more elegant way of accomplishing this? Does minimize
already have this ability and we just can't find it?