Como criar uma solução de análise de visão de ML com a API Cloud Vision e o Dataflow

Last reviewed 2024-04-16 UTC

Neste tutorial, você aprenderá como implantar um pipeline do Dataflow para processar arquivos de imagem em grande escala com o Cloud Vision. O Dataflow armazena os resultados no BigQuery para que você possa usá-los no treinamento de modelos pré-criados do BigQuery ML.

O pipeline do Dataflow que você cria no tutorial pode processar imagens em grandes quantidades. Ela é limitada apenas pela sua cota do Vision. Aumente a cota do Vision com base nos requisitos de escala.

Este tutorial é destinado a engenheiros e cientistas de dados. Ele pressupõe que você tenha conhecimento básico de criação de pipelines do Dataflow usando o SDK em Java do Apache Beam (em inglês), o SQL padrão do BigQuery e scripts básicos de shell. Também presumimos que você esteja familiarizado com o Vision.

Objetivos

  • Criar um pipeline de ingestão de metadados de imagem com notificações do Pub/Sub para o Cloud Storage.
  • Usar o Dataflow para implantar um pipeline de análise de visão em tempo real.
  • Usar o Vision para analisar imagens de um conjunto de tipos de recursos.
  • Analisar e treinar dados com o BigQuery ML.

Custos

Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Saiba mais em Limpeza.

Antes de começar

  1. No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  2. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  3. No Console do Google Cloud, ative o Cloud Shell.

    Ativar o Cloud Shell

  4. No Cloud Shell, ative as APIs Dataflow, Container Registry e Vision.

    gcloud services enable dataflow.googleapis.com \
    containerregistry.googleapis.com vision.googleapis.com
    
  5. Defina algumas variáveis de ambiente. Substitua REGION por uma das regiões do Dataflow disponíveis. Exemplo: us-central1

    export PROJECT=$(gcloud config get-value project)
    export REGION=REGION
    
  6. Clone o repositório do Git do tutorial:

    git clone https://github.com/GoogleCloudPlatform/dataflow-vision-analytics.git
    
  7. Acesse a pasta raiz do repositório:

    cd dataflow-vision-analytics
    

Arquitetura de referência

No diagrama a seguir, ilustramos o fluxo do sistema que você cria neste tutorial.

Diagrama de fluxo de trabalho mostrando o fluxo de informações para ingestão/acionamento, processo e armazenamento.

Conforme mostrado no diagrama, o fluxo é o seguinte:

  1. Os clientes fazem o upload de arquivos de imagem para um bucket do Cloud Storage.

  2. Para cada upload de arquivo, o sistema notifica o cliente automaticamente publicando uma mensagem no Pub/Sub.

  3. Para cada nova notificação, o pipeline do Dataflow faz o seguinte:

    1. Lê os metadados de arquivo a partir da mensagem do Pub/Sub.
    2. Envia cada segmento à API Vision para processamento de anotações.
    3. Armazena todas as anotações em uma tabela do BigQuery para análise posterior.

Como criar uma notificação do Pub/Sub para o Cloud Storage

Nesta seção, você cria uma notificação do Pub/Sub para o Cloud Storage. Essa notificação publica metadados para o arquivo de imagem que é carregado no bucket. Com base nos metadados, o pipeline do Dataflow começa a processar a solicitação.

  1. No Cloud Shell, crie um tópico do Pub/Sub:

    export GCS_NOTIFICATION_TOPIC="gcs-notification-topic"
    gcloud pubsub topics create ${GCS_NOTIFICATION_TOPIC}
    
  2. Crie uma assinatura do Pub/Sub para o tópico:

    export  GCS_NOTIFICATION_SUBSCRIPTION="gcs-notification-subscription"
    gcloud pubsub subscriptions create  ${GCS_NOTIFICATION_SUBSCRIPTION}  --topic=${GCS_NOTIFICATION_TOPIC}
    
  3. Crie um bucket para armazenar os arquivos de imagem de entrada:

    export IMAGE_BUCKET=${PROJECT}-images
    gsutil mb -c standard -l ${REGION} gs://${IMAGE_BUCKET}
    
  4. Crie uma notificação do Pub/Sub para o bucket:

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

Agora que você configurou as notificações, o sistema enviará uma mensagem do Pub/Sub para o tópico que você criou toda vez que fizer upload de um arquivo para o bucket.

Como criar um conjunto de dados do BigQuery

Nesta seção, você cria um conjunto de dados do BigQuery para armazenar a saída dos resultados pelo pipeline do Dataflow. O pipeline cria automaticamente tabelas com base nos tipos de recurso da visão.

  • No Cloud Shell, crie um conjunto de dados do BigQuery:

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

Como criar um modelo Flex do Dataflow

Nesta seção, você cria o código do pipeline do Apache Beam e executa o pipeline do Dataflow como um job do Dataflow usando um modelo flexível do Dataflow.

  1. No Cloud Shell, crie o código do pipeline do Apache Beam:

    gradle build
    
  2. Crie uma imagem do Docker para o modelo do Dataflow Flex:

    gcloud auth configure-docker
    gradle jib \
      --image=gcr.io/${PROJECT}/dataflow-vision-analytics:latest
    
  3. Crie um bucket do Cloud Storage para armazenar o modelo do Dataflow Flex:

    export DATAFLOW_TEMPLATE_BUCKET=${PROJECT}-dataflow-template-config
    gsutil mb -c standard -l ${REGION} \
      gs://${DATAFLOW_TEMPLATE_BUCKET}
    
  4. Faça upload do arquivo de configuração JSON do modelo para o 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
    

Como executar o pipeline do Dataflow para um conjunto de recursos do Vision

Os parâmetros listados na tabela a seguir são específicos a este pipeline do Dataflow.

Consulte a documentação do Dataflow para ver a lista completa de parâmetros de execução padrão do Dataflow.

Parâmetro Descrição

windowInterval

O intervalo de tempo de janela (em segundos) para enviar resultados para o BigQuery e para o Pub/Sub. O padrão é 5.

batchSize

O número de imagens a serem incluídas em uma solicitação à API Vision. O padrão é 1. Você pode aumentá-lo para um máximo de 16.

subscriberId

O código da assinatura do Pub/Sub que recebe notificações de entrada do Cloud Storage.

keyRange

O parâmetro que possibilita melhorar o desempenho de processamento de grandes conjuntos de dados. Um valor maior significa maior paralelismo entre workers. O padrão é 1.

visionApiProjectId

O ID do projeto a ser usado para a API Vision.

datasetName

A referência do conjunto de dados de saída do BigQuery.

features

Uma lista de recursos de processamento de imagem.

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

Parâmetros de string com nomes de tabela para várias anotações. Os valores padrão são fornecidos para cada tabela.
  1. No Cloud Shell, defina um nome de job para o pipeline do Dataflow:

    export JOB_NAME=vision-analytics-pipeline-1
    
  2. Crie um arquivo com parâmetros para o pipeline do 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. Execute o pipeline do Dataflow para processar imagens para estes tipos de recursos: 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}
    

    Esse comando usa os parâmetros listados na tabela anterior.

  4. Recupere o ID do job do Dataflow em execução:

    JOB_ID=$(gcloud dataflow jobs list --filter "name:${JOB_NAME}" --format "value(id)" --status active)
    
  5. Exiba o URL da página da Web do job do Dataflow:

    echo "https://console.cloud.google.com/dataflow/jobs/${REGION}/${JOB_ID}"
    
  6. Abra o URL exibido em uma nova guia do navegador. Após alguns segundos, o gráfico do job do Dataflow é exibido:

    Diagrama de fluxo de trabalho para o job do Dataflow.

    O pipeline do Dataflow está sendo executado e aguardando o recebimento de notificações de entrada do Pub/Sub.

  7. No Cloud Shell, acione o pipeline do Dataflow fazendo upload de alguns arquivos de teste para o bucket de entrada:

    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. No Console do Google Cloud, revise os contadores personalizados no Dataflow (no painel direito do job do Dataflow) e verifique se ele processou todas as cinco imagens:

    Lista de imagens retornadas do upload de arquivo.

  9. No Cloud Shell, confirme se as tabelas foram criadas automaticamente:

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

    A resposta é a seguinte:

    +----------------------+------------+
    |      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. Visualize o esquema da tabela landmark_annotation. Se solicitado, o recurso LANDMARK_DETECTION captura os atributos retornados da chamada de API.

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

    A resposta é a seguinte:

    [
      {
        "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. Pare o pipeline:

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

    Não há mais notificações do Pub/Sub a serem processadas, mas o pipeline de streaming que você criou continua sendo executado até você inserir esse comando.

Como analisar um conjunto de dados do Flickr30K

Nesta seção, você analisa um conjunto de dados flickr30K quanto à detecção de rótulos e pontos de referência.

  1. No Cloud Shell, defina um novo nome para o job:

    export JOB_NAME=vision-analytics-pipeline-2
    
  2. Alterar os parâmetros do pipeline do Dataflow para que ele seja otimizado para um grande conjunto de dados. O batchSize e keyRange são aumentados para permitir maior capacidade. O Dataflow escalonará o número de workers conforme necessário:

    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. Execute o canal:

    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. Faça upload do conjunto de dados para um bucket de entrada:

    gsutil -m  cp gs://df-vision-ai-test-data/*  gs://${IMAGE_BUCKET}
    
  5. Recupere o ID do job do Dataflow em execução:

    JOB_ID=$(gcloud dataflow jobs list --filter "name:${JOB_NAME}" --region ${REGION} --format "value(id)" --status active)
    
  6. Exiba o URL da página da Web do job do Dataflow:

    echo "https://console.cloud.google.com/dataflow/jobs/${REGION}/${JOB_ID}"
    
  7. Abra o URL exibido em uma nova guia do navegador.

  8. No Google Cloud Console, valide os contadores personalizados no Dataflow para garantir que todos os arquivos sejam processados. Todos os arquivos normalmente são processados em menos de 30 minutos.

  9. Filtre por contadores personalizados em Processar anotações.

    A resposta é a seguinte:

    Lista de contadores retornados após a filtragem por contadores personalizados. Mostra o
nome, o valor e a etapa do contador.

    A métrica processedFiles (31.935) corresponde ao número total de imagens que foram enviadas ao bucket (o total de arquivos é 31.936). No entanto, a métrica numberOfRequests (1.997) é menor que o número de arquivos que passaram pelo pipeline. Essa diferença ocorre porque o pipeline cria até 16 arquivos por solicitação, conforme mostrado nos valores das métricas batchSizeDistribution_*.

  10. Encerre o 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. No console do Google Cloud, acesse a página do Editor de consultas do BigQuery.

    Acessar o Editor de consultas

  12. Encontre o rótulo mais provável para cada arquivo:

    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
    

    A resposta é a seguinte: É possível ver na resposta que Ponto de referência é a descrição mais provável para o arquivo st_basils.jpeg.

    Lista de nomes, descrições e pontuações de arquivos de imagem.

  13. Encontre os 10 principais rótulos e as pontuações máximas deles:

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

    A resposta será semelhante a:

    Lista dos 10 principais rótulos encontrados. Ela inclui a descrição, o número de
vezes encontrado e uma pontuação máxima.

  14. Encontre os 10 principais pontos de referência:

    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
    

    A resposta é a seguinte: Veja na resposta que a Times Square parece ser o destino mais famoso.

    Lista dos 10 pontos de referência mais famosos retornados pela consulta. Inclui
a descrição, a contagem e a pontuação máxima.

  15. Encontre qualquer imagem que tenha uma cachoeira:

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

    A resposta é a seguinte: Ele contém apenas imagens de cachoeiras.

    Lista de cachoeiras. Inclui o nome, a descrição e a pontuação do arquivo.

  16. Encontre uma imagem de um ponto de referência a três quilômetros do Coliseu em Roma (a função ST_GEOPOINT usa a longitude e a latitude do Coliseu):

    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
    

    A resposta é a seguinte: Veja que vários destinos famosos aparecem nestas imagens:

    Lista de todas as imagens dentro de até 3 km do Coliseu de Roma. Inclui nome do
arquivo, descrição, distância em metros do Coliseu e o local.

    A mesma imagem pode conter vários locais do mesmo ponto de referência. Essa funcionalidade está descrita na documentação da API Vision. Como um local pode indicar o local da cena na imagem, vários elementos LocationInfo podem estar presentes. Outro local pode indicar onde a imagem foi tirada. Geralmente, as informações de local estão presentes para pontos de referência.

    Para visualizar os dados no BigQuery Geo Viz, cole a consulta anterior. Quando você seleciona um ponto no mapa, são exibidos os detalhes dele. O atributo Image_url contém o link para o arquivo de imagem que pode ser aberto em um navegador.

    Mapa de locais e a distância do Coliseu.

Limpeza

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

Excluir o projeto do Google Cloud

A maneira mais fácil de eliminar o faturamento é excluir o projeto do Google Cloud criado para o tutorial.

  1. No Console do Google Cloud, acesse a página Gerenciar recursos.

    Acessar "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.

A seguir