Optimieren von Hyperparametern in Pipelines
GILT FÜR:Azure CLI ML-Erweiterung v2 (aktuell)
Python SDK azure-ai-ml v2 (aktuell)
In diesem Artikel erfahren Sie, wie Sie die Hyperparameteroptimierung in Azure Machine Learning-Pipelines mithilfe der Azure Machine Learning CLI v2 oder dem Azure Machine Learning SDK für Python v2 automatisieren.
Hyperparameter sind anpassbare Parameter, mit denen Sie den Modelltrainingsprozess steuern können. Bei der Hyperparameteroptimierung handelt es sich um den Prozess, bei dem nach der Hyperparameterkonfiguration gesucht wird, die eine optimale Leistung liefert. Mit Azure Machine Learning können Sie die Hyperparameteroptimierung automatisieren und Experimente parallel ausführen, um Hyperparameter effizient zu optimieren.
Voraussetzungen
- Sie verfügen über ein Azure Machine Learning-Konto und einen Arbeitsbereich.
- Sie sind mit Azure Machine Learning-Pipelines und der Hyperparameteroptimierung eines Modells vertraut.
Erstellen und Ausführen einer Pipeline zur Hyperparameteroptimierung
Die folgenden Beispiele stammen aus Ausführen eines Pipelineauftrags mithilfe des Sweepings (Hyperdrive) in einer Pipeline im Repository mit Azure Machine Learning-Beispielen. Weitere Informationen zum Erstellen von Pipelines mit Komponenten finden Sie unter Erstellen und Ausführen von Machine Learning-Pipelines mithilfe von Komponenten mit der Azure Machine Learning CLI.
Erstellen einer Befehlskomponente mit Hyperparametereingaben
Die Azure Machine Learning-Pipeline muss über eine Befehlskomponente mit Hyperparametereingaben verfügen. Die folgende Datei train.yml aus den Beispielprojekten definiert eine trial
-Komponente mit den Hyperparametereingaben c_value
, kernel
und coef
und führt den Quellcode im Ordner ./train-src aus.
$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}}
Erstellen des Quellcodes der Testkomponente
Der Quellcode für dieses Beispiel ist eine einzelne Datei train.py. Dieser Code wird bei jedem Test des Sweep-Auftrags ausgeführt.
# 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)
Hinweis
Achten Sie darauf, die Metriken im Quellcode der Testkomponente mit exakt demselben Namen wie dem primary_metric
-Wert in der Pipelinedatei zu erfassen. In diesem Beispiel wird mlflow.autolog()
verwendet. Dabei handelt es sich um die empfohlene Methode zum Nachverfolgen von Machine Learning-Experimenten. Weitere Informationen zu MLflow finden Sie unter Nachverfolgen von Machine Learning-Experimenten und -Modellen mit MLflow.
Erstellen einer Pipeline mit einem Schritt für das Hyperparameter-Sweeping
Der folgende Code erstellt anhand der in train.yml definierten Befehlskomponente eine Pipelinedefinitionsdatei mit den beiden Schritten train
und predict
. In sweep_step
lautet der erforderliche Schritttyp sweep
, und die Hyperparametereingaben c_value
, kernel
und coef
für die trial
-Komponente werden search_space
hinzugefügt.
Im folgenden Beispiel ist die Hyperparameteroptimierung von sweep_step
hervorgehoben.
$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
Ein vollständiges Schema für einen Sweep-Auftrag finden Sie unter CLI (v2): YAML-Schema von Sweep-Aufträgen.
Übermitteln des Pipelineauftrags für die Hyperparameteroptimierung
Nachdem Sie diesen Pipelineauftrag übermittelt haben, führt Azure Machine Learning die trial
-Komponente mehrmals aus, um da Sweeping für die Hyperparameter auf der Grundlage des Suchbereichs und der Grenzwerte, die Sie in sweep_step
definiert haben, durchzuführen.
Anzeigen der Ergebnisse der Hyperparameteroptimierung in Studio
Nachdem Sie einen Pipelineauftrag übermittelt haben, erhalten Sie vom SDK- oder CLI-Widget einen Web-URL-Link zum Pipelinediagramm auf der Benutzeroberfläche von Azure Machine Learning Studio.
Um die Ergebnisse der Hyperparameteroptimierung anzuzeigen, doppelklicken Sie im Pipelinediagramm auf den Sweep-Schritt. Wählen Sie anschließend im Detailbereich die Registerkarte Untergeordnete Aufträge und dann den untergeordneten Auftrag aus.
Wählen Sie auf der Seite des untergeordneten Auftrags die Registerkarte Testversionen aus, um Metriken für alle untergeordneten Ausführungen anzuzeigen und zu vergleichen. Wählen Sie eine der untergeordneten Ausführungen aus, um die zugehörigen Details anzuzeigen.
Wenn bei einer untergeordneten Ausführung ein Fehler aufgetreten ist, wählen Sie auf der Seite der untergeordneten Ausführung die Registerkarte Ausgaben und Protokolle aus, um nützliche Debuginformationen anzuzeigen.