Scikit-learn-modellen op schaal trainen met Azure Machine Learning

VAN TOEPASSING OP: Python SDK azure-ai-ml v2 (actueel)

In dit artikel leert u hoe u uw scikit-learn-trainingsscripts uitvoert met Azure Machine Learning Python SDK v2.

De voorbeeldscripts in dit artikel worden gebruikt om irisbloemafbeeldingen te classificeren om een machine learning-model te bouwen op basis van de irisgegevensset van scikit-learn.

Of u nu een scikit-learn-model voor machine learning traint of een bestaand model naar de cloud brengt, u kunt Azure Machine Learning gebruiken om opensource-trainingstaken uit te schalen met behulp van elastische cloud-rekenresources. U kunt modellen op productieniveau bouwen, implementeren, versien en bewaken met Azure Machine Learning.

Vereisten

U kunt de code voor dit artikel uitvoeren in een Azure Machine Learning-rekenproces of uw eigen Jupyter Notebook.

  • Azure Machine Learning-rekeninstantie

    • Voltooi Resources maken om aan de slag te gaan met het maken van een rekenproces. Elk rekenproces bevat een toegewezen notebookserver die vooraf is geladen met de SDK en de voorbeeldopslagplaats voor notebooks.
    • Selecteer het notitiebloktabblad in de Azure Machine Learning-studio. Zoek in de trainingsmap met voorbeelden een voltooid en uitgebreid notebook door naar deze map te navigeren: v2 > sdk-taken >> met één stap > scikit-learn > train-hyperparameter-tune-deploy-with-sklearn.
    • U kunt de vooraf ingevulde code in de voorbeeldtrainingsmap gebruiken om deze zelfstudie te voltooien.
  • Uw Jupyter Notebook-server.

De taak instellen

In deze sectie wordt de taak voor training ingesteld door de vereiste Python-pakketten te laden, verbinding te maken met een werkruimte, een rekenresource te maken om een opdrachttaak uit te voeren en een omgeving te maken om de taak uit te voeren.

Verbinding maken naar de werkruimte

Eerst moet u verbinding maken met uw Azure Machine Learning-werkruimte. De Azure Machine Learning-werkruimte is de resource op het hoogste niveau voor de service. Het biedt u een centrale locatie om te werken met alle artefacten die u maakt wanneer u Azure Machine Learning gebruikt.

We gebruiken DefaultAzureCredential om toegang te krijgen tot de werkruimte. Deze referentie moet geschikt zijn voor het verwerken van de meeste Azure SDK-verificatiescenario's.

Als DefaultAzureCredential dit niet werkt, raadpleegt azure-identity reference documentation u of Set up authentication voor meer beschikbare referenties.

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

# Authentication package
from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()

Als u liever een browser gebruikt om u aan te melden en te verifiëren, moet u de opmerkingen in de volgende code verwijderen en in plaats daarvan gebruiken.

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

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

Haal vervolgens een ingang op voor de werkruimte door uw abonnements-id, resourcegroepnaam en werkruimtenaam op te geven. Ga als volgt te werk om deze parameters te vinden:

  1. Zoek in de rechterbovenhoek van de Azure Machine Learning-studio werkbalk naar de naam van uw werkruimte.
  2. Selecteer de naam van uw werkruimte om uw resourcegroep en abonnements-id weer te geven.
  3. Kopieer de waarden voor resourcegroep en abonnements-id naar de 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>",
)

Het resultaat van het uitvoeren van dit script is een werkruimtehandgreep die u gebruikt voor het beheren van andere resources en taken.

Notitie

Als MLClient de client wordt gemaakt, wordt er geen verbinding gemaakt met de werkruimte. De initialisatie van de client is lui en wacht op de eerste keer dat de client een oproep moet doen. In dit artikel gebeurt dit tijdens het maken van de berekening.

Een rekenresource maken

Azure Machine Learning heeft een rekenresource nodig om een taak uit te voeren. Deze resource kan machines met één of meerdere knooppunten zijn met Linux- of Windows-besturingssysteem, of een specifieke rekeninfrastructuur zoals Spark.

In het volgende voorbeeldscript richten we een Linux compute clusterin. U ziet de Azure Machine Learning pricing pagina voor de volledige lijst met VM-grootten en -prijzen. We hebben alleen een basiscluster nodig voor dit voorbeeld; Daarom kiezen we een Standard_DS3_v2 model met 2 vCPU-kernen en 7 GB RAM om een Azure Machine Learning-rekenproces te maken.

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}"
)

Een taakomgeving maken

Als u een Azure Machine Learning-taak wilt uitvoeren, hebt u een omgeving nodig. Een Azure Machine Learning-omgeving bevat de afhankelijkheden (zoals softwareruntime en bibliotheken) die nodig zijn om uw machine learning-trainingsscript uit te voeren op uw rekenresource. Deze omgeving is vergelijkbaar met een Python-omgeving op uw lokale computer.

Met Azure Machine Learning kunt u een gecureerde (of kant-en-klare) omgeving gebruiken of een aangepaste omgeving maken met behulp van een Docker-installatiekopieën of een Conda-configuratie. In dit artikel maakt u een aangepaste omgeving voor uw taken met behulp van een Conda YAML-bestand.

Een aangepaste omgeving maken

Als u uw aangepaste omgeving wilt maken, definieert u uw Conda-afhankelijkheden in een YAML-bestand. Maak eerst een map voor het opslaan van het bestand. In dit voorbeeld hebben we de map enveen naam.

import os

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

Maak vervolgens het bestand in de map met afhankelijkheden. In dit voorbeeld hebben we het bestand conda.ymleen naam.

%%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

De specificatie bevat enkele gebruikelijke pakketten (zoals numpy en pip) die u in uw taak gebruikt.

Gebruik vervolgens het YAML-bestand om deze aangepaste omgeving in uw werkruimte te maken en te registreren. De omgeving wordt tijdens runtime verpakt in een Docker-container.

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}"
)

Zie Software-omgevingen maken en gebruiken in Azure Machine Learning voor meer informatie over het maken en gebruiken van omgevingen.

[Optioneel] Een aangepaste omgeving maken met De Intel-extensie® voor Scikit-Learn

Wilt u uw scikit-learn-scripts op Intel-hardware versnellen? Probeer intel-extensie® voor Scikit-Learn toe te voegen aan uw conda yaml-bestand en volg de volgende stappen die hierboven worden beschreven. Verderop in dit voorbeeld ziet u hoe u deze optimalisaties inschakelt:

%%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

Uw trainingstaak configureren en verzenden

In deze sectie wordt beschreven hoe u een trainingstaak uitvoert met behulp van een trainingsscript dat we hebben opgegeven. Om te beginnen bouwt u de trainingstaak door de opdracht voor het uitvoeren van het trainingsscript te configureren. Vervolgens dient u de trainingstaak in om te worden uitgevoerd in Azure Machine Learning.

Het trainingsscript voorbereiden

In dit artikel hebben we het trainingsscript train_iris.py opgegeven. In de praktijk moet u elk aangepast trainingsscript kunnen gebruiken en uitvoeren met Azure Machine Learning zonder dat u uw code hoeft te wijzigen.

Notitie

Het opgegeven trainingsscript doet het volgende:

  • laat zien hoe u enkele metrische gegevens kunt registreren bij uw Azure Machine Learning-uitvoering;
  • downloadt en extraheert de trainingsgegevens met behulp van iris = datasets.load_iris(); en
  • traint een model, slaat het op en registreert het.

Als u uw eigen gegevens wilt gebruiken en openen, leest en schrijft u gegevens in een taak om gegevens beschikbaar te maken tijdens de training.

Als u het trainingsscript wilt gebruiken, maakt u eerst een map waarin u het bestand opslaat.

import os

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

Maak vervolgens het scriptbestand in de bronmap.

%%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()

[Optioneel] Intel-extensie® inschakelen voor Scikit-Learn-optimalisaties voor meer prestaties op Intel-hardware

Als u de Intel-extensie® voor Scikit-Learn hebt geïnstalleerd (zoals in de vorige sectie is gedemonstreerd), kunt u de prestatieoptimalisaties inschakelen door de twee regels code toe te voegen aan het begin van het scriptbestand, zoals hieronder wordt weergegeven.

Ga naar de documentatie van het pakket voor meer informatie over De Intel-extensie® voor Scikit-Learn.

%%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()

De trainingstaak bouwen

Nu u alle assets hebt die nodig zijn om uw taak uit te voeren, is het tijd om deze te bouwen met behulp van de Azure Machine Learning Python SDK v2. Als u de taak wilt uitvoeren, maken we een command.

Een Azure Machine Learning command is een resource waarmee alle details worden opgegeven die nodig zijn om uw trainingscode in de cloud uit te voeren. Deze details omvatten de invoer en uitvoer, het type hardware dat moet worden gebruikt, de software die moet worden geïnstalleerd en hoe u uw code uitvoert. De command bevat informatie voor het uitvoeren van één opdracht.

De opdracht configureren

U gebruikt het algemene doel command om het trainingsscript uit te voeren en uw gewenste taken uit te voeren. Maak een Command object om de configuratiegegevens van uw trainingstaak op te geven.

  • De invoer voor deze opdracht omvat het aantal tijdvakken, leersnelheid, momentum en uitvoermap.
  • Voor de parameterwaarden:
    • geef het rekencluster cpu_compute_target = "cpu-cluster" op dat u hebt gemaakt voor het uitvoeren van deze opdracht;
    • geef de aangepaste omgeving sklearn-env op die u hebt gemaakt voor het uitvoeren van de Azure Machine Learning-taak;
    • configureert u de opdrachtregelactie zelf, in dit geval is de opdracht python train_iris.py. U kunt de invoer en uitvoer in de opdracht openen via de ${{ ... }} notatie; en
    • de metagegevens, zoals de weergavenaam en de naam van het experiment, configureren; waarbij een experiment een container is voor alle iteraties die op een bepaald project worden uitgevoerd. Alle taken die onder dezelfde experimentnaam worden ingediend, worden naast elkaar weergegeven in 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",
)

De taak verzenden

Het is nu tijd om de taak in te dienen om te worden uitgevoerd in Azure Machine Learning. Deze keer gebruikt create_or_update u op ml_client.jobs.

ml_client.jobs.create_or_update(job)

Zodra de taak is voltooid, registreert de taak een model in uw werkruimte (als gevolg van training) en voert u een koppeling uit om de taak in Azure Machine Learning-studio weer te geven.

Waarschuwing

Azure Machine Learning voert trainingsscripts uit door de volledige bronmap te kopiëren. Als u gevoelige gegevens hebt die u niet wilt uploaden, gebruikt u een .ignore-bestand of neemt u het niet op in de bronmap.

Wat gebeurt er tijdens het uitvoeren van de taak

Terwijl de taak wordt uitgevoerd, doorloopt deze de volgende fasen:

  • Voorbereiden: Er wordt een Docker-installatiekopieën gemaakt op basis van de gedefinieerde omgeving. De installatiekopieën worden geüpload naar het containerregister van de werkruimte en in de cache opgeslagen voor latere uitvoeringen. Logboeken worden ook gestreamd naar de uitvoeringsgeschiedenis en kunnen worden bekeken om de voortgang te controleren. Als er een gecureerde omgeving is opgegeven, wordt de back-up van de gecureerde omgeving in de cache gebruikt.

  • Schalen: Het cluster probeert omhoog te schalen als voor het cluster meer knooppunten nodig zijn om de uitvoering uit te voeren dan momenteel beschikbaar is.

  • Wordt uitgevoerd: Alle scripts in de scriptmap src worden geüpload naar het rekendoel, gegevensarchieven worden gekoppeld of gekopieerd en het script wordt uitgevoerd. Uitvoer van stdout en de map ./logs worden gestreamd naar de uitvoeringsgeschiedenis en kunnen worden gebruikt om de uitvoering te bewaken.

Modelhyperparameters afstemmen

Nu u hebt gezien hoe u een eenvoudige Scikit-learn-trainingsuitvoering kunt uitvoeren met behulp van de SDK, gaan we kijken of u de nauwkeurigheid van uw model verder kunt verbeteren. U kunt de hyperparameters van ons model afstemmen en optimaliseren met behulp van de mogelijkheden van sweep Azure Machine Learning.

Als u de hyperparameters van het model wilt afstemmen, definieert u de parameterruimte waarin tijdens de training moet worden gezocht. U doet dit door enkele parameters (kernel en penalty) te vervangen die zijn doorgegeven aan de trainingstaak door speciale invoer uit het azure.ml.sweep pakket.

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]),
)

Vervolgens configureert u opruimen voor de opdrachttaak met behulp van enkele opruimende parameters, zoals de primaire metrische waarde die u wilt bekijken en het sampling-algoritme dat moet worden gebruikt.

In de volgende code gebruiken we willekeurige steekproeven om verschillende configuratiesets van hyperparameters uit te proberen in een poging om onze primaire metrische gegevens te maximaliseren. 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,
)

U kunt deze taak nu indienen zoals voorheen. Deze keer voert u een sweep-taak uit die over uw trainingstaak veegt.

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)

U kunt de taak controleren met behulp van de gebruikersinterfacekoppeling van studio die wordt weergegeven tijdens de taakuitvoering.

Het beste model zoeken en registreren

Zodra alle uitvoeringen zijn voltooid, kunt u de uitvoering vinden die het model heeft geproduceerd met de hoogste nauwkeurigheid.

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
        )
    )

U kunt dit model vervolgens registreren.

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

Model implementeren

Nadat u uw model hebt geregistreerd, kunt u het op dezelfde manier implementeren als elk ander geregistreerd model in Azure Machine Learning. Zie Een machine learning-model implementeren en beoordelen met een beheerd online-eindpunt met behulp van Python SDK v2 voor meer informatie over implementatie.

Volgende stappen

In dit artikel hebt u een scikit-learn-model getraind en geregistreerd en hebt u geleerd over implementatieopties. Zie deze andere artikelen voor meer informatie over Azure Machine Learning.