最小化作为 class 方法的 objective 函数
Minimising an objective function which is a method of a class
我有一个 class XYZ()
方法 build
和 Predict
。我有另一个 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
。只要 predict
是 XYZ
class 的方法,我就必须在使用它之前创建一个 XYZ()
对象。
我有一个 class XYZ()
方法 build
和 Predict
。我有另一个 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
。只要 predict
是 XYZ
class 的方法,我就必须在使用它之前创建一个 XYZ()
对象。