Save the optimization results while the optimization is running (Optim.jl)

Hi, I am running a minimization using Optim. Since it is very slow, I would like to save the results while running so that if I need to switch off the computer and brutally interrupt the minimization, I still have something.
However, the docs do not clearly explain how this can be achieved. I thought of using the callback function, but it seems that the callback does not know what the current minimizer is.

Some old discussions referred to the “x” element of the dictionary metadata, an attribute of the OptimizationState passed to the callback function. However, for LBFGS, this variable does not seem to exist (metadata contains only the “time”).

res = optimize(f, g!, start, LBFGS(), 
     Optim.Options(show_trace = true, show_every = 1, 
           callback = x -> begin
                println("Current parameters: ", x.metadata)
                if "x" in keys(x.metadata)
                     save_model(x.metadata["x"], "step.jld2")
                end
                false
           end)
     )

Is there some way to force optim to save the result?

I usually pass an additional argument to the function to be optimized which contains information that I want to keep track of during the optimization.
For example, I like to keep track of the optimization history for later inspection. So I initialize an object to hold that history at the start of the optimization and then update it each iteration. That way I know what the current best point is and can save it from time to time.

Yes, in the end, I did something similar with a cache mechanism, even if I didn’t find it an elegant solution.
I find it strange there is no easier way since I would expect that saving the best model while optimizing would be something many people want to do.

1 Like

It used to be (at least with NLopt.jl) automatic. When you interrupted the optimization (Ctrl-C or objective function error), the optimizer would return the best point found up to that time. That behavior changed recently (though I rather liked it).

What changed? I made a bunch of PRs to NLopt.jl recently. Any changes were unintentional. Can you open an issue describing?

In the recent past (I am not sure which version), when the objective function threw an exception (including pressing Ctrl-C) NLopt caught the exception and returned the best point found so far to the caller.
The current version (1.0.3 in my case) does not catch the exception, so execution halts.

I’ll fix this.

Edit: see Catch InterruptException and handle as ForcedStop by odow · Pull Request #245 · jump-dev/NLopt.jl · GitHub. I’ll have a new version out ASAP.

Thank you - I thought it might have been an intentional change.

1 Like