对模型进行超参数优化 (v2)

适用范围:Azure CLI ml 扩展 v2(最新版)Python SDK azure-ai-ml v2(最新版)

通过 SweepJob 类型使用 Azure 机器学习 SDK v2 和 CLI v2 自动执行高效的超参数优化。

  1. 为试用定义参数搜索空间
  2. 为扫描作业指定采样算法
  3. 指定要优化的对象
  4. 为低性能作业指定提前终止策略
  5. 定义扫描作业的限制
  6. 使用所定义的配置启动试验
  7. 将训练作业可视化
  8. 为模型选择最佳配置

什么是超参数优化?

超参数是可调整的参数,可用于控制模型训练过程。 例如,使用神经网络时,你决定隐藏层的数目以及每个层中的节点数。 模型性能很大程度上取决于超参数。

“超参数优化”(也称为“hyperparameter optimization”)是找到用于获得最佳性能的超参数配置的过程。 通常,该过程在计算方面成本高昂,并且是手动的。

Azure 机器学习使你能够自动执行超参数优化,并且并行运行试验以有效地优化超参数。

定义搜索空间

通过探索针对每个超参数定义的值范围来优化超参数。

超参数可以是离散的,也可以是连续的,并具有由参数表达式描述的值分布。

离散超参数

离散超参数将指定为离散值中的一个 ChoiceChoice 可以是:

  • 一个或多个逗号分隔值
  • range 对象
  • 任意 list 对象
from azure.ai.ml.sweep import Choice

command_job_for_sweep = command_job(
    batch_size=Choice(values=[16, 32, 64, 128]),
    number_of_hidden_layers=Choice(values=range(1,5)),
)

在这种情况下,batch_size 采用 [16、32、64、128] 中的一个值,number_of_hidden_layers 采用 [1、2、3、4] 中的一个值。

也可以使用一个分布来指定以下高级离散超参数:

  • QUniform(min_value, max_value, q) - 返回类似于 round(Uniform(min_value, max_value) / q) * q 的值
  • QLogUniform(min_value, max_value, q) - 返回类似于 round(exp(Uniform(min_value, max_value)) / q) * q 的值
  • QNormal(mu, sigma, q) - 返回类似于 round(Normal(mu, sigma) / q) * q 的值
  • QLogNormal(mu, sigma, q) - 返回类似于 round(exp(Normal(mu, sigma)) / q) * q 的值

连续超参数

将连续超参数指定为一个连续值范围内的分布:

  • Uniform(min_value, max_value) - 返回在 min_value 和 max_value 之间均匀分布的值
  • LogUniform(min_value, max_value) - 返回根据 exp(Uniform(min_value, max_value)) 绘制的值,使返回值的对数均匀分布
  • Normal(mu, sigma) - 返回正态分布的实际值,包括平均值 μ 和标准方差 σ
  • LogNormal(mu, sigma) - 返回根据 exp(Normal(mu, sigma)) 绘制的值,使返回值的对数呈正态分布

参数空间定义的示例:

from azure.ai.ml.sweep import Normal, Uniform

command_job_for_sweep = command_job(   
    learning_rate=Normal(mu=10, sigma=3),
    keep_probability=Uniform(min_value=0.05, max_value=0.1),
)

此代码定义具有两个参数(learning_ratekeep_probability)的搜索空间。 learning_rate 包含平均值为 10、标准偏差为 3 的正态分布。 keep_probability 包含最小值为 0.05、最大值为 0.1 的均匀分布。

对于 CLI,可以使用扫描作业 YAML 架构,在 YAML 中定义搜索空间:

    search_space:
        conv_size:
            type: choice
            values: [2, 5, 7]
        dropout_rate:
            type: uniform
            min_value: 0.1
            max_value: 0.2

超参数空间采样

指定参数采样方法来取代超参数空间。 Azure 机器学习支持以下方法:

  • 随机采样
  • 网格采样
  • 贝叶斯采样

随机采样

随机采样支持离散和连续超参数。 它支持提前终止低性能作业。 某些用户使用随机采样执行初始搜索,然后优化搜索空间来改善结果。

在随机采样中,超参数值是从定义的搜索空间中随机选择的。 创建命令作业后,可以使用扫描参数定义采样算法。

from azure.ai.ml.sweep import Normal, Uniform, RandomParameterSampling

command_job_for_sweep = command_job(   
    learning_rate=Normal(mu=10, sigma=3),
    keep_probability=Uniform(min_value=0.05, max_value=0.1),
    batch_size=Choice(values=[16, 32, 64, 128]),
)

sweep_job = command_job_for_sweep.sweep(
    compute="cpu-cluster",
    sampling_algorithm = "random",
    ...
)

Sobol

Sobol 是一种由扫描作业类型支持的随机采样类型。 可以通过 sobol 使用种子来重现结果,使其更均匀地覆盖搜索空间分布。

要使用 sobol,请使用 RandomParameterSampling 类添加种子和规则,如下例所示。

from azure.ai.ml.sweep import RandomParameterSampling

sweep_job = command_job_for_sweep.sweep(
    compute="cpu-cluster",
    sampling_algorithm = RandomParameterSampling(seed=123, rule="sobol"),
    ...
)

网格采样

网格采样支持离散超参数。 如果你的预算允许在搜索空间中彻底进行搜索,请使用网格采样。 支持提前终止低性能作业。

网格采样对所有可能的值进行简单的网格搜索。 网格采样只能与 choice 超参数一起使用。 例如,以下空间有 6 个样本:

from azure.ai.ml.sweep import Choice

command_job_for_sweep = command_job(
    batch_size=Choice(values=[16, 32]),
    number_of_hidden_layers=Choice(values=[1,2,3]),
)

sweep_job = command_job_for_sweep.sweep(
    compute="cpu-cluster",
    sampling_algorithm = "grid",
    ...
)

贝叶斯采样

贝叶斯采样基于贝叶斯优化算法。 它根据先前样本的表现情况来选取样本,以便新样本可以改善主要指标。

如果你有足够的预算来探索超参数空间,则建议使用贝叶斯采样。 为获得最佳结果,建议最大作业次数大于或等于正在优化的超参数数目的 20 倍。

并发作业的数目会影响优化过程的有效性。 数目较小的并发作业可能带来更好的采样收敛,因为较小的并行度会增加可从先前完成的作业中获益的作业数量。

Bayesian 采样仅支持搜索空间中的 choiceuniformquniform 分布。

from azure.ai.ml.sweep import Uniform, Choice

command_job_for_sweep = command_job(   
    learning_rate=Uniform(min_value=0.05, max_value=0.1),
    batch_size=Choice(values=[16, 32, 64, 128]),
)

sweep_job = command_job_for_sweep.sweep(
    compute="cpu-cluster",
    sampling_algorithm = "bayesian",
    ...
)

指定扫描的目标

通过指定希望超参数优化的主要指标和目标,定义扫描作业的目标。 将根据此主要指标评估每个训练作业。 提前终止策略使用主要指标来识别低性能作业。

  • primary_metric:主要指标的名称需要与训练脚本记录的指标的名称完全匹配。
  • goal:可以是 MaximizeMinimize,用于确定评估作业时主要指标是最大化还是最小化。
from azure.ai.ml.sweep import Uniform, Choice

command_job_for_sweep = command_job(   
    learning_rate=Uniform(min_value=0.05, max_value=0.1),
    batch_size=Choice(values=[16, 32, 64, 128]),
)

sweep_job = command_job_for_sweep.sweep(
    compute="cpu-cluster",
    sampling_algorithm = "bayesian",
    primary_metric="accuracy",
    goal="Maximize",
)

此示例最大程度地提高了“准确度”。

记录用于超参数优化的指标

模型的训练脚本必须在模型训练期间使用相同的相应指标名称记录主要指标,以便 SweepJob 可以访问以进行超参数优化。

使用以下示例代码片段在训练脚本中记录主要指标:

import mlflow
mlflow.log_metric("accuracy", float(val_accuracy))

训练脚本会计算 val_accuracy,并将其记录为主要指标“准确度”。 每次记录指标时,超参数优化服务都会收到该指标。 你需要确定报告频率。

有关为训练作业记录值的详细信息,请参阅在 Azure 机器学习训练作业中启用日志记录

指定提前终止策略

使用提前终止策略自动终止性能不佳的作业。 提前终止提高了计算效率。

你可以配置以下参数来控制何时应用该策略:

  • evaluation_interval:应用策略的频率。 每次训练脚本都会将主要指标计数记录为一个间隔。 如果 evaluation_interval 为 1,则训练脚本每次报告主要指标时,都会应用策略。 如果 evaluation_interval 为 2,则会每隔一次应用该策略。 如果未指定,则默认将 evaluation_interval 设置为 0。
  • delay_evaluation:将第一个策略评估延迟指定的间隔数。 这是一个可选参数,可让所有配置运行最小间隔数,避免训练作业过早终止。 如果已指定,则每隔大于或等于 delay_evaluation 的 evaluation_interval 倍数应用策略。 如果未指定,则默认将 delay_evaluation 设置为 0。

Azure 机器学习支持以下提前终止策略:

老虎机策略

老虎机策略基于松驰因子/松驰数量和评估间隔。 当主要指标不在最成功作业的指定松弛因子/松弛数量内时,Bandit 策略会结束作业。

指定以下配置参数:

  • slack_factorslack_amount:就性能最佳的训练作业而言允许的松弛度。 slack_factor 以比率的形式指定允许的松驰。 slack_amount 以绝对数量(而不是比率)的形式指定允许的松驰。

    例如,假设以间隔 10 应用老虎机策略。 另外,假设性能最佳的作业以间隔 10 报告了主要指标 0.8,目标是最大化主要指标。 如果策略指定的 slack_factor 为 0.2,则间隔为 10 时其最佳指标小于 0.66 (0.8/(1+slack_factor)) 的任何训练作业都会被终止。

  • evaluation_interval:(可选)应用策略的频率

  • delay_evaluation:(可选)将第一个策略评估延迟指定的间隔数

from azure.ai.ml.sweep import BanditPolicy
sweep_job.early_termination = BanditPolicy(slack_factor = 0.1, delay_evaluation = 5, evaluation_interval = 1)

在此示例中,指标报告时将在每个间隔应用提前终止策略,从评估间隔 5 开始。 其最佳指标小于最佳性能作业的 (1/(1+0.1) 或 91% 的任何作业将被终止。

中间值停止策略

中值停止是基于作业报告的主要指标的运行平均值的提前终止策略。 该策略计算所有训练作业的运行平均值,并终止其主要指标值低于平均值中值的作业。

此策略采用以下配置参数:

  • evaluation_interval:应用策略的频率(可选参数)。
  • delay_evaluation:将第一个策略评估延迟指定的间隔数(可选参数)。
from azure.ai.ml.sweep import MedianStoppingPolicy
sweep_job.early_termination = MedianStoppingPolicy(delay_evaluation = 5, evaluation_interval = 1)

在此示例中,将在每个间隔应用提前终止策略,从评估间隔 5 开始。 如果某个作业的最佳主要指标比所有训练运行中间隔 1:5 的运行平均值的中间值更差,则会在间隔 5 处终止该作业。

截断选择策略

截断选择在每个评估间隔取消给定百分比的性能最差的作业。 使用主要指标对作业进行比较。

此策略采用以下配置参数:

  • truncation_percentage:要在每个评估间隔终止的性能最低的作业百分比。 一个介于 1 到 99 之间的整数值。
  • evaluation_interval:(可选)应用策略的频率
  • delay_evaluation:(可选)将第一个策略评估延迟指定的间隔数
  • exclude_finished_jobs:指定在应用策略时是否排除已完成的作业
from azure.ai.ml.sweep import TruncationSelectionPolicy
sweep_job.early_termination = TruncationSelectionPolicy(evaluation_interval=1, truncation_percentage=20, delay_evaluation=5, exclude_finished_jobs=true)

在此示例中,将在每个间隔应用提前终止策略,从评估间隔 5 开始。 如果某个作业采用间隔 5 时的性能在采用间隔 5 的所有作业中处于 20% 的性能最低范围内,则会在间隔 5 处终止该作业,并将在应用策略时排除已完成的作业。

无终止策略(默认设置)

如果未指定策略,则超参数优化服务将让所有训练作业一直执行到完成。

sweep_job.early_termination = None

选择提前终止策略

  • 对于既可以节省成本又不会终止有前景的作业的保守策略,请考虑使用 evaluation_interval 为 1 且 delay_evaluation 为 5 的中间值停止策略。 这属于保守的设置,可以提供大约 25%-35% 的节省,且不会造成主要指标损失(基于我们的评估数据)。
  • 如果想节省更多成本,则可以使用老虎机策略或截断选择策略,因为前者的可用可宽延时间更短,后者的截断百分比更大。

为扫描作业设置限制

通过设置扫描作业的限制来控制资源预算。

  • max_total_trials:试用作业的最大数量。 必须是介于 1 到 1000 之间的整数。
  • max_concurrent_trials:(可选)可以并发运行的最大试用作业数。 如果未指定此项,则 max_total_trials 个作业将并行启动。 如果指定了此项,则它必须是介于 1 和 1000 之间的整数。
  • timeout:允许整个扫描作业运行的最长时间(秒)。 达到此限制后,系统将取消该扫描作业,包括其所有试运行。
  • trial_timeout:允许每个试用运行作业运行的最长时间(秒)。 达到此限制后,系统会取消该试运行。

注意

如果同时指定了 max_total_trials 和 timeout,则当达到这两个阈值中的第一个阈值时,超参数优化实验将终止。

注意

并发试用作业数根据指定计算目标中的可用资源进行限制。 请确保计算目标能够为所需的并发性提供足够的可用资源。

sweep_job.set_limits(max_total_trials=20, max_concurrent_trials=4, timeout=1200)

此代码将超参数优化实验配置为总共最多使用 20 个试用作业,一次运行 4 个试用作业,整个扫描作业的超时时间为 1200 秒。

配置超参数优化试验

若要配置超参数优化试验,请提供以下信息:

  • 所定义的超参数搜索空间
  • 采样算法
  • 你的提前终止策略
  • 目标
  • 资源限制
  • CommandJob 或 CommandComponent
  • SweepJob

SweepJob 可以对 Command 或 CommandComponent 运行超参数扫描。

注意

sweep_job 中使用的计算目标必须具有足够的资源来满足你的并发级别。 有关计算目标的详细信息,请参阅计算目标

配置超参数优化试验:

from azure.ai.ml import MLClient
from azure.ai.ml import command, Input
from azure.ai.ml.sweep import Choice, Uniform, MedianStoppingPolicy
from azure.identity import DefaultAzureCredential

# Create your base command job
command_job = command(
    code="./src",
    command="python main.py --iris-csv ${{inputs.iris_csv}} --learning-rate ${{inputs.learning_rate}} --boosting ${{inputs.boosting}}",
    environment="AzureML-lightgbm-3.2-ubuntu18.04-py37-cpu@latest",
    inputs={
        "iris_csv": Input(
            type="uri_file",
            path="https://azuremlexamples.blob.core.chinacloudapi.cn/datasets/iris.csv",
        ),
        "learning_rate": 0.9,
        "boosting": "gbdt",
    },
    compute="cpu-cluster",
)

# Override your inputs with parameter expressions
command_job_for_sweep = command_job(
    learning_rate=Uniform(min_value=0.01, max_value=0.9),
    boosting=Choice(values=["gbdt", "dart"]),
)

# Call sweep() on your command job to sweep over your parameter expressions
sweep_job = command_job_for_sweep.sweep(
    compute="cpu-cluster",
    sampling_algorithm="random",
    primary_metric="test-multi_logloss",
    goal="Minimize",
)

# Specify your experiment details
sweep_job.display_name = "lightgbm-iris-sweep-example"
sweep_job.experiment_name = "lightgbm-iris-sweep-example"
sweep_job.description = "Run a hyperparameter sweep job for LightGBM on Iris dataset."

# Define the limits for this sweep
sweep_job.set_limits(max_total_trials=20, max_concurrent_trials=10, timeout=7200)

# Set early stopping on this one
sweep_job.early_termination = MedianStoppingPolicy(
    delay_evaluation=5, evaluation_interval=2
)

command_job 作为函数调用,因此我们可以将参数表达式应用于扫描输入。 然后使用 trialsampling-algorithmobjectivelimitscompute 配置 sweep 函数。 上述代码片段取自示例笔记本 - 对 Command 或 CommandComponent 运行超参数扫描。 在此示例中,将优化 learning_rateboosting 参数。 作业的提前停止将由 MedianStoppingPolicy 决定,它会停止主要指标值低于所有训练作业的平均值中值的作业。(请参阅 MedianStoppingPolicy 类参考)。

要了解如何接收、分析参数值并将其传递给要优化的训练脚本,请参阅此代码示例

重要

每次超参数扫描作业都会从头开始重启训练,包括重新生成模型和所有数据加载器。 可以通过使用 Azure 机器学习管道或手动过程在训练作业之前尽可能多地准备数据来最大程度降低该成本。

提交超参数优化试验

定义超参数优化配置后,请提交作业

# submit the sweep
returned_sweep_job = ml_client.create_or_update(sweep_job)
# get a URL for the status of the job
returned_sweep_job.services["Studio"].endpoint

可视化超参数优化作业

可以将 Azure 机器学习工作室中的所有超参数优化作业可视化。 有关如何在门户中查看实验的详细信息,请参阅查看工作室中的作业记录

  • 指标图表:此可视化效果跟踪在超参数优化期间为每个超驱动器子作业记录的指标。 每行表示一个子作业,每个点在运行时的迭代中度量主要指标值。

    Hyperparameter tuning metrics chart

  • 并行坐标图:此可视化效果显示主要指标性能与单个超参数值之间的关联。 可通过这些方式与图表进行交互:移动轴(单击并拖动轴标签)以及在单个轴上突出显示值(单击并沿单个轴垂直拖动即可突出显示所需范围的值)。 在并行坐标图表的图表最右侧有一个轴,上面绘制了与为该作业实例设置的超参数相对应的最佳指标值。 提供此轴是为了以更可读的方式将图表渐变图例投影到数据上。

    Hyperparameter tuning parallel coordinates chart

  • 二维散点图:此可视化效果显示任意两个单独的超参数之间的关联以及它们对应的主要指标值。

    Hyparameter tuning 2-dimensional scatter chart

  • 三维散点图:此可视化效果与二维散点图相同,但可以显示三个超参数维度的关联和主要指标值。 还可以单击并拖动以调整图表,以在三维空间中查看不同的关联。

    Hyparameter tuning 3-dimensional scatter chart

查找最佳试用作业

完成所有超参数优化作业后,检索最佳试用输出:

# Download best trial model output
ml_client.jobs.download(returned_sweep_job.name, output_name="model")

可以使用 CLI 下载最佳试用作业的所有默认和命名输出以及扫描作业的日志。

az ml job download --name <sweep-job> --all

可选地,单独下载最佳试用输出

az ml job download --name <sweep-job> --output-name model

参考

后续步骤