对于 SciPy 函数 fmin_ncg
,有没有办法将 hessian 和梯度作为变量而不是函数提供?
我正在尝试用 python 重写一些 Matlab 代码。该代码涉及使用优化例程将某些参数拟合到一组数据。为此,我提供了渐变和粗麻布。例如在 Matlab 中我有这样的东西:
fmincon(@myFunc,x0,[],[],[],[],lb,ub,[],options);
其中 myFunc
返回 3 个值:函数评估、梯度和 hessian。
但是对于 Python 中的 fmin_ncg
,梯度和粗麻布似乎必须作为单独的函数提供。
对我来说,这似乎是低效的,因为代码必须经过一个大型数据集,并且函数、梯度和 hessian 的计算是通用的。例如想象一个函数 f(x) = a(x)*b(x)
具有梯度 g(x) = a(x)*c(x)
,hessian h(x) = a(x)*d(x)
...在 Matlab 中,我可以计算一次 a(x)
,因为看起来我必须计算这在 Python 中执行了三次。
我是否误解了 fmin_ncg
的工作原理,或者是否有解决此问题的方法?
您可以创建一个包含所有函数的类。每次迭代,公共(public)变量在第一个函数调用期间计算,然后被其他调用重用。 fmin_ncg
的回调特性可用于在每次迭代结束时重置公共(public)变量。
class function(object):
def __init__(self):
self.commonVarsDirty = True
def calcFunction(self,x,*args,**kwargs):
if self.commonVarsDirty:
self.calcCommonVars()
return self.a*b
def calcGradient(self,x,*args,**kwargs):
if self.commonVarsDirty:
self.calcCommonVars()
return self.a*c
def calcHessian(self,x,*args,**kwargs):
if self.commonVarsDirty:
self.calcCommonVars()
return self.a*d
def resetCommonVars(self,*args,**kwargs):
self.commonVarsDirty = True
def calcCommonVars(self):
self.commonVarsDirty = False
# calculate common variables and save them as class attributes
self.a = 1+1
你会像这样使用它。
f = function()
fmin_ncg(f.calcFunction,x0,f.calcGradient,fhess=f.calcHessian,callback=f.resetCommonVars)
这会增加一些开销,因此只有在计算公共(public)变量的计算工作量很大时才值得。
我是一名优秀的程序员,十分优秀!