scipy.optimize.minimize函数基本上实现了与MATLAB的’fminunc’函数等效的功能,用于查找函数的局部最小值.
在scipy中,渐变函数和Hessian函数是分开的.
res = minimize(rosen, x0, method='Newton-CG',
... jac=rosen_der, hess=rosen_hess,
... options={'xtol': 1e-30, 'disp': True})
但是,我有一个函数,其Hessian和渐变共享许多计算,并且为了效率,我想一起计算Hessian和渐变.在fminunc中,可以编写目标函数以返回多个值,即:
function [ q, grad, Hessian ] = rosen(x)
有没有好的方法可以传入一个函数scipy.optimize.minimize来一起计算这些元素?
解决方法:
您可以使用缓存解决方案,但是首先numpy数组不可哈希,其次您只需要缓存一些值,具体取决于算法是否在x上来回频繁.如果算法仅从一个点移动到下一个点,则您只能以这种方式缓存最后计算的点,而您的f_hes和f_jac只是用于计算两者的较长函数的lambda接口:
import numpy as np
# I choose the example f(x,y) = x**2 + y**2, with x,y the 1st and 2nd element of x below:
def f(x):
return x[0]**2+x[1]**2
def f_jac_hess(x):
if all(x==f_jac_hess.lastx):
print('fetch cached value')
return f_jac_hess.lastf
print('new elaboration')
res = array([2*x[0],2*x[1]]),array([[2,0],[0,2]])
f_jac_hess.lastx = x
f_jac_hess.lastf = res
return res
f_jac_hess.lastx = np.empty((2,)) * np.nan
f_jac = lambda x : f_jac_hess(x)[0]
f_hes = lambda x : f_jac_hess(x)[1]
现在,第二个调用将缓存保存的值:
>>> f_jac([3,2])
new elaboration
Out: [6, 4]
>>> f_hes([3,2])
fetch cached value
Out: [[2, 0], [0, 2]]
然后将其称为:
minimize(f,array([1,2]),method='Newton-CG',jac = f_jac, hess= f_hes, options={'xtol': 1e-30, 'disp': True})