迁移学习#
在进行黑盒优化时,用户经常运行与以前类似的任务。这个观察可用于加速当前优化任务。
OpenBox 的以 \(K + 1\) 个任务的观测作为输入: \(D^1, ..., D^K\) 指 \(K\) 个先前的任务, \(D^T\) 指当前任务。 目前,OpenBox只支持单目标任务间的迁移学习,并提供了3个迁移学习算法,包括 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()
从Optimizer中获取历史,
或使用advisor.get_history()
从Advisor中获取历史。
在这个例子里,我们生成了一个相关的源任务,和两个不相关的源任务。
# 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的列表,每个History对应一个源任务。surrogate_type
: 一个字符串。不同于 快速入门教程 中展示的”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()