Självstudie: Träna en objektidentifieringsmodell (förhandsversion) med AutoML och Python (v1)

GÄLLER FÖR:Python SDK azureml v1

Viktigt

Funktionerna som presenteras i den här artikeln är i förhandsversion. De bör betraktas som experimentella förhandsgranskningsfunktioner som kan ändras när som helst.

I den här självstudien får du lära dig hur du tränar en objektidentifieringsmodell med azure machine learning automatiserad ML med Azure Machine Learning Python SDK. Den här objektidentifieringsmodellen identifierar om bilden innehåller objekt, till exempel burk, kartong, mjölkflaska eller vattenflaska.

Automatiserad ML accepterar inställningar för träningsdata och konfiguration och itererar automatiskt genom kombinationer av olika funktionsnormaliserings-/standardiseringsmetoder, modeller och hyperparameterinställningar för att komma fram till den bästa modellen.

Du skriver kod med python-SDK:et i den här självstudien och lär dig följande uppgifter:

  • Ladda ned och transformera data
  • Träna en modell för identifiering av automatiserade maskininlärningsobjekt
  • Ange hyperparametervärden för din modell
  • Utföra en hyperparameterrensning
  • Distribuera din modell
  • Visualisera identifieringar

Förutsättningar

  • Om du inte har en Azure-prenumeration kan du skapa ett kostnadsfritt konto innan du börjar. Prova den kostnadsfria eller betalda versionen av Azure Machine Learning idag.

  • Python 3.7 eller 3.8 stöds för den här funktionen

  • Slutför snabbstarten: Kom igång med Azure Machine Learning om du inte redan har en Azure Machine Learning-arbetsyta.

  • Ladda ned och packa upp odFridgeObjects.zip-datafilen*. Datauppsättningen kommenteras i Pascal VOC-format, där varje bild motsvarar en XML-fil. Varje XML-fil innehåller information om var dess motsvarande bildfil finns och innehåller även information om avgränsningsrutorna och objektetiketterna. För att kunna använda dessa data måste du först konvertera dem till det JSONL-format som krävs enligt avsnittet Konvertera nedladdade data till JSONL i notebook-filen.

Den här självstudien är också tillgänglig på lagringsplatsen azureml-examples på GitHub om du vill köra den i din egen lokala miljö. Hämta de paket som krävs genom att

Konfiguration av beräkningsmål

Du måste först konfigurera ett beräkningsmål som ska användas för din automatiserade ML-modellträning. Automatiserade ML-modeller för avbildningsuppgifter kräver GPU-SKU:er.

I den här självstudien används NCsv3-serien (med V100 GPU:er) eftersom den här typen av beräkningsmål utnyttjar flera GPU:er för att påskynda träningen. Dessutom kan du konfigurera flera noder för att dra nytta av parallellitet när du justerar hyperparametrar för din modell.

Följande kod skapar en GPU-beräkning av storleken Standard _NC24s_v3 med fyra noder som är kopplade till arbetsytan, ws.

Varning

Se till att din prenumeration har en tillräcklig kvot för det beräkningsmål som du vill använda.

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)

Experimentkonfiguration

Skapa sedan en Experiment i din arbetsyta för att spåra dina modellträningskörningar.


from azureml.core import Experiment

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

Visualisera indata

När du har förberett indata för bilddata i JSONL-format (JSON Lines) kan du visualisera avgränsningsrutorna för grund sanning för en bild. Det gör du genom att kontrollera att du har matplotlib installerat.

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

Med hjälpfunktionerna ovan kan du för en viss bild köra följande kod för att visa avgränsningsrutorna.

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

plot_ground_truth_boxes_jsonl(image_file, jsonl_file)

Ladda upp data och skapa en datauppsättning

Om du vill använda data för träning laddar du upp dem till din arbetsyta via ett datalager. Datalagringen ger dig en mekanism för att ladda upp eller ladda ned data och interagera med dem från dina fjärrberäkningsmål.

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

När du har laddat upp till datalagringen kan du skapa en Azure Machine Learning-datamängd från data. Datauppsättningar paketera dina data i ett förbrukningsbart objekt för träning.

Följande kod skapar en datauppsättning för träning. Eftersom ingen valideringsdatauppsättning har angetts används som standard 20 % av dina träningsdata för validering.

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)

Visualisera datauppsättning

Du kan också visualisera avgränsningsrutorna för grund sanning för en bild från den här datauppsättningen.

Läs in datauppsättningen i en Pandas-dataram.

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)

För en viss bild kan du köra följande kod för att visa avgränsningsrutorna.

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

Konfigurera objektidentifieringsexperimentet

Om du vill konfigurera automatiserade ML-körningar för avbildningsrelaterade uppgifter använder du objektet AutoMLImageConfig . I kan AutoMLImageConfigdu ange modellalgoritmerna med parametern model_name och konfigurera inställningarna för att utföra en hyperparameterrensning över ett definierat parameterutrymme för att hitta den optimala modellen.

I det här exemplet använder AutoMLImageConfig vi för att träna en objektidentifieringsmodell med yolov5 och fasterrcnn_resnet50_fpn, som båda tränas på COCO, en storskalig objektidentifiering, segmentering och textningsdatauppsättning som innehåller över tusentals etiketterade bilder med över 80 etikettkategorier.

Hyperparametersgenomsökning för bilduppgifter

Du kan utföra en hyperparameterrensning över ett definierat parameterutrymme för att hitta den optimala modellen.

Följande kod definierar parameterutrymmet som förberedelse för hyperparameterrensningen för varje definierad algoritm, yolov5 och fasterrcnn_resnet50_fpn. I parameterutrymmet anger du intervallet med värden för learning_rate, optimizer, lr_schedulerosv. för AutoML att välja mellan när den försöker generera en modell med det optimala primära måttet. Om hyperparametervärden inte anges används standardvärdena för varje algoritm.

För justeringsinställningarna använder du slumpmässig sampling för att välja exempel från det här parameterutrymmet genom att importera klasserna GridParameterSampling, RandomParameterSampling och BayesianParameterSampling . På så sätt instruerar automatiserad ML att prova totalt 20 iterationer med dessa olika exempel och köra fyra iterationer åt gången på vårt beräkningsmål, som konfigurerades med hjälp av fyra noder. Ju fler parametrar utrymmet har, desto fler iterationer behöver du för att hitta optimala modeller.

Policyn för tidig uppsägning av Bandit används också. Den här principen avslutar konfigurationer med dåliga prestanda. Det vill säger de konfigurationer som inte ligger inom 20 % slack av den bäst presterande konfigurationen, vilket avsevärt sparar beräkningsresurser.

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

När parameterutrymmet och justeringsinställningarna har definierats kan du skicka dem till objektet AutoMLImageConfig och sedan skicka experimentet för att träna en bildmodell med hjälp av din träningsdatauppsättning.

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)

När du gör en hyperparameterrensning kan det vara användbart att visualisera de olika konfigurationer som provades med hjälp av HyperDrive-användargränssnittet. Du kan navigera till det här användargränssnittet genom att gå till fliken Underordnade körningar i användargränssnittet för huvudgränssnittet automl_image_run ovan, vilket är den överordnade HyperDrive-körningen. Sedan kan du gå till fliken Underordnade körningar i den här. Här nedan kan du också se den överordnade HyperDrive-körningen direkt och navigera till fliken Underordnade körningar:

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

Registrera den bästa modellen

När körningen är klar kan vi registrera modellen som skapades från den bästa körningen.

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

Distribuera modell som en webbtjänst

När du har din tränade modell kan du distribuera modellen i Azure. Du kan distribuera din tränade modell som en webbtjänst på Azure Container Instances (ACI) eller Azure Kubernetes Service (AKS). ACI är det perfekta alternativet för att testa distributioner, medan AKS passar bättre för storskalig produktionsanvändning.

I den här självstudien distribuerar vi modellen som en webbtjänst i AKS.

  1. Skapa ett AKS-beräkningskluster. I det här exemplet används en SKU för en virtuell GPU-dator för distributionsklustret

    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. Definiera den slutsatsdragningskonfiguration som beskriver hur du konfigurerar webbtjänsten som innehåller din modell. Du kan använda bedömningsskriptet och miljön från träningskörningen i din slutsatsdragningskonfiguration.

    Anteckning

    Om du vill ändra modellens inställningar öppnar du det nedladdade bedömningsskriptet och ändrar variabeln model_settings innan du distribuerar modellen.

    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. Du kan sedan distribuera modellen som en AKS-webbtjänst.

    
    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)
    

Testa webbtjänsten

Du kan testa den distribuerade webbtjänsten för att förutsäga nya avbildningar. I den här självstudien skickar du en slumpmässig bild från datauppsättningen och skickar den till bedömnings-URI:n.

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)

Visualisera identifieringar

Nu när du har fått en testbild kan du visualisera avgränsningsrutorna för den här bilden. Det gör du genom att kontrollera att matplotlib är installerat.

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

Rensa resurser

Slutför inte det här avsnittet om du planerar att köra andra Azure Machine Learning-självstudier.

Om du inte planerar att använda de resurser som du skapade tar du bort dem, så att du inte debiteras några avgifter.

  1. I Azure-portalen väljer du Resursgrupper längst till vänster.
  2. Välj den resursgrupp i listan som du har skapat.
  3. Välj Ta bort resursgrupp.
  4. Ange resursgruppsnamnet. Välj sedan Ta bort.

Du kan också behålla resursgruppen men ta bort en enstaka arbetsyta. Visa arbetsytans egenskaper och välj Ta bort.

Nästa steg

I den här automatiserade självstudiekursen om maskininlärning har du gjort följande uppgifter:

  • Konfigurerat en arbetsyta och förberett data för ett experiment.
  • Tränat en modell för automatisk objektidentifiering
  • Angivna hyperparametervärden för din modell
  • Utförde en hyperparameterrensning
  • Distribuerat din modell
  • Visualiserade identifieringar

Anteckning

Användning av datamängden kylobjekt är tillgänglig via licensen enligt MIT-licensen.