Kurz: Trénování modelu detekce objektů (Preview) pomocí AutoML a Pythonu (v1)

PLATÍ PRO:Sada Python SDK azureml v1

Důležité

Funkce uvedené v tomto článku jsou ve verzi Preview. Měly by být považovány za experimentální funkce Preview, které se můžou kdykoli změnit.

V tomto kurzu se naučíte vytrénovat model detekce objektů pomocí automatizovaného strojového učení Azure Machine Learning pomocí sady Python SDK služby Azure Machine Learning. Tento model detekce objektů identifikuje, jestli obrázek obsahuje objekty, jako je plechovku, karton, láhev od mléka nebo láhev s vodou.

Automatizované strojové učení přijímá trénovací data a nastavení konfigurace a automaticky iteruje prostřednictvím kombinací různých metod normalizace/standardizace funkcí, modelů a nastavení hyperparametrů, aby bylo možné dosáhnout nejlepšího modelu.

V tomto kurzu napíšete kód pomocí sady Python SDK a naučíte se následující úlohy:

  • Stažení a transformace dat
  • Trénování modelu detekce objektů automatizovaného strojového učení
  • Určení hodnot hyperparametrů pro model
  • Provedení úklidu hyperparametrů
  • Nasazení modelu
  • Vizualizace detekcí

Požadavky

  • Pokud ještě nemáte předplatné Azure, vytvořte si bezplatný účet před tím, než začnete. Vyzkoušejte bezplatnou nebo placenou verzi služby Azure Machine Learning ještě dnes.

  • Tato funkce podporuje Python 3.7 nebo 3.8.

  • Dokončete rychlý start: Začínáme se službou Azure Machine Learning , pokud ještě nemáte pracovní prostor Služby Azure Machine Learning.

  • Stáhněte a rozbalte * datový souborodFridgeObjects.zip . Datová sada je opatřena poznámkami ve formátu Pascal VOC, kde každý obrázek odpovídá souboru XML. Každý soubor XML obsahuje informace o umístění odpovídajícího souboru obrázku a také informace o ohraničující rámečky a popisky objektů. Abyste mohli tato data použít, musíte je nejprve převést do požadovaného formátu JSONL, jak je vidět v poznámkovém bloku v části Převod stažených dat na JSONL .

Tento kurz je také k dispozici v úložišti azureml-examples na GitHubu , pokud ho chcete spustit ve vlastním místním prostředí. Pokud chcete získat požadované balíčky,

Nastavení cílového výpočetního prostředí

Nejprve musíte nastavit cílový výpočetní objekt, který se použije pro trénování automatizovaného modelu ML. Automatizované modely STROJOVÉho učení pro úlohy imagí vyžadují skladové položky GPU.

V tomto kurzu se používá řada NCsv3 (s grafickými procesory V100), protože tento typ výpočetního cíle využívá k urychlení trénování několik GPU. Kromě toho můžete nastavit více uzlů tak, aby při ladění hyperparametrů pro váš model využívaly výhod paralelismu.

Následující kód vytvoří výpočetní výkon GPU o velikosti Standard _NC24s_v3 se čtyřmi uzly, které jsou připojené k pracovnímu prostoru ws.

Upozornění

Ujistěte se, že vaše předplatné má dostatečnou kvótu pro cílový výpočetní objekt, který chcete použít.

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)

Nastavení experimentu

Dále v pracovním prostoru vytvořte objekt Experiment pro sledování trénovacích běhů modelu.


from azureml.core import Experiment

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

Vizualizace vstupních dat

Jakmile budete mít vstupní data obrázku připravená ve formátu JSONL (JSON Lines), můžete vizualizovat rámečky ohraničení základní pravdy pro obrázek. Pokud to chcete udělat, ujistěte se, že jste nainstalovali 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 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))

Pomocí výše uvedených pomocných funkcí můžete pro libovolný obrázek spustit následující kód, který zobrazí ohraničující rámečky.

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

plot_ground_truth_boxes_jsonl(image_file, jsonl_file)

Nahrání dat a vytvoření datové sady

Pokud chcete data použít pro trénování, nahrajte je do pracovního prostoru prostřednictvím úložiště dat. Úložiště dat poskytuje mechanismus pro nahrávání nebo stahování dat a interakci s nimi ze vzdálených cílových výpočetních prostředků.

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

Po nahrání do úložiště dat můžete z dat vytvořit datovou sadu Azure Machine Learning. Datové sady zabalí data do využitelného objektu pro trénování.

Následující kód vytvoří datovou sadu pro trénování. Vzhledem k tomu, že není zadána žádná ověřovací datová sada, použije se k ověření ve výchozím nastavení 20 % trénovacích dat.

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)

Vizualizace datové sady

Můžete také vizualizovat rámečky ohraničení základní pravdy pro obrázek z této datové sady.

Načtěte datovou sadu do datového rámce 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)

U libovolného obrázku můžete spustit následující kód, který zobrazí ohraničující rámečky.

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

Konfigurace experimentu detekce objektů

Pokud chcete nakonfigurovat automatizovaná spuštění ML pro úlohy související s imagemi, použijte AutoMLImageConfig objekt . V nástroji AutoMLImageConfigmůžete zadat algoritmy modelu pomocí parametru model_name a nakonfigurovat nastavení tak, aby provedlo přemet hyperparametrů v definovaném prostoru parametrů a našel optimální model.

V tomto příkladu AutoMLImageConfig použijeme k vytrénování modelu detekce objektů s yolov5 a fasterrcnn_resnet50_fpn, z nichž oba jsou předem vytrénované ve službě COCO, což je rozsáhlá datová sada detekce objektů, segmentace a titulkování, která obsahuje více než tisíce označených obrázků s více než 80 kategoriemi popisků.

Úklid hyperparametrů pro úlohy obrázků

Pokud chcete najít optimální model, můžete provést úklid hyperparametrů v definovaném prostoru parametrů.

Následující kód definuje prostor parametrů v přípravě pro hyperparametrový úklid pro každý definovaný algoritmus yolov5 a fasterrcnn_resnet50_fpn. V prostoru parametrů zadejte rozsah hodnot pro learning_rate, optimizer, lr_scheduleratd. Pro AutoML si můžete vybrat při pokusu o vygenerování modelu s optimální primární metrikou. Pokud nejsou zadané hodnoty hyperparametrů, použijí se pro každý algoritmus výchozí hodnoty.

Pro nastavení ladění použijte náhodné vzorkování k výběru vzorků z tohoto prostoru parametrů importováním GridParameterSampling, RandomParameterSampling tříd a BayesianParameterSampling . Automatizované strojové učení tím řekne, aby s těmito různými ukázkami vyzkoušelo celkem 20 iterací a spustilo čtyři iterace najednou na našem výpočetním cíli, který byl nastavený pomocí čtyř uzlů. Čím více parametrů prostor má, tím více iterací potřebujete k nalezení optimálních modelů.

Používají se také zásady předčasného ukončení banditu. Tato zásada ukončí konfigurace s nízkým výkonem. to znamená, že konfigurace, které nedosáhnou 20% časové rezervy od konfigurace s nejlepším výkonem, což výrazně šetří výpočetní prostředky.

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

Jakmile je prostor parametrů a nastavení ladění definované, můžete je předat do objektu AutoMLImageConfig a pak odeslat experiment k trénování obrázkového modelu pomocí trénovací datové sady.

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)

Při úklidu hyperparametrů může být užitečné vizualizovat různé konfigurace, které byly vyzkoušeny pomocí uživatelského rozhraní HyperDrive. K tomuto uživatelskému rozhraní můžete přejít tak, že přejdete na kartu Podřízená spuštění v uživatelském rozhraní hlavního automl_image_run shora, což je nadřazené spuštění HyperDrivu. Pak můžete přejít na kartu Podřízená spuštění v této kartě. Případně si níže můžete přímo prohlédnout nadřazené spuštění HyperDrivu a přejít na jeho kartu Podřízená spuštění:

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

Registrace nejlepšího modelu

Po dokončení spuštění můžeme zaregistrovat model vytvořený z nejlepšího spuštění.

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

Nasazení modelu jako webové služby

Jakmile budete mít natrénovaný model, můžete ho nasadit do Azure. Natrénovaný model můžete nasadit jako webovou službu na Azure Container Instances (ACI) nebo Azure Kubernetes Service (AKS). ACI je ideální volbou pro testování nasazení, zatímco AKS je vhodnější pro velké využití v produkčním prostředí.

V tomto kurzu nasadíme model jako webovou službu v AKS.

  1. Vytvořte výpočetní cluster AKS. V tomto příkladu se pro cluster nasazení používá skladová položka virtuálního počítače GPU.

    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. Definujte konfiguraci odvozování, která popisuje, jak nastavit webovou službu obsahující váš model. V konfiguraci odvozování můžete použít bodovací skript a prostředí z trénovacího běhu.

    Poznámka

    Pokud chcete změnit nastavení modelu, otevřete stažený bodovací skript a před nasazením modelu upravte proměnnou model_settings.

    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. Model pak můžete nasadit jako webovou službu AKS.

    
    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)
    

Otestování webové služby

Nasazenou webovou službu můžete otestovat a předpovědět nové image. Pro účely tohoto kurzu předejte náhodný obrázek z datové sady a předejte ho do hodnoticího identifikátoru 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)

Vizualizace detekcí

Teď, když jste získali skóre testovacího obrázku, můžete vizualizovat ohraničující rámečky pro tento obrázek. Pokud to chcete udělat, ujistěte se, že máte nainstalovaný 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()

Vyčištění prostředků

Pokud plánujete spustit další kurzy služby Azure Machine Learning, tuto část nedokonejte.

Pokud vytvořené prostředky neplánujete používat, odstraňte je, aby se vám neúčtovaly žádné poplatky.

  1. Úplně nalevo na webu Azure Portal vyberte Skupiny prostředků.
  2. V seznamu vyberte skupinu prostředků, kterou jste vytvořili.
  3. Vyberte Odstranit skupinu prostředků.
  4. Zadejte název skupiny prostředků. Vyberte Odstranit.

Můžete také zachovat skupinu prostředků, ale odstranit jeden pracovní prostor. Zobrazte vlastnosti pracovního prostoru a vyberte Odstranit.

Další kroky

V tomto kurzu automatizovaného strojového učení jste provedli následující úlohy:

  • Nakonfigurovali jste pracovní prostor a připravili data pro experiment.
  • Trénování modelu automatizovaného rozpoznávání objektů
  • Zadané hodnoty hyperparametrů pro váš model
  • Provedli jsme úklid hyperparametrů.
  • Nasazený model
  • Vizualizované detekce

Poznámka

Použití datové sady objektů chladničky je k dispozici prostřednictvím licence v rámci licence MIT License.