Former des modèles scikit-learn à l’échelle avec Azure Machine Learning

S’APPLIQUE À : Kit de développement logiciel (SDK) Python azure-ai-mlv2 (préversion)

Dans cet article, découvrez comment exécuter vos scripts de formation scikit-learn sur le Kit SDK Python Azure Machine Learning v2.

Dans cet article, les exemples de scripts classifient les images de fleurs d'iris afin de créer un modèle d'apprentissage automatique basé sur le jeu de données iris de scikit-learn.

Que vous soyez en train d’entraîner un modèle Machine Learning scikit-Learn à partir de zéro ou que vous transfériez un modèle existant dans le cloud, vous pouvez utiliser Azure Machine Learning pour effectuer un scale-out des travaux d’apprentissage open source à l’aide de ressources de calcul élastiques dans le cloud. Vous pouvez créer, déployer, mettre à jour et surveiller des modèles de niveau production avec Azure Machine Learning.

Prérequis

Vous pouvez exécuter le code pour cet article dans une instance de calcul Azure Machine Learning ou dans votre propre notebook Jupyter.

  • Instance de calcul Azure Machine Learning

    • Terminez la section Créer des ressources pour commencer pour créer une instance de calcul. Chaque instance de calcul comprend un serveur de notebooks dédié préchargé avec le Kit de développement logiciel (SDK) et le référentiel d’échantillons de notebooks.
    • Sélectionnez l’onglet Notebook dans Azure Machine Learning studio. Dans le dossier d’entraînement d’exemples, recherchez un notebook finalisé et développé en accédant à ce répertoire : v2 > sdk > jobs > single-step > scikit-learn > train-hyperparameter-tune-deploy-with-sklearn.
    • Vous pouvez utiliser le code prérempli dans l’échantillon de dossier de formation pour terminer ce tutoriel.
  • Votre serveur de notebooks Jupyter.

Configuration du travail

Cette section configure le travail pour l’entraînement en chargeant les packages Python requis, en se connectant à un espace de travail, en créant une ressource de calcul pour exécuter un travail de commande et en créant un environnement pour exécuter le travail.

Se connecter à l’espace de travail

Vous devez d’abord vous connecter à votre espace de travail Azure Machine Learning. L’espace de travail Azure Machine Learning est la ressource de niveau supérieur du service. Il vous fournit un emplacement centralisé dans lequel utiliser tous les artefacts que vous créez quand vous utilisez Azure Machine Learning.

Nous allons utiliser DefaultAzureCredential pour accéder à l’espace de travail. Ces infos de connexion doivent être capables de gérer la plupart des scénarios d’authentification du kit SDK Azure.

Si DefaultAzureCredential ce n’est pas le cas, consultez azure-identity reference documentation ou Set up authentication pour plus d’informations d’identification disponibles.

# Handle to the workspace
from azure.ai.ml import MLClient

# Authentication package
from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()

Si vous préférez utiliser un navigateur pour vous connecter et vous authentifier, vous devez supprimer les commentaires dans le code suivant et l’utiliser à la place.

# Handle to the workspace
# from azure.ai.ml import MLClient

# Authentication package
# from azure.identity import InteractiveBrowserCredential
# credential = InteractiveBrowserCredential()

Ensuite, obtenez un descripteur pour l’espace de travail en fournissant votre ID d’abonnement, le nom du groupe de ressources et le nom de l’espace de travail. Pour rechercher ces paramètres :

  1. Recherchez le nom de votre espace de travail dans le coin supérieur droit de la barre d’outils Azure Machine Learning studio.
  2. Sélectionnez le nom de votre espace de travail pour afficher votre groupe de ressources et votre ID d’abonnement.
  3. Copiez les valeurs du groupe de ressources et de l’ID d’abonnement dans le code.
# Get a handle to the workspace
ml_client = MLClient(
    credential=credential,
    subscription_id="<SUBSCRIPTION_ID>",
    resource_group_name="<RESOURCE_GROUP>",
    workspace_name="<AML_WORKSPACE_NAME>",
)

Le résultat de l’exécution de ce script est un descripteur d’espace de travail qui vous permet de gérer d’autres ressources et travaux.

Remarque

La création de MLClient n’établit pas de connexion du client à l’espace de travail. L’initialisation du client est lente et elle attendra la première fois qu’il aura besoin de faire un appel. Dans cet article, cela se produit lors de la création du calcul.

Créer une ressource de calcul

Azure Machine Learning a besoin d’une ressource de calcul pour exécuter un travail. La ressource peut être constituée de machines à nœud unique ou à plusieurs nœuds avec un système d’exploitation Linux ou Windows, ou d’une structure de calcul spécifique comme Spark.

Dans l’exemple de script suivant, nous approvisionnons un compute cluster Linux. Vous pouvez voir la page Azure Machine Learning pricing pour obtenir la liste complète des tailles et des prix des machines virtuelles. Nous avons seulement besoin d’un cluster de base pour cet exemple ; nous choisissons donc un modèle Standard_DS3_v2 avec 2 cœurs de processeurs virtuels et 7 Go de RAM pour créer un calcul Azure Machine Learning.

from azure.ai.ml.entities import AmlCompute

# Name assigned to the compute cluster
cpu_compute_target = "cpu-cluster"

try:
    # let's see if the compute target already exists
    cpu_cluster = ml_client.compute.get(cpu_compute_target)
    print(
        f"You already have a cluster named {cpu_compute_target}, we'll reuse it as is."
    )

except Exception:
    print("Creating a new cpu compute target...")

    # Let's create the Azure ML compute object with the intended parameters
    cpu_cluster = AmlCompute(
        name=cpu_compute_target,
        # Azure ML Compute is the on-demand VM service
        type="amlcompute",
        # VM Family
        size="STANDARD_DS3_V2",
        # Minimum running nodes when there is no job running
        min_instances=0,
        # Nodes in cluster
        max_instances=4,
        # How many seconds will the node running after the job termination
        idle_time_before_scale_down=180,
        # Dedicated or LowPriority. The latter is cheaper but there is a chance of job termination
        tier="Dedicated",
    )

    # Now, we pass the object to MLClient's create_or_update method
    cpu_cluster = ml_client.compute.begin_create_or_update(cpu_cluster).result()

print(
    f"AMLCompute with name {cpu_cluster.name} is created, the compute size is {cpu_cluster.size}"
)

Créer un environnement de travail

Pour exécuter un travail Azure Machine Learning, vous avez besoin d’un environnement. Un environnement Azure Machine Learning encapsule les dépendances (telles que le runtime logiciel et les bibliothèques) nécessaires pour exécuter votre script de formation Machine Learning sur votre ressource de calcul. Cet environnement est similaire à un environnement Python sur votre ordinateur local.

Azure Machine Learning vous permet d’utiliser un environnement organisé (ou prêt à l’emploi) ou de créer un environnement personnalisé à l’aide d’une image Docker ou d’une configuration Conda. Dans cet article, vous allez créer un environnement Conda personnalisé pour vos travaux à l’aide d’un fichier YAML Conda.

Créer un environnement personnalisé

Pour créer votre environnement personnalisé, vous devez définir vos dépendances Conda dans un fichier YAML. Tout d’abord, créez un répertoire pour le stockage du fichier. Dans cet exemple, nous avons nommé le répertoire env.

import os

dependencies_dir = "./env"
os.makedirs(dependencies_dir, exist_ok=True)

Ensuite, créez le fichier dans le répertoire des dépendances. Dans cet exemple, nous avons nommé le fichier conda.yml.

%%writefile {dependencies_dir}/conda.yaml
name: sklearn-env
channels:
  - conda-forge
dependencies:
  - python=3.8
  - pip=21.2.4
  - scikit-learn=0.24.2
  - scipy=1.7.1
  - pip:  
    - azureml-mlflow==1.42.0
    - mlflow-skinny==2.3.2

La spécification contient certains packages habituels (tels que numpy et pip) que vous devez utiliser dans votre travail.

Ensuite, utilisez le fichier YAML pour créer et inscrire cet environnement personnalisé dans votre espace de travail. L’environnement est empaqueté dans un conteneur Docker au moment de l’exécution.

from azure.ai.ml.entities import Environment

custom_env_name = "sklearn-env"

job_env = Environment(
    name=custom_env_name,
    description="Custom environment for sklearn image classification",
    conda_file=os.path.join(dependencies_dir, "conda.yaml"),
    image="mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest",
)
job_env = ml_client.environments.create_or_update(job_env)

print(
    f"Environment with name {job_env.name} is registered to workspace, the environment version is {job_env.version}"
)

Pour plus d’informations sur la création et l’utilisation d’environnements, consultez Créer et utiliser des environnements logiciels dans Azure Machine Learning.

[Facultatif] Créer un environnement personnalisé avec l’extension Intel® pour Scikit-Learn

Vous souhaitez accélérer vos scripts scikit-learn sur le matériel Intel ? Essayez d’ajouter l’extension Intel® pour Scikit-Learn dans votre fichier yaml conda et suivez les étapes suivantes détaillées ci-dessus. Nous allons vous montrer comment activer ces optimisations plus loin dans cet exemple :

%%writefile {dependencies_dir}/conda.yaml
name: sklearn-env
channels:
  - conda-forge
dependencies:
  - python=3.8
  - pip=21.2.4
  - scikit-learn=0.24.2
  - scikit-learn-intelex
  - scipy=1.7.1
  - pip:  
    - azureml-mlflow==1.42.0
    - mlflow-skinny==2.3.2

Configurer et soumettre un travail de formation

Dans cette section, nous abordons la façon d’exécuter un travail de formation à l’aide d’un script de formation que nous avons fourni. Pour commencer, vous générez le travail de formation en configurant la commande d’exécution du script d’entraînement. Ensuite, vous envoyez le travail de formation à exécuter dans Azure Machine Learning.

Préparer le script d’apprentissage

Dans cet article, nous avons fourni le script d’entraînement train_iris.py. Dans la pratique, vous devez être capable de prendre n’importe quel script de formation personnalisé et de l’exécuter avec Azure Machine Learning sans avoir à modifier votre code.

Notes

Le script de formation fourni réalise les opérations suivantes :

  • montre comment enregistrer certaines métriques dans votre exécution d’Azure Machine Learning ;
  • télécharge et extrait les données d’apprentissage à l’aide de iris = datasets.load_iris() ; et
  • effectue l’apprentissage d’un modèle, puis l’enregistre et l’inscrit.

Pour utiliser vos propres données et y accéder, découvrez comment lire et écrire des données dans un travail afin de rendre les données disponibles pendant l’entraînement.

Pour utiliser le script de formation, commencez par créer un répertoire dans lequel vous allez stocker le fichier.

import os

src_dir = "./src"
os.makedirs(src_dir, exist_ok=True)

Ensuite, créez le fichier de script dans le répertoire source.

%%writefile {src_dir}/train_iris.py
# Modified from https://www.geeksforgeeks.org/multiclass-classification-using-scikit-learn/

import argparse
import os

# importing necessary libraries
import numpy as np

from sklearn import datasets
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split

import joblib

import mlflow
import mlflow.sklearn

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('--kernel', type=str, default='linear',
                        help='Kernel type to be used in the algorithm')
    parser.add_argument('--penalty', type=float, default=1.0,
                        help='Penalty parameter of the error term')

    # Start Logging
    mlflow.start_run()

    # enable autologging
    mlflow.sklearn.autolog()

    args = parser.parse_args()
    mlflow.log_param('Kernel type', str(args.kernel))
    mlflow.log_metric('Penalty', float(args.penalty))

    # loading the iris dataset
    iris = datasets.load_iris()

    # X -> features, y -> label
    X = iris.data
    y = iris.target

    # dividing X, y into train and test data
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

    # training a linear SVM classifier
    from sklearn.svm import SVC
    svm_model_linear = SVC(kernel=args.kernel, C=args.penalty)
    svm_model_linear = svm_model_linear.fit(X_train, y_train)
    svm_predictions = svm_model_linear.predict(X_test)

    # model accuracy for X_test
    accuracy = svm_model_linear.score(X_test, y_test)
    print('Accuracy of SVM classifier on test set: {:.2f}'.format(accuracy))
    mlflow.log_metric('Accuracy', float(accuracy))
    # creating a confusion matrix
    cm = confusion_matrix(y_test, svm_predictions)
    print(cm)

    registered_model_name="sklearn-iris-flower-classify-model"

    ##########################
    #<save and register model>
    ##########################
    # Registering the model to the workspace
    print("Registering the model via MLFlow")
    mlflow.sklearn.log_model(
        sk_model=svm_model_linear,
        registered_model_name=registered_model_name,
        artifact_path=registered_model_name
    )

    # # Saving the model to a file
    print("Saving the model via MLFlow")
    mlflow.sklearn.save_model(
        sk_model=svm_model_linear,
        path=os.path.join(registered_model_name, "trained_model"),
    )
    ###########################
    #</save and register model>
    ###########################
    mlflow.end_run()

if __name__ == '__main__':
    main()

[Facultatif] Activer l’extension Intel® pour les optimisations Scikit-Learn pour de meilleures performances sur le matériel Intel

Si vous avez installé l’extension Intel® pour Scikit-Learn (comme illustré dans la section précédente), vous pouvez activer les optimisations des performances en ajoutant les deux lignes de code en haut du fichier de script, comme indiqué ci-dessous.

Pour en savoir plus sur l’extension Intel® pour Scikit-Learn, consultez la documentation du package.

%%writefile {src_dir}/train_iris.py
# Modified from https://www.geeksforgeeks.org/multiclass-classification-using-scikit-learn/

import argparse
import os

# Import and enable Intel Extension for Scikit-learn optimizations
# where possible

from sklearnex import patch_sklearn
patch_sklearn()

# importing necessary libraries
import numpy as np


from sklearn import datasets
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split

import joblib

import mlflow
import mlflow.sklearn

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('--kernel', type=str, default='linear',
                        help='Kernel type to be used in the algorithm')
    parser.add_argument('--penalty', type=float, default=1.0,
                        help='Penalty parameter of the error term')

    # Start Logging
    mlflow.start_run()

    # enable autologging
    mlflow.sklearn.autolog()

    args = parser.parse_args()
    mlflow.log_param('Kernel type', str(args.kernel))
    mlflow.log_metric('Penalty', float(args.penalty))

    # loading the iris dataset
    iris = datasets.load_iris()

    # X -> features, y -> label
    X = iris.data
    y = iris.target

    # dividing X, y into train and test data
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

    # training a linear SVM classifier
    from sklearn.svm import SVC
    svm_model_linear = SVC(kernel=args.kernel, C=args.penalty)
    svm_model_linear = svm_model_linear.fit(X_train, y_train)
    svm_predictions = svm_model_linear.predict(X_test)

    # model accuracy for X_test
    accuracy = svm_model_linear.score(X_test, y_test)
    print('Accuracy of SVM classifier on test set: {:.2f}'.format(accuracy))
    mlflow.log_metric('Accuracy', float(accuracy))
    # creating a confusion matrix
    cm = confusion_matrix(y_test, svm_predictions)
    print(cm)

    registered_model_name="sklearn-iris-flower-classify-model"

    ##########################
    #<save and register model>
    ##########################
    # Registering the model to the workspace
    print("Registering the model via MLFlow")
    mlflow.sklearn.log_model(
        sk_model=svm_model_linear,
        registered_model_name=registered_model_name,
        artifact_path=registered_model_name
    )

    # # Saving the model to a file
    print("Saving the model via MLFlow")
    mlflow.sklearn.save_model(
        sk_model=svm_model_linear,
        path=os.path.join(registered_model_name, "trained_model"),
    )
    ###########################
    #</save and register model>
    ###########################
    mlflow.end_run()

if __name__ == '__main__':
    main()

Créer le travail d’entraînement

Maintenant que vous disposez de toutes les ressources nécessaires pour exécuter votre travail, il est temps de le générer à l’aide du SDK Python Azure Machine Learning v2. Pour exécuter le travail, nous créons un command.

Un command Azure Machine Learning est une ressource qui spécifie tous les détails nécessaires pour exécuter votre code d’entraînement dans le cloud. Ces détails incluent les entrées et sorties, le type de matériel à utiliser, le logiciel à installer et la façon d’exécuter votre code. command contient des informations pour exécuter une seule commande.

Configurer la commande

Vous utilisez le command à usage général pour exécuter le script de formation, puis effectuer vos tâches souhaitées. Créez un objet Command pour spécifier les détails de configuration de votre travail de formation.

  • Les entrées de cette commande incluent le nombre d’époques, le taux d’apprentissage, l’élan et le répertoire de sortie.
  • Pour les valeurs de paramètre :
    • fournissez le cluster de calcul cpu_compute_target = "cpu-cluster" que vous avez créé pour exécuter cette commande ;
    • fournissez l’environnement personnalisé sklearn-env que vous avez créé pour exécuter le travail Azure Machine Learning ;
    • configurez l’action de ligne de commande elle-même — dans ce cas, la commande est python train_iris.py. Vous pouvez accéder aux entrées et sorties dans la commande via la notation ${{ ... }} ; et
    • configurez les métadonnées telles que le nom d’affichage et le nom de l’expérience ; où une expérience est un conteneur pour toutes les itérations qu’il effectue sur un certain projet. Tous les travaux soumis sous le même nom d’expérience sont listés les uns à côtés des autres dans Azure Machine Learning Studio.
from azure.ai.ml import command
from azure.ai.ml import Input

job = command(
    inputs=dict(kernel="linear", penalty=1.0),
    compute=cpu_compute_target,
    environment=f"{job_env.name}:{job_env.version}",
    code="./src/",
    command="python train_iris.py --kernel ${{inputs.kernel}} --penalty ${{inputs.penalty}}",
    experiment_name="sklearn-iris-flowers",
    display_name="sklearn-classify-iris-flower-images",
)

Envoi du travail

Il est maintenant temps de soumettre le travail à exécuter dans Azure Machine Learning. Cette fois, vous utilisez create_or_update sur ml_client.jobs.

ml_client.jobs.create_or_update(job)

Une fois terminé, le travail inscrit un modèle dans votre espace de travail (à la suite de la formation), puis génère un lien qui vous permet de voir ce travail dans Azure Machine Learning studio.

Avertissement

Azure Machine Learning exécute des scripts d’apprentissage en copiant l’intégralité du répertoire source. Si vous avez des données sensibles que vous ne souhaitez pas charger, utilisez un fichier .ignore ou ne l’incluez pas dans le répertoire source.

Ce qui se passe lors de l’exécution

Quand le travail est exécuté, elle passe par les phases suivantes :

  • Préparation : une image docker est créée en fonction de l’environnement défini. L’image est chargée dans le registre de conteneurs de l’espace de travail et mise en cache pour des exécutions ultérieures. Les journaux sont également transmis en continu à l’historique des exécutions et peuvent être affichés afin de surveiller la progression. Si un environnement organisé est spécifié, l’image mise en cache sur laquelle repose cet environnement organisé est utilisée.

  • Mise à l’échelle : le cluster tente de monter en puissance si le cluster nécessite plus de nœuds pour l’exécution que la quantité disponible actuellement.

  • En cours d’exécution : tous les scripts dans le dossier de script src sont chargés dans la cible de calcul, les magasins de données sont montés ou copiés, puis le script est exécuté. Les sorties issues de stdout et du dossier ./logs sont transmises en continu à l’historique des exécutions et peuvent être utilisées pour superviser l’exécution.

Régler les hyperparamètres du modèle

Maintenant que vous avez vu comment effectuer une simple exécution de formation Scikit-learn à l’aide du Kit de développement logiciel (SDK), voyons si vous pouvez améliorer davantage la précision de votre modèle. Vous pouvez paramétrer et optimiser les hyperparamètres de notre modèle à l’aide des fonctionnalités d’Azure sweep Machine Learning.

Pour paramétrer les hyperparamètres du modèle, définissez l’espace de paramètres dans lequel effectuer une recherche pendant la formation. Pour ce faire, remplacez certains des paramètres (kernel et penalty) transmis au travail de formation par des entrées spéciales du package azure.ml.sweep.

from azure.ai.ml.sweep import Choice

# we will reuse the command_job created before. we call it as a function so that we can apply inputs
# we do not apply the 'iris_csv' input again -- we will just use what was already defined earlier
job_for_sweep = job(
    kernel=Choice(values=["linear", "rbf", "poly", "sigmoid"]),
    penalty=Choice(values=[0.5, 1, 1.5]),
)

Ensuite, vous configurez le balayage sur le travail de commande, en utilisant certains paramètres spécifiques au balayage, tels que la métrique principale à surveiller et l’algorithme d’échantillonnage à utiliser.

Dans le code suivant, nous utilisons l’échantillonnage aléatoire pour essayer différents jeux de configuration d’hyperparamètres dans une tentative d’optimisation de notre métrique principale, Accuracy.

sweep_job = job_for_sweep.sweep(
    compute="cpu-cluster",
    sampling_algorithm="random",
    primary_metric="Accuracy",
    goal="Maximize",
    max_total_trials=12,
    max_concurrent_trials=4,
)

Maintenant, vous pouvez soumettre ce travail comme avant. Cette fois, vous exécutez un travail de balayage de votre travail de formation.

returned_sweep_job = ml_client.create_or_update(sweep_job)

# stream the output and wait until the job is finished
ml_client.jobs.stream(returned_sweep_job.name)

# refresh the latest status of the job after streaming
returned_sweep_job = ml_client.jobs.get(name=returned_sweep_job.name)

Vous pouvez surveiller le travail à l’aide du lien d’interface utilisateur studio qui est présenté pendant l’exécution du travail.

Rechercher et inscrire le meilleur modèle

Une fois toutes les exécutions terminées, vous pouvez trouver l’exécution qui a produit le modèle avec la plus grande précision.

from azure.ai.ml.entities import Model

if returned_sweep_job.status == "Completed":

    # First let us get the run which gave us the best result
    best_run = returned_sweep_job.properties["best_child_run_id"]

    # lets get the model from this run
    model = Model(
        # the script stores the model as "sklearn-iris-flower-classify-model"
        path="azureml://jobs/{}/outputs/artifacts/paths/sklearn-iris-flower-classify-model/".format(
            best_run
        ),
        name="run-model-example",
        description="Model created from run.",
        type="custom_model",
    )

else:
    print(
        "Sweep job status: {}. Please wait until it completes".format(
            returned_sweep_job.status
        )
    )

Vous pouvez ensuite inscrire ce modèle.

registered_model = ml_client.models.create_or_update(model=model)

Déployer le modèle

Une fois que vous avez enregistré votre modèle, vous pouvez le déployer de la même façon que n’importe quel autre modèle enregistré dans Azure Machine Learning. Pour plus d’informations sur le déploiement, consultez Déployer et noter un modèle Machine Learning avec un point de terminaison en ligne managé à l’aide du Kit de développement logiciel (SDK) Python v2.

Étapes suivantes

Dans cet article, vous avez entraîné et inscrit un modèle scikit-learn, et vous avez découvert les options de déploiement. Consultez ces autres articles pour en savoir plus sur Azure Machine Learning.