scipy 优化中的自定义收敛标准

Custom convergence criterion in scipy optimise

我正在按以下方式使用 scipy.optimize 优化函数:

yEst=minimize(myFunction, y0, method='L-BFGS-B', tol=1e-6).x

我的问题是我不想在公差小于某个值时简单地停止(例如,如果第 n 次迭代停止是 |y_n - y_(n-1)|<tol)。相反,我有一个 y_ny_(n-1) 稍微复杂的函数,比如 tolFun,我想在 tolFun(y_n, y_(n-1))<tol 时停止。

为了更详细地说明我的容差函数如下。它将 y 划分为多个块,然后检查是否有任何单独的分区在公差范围内具有范数差异,如果有,则应停止最小化。

# Takes in current and previous iteration values and a pre-specified fixed scalar r.
def tolFun(yprev,ycurr,r):

  # The minimum norm so far (initialized to a big value)
  minnorm = 5000

  for i in np.arange(r):

    # Work out the norm of the ith partition/block of entries
    norm = np.linalg.norm(yprev[np.arange(r)+i*r],ycurr[np.arange(r)+i*r])

    # Update minimum norm
    minnorm = np.min(norm, minnorm)

  return(minnorm)

我的问题类似于 ,但不同之处在于该用户仅需要 y 的当前迭代值,而我的自定义容差函数需要 [=] 的当前迭代值19=] 和之前的值。有谁知道我该怎么做?

你不能直接做你想做的事,因为回调函数只接收当前参数向量。要解决您的问题,您可以通过以下方式修改 的第二个解决方案(我更喜欢使用 global 的第一个解决方案):

class Callback:
    def __init__(self, tolfun, tol=1e-8):
        self._tolf = tolfun
        self._tol = tol
        self._xk_prev = None

    def __call__(self, xk):
        if self._xk_prev is not None and self._tolf(xk, self._xk_prev) < self._tol:
            return True

        self._xk_prev = xk
        return False

cb = Callback(tolfun=tolFun, tol=tol)  # set tol here to control convergence
yEst = minimize(myFunction, y0, method='L-BFGS-B', tol=0, callback=cb)

yEst = optimize.minimize(
    myFunction, y0, method='L-BFGS-B',
    callback=cb, options={'gtol': 0, 'ftol': 0}
)

您可以使用以下方法找到 solver/method 的可用选项:

optimize.show_options('minimize', 'L-BFGS-B')