Esercitazione: Eseguire il training di un modello di rilevamento oggetti (anteprima) con AutoML e Python (v1)

SI APPLICA A:Azureml di Python SDK v1

Importante

Le funzionalità presentate in questo articolo sono disponibili in anteprima. Devono essere considerate funzionalità di anteprima sperimentale che potrebbero cambiare in qualsiasi momento.

Questa esercitazione descrive come eseguire il training di un modello di rilevamento oggetti usando Machine Learning automatizzato ml con Azure Machine Learning Python SDK. Questo modello di rilevamento oggetti identifica se l'immagine contiene oggetti, ad esempio un can, una scatola, una bottiglia di latte o una bottiglia di acqua.

Machine Learning automatizzato accetta i dati di training e le impostazioni di configurazione e esegue automaticamente l'iterazione tramite combinazioni di metodi di normalizzazione/standardizzazione delle funzionalità diversi, modelli e impostazioni di iperparametri per arrivare al modello migliore.

Si scriverà codice usando Python SDK in questa esercitazione e si apprenderà le attività seguenti:

  • Scaricare e trasformare i dati
  • Eseguire il training di un modello di rilevamento oggetti di Machine Learning automatizzato
  • Specificare i valori di iperparametri per il modello
  • Eseguire uno spazzamento di iperparametri
  • Distribuire il modello
  • Visualizzare i rilevamenti

Prerequisiti

  • Se non si ha una sottoscrizione di Azure, creare un account gratuito prima di iniziare. Provare la versione gratuita o a pagamento di Azure Machine Learning.

  • Python 3.7 o 3.8 sono supportati per questa funzionalità

  • Completare l'avvio rapido: introduzione ad Azure Machine Learning se non si dispone già di un'area di lavoro di Azure Machine Learning.

  • Scaricare e decomprimere il * file di datiodFridgeObjects.zip. Il set di dati viene annotato in formato Pascal VOC, in cui ogni immagine corrisponde a un file xml. Ogni file xml contiene informazioni sulla posizione in cui si trova il file di immagine corrispondente e contiene anche informazioni sui rettangoli di selezione e sulle etichette dell'oggetto. Per usare questi dati, è prima necessario convertirlo nel formato JSONL richiesto, come illustrato nella sezione Converti i dati scaricati in JSONL del notebook.

Questa esercitazione è disponibile anche nel repository azureml-example in GitHub se si vuole eseguirla nell'ambiente locale. Per ottenere i pacchetti richiesti:

Configurazione della destinazione di calcolo

Per prima cosa è necessario configurare una destinazione di calcolo da usare per il training automatico del modello di Machine Learning. I modelli di Machine Learning automatizzati per le attività di immagine richiedono SKU GPU.

Questa esercitazione usa la serie NCsv3 (con GPU V100) perché questo tipo di destinazione di calcolo sfrutta più GPU per velocizzare il training. È inoltre possibile configurare più nodi per sfruttare il parallelismo durante l'ottimizzazione degli iperparametri per il modello.

Il codice seguente crea un calcolo GPU di dimensioni Standard _NC24s_v3 con quattro nodi collegati all'area di lavoro, ws.

Avviso

Assicurarsi che la sottoscrizione disponga di una quota sufficiente per la destinazione di calcolo da usare.

from azureml.core.compute import AmlCompute, ComputeTarget

cluster_name = "gpu-nc24sv3"

try:
    compute_target = ComputeTarget(workspace=ws, name=cluster_name)
    print('Found existing compute target.')
except KeyError:
    print('Creating a new compute target...')
    compute_config = AmlCompute.provisioning_configuration(vm_size='Standard_NC24s_v3',
                                                           idle_seconds_before_scaledown=1800,
                                                           min_nodes=0,
                                                           max_nodes=4)

    compute_target = ComputeTarget.create(ws, cluster_name, compute_config)

#If no min_node_count is provided, the scale settings are used for the cluster.
compute_target.wait_for_completion(show_output=True, min_node_count=None, timeout_in_minutes=20)

Configurazione dell'esperimento

Creare quindi un oggetto Experiment nell'area di lavoro per tenere traccia delle esecuzioni di training del modello.


from azureml.core import Experiment

experiment_name = 'automl-image-object-detection'
experiment = Experiment(ws, name=experiment_name)

Visualizzare i dati di input

Dopo aver preparato i dati dell'immagine di input in formato JSONL (LINEE JSON), è possibile visualizzare le caselle di selezione della verità di terra per un'immagine. A tale scopo, assicurarsi di aver matplotlib installato.

%pip install --upgrade matplotlib

%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import matplotlib.patches as patches
from PIL import Image as pil_image
import numpy as np
import json
import os

def plot_ground_truth_boxes(image_file, ground_truth_boxes):
    # Display the image
    plt.figure()
    img_np = mpimg.imread(image_file)
    img = pil_image.fromarray(img_np.astype("uint8"), "RGB")
    img_w, img_h = img.size

    fig,ax = plt.subplots(figsize=(12, 16))
    ax.imshow(img_np)
    ax.axis("off")

    label_to_color_mapping = {}

    for gt in ground_truth_boxes:
        label = gt["label"]

        xmin, ymin, xmax, ymax =  gt["topX"], gt["topY"], gt["bottomX"], gt["bottomY"]
        topleft_x, topleft_y = img_w * xmin, img_h * ymin
        width, height = img_w * (xmax - xmin), img_h * (ymax - ymin)

        if label in label_to_color_mapping:
            color = label_to_color_mapping[label]
        else:
            # Generate a random color. If you want to use a specific color, you can use something like "red".
            color = np.random.rand(3)
            label_to_color_mapping[label] = color

        # Display bounding box
        rect = patches.Rectangle((topleft_x, topleft_y), width, height,
                                 linewidth=2, edgecolor=color, facecolor="none")
        ax.add_patch(rect)

        # Display label
        ax.text(topleft_x, topleft_y - 10, label, color=color, fontsize=20)

    plt.show()

def plot_ground_truth_boxes_jsonl(image_file, jsonl_file):
    image_base_name = os.path.basename(image_file)
    ground_truth_data_found = False
    with open(jsonl_file) as fp:
        for line in fp.readlines():
            line_json = json.loads(line)
            filename = line_json["image_url"]
            if image_base_name in filename:
                ground_truth_data_found = True
                plot_ground_truth_boxes(image_file, line_json["label"])
                break
    if not ground_truth_data_found:
        print("Unable to find ground truth information for image: {}".format(image_file))

def plot_ground_truth_boxes_dataset(image_file, dataset_pd):
    image_base_name = os.path.basename(image_file)
    image_pd = dataset_pd[dataset_pd['portable_path'].str.contains(image_base_name)]
    if not image_pd.empty:
        ground_truth_boxes = image_pd.iloc[0]["label"]
        plot_ground_truth_boxes(image_file, ground_truth_boxes)
    else:
        print("Unable to find ground truth information for image: {}".format(image_file))

Usando le funzioni helper precedenti, per qualsiasi immagine specificata, è possibile eseguire il codice seguente per visualizzare le caselle di selezione.

image_file = "./odFridgeObjects/images/31.jpg"
jsonl_file = "./odFridgeObjects/train_annotations.jsonl"

plot_ground_truth_boxes_jsonl(image_file, jsonl_file)

Caricare dati e creare set di dati

Per usare i dati per il training, caricarlo nell'area di lavoro tramite un archivio dati. L'archivio dati fornisce un meccanismo per caricare o scaricare dati e interagire con esso dalle destinazioni di calcolo remote.

ds = ws.get_default_datastore()
ds.upload(src_dir='./odFridgeObjects', target_path='odFridgeObjects')

Dopo aver caricato nell'archivio dati, è possibile creare un set di dati di Azure Machine Learning dai dati. Set di dati in un oggetto di consumo per il training.

Il codice seguente crea un set di dati per il training. Poiché non viene specificato alcun set di dati di convalida, per impostazione predefinita viene usato il 20% dei dati di training per la convalida.

from azureml.core import Dataset
from azureml.data import DataType

training_dataset_name = 'odFridgeObjectsTrainingDataset'
if training_dataset_name in ws.datasets:
    training_dataset = ws.datasets.get(training_dataset_name)
    print('Found the training dataset', training_dataset_name)
else:
    # create training dataset
        # create training dataset
    training_dataset = Dataset.Tabular.from_json_lines_files(
        path=ds.path('odFridgeObjects/train_annotations.jsonl'),
        set_column_types={"image_url": DataType.to_stream(ds.workspace)},
    )
    training_dataset = training_dataset.register(workspace=ws, name=training_dataset_name)

print("Training dataset name: " + training_dataset.name)

Visualizzare il set di dati

È anche possibile visualizzare le caselle di selezione della verità di terra per un'immagine da questo set di dati.

Caricare il set di dati in un dataframe pandas.

import azureml.dataprep as dprep

from azureml.dataprep.api.functions import get_portable_path

# Get pandas dataframe from the dataset
dflow = training_dataset._dataflow.add_column(get_portable_path(dprep.col("image_url")),
                                              "portable_path", "image_url")
dataset_pd = dflow.to_pandas_dataframe(extended_types=True)

Per qualsiasi immagine specificata, è possibile eseguire il codice seguente per visualizzare le caselle di selezione.

image_file = "./odFridgeObjects/images/31.jpg"
plot_ground_truth_boxes_dataset(image_file, dataset_pd)

Configurare l'esperimento di rilevamento degli oggetti

Per configurare le esecuzioni automatizzate di MACHINE per le attività correlate all'immagine, usare l'oggetto AutoMLImageConfig . AutoMLImageConfigIn è possibile specificare gli algoritmi del modello con il model_name parametro e configurare le impostazioni per eseguire uno spazio di iperparametri su uno spazio di parametri definito per trovare il modello ottimale.

In questo esempio viene usato per eseguire il AutoMLImageConfig training di un modello di rilevamento oggetti con yolov5 e fasterrcnn_resnet50_fpn, entrambi pre-sottoposti a training in COCO, un rilevamento di oggetti su larga scala, segmentazione e set di dati di didascalia che contiene oltre migliaia di immagini etichettate con oltre 80 categorie di etichette.

Spaziatura iperparametri per le attività di immagine

È possibile eseguire uno spazzamento iperparametro su uno spazio di parametri definito per trovare il modello ottimale.

Il codice seguente definisce lo spazio dei parametri in preparazione dell'iperparametro per ogni algoritmo yolov5 definito e fasterrcnn_resnet50_fpn. Nello spazio dei parametri specificare l'intervallo di valori per learning_rate, optimizer, lr_schedulere così via, per AutoML da scegliere quando tenta di generare un modello con la metrica primaria ottimale. Se i valori di iperparametri non vengono specificati, i valori predefiniti vengono usati per ogni algoritmo.

Per le impostazioni di ottimizzazione, usare il campionamento casuale per selezionare esempi da questo spazio di parametri importando le GridParameterSampling, RandomParameterSampling classi e BayesianParameterSampling . In questo modo, indica a Machine Learning automatizzato di provare un totale di 20 iterazioni con questi diversi esempi, eseguendo quattro iterazioni alla volta sulla destinazione di calcolo, che è stata configurata usando quattro nodi. Più parametri hanno lo spazio, più iterazioni è necessario trovare modelli ottimali.

Viene usato anche il criterio di terminazione anticipata di Bandit. Questo criterio termina le configurazioni con prestazioni ridotte; ovvero quelle configurazioni che non si trovano all'interno del 20% della configurazione con prestazioni migliori, che salvano significativamente le risorse di calcolo.

from azureml.train.hyperdrive import RandomParameterSampling
from azureml.train.hyperdrive import BanditPolicy, HyperDriveConfig
from azureml.train.hyperdrive import choice, uniform

parameter_space = {
    'model': choice(
        {
            'model_name': choice('yolov5'),
            'learning_rate': uniform(0.0001, 0.01),
            #'model_size': choice('small', 'medium'), # model-specific
            'img_size': choice(640, 704, 768), # model-specific
        },
        {
            'model_name': choice('fasterrcnn_resnet50_fpn'),
            'learning_rate': uniform(0.0001, 0.001),
            #'warmup_cosine_lr_warmup_epochs': choice(0, 3),
            'optimizer': choice('sgd', 'adam', 'adamw'),
            'min_size': choice(600, 800), # model-specific
        }
    )
}

tuning_settings = {
    'iterations': 20,
    'max_concurrent_iterations': 4,
    'hyperparameter_sampling': RandomParameterSampling(parameter_space),
    'policy': BanditPolicy(evaluation_interval=2, slack_factor=0.2, delay_evaluation=6)
}

Dopo aver definito lo spazio dei parametri e le impostazioni di ottimizzazione, è possibile passarli all'oggetto AutoMLImageConfig e quindi inviare l'esperimento per eseguire il training di un modello di immagine usando il set di dati di training.

from azureml.train.automl import AutoMLImageConfig
automl_image_config = AutoMLImageConfig(task='image-object-detection',
                                        compute_target=compute_target,
                                        training_data=training_dataset,
                                        validation_data=validation_dataset,
                                        primary_metric='mean_average_precision',
                                        **tuning_settings)

automl_image_run = experiment.submit(automl_image_config)
automl_image_run.wait_for_completion(wait_post_processing=True)

Quando si esegue uno sweep di iperparametri, può essere utile visualizzare le diverse configurazioni che sono state tentate usando l'interfaccia utente di HyperDrive. È possibile passare a questa interfaccia utente passando alla scheda "Esecuzioni figlio" nell'interfaccia utente della automl_image_run principale da sopra, ovvero l'esecuzione padre di HyperDrive. È quindi possibile passare alla scheda "Esecuzioni figlio" di questa. In alternativa, qui di seguito è possibile visualizzare direttamente l'esecuzione padre di HyperDrive e passare alla scheda "Esecuzioni figlio":

from azureml.core import Run
hyperdrive_run = Run(experiment=experiment, run_id=automl_image_run.id + '_HD')
hyperdrive_run

Registrare il modello migliore

Al termine dell'esecuzione, è possibile registrare il modello creato dall'esecuzione migliore.

best_child_run = automl_image_run.get_best_child()
model_name = best_child_run.properties['model_name']
model = best_child_run.register_model(model_name = model_name, model_path='outputs/model.pt')

Distribuire il modello come servizio Web

Dopo aver eseguito il training del modello, è possibile distribuire il modello in Azure. È possibile distribuire il modello sottoposto a training come servizio Web in Istanze di Azure Container (ACI) o servizio Azure Kubernetes (Servizio Azure Kubernetes). ACI è l'opzione perfetta per i test delle distribuzioni, mentre il servizio Azure Kubernetes è più adatto per l'utilizzo su larga scala e di produzione.

In questa esercitazione viene distribuito il modello come servizio Web nel servizio Azure Kubernetes.

  1. Creare un cluster di calcolo del servizio Azure Kubernetes. In questo esempio viene usato uno SKU di macchina virtuale GPU per il cluster di distribuzione

    from azureml.core.compute import ComputeTarget, AksCompute
    from azureml.exceptions import ComputeTargetException
    
    # Choose a name for your cluster
    aks_name = "cluster-aks-gpu"
    
    # Check to see if the cluster already exists
    try:
        aks_target = ComputeTarget(workspace=ws, name=aks_name)
        print('Found existing compute target')
    except ComputeTargetException:
        print('Creating a new compute target...')
        # Provision AKS cluster with GPU machine
        prov_config = AksCompute.provisioning_configuration(vm_size="STANDARD_NC6",
                                                            location="eastus2")
        # Create the cluster
        aks_target = ComputeTarget.create(workspace=ws,
                                          name=aks_name,
                                          provisioning_configuration=prov_config)
        aks_target.wait_for_completion(show_output=True)
    
  2. Definire la configurazione dell'inferenza che descrive come configurare il servizio Web contenente il modello. È possibile usare lo script di assegnazione dei punteggi e l'ambiente dall'esecuzione del training nella configurazione di inferenza.

    Nota

    Per modificare le impostazioni del modello, aprire lo script di assegnazione dei punteggi scaricato e modificare la variabile di model_settings prima di distribuire il modello.

    from azureml.core.model import InferenceConfig
    
    best_child_run.download_file('outputs/scoring_file_v_1_0_0.py', output_file_path='score.py')
    environment = best_child_run.get_environment()
    inference_config = InferenceConfig(entry_script='score.py', environment=environment)
    
  3. È quindi possibile distribuire il modello come servizio Web del servizio Web del servizio Azure Kubernetes.

    
    from azureml.core.webservice import AksWebservice
    from azureml.core.webservice import Webservice
    from azureml.core.model import Model
    from azureml.core.environment import Environment
    
    aks_config = AksWebservice.deploy_configuration(autoscale_enabled=True,
                                                    cpu_cores=1,
                                                    memory_gb=50,
                                                    enable_app_insights=True)
    
    aks_service = Model.deploy(ws,
                               models=[model],
                               inference_config=inference_config,
                               deployment_config=aks_config,
                               deployment_target=aks_target,
                               name='automl-image-test',
                               overwrite=True)
    aks_service.wait_for_deployment(show_output=True)
    print(aks_service.state)
    

Testare il servizio Web

È possibile testare il servizio Web distribuito per stimare le nuove immagini. Per questa esercitazione, passare un'immagine casuale dal set di dati e passarla all'URI di assegnazione dei punteggi.

import requests

# URL for the web service
scoring_uri = aks_service.scoring_uri

# If the service is authenticated, set the key or token
key, _ = aks_service.get_keys()

sample_image = './test_image.jpg'

# Load image data
data = open(sample_image, 'rb').read()

# Set the content type
headers = {'Content-Type': 'application/octet-stream'}

# If authentication is enabled, set the authorization header
headers['Authorization'] = f'Bearer {key}'

# Make the request and display the response
resp = requests.post(scoring_uri, data, headers=headers)
print(resp.text)

Visualizzare i rilevamenti

Dopo aver ottenuto il punteggio di un'immagine di test, è possibile visualizzare le caselle di selezione per questa immagine. A tale scopo, assicurarsi di avere installato matplotlib.

%pip install --upgrade matplotlib
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import matplotlib.patches as patches
from PIL import Image
import numpy as np
import json

IMAGE_SIZE = (18,12)
plt.figure(figsize=IMAGE_SIZE)
img_np=mpimg.imread(sample_image)
img = Image.fromarray(img_np.astype('uint8'),'RGB')
x, y = img.size

fig,ax = plt.subplots(1, figsize=(15,15))
# Display the image
ax.imshow(img_np)

# draw box and label for each detection
detections = json.loads(resp.text)
for detect in detections['boxes']:
    label = detect['label']
    box = detect['box']
    conf_score = detect['score']
    if conf_score > 0.6:
        ymin, xmin, ymax, xmax =  box['topY'],box['topX'], box['bottomY'],box['bottomX']
        topleft_x, topleft_y = x * xmin, y * ymin
        width, height = x * (xmax - xmin), y * (ymax - ymin)
        print('{}: [{}, {}, {}, {}], {}'.format(detect['label'], round(topleft_x, 3),
                                                round(topleft_y, 3), round(width, 3),
                                                round(height, 3), round(conf_score, 3)))

        color = np.random.rand(3) #'red'
        rect = patches.Rectangle((topleft_x, topleft_y), width, height,
                                 linewidth=3, edgecolor=color,facecolor='none')

        ax.add_patch(rect)
        plt.text(topleft_x, topleft_y - 10, label, color=color, fontsize=20)

plt.show()

Pulire le risorse

Se si intende eseguire altre esercitazioni su Azure Machine Learning, non completare questa sezione.

Se non si prevede di usare le risorse create, eliminarle per evitare addebiti.

  1. Nel portale di Azure fare clic su Gruppi di risorse all'estrema sinistra.
  2. Nell'elenco selezionare il gruppo di risorse creato.
  3. Selezionare Elimina gruppo di risorse.
  4. Immettere il nome del gruppo di risorse. Selezionare Elimina.

È anche possibile mantenere il gruppo di risorse ma eliminare una singola area di lavoro. Visualizzare le proprietà dell'area di lavoro e selezionare Elimina.

Passaggi successivi

In questa esercitazione sulla modalità automatizzata di apprendimento automatico sono state eseguite queste attività:

  • Configurare un'area di lavoro e preparare i dati per un esperimento.
  • Training di un modello di rilevamento oggetti automatizzato
  • Valori di iperparametri specificati per il modello
  • Esecuzione di uno spazzamento di iperparametri
  • Distribuzione del modello
  • Rilevamenti visualizzati

Nota

L'uso del set di dati degli oggetti frigorifero è disponibile tramite la licenza con la licenza MIT.