迁移学习¶
在执行黑盒优化时,用户经常运行与之前任务相似的任务。这一观察可以用来加速当前任务。
OpenBox 接收来自 \(K + 1\) 个任务的观测数据作为输入:\(D^1, ..., D^K\) 用于之前的 \(K\) 个任务,\(D^T\) 用于当前任务。到目前为止,OpenBox 仅支持单目标任务之间的迁移学习。支持三种迁移学习算法,分别是 RGPE、SGPR 和 TransBO。
我们提供了一个示例在 examples/transfer_learning.py。 在本教程中,我们将解释如何基于此示例使用迁移学习。
我们首先定义当前任务的目标函数和搜索空间。
import numpy as np
import matplotlib.pyplot as plt
from openbox import Observation, History, Advisor, space as sp, logger
# Define config space
cs = sp.Space()
for i in range(3):
cs.add_variable(sp.Float('x%d' % (i+1), -200, 200))
# Define objective function
def obj(config):
x1, x2, x3 = config['x1'], config['x2'], config['x3']
y = (x1-10)**2 + x2**2 + (x3-100)**2
return {'objectives': [y]}
然后,我们展示了如何为每个源任务构建一个History类。
我们假设我们已经对一些类似的任务进行了一些观察。
对于每个源任务,我们需要:
构建
Observation。将
Observation更新到History中。
如果源任务也使用OpenBox进行优化,可以通过optimizer.get_history()获取优化器的历史记录,或通过advisor.get_history()获取顾问的历史记录。
在这种情况下,我们生成一个相关的源任务和两个不相关的源任务。
# Generate history data for transfer learning. transfer_learning_history requires a list of History.
transfer_learning_history = list() # type: List[History]
# 3 source tasks with 50 evaluations of random configurations each
# one task is relevant to the target task, the other two are irrelevant
num_history_tasks, num_results_per_task = 3, 50
for task_idx in range(num_history_tasks):
# Build a History class for each source task based on previous observations.
# If source tasks are also optimized by Openbox, you can get the History by
# using the APIs from Optimizer or Advisor. E.g., history = advisor.get_history()
history = History(task_id=f'history{task_idx}', config_space=cs)
for _ in range(num_results_per_task):
config = cs.sample_configuration()
if task_idx == 1: # relevant task
y = obj(config)['objectives'][0] + 100
else: # irrelevant tasks
y = np.random.random()
# build and update observation
observation = Observation(config=config, objectives=[y])
history.update_observation(observation)
transfer_learning_history.append(history)
要开启迁移学习,我们需要指定 transfer_learning_history 和 surrogate_type:
transfer_learning_history: 一个History列表,表示来自每个源任务的观察结果。surrogate_type: 一个字符串。与Quick Start中显示的“auto”不同,这里的surrogate_type包括三个部分。第一部分必须是
"tlbo"。第二部分是迁移学习算法,它们是
"rgpe","sgpr", 和"topov3"。第三部分是代理类型,例如
"gp"或"prf"。
这三个部分用“_”连接。
使用RGPE作为迁移学习算法和高斯过程作为代理的一个例子是
"tlbo_rgpe_gp"。
在这里我们定义了一个Advisor,并使用了与examples/ask_and_tell_interface.py中展示的相同API。
你也可以像在快速开始中所示的那样定义一个Optimizer。
tlbo_advisor = Advisor(
config_space=cs,
num_objectives=1,
num_constraints=0,
initial_trials=3,
transfer_learning_history=transfer_learning_history, # type: List[History]
surrogate_type='tlbo_rgpe_gp',
acq_type='ei',
acq_optimizer_type='random_scipy',
task_id='TLBO',
)
max_iter = 20
for i in range(max_iter):
config = tlbo_advisor.get_suggestion()
res = obj(config)
logger.info(f'Iteration {i+1}, result: {res}')
observation = Observation(config=config, objectives=res['objectives'])
tlbo_advisor.update_observation(observation)
优化后,我们可以绘制结果。
# show results
history = tlbo_advisor.get_history()
print(history)
history.plot_convergence()
plt.show()