Entrenamiento de modelos de scikit-learn a gran escala con Azure Machine Learning
SE APLICA A: SDK de Python azure-ai-ml v2 (actual)
En este artículo, obtendrá información sobre cómo ejecutar los scripts de entrenamiento de scikit-learn con Azure Machine Learning Python SDK v2.
Los scripts de ejemplo de este artículo se usan para clasifica imágenes de flores Iris para crear un modelo de Machine Learning basado en el conjunto de datos de Iris de scikit-learn.
Tanto si va a entrenar un modelo de scikit-learn de Machine Learning desde el principio como si va a incorporar un modelo existente a la nube, puede usar Azure Machine Learning para escalar horizontalmente trabajos de entrenamiento de código abierto mediante recursos de proceso en la nube elástica. Puede compilar, implementar y supervisar modelos de nivel de producción, así como crear versiones de dichos mismos, mediante Azure Machine Learning.
Requisitos previos
Puede ejecutar el código de este artículo en una instancia de proceso de Azure Machine Learning o en su propio Jupyter Notebook.
Instancia de proceso de Azure Machine Learning
- Complete Creación de recursos para empezar para crear una instancia de proceso. Cada instancia de proceso incluye un servidor de cuadernos dedicado precargado con el SDK y el repositorio de ejemplos de cuadernos.
- Seleccione la pestaña Cuaderno en el Estudio de Azure Machine Learning. En la carpeta de entrenamiento de muestras, encuentre un cuaderno completo y expandido navegando a este directorio: v2 > sdk > jobs > single-step > scikit-learn > train-hyperparameter-tune-deploy-with-sklearn.
- Puede usar el código rellenado previamente en la carpeta de entrenamiento de ejemplo para completar este tutorial.
Su servidor de Jupyter Notebook
Configuración de la herramienta
En esta sección se configura el trabajo para el entrenamiento mediante la carga de los paquetes de Python necesarios, la conexión a un área de trabajo, la creación de un recurso de proceso para ejecutar un trabajo de comando y la creación de un entorno para ejecutar el trabajo.
Conexión a un área de trabajo
En primer lugar, debe conectarse al área de trabajo de Azure Machine Learning. El área de trabajo de Azure Machine Learning es el recurso de nivel superior para el servicio. Proporciona un lugar centralizado para trabajar con todos los artefactos que cree al usar Azure Machine Learning.
Usaremos DefaultAzureCredential
para obtener acceso al área de trabajo. Esta credencial es capaz de manejar la mayoría de los escenarios de autenticación del SDK de Azure.
Si DefaultAzureCredential
no funciona, consulte azure-identity reference documentation
o Set up authentication
para obtener más credenciales disponibles.
# Handle to the workspace
from azure.ai.ml import MLClient
# Authentication package
from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()
Si prefiere usar un explorador para iniciar sesión y autenticarse, debe quitar los comentarios en el código siguiente y usarlo en su lugar.
# Handle to the workspace
# from azure.ai.ml import MLClient
# Authentication package
# from azure.identity import InteractiveBrowserCredential
# credential = InteractiveBrowserCredential()
A continuación, obtenga un identificador para el área de trabajo proporcionando el identificador de suscripción, el nombre del grupo de recursos y el nombre del área de trabajo. Para buscar estos parámetros:
- Busque en la esquina superior derecha de la barra de herramientas del estudio de Azure Machine Learning el nombre del área de trabajo.
- Seleccione el nombre del área de trabajo para mostrar el identificador de suscripción y el grupo de recursos.
- Copie los valores del grupo de recursos y el identificador de suscripción en el código.
# 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>",
)
El resultado de la ejecución de este script es un manipulador del área de trabajo que se utiliza para administrar otros recursos y trabajos.
Nota:
La creación de MLClient
no conectará al cliente con el área de trabajo. La inicialización del cliente es lenta y esperará a la primera vez que necesite hacer una llamada. En este artículo, esto ocurrirá durante la creación del proceso.
Creación de un recurso de proceso
Azure Machine Learning necesita un recurso de proceso para ejecutar un trabajo. Este recurso puede ser máquinas de un solo nodo o de varios nodos con sistema operativo Linux o Windows, o un tejido de proceso específico, como Spark.
En el siguiente script de ejemplo, aprovisionamos un Linux compute cluster
. Puede ver la página Azure Machine Learning pricing
para ver la lista completa de tamaños y precios de máquina virtual. Solo necesitamos un clúster básico para este ejemplo; por lo tanto, elegiremos un modelo de Standard_DS3_v2 con 2 núcleos de vCPU y 7 GB de RAM para crear un proceso de 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}"
)
Creación de un entorno de trabajo
Para ejecutar un trabajo de Azure Machine Learning, necesita un entorno. Un entorno de Azure Machine Learning encapsula las dependencias (como el tiempo de ejecución de software y las bibliotecas) necesarias para ejecutar el script de entrenamiento de aprendizaje automático en el recurso de proceso. Este entorno es similar a un entorno de Python en la máquina local.
Azure Machine Learning le permite usar un entorno mantenido (o listo) o crear un entorno personalizado mediante una imagen de Docker o una configuración de Conda. En este artículo, creará un entorno personalizado para sus trabajos, mediante un archivo YAML de Conda.
Creación de un entorno personalizado
Para crear el entorno personalizado, definirá las dependencias de Conda en un archivo YAML. En primer lugar, cree un directorio para almacenar el archivo. En este ejemplo, hemos nombrado el directorio env
.
import os
dependencies_dir = "./env"
os.makedirs(dependencies_dir, exist_ok=True)
Después, cree el archivo en el directorio de dependencias. En este ejemplo, hemos nombrado el archivo 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 especificación contiene algunos paquetes habituales (como numpy y pip) que utilizará en el trabajo.
A continuación, utilice el archivo YAML para crear y registrar este entorno personalizado en su área de trabajo. El entorno se empaquetará en un contenedor de Docker en tiempo de ejecución.
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}"
)
Para más información sobre la creación y el uso de los entornos, consulte Creación y uso de entornos de software en Azure Machine Learning.
[Opcional] Creación de un entorno personalizado con la Extensión Intel® para Scikit-Learn
¿Quiere acelerar sus scripts de scikit-learn en hardware Intel? Pruebe a agregar la Extensión Intel® para Scikit-Learn en su archivo yaml de conda y siga los pasos posteriores detallados anteriormente. Le mostraremos cómo habilitar estas optimizaciones más adelante en este ejemplo:
%%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
Configuración y envío del trabajo de entrenamiento
En esta sección, vamos a explicar cómo ejecutar un trabajo de entrenamiento mediante un script de entrenamiento que hemos proporcionado. Para empezar, compilará el trabajo de entrenamiento mediante la configuración del comando para ejecutar el script de entrenamiento. Después, enviará el trabajo de entrenamiento para que se ejecute en Azure Machine Learning.
Preparar el script de entrenamiento
En este artículo, hemos proporcionado el script de entrenamiento train_iris.py. En la práctica, debería poder usar cualquier script de entrenamiento personalizado tal cual y ejecutarlo con Azure Machine Learning sin tener que modificar el código.
Nota
El script de entrenamiento proporcionado realiza lo siguiente:
- muestra cómo registrar algunas métricas en la ejecución de Azure Machine Learning;
- descarga y extrae los datos de entrenamiento mediante
iris = datasets.load_iris()
; y - entrena un modelo y, a continuación, lo guarda y lo registra.
Para acceder a sus propios datos y usarlos, consulte Cómo leer y escribir datos en un trabajo para que los datos estén disponibles durante el entrenamiento.
Para usar el script de entrenamiento, cree primero un directorio donde almacenará el archivo.
import os
src_dir = "./src"
os.makedirs(src_dir, exist_ok=True)
A continuación, cree el archivo de script en el directorio de origen.
%%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()
[Opcional] Habilitación de la Extensión Intel® para optimizaciones de Scikit-Learn para obtener más rendimiento en hardware Intel
Si ha instalado la Extensión Intel® para Scikit-Learn (como se muestra en la sección anterior), puede habilitar las optimizaciones de rendimiento agregando las dos líneas de código a la parte superior del archivo de script, como se muestra a continuación.
Para obtener más información sobre la Extensión Intel® para Scikit-Learn, visite la documentación de del paquete.
%%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()
Compilación del trabajo de entrenamiento
Ahora que tiene todos los recursos necesarios para ejecutar el trabajo, es el momento de compilar mediante el SDK de Python v2 de Azure Machine Learning. Para ejecutar el trabajo, creamos un command
.
Un command
de Azure Machine Learning es un recurso que especifica todos los detalles necesarios para ejecutar el código de entrenamiento en la nube. Estos detalles incluyen las entradas y salidas, el tipo de hardware que se va a usar, el software que se va a instalar y cómo ejecutar el código. command
contiene información para ejecutar un único comando.
Configuración del comando
Usará el command
de uso general para ejecutar el script de entrenamiento y realizar las tareas deseadas. Cree un objeto Command
para especificar los detalles de configuración del trabajo de entrenamiento.
- Las entradas de este comando incluyen el número de épocas, velocidad de aprendizaje, impulso y directorio de salida.
- Para los valores de parámetro:
- proporcione el clúster de proceso
cpu_compute_target = "cpu-cluster"
que creó para ejecutar este comando; - Proporcione el entorno
sklearn-env
personalizado que creó para ejecutar el trabajo de Azure Machine Learning; - configurar la acción de la línea de comandos en sí, en este caso, el comando es
python train_iris.py
. Puede acceder a las entradas y salidas en el comando a través de la notación${{ ... }}
; y - configure los metadatos, como el nombre para mostrar y el nombre del experimento; donde un experimento es un contenedor para todas las iteraciones que se realiza en un proyecto determinado. Todos los trabajos enviados en el mismo nombre de experimento se enumerarán de manera correlativa en Estudio de Azure Machine Learning.
- proporcione el clúster de proceso
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",
)
Enviar el archivo
Ahora es el momento de enviar el trabajo para que se ejecute en Azure Machine Learning. Esta vez se usa create_or_update
en ml_client.jobs
.
ml_client.jobs.create_or_update(job)
Una vez completado, el trabajo registra un modelo en el área de trabajo (como resultado del entrenamiento) y genera un vínculo para ver el trabajo en Estudio de Azure Machine Learning.
Advertencia
Azure Machine Learning ejecuta scripts de entrenamiento mediante la copia de todo el directorio de origen. Si tiene información confidencial que no quiere cargar, use un archivo .ignore o no la incluya en el directorio de origen.
¿Qué ocurre durante la ejecución del trabajo?
Durante la ejecución del trabajo, este pasa por las fases siguientes:
Preparando: se crea una imagen de Docker según el entorno definido. La imagen se carga en el registro de contenedor del área de trabajo y se almacena en memoria caché para ejecuciones posteriores. Los registros también se transmiten al historial de ejecución y se pueden consultar para supervisar el progreso. Si se especifica un entorno mantenido, se usa la imagen almacenada en caché que respalda el entorno mantenido.
Escalado: el clúster intenta escalar verticalmente si el clúster requiere más nodos para ejecutar la ejecución de los que están disponibles actualmente.
Ejecución: todos los scripts de la carpeta de scripts src se cargan en el objetivo de proceso, se montan o copian los almacenes de datos y se ejecuta el script. Las salidas de stdout y la carpeta ./logs se transmiten al historial de ejecución y se pueden usar para supervisar la ejecución.
Optimizar los hiperparámetros del modelo
Ahora que ha visto cómo realizar una ejecución de entrenamiento simple de Scikit-learn mediante el SDK, veamos si puede mejorar aún más la precisión del modelo. Puede ajustar y optimizar los hiperparámetros del modelo mediante las funcionalidades de sweep
Azure Machine Learning.
Para ajustar los hiperparámetros del modelo, defina el espacio de parámetros en el que se va a buscar durante el entrenamiento. Para ello, reemplace algunos de los parámetros (kernel
y penalty
) pasados al trabajo de entrenamiento con entradas especiales del paquete 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]),
)
Después, configurará el barrido en el trabajo de comando con algunos parámetros específicos del barrido, como la métrica principal para inspeccionar y el algoritmo de muestreo que se va a usar.
En el código siguiente se usa el muestreo aleatorio para probar diferentes conjuntos de configuración de hiperparámetros en un intento de maximizar la métrica principal, 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,
)
Ahora, puede enviar este trabajo como antes. Esta vez, va a ejecutar un trabajo de barrido que barrerá el trabajo de entrenamiento.
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)
Puede supervisar el trabajo mediante el vínculo de la interfaz de usuario de Studio que se presenta durante la ejecución del trabajo.
Búsqueda y registro del mejor modelo
Una vez completadas todas las ejecuciones, puede encontrar la ejecución que generó el modelo con la mayor precisión.
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
)
)
A continuación, puede registrar este modelo.
registered_model = ml_client.models.create_or_update(model=model)
Implementación del modelo
Después de registrar el modelo, puede implementarlo de la misma manera que cualquier otro modelo registrado en Azure Machine Learning. Para más información sobre la implementación, consulte Implementación y puntuación de un modelo de Machine Learning con un punto de conexión en línea administrado mediante el SDK de Python v2.
Pasos siguientes
En este artículo, ha entrenado y registrado un modelo scikit-learn, y ha aprendido sobre las opciones de implementación. Consulte estos otros artículos para más información sobre Azure Machine Learning.