【问题标题】:Stop scipy.optimize.minimize after maximum runtime最长运行时间后停止 scipy.optimize.minimize
【发布时间】:2016-03-04 03:34:20
【问题描述】:

我在集群上运行scipy.optimize.minimize(method='L-BFGS-B')。运行时间超过 72 小时的任务将被终止,并且没有任何保存结果的选项。有没有办法在 T=48h 的运行时间过去后退出scipy.optimize.minimize()

【问题讨论】:

  • 您可以使用callback 方法。请注意,您只能在完成一个完整的迭代步骤后停止。如果您的函数值评估或梯度非常昂贵,您必须考虑到这一点。
  • 或者,只允许“少量”迭代,保存该结果,然后使用返回值重新启动。问题是大还是复杂,或两者兼而有之?
  • 问题很大(100 到 1000 个自变量)而且很复杂。经过少量迭代后,我确实可以重新启动。然而,它也有其缺点,因为 BFGS 算法使用来自先前迭代的信息,因此不会超过 10 个。我不知道如何使用回调函数停止优化。我只设法提出了一个错误。你能解释一下吗?

标签: python scipy runtime minimize


【解决方案1】:
  1. 一种方法是估计一次迭代的评估时间,然后在options 参数中相应地设置maxiter

  2. 另一种方法是定义一个类,它修改一个函数fun,使其在指定时间后返回错误并记录最后一个输入值x及其输出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
    

    这样优化可以在fun 被调用后停止,比如说,在第一次调用后的 2 秒之后:

    ## 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
    

顺便说一句,请查看我的包optimparallel,它允许您通过并行计算加速优化,并返回每个步骤的评估值xfun(x)jac(x)

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])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    • 2012-05-11
    • 2014-02-11
    • 1970-01-01
    • 2022-08-18
    相关资源
    最近更新 更多