Zelfstudie: Een objectdetectiemodel (preview) trainen met AutoML en Python (v1)

VAN TOEPASSING OP:Python SDK azureml v1

Belangrijk

De functies die in dit artikel worden beschreven, zijn in preview. Ze moeten worden beschouwd als experimentele preview-functies die op elk gewenst moment kunnen worden gewijzigd.

In deze zelfstudie leert u hoe u een objectdetectiemodel traint met behulp van geautomatiseerde ML van Azure Machine Learning met de Azure Machine Learning Python SDK. Dit objectdetectiemodel geeft aan of de afbeelding objecten bevat, zoals een blik, karton, melkfles of waterfles.

Geautomatiseerde ML accepteert trainingsgegevens en configuratie-instellingen en itereert automatisch combinaties van verschillende methoden voor normalisatie/standaardisatie van functies, modellen en hyperparameters om tot het beste model te komen.

In deze zelfstudie schrijft u code met behulp van de Python SDK en leert u de volgende taken:

  • Gegevens downloaden en transformeren
  • Een geautomatiseerd machine learning-objectdetectiemodel trainen
  • Hyperparameterwaarden opgeven voor uw model
  • Een hyperparameter-sweep uitvoeren
  • Uw model implementeren
  • Detecties visualiseren

Vereisten

  • Als u geen Azure-abonnement hebt, maak dan een gratis account voordat u begint. Probeer vandaag nog de gratis of betaalde versie van Azure Machine Learning.

  • Python 3.7 of 3.8 worden ondersteund voor deze functie

  • Voltooi de Quickstart: Aan de slag met Azure Machine Learning als u nog geen Azure Machine Learning-werkruimte hebt.

  • Download hetodFridgeObjects.zipgegevensbestand en pak het * uit. De gegevensset is voorzien van aantekeningen in Pascal VOC-indeling, waarbij elke afbeelding overeenkomt met een XML-bestand. Elk XML-bestand bevat informatie over waar het bijbehorende afbeeldingsbestand zich bevindt en bevat ook informatie over de begrenzingsvakken en de objectlabels. Als u deze gegevens wilt gebruiken, moet u deze eerst converteren naar de vereiste JSONL-indeling, zoals wordt weergegeven in de sectie De gedownloade gegevens converteren naar JSONL van het notebook.

Deze zelfstudie is ook beschikbaar in de opslagplaats azureml-examples op GitHub als u deze in uw eigen lokale omgeving wilt uitvoeren. Om de vereiste pakketten te downloaden

Instellen van rekendoel

U moet eerst een rekendoel instellen voor gebruik voor uw geautomatiseerde ML-modeltraining. Geautomatiseerde ML-modellen voor afbeeldingstaken vereisen GPU-SKU's.

In deze zelfstudie wordt gebruikgemaakt van de NCsv3-serie (met V100-GPU's), omdat dit type rekendoel gebruikmaakt van meerdere GPU's om de training te versnellen. Daarnaast kunt u meerdere knooppunten instellen om te profiteren van parallelle uitvoering bij het afstemmen van hyperparameters voor uw model.

Met de volgende code maakt u een GPU-berekening van de grootte Standard _NC24s_v3 met vier knooppunten die zijn gekoppeld aan de werkruimte, ws.

Waarschuwing

Zorg ervoor dat uw abonnement voldoende quotum heeft voor het rekendoel dat u wilt gebruiken.

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)

Experiment instellen

Maak vervolgens een Experiment in uw werkruimte om de uitvoeringen van uw modeltraining bij te houden.


from azureml.core import Experiment

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

Invoergegevens visualiseren

Zodra u de invoerafbeeldingsgegevens hebt voorbereid in JSONL-indeling (JSONL-lijnen ), kunt u de begrenzingsvakken voor de grondwaarheid voor een afbeelding visualiseren. Zorg ervoor dat u dit hebt matplotlib geïnstalleerd.

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

Met behulp van de bovenstaande helperfuncties kunt u voor elke afbeelding de volgende code uitvoeren om de begrenzingsvakken weer te geven.

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

plot_ground_truth_boxes_jsonl(image_file, jsonl_file)

Gegevens uploaden en gegevensset maken

Als u de gegevens wilt gebruiken voor training, uploadt u deze naar uw werkruimte via een gegevensarchief. Het gegevensarchief biedt een mechanisme waarmee u gegevens kunt uploaden of downloaden en ermee kunt werken vanaf uw externe rekendoelen.

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

Na het uploaden naar het gegevensarchief kunt u een Azure Machine Learning-gegevensset maken op basis van de gegevens. Gegevenssets verpakken uw gegevens in een verbruiksobject voor training.

Met de volgende code maakt u een gegevensset voor training. Omdat er geen validatiegegevensset is opgegeven, wordt standaard 20% van uw trainingsgegevens gebruikt voor validatie.

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)

Gegevensset visualiseren

U kunt ook de begrenzingsvakken voor de grondwaarheid visualiseren voor een afbeelding uit deze gegevensset.

Laad de gegevensset in een pandas-gegevensframe.

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)

Voor een bepaalde afbeelding kunt u de volgende code uitvoeren om de begrenzingsvakken weer te geven.

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

Uw objectdetectieexperiment configureren

Gebruik het AutoMLImageConfig -object om geautomatiseerde ML-uitvoeringen te configureren voor taken met betrekking tot installatiekopieën. In uw AutoMLImageConfigkunt u de modelalgoritmen opgeven met de model_name parameter en de instellingen configureren om een hyperparameter-sweep uit te voeren over een gedefinieerde parameterruimte om het optimale model te vinden.

In dit voorbeeld gebruiken we de AutoMLImageConfig om een objectdetectiemodel te trainen met yolov5 en fasterrcnn_resnet50_fpn, die beide vooraf zijn getraind op COCO, een grootschalige gegevensset voor objectdetectie, segmentatie en bijschriften die meer dan duizenden gelabelde afbeeldingen met meer dan 80 labelcategorieën bevat.

Hyperparameter opruimen voor afbeeldingstaken

U kunt een hyperparameter-sweep uitvoeren over een gedefinieerde parameterruimte om het optimale model te vinden.

De volgende code definieert de parameterruimte ter voorbereiding op de hyperparameter-sweep voor elk gedefinieerd algoritme, yolov5 en fasterrcnn_resnet50_fpn. Geef in de parameterruimte het waardenbereik op voor learning_rate, optimizer, lr_scheduler, enzovoort, waaruit AutoML moet kiezen wanneer wordt geprobeerd een model te genereren met de optimale primaire metrische gegevens. Als er geen hyperparameterwaarden worden opgegeven, worden voor elk algoritme standaardwaarden gebruikt.

Voor de afstemmingsinstellingen gebruikt u willekeurige steekproeven om voorbeelden uit deze parameterruimte te kiezen door de GridParameterSampling, RandomParameterSampling klassen en BayesianParameterSampling te importeren. Als u dit doet, moet geautomatiseerde ML in totaal 20 iteraties proberen met deze verschillende voorbeelden, waarbij vier iteraties tegelijk worden uitgevoerd op ons rekendoel, dat is ingesteld met behulp van vier knooppunten. Hoe meer parameters de ruimte heeft, hoe meer iteraties u nodig hebt om optimale modellen te vinden.

Het beleid voor vroegtijdige beëindiging van Bandit wordt ook gebruikt. Dit beleid beëindigt slecht presterende configuraties; dat wil gezegd, configuraties die niet binnen 20% marge van de best presterende configuratie liggen, waardoor rekenresources aanzienlijk worden bespaard.

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

Zodra de parameterruimte en afstemmingsinstellingen zijn gedefinieerd, kunt u deze doorgeven aan uw AutoMLImageConfig object en vervolgens het experiment verzenden om een afbeeldingsmodel te trainen met behulp van uw trainingsgegevensset.

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)

Wanneer u een hyperparameter-sweep uitvoert, kan het handig zijn om de verschillende configuraties te visualiseren die zijn geprobeerd met behulp van de Gebruikersinterface van HyperDrive. U kunt naar deze gebruikersinterface navigeren door naar het tabblad Onderliggende uitvoeringen te gaan in de gebruikersinterface van de hoofd-automl_image_run hierboven. Dit is de bovenliggende HyperDrive-uitvoering. Vervolgens kunt u naar het tabblad 'Onderliggende uitvoeringen' van dit tabblad gaan. U kunt ook hieronder rechtstreeks de bovenliggende HyperDrive-uitvoering zien en naar het tabblad Onderliggende uitvoeringen navigeren:

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

Het beste model registreren

Zodra de uitvoering is voltooid, kunnen we het model registreren dat is gemaakt op basis van de beste uitvoering.

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

Model implementeren als een webservice

Zodra u het getrainde model hebt, kunt u het model implementeren in Azure. U kunt uw getrainde model implementeren als een webservice op Azure Container Instances (ACI) of Azure Kubernetes Service (AKS). ACI is de perfecte optie voor het testen van implementaties, terwijl AKS beter geschikt is voor grootschalige productiegebruik.

In deze zelfstudie implementeren we het model als een webservice in AKS.

  1. Een AKS-rekencluster maken. In dit voorbeeld wordt een SKU van de virtuele GPU-machine gebruikt voor het implementatiecluster

    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. Definieer de deductieconfiguratie die beschrijft hoe u de webservice met uw model instelt. U kunt het scorescript en de omgeving van de trainingsuitvoering gebruiken in uw deductieconfiguratie.

    Notitie

    Als u de instellingen van het model wilt wijzigen, opent u het gedownloade scorescript en wijzigt u de variabele model_settings voordat u het model implementeert.

    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. Vervolgens kunt u het model implementeren als een AKS-webservice.

    
    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)
    

De webservice testen

U kunt de geïmplementeerde webservice testen om nieuwe afbeeldingen te voorspellen. Voor deze zelfstudie geeft u een willekeurige afbeelding uit de gegevensset door en geeft u deze door aan de score-URI.

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)

Detecties visualiseren

Nu u een testafbeelding hebt gescoord, kunt u de begrenzingsvakken voor deze afbeelding visualiseren. Zorg ervoor dat u matplotlib hebt geïnstalleerd om dit te doen.

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

Resources opschonen

Voer deze sectie niet uit als u van plan bent andere Azure Machine Learning-zelfstudies uit te voeren.

Als u niet van plan bent om gebruik te maken van de resources die u hebt gemaakt, kunt u ze verwijderen zodat er geen kosten voor in rekening worden gebracht.

  1. Selecteer Resourcegroepen links in Azure Portal.
  2. Selecteer de resourcegroep die u eerder hebt gemaakt uit de lijst.
  3. Selecteer Resourcegroep verwijderen.
  4. Voer de naam van de resourcegroup in. Selecteer vervolgens Verwijderen.

U kunt de resourcegroep ook bewaren en slechts één werkruimte verwijderen. Bekijk de eigenschappen van de werkruimte en selecteer Verwijderen.

Volgende stappen

In deze zelfstudie over geautomatiseerde machine learning hebt u het volgende gedaan:

  • U hebt een werkruimte geconfigureerd en gegevens voorbereid voor een experiment.
  • Een geautomatiseerd objectdetectiemodel getraind
  • Opgegeven hyperparameterwaarden voor uw model
  • Een hyperparameter-sweep uitgevoerd
  • Uw model geïmplementeerd
  • Gevisualiseerde detecties

Notitie

Het gebruik van de gegevensset koelkastobjecten is beschikbaar via de licentie onder de MIT-licentie.