Compartir a través de


Conceptos de Hyperopt

Nota:

La versión de código abierto de Hyperopt ya no se mantiene.

Hyperopt se quitará en la siguiente versión principal de DBR ML. Azure Databricks recomienda usar Optuna para obtener una experiencia similar y acceder a algoritmos de ajuste de hiperparámetros más actualizados.

En este artículo se describen algunos de los conceptos que debe saber para usar Hyperopt distribuido.

En esta sección:

Para obtener ejemplos que ilustran cómo usar Hyperopt en Azure Databricks, vea Hyperopt.

fmin()

Usará fmin() para realizar una ejecución de Hyperopt. Los argumentos de fmin() se muestran en la tabla; consulte la documentación de Hyperopt para más información. Para ver ejemplos de cómo usar cada argumento, consulte los cuadernos de ejemplo.

Nombre de argumento Descripción
fn Función objective. Hyperopt llama a esta función con valores generados a partir del espacio de hiperparámetros proporcionado en el argumento de espacio. Esta función puede devolver la pérdida como un valor escalar o en un diccionario (consulte la documentación de Hyperopt para más información). Esta función normalmente contiene código para el entrenamiento del modelo y el cálculo de pérdida.
space Define el espacio de hiperparámetros que se buscará. Hyperopt proporciona una gran flexibilidad en cuanto a la forma de definir este espacio. Puede elegir una opción categórica, como algoritmo, o una distribución probabilística para valores numéricos, como uniforme y registro.
algo Algoritmo de búsqueda de Hyperopt que se usará para buscar en el espacio de hiperparámetros. Los más usados son hyperopt.rand.suggest para búsqueda aleatoria y hyperopt.tpe.suggest para TPE.
max_evals Número de configuraciones de hiperparámetros que se probarán (el número de modelos que caben).
max_queue_len Número de configuraciones de hiperparámetros que Hyperopt debe generar con antelación. Dado que el algoritmo de generación TPE de Hyperopt puede tardar algún tiempo, puede ser útil aumentarlo por encima del valor predeterminado de 1, pero generalmente no mayor que el valor parallelism de SparkTrials.
trials Un objeto Trials o SparkTrials. Use SparkTrials al llamar a algoritmos de una sola máquina, como los métodos scikit-learn, en la función objective. Use Trials cuando llame a algoritmos de entrenamiento distribuido, como métodos MLlib o Horovod en la función objective.
early_stop_fn Función de detención anticipada opcional para determinar si fmin debe detenerse antes de alcanzar max_evals. El valor predeterminado es None. La firma de entrada de la función es Trials, *args y la firma de salida es bool, *args. El valor booleano de salida indica si se debe detener o no. *args es cualquier estado, donde la salida de una llamada a early_stop_fn actúa como entrada para la siguiente llamada. Trials puede ser un objeto SparkTrials. Cuando se usa SparkTrials, no se garantiza que la función de detención temprana se ejecute después de cada prueba y, en su lugar, se sondea. Ejemplo de una función de detención temprana

La clase SparkTrials

SparkTrials es una API desarrollada por Databricks que permite distribuir una ejecución de Hyperopt sin realizar otros cambios en el código de Hyperopt. SparkTrials acelera el ajuste de una sola máquina mediante la distribución de pruebas a los nodos de trabajo de Spark.

Nota:

SparkTrialsestá diseñado para paralelizar los cálculos en modelos de ML de una sola máquina, como scikit-learn. En el caso de modelos creados con algoritmos de ML distribuido, como MLlib o Horovod, no use SparkTrials. En este caso, el proceso de creación de modelos se paraleliza automáticamente en el clúster y debe usar la clase Trials de Hyperopt predeterminada.

En esta sección se describe cómo configurar los argumentos que se pasan a SparkTrials y los aspectos de implementación de SparkTrials.

Argumentos

SparkTrials toma dos argumentos opcionales:

  • parallelism: número máximo de pruebas que se evaluarán simultáneamente. Un número mayor le permite escalar horizontalmente la prueba de más configuraciones de hiperparámetros. Dado que Hyperopt propone nuevas pruebas basadas en resultados pasados, hay un equilibrio entre el paralelismo y la adaptatividad. En el caso de un valor fijo de max_evals, a mayor paralelismo más rápidos son los cálculos, pero un paralelismo menor puede dar lugar a mejores resultados, ya que con cada iteración hay más acceso a más resultados anteriores.

    Valor predeterminado: número de ejecutores de Spark disponibles. Máximo: 128 Si el valor es mayor que el número de tareas simultáneas permitidas por la configuración del clúster, SparkTrials reduce el paralelismo a este valor.

  • timeout: número máximo de segundos que puede tardar una llamada a fmin(). Cuando se supera este número, todas las ejecuciones finalizan y fmin() se cierra. La información sobre las ejecuciones completadas se guarda.

Implementación

Al definir la función objective fn pasada a fmin() y seleccionar una configuración de clúster, resulta útil comprender cómo SparkTrials distribuye las tareas de optimización.

En Hyperopt, una prueba suele corresponder a ajustar un modelo en una configuración de hiperparámetros. Hyperopt genera de forma iterativa las pruebas, las evalúa y se repite.

Con SparkTrials, el nodo de controlador del clúster genera nuevas pruebas y los nodos de trabajo las evalúan. Cada prueba se genera con un trabajo de Spark que tiene una tarea y se evalúa en la tarea en una máquina de trabajo. Si el clúster está configurado para ejecutar varias tareas por trabajo, se pueden evaluar varias pruebas a la vez en ese trabajo.

SparkTrials y MLflow

ML de Databricks Runtime admite el registro en MLflow desde los nodos de trabajo. Puede agregar código de registro personalizado en la función objective que pasa a Hyperopt.

SparkTrials registra los resultados de optimización como ejecuciones de MLflow anidadas de la siguiente manera:

  • Ejecución principal o primaria: la llamada a fmin() se registra como la ejecución principal. Si hay una ejecución activa, SparkTrials se registra en ella y no finaliza la ejecución cuando se devuelve fmin(). Si no hay ninguna ejecución activa, SparkTrials crea una ejecución, la registra y la finaliza antes de que se devuelva fmin().
  • Ejecuciones secundarias: cada configuración de hiperparámetro probada (una "prueba") se registra como una ejecución secundaria en la ejecución principal. Las entradas de registro de MLflow de los nodos de trabajo también se almacenan en las ejecuciones secundarias correspondientes.

Al llamar a fmin(), Databricks recomienda la administración de ejecuciones activas de MLflow; es decir, encapsular la llamada a fmin() dentro de una instrucción with mlflow.start_run():. Así se garantiza que cada llamada a fmin() se registra en una ejecución principal de MLflow independiente y se facilita el registro de etiquetas, parámetros o métricas adicionales en esa ejecución.

Nota:

Cuando se llama a fmin() varias veces dentro de la misma ejecución activa de MLflow, MLflow registra esas llamadas en la misma ejecución principal. Para resolver conflictos de nombres de etiquetas y parámetros registrados, MLflow anexa un UUID a los nombres con conflictos.

Al realizar el registro desde los nodos de trabajo, no es necesario administrar las ejecuciones explícitamente en la función objective. Llame a mlflow.log_param("param_from_worker", x) en la función objective para registrar un parámetro en la ejecución secundaria. Puede registrar parámetros, métricas, etiquetas y artefactos en la función objective.