Tutorial: Treine um modelo de deteção de objetos (pré-visualização) com AutoML e Python (v1)

APLICA-SE A:Python SDK azureml v1

Importante

Os comandos Azure CLI neste artigo requerem a azure-cli-mlextensão , ou v1, para Azure Machine Learning. Recomendamos que selecione v2 (corrente) para o V2 CLI melhorado utilizando a ml extensão. Para mais informações, consulte Machine Learning CLI (v1).

Importante

As funcionalidades apresentadas neste artigo estão em pré-visualização. Devem ser considerados funcionalidades experimentais de pré-visualização que podem mudar a qualquer momento.

Neste tutorial, você aprende a treinar um modelo de deteção de objetos usando Azure Machine Learning automatizado ML com o Azure Machine Learning Python SDK. Este modelo de deteção de objetos identifica se a imagem contém objetos, tais como uma lata, caixa, garrafa de leite ou garrafa de água.

A ML automatizada aceita definições de dados de formação e configurações, e itera automaticamente através de combinações de diferentes métodos de normalização/normalização de funcionalidades, modelos e configurações de hiperparímetro para chegar ao melhor modelo.

Você vai escrever código usando o Python SDK neste tutorial e aprender as seguintes tarefas:

  • Descarregar e transformar dados
  • Treine um modelo automatizado de deteção de objetos de aprendizagem automática
  • Especifique valores de hiperparmetro para o seu modelo
  • Realizar uma varredura de hiperparmetro
  • Implemente o seu modelo
  • Visualizar deteções

Pré-requisitos

  • Se não tiver uma subscrição do Azure, crie uma conta gratuita antes de começar. Experimente hoje a versão gratuita ou paga do Azure Machine Learning.

  • Python 3.6 ou 3.7 são suportados para esta característica

  • Complete o Quickstart: Começa com o Azure Machine Learning se ainda não tiveres um espaço de trabalho para aprendizagem automática Azure.

  • Faça o download e desaperte o * ficheiro de dadosodFridgeObjects.zip. O conjunto de dados é anotado no formato Pascal VOC, onde cada imagem corresponde a um ficheiro xml. Cada ficheiro xml contém informações sobre onde está localizado o seu ficheiro de imagem correspondente e também contém informações sobre as caixas de delimitação e as etiquetas do objeto. Para utilizar estes dados, primeiro tem de os converter no formato JSONL necessário, tal como visto na secção Converte os dados descarregados para a secção JSONL do caderno.

Este tutorial também está disponível no repositório de exemplos azureml no GitHub se você quiser executá-lo em seu próprio ambiente local. Para obter os pacotes necessários,

Configuração do alvo do cálculo

Primeiro, você precisa configurar um alvo de computação para usar para o seu treino automatizado de modelo ml. Os modelos ML automatizados para tarefas de imagem requerem SKUs GPU.

Este tutorial usa a série NCsv3 (com GPUs V100) como este tipo de alvo de computação aproveita vários GPUs para acelerar o treino. Além disso, pode configurar múltiplos nós para aproveitar o paralelismo ao sintonizar hiperparmetros para o seu modelo.

O código a seguir cria um cálculo GPU de tamanho Standard _NC24s_v3 com quatro nós que estão ligados ao espaço de trabalho, ws.

Aviso

Certifique-se de que a sua subscrição tem quota suficiente para o alvo de computação que pretende utilizar.

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)

Configuração de experiências

Em seguida, crie um Experiment no seu espaço de trabalho para acompanhar as suas corridas de treino de modelo.


from azureml.core import Experiment

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

Visualizar dados de entrada

Uma vez preparados os dados de imagem de entrada no formato JSONL (Linhas JSON), pode visualizar as caixas de delimitação da verdade terrestre para uma imagem. Para tal, certifique-se de que já matplotlib instalou.

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

Utilizando as funções de ajudante acima, para qualquer imagem, pode executar o seguinte código para exibir as caixas de delimitação.

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

plot_ground_truth_boxes_jsonl(image_file, jsonl_file)

Faça upload de dados e crie conjunto de dados

Para utilizar os dados para treino, faça o upload para o seu espaço de trabalho através de uma datastore. A datastore fornece um mecanismo para que você carremeja ou descarregue dados, e interaja com ele a partir dos seus alvos de computação remota.

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

Uma vez enviado para a datastore, pode criar um conjunto de dados Azure Machine Learning a partir dos dados. Os conjuntos de dados embalam os seus dados num objeto consumível para treino.

O seguinte código cria um conjunto de dados para o treino. Uma vez que não é especificado nenhum conjunto de dados de validação, por padrão 20% dos seus dados de formação são utilizados para validação.

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)

Visualizar conjunto de dados

Também pode visualizar as caixas de limites da verdade terrestre para uma imagem deste conjunto de dados.

Carregue o conjunto de dados num dataframe de 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)

Para qualquer imagem, pode executar o seguinte código para exibir as caixas de delimitação.

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

Configure a sua experiência de deteção de objetos

Para configurar ml automatizado corre para tarefas relacionadas com a imagem, use o AutoMLImageConfig objeto. No seu AutoMLImageConfig, pode especificar os algoritmos do modelo com o model_name parâmetro e configurar as definições para realizar uma varredura de hiperparímetro sobre um espaço de parâmetro definido para encontrar o modelo ideal.

Neste exemplo, utilizamos o AutoMLImageConfig para formar um modelo de deteção de objetos com yolov5 e fasterrcnn_resnet50_fpn, ambos pré-treinados no COCO, um conjunto de dados de deteção, segmentação e legendagem de objetos em larga escala que contém mais de milhares de imagens etiquetadas com mais de 80 categorias de etiquetas.

Hiperparametro varrendo para tarefas de imagem

Pode executar uma varredura de hiperparímetro sobre um espaço de parâmetro definido para encontrar o modelo ideal.

O seguinte código, define o espaço dos parâmetros em preparação para a varredura do hiperparímetro para cada algoritmo definido, yolov5 e fasterrcnn_resnet50_fpn. No espaço dos parâmetros, especifique a gama de valores paralearning_rate, optimizerlr_scheduleretc., para que o AutoML escolha à medida que tenta gerar um modelo com a métrica primária ideal. Se os valores do hiperparmetro não forem especificados, então os valores predefinidos são usados para cada algoritmo.

Para as definições de afinação, utilize amostras aleatórias para recolher amostras deste espaço de parâmetros importando as GridParameterSampling, RandomParameterSampling classes e BayesianParameterSampling as classes. Ao fazê-lo, diz à ML automatizada para experimentar um total de 20 iterações com estas amostras diferentes, executando quatro iterações de cada vez no nosso alvo computacional, que foi criado usando quatro nós. Quanto mais parâmetros o espaço tiver, mais iterações precisa para encontrar modelos ideais.

A política de rescisão antecipada do bandido também é utilizada. Esta política encerra configurações de mau desempenho; ou seja, aquelas configurações que não estão dentro de 20% da redução da configuração de melhor desempenho, o que poupa significativamente recursos computacional.

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

Uma vez definidas as definições de espaço e afinação dos parâmetros, pode passá-las para o seu AutoMLImageConfig objeto e, em seguida, submeter a experiência para treinar um modelo de imagem utilizando o seu conjunto de dados de treino.

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)

Ao fazer uma varredura de hiperparímetro, pode ser útil visualizar as diferentes configurações que foram experimentantes usando o HyperDrive UI. Você pode navegar para este UI indo para o separador 'Child runs' no UI do automl_image_run principal de cima, que é a corrida dos pais do HyperDrive. Depois podes ir ao separador "Criança corre" desta. Alternativamente, aqui abaixo pode ver diretamente a corrida dos pais do HyperDrive e navegar para o separador 'Child runs':

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

Registar o melhor modelo

Uma vez concluída a corrida, podemos registar o modelo que foi criado a partir da melhor execução.

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

Implementar o modelo como um serviço web

Assim que tiver o seu modelo treinado, pode implantar o modelo no Azure. Pode implementar o seu modelo treinado como serviço web em Azure Container Instances (ACI) ou Azure Kubernetes Service (AKS). O ACI é a opção perfeita para testar implementações, enquanto a AKS é mais adequada para uma utilização de produção de alta escala.

Neste tutorial, implementamos o modelo como um serviço web em AKS.

  1. Crie um cluster de computação AKS. Neste exemplo, uma máquina virtual GPU SKU é usada para o cluster de implantação

    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. Defina a configuração de inferência que descreve como configurar o serviço web que contém o seu modelo. Você pode usar o script de pontuação e o ambiente da corrida de treino na sua inferência config.

    Nota

    Para alterar as definições do modelo, abra o script de pontuação descarregado e modifique a variável model_settings antes de implementar o modelo.

    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. Em seguida, pode implementar o modelo como um serviço web 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)
    

Testar o serviço Web

Pode testar o serviço web implantado para prever novas imagens. Para este tutorial, passe uma imagem aleatória do conjunto de dados e passe-a para o URI de pontuação.

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)

Visualizar deteções

Agora que marcou uma imagem de teste, pode visualizar as caixas de delimitação para esta imagem. Para tal, certifique-se de que tem matplotlib instalado.

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

Limpar os recursos

Não preencha esta secção se planeia executar outros tutoriais de Aprendizagem automática Azure.

Se não planeia usar os recursos que criou, elimine-os, para não incorrer em quaisquer encargos.

  1. No portal do Azure, selecione Grupos de recursos na extremidade esquerda.
  2. Na lista, selecione o grupo de recursos que criou.
  3. Selecione Eliminar grupo de recursos.
  4. Introduza o nome do grupo de recursos. Em seguida, selecione Eliminar.

Também pode manter o grupo de recursos, mas apagar um único espaço de trabalho. Exiba as propriedades do espaço de trabalho e selecione Delete.

Passos seguintes

Neste tutorial automatizado de aprendizagem automática, fez as seguintes tarefas:

  • Configurar um espaço de trabalho e preparar dados para uma experiência.
  • Treinado um modelo automatizado de deteção de objetos
  • Valores de hiperparmetro especificados para o seu modelo
  • Realizou uma varredura de hiperparmetro
  • Implementou o seu modelo
  • Deteções visualizadas

Nota

A utilização do conjunto de dados de objetos do frigorífico está disponível através da licença ao abrigo da Licença MIT.