Paralléliser le réglage des hyperparamètres Hyperopt
La version open source de Hyperopt n'est plus maintenue.
Hyperopt n'est pas inclus dans Databricks Runtime for Machine Learning après 16.4 LTS ML. Databricks recommande d'utiliser soit Optuna pour l'optimisation à nœud unique, soit RayTune pour une expérience similaire à la fonctionnalité obsolète d'ajustement distribué des hyperparamètres d'Hyperopt. En savoir plus sur l'utilisation de RayTune sur Databricks.
Ce Notebook d'exemple montre comment monter en charge l'ajustement des hyperparamètres sur une seule machine à un cluster Databricks à l'aide de Hyperopt avec SparkTrials. En ajustant un classifieur SVM scikit-learn sur le dataset Iris, vous créez d'abord un workflow fmin() sur une seule machine, puis vous le parallélisez sur des Worker Spark, avec MLflow qui suit automatiquement chaque essai.
Importez les packages requis et chargez le dataset
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score
from sklearn.svm import SVC
from hyperopt import fmin, tpe, hp, SparkTrials, STATUS_OK, Trials
# If you are running Databricks Runtime for Machine Learning, `mlflow` is already installed and you can skip the following line.
import mlflow
# Load the iris dataset from scikit-learn
iris = iris = load_iris()
X = iris.data
y = iris.target
Partie 1. Workflow Hyperopt à machine unique
Voici les étapes d'un workflow Hyperopt :
- Définissez une fonction à minimiser.
- Définir un espace de recherche sur les hyperparamètres.
- Sélectionnez un algorithme de recherche.
- Exécutez l'algorithme d'ajustement avec Hyperopt
fmin().
Pour en savoir plus, consultez la documentation Hyperopt.
Définissez une fonction à minimiser
Dans cet exemple, nous utilisons un classificateur à machine à vecteurs de support. L'objectif est de trouver la meilleure valeur pour le paramètre de régularisation C.
La majeure partie du code d'un workflow Hyperopt se trouve dans la fonction objectif. Cet exemple utilise le classifieur à vecteurs de support de scikit-learn.
Si votre cluster utilise Databricks Runtime 11.3 ML, modifiez le classificateur à vecteurs de support pour qu'il prenne un argument positionnel, clf = SVC(C).
def objective(C):
# Create a support vector classifier model
clf = SVC(C=C)
# Use the cross-validation accuracy to compare the models' performance
accuracy = cross_val_score(clf, X, y).mean()
# Hyperopt tries to minimize the objective function. A higher accuracy value means a better model, so you must return the negative accuracy.
return {'loss': -accuracy, 'status': STATUS_OK}
Définir l'espace de recherche sur les hyperparamètres
Consultez les documents Hyperopt pour plus de détails sur la définition d'un espace de recherche et les expressions de paramètres.
search_space = hp.lognormal('C', 0, 1.0)
Sélectionner un algorithme de recherche
Les deux principaux choix sont :
hyperopt.tpe.suggest: Tree of Parzen Estimators, une approche bayésienne qui sélectionne de manière itérative et adaptative de nouveaux réglages d'hyperparamètres à explorer en fonction des résultats passéshyperopt.rand.suggest: recherche aléatoire, une approche non adaptative qui échantillonne l’espace de recherche
algo=tpe.suggest
Exécuter l'algorithme de réglage avec Hyperopt fmin()
Définissez max_evals comme le nombre maximal de points dans l'espace des hyperparamètres à tester, c'est-à-dire le nombre maximal de modèles à ajuster et à évaluer.
argmin = fmin(
fn=objective,
space=search_space,
algo=algo,
max_evals=16)
# Print the best value found for C
print("Best value found: ", argmin)
Partie 2. Réglage distribué à l'aide d'Apache Spark et de MLflow
Pour distribuer l'optimisation, ajoutez un argument supplémentaire à fmin(): une classe Trials appelée SparkTrials.
SparkTrials prend 2 arguments facultatifs :
parallelism: Nombre de modèles à entraîner et évaluer simultanément. La default est le nombre d'emplacements de tâches Spark disponibles.timeout: Temps maximal (en secondes) pendant lequelfmin()peut s’exécuter. Le default est qu’il n’y a pas de limite de temps maximale.
Cet exemple utilise la fonction objective très simple définie dans la commande 7. Dans ce cas, la fonction s'exécute rapidement et la surcharge du démarrage des Jobs Spark domine le temps de calcul, de sorte que les calculs pour le cas distribué prennent plus de temps. Pour les problèmes typiques du monde réel, la fonction objective est plus complexe, et l'utilisation de SparkTrails pour distribuer les calculs est plus rapide que l'optimisation sur une seule machine.
Le suivi MLflow automatisé est activé par default. Pour l'utiliser, appelez mlflow.start_run() avant d'appeler fmin() comme indiqué dans l'exemple.
from hyperopt import SparkTrials
# To display the API documentation for the SparkTrials class, uncomment the following line.
# help(SparkTrials)
spark_trials = SparkTrials()
with mlflow.start_run():
argmin = fmin(
fn=objective,
space=search_space,
algo=algo,
max_evals=16,
trials=spark_trials)
# Print the best value found for C
print("Best value found: ", argmin)
Pour afficher l'expérimentation MLflow associée au Notebook, cliquez sur l'icône Expérimentation dans la barre de contexte du Notebook, en haut à droite. Là, vous pouvez afficher toutes les exécutions. Pour afficher les exécutions dans l'interface utilisateur de MLflow, cliquez sur l'icône tout à fait à droite, à côté de Exécutions d'Expérimentation .
Pour examiner l'effet du réglage de C:
- Sélectionnez les exécutions résultantes et cliquez sur Comparer .
- Dans le nuage de points, sélectionnez C pour l'axe des X et loss pour l'axe des Y.
Une fois que vous avez effectué les actions dans la dernière cellule du notebook, votre interface utilisateur MLflow devrait afficher :
