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

问题描述

我想使用 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,options={'disp': True})

谢谢!

解决方法

您可以使用自定义类缓存渐变,然后在请求时返回它:

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,*args):
        return self.cache.pop('grad')


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