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:
SparkTrials
está 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 demax_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 afmin()
. Cuando se supera este número, todas las ejecuciones finalizan yfmin()
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 devuelvefmin()
. Si no hay ninguna ejecución activa,SparkTrials
crea una ejecución, la registra y la finaliza antes de que se devuelvafmin()
. - 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.