Creazione di una soluzione di analisi della visione artificiale con Dataflow e l'API Cloud Vision

Last reviewed 2021-02-10 UTC

In questo tutorial imparerai a eseguire il deployment di una pipeline Dataflow per elaborare file immagine su larga scala con Cloud Vision. Dataflow archivia i risultati in BigQuery in modo che tu possa utilizzarli per addestrare i modelli predefiniti di ML ML.

La pipeline Dataflow che crei nel tutorial è in grado di gestire le immagini in grandi quantità. È limitato solo dalla quota di Vision. Puoi aumentare la quota di Vision in base ai requisiti di scalabilità.

Il tutorial è rivolto a data engineer e data scientist. Si presume che tu disponga delle conoscenze di base per la creazione di pipeline Dataflow utilizzando l'SDK Java di Apache Beam, l'SQL standard di BigQuery e gli script di base di shell. Si presume anche che tu abbia dimestichezza con Vision.

Obiettivi

  • Creare una pipeline di importazione dei metadati delle immagini con notifiche Pub/Sub per Cloud Storage.
  • Utilizza Dataflow per eseguire il deployment di una pipeline di analisi della visione in tempo reale.
  • Utilizza Vision per analizzare le immagini in base a un insieme di tipi di caratteristiche.
  • Analizza e addestra i dati con BigQuery ML.

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il Calcolatore prezzi. I nuovi utenti di Google Cloud possono essere idonei a una prova senza costi aggiuntivi.

Una volta completate le attività descritte in questo documento, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la pagina Pulizia.

Prima di iniziare

  1. Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  2. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  3. Nella console Google Cloud, attiva Cloud Shell.

    Attiva Cloud Shell

  4. In Cloud Shell, abilita le API Dataflow, Container Registry e Vision.

    gcloud services enable dataflow.googleapis.com \
    containerregistry.googleapis.com vision.googleapis.com
    
  5. Imposta alcune variabili di ambiente. (Sostituisci REGION con una delle regioni Dataflow disponibili. us-central1, ad esempio).

    export PROJECT=$(gcloud config get-value project)
    export REGION=REGION
    
  6. Clona il repository Git del tutorial:

    git clone https://github.com/GoogleCloudPlatform/dataflow-vision-analytics.git
    
  7. Vai alla cartella principale del repository:

    cd dataflow-vision-analytics
    

Architettura di riferimento

Il seguente diagramma illustra il flusso del sistema che crei in questo tutorial.

Diagramma di flusso di lavoro che mostra il flusso di informazioni per importazione/attivatore, elaborazione e archiviazione.

Come mostrato nel diagramma, il flusso è il seguente:

  1. I client caricano i file immagine in un bucket Cloud Storage.

  2. Per ogni caricamento file, il sistema invia una notifica automatica al client pubblicando un messaggio in Pub/Sub.

  3. Per ogni nuova notifica, la pipeline Dataflow esegue le seguenti operazioni:

    1. Legge i metadati dei file dal messaggio Pub/Sub.
    2. Invia ogni segmento all'API Vision per l'elaborazione delle annotazioni.
    3. Archivia tutte le annotazioni in una tabella BigQuery per eseguire ulteriori analisi.

Creazione di una notifica Pub/Sub per Cloud Storage

In questa sezione, crei una notifica Pub/Sub per Cloud Storage. Questa notifica pubblica i metadati per il file immagine caricato nel bucket. In base ai metadati, la pipeline Dataflow inizia a elaborare la richiesta.

  1. In Cloud Shell, crea un argomento Pub/Sub:

    export GCS_NOTIFICATION_TOPIC="gcs-notification-topic"
    gcloud pubsub topics create ${GCS_NOTIFICATION_TOPIC}
    
  2. Crea una sottoscrizione Pub/Sub per l'argomento:

    export  GCS_NOTIFICATION_SUBSCRIPTION="gcs-notification-subscription"
    gcloud pubsub subscriptions create  ${GCS_NOTIFICATION_SUBSCRIPTION}  --topic=${GCS_NOTIFICATION_TOPIC}
    
  3. Crea un bucket in cui archiviare i file immagine di input:

    export IMAGE_BUCKET=${PROJECT}-images
    gsutil mb -c standard -l ${REGION} gs://${IMAGE_BUCKET}
    
  4. Crea una notifica Pub/Sub per il bucket:

    gsutil notification create -t ${GCS_NOTIFICATION_TOPIC} \
      -f json gs://${IMAGE_BUCKET}
    

Ora che hai configurato le notifiche, il sistema invia un messaggio Pub/Sub all'argomento che hai creato. Questa azione si verifica ogni volta che carichi un file nel bucket.

Creazione di un set di dati BigQuery

In questa sezione creerai un set di dati BigQuery per archiviare i risultati restituiti dalla pipeline Dataflow. La pipeline crea automaticamente tabelle basate sui tipi di caratteristiche di visione.

  • In Cloud Shell, crea un set di dati BigQuery:

    export BIGQUERY_DATASET="vision_analytics"
    bq mk -d --location=US ${BIGQUERY_DATASET}
    

Creazione di un modello Dataflow Flex

In questa sezione, crei il codice della pipeline Apache Beam e poi esegui la pipeline Dataflow come job Dataflow utilizzando un modello FlexDataflow.

  1. In Cloud Shell, crea il codice della pipeline Apache Beam:

    gradle build
    
  2. Crea un'immagine Docker per il modello Dataflow Flex:

    gcloud auth configure-docker
    gradle jib \
      --image=gcr.io/${PROJECT}/dataflow-vision-analytics:latest
    
  3. Crea un bucket Cloud Storage per archiviare il modello flessibile Dataflow:

    export DATAFLOW_TEMPLATE_BUCKET=${PROJECT}-dataflow-template-config
    gsutil mb -c standard -l ${REGION} \
      gs://${DATAFLOW_TEMPLATE_BUCKET}
    
  4. Carica il file di configurazione JSON del modello nel bucket:

    cat << EOF | gsutil cp - gs://${DATAFLOW_TEMPLATE_BUCKET}/dynamic_template_vision_analytics.json
    {
      "image": "gcr.io/${PROJECT}/dataflow-vision-analytics:latest",
      "sdk_info": {"language": "JAVA"}
    }
    EOF
    

Esecuzione della pipeline Dataflow per un set di funzionalità di Vision

I parametri elencati nella seguente tabella sono specifici per questa pipeline Dataflow.

Per l'elenco completo dei parametri di esecuzione Dataflow standard, consulta la documentazione di Dataflow.

Parametro Descrizione

windowInterval

L'intervallo di tempo della finestra (in secondi) per l'output dei risultati in BigQuery e Pub/Sub. Il valore predefinito è 5.

batchSize

Il numero di immagini da includere in una richiesta all'API Vision. Il valore predefinito è 1. Puoi aumentarla fino a un massimo di 16.

subscriberId

L'ID della sottoscrizione Pub/Sub che riceve le notifiche di Cloud Storage di input.

keyRange

Il parametro che consente di migliorare le prestazioni di elaborazione per set di dati di grandi dimensioni. Un valore più alto significa un parallelismo tra i lavoratori. Il valore predefinito è 1.

visionApiProjectId

L'ID progetto da utilizzare per l'API Vision.

datasetName

Il riferimento del set di dati BigQuery di output.

features

Un elenco di funzionalità per l'elaborazione delle immagini.

labelAnnottationTable, landmarkAnnotationTable, logoAnnotationTable, faceAnnotationTable, imagePropertiesTable, cropHintAnnotationTable, errorLogTable

Parametri stringa con nomi di tabella per varie annotazioni. Per ogni tabella vengono forniti i valori predefiniti.
  1. In Cloud Shell, definisci un nome job per la pipeline Dataflow:

    export JOB_NAME=vision-analytics-pipeline-1
    
  2. Crea un file con i parametri per la pipeline Dataflow:

    PARAMETERS=params.yaml
    cat << EOF > ${PARAMETERS}
    --parameters:
      autoscalingAlgorithm: THROUGHPUT_BASED
      enableStreamingEngine: "true"
      subscriberId: projects/${PROJECT}/subscriptions/${GCS_NOTIFICATION_SUBSCRIPTION}
      visionApiProjectId: ${PROJECT}
      features: IMAGE_PROPERTIES,LABEL_DETECTION,LANDMARK_DETECTION,LOGO_DETECTION,CROP_HINTS,FACE_DETECTION
      datasetName: ${BIGQUERY_DATASET}
    EOF
    
  3. Esegui la pipeline Dataflow per elaborare le immagini per questi tipi di funzionalità: IMAGE_PROPERTIES, LABEL_DETECTION, LANDMARK_DETECTION, LOGO_DETECTION, CROP_HINTS,FACE_DETECTION.

    gcloud dataflow flex-template run ${JOB_NAME} \
    --project=${PROJECT} \
    --region=${REGION} \
    --template-file-gcs-location=gs://${DATAFLOW_TEMPLATE_BUCKET}/dynamic_template_vision_analytics.json \
    --flags-file ${PARAMETERS}
    

    Questo comando utilizza i parametri elencati nella tabella precedente.

  4. Recupera l'ID del job Dataflow in esecuzione:

    JOB_ID=$(gcloud dataflow jobs list --filter "name:${JOB_NAME}" --format "value(id)" --status active)
    
  5. Visualizza l'URL della pagina web del job Dataflow:

    echo "https://console.cloud.google.com/dataflow/jobs/${REGION}/${JOB_ID}"
    
  6. Apri l'URL visualizzato in una nuova scheda del browser. Dopo alcuni secondi, viene visualizzato il grafico per il job Dataflow:

    Diagramma di flusso di lavoro per il job Dataflow.

    La pipeline Dataflow è ora in esecuzione e in attesa di ricevere notifiche di input da Pub/Sub.

  7. In Cloud Shell, attiva la pipeline Dataflow caricando alcuni file di test nel bucket di input:

    gsutil cp gs://df-vision-ai-test-data/bali.jpeg gs://${IMAGE_BUCKET}
    gsutil cp gs://df-vision-ai-test-data/faces.jpeg gs://${IMAGE_BUCKET}
    gsutil cp gs://df-vision-ai-test-data/bubble.jpeg gs://${IMAGE_BUCKET}
    gsutil cp gs://df-vision-ai-test-data/setagaya.jpeg gs://${IMAGE_BUCKET}
    gsutil cp gs://df-vision-ai-test-data/st_basils.jpeg gs://${IMAGE_BUCKET}
    
  8. Nella console Google Cloud, esamina i contatori personalizzati in Dataflow (nel riquadro a destra del job Dataflow) e verifica che abbiano elaborato tutte e cinque le immagini:

    Elenco di immagini restituite dal caricamento file.

  9. In Cloud Shell, verifica che le tabelle siano state create automaticamente:

    bq query "select table_name, table_type from \
    ${BIGQUERY_DATASET}.INFORMATION_SCHEMA.TABLES"
    

    L'output è il seguente:

    +----------------------+------------+
    |      table_name      | table_type |
    +----------------------+------------+
    | face_annotation      | BASE TABLE |
    | label_annotation     | BASE TABLE |
    | crop_hint_annotation | BASE TABLE |
    | landmark_annotation  | BASE TABLE |
    | image_properties     | BASE TABLE |
    +----------------------+------------+
    
  10. Visualizza lo schema per la tabella landmark_annotation. Se richiesto, la funzionalità LANDMARK_DETECTION acquisisce gli attributi restituiti dalla chiamata API.

    bq show --schema --format=prettyjson ${BIGQUERY_DATASET}.landmark_annotation
    

    L'output è il seguente:

    [
      {
        "mode": "REQUIRED",
        "name": "gcs_uri",
        "type": "STRING"
      },
      {
        "mode": "NULLABLE",
        "name": "mid",
        "type": "STRING"
      },
      {
        "mode": "REQUIRED",
        "name": "description",
        "type": "STRING"
      },
      {
        "mode": "REQUIRED",
        "name": "score",
        "type": "FLOAT"
      },
      {
        "fields": [
          {
            "fields": [
              {
                "mode": "REQUIRED",
                "name": "x",
                "type": "FLOAT"
              },
              {
                "mode": "REQUIRED",
                "name": "y",
                "type": "FLOAT"
              }
            ],
            "mode": "REPEATED",
            "name": "vertices",
            "type": "RECORD"
          }
        ],
        "mode": "NULLABLE",
        "name": "bounding_poly",
        "type": "RECORD"
      },
      {
        "mode": "REPEATED",
        "name": "locations",
        "type": "GEOGRAPHY"
      },
      {
        "mode": "REQUIRED",
        "name": "transaction_timestamp",
        "type": "TIMESTAMP"
      }
    ]
    
  11. Arresta pipeline:

    gcloud dataflow jobs drain ${JOB_ID} \
    --region ${REGION}
    

    Anche se non ci sono altre notifiche Pub/Sub da elaborare, la pipeline in modalità flusso che hai creato continua a essere eseguita fino a quando non inserisci questo comando.

Analisi di un set di dati iCloud30K

In questa sezione analizzerai un set di dati flickr30K per il rilevamento di etichette e punti di riferimento.

  1. In Cloud Shell, definisci un nuovo nome del job:

    export JOB_NAME=vision-analytics-pipeline-2
    
  2. Modifica i parametri della pipeline Dataflow in modo che siano ottimizzati per un set di dati di grandi dimensioni. I valori batchSize e keyRange vengono aumentati per consentire una velocità effettiva più elevata. Dataflow scala il numero di worker in base alle esigenze:

    cat <<EOF > ${PARAMETERS}
    --parameters:
      autoscalingAlgorithm: THROUGHPUT_BASED
      enableStreamingEngine: "true"
      subscriberId: projects/${PROJECT}/subscriptions/${GCS_NOTIFICATION_SUBSCRIPTION}
      visionApiProjectId: ${PROJECT}
      features: LABEL_DETECTION,LANDMARK_DETECTION
      datasetName: ${BIGQUERY_DATASET}
      batchSize: "16"
      windowInterval: "5"
      keyRange: "2"
    EOF
    
  3. Esegui la pipeline:

    gcloud dataflow flex-template run ${JOB_NAME} \
    --project=${PROJECT} \
    --region=${REGION} \
    --template-file-gcs-location=gs://${DATAFLOW_TEMPLATE_BUCKET}/dynamic_template_vision_analytics.json \
    --flags-file ${PARAMETERS}
    
  4. Carica il set di dati in un bucket di input:

    gsutil -m  cp gs://df-vision-ai-test-data/*  gs://${IMAGE_BUCKET}
    
  5. Recupera l'ID del job Dataflow in esecuzione:

    JOB_ID=$(gcloud dataflow jobs list --filter "name:${JOB_NAME}" --region ${REGION} --format "value(id)" --status active)
    
  6. Visualizza l'URL della pagina web del job Dataflow:

    echo "https://console.cloud.google.com/dataflow/jobs/${REGION}/${JOB_ID}"
    
  7. Apri l'URL visualizzato in una nuova scheda del browser.

  8. Nella console Google Cloud, convalida i contatori personalizzati in Dataflow per assicurarti che tutti i file vengano elaborati. In genere, tutti i file vengono elaborati in meno di 30 minuti.

  9. Filtra in base ai contatori personalizzati in Elabora annotazioni.

    L'output è il seguente:

    Elenco dei contatori restituito dopo l'applicazione di un filtro in base ai contatori personalizzati. Mostra il nome del contatore, il valore e il passaggio.

    La metrica processedFiles (31.935) corrisponde al numero totale di immagini caricate nel bucket (il numero totale di file è 31.936). Tuttavia, la metrica numberOfRequests (1997) è inferiore al numero di file che sono passati attraverso la pipeline. Questa differenza è dovuta al fatto che la pipeline esegue in batch fino a 16 file per richiesta, come mostrato nei valori delle metriche batchSizeDistribution_*.

  10. Arresta la pipeline:

    JOB_ID=$(gcloud dataflow jobs list --filter "name:${JOB_NAME}"
    --region ${REGION}
    --format "value(id)"
    --status active) \
    gcloud dataflow jobs drain ${JOB_ID} \
    --region ${REGION}
    
  11. Nella console Google Cloud, vai alla pagina Editor query di BigQuery.

    Vai all'Editor query

  12. Trova l'etichetta più probabile per ogni file:

    SELECT
      SPLIT(gcs_uri,'/')[OFFSET(3)] file,
      description,
      score
    FROM (
      SELECT
        gcs_uri,
        description,
        score,
        ROW_NUMBER() OVER (PARTITION BY gcs_uri ORDER BY score DESC )
    AS row_num
      FROM
         `vision_analytics.label_annotation`)
    WHERE
      row_num = 1
    ORDER BY
      gcs_uri DESC
    

    L'output è il seguente. Dalla risposta è emerso che Landmark è la descrizione più probabile del file st_basils.jpeg.

    Elenco di nomi, descrizioni e punteggi di file immagine.

  13. Trova le prime 10 etichette e i relativi punteggi massimi:

    SELECT
      description,
      COUNT(*) AS found,
      MAX(score) AS max_score
    FROM
      `vision_analytics.label_annotation`
    GROUP BY
      description
    ORDER BY
      found DESC
    LIMIT 10
    

    L'output finale è simile al seguente:

    Elenco delle prime 10 etichette trovate. Include la descrizione, il numero
di volte e un punteggio massimo.

  14. Trova i 10 principali punti di riferimento popolari:

    SELECT
      description,
      COUNT(*) AS count,
      MAX(score) AS max_score
    FROM
      `vision_analytics.landmark_annotation`
    WHERE
      LENGTH(description)>0
    GROUP BY
      description
    ORDER BY
      count DESC
    LIMIT 10
    

    L'output è il seguente. Come puoi vedere, Times Square sembra essere la destinazione più popolare.

    Elenco dei primi 10 punti di riferimento più popolari restituiti dalla query. Include descrizione, conteggio e punteggio massimo.

  15. Trova qualsiasi immagine con una cascata:

    SELECT
      SPLIT(gcs_uri,'/')[OFFSET(3)] file,
      description,
      score
    FROM
      `vision_analytics.landmark_annotation`
    WHERE
      LOWER(description) LIKE '%fall%'
    ORDER BY score DESC
    

    L'output è il seguente. Contiene solo immagini delle cascate.

    Elenco di cascate. Include il nome del file, la descrizione e il punteggio.

  16. Trova un'immagine di un luogo di interesse entro 3 km dal Colosseo a Roma (la funzione ST_GEOPOINT utilizza la longitudine e la latitudine di Colosseo):

    WITH
      landmarksWithDistances AS (
      SELECT
        gcs_uri,
        description,
        location,
        ST_DISTANCE(location,
          ST_GEOGPOINT(12.492231,
            41.890222)) distance_in_meters,
      FROM
        `vision_analytics.landmark_annotation` landmarks
      CROSS JOIN
        UNNEST(landmarks.locations) AS location )
    SELECT
      SPLIT(gcs_uri,"/")[OFFSET(3)] file,
      description,
        ROUND(distance_in_meters) distance_in_meters,
      location,
      CONCAT("https://storage.cloud.google.com/", SUBSTR(gcs_uri, 6)) AS image_url
    FROM
      landmarksWithDistances
    WHERE
      distance_in_meters < 3000
    ORDER BY
      distance_in_meters
    LIMIT
      100
    

    L'output è il seguente. Come vedi, in queste immagini sono presenti diverse destinazioni popolari:

    Elenco di tutte le immagini entro 3 km dal Colosseo a Roma. Include nome, descrizione, distanza in metri dal Colosseo e posizione.

    La stessa immagine può contenere più posizioni dello stesso punto di riferimento. Questa funzionalità è descritta nella documentazione dell'API Vision. Poiché una posizione può indicare la posizione della scena nell'immagine, possono essere presenti più elementi LocationInfo. Un'altra posizione può indicare la posizione in cui è stata scattata l'immagine. Solitamente, le informazioni sulla posizione sono presenti per i punti di riferimento.

    Puoi visualizzare i dati in BigQuery Geo Viz incollando nella query precedente. Quando selezioni un punto sulla mappa, ne vedi i dettagli. L'attributo Image_url contiene il link al file immagine che puoi aprire in un browser.

    Mappa delle località e relativa distanza dal Colosseo.

Esegui la pulizia

Per evitare che al tuo Account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

Elimina il progetto Google Cloud

Il modo più semplice per eliminare la fatturazione è eliminare il progetto Google Cloud che hai creato per il tutorial.

  1. Nella console Google Cloud, vai alla pagina Gestisci risorse.

    Vai a Gestisci risorse

  2. Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
  3. Nella finestra di dialogo, digita l'ID del progetto e fai clic su Chiudi per eliminare il progetto.

Passaggi successivi