Tutorial sui container Edge

Dopo aver creato un modello AutoML Vision Edge ed averlo esportato in un bucket di Google Cloud Storage, puoi utilizzare i servizi RESTful con i tuoi modelli AutoML ML Vision Edge e le immagini Docker TF Serving.

Cosa devi creare

I container Docker possono aiutarti a eseguire facilmente il deployment di modelli periferici su dispositivi diversi. Puoi eseguire modelli periferici richiamando le API REST dai container con il linguaggio che preferisci, con il vantaggio aggiuntivo di non dover installare dipendenze o di trovare versioni di TensorFlow adeguate.

In questo tutorial, avrai un'esperienza passo passo dell'esecuzione di modelli perimetrali sui dispositivi che utilizzano container Docker.

Nello specifico, in questo tutorial vengono illustrati tre passaggi:

  1. Recupero dei container predefiniti.
  2. Esecuzione di container con modelli Edge per avviare le API REST.
  3. Generazione di previsioni.

Molti dispositivi hanno solo CPU, mentre alcuni potrebbero avere GPU per ottenere previsioni più rapide. Per questo motivo, forniamo tutorial con container preconfigurati e GPU GPU.

Obiettivi

In questa presentazione dettagliata end-to-end, utilizzerai esempi di codice per:

  1. Recupera il container Docker.
  2. Avvia le API REST utilizzando i container Docker con modelli perimetrali.
  3. Effettua previsioni per ottenere risultati analizzati.

Prima di iniziare

Per completare questo tutorial devi:

  1. Addestra un modello Edge esportabile. Segui la guida rapida sul modello di dispositivo Edge per addestrare un modello Edge.
  2. Esporta un modello AutoML Vision Edge. Questo modello verrà pubblicato con i container come API REST.
  3. Installa Docker. Si tratta del software richiesto per eseguire i container Docker.
  4. (Facoltativo) Installa docker e driver NVIDIA. Si tratta di un passaggio facoltativo se hai dispositivi con GPU e vuoi ricevere previsioni più veloci.
  5. Prepara le immagini di test. Queste immagini verranno inviate nelle richieste per ottenere risultati analizzati.

La sezione che segue contiene informazioni dettagliate sull'esportazione dei modelli e sull'installazione del software necessario.

Esporta modello AutoML Vision Edge

Dopo aver addestrato un modello Edge, puoi esportarlo in diversi dispositivi.

I container supportano i modelli TensorFlow, chiamati saved_model.pb in fase di esportazione.

Per esportare un modello AutoML Vision Edge per i container, seleziona la scheda Container nella UI, quindi esporta il modello in ${YOUR_MODEL_PATH} su Google Cloud Storage. Questo modello esportato verrà pubblicato con i container come API REST in un secondo momento.

Opzione Esporta in contenitore

Per scaricare il modello esportato in locale, esegui questo comando.

Dove:

  • ${YOUR_MODEL_PATH} - La località del modello su Google Cloud Storage (ad esempio, gs://my-bucket-vcm/models/edge/ICN4245971651915048908/2020-01-20_01-27-14-064_tf-saved-model/)
  • ${YOUR_LOCAL_MODEL_PATH} - Il percorso locale in cui vuoi scaricare il modello (ad esempio, /tmp).
gsutil cp ${YOUR_MODEL_PATH} ${YOUR_LOCAL_MODEL_PATH}/saved_model.pb

Installa Docker

Docker è un software utilizzato per il deployment e l'esecuzione di applicazioni all'interno dei container.

Installa Docker Community Edition (CE) sul tuo sistema. Lo utilizzerai per gestire i modelli Edge come API REST.

Installa il driver NVIDIA e NVIDIA DOCKER (facoltativo, solo per GPU)

Alcuni dispositivi hanno una GPU per fornire previsioni più veloci. Viene fornito il container docker GPU per supportare le GPU NVIDIA.

Per eseguire i container GPU, devi installare il driver NVIDIA e Docker IDIA Docker nel tuo sistema.

Esecuzione dell'inferenza del modello mediante CPU

Questa sezione fornisce istruzioni dettagliate per eseguire le inferenze del modello utilizzando i container CPU. Utilizzerai il Docker installato per eseguire ed eseguire il container della CPU in modo da gestire i modelli Edge esportati come API REST e poi inviare le richieste di un'immagine di test alle API REST per ottenere i risultati analizzati.

Esegui il pull dell'immagine Docker

Innanzitutto, utilizzerai Docker per ottenere un container della CPU predefinito. Il container predefinito della CPU ha già l'intero ambiente per gestire i modelli Edge esportati, che non contiene ancora modelli Edge.

Il container CPU predefinito è archiviato in Google Container Registry. Prima di richiedere il container, imposta una variabile di ambiente per la sua posizione in Google Container Registry:

export CPU_DOCKER_GCS_PATH=gcr.io/cloud-devrel-public-resources/gcloud-container-1.14.0:latest

Dopo aver impostato la variabile di ambiente per il percorso Container Registry, esegui la riga di comando seguente per ottenere il container CPU:

sudo docker pull ${CPU_DOCKER_GCS_PATH}

Esegui il container Docker

Dopo aver ottenuto il container esistente, eseguirai questo container CPU per gestire le inferenze del modello Edge con le API REST.

Prima di iniziare il container CPU, devi impostare le variabili di sistema:

  • ${CONTAINER_NAME} - Una stringa che indica il nome del container quando viene eseguito, ad esempio CONTAINER_NAME=automl_high_accuracy_model_cpu.
  • ${PORT} - Un numero che indica la porta nel dispositivo in modo da poter accettare le chiamate API REST in un secondo momento, come PORT=8501.

Dopo aver impostato le variabili, esegui Docker nella riga di comando per gestire le inferenze del modello Edge con le API REST:

sudo docker run --rm --name ${CONTAINER_NAME} -p ${PORT}:8501 -v ${YOUR_MODEL_PATH}:/tmp/mounted_model/0001 -t ${CPU_DOCKER_GCS_PATH}

Una volta eseguito correttamente il container, le API REST sono pronte per essere pubblicate in http://localhost:${PORT}/v1/models/default:predict. La sezione seguente spiega come inviare richieste di previsione a questa località.

Invia una richiesta di previsione

Ora che il container è in esecuzione, puoi inviare una richiesta di previsione su un'immagine di test alle API REST.

Riga di comando

Il corpo della richiesta della riga di comando contiene l'elemento image_bytes con codifica base64 e una stringa key per identificare l'immagine fornita. Consulta l'argomento Codifica Base64 per ulteriori informazioni sulla codifica delle immagini. Il formato del file JSON della richiesta è il seguente:

/tmp/request.json
{
  "instances":
  [
    {
      "image_bytes":
      {
        "b64": "/9j/7QBEUGhvdG9zaG9...base64-encoded-image-content...fXNWzvDEeYxxxzj/Coa6Bax//Z"
      },
      "key": "your-chosen-image-key"
    }
  ]
}

Dopo aver creato un file di richiesta JSON locale, puoi inviare la tua richiesta di previsione.

Utilizza il seguente comando per inviare la richiesta di previsione:

curl -X POST -d  @/tmp/request.json http://localhost:${PORT}/v1/models/default:predict
Risposta

Dovresti vedere un output simile al seguente:

{
  "predictions": [
    {
      "detection_multiclass_scores": [
        [0.00233048, 0.00207388, 0.00123361, 0.0052332, 0.00132892, 0.00333592],
        [0.00233048, 0.00207388, 0.00123361, 0.0052332, 0.00132892, 0.00333592],
        [0.00240907, 0.00173151, 0.00134027, 0.00287125, 0.00130472, 0.00242674],
        [0.00227344, 0.00124374, 0.00147101, 0.00377446, 0.000997812, 0.0029003],
        [0.00132903, 0.000844955, 0.000537515, 0.00474253, 0.000508994, 0.00130466],
        [0.00233048, 0.00207388, 0.00123361, 0.0052332, 0.00132892, 0.00333592],
        [0.00110534, 0.000204086, 0.000247836, 0.000553966, 0.000193745, 0.000359297],
        [0.00112912, 0.000443578, 0.000779897, 0.00203282, 0.00069508, 0.00188044],
        [0.00271052, 0.00163364, 0.00138229, 0.00314173, 0.00164038, 0.00332257],
        [0.00227907, 0.00217116, 0.00190553, 0.00321552, 0.00233933, 0.0053153],
        [0.00271052, 0.00163364, 0.00138229, 0.00314173, 0.00164038, 0.00332257],
        [0.00250274, 0.000489146, 0.000879943, 0.00355569, 0.00129834, 0.00355521],
        [0.00227344, 0.00124374, 0.00147101, 0.00377446, 0.000997812, 0.0029003],
        [0.00241205, 0.000786602, 0.000896335, 0.00187016, 0.00106838, 0.00193021],
        [0.00132069, 0.00173706, 0.00389183, 0.00536761, 0.00387135, 0.00752795],
        [0.0011555, 0.00025022, 0.000221372, 0.000536889, 0.000187278, 0.000306398],
        [0.00150242, 0.000391901, 0.00061205, 0.00158429, 0.000300348, 0.000788659],
        [0.00181362, 0.000169843, 0.000458032, 0.000690967, 0.000296295, 0.000412017],
        [0.00101465, 0.000184, 0.000148445, 0.00068599, 0.000111818, 0.000290155],
        [0.00128508, 0.00108775, 0.00298983, 0.00174832, 0.00143594, 0.00285548],
        [0.00137702, 0.000480384, 0.000831485, 0.000920624, 0.000405788, 0.000735044],
        [0.00103369, 0.00152704, 0.000892937, 0.00269693, 0.00214335, 0.00588191],
        [0.0013324, 0.000647604, 0.00293729, 0.00156629, 0.00195253, 0.00239435],
        [0.0022423, 0.00141206, 0.0012649, 0.00450748, 0.00138766, 0.00249887],
        [0.00125939, 0.0002428, 0.000370741, 0.000917137, 0.00024578, 0.000412881],
        [0.00135186, 0.000139147, 0.000525713, 0.00103053, 0.000366062, 0.000844955],
        [0.00127548, 0.000989318, 0.00256863, 0.00162545, 0.00311682, 0.00439551],
        [0.00112912, 0.000443578, 0.000779897, 0.00203282, 0.00069508, 0.00188044],
        [0.00114602, 0.00107747, 0.00145, 0.00320849, 0.00211915, 0.00331426],
        [0.00148326, 0.00059548, 0.00431389, 0.00164703, 0.00311947, 0.00268343],
        [0.00154313, 0.000925034, 0.00770769, 0.00252789, 0.00489518, 0.00352332],
        [0.00135094, 0.00042069, 0.00088492, 0.000987828, 0.000755847, 0.00144881],
        [0.0015994, 0.000540197, 0.00163212, 0.00140327, 0.00114474, 0.0026556],
        [0.00150502, 0.000138223, 0.000343591, 0.000529736, 0.000173837, 0.000381887],
        [0.00127372, 0.00066787, 0.00149515, 0.00272799, 0.00110033, 0.00370145],
        [0.00144503, 0.000365585, 0.00318581, 0.00126475, 0.00212631, 0.00204816],
        [0.00132069, 0.00173706, 0.00389183, 0.00536761, 0.00387135, 0.00752795],
        [0.00198057, 0.000307024, 0.000573188, 0.00147268, 0.000757724, 0.0017142],
        [0.00157535, 0.000590324, 0.00190055, 0.00170627, 0.00138417, 0.00246152],
        [0.00177169, 0.000364572, 0.00183856, 0.000767767, 0.00121492, 0.000916481]
      ],
      "detection_classes":
        [5.0, 2.0, 5.0, 5.0, 5.0, 4.0, 5.0, 5.0, 4.0, 4.0, 2.0, 4.0, 4.0, 4.0, 5.0, 4.0, 5.0,
        5.0, 4.0, 5.0, 5.0, 4.0, 5.0, 2.0, 4.0, 4.0, 5.0, 4.0, 4.0, 5.0, 5.0, 5.0, 5.0, 4.0, 4.0,
        5.0, 4.0, 4.0, 5.0, 5.0],
      "num_detections": 40.0,
      "image_info": [320, 320, 1, 0, 320, 320],
      "detection_boxes": [
        [0.457792, 0.0, 0.639324, 0.180828],
        [0.101111, 0.0, 0.89904, 0.995376],
        [0.447649, 0.314644, 0.548206, 0.432875],
        [0.250341, 0.733411, 0.3419, 0.847185],
        [0.573936, 0.0933048, 0.766472, 0.208054],
        [0.490438, 0.194659, 0.825894, 0.563959],
        [0.619383, 0.57948, 0.758244, 0.694948],
        [0.776185, 0.554518, 0.841549, 0.707129],
        [0.101111, 0.0, 0.89904, 0.995376],
        [0.431243, 0.0917888, 0.850772, 0.617123],
        [0.250883, 0.13572, 0.780518, 0.817881],
        [0.327646, 0.878977, 0.607503, 0.989904],
        [0.573936, 0.0933048, 0.766472, 0.208054],
        [0.37792, 0.460952, 0.566977, 0.618865],
        [0.373325, 0.575019, 0.463646, 0.642949],
        [0.27251, 0.0714827, 0.790764, 0.77176],
        [0.725154, 0.561221, 0.849777, 0.702165],
        [0.37549, 0.558988, 0.460575, 0.626821],
        [0.265563, 0.248368, 0.785451, 0.977509],
        [0.605674, 0.597553, 0.760419, 0.744799],
        [0.400611, 0.327271, 0.487579, 0.424036],
        [0.48632, 0.980808, 0.606008, 0.997468],
        [0.542414, 0.0588853, 0.752879, 0.200775],
        [0.490438, 0.194659, 0.825894, 0.563959],
        [0.368839, 0.115654, 0.741839, 0.587659],
        [0.467101, 0.985155, 0.588853, 0.997708],
        [0.755204, 0.561319, 0.836475, 0.676249],
        [0.409855, 0.302322, 0.773464, 0.587772],
        [0.351938, 0.934163, 0.587043, 0.99954],
        [0.27758, 0.72402, 0.334137, 0.846945],
        [0.29875, 0.601199, 0.381122, 0.679323],
        [0.64637, 0.566566, 0.767553, 0.67331],
        [0.372612, 0.596795, 0.457588, 0.666544],
        [0.438422, 0.989558, 0.578529, 0.998366],
        [0.586531, 0.499894, 0.879711, 0.845526],
        [0.608476, 0.644501, 0.759154, 0.827037],
        [0.352501, 0.477601, 0.710863, 0.948605],
        [0.466184, 0.953443, 0.668056, 0.996681],
        [0.547756, 0.00152373, 0.722814, 0.150687],
        [0.759639, 0.548476, 0.866864, 0.722007]
      ],
      "detection_scores":
        [0.877304, 0.839354, 0.824509, 0.579912, 0.461549, 0.306151, 0.268687, 0.197998, 0.181444,
        0.17856, 0.152705, 0.148958, 0.14726, 0.135506, 0.128483, 0.12234, 0.105697, 0.105665,
        0.0941569, 0.0891062, 0.0845169, 0.0810551, 0.0794339, 0.0784486, 0.0771784, 0.0770716,
        0.075339, 0.0716749, 0.0715761, 0.07108, 0.0705339, 0.0693555, 0.0677402, 0.0644643,
        0.0631491, 0.062369, 0.0619523, 0.060859, 0.0601122, 0.0589799],
      "detection_classes_as_text":
        ["Tomato", "Salad", "Tomato", "Tomato", "Tomato", "Seafood", "Tomato", "Tomato", "Seafood",
        "Seafood", "Salad", "Seafood", "Seafood", "Seafood", "Tomato", "Seafood", "Tomato",
        "Tomato", "Seafood", "Tomato", "Tomato", "Seafood", "Tomato", "Salad", "Seafood",
        "Seafood", "Tomato", "Seafood", "Seafood", "Tomato", "Tomato", "Tomato", "Tomato",
        "Seafood", "Seafood", "Tomato", "Seafood", "Seafood", "Tomato", "Tomato"],
      "key": "1"
    }
  ]
}

Python

import base64
import cv2
import io
import json

import requests

def preprocess_image(image_file_path, max_width, max_height):
    """Preprocesses input images for AutoML Vision Edge models.

    Args:
        image_file_path: Path to a local image for the prediction request.
        max_width: The max width for preprocessed images. The max width is 640
            (1024) for AutoML Vision Image Classfication (Object Detection)
            models.
        max_height: The max width for preprocessed images. The max height is
            480 (1024) for AutoML Vision Image Classfication (Object
            Detetion) models.
    Returns:
        The preprocessed encoded image bytes.
    """
    # cv2 is used to read, resize and encode images.
    encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 85]
    im = cv2.imread(image_file_path)
    [height, width, _] = im.shape
    if height > max_height or width > max_width:
        ratio = max(height / float(max_width), width / float(max_height))
        new_height = int(height / ratio + 0.5)
        new_width = int(width / ratio + 0.5)
        resized_im = cv2.resize(
            im, (new_width, new_height), interpolation=cv2.INTER_AREA)
        _, processed_image = cv2.imencode('.jpg', resized_im, encode_param)
    else:
        _, processed_image = cv2.imencode('.jpg', im, encode_param)
    return base64.b64encode(processed_image).decode('utf-8')

def container_predict(image_file_path, image_key, port_number=8501):
    """Sends a prediction request to TFServing docker container REST API.

    Args:
        image_file_path: Path to a local image for the prediction request.
        image_key: Your chosen string key to identify the given image.
        port_number: The port number on your device to accept REST API calls.
    Returns:
        The response of the prediction request.
    """
    # AutoML Vision Edge models will preprocess the input images.
    # The max width and height for AutoML Vision Image Classification and
    # Object Detection models are 640*480 and 1024*1024 separately. The
    # example here is for Image Classification models.
    encoded_image = preprocess_image(
        image_file_path=image_file_path, max_width=640, max_height=480)

    # The example here only shows prediction with one image. You can extend it
    # to predict with a batch of images indicated by different keys, which can
    # make sure that the responses corresponding to the given image.
    instances = {
            'instances': [
                    {'image_bytes': {'b64': str(encoded_image)},
                     'key': image_key}
            ]
    }

    # This example shows sending requests in the same server that you start
    # docker containers. If you would like to send requests to other servers,
    # please change localhost to IP of other servers.
    url = 'http://localhost:{}/v1/models/default:predict'.format(port_number)

    response = requests.post(url, data=json.dumps(instances))
    print(response.json())

(Facoltativo) Esegui il modello di inferenza utilizzando i container GPU

Questa sezione mostra come eseguire le inferenze del modello utilizzando i container GPU. Questo processo è molto simile all'esecuzione dell'inferenza del modello mediante una CPU. Le differenze principali sono il percorso del container GPU e la modalità di avvio dei container GPU.

Esegui il pull dell'immagine Docker

Innanzitutto, utilizzerai Docker per ottenere un container GPU predefinito. Il container predefinito di GPU ha già l'ambiente per gestire i modelli Edge esportati con GPU, che non contengono ancora modelli Edge o i driver.

Il container CPU predefinito è archiviato in Google Container Registry. Prima di richiedere il container, imposta una variabile di ambiente per la sua posizione in Google Container Registry:

export GPU_DOCKER_GCS_PATH=gcr.io/cloud-devrel-public-resources/gcloud-container-1.14.0-gpu:latest

Esegui la seguente riga di comando per ottenere il container GPU:

sudo docker pull ${GPU_DOCKER_GCS_PATH}

Esegui il container Docker

Questo passaggio eseguirà il container GPU per gestire le inferenze del modello Edge con le API REST. Devi installare il driver NVIDIA e il docker come indicato in precedenza. Inoltre, devi impostare le seguenti variabili di sistema:

  • ${CONTAINER_NAME} - Una stringa che indica il nome del container quando viene eseguito, ad esempio CONTAINER_NAME=automl_high_accuracy_model_gpu.
  • ${PORT} - Un numero che indica la porta nel dispositivo in modo da poter accettare le chiamate API REST in un secondo momento, come PORT=8502.

Dopo aver impostato le variabili, esegui Docker nella riga di comando per gestire le inferenze del modello Edge con le API REST:

sudo docker run --runtime=nvidia --rm --name "${CONTAINER_NAME}" -v \
${YOUR_MODEL_PATH}:/tmp/mounted_model/0001 -p \
${PORT}:8501 -t ${GPU_DOCKER_GCS_PATH}

Una volta eseguito correttamente il container, le API REST sono pronte per essere pubblicate in http://localhost:${PORT}/v1/models/default:predict. La sezione seguente spiega come inviare richieste di previsione a questa località.

Invia una richiesta di previsione

Ora che il container è in esecuzione, puoi inviare una richiesta di previsione su un'immagine di test alle API REST.

Riga di comando

Il corpo della richiesta della riga di comando contiene l'elemento image_bytes con codifica base64 e una stringa key per identificare l'immagine fornita. Consulta l'argomento Codifica Base64 per ulteriori informazioni sulla codifica delle immagini. Il formato del file JSON della richiesta è il seguente:

/tmp/request.json
{
  "instances":
  [
    {
      "image_bytes":
      {
        "b64": "/9j/7QBEUGhvdG9zaG9...base64-encoded-image-content...fXNWzvDEeYxxxzj/Coa6Bax//Z"
      },
      "key": "your-chosen-image-key"
    }
  ]
}

Dopo aver creato un file di richiesta JSON locale, puoi inviare la tua richiesta di previsione.

Utilizza il seguente comando per inviare la richiesta di previsione:

curl -X POST -d  @/tmp/request.json http://localhost:${PORT}/v1/models/default:predict
Risposta

Dovresti vedere un output simile al seguente:

{
  "predictions": [
    {
      "detection_multiclass_scores": [
        [0.00233048, 0.00207388, 0.00123361, 0.0052332, 0.00132892, 0.00333592],
        [0.00233048, 0.00207388, 0.00123361, 0.0052332, 0.00132892, 0.00333592],
        [0.00240907, 0.00173151, 0.00134027, 0.00287125, 0.00130472, 0.00242674],
        [0.00227344, 0.00124374, 0.00147101, 0.00377446, 0.000997812, 0.0029003],
        [0.00132903, 0.000844955, 0.000537515, 0.00474253, 0.000508994, 0.00130466],
        [0.00233048, 0.00207388, 0.00123361, 0.0052332, 0.00132892, 0.00333592],
        [0.00110534, 0.000204086, 0.000247836, 0.000553966, 0.000193745, 0.000359297],
        [0.00112912, 0.000443578, 0.000779897, 0.00203282, 0.00069508, 0.00188044],
        [0.00271052, 0.00163364, 0.00138229, 0.00314173, 0.00164038, 0.00332257],
        [0.00227907, 0.00217116, 0.00190553, 0.00321552, 0.00233933, 0.0053153],
        [0.00271052, 0.00163364, 0.00138229, 0.00314173, 0.00164038, 0.00332257],
        [0.00250274, 0.000489146, 0.000879943, 0.00355569, 0.00129834, 0.00355521],
        [0.00227344, 0.00124374, 0.00147101, 0.00377446, 0.000997812, 0.0029003],
        [0.00241205, 0.000786602, 0.000896335, 0.00187016, 0.00106838, 0.00193021],
        [0.00132069, 0.00173706, 0.00389183, 0.00536761, 0.00387135, 0.00752795],
        [0.0011555, 0.00025022, 0.000221372, 0.000536889, 0.000187278, 0.000306398],
        [0.00150242, 0.000391901, 0.00061205, 0.00158429, 0.000300348, 0.000788659],
        [0.00181362, 0.000169843, 0.000458032, 0.000690967, 0.000296295, 0.000412017],
        [0.00101465, 0.000184, 0.000148445, 0.00068599, 0.000111818, 0.000290155],
        [0.00128508, 0.00108775, 0.00298983, 0.00174832, 0.00143594, 0.00285548],
        [0.00137702, 0.000480384, 0.000831485, 0.000920624, 0.000405788, 0.000735044],
        [0.00103369, 0.00152704, 0.000892937, 0.00269693, 0.00214335, 0.00588191],
        [0.0013324, 0.000647604, 0.00293729, 0.00156629, 0.00195253, 0.00239435],
        [0.0022423, 0.00141206, 0.0012649, 0.00450748, 0.00138766, 0.00249887],
        [0.00125939, 0.0002428, 0.000370741, 0.000917137, 0.00024578, 0.000412881],
        [0.00135186, 0.000139147, 0.000525713, 0.00103053, 0.000366062, 0.000844955],
        [0.00127548, 0.000989318, 0.00256863, 0.00162545, 0.00311682, 0.00439551],
        [0.00112912, 0.000443578, 0.000779897, 0.00203282, 0.00069508, 0.00188044],
        [0.00114602, 0.00107747, 0.00145, 0.00320849, 0.00211915, 0.00331426],
        [0.00148326, 0.00059548, 0.00431389, 0.00164703, 0.00311947, 0.00268343],
        [0.00154313, 0.000925034, 0.00770769, 0.00252789, 0.00489518, 0.00352332],
        [0.00135094, 0.00042069, 0.00088492, 0.000987828, 0.000755847, 0.00144881],
        [0.0015994, 0.000540197, 0.00163212, 0.00140327, 0.00114474, 0.0026556],
        [0.00150502, 0.000138223, 0.000343591, 0.000529736, 0.000173837, 0.000381887],
        [0.00127372, 0.00066787, 0.00149515, 0.00272799, 0.00110033, 0.00370145],
        [0.00144503, 0.000365585, 0.00318581, 0.00126475, 0.00212631, 0.00204816],
        [0.00132069, 0.00173706, 0.00389183, 0.00536761, 0.00387135, 0.00752795],
        [0.00198057, 0.000307024, 0.000573188, 0.00147268, 0.000757724, 0.0017142],
        [0.00157535, 0.000590324, 0.00190055, 0.00170627, 0.00138417, 0.00246152],
        [0.00177169, 0.000364572, 0.00183856, 0.000767767, 0.00121492, 0.000916481]
      ],
      "detection_classes":
        [5.0, 2.0, 5.0, 5.0, 5.0, 4.0, 5.0, 5.0, 4.0, 4.0, 2.0, 4.0, 4.0, 4.0, 5.0, 4.0, 5.0,
        5.0, 4.0, 5.0, 5.0, 4.0, 5.0, 2.0, 4.0, 4.0, 5.0, 4.0, 4.0, 5.0, 5.0, 5.0, 5.0, 4.0, 4.0,
        5.0, 4.0, 4.0, 5.0, 5.0],
      "num_detections": 40.0,
      "image_info": [320, 320, 1, 0, 320, 320],
      "detection_boxes": [
        [0.457792, 0.0, 0.639324, 0.180828],
        [0.101111, 0.0, 0.89904, 0.995376],
        [0.447649, 0.314644, 0.548206, 0.432875],
        [0.250341, 0.733411, 0.3419, 0.847185],
        [0.573936, 0.0933048, 0.766472, 0.208054],
        [0.490438, 0.194659, 0.825894, 0.563959],
        [0.619383, 0.57948, 0.758244, 0.694948],
        [0.776185, 0.554518, 0.841549, 0.707129],
        [0.101111, 0.0, 0.89904, 0.995376],
        [0.431243, 0.0917888, 0.850772, 0.617123],
        [0.250883, 0.13572, 0.780518, 0.817881],
        [0.327646, 0.878977, 0.607503, 0.989904],
        [0.573936, 0.0933048, 0.766472, 0.208054],
        [0.37792, 0.460952, 0.566977, 0.618865],
        [0.373325, 0.575019, 0.463646, 0.642949],
        [0.27251, 0.0714827, 0.790764, 0.77176],
        [0.725154, 0.561221, 0.849777, 0.702165],
        [0.37549, 0.558988, 0.460575, 0.626821],
        [0.265563, 0.248368, 0.785451, 0.977509],
        [0.605674, 0.597553, 0.760419, 0.744799],
        [0.400611, 0.327271, 0.487579, 0.424036],
        [0.48632, 0.980808, 0.606008, 0.997468],
        [0.542414, 0.0588853, 0.752879, 0.200775],
        [0.490438, 0.194659, 0.825894, 0.563959],
        [0.368839, 0.115654, 0.741839, 0.587659],
        [0.467101, 0.985155, 0.588853, 0.997708],
        [0.755204, 0.561319, 0.836475, 0.676249],
        [0.409855, 0.302322, 0.773464, 0.587772],
        [0.351938, 0.934163, 0.587043, 0.99954],
        [0.27758, 0.72402, 0.334137, 0.846945],
        [0.29875, 0.601199, 0.381122, 0.679323],
        [0.64637, 0.566566, 0.767553, 0.67331],
        [0.372612, 0.596795, 0.457588, 0.666544],
        [0.438422, 0.989558, 0.578529, 0.998366],
        [0.586531, 0.499894, 0.879711, 0.845526],
        [0.608476, 0.644501, 0.759154, 0.827037],
        [0.352501, 0.477601, 0.710863, 0.948605],
        [0.466184, 0.953443, 0.668056, 0.996681],
        [0.547756, 0.00152373, 0.722814, 0.150687],
        [0.759639, 0.548476, 0.866864, 0.722007]
      ],
      "detection_scores":
        [0.877304, 0.839354, 0.824509, 0.579912, 0.461549, 0.306151, 0.268687, 0.197998, 0.181444,
        0.17856, 0.152705, 0.148958, 0.14726, 0.135506, 0.128483, 0.12234, 0.105697, 0.105665,
        0.0941569, 0.0891062, 0.0845169, 0.0810551, 0.0794339, 0.0784486, 0.0771784, 0.0770716,
        0.075339, 0.0716749, 0.0715761, 0.07108, 0.0705339, 0.0693555, 0.0677402, 0.0644643,
        0.0631491, 0.062369, 0.0619523, 0.060859, 0.0601122, 0.0589799],
      "detection_classes_as_text":
        ["Tomato", "Salad", "Tomato", "Tomato", "Tomato", "Seafood", "Tomato", "Tomato", "Seafood",
        "Seafood", "Salad", "Seafood", "Seafood", "Seafood", "Tomato", "Seafood", "Tomato",
        "Tomato", "Seafood", "Tomato", "Tomato", "Seafood", "Tomato", "Salad", "Seafood",
        "Seafood", "Tomato", "Seafood", "Seafood", "Tomato", "Tomato", "Tomato", "Tomato",
        "Seafood", "Seafood", "Tomato", "Seafood", "Seafood", "Tomato", "Tomato"],
      "key": "1"
    }
  ]
}

Python

import base64
import cv2
import io
import json

import requests

def preprocess_image(image_file_path, max_width, max_height):
    """Preprocesses input images for AutoML Vision Edge models.

    Args:
        image_file_path: Path to a local image for the prediction request.
        max_width: The max width for preprocessed images. The max width is 640
            (1024) for AutoML Vision Image Classfication (Object Detection)
            models.
        max_height: The max width for preprocessed images. The max height is
            480 (1024) for AutoML Vision Image Classfication (Object
            Detetion) models.
    Returns:
        The preprocessed encoded image bytes.
    """
    # cv2 is used to read, resize and encode images.
    encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 85]
    im = cv2.imread(image_file_path)
    [height, width, _] = im.shape
    if height > max_height or width > max_width:
        ratio = max(height / float(max_width), width / float(max_height))
        new_height = int(height / ratio + 0.5)
        new_width = int(width / ratio + 0.5)
        resized_im = cv2.resize(
            im, (new_width, new_height), interpolation=cv2.INTER_AREA)
        _, processed_image = cv2.imencode('.jpg', resized_im, encode_param)
    else:
        _, processed_image = cv2.imencode('.jpg', im, encode_param)
    return base64.b64encode(processed_image).decode('utf-8')

def container_predict(image_file_path, image_key, port_number=8501):
    """Sends a prediction request to TFServing docker container REST API.

    Args:
        image_file_path: Path to a local image for the prediction request.
        image_key: Your chosen string key to identify the given image.
        port_number: The port number on your device to accept REST API calls.
    Returns:
        The response of the prediction request.
    """
    # AutoML Vision Edge models will preprocess the input images.
    # The max width and height for AutoML Vision Image Classification and
    # Object Detection models are 640*480 and 1024*1024 separately. The
    # example here is for Image Classification models.
    encoded_image = preprocess_image(
        image_file_path=image_file_path, max_width=640, max_height=480)

    # The example here only shows prediction with one image. You can extend it
    # to predict with a batch of images indicated by different keys, which can
    # make sure that the responses corresponding to the given image.
    instances = {
            'instances': [
                    {'image_bytes': {'b64': str(encoded_image)},
                     'key': image_key}
            ]
    }

    # This example shows sending requests in the same server that you start
    # docker containers. If you would like to send requests to other servers,
    # please change localhost to IP of other servers.
    url = 'http://localhost:{}/v1/models/default:predict'.format(port_number)

    response = requests.post(url, data=json.dumps(instances))
    print(response.json())

Riepilogo

In questo tutorial, hai seguito i passaggi per l'esecuzione di modelli Edge utilizzando container Docker o CPU. Ora puoi eseguire il deployment di questa soluzione basata su container su più dispositivi.

Passaggi successivi