Compartir vía


Cómo realizar el ajuste de hiperparámetros en la canalización

SE APLICA A:Extensión ML de la CLI de Azure v2 (actual)SDK de Python azure-ai-ml v2 (actual)

En este artículo, aprenderá a automatizar el ajuste de hiperparámetros en canalizaciones de Azure Machine Learning mediante la CLI de Azure Machine Learning v2 o el SDK de Azure Machine Learning para Python v2.

Los hiperparámetros son parámetros ajustables que permiten controlar el proceso de entrenamiento de un modelo. El ajuste de hiperparámetros es el proceso de encontrar la configuración de hiperparámetros que produzca el mejor rendimiento. Azure Machine Learning permite automatizar el ajuste de hiperparámetros y ejecutar experimentos en paralelo para optimizar los hiperparámetros de forma eficaz.

Requisitos previos

Creación y ejecución de una canalización de optimización de hiperparámetros

Los ejemplos siguientes proceden de Ejecución de un trabajo de canalización mediante barrido (hyperdrive) en la canalización en el repositorio de ejemplos de Azure Machine Learning. Para más información sobre cómo crear canalizaciones con componentes, consulte Creación y ejecución de canalizaciones de aprendizaje automático mediante componentes con la CLIde Azure Machine Learning.

Creación de un componente de comando con entradas de hiperparámetros

La canalización de Azure Machine Learning debe tener un componente de comando con entradas de hiperparámetros. El siguiente archivo train.yml de los proyectos de ejemplo define un trial componente que tiene las entradas de hiperparámetros c_value, kernel y coef y ejecuta el código fuente que se encuentra en la carpeta ./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}}

Creación del código fuente del componente de prueba

El código fuente de este ejemplo es un único archivo train.py. Este código se ejecuta en todas las pruebas del trabajo de barrido.

# 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)

Nota:

Asegúrese de registrar las métricas en el código fuente del componente de prueba con exactamente el mismo nombre que el primary_metric valor en el archivo de canalización. En este ejemplo se usa mlflow.autolog(), que es la manera recomendada de realizar un seguimiento de los experimentos de aprendizaje automático. Para más información sobre MLflow, consulte Seguimiento de experimentos y modelos de ML con MLflow.

Creación de una canalización con un paso de barrido de hiperparámetros

Dado el componente de comando definido en train.yml, el código siguiente crea un archivo de definición de canalización y predict dos pasos train. En sweep_step, el tipo de paso necesario es sweepy las entradas de hiperparámetros c_value, kernel y coef para el componente trial se agregan a search_space.

En el ejemplo siguiente se resalta el ajuste de hiperparámetros 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

Para obtener el esquema completo del trabajo de barrido, consulte Esquema YAML del trabajo de barrido de la CLI (v2).

Envío del trabajo de canalización de optimización de hiperparámetros

Después de enviar este trabajo de canalización, Azure Machine Learning ejecuta el componente trial varias veces para barrer los hiperparámetros, basándose en el espacio de búsqueda y los límites que haya definido en el archivo sweep_step.

Visualización de los resultados del ajuste de hiperparámetros en Studio

Después de enviar un trabajo de canalización, el SDK o el widget de la CLI proporciona un vínculo de dirección URL web al grafo de canalización en la interfaz de usuario de Azure Machine Learning Studio.

Para ver los resultados del ajuste de hiperparámetros, haga doble clic en el paso de barrido en el gráfico de canalización, seleccione la pestaña Trabajos secundarios en el panel de detalles y, a continuación, seleccione el trabajo secundario.

Captura de pantalla de la canalización con el trabajo secundario y el nodo train_model resaltado.

En la página trabajo secundario, seleccione la pestaña Pruebas para ver y comparar las métricas de todas las ejecuciones secundarias. Seleccione cualquiera de las ejecuciones secundarias para ver los detalles de esa ejecución.

Captura de pantalla de la página del trabajo secundario con la pestaña Pruebas.

Si se produjo un error en una ejecución secundaria, puede seleccionar la pestaña Salidas y registros de la página de ejecución secundaria para ver información útil de depuración.

Captura de pantalla de la pestaña de salida y registros de una ejecución hija.