最小化作为 class 方法的 objective 函数

Minimising an objective function which is a method of a class

我有一个 class XYZ() 方法 buildPredict。我有另一个 class BuildSurrogate(),它有一个属性 SurrogateClass 指向 class XYZ() 类型的对象。 SurrogateClass 的方法是 _minima ,定义如下。

class XYZ():
        ...

    def build(self):
        ...

    def Predict(self):
        ...

class BuildSurrogate():
    def __init__(self, args):
        self.SurrogateClass = XYZ(*args)

    def _minima(self):
        """
        This returns the minima of the surrogate
        """

        x0 = copy(self.x0_)
        solution = minimize(fun=self.SurrogateClass.Predict, x0=x0, args=args, method='Nelder-Mead')# x0=x0, options={'xtol':1e-5,'ftol':1e-5})
        return solution

脚本引发错误:

 Traceback (most recent call last):
  File "/path/to/optiblade/Optimizer/SurrogateModel.py", line 1067, in <module>
    print SurrogateObj._minima()
  File "/path/to/optiblade/Optimizer/SurrogateModel.py", line 1006, in _minima
    solution = minimize(fun=self.SurrogateClass.Predict, x0=x0, method='Nelder-Mead')# x0=x0, options={'xtol':1e-5,'ftol':1e-5})
  File "/usr/local/lib/python2.7/dist-packages/scipy/optimize/_minimize.py", line 435, in minimize
    return _minimize_neldermead(fun, x0, args, callback, **options)
  File "/usr/local/lib/python2.7/dist-packages/scipy/optimize/optimize.py", line 439, in _minimize_neldermead
    fsim[0] = func(x0)
ValueError: setting an array element with a sequence.

我推测出现此错误是因为 self 其中 self = self.SurrogateClass 将传递给 Predict。我必须改变我的代码结构还是有什么方法可以在不改变我的代码结构的情况下解决上述问题?

minimize 文档的示例开始:

In [183]: x0 = [1.3, 0.7, 0.8, 1.9, 1.2]
In [185]: optimize.minimize(optimize.rosen, x0, method='Nelder-Mead', tol=1e-6)
Out[185]: 
 final_simplex: (array([[ 1.00000002,  1.00000002,  1.00000007,  1.00000015,  1.00000028],
...
             x: array([ 1.00000002,  1.00000002,  1.00000007,  1.00000015,  1.00000028])

定义一个可调用的 class 做同样的事情:

In [191]: class Class1(object):
    def __init__(self):
        pass
    def __call__(self,args):
        return optimize.rosen(args)
In [190]: optimize.minimize(Class1(), x0, method='Nelder-Mead', tol=1e-6)

一个 Class1 对象是可调用的,所以我可以像定义一个 rosen 方法一样使用它

In [191]: Class1()(x0)
Out[191]: 848.22000000000003

我可以这样定义它:

In [192]: class Class2(object):
    def rosen(self,args):
        return optimize.rosen(args)   

In [193]: optimize.minimize(Class2().rosen, x0, method='Nelder-Mead', tol=1e-6)

In [194]: Class2().rosen(x0)
Out[194]: 848.22000000000003

添加 class 层应该不会有什么不同,只要 minimize 的第一个参数是一个函数 returns 在用 [=20 调用时的值=].

在你的情况下你只需要定义:

class XYZ(object):
    def predict(self, args):
        return optimize.rosen(args)

class BuildSurrogate(object):
    def __init__(self):
        self.surrogateObj = XYZ()
    def minima(self,x0):
        return optimize.minimize(self.surrogateObj.predict, x0, method='Nelder-Mead', tol=1e-6)

并使用:

BuildSurrogate().minima(x0)

或类似的东西。

我也可以定义 self.SurrogateClass=XYZ 并调用 self.SurrogateClass().predict。只要 predictXYZ class 的方法,我就必须在使用它之前创建一个 XYZ() 对象。