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.
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
-
No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.
-
Verifique se a cobrança está ativada para o seu projeto do Google Cloud.
-
No Console do Google Cloud, ative o Cloud Shell.
No Cloud Shell, ative as APIs Dataflow, Container Registry e Vision.
gcloud services enable dataflow.googleapis.com \ containerregistry.googleapis.com vision.googleapis.com
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
Clone o repositório do Git do tutorial:
git clone https://github.com/GoogleCloudPlatform/dataflow-vision-analytics.git
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.
Conforme mostrado no diagrama, o fluxo é o seguinte:
Os clientes fazem o upload de arquivos de imagem para um bucket do Cloud Storage.
Para cada upload de arquivo, o sistema notifica o cliente automaticamente publicando uma mensagem no Pub/Sub.
Para cada nova notificação, o pipeline do Dataflow faz o seguinte:
- Lê os metadados de arquivo a partir da mensagem do Pub/Sub.
- Envia cada segmento à API Vision para processamento de anotações.
- 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.
No Cloud Shell, crie um tópico do Pub/Sub:
export GCS_NOTIFICATION_TOPIC="gcs-notification-topic" gcloud pubsub topics create ${GCS_NOTIFICATION_TOPIC}
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}
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}
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.
No Cloud Shell, crie o código do pipeline do Apache Beam:
gradle build
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
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}
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 |
---|---|
|
O intervalo de tempo de janela (em segundos) para enviar resultados para o BigQuery e para o Pub/Sub. O padrão é 5. |
|
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. |
|
O código da assinatura do Pub/Sub que recebe notificações de entrada do Cloud Storage. |
|
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. |
|
O ID do projeto a ser usado para a API Vision. |
|
A referência do conjunto de dados de saída do BigQuery. |
|
Uma lista de recursos de processamento de imagem. |
|
Parâmetros de string com nomes de tabela para várias anotações. Os valores padrão são fornecidos para cada tabela. |
No Cloud Shell, defina um nome de job para o pipeline do Dataflow:
export JOB_NAME=vision-analytics-pipeline-1
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
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.
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)
Exiba o URL da página da Web do job do Dataflow:
echo "https://console.cloud.google.com/dataflow/jobs/${REGION}/${JOB_ID}"
Abra o URL exibido em uma nova guia do navegador. Após alguns segundos, o gráfico do job do Dataflow é exibido:
O pipeline do Dataflow está sendo executado e aguardando o recebimento de notificações de entrada do Pub/Sub.
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}
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:
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 | +----------------------+------------+
Visualize o esquema da tabela
landmark_annotation
. Se solicitado, o recursoLANDMARK_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" } ]
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.
No Cloud Shell, defina um novo nome para o job:
export JOB_NAME=vision-analytics-pipeline-2
Alterar os parâmetros do pipeline do Dataflow para que ele seja otimizado para um grande conjunto de dados. O
batchSize
ekeyRange
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
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}
Faça upload do conjunto de dados para um bucket de entrada:
gsutil -m cp gs://df-vision-ai-test-data/* gs://${IMAGE_BUCKET}
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)
Exiba o URL da página da Web do job do Dataflow:
echo "https://console.cloud.google.com/dataflow/jobs/${REGION}/${JOB_ID}"
Abra o URL exibido em uma nova guia do navegador.
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.
Filtre por contadores personalizados em Processar anotações.
A resposta é a seguinte:
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étricanumberOfRequests
(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étricasbatchSizeDistribution_*
.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}
No console do Google Cloud, acesse a página do Editor de consultas do BigQuery.
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
.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:
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.
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.
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:
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.
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.
- No Console do Google Cloud, acesse a página Gerenciar recursos.
- Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
- Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.
A seguir
- Saiba mais sobre os padrões de referência de análises inteligentes.
- Confira arquiteturas de referência, diagramas e práticas recomendadas do Google Cloud. Confira o Centro de arquitetura do Cloud.