Partager via


Réglage des hyperparamètres (aperçu)

Le réglage des hyperparamètres est le processus de recherche des valeurs optimales pour les paramètres qui ne sont pas appris par le modèle Machine Learning pendant l’entraînement, mais plutôt définis par l’utilisateur avant le début du processus d’entraînement. Ces paramètres sont communément appelés hyperparamètres et comprennent, par exemple, le taux d’apprentissage, le nombre de couches cachées dans un réseau neuronal, la force de régularisation et la taille du lot.

Les performances d’un modèle Machine Learning peuvent être très sensibles au choix des hyperparamètres, et l’ensemble optimal d’hyperparamètres peut varier considérablement en fonction du problème spécifique et du jeu de données. Le réglage des hyperparamètres est donc une étape critique du pipeline d’apprentissage automatique, car il peut avoir un impact significatif sur la précision et les performances de généralisation du modèle.

Dans Fabric, les scientifiques des données peuvent tirer parti de FLAML, une bibliothèque Python légère pour l’automatisation efficace des opérations d’apprentissage automatique et d’IA, pour leurs besoins de réglage des hyperparamètres. Dans les notebooks Fabric, les utilisateurs peuvent appeler flaml.tune pour un réglage économique des hyperparamètres.

Important

Cette fonctionnalité est en version préliminaire.

Flux de travail de réglage

Il y a trois étapes essentielles pour utiliser flaml.tune afin de terminer une tâche de réglage de base :

  1. Spécifier l’objectif du réglage par rapport aux hyperparamètres.
  2. Spécifier un espace de recherche pour les hyperparamètres.
  3. Spécifiez les contraintes de réglage, y compris les contraintes sur le budget des ressources pour effectuer le réglage, les contraintes sur les configurations, ou/et les contraintes sur une (ou plusieurs) métrique(s) particulière(s).

Objectif de réglage

La première étape consiste à spécifier votre objectif de réglage. Pour ce faire, vous devez d’abord spécifier votre procédure d’évaluation par rapport aux hyperparamètres dans une fonction définie par l’utilisateur evaluation_function. La fonction a besoin d’une configuration d’hyperparamètres en entrée. Elle peut simplement renvoyer une valeur de métrique dans un scalaire ou renvoyer un dictionnaire de paires de noms de métriques et de valeurs de métriques.

Dans l’exemple ci-dessous, nous pouvons définir une fonction d’évaluation par rapport à 2 hyperparamètres nommés x et y.

import time

def evaluate_config(config: dict):
    """evaluate a hyperparameter configuration"""
    score = (config["x"] - 85000) ** 2 - config["x"] / config["y"]


    faked_evaluation_cost = config["x"] / 100000
    time.sleep(faked_evaluation_cost)
    # we can return a single float as a score on the input config:
    # return score
    # or, we can return a dictionary that maps metric name to metric value:
    return {"score": score, "evaluation_cost": faked_evaluation_cost, "constraint_metric": config["x"] * config["y"]}

Espace de recherche

Nous allons ensuite spécifier l’espace de recherche des hyperparamètres. Dans l’espace de recherche, vous devez spécifier les valeurs valides pour vos hyperparamètres et la manière dont ces valeurs sont échantillonnées (par exemple, à partir d’une distribution uniforme ou d’une distribution log-uniforme). Dans l’exemple ci-dessous, nous pouvons fournir l’espace de recherche pour les hyperparamètres x et y. Les valeurs valables pour les deux sont des entiers compris entre [1, 100 000]. Ces hyperparamètres sont échantillonnés uniformément dans les plages spécifiées.

from flaml import tune

# construct a search space for the hyperparameters x and y.
config_search_space = {
    "x": tune.lograndint(lower=1, upper=100000),
    "y": tune.randint(lower=1, upper=100000)
}

# provide the search space to tune.run
tune.run(..., config=config_search_space, ...)

Avec FLAML, les utilisateurs peuvent personnaliser le domaine d’un hyperparamètre particulier. Cela permet aux utilisateurs de spécifier un type et une plage valide pour l’échantillonnage des paramètres. FLAML prend en charge les types d’hyperparamètres suivants : flottant, entier et catégorique. Vous pouvez voir l’exemple ci-dessous pour les domaines couramment utilisés :

config = {
    # Sample a float uniformly between -5.0 and -1.0
    "uniform": tune.uniform(-5, -1),

    # Sample a float uniformly between 3.2 and 5.4,
    # rounding to increments of 0.2
    "quniform": tune.quniform(3.2, 5.4, 0.2),

    # Sample a float uniformly between 0.0001 and 0.01, while
    # sampling in log space
    "loguniform": tune.loguniform(1e-4, 1e-2),

    # Sample a float uniformly between 0.0001 and 0.1, while
    # sampling in log space and rounding to increments of 0.00005
    "qloguniform": tune.qloguniform(1e-4, 1e-1, 5e-5),

    # Sample a random float from a normal distribution with
    # mean=10 and sd=2
    "randn": tune.randn(10, 2),

    # Sample a random float from a normal distribution with
    # mean=10 and sd=2, rounding to increments of 0.2
    "qrandn": tune.qrandn(10, 2, 0.2),

    # Sample a integer uniformly between -9 (inclusive) and 15 (exclusive)
    "randint": tune.randint(-9, 15),

    # Sample a random uniformly between -21 (inclusive) and 12 (inclusive (!))
    # rounding to increments of 3 (includes 12)
    "qrandint": tune.qrandint(-21, 12, 3),

    # Sample a integer uniformly between 1 (inclusive) and 10 (exclusive),
    # while sampling in log space
    "lograndint": tune.lograndint(1, 10),

    # Sample a integer uniformly between 2 (inclusive) and 10 (inclusive (!)),
    # while sampling in log space and rounding to increments of 2
    "qlograndint": tune.qlograndint(2, 10, 2),

    # Sample an option uniformly from the specified choices
    "choice": tune.choice(["a", "b", "c"]),
}

Pour en savoir plus sur la façon dont vous pouvez personnaliser les domaines dans votre espace de recherche, consultez la documentation FLAML sur la personnalisation des espaces de recherche.

Contraintes de réglage

La dernière étape consiste à spécifier les contraintes de la tâche de réglage. Une propriété notable de flaml.tune est qu’elle est capable de terminer le processus de réglage dans les limites d’une contrainte de ressource requise. Pour ce faire, l’utilisateur peut fournir des contraintes de ressources en termes de temps d’horloge (en secondes) en utilisant l’argument time_budget_s ou en termes de nombre d’essais en utilisant l’argument num_samples.

# Set a resource constraint of 60 seconds wall-clock time for the tuning.
flaml.tune.run(..., time_budget_s=60, ...)

# Set a resource constraint of 100 trials for the tuning.
flaml.tune.run(..., num_samples=100, ...)

# Use at most 60 seconds and at most 100 trials for the tuning.
flaml.tune.run(..., time_budget_s=60, num_samples=100, ...)

Pour en savoir plus sur les contraintes de configuration supplémentaires, vous pouvez consulter la documentation FLAML sur les options de réglage avancées.

Synthèse

Une fois que nous avons défini nos critères de réglage, nous pouvons exécuter l’essai de réglage. Pour suivre les résultats de notre essai, nous pouvons tirer parti de la journalisation automatique de MLFlow pour capturer les métriques et les paramètres de chacune de ces exécutions. Ce code capture l’intégralité de l’essai de réglage des hyperparamètres, en mettant en évidence chacune des combinaisons d’hyperparamètres explorées par FLAML.

import mlflow
mlflow.set_experiment("flaml_tune_experiment")
mlflow.autolog(exclusive=False)

with mlflow.start_run(nested=True, run_name="Child Run: "):
    analysis = tune.run(
        evaluate_config,  # the function to evaluate a config
        config=config_search_space,  # the search space defined
        metric="score",
        mode="min",  # the optimization mode, "min" or "max"
        num_samples=-1,  # the maximal number of configs to try, -1 means infinite
        time_budget_s=10,  # the time budget in seconds
    )

Remarque

Lorsque la journalisation automatique de MLflow est activée, les métriques, les paramètres et les modèles devraient être journalisés automatiquement au fur et à mesure que MLFlow s’exécute. Cependant, cela varie en fonction du cadre. Les métriques et les paramètres de modèles spécifiques peuvent ne pas être journalisés. Par exemple, aucune métrique ne sera journalisée pour les modèles XGBoost , LightGBM , Spark et SynapseML. Pour en savoir plus sur les métriques et paramètres capturés dans chaque cadre, consultez la documentation sur la journalisation automatique de MLFlow.

Réglage en parallèle avec Apache Spark

La fonctionnalité flaml.tune prend en charge le réglage à la fois d’Apache Spark et des apprenants à nœud unique. De plus, lorsque vous réglez des apprenants à nœud unique (par exemple, des apprenants Scikit-Learn), vous pouvez également paralléliser le réglage pour accélérer votre processus de réglage en configurant use_spark = True. Pour les clusters Spark, par défaut, FLAML lancera un essai par exécuteur. Vous pouvez également personnaliser le nombre d’essais simultanés en utilisant l’argument n_concurrent_trials.


analysis = tune.run(
    evaluate_config,  # the function to evaluate a config
    config=config_search_space,  # the search space defined
    metric="score",
    mode="min",  # the optimization mode, "min" or "max"
    num_samples=-1,  # the maximal number of configs to try, -1 means infinite
    time_budget_s=10,  # the time budget in seconds
    use_spark=True,
)
print(analysis.best_trial.last_result)  # the best trial's result
print(analysis.best_config)  # the best config

Pour en savoir plus sur la manière de paralléliser vos essais de réglage, vous pouvez consulter la documentation FLAML pour les tâches Spark parallèles.

Visualiser les résultats

Le module flaml.visualization fournit des fonctions utilitaires pour tracer le processus d’optimisation à l’aide de Plotly. Grâce à Plotly, les utilisateurs peuvent explorer de manière interactive les résultats de leurs expériences AutoML. Pour utiliser ces fonctions de traçage, il suffit de fournir votre objet flaml.AutoML ou flaml.tune.tune.ExperimentAnalysis optimisé en entrée.

Vous pouvez utiliser les fonctions suivantes dans votre notebook :

  • plot_optimization_history : tracer l’historique de l’optimisation de tous les essais de l’expérience.
  • plot_feature_importance : tracer l’importance de chaque caractéristique dans le jeu de données.
  • plot_parallel_coordinate : tracer les relations entre les paramètres à haute dimension dans l’expérience.
  • plot_contour : tracer les relations entre les paramètres sous forme de tracé de contour dans l’expérience.
  • plot_edf : tracer la valeur objective EDF (fonction de distribution empirique) de l’expérience.
  • plot_timeline : tracer la chronologie de l’expérience.
  • plot_slice : trace la relation entre les paramètres sous la forme d’un tracé de tranches dans le cadre d’une étude.
  • plot_param_importance : tracer l’importance des hyperparamètres de l’expérience.