次の方法で共有


パイプラインでハイパーパラメーター調整を行う方法

適用対象:Azure CLI ml extension v2 (現行)Python SDK azure-ai-ml v2 (現行)

この記事では、Azure Machine Learning CLI v2 または Azure Machine Learning SDK for Python v2 を使用して、Azure Machine Learning パイプラインでのハイパーパラメーター調整を自動化する方法について説明します。

ハイパーパラメーターは、モデルのトレーニング プロセスを制御できるようにする調整可能なパラメーターです。 ハイパーパラメーターの調整は、最適なパフォーマンスを得られるハイパーパラメーターの構成を見つけるプロセスです。 Azure Machine Learning を使用すると、ハイパーパラメーターの調整を自動化し、実験を並列で行ってハイパーパラメーターを効率的に最適化できます。

前提条件

ハイパーパラメーター調整パイプラインを作成して実行する

次の例は、Azure Machine Learning の例リポジトリにある「パイプラインでスイープ (ハイパードライブ) を使用してパイプライン ジョブを実行する」に由来します。 コンポーネントを持つパイプラインの作成の詳細については、「Azure Machine Learning CLI でコンポーネントを使用して機械学習パイプラインを作成して実行する」を参照してください。

ハイパーパラメーター入力を持つコマンド コンポーネントを作成する

Azure Machine Learning パイプラインには、ハイパーパラメーター入力を持つコマンド コンポーネントが必要です。 サンプル プロジェクトの次の train.yml ファイルでは、ハイパーパラメーターの入力 c_valuekernelcoef を持つ trial コンポーネントを定義し、./train-src フォルダーにあるソース コードを実行します。

$schema: https://azuremlschemas.azureedge.net/latest/commandComponent.schema.json
type: command

name: train_model
display_name: train_model
version: 1

inputs: 
  data:
    type: uri_folder
  c_value:
    type: number
    default: 1.0
  kernel:
    type: string
    default: rbf
  degree:
    type: integer
    default: 3
  gamma:
    type: string
    default: scale
  coef0: 
    type: number
    default: 0
  shrinking:
    type: boolean
    default: false
  probability:
    type: boolean
    default: false
  tol:
    type: number
    default: 1e-3
  cache_size:
    type: number
    default: 1024
  verbose:
    type: boolean
    default: false
  max_iter:
    type: integer
    default: -1
  decision_function_shape:
    type: string
    default: ovr
  break_ties:
    type: boolean
    default: false
  random_state:
    type: integer
    default: 42

outputs:
  model_output:
    type: mlflow_model
  test_data:
    type: uri_folder
  
code: ./train-src

environment: azureml://registries/azureml/environments/sklearn-1.5/labels/latest

command: >-
  python train.py 
  --data ${{inputs.data}}
  --C ${{inputs.c_value}}
  --kernel ${{inputs.kernel}}
  --degree ${{inputs.degree}}
  --gamma ${{inputs.gamma}}
  --coef0 ${{inputs.coef0}}
  --shrinking ${{inputs.shrinking}}
  --probability ${{inputs.probability}}
  --tol ${{inputs.tol}}
  --cache_size ${{inputs.cache_size}}
  --verbose ${{inputs.verbose}}
  --max_iter ${{inputs.max_iter}}
  --decision_function_shape ${{inputs.decision_function_shape}}
  --break_ties ${{inputs.break_ties}}
  --random_state ${{inputs.random_state}}
  --model_output ${{outputs.model_output}}
  --test_data ${{outputs.test_data}}

試行コンポーネントのソース コードを作成する

この例のソース コードは、train.py ファイル 1 つです。 このコードは、スイープ ジョブ試行のすべてで実行されます。

# imports
import os
import mlflow
import argparse

import pandas as pd
from pathlib import Path

from sklearn.svm import SVC
from sklearn.model_selection import train_test_split

# define functions
def main(args):
    # enable auto logging
    mlflow.autolog()

    # setup parameters
    params = {
        "C": args.C,
        "kernel": args.kernel,
        "degree": args.degree,
        "gamma": args.gamma,
        "coef0": args.coef0,
        "shrinking": args.shrinking,
        "probability": args.probability,
        "tol": args.tol,
        "cache_size": args.cache_size,
        "class_weight": args.class_weight,
        "verbose": args.verbose,
        "max_iter": args.max_iter,
        "decision_function_shape": args.decision_function_shape,
        "break_ties": args.break_ties,
        "random_state": args.random_state,
    }

    # read in data
    df = pd.read_csv(args.data)

    # process data
    X_train, X_test, y_train, y_test = process_data(df, args.random_state)

    # train model
    model = train_model(params, X_train, X_test, y_train, y_test)
    # Output the model and test data
    # write to local folder first, then copy to output folder

    mlflow.sklearn.save_model(model, "model")

    from distutils.dir_util import copy_tree

    # copy subdirectory example
    from_directory = "model"
    to_directory = args.model_output

    copy_tree(from_directory, to_directory)

    X_test.to_csv(Path(args.test_data) / "X_test.csv", index=False)
    y_test.to_csv(Path(args.test_data) / "y_test.csv", index=False)


def process_data(df, random_state):
    # split dataframe into X and y
    X = df.drop(["species"], axis=1)
    y = df["species"]

    # train/test split
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.2, random_state=random_state
    )

    # return split data
    return X_train, X_test, y_train, y_test


def train_model(params, X_train, X_test, y_train, y_test):
    # train model
    model = SVC(**params)
    model = model.fit(X_train, y_train)

    # return model
    return model


def parse_args():
    # setup arg parser
    parser = argparse.ArgumentParser()

    # add arguments
    parser.add_argument("--data", type=str)
    parser.add_argument("--C", type=float, default=1.0)
    parser.add_argument("--kernel", type=str, default="rbf")
    parser.add_argument("--degree", type=int, default=3)
    parser.add_argument("--gamma", type=str, default="scale")
    parser.add_argument("--coef0", type=float, default=0)
    parser.add_argument("--shrinking", type=bool, default=False)
    parser.add_argument("--probability", type=bool, default=False)
    parser.add_argument("--tol", type=float, default=1e-3)
    parser.add_argument("--cache_size", type=float, default=1024)
    parser.add_argument("--class_weight", type=dict, default=None)
    parser.add_argument("--verbose", type=bool, default=False)
    parser.add_argument("--max_iter", type=int, default=-1)
    parser.add_argument("--decision_function_shape", type=str, default="ovr")
    parser.add_argument("--break_ties", type=bool, default=False)
    parser.add_argument("--random_state", type=int, default=42)
    parser.add_argument("--model_output", type=str, help="Path of output model")
    parser.add_argument("--test_data", type=str, help="Path of output model")

    # parse args
    args = parser.parse_args()

    # return args
    return args


# run script
if __name__ == "__main__":
    # parse args
    args = parse_args()

    # run main function
    main(args)

Note

パイプライン ファイルの primary_metric 値とまったく同じ名前で、試行コンポーネントのソース コードのメトリックをログに記録してください。 この例では、mlflow.autolog()を使用します。これは、機械学習の実験を追跡するために推奨される方法です。 MLflow の詳細については、「MLflow を使用して ML の実験とモデルを追跡する」を参照してください。

ハイパーパラメーター スイープ ステップを使用してパイプラインを作成する

train.yml で定義されているコマンド コンポーネントが与えられると、次のコードは 2 段階の trainpredict パイプライン定義ファイルを作成します。 sweep_step では、必要なステップの種類は sweep であり、c_valuekernel、および coef ハイパーパラメーターの trial コンポーネントに対する入力が search_space に追加されます。

次の例では、ハイパーパラメーター調整 sweep_step が強調表示されています。

$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
type: pipeline
display_name: pipeline_with_hyperparameter_sweep
description: Tune hyperparameters using TF component
settings:
    default_compute: azureml:cpu-cluster
jobs:
  sweep_step:
    type: sweep
    inputs:
      data: 
        type: uri_file
        path: wasbs://datasets@azuremlexamples.blob.core.windows.net/iris.csv
      degree: 3
      gamma: "scale"
      shrinking: False
      probability: False
      tol: 0.001
      cache_size: 1024
      verbose: False
      max_iter: -1
      decision_function_shape: "ovr"
      break_ties: False
      random_state: 42
    outputs:
      model_output:
      test_data:
    sampling_algorithm: random
    trial: ./train.yml
    search_space:
      c_value:
        type: uniform
        min_value: 0.5
        max_value: 0.9
      kernel:
        type: choice
        values: ["rbf", "linear", "poly"]
      coef0:
        type: uniform
        min_value: 0.1
        max_value: 1
    objective:
      goal: minimize
      primary_metric: training_f1_score
    limits:
      max_total_trials: 5
      max_concurrent_trials: 3
      timeout: 7200

  predict_step:
    type: command
    inputs:
      model: ${{parent.jobs.sweep_step.outputs.model_output}}
      test_data: ${{parent.jobs.sweep_step.outputs.test_data}}
    outputs:
      predict_result:
    component: ./predict.yml

完全スイープ ジョブ スキーマについては、「CLI (v2) スイープ ジョブの YAML スキーマ」を参照してください。

ハイパーパラメーター 調整パイプライン ジョブを送信する

このパイプライン ジョブを送信すると、Azure Machine Learning は、sweep_step に定義された検索空間と制限に基づいて、trial コンポーネントを複数回実行して、ハイパーパラメーターをスイープします。

スタジオでハイパーパラメーター調整の結果を表示する

パイプライン ジョブを送信すると、SDK または CLI ウィジェットによって、Azure Machine Learning スタジオ UI のパイプライン グラフへの Web URL リンクが表示されます。

ハイパーパラメーター調整の結果を表示するには、パイプライン グラフでスイープ ステップをダブルクリックし、詳細パネルで [子ジョブ] タブを選択し、子ジョブを選択します。

子ジョブのあるパイプラインと強調表示されている train_model ノードのスクリーンショット。

[子ジョブ] ページで [試行] タブを選択して、すべての子実行のメトリックを表示および比較します。 子実行のいずれかを選択すると、その実行の詳細が表示されます。

[試行] タブが表示された子ジョブ ページのスクリーンショット。

子実行に失敗した場合は、子実行ページの [出力 + ログ] タブを選択して、有用なデバッグ情報を表示できます。

[子実行] の [出力 + ログ] のスクリーンショット。