OpenBayes 自动调参

最后更新于

自动调参是指通过为程序指定一系列参数的规约 parameter_specs 同时指定一个目标变量 hyperparameter_metric 并指定其最优解的方向(MAXIMIZEMINIMIZE)后,自动为特定的程序生成参数并获取 hyperparameter_metric 的过程。自动调参可以将工程师从繁琐的调参过程中解放出来。

为了使用自动调参需要做一下的工作:

  1. 明确自己程序的参数范围以及目标变量以配置的形式写入 openbayes.yaml
  2. 为自己的程序做以下修改:
    1. 让自己的代码支持从特定文件 openbayes_params.json 或者命令行参数读取生成的参数
    2. 在程序中通过 openbayestool.log_metric 记录特定的目标变量,记录的目标变量必须与配置保持一致

下面具体介绍这些步骤。

注意 自动调参是比较高阶的用法,使用自动调参的前提是你对 bayes 命令行工具有所了解,可以参考 bayes 命令行工具入门,同时需要了解 openbayes 配置文件

准备自动调参的配置

在通过 bayes gear init 将当前目录和容器绑定后目录下会出现文件 openbayes.yaml 内部初始化内容如下:

data_binding: []
resource: cpu
env: tensorflow-1.12
command: ""
hyper_tuning:
  max_job_count: 0
  parallel_count: 1
  hyperparameter_metric: ""
  goal: ""
  algorithm: ""
  parameter_specs: []

其中 hyper_tuning 下的参数就是自动调参所需要配置的内容:

  1. max_job_count 一次自动调参的尝试次数,最多支持 100 次
  2. parallel_count 并行的尝试个数受限于用户的单个资源类型的最大并行个数,通常是 1 或者 2
  3. hyperparameter_metric 目标变量
  4. goal 最优解的方向(MAXIMIZEMINIMIZE
  5. algorithm 采用的算法,支持 Bayesian RandomGrid
  6. parameter_specs 输入参数的规约

其中支持的算法:

算法 描述
Grid 对于只有 DISCRETE 以及 CATEGORICAL 类型参数的场景可以通过 GridSearch 遍历所有参数的组合
Random 针对 INTEGER 以及 DOUBLE 类型,依据其所支持的分布类型,在 min_valuemax_value 之间随机选择数值,对于 DISCRETECATEGORICAL 类型,其行为和 Grid 方式类似
Bayesian 每次生成参数时考虑之前的「参数」-「目标变量」的结果,通过更新后的分布函数提供参数以期望获取更好的结果,其算法可以参考该文章

这里展示一个完整的配置的样例:

data_binding: []
resource: cpu
env: tensorflow-1.12
command: "python main.py"
hyper_tuning:
  max_job_count: 3
  hyperparameter_metric: precision
  goal: MINIMIZE
  algorithm: Bayesian
  parameter_specs:
  - name: regularization
    type: DOUBLE
    min_value: 0.001
    max_value: 10.0
    scale_type: UNIT_LOG_SCALE
  - name: latent_factors
    type: INTEGER
    min_value: 5
    max_value: 50
    scale_type: UNIT_LINEAR_SCALE
  - name: unobs_weight
    type: DOUBLE
    min_value: 0.001
    max_value: 5.0
    scale_type: UNIT_LOG_SCALE
  - name: feature_wt_factor
    type: DOUBLE
    min_value: 1
    max_value: 200
    scale_type: UNIT_LOG_SCALE
  - name: level
    type: DISCRETE
    discrete_values: [1, 2, 3, 4]
  - name: category
    type: CATEGORICAL
    categorical_values: ["A", "B", "C"]

后文会介绍具体的 parameter_specs 类型。

修改自身代码以支持自动调参

1. 获取自动调参生成的参数

自动调参启动的任务可以通过两种方式获取其提供的参数:

  1. 读取 openbayes_params.json:如上的 parameter_specs 会生成四个参数,那么在容器的工作目录下会首先出现包含这些内容的 openbayes_params.json

    {
       "regularization": 6.933098216541059,
       "latent_factors": 29,
       "unobs_weight": 3.439490399012204,
       "feature_wt_factor": 102.9461653166788
    }
    

    读取该文件内的参数并使用即可

  2. 读取命令行参数:通过自动调参创建的任务其参数会以以下形式被添加到入口命令上:

    python main.py \
        --regularization=6.933 \
        --latent_factors=29 \
        --unobs_weight=3.439 \
        --feature_wt_factor=102.9
    

    采用 argparse 可以解析并使用这些参数。

2. 上报目标变量

系统指标与自定义指标 章节介绍了 openbayestool 工具有 log_metric 方法可以上报自定义的指标。自动调参同样采用这个工具即可实现指标的上报。在程序结束时通过以下代码即可实现上报:

import openbayestool

openbayestool.log_metric("precision", 0.809)

创建自动调参

在以上内容都准备好之后,通过命令 bayes gear run hypertuning 创建自动调参任务:

查看自动调参

如上所示,自动调参页面会通过「图表」「平行坐标」等方式展示当前执行的状况,用户可以通过结果选择最好的一次执行作为结果或者依据目前的结果更新自动调参参数范围后继续新的自动调参任务。

参数规约的定义

类型 数值范围 数据类型 描述
DOUBLE min_value - max_value 浮点型  
INTEGER min_value - max_value 整数  
CATEGORICAL   枚举类型 字符串
DISCRETE   离散类型 有顺序的数值

其中 INTEGERDOUBLE 类型还可以支持设定获取参数的分布类型(scale_type):

分布类型 描述
UNIT_LINEAR_SCALE 线性分布,指数据在 min_valuemax_value 是遵循均匀分布抽样
UNIT_LOG_SCALE LOG 分布,指 log(value) 在 min_valuemax_value 之间遵循均匀分布,也就是在抽样时,数值越小其抽样的密度越大,在使用 UNIT_LOG_SCALE 时 min_value 不能小于 0