注意
点击 此处 下载完整示例代码
示例 8 - MNIST 的温启动¶
有时需要继续一个已完成的运行,因为优化需要更多的函数评估。在其他情况下,可能希望使用先前运行的结果来加速优化。如果在初始运行时使用了相对较小的预算,或者仅使用了一部分数据来初步了解问题,这可能会很有用。
在这里,我们将看到如何使用示例 5 的结果来初始化 BOHB 的模型。变化之处在于: - 训练点数量从 8192 增加到 32768 - 验证点数量从 1024 增加到 16384 - 最小预算现在是 3 而不是 1,因为我们已经针对少量 epoch 进行了相当多的运行
请注意,加载的运行将显示在新运行的结果中。它们都被合并到一个索引为 -1 的迭代中,并且它们的时间戳已被修改,使得最后一次运行在时间 0 结束,而所有其他时间都是负数。在分析运行时,这些信息可以用来过滤掉这些运行。
import os
import pickle
import argparse
import hpbandster.core.nameserver as hpns
import hpbandster.core.result as hpres
from hpbandster.optimizers import BOHB
import logging
logging.basicConfig(level=logging.DEBUG)
parser = argparse.ArgumentParser(description='Example 1 - sequential and local execution.')
parser.add_argument('--min_budget', type=float, help='Minimum number of epochs for training.', default=3)
parser.add_argument('--max_budget', type=float, help='Maximum number of epochs for training.', default=9)
parser.add_argument('--n_iterations', type=int, help='Number of iterations performed by the optimizer', default=4)
parser.add_argument('--worker', help='Flag to turn this into a worker process', action='store_true')
parser.add_argument('--run_id', type=str, help='A unique run id for this optimization run. An easy option is to use the job id of the clusters scheduler.')
parser.add_argument('--nic_name',type=str, help='Which network interface to use for communication.', default='lo')
parser.add_argument('--shared_directory',type=str, help='A directory that is accessible for all processes, e.g. a NFS share.', default='.')
parser.add_argument('--backend',help='Toggles which worker is used. Choose between a pytorch and a keras implementation.', choices=['pytorch', 'keras'], default='keras')
parser.add_argument('--previous_run_dir',type=str, help='A directory that contains a config.json and results.json for the same configuration space.', default='./example_5_run/')
args=parser.parse_args()
if args.backend == 'pytorch':
from example_5_pytorch_worker import PyTorchWorker as worker
else:
from example_5_keras_worker import KerasWorker as worker
# Every process has to lookup the hostname
host = hpns.nic_name_to_host(args.nic_name)
if args.worker:
import time
time.sleep(5) # short artificial delay to make sure the nameserver is already running
w = worker(run_id=args.run_id, host=host, timeout=120)
w.load_nameserver_credentials(working_directory=args.shared_directory)
w.run(background=False)
exit(0)
# This example shows how to log live results. This is most useful
# for really long runs, where intermediate results could already be
# interesting. The core.result submodule contains the functionality to
# read the two generated files (results.json and configs.json) and
# create a Result object.
result_logger = hpres.json_result_logger(directory=args.shared_directory, overwrite=False)
# Start a nameserver:
NS = hpns.NameServer(run_id=args.run_id, host=host, port=0, working_directory=args.shared_directory)
ns_host, ns_port = NS.start()
# Start local worker
w = worker(run_id=args.run_id, host=host, nameserver=ns_host, nameserver_port=ns_port, timeout=120)
w.run(background=True)
# Let us load the old run now to use its results to warmstart a new run with slightly
# different budgets in terms of datapoints and epochs.
# Note that the search space has to be identical though!
previous_run = hpres.logged_results_to_HBS_result(args.previous_run_dir)
# Run an optimizer
bohb = BOHB( configspace = worker.get_configspace(),
run_id = args.run_id,
host=host,
nameserver=ns_host,
nameserver_port=ns_port,
result_logger=result_logger,
min_budget=args.min_budget, max_budget=args.max_budget,
previous_result = previous_run, # this is how you tell any optimizer about previous runs
)
res = bohb.run(n_iterations=args.n_iterations)
# store results
with open(os.path.join(args.shared_directory, 'results.pkl'), 'wb') as fh:
pickle.dump(res, fh)
# shutdown
bohb.shutdown(shutdown_workers=True)
NS.shutdown()
脚本总运行时间: ( 0 分钟 0.000 秒)