在Python中为fmin_ncg提供Hessian
对于SciPy中的函数 fmin_ncg
,有没有办法把海森矩阵和梯度作为变量提供,而不是作为函数?
我正在把一些Matlab代码改写成Python。这段代码涉及使用优化程序来调整一些参数以适应一组数据。为此,我提供了梯度和海森矩阵。比如在Matlab中,我有这样的代码:
fmincon(@myFunc,x0,[],[],[],[],lb,ub,[],options);
其中 myFunc
返回三个值:函数的计算结果、梯度和海森矩阵。
但是在Python的 fmin_ncg
中,似乎梯度和海森矩阵必须作为单独的函数提供。
我觉得这样效率不高,因为代码需要处理大量数据,而函数、梯度和海森矩阵之间有一些共同的计算。比如,想象一个函数 f(x) = a(x)*b(x)
,它的梯度是 g(x) = a(x)*c(x)
,海森矩阵是 h(x) = a(x)*d(x)
... 在Matlab中,我可以只计算一次 a(x)
,而在Python中,似乎我必须计算三次。
我是不是误解了 fmin_ncg
的工作原理,或者有没有其他解决办法?
1 个回答
4
你可以创建一个类,把你所有的函数都放在里面。每次运行的时候,第一次调用函数时会计算一些共同的变量,然后后面的调用就可以重复使用这些变量。fmin_ncg
的回调功能可以用来在每次运行结束时重置这些共同的变量。
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)
这样做会增加一些额外的开销,所以只有在计算共同变量的工作量比较大的时候,这样做才有意义。