OpenMDAO 3.34版本中Bayesian optimization的实现方案咨询
适配OpenMDAO 3.34的贝叶斯优化实现思路
思路1:自定义OpenMDAO Driver实现贝叶斯优化
OpenMDAO 3.x的驱动架构支持自定义扩展,你可以基于Driver或ExplicitDriver基类,封装成熟的贝叶斯优化库(如scikit-optimize、GPyOpt)实现原生集成:
- 核心步骤:
- 继承
openmdao.core.driver.Driver,在初始化方法中配置贝叶斯优化器,同时从OpenMDAO问题中读取设计变量的上下界、目标函数和约束信息。 - 实现
run()方法:在迭代循环中,让优化器生成下一组设计变量值,通过self.set_design_vars()将值传入OpenMDAO模型,调用self._problem.run_model()运行模型,再通过self.get_val()获取目标函数和约束值,反馈给优化器更新代理模型。 - 处理约束:将OpenMDAO的约束条件转换为优化库支持的格式(比如
skopt允许通过constraints参数传入不等式约束)。
- 继承
- 示例代码片段:
from openmdao.core.driver import Driver from skopt import gp_minimize from skopt.space import Real class BayesOptDriver(Driver): def __init__(self, **kwargs): super().__init__(**kwargs) self._desvar_spaces = [] def _setup_driver(self, problem): super()._setup_driver(problem) # 提取设计变量空间 for name, meta in self._designvars.items(): self._desvar_spaces.append(Real(low=meta['lower'], high=meta['upper'], name=name)) def run(self): def objective(x): # 设置设计变量 for i, (name, _) in enumerate(self._designvars.items()): self.set_val(name, x[i]) # 运行模型 self._problem.run_model() # 获取目标值 obj_val = self.get_val(self._objs[0]['name']) # 获取约束值(如果有) constraints = [] for con in self._cons.values(): con_val = self.get_val(con['name']) constraints.append(con_val - con['upper'] if con['upper'] is not None else con['lower'] - con_val) return obj_val, constraints # 初始化并运行贝叶斯优化 res = gp_minimize( lambda x: objective(x)[0], dimensions=self._desvar_spaces, constraints=[{'type': 'ineq', 'fun': lambda x: objective(x)[1][i]} for i in range(len(self._cons))], n_calls=50, random_state=42 ) # 将最优结果设置回模型 for i, (name, _) in enumerate(self._designvars.items()): self.set_val(name, res.x[i]) self._problem.run_model()
思路2:迁移旧版BayesOpt驱动至3.34版本
针对你提到的旧版驱动,核心是适配OpenMDAO 3.x的API变化:
- 替换旧版API:比如1.7.1中的设计变量元数据获取逻辑改为直接访问
self._designvars字典;目标值获取改用self.get_val(self._objs[0]['name']);模型运行调用problem.run_model()替代旧版的problem.run()。 - 更新依赖:确保驱动依赖的贝叶斯优化库与当前Python版本兼容,必要时替换为维护更活跃的替代库。
- 简化冗余逻辑:复用OpenMDAO 3.x内置的变量解析、结果同步等工具类,移除旧版中自行实现的重复逻辑。
思路3:半集成式封装(备选)
如果自定义驱动成本较高,可在不把模型完全当黑盒的前提下,用OpenMDAO的CaseReader和CaseRecorder实现与外部贝叶斯优化脚本的轻量化对接:
- 在OpenMDAO模型中添加
CaseRecorder记录每次迭代的输入输出; - 外部优化脚本通过
CaseReader读取历史数据,调用贝叶斯优化生成新变量,再通过problem.set_val()传入模型并运行。 - 此方法比纯黑盒调用更贴近OpenMDAO生态,但灵活性不如自定义驱动。
优先推荐思路1,既能完全集成到OpenMDAO工作流中,又能利用成熟优化库的稳定性和功能;如果旧版驱动逻辑符合你的需求,思路2的迁移成本会更低。
内容的提问来源于stack exchange,提问作者jthomas
相关产品推荐
相关产品推荐

