Reputation: 612
I run scipy.optimize.minimize(method='L-BFGS-B')
on a cluster. Tasks running longer than 72 hours will be killed without any option of saving the result. Is there a way to exit scipy.optimize.minimize()
after a runtime of T=48h has passed?
Upvotes: 2
Views: 1966
Reputation: 2556
One approach is to estimate the evaluation time of one iteration and then set maxiter
in the options
argument accordingly.
Another approach is to define a class, which modifies a function fun
such that it returns an error after a specified time and records the last input value x
and its output fun(x)
:
from scipy.optimize import minimize
import numpy as np
import time
class TimedFun:
def __init__(self, fun, stop_after=10):
self.fun_in = fun
self.started = False
self.stop_after = stop_after
def fun(self, x):
if self.started is False:
self.started = time.time()
elif abs(time.time() - self.started) >= self.stop_after:
raise ValueError("Time is over.")
self.fun_value = self.fun_in(x)
self.x = x
return self.fun_value
With that the optimization can be stopped after fun
is called, say, later than 2 seconds after the first call:
## Objective function:
def fun(x):
time.sleep(5)
return sum(x**2)
## Minimize with early stopping:
fun_timed = TimedFun(fun=fun, stop_after=2)
try:
minimize(fun=fun_timed.fun, x0=np.array([100]), method='L-BFGS-B')
except Exception as e:
print("Error: " + str(e))
# Error: Time is over.
## Retrieve last evaluated `x` and `fun(x)`:
print('x=', fun_timed.x, ', fun(x)=', fun_timed.fun_value, sep='')
# x=[100.], fun(x)=10000.0
BTW, checkout my package optimparallel, which allows you to speedup the optimization with parallel computing and to return the evaluated value x
, fun(x)
, and jac(x)
of every step.
from optimparallel import minimize_parallel
minimize_parallel(fun=fun, x0=np.array([100]), parallel={'loginfo': True})
# fun: 2.565413976271745e-17
# hess_inv: array([[0.50000039]])
# jac: array([-1.29983171e-10])
# loginfo: {'x': array([[ 1.00000000e+02],
# [ 9.90000000e+01],
# [ 9.50000000e+01],
# [ 7.90000000e+01],
# [ 8.22875951e-05],
# [-5.06499159e-09]]), 'fun': array([[1.00000000e+04],
# [9.80100000e+03],
# [9.02500000e+03],
# [6.24100000e+03],
# [6.77124832e-09],
# [2.56541398e-17]]), 'jac': array([[ 1.99999886e+02],
# [ 1.97999907e+02],
# [ 1.89999810e+02],
# [ 1.57999875e+02],
# [ 1.64585190e-04],
# [-1.29983171e-10]])}
# message: b'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL'
# nfev: 6
# nit: 3
# status: 0
# success: True
# x: array([-5.06499159e-09])
Upvotes: 1