HPO 教程(PyTorch 版本)

本教程对 PyTorch 官方教程 进行超参调优。

教程分为四步:

  1. 修改调优的模型代码;

  2. 定义超参的搜索空间;

  3. 配置实验;

  4. 运行实验。

步骤一:准备模型

首先,我们需要准备待调优的模型。

由于被调优的模型会被独立地运行多次, 并且使用特定训练平台时还可能会被上传到云端执行, 我们需要将代码写在另一个 py 文件中。

本教程使用的模型的代码是 model.py

模型代码在一个普通的 PyTorch 模型基础之上,增加了3个 API 调用:

  1. 使用 nni.get_next_parameter() 获取需要评估的超参;

  2. 使用 nni.report_intermediate_result() 报告每个 epoch 产生的中间训练结果;

  3. 使用 nni.report_final_result() 报告最终准确率。

请先理解模型代码,然后再继续下一步。

步骤二:定义搜索空间

在模型代码中,我们准备了三个需要调优的超参:features、lr、momentum。

现在,我们需要定义的它们的“搜索空间”,指定它们的取值范围和分布规律。

假设我们对三个超参有以下先验知识:

  1. features 的取值可以为128、256、512、1024;

  2. lr 的取值在0.0001到0.1之间,其取值符合指数分布;

  3. momentum 的取值在0到1之间。

在 NNI 中,features 的取值范围称为 choice , lr 的取值范围称为 loguniform , momentum 的取值范围称为 uniform 。 您可能已经注意到了,这些名称和 numpy.random 中的函数名一致。

完整的搜索空间文档: Search Space.

我们的搜索空间定义如下:

search_space = {
    'features': {'_type': 'choice', '_value': [128, 256, 512, 1024]},
    'lr': {'_type': 'loguniform', '_value': [0.0001, 0.1]},
    'momentum': {'_type': 'uniform', '_value': [0, 1]},
}

步骤三:配置实验

NNI 使用“实验”来管理超参调优,“实验配置”定义了如何训练模型、如何遍历搜索空间。

在本教程中我们使用 local 模式的实验,这意味着实验只在本机运行,不使用任何特别的训练平台。

from nni.experiment import Experiment
experiment = Experiment('local')

现在我们开始配置实验。

配置 trial

在 NNI 中评估一组超参的过程被称为一个“trial”(试验),上面的模型代码被称为“trial 代码”。

experiment.config.trial_command = 'python model.py'
experiment.config.trial_code_directory = '.'

如果 trial_code_directory 是一个相对路径,它被认为相对于当前的工作目录。 如果您想在其他路径下运行本文件 main.py ,您可以将代码目录设置为 Path(__file__).parent 。 (__file__ 只能在 py 文件中使用,不能在 Jupyter Notebook 中使用)

注意

如果您使用 Linux 系统,并且没有使用 Conda, 您可能需要将 "python model.py" 改为 "python3 model.py"

配置搜索空间

experiment.config.search_space = search_space

配置调优算法

此处我们使用 TPE 算法

experiment.config.tuner.name = 'TPE'
experiment.config.tuner.class_args['optimize_mode'] = 'maximize'

配置运行多少 trial

本教程中我们总共尝试10组超参,并且每次并行地评估2组超参。

experiment.config.max_trial_number = 10
experiment.config.trial_concurrency = 2

您也可以设置 max_experiment_duration = '1h' 来限制运行时间。

如果 max_trial_numbermax_experiment_duration 都没有设置,实验将会一直运行,直到您按下 Ctrl-C。

备注

此处将 max_trial_number 设置为10是为了让教程能够较快地运行结束, 在实际使用中应该设为更大的数值,TPE 算法在默认参数下需要评估20组超参才会完成初始化。

步骤四:运行实验

现在实验已经配置完成了,您可以指定一个端口来运行它,教程中我们使用8080端口。

您可以通过网页控制台查看实验状态: http://localhost:8080.

experiment.run(8080)

Out:

[2022-04-13 12:07:29] Creating experiment, Experiment ID: hgkju3iq
[2022-04-13 12:07:29] Starting web server...
[2022-04-13 12:07:30] Setting up...
[2022-04-13 12:07:30] Web portal URLs: http://127.0.0.1:8080 http://192.168.100.103:8080

True

实验结束之后

您只需要等待函数返回就可以正常结束实验,以下内容为可选项。

如果您使用的是普通 Python 而不是 Jupyter Notebook, 您可以在代码末尾加上一行 input() 或者 signal.pause() 来避免 Python 解释器自动退出, 这样您就能继续使用网页控制台。

# input('Press enter to quit')
experiment.stop()

Out:

[2022-04-13 12:08:50] Stopping experiment, please wait...
[2022-04-13 12:08:53] Experiment stopped

nni.experiment.Experiment.stop() 会在 Python 退出前自动调用,所以您可以将其省略,不写在自己的代码中。

实验完全停止之后,您可以使用 nni.experiment.Experiment.view() 重新启动网页控制台。

小技巧

本教程使用 Python API 创建实验, 除此之外您也可以选择使用 命令行工具

Total running time of the script: ( 1 minutes 24.367 seconds)

Gallery generated by Sphinx-Gallery