1

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

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

我的问题是我不想简单地在容差小于一个值时停止(例如,如果在第 n 次迭代停止是|y_n - y_(n-1)|<tol)。相反,我有一个稍微复杂的函数y_nand y_(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,而我的自定义容差函数既需要 的当前迭代值,y也需要先前的值。有谁知道我该怎么做?

4

1 回答 1

4

你不能直接做你想做的事,因为回调函数只接收当前参数向量。要解决您的问题,您可以通过以下方式从https://stackoverflow.com/a/30365576/8033585修改第二个解决方案(我更喜欢使用的第一个解决方案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}
)

您可以使用以下方法找到求解器/方法的可用选项:

optimize.show_options('minimize', 'L-BFGS-B')
于 2019-08-07T01:11:04.047 回答