如何在scipy中终止优化?
How terminate the optimization in scipy?
我编写的代码具有更多的初始猜测值,因此需要很长时间才能完成优化。虽然几个小时后它几乎会收敛,所以我想在那个时候停止优化。
res = minimize(f, x0=x0, bounds=bounds,options={'tol': 1e-6,'maxiter':100})
我已经实现了 maxiter
但它不起作用,因为迭代次数已经超过并且优化没有停止。所以我想知道 maxiter
是如何使用的?我也看到了,作为另一种选择,callback
可以使用,但我不知道如何?所以请帮我解决这些问题。
scipy.optimize.minimize 中的优化可以使用 tol 和 maxiter 终止(maxfev 也适用于一些优化方法)。还有一些特定于方法的终止符,如 xtol、ftol、gtol 等,如前所述在 scipy.optimize.minimize documentation page 上。还提到,如果您不提供方法,则根据问题使用 BFGS、L-BFGS-B 或 SLSQP。
关于你的第一个问题,你正在以正确的方式使用 maxiter 选项,但我不能说为什么它没有被强制执行,因为你没有提供MWE。但是,tol选项放在options括号中,这是错误的,应该在它之外,如:
res = minimize(f, x0=x0, bounds=bounds, tol=1e-6,options={'maxiter':100})
我的建议是在上述 scipy.optimize.minimize 文档页面上寻找针对您的问题的优化方法,并使用特定的容差选项。
关于你的第二个问题,如果你想在一段时间后终止优化,你可以这样做,这是受 solution proposed by SuperKogito的启发:
from time import time
import warnings
from scipy.optimize import minimize
class TookTooLong(Warning):
pass
class optimizer():
def __init__(self, maxtime_sec):
self.nit = 0
self.maxtime_sec = maxtime_sec
# def fun(self, *args):
# define your function to be minimized here
def callback(self, x):
# callback to terminate if maxtime_sec is exceeded
self.nit += 1
elapsed_time = time() - self.start_time
if elapsed_time > self.maxtime_sec:
warnings.warn("Terminating optimization: time limit reached",
TookTooLong)
else:
# you could print elapsed iterations and time
print("Elapsed: %.3f sec" % elapsed_time)
print("Elapsed iterations: ", self.nit)
def optimize(self):
self.start_time = time()
# set your initial guess to 'x0'
# set your bounds to 'bounds'
opt = minimize(self.fun, x0=x0, bounds=bounds,
callback=self.callback, tol=1e-6,options={'maxiter':100})
return opt
# set maxtime_sec variable to desired stopping time
maxtime_sec = 100
op = optimizer(maxtime_sec)
res = op.optimize()
print(res)
您还可以使用 回调 在所需的迭代后停止优化。然而,这并不优雅。只需将上面代码中的callback函数改成如下:
class TookTooManyIters(Warning):
pass
class optimizer():
def __init__(self, maxtime_sec):
self.nit = 0
self.maxtime_sec = maxtime_sec
# def fun(self, *args):
# define your function to be minimized here
def callback(self, x):
# callback to terminate if desired_iteration is reached
self.nit += 1
desired_iteration = 10 # for example you want it to stop after 10 iterations
if self.nit == desired_iteration:
warnings.warn("Terminating optimization: iteration limit reached",
TookTooManyIters)
else:
# you could print elapsed iterations, current solution
# and current function value
print("Elapsed iterations: ", self.nit)
print("Current solution: ", x)
print("Current function value: ", self.fun(x))
我编写的代码具有更多的初始猜测值,因此需要很长时间才能完成优化。虽然几个小时后它几乎会收敛,所以我想在那个时候停止优化。
res = minimize(f, x0=x0, bounds=bounds,options={'tol': 1e-6,'maxiter':100})
我已经实现了 maxiter
但它不起作用,因为迭代次数已经超过并且优化没有停止。所以我想知道 maxiter
是如何使用的?我也看到了,作为另一种选择,callback
可以使用,但我不知道如何?所以请帮我解决这些问题。
scipy.optimize.minimize 中的优化可以使用 tol 和 maxiter 终止(maxfev 也适用于一些优化方法)。还有一些特定于方法的终止符,如 xtol、ftol、gtol 等,如前所述在 scipy.optimize.minimize documentation page 上。还提到,如果您不提供方法,则根据问题使用 BFGS、L-BFGS-B 或 SLSQP。
关于你的第一个问题,你正在以正确的方式使用 maxiter 选项,但我不能说为什么它没有被强制执行,因为你没有提供MWE。但是,tol选项放在options括号中,这是错误的,应该在它之外,如:
res = minimize(f, x0=x0, bounds=bounds, tol=1e-6,options={'maxiter':100})
我的建议是在上述 scipy.optimize.minimize 文档页面上寻找针对您的问题的优化方法,并使用特定的容差选项。
关于你的第二个问题,如果你想在一段时间后终止优化,你可以这样做,这是受
from time import time
import warnings
from scipy.optimize import minimize
class TookTooLong(Warning):
pass
class optimizer():
def __init__(self, maxtime_sec):
self.nit = 0
self.maxtime_sec = maxtime_sec
# def fun(self, *args):
# define your function to be minimized here
def callback(self, x):
# callback to terminate if maxtime_sec is exceeded
self.nit += 1
elapsed_time = time() - self.start_time
if elapsed_time > self.maxtime_sec:
warnings.warn("Terminating optimization: time limit reached",
TookTooLong)
else:
# you could print elapsed iterations and time
print("Elapsed: %.3f sec" % elapsed_time)
print("Elapsed iterations: ", self.nit)
def optimize(self):
self.start_time = time()
# set your initial guess to 'x0'
# set your bounds to 'bounds'
opt = minimize(self.fun, x0=x0, bounds=bounds,
callback=self.callback, tol=1e-6,options={'maxiter':100})
return opt
# set maxtime_sec variable to desired stopping time
maxtime_sec = 100
op = optimizer(maxtime_sec)
res = op.optimize()
print(res)
您还可以使用 回调 在所需的迭代后停止优化。然而,这并不优雅。只需将上面代码中的callback函数改成如下:
class TookTooManyIters(Warning):
pass
class optimizer():
def __init__(self, maxtime_sec):
self.nit = 0
self.maxtime_sec = maxtime_sec
# def fun(self, *args):
# define your function to be minimized here
def callback(self, x):
# callback to terminate if desired_iteration is reached
self.nit += 1
desired_iteration = 10 # for example you want it to stop after 10 iterations
if self.nit == desired_iteration:
warnings.warn("Terminating optimization: iteration limit reached",
TookTooManyIters)
else:
# you could print elapsed iterations, current solution
# and current function value
print("Elapsed iterations: ", self.nit)
print("Current solution: ", x)
print("Current function value: ", self.fun(x))