Dans ce tutoriel, vous allez apprendre à déployer un pipeline Dataflow pour traiter des fichiers image à grande échelle avec Cloud Vision. Dataflow stocke les résultats dans BigQuery afin que vous puissiez vous en servir pour entraîner des modèles prédéfinis BigQuery ML.
Le pipeline Dataflow que vous créez dans ce tutoriel peut gérer des images en grandes quantités. Il n'est limité que par votre quota Vision. Vous pouvez augmenter votre quota Vision en fonction de vos exigences d'évolutivité.
Ce tutoriel est destiné aux ingénieurs de données et aux data scientists. Nous supposons ici que vous disposez de connaissances de base sur la création de pipelines Dataflow à l'aide du SDK Java d'Apache Beam, du SQL standard BigQuery et de scripts shell de base. Nous supposons également que vous maîtrisez Vision.
Objectifs
- Créer un pipeline d'ingestion de métadonnées d'images avec des notifications Pub/Sub pour Cloud Storage.
- Déployer un pipeline d'analyse de vision en temps réel avec Dataflow.
- Utiliser Vision pour analyser des images pour un ensemble de types de fonctionnalités.
- Analyser et entraîner des données avec BigQuery ML.
Coûts
Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :
Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût.
Une fois que vous avez terminé les tâches décrites dans ce document, vous pouvez éviter de continuer à payer des frais en supprimant les ressources que vous avez créées. Pour en savoir plus, consultez la section Effectuer un nettoyage.
Avant de commencer
-
Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.
-
Vérifiez que la facturation est activée pour votre projet Google Cloud.
-
Dans la console Google Cloud, activez Cloud Shell.
Dans Cloud Shell, activez les API Dataflow, Container Registry et Vision.
gcloud services enable dataflow.googleapis.com \ containerregistry.googleapis.com vision.googleapis.com
Définissez des variables d'environnement. (Remplacez REGION par l'une des régions Dataflow disponibles. Par exemple :
us-central1
.)export PROJECT=$(gcloud config get-value project) export REGION=REGION
Clonez le dépôt Git du tutoriel :
git clone https://github.com/GoogleCloudPlatform/dataflow-vision-analytics.git
Accédez au dossier racine du dépôt :
cd dataflow-vision-analytics
Architecture de référence
Le schéma suivant illustre le flux du système que vous créez dans ce tutoriel.
Comme le montre le schéma, le flux est le suivant :
Les clients importent des fichiers image dans un bucket Cloud Storage.
Pour chaque importation de fichier, le système informe automatiquement le client en publiant un message dans Pub/Sub.
Pour chaque nouvelle notification, le pipeline Dataflow effectue les actions suivantes :
- Il lit les métadonnées du fichier à partir du message Pub/Sub.
- Envoi de chaque segment à l'API Vision pour le traitement des annotations.
- Il stocke toutes les annotations dans une table BigQuery pour une analyse plus approfondie.
Créer une notification Pub/Sub pour Cloud Storage
Dans cette section, vous allez créer une notification Pub/Sub pour Cloud Storage. Cette notification publie les métadonnées pour le fichier image importé dans le bucket. En fonction des métadonnées, le pipeline Dataflow commence à traiter la requête.
Dans Cloud Shell, créez un sujet Pub/Sub :
export GCS_NOTIFICATION_TOPIC="gcs-notification-topic" gcloud pubsub topics create ${GCS_NOTIFICATION_TOPIC}
Créez un abonnement Pub/Sub pour le sujet :
export GCS_NOTIFICATION_SUBSCRIPTION="gcs-notification-subscription" gcloud pubsub subscriptions create ${GCS_NOTIFICATION_SUBSCRIPTION} --topic=${GCS_NOTIFICATION_TOPIC}
Créez un bucket pour stocker les fichiers image d'entrée :
export IMAGE_BUCKET=${PROJECT}-images gsutil mb -c standard -l ${REGION} gs://${IMAGE_BUCKET}
Créez une notification Pub/Sub pour le bucket :
gsutil notification create -t ${GCS_NOTIFICATION_TOPIC} \ -f json gs://${IMAGE_BUCKET}
Une fois les notifications configurées, le système envoie un message Pub/Sub au sujet que vous avez créé. Cette action se produit à chaque fois que vous importez un fichier dans le bucket.
Créer un ensemble de données BigQuery
Dans cette section, vous créez un ensemble de données BigQuery pour stocker les résultats générés par le pipeline Dataflow. Le pipeline crée automatiquement des tables basées sur les types de caractéristiques Vision.
Dans Cloud Shell, créez un ensemble de données BigQuery :
export BIGQUERY_DATASET="vision_analytics" bq mk -d --location=US ${BIGQUERY_DATASET}
Créer un modèle Flex Dataflow
Dans cette section, vous créez du code de pipeline Apache Beam, puis exécutez le pipeline Dataflow en tant que tâche Dataflow à l'aide d'un modèle Flex Dataflow.
Dans Cloud Shell, créez le code du pipeline Apache Beam :
gradle build
Créez une image Docker pour le modèle Dataflow Flex :
gcloud auth configure-docker gradle jib \ --image=gcr.io/${PROJECT}/dataflow-vision-analytics:latest
Créez un bucket Cloud Storage pour stocker le modèle Dataflow Flex :
export DATAFLOW_TEMPLATE_BUCKET=${PROJECT}-dataflow-template-config gsutil mb -c standard -l ${REGION} \ gs://${DATAFLOW_TEMPLATE_BUCKET}
Importez le fichier de configuration JSON du modèle dans le 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
Exécuter le pipeline Dataflow pour un ensemble de fonctionnalités Vision
Les paramètres répertoriés dans le tableau suivant sont spécifiques à ce pipeline Dataflow.
Consultez la documentation Dataflow pour obtenir la liste complète des paramètres d'exécution Dataflow standards.
Paramètre | Description |
---|---|
|
Intervalle de temps (en secondes) pour générer des résultats vers BigQuery et Pub/Sub. La valeur par défaut est 5. |
|
Nombre d'images à inclure dans une requête adressée à l'API Vision. La valeur par défaut est 1. Vous définir cette valeur sur un maximum de 16 images. |
|
ID de l'abonnement Pub/Sub qui reçoit les notifications Cloud Storage d'entrée. |
|
Paramètre permettant d'améliorer les performances de traitement pour les ensembles de données volumineux. Plus la valeur est haute, plus le parallélisme est élevé entre les nœuds de calcul. La valeur par défaut est 1. |
|
ID de projet à utiliser pour l'API Vision. |
|
Référence de l'ensemble de données BigQuery de sortie. |
|
Liste des fonctionnalités de traitement d'image. |
|
Paramètres de chaîne avec des noms de table pour diverses annotations. Les valeurs par défaut sont fournies pour chaque table. |
Dans Cloud Shell, définissez un nom de tâche pour le pipeline Dataflow :
export JOB_NAME=vision-analytics-pipeline-1
Créez un fichier en incluant les paramètres pour le 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
Exécutez le pipeline Dataflow pour traiter les images pour ces types de fonctionnalités :
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}
Cette commande utilise les paramètres répertoriés dans le tableau précédent.
Récupérez l'ID de la tâche Dataflow en cours d'exécution :
JOB_ID=$(gcloud dataflow jobs list --filter "name:${JOB_NAME}" --format "value(id)" --status active)
Affichez l'URL de la page Web de la tâche Dataflow :
echo "https://console.cloud.google.com/dataflow/jobs/${REGION}/${JOB_ID}"
Ouvrez l'URL dans un nouvel onglet de navigateur. Après quelques secondes, le graphique de la tâche Dataflow s'affiche :
Le pipeline Dataflow est maintenant en cours d'exécution et attend de recevoir des notifications d'entrée de Pub/Sub.
Dans Cloud Shell, déclenchez le pipeline Dataflow en important quelques fichiers de test dans le bucket d'entrée :
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}
Dans Google Cloud Console, examinez les compteurs personnalisés dans Dataflow (dans le panneau de droite de la tâche Dataflow) et vérifiez qu'ils ont traité les cinq images :
Dans Cloud Shell, vérifiez que les tables ont été créées automatiquement :
bq query "select table_name, table_type from \ ${BIGQUERY_DATASET}.INFORMATION_SCHEMA.TABLES"
Voici le résultat :
+----------------------+------------+ | 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 | +----------------------+------------+
Affichez le schéma de la table
landmark_annotation
. Sur demande, la fonctionnalitéLANDMARK_DETECTION
capture les attributs renvoyés par l'appel d'API.bq show --schema --format=prettyjson ${BIGQUERY_DATASET}.landmark_annotation
Voici le résultat :
[ { "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" } ]
Arrêtez le pipeline :
gcloud dataflow jobs drain ${JOB_ID} \ --region ${REGION}
Bien qu'il n'y ait plus d'autres notifications Pub/Sub à traiter, le pipeline de streaming que vous avez créé continue de s'exécuter jusqu'à ce que vous saisissiez cette commande.
Analyser un ensemble de données Flickr30K
Dans cette section, vous allez analyser un ensemble de données Flickr30K pour la détection de libellés et de points de repère.
Dans Cloud Shell, définissez un nouveau nom de tâche :
export JOB_NAME=vision-analytics-pipeline-2
Modifiez les paramètres du pipeline Dataflow afin qu'ils soient optimisés pour un grand ensemble de données. Les valeurs
batchSize
etkeyRange
sont augmentées pour permettre un débit supérieur. Dataflow adaptera le nombre de nœuds de calcul en fonction des besoins :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
Exécutez le 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}
Importez l'ensemble de données dans un bucket d'entrée :
gsutil -m cp gs://df-vision-ai-test-data/* gs://${IMAGE_BUCKET}
Récupérez l'ID de la tâche Dataflow en cours d'exécution :
JOB_ID=$(gcloud dataflow jobs list --filter "name:${JOB_NAME}" --region ${REGION} --format "value(id)" --status active)
Affichez l'URL de la page Web de la tâche Dataflow :
echo "https://console.cloud.google.com/dataflow/jobs/${REGION}/${JOB_ID}"
Ouvrez l'URL dans un nouvel onglet de navigateur.
Dans Google Cloud Console, validez les compteurs personnalisés dans Dataflow pour vous assurer que tous les fichiers sont traités. Tous les fichiers sont généralement traités en moins de 30 minutes.
Filtrez par compteurs personnalisés sous Traiter les annotations.
Voici le résultat :
La métrique
processedFiles
(31 935) correspond au nombre total d'images importées dans le bucket (nombre total de fichiers : 31 936). Cependant, la métriquenumberOfRequests
(1 997) est inférieure au nombre de fichiers ayant été traités dans le pipeline. Cette différence est due au fait que le pipeline regroupe jusqu'à 16 fichiers par requête, comme indiqué dans les valeurs des métriquesbatchSizeDistribution_*
.Arrêtez le 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}
Dans la console Google Cloud, accédez à la page Éditeur de requête de BigQuery.
Trouvez le libellé le plus probable pour chaque fichier :
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
Voici le résultat : Vous pouvez voir dans la réponse que le point de repère est la description la plus probable pour le fichier
st_basils.jpeg
.Trouvez les 10 meilleurs libellés et leur score maximal :
SELECT description, COUNT(*) AS found, MAX(score) AS max_score FROM `vision_analytics.label_annotation` GROUP BY description ORDER BY found DESC LIMIT 10
La sortie ressemble à ceci :
Trouvez les 10 points de repère les plus populaires :
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
Voici le résultat : Vous pouvez voir dans la réponse que Times Square est la destination la plus populaire.
Trouvez n'importe quelle image comportant une cascade :
SELECT SPLIT(gcs_uri,'/')[OFFSET(3)] file, description, score FROM `vision_analytics.landmark_annotation` WHERE LOWER(description) LIKE '%fall%' ORDER BY score DESC
Voici le résultat : Il ne contient que des images de cascades.
Trouvez une image d'un monument emblématique dans un rayon de 3 kilomètres du Colisée à Rome (la fonction
ST_GEOPOINT
utilise la longitude et la latitude du Colisée) :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
Voici le résultat : Vous pouvez voir que plusieurs destinations populaires apparaissent dans ces images :
La même image peut contenir plusieurs emplacements du même point de repère. Cette fonctionnalité est décrite dans la documentation de l'API Vision. Étant donné qu'un emplacement peut indiquer le lieu de la scène dans l'image, plusieurs éléments
LocationInfo
peuvent être présents. Un autre emplacement peut indiquer le lieu où l'image a été prise. Des informations concernant la localisation sont généralement disponibles pour les points de repère.Vous pouvez visualiser les données dans BigQuery Geo Viz en collant la requête précédente. Lorsque vous sélectionnez un point sur la carte, les détails associés s'affichent. L'attribut
Image_url
contient le lien vers le fichier image, que vous pouvez ouvrir dans un navigateur.
Nettoyer
Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et supprimez les ressources individuelles.
Supprimer le projet Google Cloud
Le moyen le plus simple d'éviter la facturation consiste à supprimer le projet Google Cloud que vous avez créé pour le tutoriel.
- Dans la console Google Cloud, accédez à la page Gérer les ressources.
- Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
- Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.
Étapes suivantes
- En savoir plus sur les modèles de référence pour les analyses intelligentes.
- Découvrez des architectures de référence, des schémas et des bonnes pratiques concernant Google Cloud. Consultez notre Centre d'architecture cloud.