Eseguire il training di modelli scikit-learn su larga scala con Azure Machine Learning
SI APPLICA A: Python SDK azure-ai-ml v2 (corrente)
Questo articolo mostra come eseguire script di training scikit-learn con Python SDK per Azure Machine Learning v2.
Gli script di esempio in questo articolo vengono usati per classificare le immagini del fiore Iris e compilare un modello di apprendimento automatico basato sul set di dati Iris di scikit-learn.
Indipendentemente dal fatto che si stia eseguendo il training di un modello di apprendimento automatico scikit-learn da zero o si stia portando un modello esistente nel cloud, è possibile usare Azure Machine Learning per aumentare il numero di processi di training open source usando risorse di calcolo cloud elastiche. Con Azure Machine Learning è possibile compilare e distribuire la versione e monitorare i modelli negli ambienti di produzione.
Prerequisiti
È possibile eseguire il codice in questo articolo usando un'istanza di ambiente di calcolo di Azure Machine Learning o il Jupyter Notebook.
Istanza di calcolo di Azure Machine Learning
- Completare Creare risorse per iniziare per creare un'istanza di ambiente di calcolo. Ogni istanza di ambiente di calcolo include un server di notebook dedicato, precaricato con l'SDK e con il repository dei notebook di esempio.
- Selezionare la scheda Notebook nello studio di Azure Machine Learning. Nella cartella di training degli esempi trovare un notebook completato ed espanso passando alla seguente directory: v2 > sdk > processi > passaggio singolo > scikit-learn > train-hyperparameter-tune-deploy-with-sklearn.
- Per completare questa esercitazione è possibile usare il codice precompilato presente nella cartella di training degli esempi.
Server Jupyter Notebook.
Configurare il processo
Questa sezione consente di configurare il processo di training caricando i pacchetti Python necessari, connettendosi a un'area di lavoro, creando una risorsa di calcolo per eseguire un processo di comando e creando un ambiente per eseguire il processo.
Connettersi all'area di lavoro
Prima di tutto, è necessario connettersi all' area di lavoro di Azure Machine Learning. L' Area di lavoro di Azure Machine Learning è la risorsa di primo livello per il servizio. Offre una posizione centralizzata per lavorare con tutti gli artefatti creati durante l’uso di Azure Machine Learning.
Si userà DefaultAzureCredential
per ottenere l'accesso all'area di lavoro. Questa credenziale deve essere in grado di gestire la maggior parte degli scenari di autenticazione di Azure SDK.
Se DefaultAzureCredential
non funziona per l'utente, vedere azure-identity reference documentation
o Set up authentication
per altre credenziali disponibili.
# Handle to the workspace
from azure.ai.ml import MLClient
# Authentication package
from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()
Se si preferisce usare un browser per accedere ed eseguire l'autenticazione, usare il codice seguente dopo aver rimosso i commenti.
# Handle to the workspace
# from azure.ai.ml import MLClient
# Authentication package
# from azure.identity import InteractiveBrowserCredential
# credential = InteractiveBrowserCredential()
Ottenere quindi un handle per l'area di lavoro specificando l'ID sottoscrizione, il nome del gruppo di risorse e il nome dell'area di lavoro. Per trovare questi parametri:
- Cercare il nome dell'area di lavoro nell'angolo in alto a destra della barra degli strumenti dello studio di Azure Machine Learning.
- Selezionare il nome dell'area di lavoro per visualizzare il gruppo di risorse e l'ID sottoscrizione.
- Copiare i valori per il gruppo di risorse e l'ID sottoscrizione nel codice.
# 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>",
)
Il risultato dell'esecuzione di questo script è un handle dell'area di lavoro che viene usato per gestire altre risorse e processi.
Nota
La creazione di MLClient
non connetterà il client all'area di lavoro. L'inizializzazione del client è differita e attenderà la prima volta che sarà necessario effettuare una chiamata. In questo articolo, tale operazione verrà eseguita durante la creazione dell’ambiente di calcolo.
Creare una risorsa di calcolo
Azure Machine Learning richiede una risorsa di calcolo per eseguire un processo. La risorsa può essere un computer singolo o multinodo con sistema operativo Linux o Windows oppure un'infrastruttura di calcolo specifica come Spark.
Nello script di esempio seguente viene effettuato il provisioning di un compute cluster
Linux. È possibile visualizzare la pagina Azure Machine Learning pricing
per l'elenco completo delle dimensioni e dei prezzi delle macchine virtuali. Per questo esempio basta solo un cluster di base; scegliere quindi un modello Standard_DS3_v2 con 2 core vCPU e 7 GB di RAM per creare un ambiente di calcolo di 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}"
)
Creare un ambiente di processo
Per eseguire un processo di Azure Machine Learning, è necessario un ambiente. Un ambiente di Azure Machine Learning incapsula le dipendenze (ad esempio il runtime del software e le librerie) necessarie per eseguire lo script di training di apprendimento automatico nella risorsa di calcolo. Questo ambiente è simile a un ambiente Python nel computer locale.
Azure Machine Learning consente di usare un ambiente curato (o pronto) o di creare un ambiente personalizzato usando un'immagine Docker o una configurazione Conda. In questo articolo viene creato un ambiente personalizzato per i processi usando un file Conda YAML.
Creare un ambiente personalizzato
Per creare un ambiente personalizzato devono essere definite le dipendenze Conda in un file YAML. Innanzitutto, creare una directory in cui archiviare il file. In questo esempio la nuova directory è stata denominata env
.
import os
dependencies_dir = "./env"
os.makedirs(dependencies_dir, exist_ok=True)
Successivamente, creare il file nella directory delle dipendenze. In questo esempio il file è stato denominato 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 specifica contiene alcuni pacchetti consueti (ad esempio, numpy e pip), che vengono usati nel processo.
Usare quindi il file YAML per creare e registrare questo ambiente personalizzato nell'area di lavoro. Viene creato un pacchetto dell'ambiente in un contenitore Docker in fase di esecuzione.
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}"
)
Per altre informazioni sulla creazione e sull'uso di ambienti vedere Creare e usare ambienti software in Azure Machine Learning.
[Facoltativo] Creare un ambiente personalizzato con l'estensione Intel® per Scikit-Learn
Velocizzare gli script scikit-learn sull'hardware Intel? Provare ad aggiungere l'estensione Intel® per Scikit-Learn nel file YAML Conda e a seguire i passaggi successivi descritti in precedenza. Più avanti in questo esempio verrà mostrato come abilitare queste ottimizzazioni:
%%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
Configurare e inviare un processo di training
In questa sezione viene mostrato come eseguire un processo di training usando uno script di training fornito. Si apprenderà come compilare il processo di training configurando il comando per l'esecuzione dello script di training. Successivamente, il processo di training viene inviato per l'esecuzione in Azure Machine Learning.
Preparare lo script di training
In questo articolo è stato fornito lo script di training tf_mnist.py. In pratica, si dovrebbe essere in grado di eseguire qualsiasi script di training personalizzato così com'è in Azure Machine Learning, senza dover modificare il codice.
Nota
Lo script di training fornito esegue le operazioni seguenti:
- mostra come registrare alcune metriche nell'esecuzione di Azure Machine Learning;
- scarica ed estrae i dati di training usando
iris = datasets.load_iris()
e - esegue il training di un modello e poi lo salva e lo registra.
Per usare e accedere ai propri dati vedere come leggere e scrivere i dati in un processo per rendere disponibili i dati durante il training.
Per usare lo script di training creare innanzitutto una directory in cui archiviare il file.
import os
src_dir = "./src"
os.makedirs(src_dir, exist_ok=True)
Creare quindi il file di script nella directory di origine.
%%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()
[Facoltativo] Abilitare le ottimizzazioni dell’estensione Intel® per Scikit-Learn per prestazioni più elevate sull'hardware Intel
Se è stata installata l'estensione Intel® per Scikit-Learn (come mostrato nella sezione precedente) è possibile abilitare le ottimizzazioni delle prestazioni aggiungendo le due righe di codice all'inizio del file di script, come mostrato di seguito.
Per altre informazioni sull'estensione Intel® per Scikit-Learn visualizzare la documentazionedel pacchetto.
%%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()
Compilare il processo di training
Ora che si dispone di tutti gli asset necessari per eseguire il processo, è possibile compilarlo usando Python SDK per Azure Machine Learning v2. Per eseguire il processo, viene creato un command
.
Azure Machine Learning command
è una risorsa che specifica tutti i dettagli necessari per eseguire il codice di training nel cloud. Tali dettagli includono gli input e gli output, il tipo di hardware da usare, il software da installare e come eseguire il codice. command
contiene informazioni per eseguire un singolo comando.
Configurare il comando
Si imposta l'utilizzo generico command
per eseguire lo script di training e le attività desiderate. Creare un oggetto Command
per specificare i dettagli di configurazione del processo di training.
- Gli input per questo comando includono numero di periodi, frequenza di apprendimento, momentum e directory di output.
- Per i valori dei parametri:
- specificare il cluster di elaborazione
cpu_compute_target = "cpu-cluster"
creato per l'esecuzione di questo comando; - specificare l'ambiente personalizzato
sklearn-env
creato per l'esecuzione del processo di Azure Machine Learning; - configurare l'azione della riga di comando stessa; in questo caso il comando è
python train_iris.py
. È possibile accedere agli input e agli output nel comando tramite la notazione${{ ... }}
e - configurare i metadati (ad esempio, il nome visualizzato e il nome dell'esperimento) dove un esperimento è il contenitore di tutte le iterazioni eseguite in un determinato progetto. Tutti i processi inviati con lo stesso nome dell'esperimento verranno elencati uno accanto all'altro in Studio di Azure Machine Learning.
- specificare il cluster di elaborazione
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",
)
Inviare il processo
È ora possibile inviare il processo per l'esecuzione in Azure Machine Learning. Questa volta si userà create_or_update
in ml_client.jobs
.
ml_client.jobs.create_or_update(job)
Al termine, il processo registra un modello nell'area di lavoro (come risultato del training) e restituisce un collegamento per visualizzare il processo in Studio di Azure Machine Learning.
Avviso
Azure Machine Learning esegue gli script di training copiando l'intera directory di origine. Se sono presenti dati sensibili che non si intende caricare, usare un file .ignore oppure non includerli nella directory di origine.
Ciò che accade durante l'esecuzione del processo
Il processo di esecuzione si articola nelle fasi seguenti:
Preparazione: viene creata un'immagine Docker in base all'ambiente definito. L'immagine viene caricata nel registro contenitori dell'area di lavoro e memorizzata nella cache per le esecuzioni successive. I log vengono trasmessi anche alla cronologia di esecuzione e possono essere visualizzati per monitorare lo stato di avanzamento. Se viene specificato un ambiente curato, verrà usata l'immagine memorizzata nella cache in cui è stato eseguito il backup dell'ambiente curato.
Ridimensionamento: il cluster tenta di aumentare il numero di nodi, se il cluster richiede più nodi per eseguire l'esecuzione di quelli attualmente disponibili.
Esecuzione: tutti gli script nella cartella degli script src vengono caricati nella destinazione di calcolo, gli archivi dati vengono montati o copiati e lo script viene eseguito. Gli output di stdout e la cartella ./logs vengono trasmessi alla cronologia di esecuzione e possono essere usati per monitorare l’esecuzione.
Ottimizzare gli iperparametri del modello
Dopo aver visto come eseguire una semplice esecuzione di training Scikit-learn usando l'SDK, è possibile migliorare ulteriormente l'accuratezza del modello. È possibile affinare e ottimizzare gli iperparametri del modello usando le funzionalità di sweep
Azure Machine Learning.
Per ottimizzare gli iperparametri del modello definire lo spazio dei parametri in cui eseguire la ricerca durante il training. A tale scopo, sostituire alcuni dei parametri (kernel
e penalty
) passati al processo di training con input speciali del pacchetto 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]),
)
Si crea quindi una configurazione di sweep nel processo di comando usando alcuni parametri specifici di sweep, ad esempio la metrica primaria da controllare e l'algoritmo di campionamento da usare.
Nel codice seguente viene usato il campionamento casuale per provare diversi set di configurazioni di iperparametri nel tentativo di ottimizzare la metrica primaria 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,
)
È ora possibile inviare questo processo come mostrato in precedenza. Questa volta si esegue un processo di sweep che esegue tale operazione sul processo di training.
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)
È possibile monitorare il processo usando il collegamento all'interfaccia utente dello studio presentato durante l'esecuzione del processo.
Trovare e registrare il modello migliore
Al termine di tutte le esecuzioni è possibile trovare l'esecuzione che ha prodotto il modello con la massima accuratezza.
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
)
)
È quindi possibile registrare il modello.
registered_model = ml_client.models.create_or_update(model=model)
Distribuire il modello
Il modello appena registrato può essere distribuito come qualsiasi altro modello registrato in Azure Machine Learning. Per altre informazioni sulla distribuzione vedere Distribuire e assegnare punteggi a un modello di Machine Learning con endpoint online gestito con Python SDK v2.
Passaggi successivi
In questo articolo è stato eseguito il training e la registrazione di un modello scikit-learn e sono state illustrate le opzioni di distribuzione. Per altre informazioni su Azure Machine Learning vedere gli altri articoli seguenti.