在时间阈值后停止 Scipy differential_evolution()
Stop Scipy differential_evolution() after a time threshold
我的问题已经得到部分回答here。我只需要将答案扩展到另一个 Scipy 函数。 (Scipy 1.4.0,Python 3.7 在 Windows 10 上)
参考@ali_m给出的答案,我尝试将相同的想法应用于differential_evolution()
Scipy函数,该函数也有callback
参数。
我想确保我的 Scipy differential_evolution()
函数在特定时间限制后停止 运行ning。在这种情况下,我选择了具有 40 个输入参数和 0.3 秒阈值的 Rosenbrock 函数来突出显示发生的情况。
import numpy as np
from scipy.optimize import differential_evolution, rosen
import time
import warnings
class TookTooLong(Warning):
pass
class MinimizeStopper(object):
def __init__(self, max_sec=0.3):
self.max_sec = max_sec
self.start = time.time()
def __call__(self, xk=None, convergence=None):
elapsed = time.time() - self.start
if elapsed > self.max_sec:
warnings.warn("Terminating optimization: time limit reached",
TookTooLong)
else:
print("Elapsed: %.3f sec" % elapsed)
n_var = 40
upper_bound_array = np.ones(n_var) * 5
lower_bound_array = np.ones(n_var) * -5
bounds = Bounds(lower_bound_array, upper_bound_array)
# function call
res = differential_evolution(Rosen, bounds, strategy='best1bin',disp=False,
callback=MinimizeStopper(),
maxiter=1000000)
因此我没有收到任何错误,但似乎 Scipy minimize()
中使用的相同逻辑在这里不起作用。更具体地说,当我 运行 程序时,即使在引发 Warning 之后,程序仍然默默地继续计算所有必要的迭代,直到优化问题收敛。
有谁知道为什么在这种情况下它不像 minimize()
那样工作?
非常感谢您的帮助。
提前致谢
问题是 callback
必须 return True
或 False
作为是否必须停止优化(分别)。
在你的情况下,MinimizeStopper
不会 return 任何东西,它基本上只是发出警告。所以你也必须硬编码 True/False returns。
试试这个
class MinimizeStopper(object):
def __init__(self, max_sec=0.3):
self.max_sec = max_sec
self.start = time.time()
def __call__(self, xk=None, convergence=None):
elapsed = time.time() - self.start
if elapsed > self.max_sec:
print("Terminating optimization: time limit reached")
return True
else:
# you might want to report other stuff here
# print("Elapsed: %.3f sec" % elapsed)
return False
有几件事应该考虑:
- 除非你指定
polish=False
作为differential_evolution()
的输入,抛光操作在停止进化后仍然进行:这会增加额外的时间
callback
在完成每一代的评估后触发:当迭代花费大量时间时,这可能会超过限制。
我的问题已经得到部分回答here。我只需要将答案扩展到另一个 Scipy 函数。 (Scipy 1.4.0,Python 3.7 在 Windows 10 上)
参考@ali_m给出的答案,我尝试将相同的想法应用于differential_evolution()
Scipy函数,该函数也有callback
参数。
我想确保我的 Scipy differential_evolution()
函数在特定时间限制后停止 运行ning。在这种情况下,我选择了具有 40 个输入参数和 0.3 秒阈值的 Rosenbrock 函数来突出显示发生的情况。
import numpy as np
from scipy.optimize import differential_evolution, rosen
import time
import warnings
class TookTooLong(Warning):
pass
class MinimizeStopper(object):
def __init__(self, max_sec=0.3):
self.max_sec = max_sec
self.start = time.time()
def __call__(self, xk=None, convergence=None):
elapsed = time.time() - self.start
if elapsed > self.max_sec:
warnings.warn("Terminating optimization: time limit reached",
TookTooLong)
else:
print("Elapsed: %.3f sec" % elapsed)
n_var = 40
upper_bound_array = np.ones(n_var) * 5
lower_bound_array = np.ones(n_var) * -5
bounds = Bounds(lower_bound_array, upper_bound_array)
# function call
res = differential_evolution(Rosen, bounds, strategy='best1bin',disp=False,
callback=MinimizeStopper(),
maxiter=1000000)
因此我没有收到任何错误,但似乎 Scipy minimize()
中使用的相同逻辑在这里不起作用。更具体地说,当我 运行 程序时,即使在引发 Warning 之后,程序仍然默默地继续计算所有必要的迭代,直到优化问题收敛。
有谁知道为什么在这种情况下它不像 minimize()
那样工作?
非常感谢您的帮助。
提前致谢
问题是 callback
必须 return True
或 False
作为是否必须停止优化(分别)。
在你的情况下,MinimizeStopper
不会 return 任何东西,它基本上只是发出警告。所以你也必须硬编码 True/False returns。
试试这个
class MinimizeStopper(object):
def __init__(self, max_sec=0.3):
self.max_sec = max_sec
self.start = time.time()
def __call__(self, xk=None, convergence=None):
elapsed = time.time() - self.start
if elapsed > self.max_sec:
print("Terminating optimization: time limit reached")
return True
else:
# you might want to report other stuff here
# print("Elapsed: %.3f sec" % elapsed)
return False
有几件事应该考虑:
- 除非你指定
polish=False
作为differential_evolution()
的输入,抛光操作在停止进化后仍然进行:这会增加额外的时间 callback
在完成每一代的评估后触发:当迭代花费大量时间时,这可能会超过限制。