将 python scipy.optimize.minimize 与计算值和梯度的函数一起使用

Using python scipy.optimize.minimize with function that evaluates both value and gradient

我想使用 python 找到一个函数(具有多个变量)的局部最小值。 scipy.optimize.minimize 中描述的一组基于梯度的优化方法似乎是一个很好的开始。

我可以计算函数的值以及这个函数的梯度。事实上,当我评估函数时,我基本上是免费获得梯度的。 有没有办法利用这个 属性 来最小化使用 scipy.optimize.minimize 的函数调用次数?

我仅指使用基于梯度的优化的方法(例如 BFGS)。

更准确地说,我如何将计算我的数学函数的值及其梯度值的单个 python 函数插入到 scipy.optimize.minimize 中?

而不是这个:

res = minimize(fun, x0, method='BFGS', jac=grad_fun,options={'disp': True})

我想要这样的东西:

res = minimize(fun_and_grad, x0, method='BFGS', options={'disp': True})

谢谢!

您可以使用缓存渐变的自定义 class,然后在请求时 returns 它:

class Wrapper:
    def __init__(self):
        self.cache = {}

    def __call__(self, x, *args):
        fun, grad = compute_something(x)
        self.cache['grad'] = grad
        return fun

    def jac(self, x, *args):
        return self.cache.pop('grad')


wrapper = Wrapper()
res = minimize(wrapper, x0, jac=wrapper.jac, method='BFGS', options={'disp': True})