Procesamiento de imágenes con implementaciones de modelos por lotes
SE APLICA A:Extensión ML de la CLI de Azure v2 (actual)SDK de Python azure-ai-ml v2 (actual)
Puede usar implementaciones de modelos por lotes para procesar datos tabulares, pero también cualquier otro tipo de archivo, como imágenes. Esas implementaciones se admiten tanto en MLflow como en modelos personalizados. En este artículo, aprenderá a implementar un modelo que clasifica las imágenes según la taxonomía ImageNet.
Requisitos previos
Suscripción a Azure. Si no tiene una suscripción de Azure, cree una cuenta gratuita antes de empezar. Pruebe la versión gratuita o de pago de Azure Machine Learning.
Un área de trabajo de Azure Machine Learning. Para crear un área de trabajo, vea Administración de áreas de trabajo de Azure Machine Learning.
Asegúrese de que dispone de los siguientes permisos en el área de trabajo de Machine Learning:
- Crear o administrar implementaciones y puntos de conexión por lotes: use los roles de propietario, colaborador o un rol personalizado que permita
Microsoft.MachineLearningServices/workspaces/batchEndpoints/*
. - Creación de implementaciones de Azure Resource Manager en el grupo de recursos del área de trabajo: use un rol de propietario, colaborador o personalizado que permita
Microsoft.Resources/deployments/write
en el grupo de recursos donde se implementa el área de trabajo.
- Crear o administrar implementaciones y puntos de conexión por lotes: use los roles de propietario, colaborador o un rol personalizado que permita
Instale el siguiente software para trabajar con Machine Learning:
Ejecute el siguiente comando para instalar la CLI de Azure y la extensión
ml
para Azure Machine Learning:az extension add -n ml
Las implementaciones de componentes de canalización para puntos de conexión por lotes se introdujeron en la versión 2.7 de la extensión
ml
para la CLI de Azure. Use el comandoaz extension update --name ml
para obtener la versión más reciente.
Conexión con su área de trabajo
El área de trabajo es el recurso de nivel superior de Machine Learning. Proporciona un lugar centralizado para trabajar con todos los artefactos que cree al usar Machine Learning. En esta sección, se conectará al área de trabajo donde realizará las tareas de implementación.
En el siguiente comando, escriba los valores de id. de suscripción, área de trabajo, ubicación y grupo de recursos:
az account set --subscription <subscription>
az configure --defaults workspace=<workspace> group=<resource-group> location=<location>
Acerca de este ejemplo
En este artículo se usa un modelo que se creó con TensorFlow junto con la arquitectura RestNet. Para obtener más información, consulte Asignaciones de identidades en redes residuales profundas. Puede descargar un ejemplo de este modelo. El modelo tiene las restricciones siguientes:
- Funciona con imágenes de tamaño de 244 x 244 (tensores de
(224, 224, 3)
). - Requiere que las entradas se escalen al intervalo
[0,1]
.
La información de este artículo se basa en ejemplos de código que se encuentran en el repositorio azureml-examples. Para ejecutar los comandos localmente sin tener que copiar o pegar YAML y otros archivos, clone el repositorio. Cambie los directorios a cli/endpoints/batch/deploy-models/imagenet-classifier si usa la CLI de Azure o sdk/python/endpoints/batch/deploy-models/imagenet-classifier si usa el SDK para Python.
git clone https://github.com/Azure/azureml-examples --depth 1
cd azureml-examples/cli/endpoints/batch/deploy-models/imagenet-classifier
Siga estos pasos en Jupyter Notebooks
Puede seguir este ejemplo en un Jupyter Notebook. En el repositorio clonado, abra el cuaderno: imagenet-classifier-batch.ipynb.
Clasificación de imágenes con implementaciones por lotes
En este ejemplo, aprenderá a implementar un modelo de aprendizaje profundo que pueda clasificar una imagen determinada según la Taxonomía de ImageNet.
Creación del punto de conexión
Cree el punto de conexión que hospeda el modelo:
Especifique el nombre del punto de conexión.
ENDPOINT_NAME="imagenet-classifier-batch"
Cree el siguiente archivo YAML para definir el punto de conexión por lotes, denominado endpoint.yml:
$schema: https://azuremlschemas.azureedge.net/latest/batchEndpoint.schema.json name: imagenet-classifier-batch description: A batch endpoint for performing image classification using a TFHub model ImageNet model. auth_mode: aad_token
Para crear el punto de conexión, ejecute el código siguiente:
az ml batch-endpoint create --file endpoint.yml --name $ENDPOINT_NAME
Registro del modelo
Las implementaciones de modelos solo pueden implementar modelos registrados. Debe registrar el modelo. Puede omitir este paso si el modelo que está intentando implementar ya está registrado.
Descargue una copia del modelo.
wget https://azuremlexampledata.blob.core.windows.net/data/imagenet/model.zip unzip model.zip -d .
Registre el modelo.
MODEL_NAME='imagenet-classifier' az ml model create --name $MODEL_NAME --path "model"
Crear un script de puntuación
Cree un script de puntuación que pueda leer las imágenes proporcionadas por la implementación por lotes y devolver las puntuaciones del modelo.
- El método
init
carga el modelo mediante el módulokeras
entensorflow
. - El método
run
se ejecuta para cada miniproceso que proporciona la implementación por lotes. - El método
run
lee una imagen del archivo a la vez. - El método
run
cambia el tamaño de las imágenes a los tamaños esperados del modelo. - El método
run
vuelve a escalar las imágenes al dominio de intervalo[0,1]
, que es lo que espera el modelo. - El script devuelve las clases y las probabilidades asociadas a las predicciones.
Este código es el archivocode/score-by-file/batch_driver.py:
import os
import numpy as np
import pandas as pd
import tensorflow as tf
from os.path import basename
from PIL import Image
from tensorflow.keras.models import load_model
def init():
global model
global input_width
global input_height
# AZUREML_MODEL_DIR is an environment variable created during deployment
model_path = os.path.join(os.environ["AZUREML_MODEL_DIR"], "model")
# load the model
model = load_model(model_path)
input_width = 244
input_height = 244
def run(mini_batch):
results = []
for image in mini_batch:
data = Image.open(image).resize(
(input_width, input_height)
) # Read and resize the image
data = np.array(data) / 255.0 # Normalize
data_batch = tf.expand_dims(
data, axis=0
) # create a batch of size (1, 244, 244, 3)
# perform inference
pred = model.predict(data_batch)
# Compute probabilities, classes and labels
pred_prob = tf.math.reduce_max(tf.math.softmax(pred, axis=-1)).numpy()
pred_class = tf.math.argmax(pred, axis=-1).numpy()
results.append([basename(image), pred_class[0], pred_prob])
return pd.DataFrame(results)
Sugerencia
Aunque la implementación proporciona imágenes en mini lotes, este script de puntuación procesa una imagen cada vez. Este es un patrón común porque intentar cargar todo el lote y enviarlo al modelo a la vez podría dar lugar a una presión de memoria alta en el ejecutor de lotes (excepciones de OOM).
Hay ciertos casos en los que, al hacerlo, se habilita un alto rendimiento en la tarea de puntuación. Este es el caso de las implementaciones por lotes a través del hardware de GPU donde desea lograr un uso elevado de GPU. Para obtener un script de puntuación que aproveche este enfoque, consulte Implementaciones de alto rendimiento.
Nota:
Si desea implementar un modelo generativo, que genera archivos, aprenda a crear un script de puntuación: Personalizar salidas en implementaciones por lotes.
Creación de la implementación
Después de crear el script de puntuación, cree una implementación por lotes para él. Utilice el siguiente procedimiento:
Asegúrese de que tiene un clúster de proceso creado donde puede crear la implementación. En este ejemplo, use un clúster de proceso denominado
gpu-cluster
. Aunque no es necesario, el uso de GPU acelera el procesamiento.Indique en qué entorno se va a ejecutar la implementación. En este ejemplo, el modelo se ejecuta en
TensorFlow
. Azure Machine Learning ya tiene un entorno con el software necesario instalado, por lo que puede reutilizar este entorno. Debe agregar un par de dependencias en un archivo conda.yml.La definición del entorno se incluye en el archivo de implementación.
compute: azureml:gpu-cluster environment: name: tensorflow212-cuda11-gpu image: mcr.microsoft.com/azureml/curated/tensorflow-2.12-cuda11:latest
Cree la implementación.
Para crear una nueva implementación en el punto de conexión creado, cree una configuración de
YAML
como en el ejemplo siguiente. Para ver otras propiedades, consulte la esquema de YAML de punto de conexión por lotes completo.$schema: https://azuremlschemas.azureedge.net/latest/modelBatchDeployment.schema.json endpoint_name: imagenet-classifier-batch name: imagenet-classifier-resnetv2 description: A ResNetV2 model architecture for performing ImageNet classification in batch type: model model: azureml:imagenet-classifier@latest compute: azureml:gpu-cluster environment: name: tensorflow212-cuda11-gpu image: mcr.microsoft.com/azureml/curated/tensorflow-2.12-cuda11:latest conda_file: environment/conda.yaml code_configuration: code: code/score-by-file scoring_script: batch_driver.py resources: instance_count: 2 settings: max_concurrency_per_instance: 1 mini_batch_size: 5 output_action: append_row output_file_name: predictions.csv retry_settings: max_retries: 3 timeout: 300 error_threshold: -1 logging_level: info
Cree la implementación con el siguiente comando:
az ml batch-deployment create --file deployment-by-file.yml --endpoint-name $ENDPOINT_NAME --set-default
Aunque puede invocar una implementación específica dentro de un punto de conexión, normalmente querrá invocar el propio punto de conexión y dejar que este decida qué implementación se va a usar. Esta implementación se denomina implementación predeterminada.
Este enfoque le permite cambiar la implementación predeterminada y cambiar el modelo que atiende la implementación sin cambiar el contrato con el usuario invocando el punto de conexión. Use el código siguiente para actualizar la implementación predeterminada:
az ml batch-endpoint update --name $ENDPOINT_NAME --set defaults.deployment_name=$DEPLOYMENT_NAME
El punto de conexión por lotes está listo para usarse.
Prueba de la implementación
Para probar el punto de conexión, use un ejemplo de 1000 imágenes del conjunto de datos ImageNet original. Los puntos de conexión de lote solo pueden procesar los datos que se encuentran en la nube y que son accesibles desde el área de trabajo de Azure Machine Learning. Cárguelo en un almacén de datos de Azure Machine Learning. Cree un recurso de datos que se pueda usar para invocar el punto de conexión para la puntuación.
Nota:
Los puntos de conexión de Batch aceptan datos que se pueden colocar en varios tipos de ubicaciones.
Descargue los datos de ejemplo asociados.
wget https://azuremlexampledata.blob.core.windows.net/data/imagenet/imagenet-1000.zip unzip imagenet-1000.zip -d data
Nota:
Si no tiene
wget
instalado localmente, instálelo o use un explorador para obtener el archivo .zip.Cree el recurso de datos a partir de los datos descargados.
Cree una definición de recurso de datos en un archivo
YAML
denominado imagenet-sample-unlabeled.yml:$schema: https://azuremlschemas.azureedge.net/latest/data.schema.json name: imagenet-sample-unlabeled description: A sample of 1000 images from the original ImageNet dataset. Download content from https://azuremlexampledata.blob.core.windows.net/data/imagenet-1000.zip. type: uri_folder path: data
Cree el recurso de datos.
az ml data create -f imagenet-sample-unlabeled.yml
Cuando los datos se carguen y estén listos para usarse, invoque el punto de conexión.
JOB_NAME=$(az ml batch-endpoint invoke --name $ENDPOINT_NAME --input azureml:imagenet-sample-unlabeled@latest --query name -o tsv)
Nota:
Si la utilidad
jq
no está instalada, consulte Descargar jq.
Sugerencia
No se indica el nombre de implementación en la operación de invocación. Esto se debe a que el punto de conexión enruta automáticamente el trabajo a la implementación predeterminada. Puesto que el punto de conexión solo tiene una implementación, esa es la predeterminada. Puede tener como destino una implementación específica indicando el argumento o parámetro deployment_name
.
Un trabajo por lotes se inicia en cuanto se devuelve el comando. Puede supervisar el estado del trabajo hasta que finalice.
az ml job show -n $JOB_NAME --web
Una vez finalizada la implementación, descargue las predicciones.
Use los siguientes comandos para descargar las predicciones:
az ml job download --name $JOB_NAME --output-name score --download-path ./
Las predicciones tienen un aspecto similar al siguiente resultado. Las predicciones se combinan con las etiquetas para la comodidad del lector. Para obtener más información acerca de cómo lograr este efecto, consulte el cuaderno asociado.
import pandas as pd score = pd.read_csv("named-outputs/score/predictions.csv", header=None, names=['file', 'class', 'probabilities'], sep=' ') score['label'] = score['class'].apply(lambda pred: imagenet_labels[pred]) score
file class probabilities etiqueta n02088094_Lebrel_afgano.JPEG 161 0,994745 Lebrel afgano n02088238_basset 162 0,999397 basset n02088364_beagle.JPEG 165 0,366914 bluetick n02088466_Perro_de_San_Huberto.JPEG 164 0,926464 Perro de San Huberto ... ... ... ...
Implementaciones de alto rendimiento
Como se ha mencionado antes, la implementación procesa una imagen a la vez, incluso cuando la implementación por lotes está proporcionando un lote de ellos. En la mayoría de los casos, este enfoque es mejor. Simplifica la ejecución de los modelos y evita los posibles problemas de memoria insuficiente. Sin embargo, en algunos otros casos, es posible que quiera saturar tanto como sea posible el hardware subyacente. Esta situación es el caso de las GPU, por ejemplo.
En esos casos, es posible que desee realizar inferencias en todo el lote de datos. Este enfoque implica cargar todo el conjunto de imágenes en la memoria y enviarlos directamente al modelo. En el ejemplo siguiente se usa TensorFlow
para leer el lote de imágenes y puntuarlas todas a la vez. También usa TensorFlow
operaciones para realizar cualquier preprocesamiento de datos. Toda la canalización se produce en el mismo dispositivo que se usa (CPU/GPU).
Advertencia
Algunos modelos tienen una relación no lineal con el tamaño de las entradas en términos del consumo de memoria. Para evitar excepciones fuera de memoria, vuelva a procesar por lotes (como se hace en este ejemplo) o reduzca el tamaño de los lotes creados por la implementación de lotes.
Cree el código de script de puntuación/score-by-batch/batch_driver.py:
import os import numpy as np import pandas as pd import tensorflow as tf from tensorflow.keras.models import load_model def init(): global model global input_width global input_height # AZUREML_MODEL_DIR is an environment variable created during deployment model_path = os.path.join(os.environ["AZUREML_MODEL_DIR"], "model") # load the model model = load_model(model_path) input_width = 244 input_height = 244 def decode_img(file_path): file = tf.io.read_file(file_path) img = tf.io.decode_jpeg(file, channels=3) img = tf.image.resize(img, [input_width, input_height]) return img / 255.0 def run(mini_batch): images_ds = tf.data.Dataset.from_tensor_slices(mini_batch) images_ds = images_ds.map(decode_img).batch(64) # perform inference pred = model.predict(images_ds) # Compute probabilities, classes and labels pred_prob = tf.math.reduce_max(tf.math.softmax(pred, axis=-1)).numpy() pred_class = tf.math.argmax(pred, axis=-1).numpy() return pd.DataFrame( [mini_batch, pred_prob, pred_class], columns=["file", "probability", "class"] )
- Este script crea un conjunto de datos de tensor a partir del minilote enviado por la implementación por lotes. Este conjunto de datos se preprocesa para obtener los tensores esperados para el modelo mediante la operación
map
con la funcióndecode_img
. - El conjunto de datos se vuelve a procesar por lotes (16) para enviar los datos al modelo. Use este parámetro para controlar la cantidad de información que puede cargar en la memoria y enviar al modelo a la vez. Si se ejecuta en una GPU, debe ajustar cuidadosamente este parámetro para lograr el uso máximo de la GPU justo antes de obtener una excepción de OOM.
- Una vez calculadas las predicciones, los tensores se convierten en
numpy.ndarray
.
- Este script crea un conjunto de datos de tensor a partir del minilote enviado por la implementación por lotes. Este conjunto de datos se preprocesa para obtener los tensores esperados para el modelo mediante la operación
Cree la implementación.
- Para crear una nueva implementación en el punto de conexión creado, cree una configuración de
YAML
como en el ejemplo siguiente. Para ver otras propiedades, consulte la esquema de YAML de punto de conexión por lotes completo.
$schema: https://azuremlschemas.azureedge.net/latest/modelBatchDeployment.schema.json endpoint_name: imagenet-classifier-batch name: imagenet-classifier-resnetv2 description: A ResNetV2 model architecture for performing ImageNet classification in batch type: model model: azureml:imagenet-classifier@latest compute: azureml:gpu-cluster environment: name: tensorflow212-cuda11-gpu image: mcr.microsoft.com/azureml/curated/tensorflow-2.12-cuda11:latest conda_file: environment/conda.yaml code_configuration: code: code/score-by-batch scoring_script: batch_driver.py resources: instance_count: 2 tags: device_acceleration: CUDA device_batching: 16 settings: max_concurrency_per_instance: 1 mini_batch_size: 5 output_action: append_row output_file_name: predictions.csv retry_settings: max_retries: 3 timeout: 300 error_threshold: -1 logging_level: info
- Cree la implementación con el siguiente comando:
az ml batch-deployment create --file deployment-by-batch.yml --endpoint-name $ENDPOINT_NAME --set-default
- Para crear una nueva implementación en el punto de conexión creado, cree una configuración de
Puede usar esta nueva implementación con los datos de ejemplo mostrados anteriormente. Recuerde que para invocar esta implementación, indique el nombre de la implementación en el método de invocación o establézcalo como predeterminado.
Consideraciones sobre el procesamiento de imágenes de modelos de MLflow
Los modelos de MLflow en puntos de conexión de Batch admiten la lectura de imágenes como datos de entrada. Dado que las implementaciones de MLflow no requieren un script de puntuación, tenga en cuenta las siguientes consideraciones al usarlas:
- Los archivos de imagen admitidos incluyen: .png, .jpg, .jpeg, .tiff, .bmp, y .gif.
- Los modelos de MLflow deben esperar recibir un
np.ndarray
como entrada que coincida con las dimensiones de la imagen de entrada. Para admitir varios tamaños de imagen en cada lote, el ejecutor de lotes invoca el modelo de MLflow una vez por archivo de imagen. - Se recomienda encarecidamente que los modelos de MLflow incluyan una firma. Si lo hacen, debe ser de tipo
TensorSpec
. Las entradas se vuelven a configurar para que coincidan con la forma del tensor si está disponible. Si no hay ninguna firma disponible, se infieren tensores de tiponp.uint8
. - Para los modelos que incluyen una firma y se espera que controle el tamaño variable de las imágenes, incluya una firma que pueda garantizarla. Por ejemplo, en el ejemplo de firma siguiente se permiten lotes de 3 imágenes canaladas.
import numpy as np
import mlflow
from mlflow.models.signature import ModelSignature
from mlflow.types.schema import Schema, TensorSpec
input_schema = Schema([
TensorSpec(np.dtype(np.uint8), (-1, -1, -1, 3)),
])
signature = ModelSignature(inputs=input_schema)
(...)
mlflow.<flavor>.log_model(..., signature=signature)
Puede encontrar un ejemplo de trabajo en el cuaderno de Jupyter imagenet-classifier-mlflow.ipynb. Para obtener más información acerca de cómo usar modelos de MLflow en implementaciones por lotes, consulte Uso de modelos de MLflow en implementaciones por lotes.