问题描述
我想使用 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})