Sdílet prostřednictvím


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

PLATÍ PRO: Python SDK azureml v1

Důležité

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

V tomto kurzu se naučíte trénovat model rozpoznávání objektů pomocí automatizovaného strojového učení Azure Machine Learning pomocí sady Azure Machine Learning Python SDK. Tento model rozpoznávání objektů identifikuje, jestli obrázek obsahuje objekty, jako je plechovky, krabička, láhev mléka nebo láhev vody.

Automatizované strojové učení přijímá trénovací data a nastavení konfigurace a automaticky iteruje kombinací různých metod normalizace a standardizace funkcí, modelů a nastavení hyperparametrů, aby bylo dosaženo 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 automatizovaného rozpoznávání objektů strojového učení
  • Zadání hodnot hyperparametrů pro váš model
  • Provedení úklidu hyperparametrů
  • Nasazení modelu
  • Vizualizace detekcí

Požadavky

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 objektu

Nejdřív musíte nastavit cílový výpočetní objekt, který se použije pro trénování automatizovaného modelu ML. Modely automatizovaného 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 cílového výpočetního objektu využívá k urychlení trénování více GPU. Kromě toho můžete nastavit více uzlů, abyste při ladění hyperparametrů pro váš model využili paralelismu.

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

Upozorňující

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

V dalším kroku vytvořte v pracovním prostoru pro Experiment 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 máte vstupní data obrázků připravená ve formátu JSONL (řádky JSON), můžete vizualizovat rámečky ohraničující pravdu 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í pro libovolný obrázek můžete 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 k trénování, nahrajte je do svého 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í vaše data do spotřebního objektu pro trénování.

Následující kód vytvoří datovou sadu pro trénování. Vzhledem k tomu, že není zadaná žádná ověřovací datová sada, ve výchozím nastavení se k ověření používá 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 uzemněnou pravdu ohraničující rámečky obrázku 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ů

Ke konfiguraci automatizovaných spuštění strojového AutoMLImageConfig učení pro úlohy související s imagemi použijte objekt. Ve svém AutoMLImageConfignástroji můžete zadat algoritmy modelu s parametrem model_name a nakonfigurovat nastavení tak, aby prováděla úklid hyperparametrů nad definovaným prostorem parametrů, abyste našli optimální model.

V tomto příkladu AutoMLImageConfig používáme k trénování modelu detekce objektů předem yolov5 fasterrcnn_resnet50_fpnnatrénovaný v COCO, rozsáhlé detekci objektů, segmentaci a popisovací datovou sadu, která obsahuje více než tisíc obrázků s popisky 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ů nad definovaným prostorem parametrů.

Následující kód definuje prostor parametrů při přípravě pro úklid hyperparametrů pro každý definovaný algoritmus yolov5 a fasterrcnn_resnet50_fpn. V prostoru parametrů zadejte rozsah hodnot pro learning_rate, optimizerlr_scheduler, atd., pro AutoML zvolit, když se pokusí vygenerovat model s optimální primární metrikou. Pokud nejsou zadány hodnoty hyperparametrů, použijí se výchozí hodnoty pro každý algoritmus.

Pro nastavení ladění použijte náhodné vzorkování k výběru vzorků z tohoto prostoru parametrů importováním GridParameterSampling, RandomParameterSampling a BayesianParameterSampling tříd. Tím sdělíte automatizovanému strojovému učení, aby vyzkoušelo celkem 20 iterací s těmito různými ukázkami a spustilo čtyři iterace najednou na našem cílovém výpočetním objektu, které se nastavily pomocí čtyř uzlů. Čím více parametrů prostor má, tím více iterací potřebujete najít optimální modely.

Používá se také zásada předčasného ukončení banditu. Tato zásada ukončí konfigurace s nízkým výkonem; to znamená, že konfigurace, které nejsou v rámci 20% časové rezervy nejlepší konfigurace, 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)
}

Po definování prostoru parametrů a nastavení ladění je můžete předat do AutoMLImageConfig objektu a pak experiment odeslat k trénování modelu obrázku 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é se pokusily použít uživatelské rozhraní HyperDrivu. 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 z výše uvedeného, což je nadřazené spuštění HyperDrivu. Pak můžete přejít na kartu Podřízená spuštění této. Případně níže vidíte přímo nadřazené spuštění HyperDrivu a přejděte 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 v Azure. Trénovaný model můžete nasadit jako webovou službu ve službě Azure Container Instances (ACI) nebo Azure Kubernetes Service (AKS). ACI je ideální možností pro testování nasazení, zatímco AKS je vhodnější pro vysoce škálovatelné produkční využití.

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. Skript bodování a prostředí můžete použít z trénovacího spuštění v konfiguraci odvozování.

    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 nainstalovanou 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 nedokončení neprovádějte.

Pokud nechcete používat prostředky, které jste vytvořili, odstraňte je, takže se vám nebudou účtovat žá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ů. Poté 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í modelu
  • Vizualizované detekce

Poznámka:

Použití datové sady objektů ledniček je dostupné prostřednictvím licence MIT License.