超參數微調模型 (2)

適用於:Azure CLI ml 延伸模組 v2 (目前)Python SDK azure-ai-ml v2 (目前)

使用 Azure Machine Learning SDK 第 2 版和 CLI 第 2 版,透過 SweepJob 類型,自動進行有效率的超參數微調。

  1. 定義參數搜尋空間供您試用
  2. 指定掃掠作業的取樣演算法
  3. 指定最佳化目標
  4. 指定表現不佳工作的提早終止原則
  5. 定義掃掠作業的限制
  6. 使用定義的設定啟動實驗
  7. 將定型作業視覺化
  8. 選取最適合您模型的設定

什麼是超參數微調?

超參數是可調整的參數,可讓您控制模型定型流程。 例如,使用神經網路時,您可以決定隱藏層的數目和每個圖層中的節點數目。 模型效能主要取決於超參數。

超參數微調也稱為超參數最佳化,是尋找產生最佳效能之超參數設定的過程。 此程序通常耗費昂貴的計算成本,而且是手動操作。

Azure Machine Learning 可讓您將超參數微調自動化,並平行執行實驗,以有效率地最佳化超參數。

定義搜尋空間

藉由探索為每個超參數定義的值範圍,來微調超參數。

超參數可以是離散或連續的,而且具有參數運算式描述的值分佈。

離散超參數

離散超參數會指定為離散值之間的一個 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) - 傳回以平均值 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_probabilitylearning_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 Machine Learning 支援以下方法:

  • 隨機取樣
  • 格線取樣
  • 貝氏取樣

隨機取樣

隨機取樣支援離散和連續超參數。 這支援提早終止表現不佳的作業。 有些使用者會透過隨機取樣進行初始搜尋,然後縮小搜尋空間範圍來改善結果。

在隨機取樣中,超參數值會從定義的搜尋空間隨機選取。 建立命令作業之後,您可以使用 sweep 參數來定義取樣演算法。

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 超參數。 例如,下列空間共有六個樣本:

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 倍。

同時作業的數目會影響微調流程的效果。 較少的同時作業可讓取樣收斂得更好,因為平行程度較低可讓更多作業受益於先前完成的作業。

貝氏取樣僅支援搜尋空間上的 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 Machine Learning 定型作業中啟用記錄

指定提前終止原則

使用提早終止原則自動結束表現不佳的作業。 提早終止可改善計算效率。

您可以設定下列參數來控制何時套用原則:

  • evaluation_interval:套用原則的頻率。 每次定型指令碼記錄主要計量都算是一個間隔。 evaluation_interval 為 1,表示每當定型指令碼回報主要計量時,就會套用原則。 evaluation_interval 為 2,表示將每隔一段時間就套用原則。 如果未指定,evaluation_interval 預設為 0。
  • delay_evaluation:將第一次原則評估延遲到指定間隔數目之後。 這是選擇性參數,允許以最少間隔數執行所有設定,以避免過早終止定型作業。 如果指定,則會每隔 evaluation_interval (大於或等於 delay_evaluation) 的倍數套用原則一次。 如果未指定,delay_evaluation 預設為 0。

Azure Machine Learning 支援下列提早終止原則:

Bandit 原則

Bandit 原則是以寬限時間因數/寬限時間數量,以及評估間隔為基準。 如果主要計量不在最成功作業已指定的寬限因數/寬限量內,Bandit 原則會結束作業。

指定下列設定參數︰

  • slack_factorslack_amount:相對於表現最佳的定型作業而允許的寬限。 slack_factor 將允許的寬限時間指定為小數比。 slack_amount 將允許的寬限時間指定為絕對數量,而不是小數比。

    例如,請考慮在間隔 10 套用的 Bandit 原則。 假設在第 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% (取決於我們的評估資料)。
  • 若要更積極地節省成本,請使用 Bandit 原則,其提供較小的允許寬限時間,或較大截斷百分比的截斷選取原則。

設定掃掠作業的限制

設定掃掠作業的限制來控制資源預算。

  • 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 個試用作業,每次執行四個試用作業,整個掃掠作業的逾時為 1200 秒。

設定超參數微調實驗

若要設定您的超參數微調實驗,請提供下列各項:

  • 定義的超參數搜尋空間
  • 取樣演算法
  • 您的提早終止原則
  • 目標
  • 資源限制
  • CommandJob 或 CommandComponent
  • SweepJob

SweepJob 可以在 Command 或 Command 元件上執行超參數掃掠。

注意

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.windows.net/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 Machine Learning 管線或手動流程,在定型作業之前盡可能做好資料準備,將此成本降到最低。

提交超參數微調實驗

定義超參數微調設定之後,請提交作業

# 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 Machine Learning 工作室中將所有超參數微調作業視覺化。 如需如何在入口網站中檢視實驗的詳細資訊,請參閱在工作室中檢視作業記錄

  • 計量圖表:此視覺效果在超參數微調期間,追蹤針對每個 hyperdrive 子作業所記錄的計量。 每條線代表一個子作業,每個點測量執行階段在這次反覆運算的主要計量值。

    Hyperparameter tuning metrics chart

  • 平行座標圖:此視覺效果會顯示主要計量效能和個別超參數值之間的相互關聯。 此圖表是透過軸移動的互動方式 (按一下並拖曳軸標籤),以及藉由在單一軸上反白顯示值 (按一下,然後沿著單一軸垂直拖曳,以反白顯示所需值的範圍)。 平行座標圖在圖表最右側有一個軸,其繪製與該作業執行個體的超參數集相對應的最佳計量值。 提供此軸的目的是要以更容易閱讀的方式,將圖表梯度圖例投射到資料上。

    Hyperparameter tuning parallel coordinates chart

  • 2D 散佈圖:此視覺效果會顯示任何兩個個別超參數與其相關聯的主要計量值之間的相互關聯。

    Hyparameter tuning 2-dimensional scatter chart

  • 3D 散佈圖:此視覺效果與 2D 相同,但允許三個超參數維度與主要計量值的相互關聯。 您也可以按一下並拖曳,藉此重新定向圖表以在3D 空間中檢視不同的相互關聯。

    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

參考資料

下一步