MetaModel非结构化计算时间

MetaModelUnstructured Computational Time

我正在使用示例二维函数通过 MetaModelUnStructuredComp 进行优化。 下面是一个代码片段。当我增加样本点的数量时,用于训练的计算时间会大大增加。我不确定是否预期会增加这么多,或者我做错了什么。 问题是二维的,预测下面的 1 个输出是一些性能时间;

45 sec for 900 points* 
14 sec for 625 points 
3.7 sec for 400 points

*points代表每个训练输入的维度

减少这个会不会成为openMDAO开发团队未来的工作重点? (继续阅读编辑版本)

import numpy as np
from openmdao.api import Problem,  IndepVarComp
from openmdao.api import  ScipyOptimizeDriver
from openmdao.api import MetaModelUnStructuredComp, FloatKrigingSurrogate,MetaModelUnStructuredComp
from openmdao.api import CaseReader, SqliteRecorder
import time
t0 = time.time()

class trig(MetaModelUnStructuredComp):
    def setup(self):
        ii=3
        nx, ny = (10*ii, 10*ii)
        print(nx*ny)
        xx = np.linspace(-3,3, nx)
        yy = np.linspace(-2,2, ny)        
        x, y = np.meshgrid(xx, yy)
#        z = np.sin(x)**10 + np.cos(10 + y) * np.cos(x)
#        z=4+4.5*x-4*y+x**2+2*y**2-2*x*y+x**4-2*x**2*y
        term1 = (4-2.1*x**2+(x**4)/3) * x**2;
        term2 = x*y;
        term3 = (-4+4*y**2) * y**2;            
        z = term1 + term2 + term3;        

        self.add_input('x',  training_data=x.flatten())
        self.add_input('y',  training_data=y.flatten())
        self.add_output('meta_out', surrogate=FloatKrigingSurrogate(), 
                        training_data=z.flatten())
prob = Problem()
inputs_comp = IndepVarComp()
inputs_comp.add_output('x',  1.5)
inputs_comp.add_output('y',  1.5)
prob.model.add_subsystem('inputs_comp', inputs_comp)
#triginst=
prob.model.add_subsystem('trig', trig())

prob.model.connect('inputs_comp.x', 'trig.x')
prob.model.connect('inputs_comp.y', 'trig.y')

prob.driver = ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'SLSQP'

prob.driver.options['tol'] = 1e-8
prob.driver.options['disp'] = True

prob.model.add_design_var('inputs_comp.x', lower=-3, upper=3)
prob.model.add_design_var('inputs_comp.y', lower=-2, upper=2)
prob.model.add_objective('trig.meta_out')

prob.setup(check=True)
prob.run_model()
print(prob['inputs_comp.x'])
print(prob['inputs_comp.y'])
print(prob['trig.meta_out'])
t1 = time.time()

total = t1-t0
print(total)

根据下面的答案,我添加了一个显式组件的代码片段,该组件使用 SMT 工具箱进行代理。我想这是使用工具箱功能的一种方式。

import numpy as np
from smt.surrogate_models import RBF
from openmdao.api import ExplicitComponent
from openmdao.api import Problem, ScipyOptimizeDriver
from openmdao.api import Group, IndepVarComp
import smt
# Sample problem with SMT Toolbox and OpenMDAO Explicit Comp 
#Optimization of SIX-HUMP CAMEL FUNCTION with 2 global optima
class MetaCompSMT(ExplicitComponent):
    def initialize(self):
        self.options.declare('sm', types=smt.surrogate_models.rbf.RBF)
    def setup(self):        
        self.add_input('x')
        self.add_input('y')
        self.add_output('z')        
#        self.declare_partials(of='z', wrt=['x','y'], method='fd')
        self.declare_partials(of='*', wrt='*')
    def compute(self, inputs, outputs):
#        sm    = self.options['sm'] # seems like this is not needed
        sta=np.column_stack([inputs[i] for i in inputs])        
        outputs['z'] =sm.predict_values(sta).flatten()               
    def compute_partials(self, inputs, partials):   
        sta=np.column_stack([inputs[i] for i in inputs])        
        print(sta)
        for i,invar in enumerate(inputs):
            partials['z', invar] =sm.predict_derivatives(sta,i)

# SMT SURROGATE IS TRAINED IN ADVANCE AND PASSED TO THE COMPONENT AS GLOBAL INPUT
# Training Data
ii=3 # "incerases the domain size"
nx, ny = (10*ii, 5*ii)  
x, y = np.meshgrid(np.linspace(-3,3, nx), np.linspace(-2,2, ny))
term1 = (4-2.1*x**2+(x**4)/3) * x**2;
term2 = x*y;
term3 = (-4+4*y**2) * y**2;        
z = term1 + term2 + term3; 
# Surrogate training
xt=np.column_stack([x.flatten(),y.flatten()])
yt=z.flatten()
#sm = KPLSK(theta0=[1e-2])
sm=RBF(d0=-1,poly_degree=-1,reg=1e-13,print_global=False)
sm.set_training_values(xt, yt)
sm.train()


prob = Problem() # Start the OpenMDAO optimization problem
prob.model = model = Group() # Assemble a group within the problem. In this case single group. 
"Independent component  ~ single Design variable " 
inputs_comp = IndepVarComp() # OpenMDAO approach for the design variable as independent component output
inputs_comp.add_output('x',  2.5) # Vary initial value for finding the second global optimum
inputs_comp.add_output('y',  1.5) # Vary initial value for finding the second global optimum
model.add_subsystem('inputs_comp', inputs_comp)
"Component 1"
comp = MetaCompSMT(sm=sm)
model.add_subsystem('MetaCompSMT', comp)
"Connect design variable to the 2 components. Easier to follow than promote"
model.connect('inputs_comp.x', 'MetaCompSMT.x')
model.connect('inputs_comp.y', 'MetaCompSMT.y')
"Lower/Upper bound design variables"
model.add_design_var('inputs_comp.x', lower=-3, upper=3)
model.add_design_var('inputs_comp.y', lower=-2, upper=2)
model.add_objective('MetaCompSMT.z')

prob.driver = ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'SLSQP'
prob.driver.options['disp'] = True

prob.driver.options['tol'] = 1e-9
prob.setup(check=True, mode='fwd')

prob.run_driver()
print(prob['inputs_comp.x'],prob['inputs_comp.y'],prob['MetaCompSMT.z'])

我将使用您的测试用例更仔细地研究 MetaModelUnStructuredComp 的性能。虽然我确实注意到这个测试用例确实涉及拟合结构化数据集。如果您使用 MetaModelStructuredComp(http://openmdao.org/twodocs/versions/2.2.0/features/building_blocks/components/metamodelstructured.html),性能会好得多:

class trig(MetaModelStructuredComp):
def setup(self):
    ii=3
    nx, ny = (10*ii, 10*ii)
    xx = np.linspace(-3,3, nx)
    yy = np.linspace(-2,2, ny)        
    x, y = np.meshgrid(xx, yy, indexing='ij')

    term1 = (4-2.1*x**2+(x**4)/3) * x**2;
    term2 = x*y;
    term3 = (-4+4*y**2) * y**2;            
    z = term1 + term2 + term3;        

    self.add_input('x', 0.0, xx)
    self.add_input('y', 0.0, yy)
    self.add_output('meta_out', 0.0, z)

900 分的情况从我机器上使用 MetaModelUnStructuredComp 的 14 秒变为使用 MetaModelStructuredComp 时的 0.081。

如果您愿意自己编译一些代码,您可以为 Surrogate Modeling Toolbox (SMT) 编写非常轻量级的包装器。您可以编写该包装器以与标准 MetaModelUnstructuredComp 一起使用,或者只编写您自己的组件包装器。

无论哪种方式,该库中都有一些明显更快的非结构化代理模型。默认的 OpenMDAO 实现只是基本实现。我们可能会随着时间的推移改进它们,但对于更大的数据集或设计空间,SMT 提供了更好的算法。

从 2.4 版开始,我们还没有在 OpenMDAO 中编写通用的 SMT 包装器,但编写您自己的包装器并不难。