Ajuste de hiperparámetros de un modelo (v2)

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 eficaz de hiperparámetros con el SDK v2 de Azure Machine Learning y la CLI v2 mediante la clase SweepJob.

  • Definición del espacio de búsqueda de parámetros
  • Elección de un algoritmo de muestreo
  • Establecimiento del objetivo de optimización
  • Configuración de una directiva de terminación anticipada
  • Establecer límites de tareas de barrido
  • Envío del experimento
  • Visualización de tareas de entrenamiento
  • Selección de la mejor configuración

Antes de empezar

Antes de ejecutar un trabajo de barrido, asegúrese de que tiene:

  • Un área de trabajo de Azure Machine Learning y un destino de proceso, como un clúster de CPU.
  • Script de entrenamiento que registra la métrica objetivo con el nombre exacto usado en primary_metric.
  • El Azure ML SDK v2 instalado en su entorno de Python y autenticado mediante DefaultAzureCredential o az login.
  • La CLI de Azure y la extensión de la CLI de Azure ML se instalan si utilizas los ejemplos basados en YAML de este artículo.

Los ejemplos de este artículo presuponen que existe un espacio de trabajo y un destino de proceso existentes a los que el usuario actual puede acceder.

¿Qué es el ajuste de hiperparámetros?

Los hiperparámetros son valores ajustables que controlan el entrenamiento del modelo. En el caso de las redes neuronales, elija el número de capas ocultas y el número de nodos por capa. El rendimiento del modelo depende en gran medida de estos valores.

El ajuste de hiperparámetros (o la optimización de hiperparámetros) es el proceso de búsqueda de la configuración de hiperparámetros que produce el mejor rendimiento. Este proceso suele ser costoso de cálculo y manual.

Azure Machine Learning automatiza el ajuste de hiperparámetros y ejecuta experimentos en paralelo para optimizar de forma eficaz los hiperparámetros.

Definición del espacio de búsqueda

Ajuste automáticamente los hiperparámetros explorando el rango de valores definidos para cada hiperparámetro.

Los hiperparámetros pueden ser discretos o continuos y pueden tener una distribución de valores expresada con una expresión de parámetro.

Hiperparámetros discretos

Especifique hiperparámetros discretos como un Choice entre valores discretos. Choice puede ser:

  • uno o más valores separados por comas;
  • un objeto range;
  • cualquier objeto list arbitrario.
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)),
)

Referencias:

En este caso, batch_size toma uno de [16, 32, 64, 128] y number_of_hidden_layers toma uno de [1, 2, 3, 4].

También puede especificar los siguientes hiperparámetros discretos avanzados mediante una distribución:

  • QUniform(min_value, max_value, q) : devuelve un valor como round(Uniform(min_value, max_value) / q) * q.
  • QLogUniform(min_value, max_value, q) : devuelve un valor como round(exp(Uniform(min_value, max_value)) / q) * q.
  • QNormal(mu, sigma, q) : devuelve un valor como round(Normal(mu, sigma) / q) * q.
  • QLogNormal(mu, sigma, q) : devuelve un valor como round(exp(Normal(mu, sigma)) / q) * q.

Hiperparámetros continuos

Especifique hiperparámetros continuos como una distribución a través de un intervalo continuo de valores:

  • Uniform(min_value, max_value) : devuelve un valor distribuido uniformemente entre min_value y max_value.
  • LogUniform(min_value, max_value) : devuelve un valor dibujado según exp(Uniform(min_value, max_value)) para que el logaritmo del valor devuelto se distribuya uniformemente.
  • Normal(mu, sigma) - Devuelve un valor real que sigue una distribución normal con media sigma y desviación estándar mu.
  • LogNormal(mu, sigma) : devuelve un valor dibujado según exp(Normal(mu, sigma)) para que el logaritmo del valor devuelto se distribuya normalmente.

El siguiente es un ejemplo de definición de espacio de parámetros:

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

Referencias:

Este código define un espacio de búsqueda con dos parámetros: learning_rate y keep_probability. learning_rate tiene una distribución normal con un valor medio de 10 y una desviación estándar de 3. keep_probability tiene una distribución uniforme con un valor mínimo de 0,05 y un valor máximo de 0,1.

Para la CLI, use el esquema YAML del trabajo de limpieza para definir el espacio de búsqueda:

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

Muestreo del espacio de hiperparámetros

Especifique el método de muestreo para el espacio de hiperparámetros. Azure Machine Learning admite las siguientes funcionalidades:

  • Muestreo aleatorio
  • Muestreo de cuadrícula
  • Muestreo bayesiano

Muestreo aleatorio

El muestreo aleatorio admite hiperparámetros discretos y continuos y admite la finalización anticipada de trabajos de bajo rendimiento. Muchos usuarios comienzan con el muestreo aleatorio para identificar regiones prometedores y, a continuación, refinar.

En el muestreo aleatorio, los valores se extraen uniformemente (o a través de la regla aleatoria especificada) desde el espacio de búsqueda definido. Después de crear el trabajo de comando, use sweep para definir el algoritmo de muestreo.

from azure.ai.ml.entities import CommandJob
from azure.ai.ml.sweep import RandomSamplingAlgorithm, SweepJob, SweepJobLimits

   command_job = CommandJob(
       inputs=dict(kernel="linear", penalty=1.0),
       compute=cpu_cluster,
       environment=f"{job_env.name}:{job_env.version}",
       code="./scripts",
       command="python scripts/train.py --kernel $kernel --penalty $penalty",
       experiment_name="sklearn-iris-flowers",
   )

   sweep = SweepJob(
       sampling_algorithm=RandomSamplingAlgorithm(seed=999, rule="sobol", logbase="e"),
       trial=command_job,
       search_space={"ss": Choice(type="choice", values=[{"space1": True}, {"space2": True}])},
       inputs={"input1": {"file": "top_level.csv", "mode": "ro_mount"}},  # type:ignore
       compute="top_level",
       limits=SweepJobLimits(trial_timeout=600),
   )

Referencias:

Sobol

Sobol es una secuencia casi aleatoria que mejora el llenado de espacio y la reproducibilidad. Proporcione una semilla y establezca rule="sobol" en RandomSamplingAlgorithm.

from azure.ai.ml.sweep import  RandomSamplingAlgorithm

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

Referencias: RandomSamplingAlgorithm

Muestreo de cuadrícula

El muestreo de cuadrícula admite hiperparámetros discretos. Use el muestreo de cuadrícula si su presupuesto le permite buscar en el espacio de búsqueda de manera exhaustiva. Admite la terminación anticipada de los trabajos de bajo rendimiento.

El muestreo de cuadrícula realiza una búsqueda de cuadrícula sencilla sobre todos los valores posibles. El muestreo de cuadrícula solo se puede usar con hiperparámetros de choice. Por ejemplo, el siguiente espacio tiene seis muestras:

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",
    ...
)

Referencias: Opción

Muestreo bayesiano

El muestreo bayesiano (optimización bayesiana) selecciona nuevas muestras en función de los resultados anteriores para mejorar la métrica principal de forma eficaz.

Use el muestreo bayesiano si tiene suficiente presupuesto para explorar el espacio de hiperparámetros. Para obtener los mejores resultados, establezca el número máximo de trabajos en al menos 20 veces el número de hiperparámetros que está ajustando.

El número de trabajos simultáneos afecta a la eficacia del proceso de optimización. Un número menor de trabajos simultáneos podría dar lugar a una mejor convergencia de muestreo. El menor grado de paralelismo aumenta el número de trabajos que se benefician de los trabajos completados anteriormente.

El muestreo bayesiano admite las distribuciones choice, uniform y quniform.

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",
    ...
)

Referencias:

Especificación del objetivo del barrido

Para definir el objetivo del trabajo de limpieza especifique la métrica principal y el objetivo que quiere que el ajuste de hiperparámetros optimice. En cada trabajo de entrenamiento se evalúa la métrica principal. La directiva de terminación anticipada usa la métrica principal para identificar los trabajos de bajo rendimiento.

  • primary_metric: el nombre de la métrica principal debe coincidir exactamente con el nombre de la métrica registrada por el script de entrenamiento.
  • goal: puede ser maximize o minimize y determina si la métrica principal está maximizada o minimizada al evaluar los trabajos.
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",
)

Referencias:

Esta muestra maximiza la "precisión".

Registrar métricas para el ajuste de hiperparámetros

El script de entrenamiento debe registrar la métrica principal con el nombre exacto esperado por la tarea de barrido.

Registre la métrica principal en el script de entrenamiento mediante el siguiente fragmento de código de ejemplo:

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

Referencias: mlflow.log_metric

El script de entrenamiento calcula el parámetro val_accuracy y lo registra como la métrica principal de "precisión". Cada vez que se registra la métrica, el servicio de optimización de hiperparámetros lo recibe. Decida con qué frecuencia notificar la métrica.

Para obtener más información sobre cómo registrar valores en trabajos de entrenamiento, consulte Habilitar el registro en trabajos de entrenamiento de Azure Machine Learning.

Especificación de una directiva de terminación anticipada

Terminar los trabajos con un rendimiento deficiente temprano para mejorar la eficiencia.

Puede configurar los siguientes parámetros que controlan cuándo se aplica una directiva:

  • evaluation_interval: la frecuencia con que se aplica la directiva. Cada vez que el script de entrenamiento registra la métrica principal se considera un intervalo. Un evaluation_interval de 1 hace que se aplique la directiva cada vez que el script de entrenamiento informa de la métrica principal. Un evaluation_interval de 2 aplica la directiva una de cada dos veces.
  • delay_evaluation: retrasa la primera evaluación de la directiva un número especificado de intervalos. Este parámetro opcional evita la terminación prematura de los trabajos de entrenamiento al permitir que todas las configuraciones se ejecuten durante un número mínimo de intervalos. Si se especifica, la directiva aplica cada múltiplo de evaluation_interval que es mayor o igual que delay_evaluation. Si no se especifica, delay_evaluation el valor predeterminado es 0.

El valor predeterminado evaluation_interval depende de la directiva de terminación anticipada que elija.

Azure Machine Learning admite las siguientes directivas de terminación anticipada:

Directiva de bandidos

La política Bandit utiliza un factor de margen o una cantidad de margen, junto con un intervalo de evaluación. Finaliza un trabajo cuando su métrica principal está fuera del margen de demora permitido del trabajo óptimo.

Especifique los siguientes parámetros de configuración:

  • slack_factor o slack_amount: Diferencia permitida respecto al mejor trabajo. slack_factor es una relación; slack_amount es un valor absoluto.

    Por ejemplo, imagine que se aplica una directiva de bandidos en el intervalo 10. Supongamos que la tarea con mejor rendimiento en el intervalo 10 registró una métrica principal de 0,8, con el objetivo de maximizar la métrica principal. Si la directiva especifica un slack_factor valor de 0,2, la directiva finaliza los trabajos de entrenamiento cuya mejor métrica en el intervalo 10 es menor que 0,66 (0,8/(1+slack_factor)).

  • evaluation_interval: la frecuencia con que se aplica la directiva (opcional)

  • delay_evaluation: retrasa la primera evaluación de la directiva un número especificado de intervalos (opcional)

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

Referencias: BanditPolicy

En este ejemplo, se aplica la directiva de terminación anticipada en cada intervalo cuando se notifican las métricas, comenzando en el intervalo de evaluación 5. La política detiene los trabajos cuya mejor métrica sea inferior a (1/(1+0.1)) o al 91 % de la de los trabajos con mejor rendimiento.

Directiva de mediana de detención

La política de detención por mediana es una política de terminación anticipada que utiliza los promedios acumulados de las métricas primarias notificadas por los trabajos. Esta directiva calcula las medias móviles en todos los trabajos de entrenamiento y detiene los trabajos cuyo valor de métrica principal sea peor que la mediana de los promedios.

Esta directiva toma los parámetros de configuración siguientes:

  • evaluation_interval: frecuencia con la que se aplica la directiva (opcional).
  • delay_evaluation: número de intervalos para retrasar la primera evaluación de directiva (opcional).
from azure.ai.ml.sweep import MedianStoppingPolicy
sweep_job.early_termination = MedianStoppingPolicy(delay_evaluation = 5, evaluation_interval = 1)

Referencias: MedianStoppingPolicy

En este ejemplo, se aplica la directiva de terminación anticipada en cada intervalo, comenzando en el intervalo de evaluación 5. Un trabajo se interrumpe en el intervalo 5 si su mejor métrica principal es peor que la mediana de las medias acumuladas desde el intervalo 1 hasta el 5 de todos los trabajos de entrenamiento.

Directiva de selección de truncamiento

La directiva de selección de truncamiento cancela un porcentaje de los trabajos con peor rendimiento en cada intervalo de evaluación. Los trabajos se comparan mediante la métrica principal.

Esta directiva toma los parámetros de configuración siguientes:

  • truncation_percentage: el porcentaje de trabajos con rendimiento más bajo que se terminarán en cada intervalo de evaluación. Un valor entero comprendido entre 1 y 99.
  • evaluation_interval: frecuencia con la que se aplica la directiva (opcional).
  • delay_evaluation: número de intervalos para retrasar la primera evaluación de directiva (opcional).
from azure.ai.ml.sweep import TruncationSelectionPolicy
sweep_job.early_termination = TruncationSelectionPolicy(
    evaluation_interval=1,
    truncation_percentage=20,
    delay_evaluation=5,
)

Referencias: TruncationSelectionPolicy

En este ejemplo, se aplica la directiva de terminación anticipada en cada intervalo, comenzando en el intervalo de evaluación 5. Un trabajo finaliza en el intervalo 5 si su rendimiento en el intervalo 5 está en los 20% más bajos del rendimiento de todos los trabajos en el intervalo 5.

Sin directiva de terminación (predeterminado)

Si no especifica una política, el servicio de ajuste de hiperparámetros permite que todos los trabajos de entrenamiento se ejecuten hasta su finalización.

sweep_job.early_termination = None

Referencias: SweepJob

Elegir una política de terminación anticipada

  • Para una política conservadora que ahorra recursos sin interrumpir trabajos prometedores, considere usar una política de detención por mediana con evaluation_interval configurado en 1 y delay_evaluation configurado en 5. Esta configuración es conservadora y puede proporcionar aproximadamente 25%-35% ahorro sin pérdida en la métrica principal, en función de los datos de evaluación.
  • Para lograr un ahorro más significativo, utiliza una directiva Bandit con un margen de tolerancia menor o una directiva de selección por truncamiento con un porcentaje de truncamiento mayor.

Establecimiento de límites para el trabajo de barrido

Controle el presupuesto de recursos estableciendo límites para el trabajo de barrido.

  • max_total_trials: número máximo de trabajos de prueba. Debe ser un entero entre 1 y 1000.
  • max_concurrent_trials: número máximo de trabajos que se pueden ejecutar simultáneamente (opcional). Si no se especifica, max_total_trials es el número de trabajos que se inician en paralelo. Si se especifica, el tiempo de espera debe ser un entero comprendido entre 1 y 1000.
  • timeout: el tiempo máximo en segundos durante el que se puede ejecutar todo el trabajo de barrido. Una vez alcanzado este límite, el sistema cancela el trabajo de barrido, incluidas todas sus pruebas.
  • trial_timeout: el tiempo máximo en segundos durante el que se puede ejecutar cada trabajo de prueba. Una vez alcanzado este límite, el sistema cancela la prueba.

Nota:

Si se especifican max_total_trials y timeout, el experimento de ajuste de hiperparámetros finaliza cuando se alcanza el primero de estos dos umbrales.

Nota:

El número de trabajos simultáneos viene determinado por los recursos disponibles en el destino de proceso especificado. Asegúrese de que el destino de proceso tenga los recursos disponibles para la simultaneidad deseada.

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

Referencias: SweepJob.set_limits

Este código configura el experimento de ajuste de hiperparámetros para usar un máximo total de 20 trabajos de prueba, con la ejecución de cuatro trabajos de prueba a la vez y un tiempo de espera de 1200 segundos para todo el trabajo de barrido.

Configuración del experimento de ajuste de hiperparámetros

Para configurar el experimento de ajuste de hiperparámetros, proporcione la siguiente información:

  • El espacio de búsqueda de hiperparámetros definido
  • Algoritmos de muestreo
  • Una directiva de terminación anticipada
  • Su objetivo
  • Límites de recursos
  • CommandJob o CommandComponent
  • SweepJob

SweepJob puede ejecutar un barrido de hiperparámetros en el comando o el componente de comando.

Nota:

El destino de proceso usado en sweep_job debe tener suficientes recursos para satisfacer el nivel de simultaneidad. Para obtener más información sobre los destinos de cálculo, consulte Destinos de cálculo.

Configure el experimento de ajuste de hiperparámetros:

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
)

Referencias:

command_job se invoca como una función para que pueda aplicar expresiones de parámetro. Configure la sweep función con trial, algoritmo de muestreo, objetivo, límites y proceso. El fragmento de código siguiente procede del cuaderno de ejemplo Ejecutar una búsqueda de hiperparámetros en un Command o CommandComponent. En este ejemplo, ajusta learning_rate y boosting. El MedianStoppingPolicy determina la detención anticipada. Esta directiva detiene un trabajo cuya métrica principal es peor que la mediana de promedios de ejecución en todos los trabajos. Para obtener más información, consulte la referencia de MedianStoppingPolicy.

Para ver cómo se reciben, analizan y pasan los valores de parámetro al script de entrenamiento para la optimización, consulte este ejemplo de código.

Importante

Cada trabajo de barrido de hiperparámetros reinicia el entrenamiento desde cero, lo que incluye volver a generar el modelo y todos los cargadores de datos. Puede minimizar este costo mediante una canalización de Azure Machine Learning o un proceso manual para realizar la preparación de datos tanto como sea posible antes de los trabajos de entrenamiento.

Envío del experimento de ajuste de hiperparámetros

Tras definir la configuración de ajuste de hiperparámetros, envíe el trabajo:

# 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

Referencias:

Visualización de los trabajos de ajuste de hiperparámetros

Visualización de trabajos de ajuste de hiperparámetros en Azure Machine Learning Studio. Para obtener más información, consulte Ver registros de trabajos en el studio.

  • Gráfico de métricas: esta visualización realiza un seguimiento de las métricas registradas para cada trabajo secundario de Hyperdrive durante el ajuste de hiperparámetros. Cada línea representa un trabajo secundario y cada punto mide el valor de la métrica principal en esa iteración del tiempo de ejecución.

    Gráfico de métricas de ajuste de hiperparámetros

  • Gráfico de coordenadas paralelas: esta visualización muestra la correlación entre el rendimiento de las métricas principales y los valores de hiperparámetros individuales. El gráfico es interactivo mediante el movimiento de ejes (seleccionar y arrastrar por la etiqueta del eje) y resaltando los valores en un solo eje (seleccione y arrastre verticalmente a lo largo de un solo eje para resaltar un intervalo de valores deseados). El gráfico de coordenadas paralelas incluye un eje en la parte superior derecha del gráfico que traza el mejor valor de métrica correspondiente a los hiperparámetros establecidos para esa instancia de trabajo. Este eje se proporciona para proyectar la leyenda de degradado del gráfico en los datos de forma más legible.

    Gráfico de coordenadas paralelas de ajuste de hiperparámetros

  • Gráfico de dispersión de dos dimensiones: esta visualización muestra la correlación entre dos hiperparámetros individuales junto con su valor de métrica principal asociado.

    Gráfico de dispersión de dos dimensiones de ajuste de hiperparámetros

  • Gráfico de dispersión de tres dimensiones: esta visualización es la misma que la de 2D, pero permite tres dimensiones de hiperparámetros de correlación con el valor de métrica principal. También puede seleccionar y arrastrar para volver a orientar el gráfico para ver diferentes correlaciones en el espacio 3D.

    Gráfico de dispersión de tres dimensiones de ajuste de hiperparámetros

Búsqueda del mejor trabajo de prueba

Cuando finalicen todos los trabajos de optimización, recupere las mejores salidas de prueba:

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

Referencias:

Use la CLI para descargar todas las salidas predeterminadas y las salidas con nombre de la mejor ejecución de prueba, así como los registros del trabajo de barrido.

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

Opcionalmente, descargue solo la mejor salida de prueba:

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

Referencias

Pasos siguientes