多目标带约束

在本教程中,我们将介绍如何使用OpenBox优化约束多目标问题。

问题设置

在这个例子中,我们使用了约束多目标问题CONSTR。由于CONSTR是一个内置函数,其搜索空间和目标函数被包装如下:

from openbox.benchmark.objective_functions.synthetic import CONSTR

prob = CONSTR()
dim = 2
initial_runs = 2 * (dim + 1)
import numpy as np
from openbox import space as sp
params = {'x1': (0.1, 10.0),
          'x2': (0.0, 5.0)}
space = sp.Space()
space.add_variables([sp.Real(k, *v) for k, v in params.items()])

def objective_funtion(config: sp.Configuration):
    X = np.array(list(config.get_dictionary().values()))

    result = dict()
    obj1 = X[..., 0]
    obj2 = (1.0 + X[..., 1]) / X[..., 0]
    result['objectives'] = np.stack([obj1, obj2], axis=-1)

    c1 = 6.0 - 9.0 * X[..., 0] - X[..., 1]
    c2 = 1.0 - 9.0 * X[..., 0] + X[..., 1]
    result['constraints'] = np.stack([c1, c2], axis=-1)

    return result

评估后,目标函数返回一个dict (推荐)。 结果字典应包含:

  • 'objectives': 一个列表/元组,包含目标值(需要最小化)。 在这个例子中,我们只有一个目标,因此元组包含一个单一的值。

  • 'constraints': 一个列表/元组约束值。 非正的约束值(“<=0”)意味着可行性。

优化

from openbox import Optimizer
opt = Optimizer(
    prob.evaluate,
    prob.config_space,
    num_objectives=prob.num_objectives,
    num_constraints=prob.num_constraints,
    max_runs=100,
    surrogate_type='gp',                # try using 'auto'!
    acq_type='ehvic',                   # try using 'auto'!
    acq_optimizer_type='random_scipy',  # try using 'auto'!
    initial_runs=initial_runs,
    init_strategy='sobol',
    ref_point=prob.ref_point,
    task_id='moc',
    random_state=1,
    # Have a try on the new HTML visualization feature!
    # visualization='advanced',   # or 'basic'. For 'advanced', run 'pip install "openbox[extra]"' first
    # auto_open_html=True,        # open the visualization page in your browser automatically
)
history = opt.run()

在这里我们创建了一个Optimizer实例,并将目标函数和搜索空间传递给它。 其他参数包括:

  • num_objectivesnum_constraints 设置目标函数将返回多少个目标和约束。 在这个例子中,num_objectives=2num_constraints=2

  • max_runs=100 意味着优化将进行100轮(优化目标函数100次)。

  • surrogate_type='gp'. 对于数学问题,我们建议使用高斯过程('gp')作为贝叶斯代理模型。对于超参数优化(HPO)等实际问题,我们建议使用随机森林('prf')。设置为'auto'以启用自动算法选择

  • acq_type='ehvic'。使用EHVIC(带约束的预期超体积改进)作为贝叶斯获取函数。 设置为'auto'以启用 自动算法选择

  • acq_optimizer_type='random_scipy'. 对于数学问题,我们建议使用 'random_scipy' 作为 采集函数优化器。对于超参数优化(HPO)等实际问题,我们建议 使用 'local_random'。 设置为 'auto' 以启用 自动算法选择

  • initial_runs 设置优化循环前由 init_strategy 建议的配置数量。

  • init_strategy='sobol' 设置策略以建议初始配置。

  • ref_point 指定参考点,这是用于计算超体积的目标的上限。如果使用EHVI方法,必须提供一个参考点。在实践中,参考点可以设置为1)使用领域知识略差于目标值的上限,其中上限是每个目标的最大可接受值,或2)使用动态参考点选择策略。

  • task_id 用于标识优化过程。

  • visualization: 'none', 'basic''advanced'. 参见 HTML Visualization.

  • auto_open_html: 是否自动在浏览器中打开可视化页面。 参见 HTML Visualization

然后,调用opt.run()以启动优化过程。

可视化

由于我们同时优化两个目标,因此我们得到了一个帕累托前沿作为结果。 调用opt.get_history().plot_pareto_front()来绘制帕累托前沿。 请注意,plot_pareto_front仅在目标数量为2或3时有效。

import matplotlib.pyplot as plt

history = opt.get_history()
# plot pareto front
if history.num_objectives in [2, 3]:
    history.plot_pareto_front()  # support 2 or 3 objectives
    plt.show()
../_images/plot_pareto_front_constr.png

然后绘制优化过程中与理想帕累托前沿相比的超体积差异。

# plot hypervolume (optimal hypervolume of CONSTR is approximated using NSGA-II)
history.plot_hypervolumes(optimal_hypervolume=92.02004226679216, logy=True)
plt.show()
../_images/plot_hypervolume_constr.png

(新功能!) 调用 history.visualize_html() 在HTML页面中可视化优化过程。 对于 show_importanceverify_surrogate,首先运行 pip install "openbox[extra]"。 详情请参见 HTML Visualization

history.visualize_html(open_html=True, show_importance=True,
                       verify_surrogate=True, optimizer=opt)
../_images/html_example_moc.jpg