Classer des données d'images à l'aide de BigQuery ML

1. Introduction

Dans cet atelier de programmation, nous allons voir comment stocker et analyser des images de postures de yoga dans BigQuery. Nous découvrirons également comment implémenter un modèle de classification à l'aide de BigQuery ML pour étiqueter les postures en utilisant des structures SQL uniquement.

BigQuery et BQML

BigQuery est un entrepôt de données multicloud sans serveur, capable de passer des gigaoctets aux pétaoctets sans que cela n'engendre de coûts opérationnels. Il est le choix idéal pour stocker les données d'entraînement de ML. En outre, grâce aux fonctionnalités d'analyse et de machine learning de BigQuery (BQML) intégrées, vous pouvez créer des prédictions sans code en utilisant uniquement des requêtes SQL. Vous pouvez également accéder aux données de sources externes à l'aide de requêtes fédérées, éliminant le besoin de pipelines ETL complexes. Pour en savoir plus sur toutes les fonctionnalités de BigQuery, consultez cette page.

Jusqu'à présent, nous connaissions BigQuery comme cet entrepôt de données cloud entièrement géré, qui permet aux utilisateurs d'analyser des données structurées et semi-structurées. Mais aujourd'hui :

  • BigQuery a été élargi et il peut effectuer toutes les tâches d'analyse et de ML sur des données non structurées ;
  • nous pouvons utiliser des requêtes SQL pour effectuer des tâches pertinentes d'analyse et de ML sur des images, des vidéos, de l'audio, etc. à grande échelle sans avoir à écrire du code supplémentaire ;
  • nous pouvons combiner les données structurées et non structurées comme si elles coexistaient dans une même table.

Nous aborderons ces fonctionnalités dans notre cas d'utilisation de classification de postures de yoga à la section suivante.

Classer des données d'images à l'aide de BigQuery ML

Pouvoir traiter et analyser des images à l'aide de requêtes structurées comme s'il s'agissait de données structurées est une fonctionnalité unique en son genre. Nous sommes désormais capables de prédire des résultats en utilisant des modèles de classification de machine learning à l'aide de BigQuery ML. J'ai dégagé 5 étapes de processus pour vous aider à mieux comprendre :

fe97945bce996e1.jpeg

À première vue, ces étapes, présentées sous forme d'étiquettes, ont l'air complexes. Reportez-vous aux détails de chacun des composants impliqués tels que les ensemble de données BigQuery, la connexion BigLake, les buckets Cloud Storage (conteneurs), la table d'objets (source de données externe), BQML, etc. dans la section d'implémentation. Ne vous découragez donc pas si vous ne connaissez pas bien ces termes.

Objectifs de l'atelier

Vous allez créer un modèle de classification de données d'image à l'aide de BQML, ce qui inclut :

  • un ensemble de données BigQuery qui contiendra les composants de table et de modèle ;
  • le bucket Google Cloud Storage (GCS) pour stocker les images de postures de yoga du modèle ;
  • une table externe pour accéder aux images dans Cloud Storage ;
  • une connexion BigLake pour que la table externe accède aux images dans GCS ;
  • le modèle ResNet dans BigQuery ML ;
  • l'inférence utilisant le modèle créé ;
  • le BigQuery SQL pour analyser les données d'image ;
  • le BigQuery SQL pour interroger les données structurées et non structurées ensemble.

Points abordés

  • Créer un bucket Cloud Storage et stocker des images
  • Créer un ensemble de données, une table et une connexion BigQuery
  • Créer un modèle de classification de données d'image à l'aide de BQML
  • Prédire avec le modèle créé à l'aide de BQML
  • Interroger les images et les combiner avec les données structurées à l'aide de BigQuery SQL

2. Conditions requises

  • Un navigateur tel que Chrome ou Firefox
  • Un projet Google Cloud pour lequel la facturation est activée, et qui contient vos services BigQuery, Cloud Storage et de connexion BigLake
  • La section suivante comporte la liste des étapes pour créer l'application de classification des données d'image

3. Créer un ensemble de données et une connexion BigLake

Pour notre cas d'utilisation impliquant la détection d'images de 5 postures de yoga, j'ai utilisé un ensemble de données accessible publiquement. Retrouvez-le dans ce dépôt. Les postures de yoga que nous identifions sont le chien tête en bas, la déesse, la planche, l'arbre et le guerrier 2. Avant de commencer à créer un ensemble de données BigQuery, veillez à sélectionner ou à créer un projet Google Cloud, et assurez-vous que la facturation est activée sur le projet. Activez l'API BigQuery et l'API BigQuery Connection. Notez que tous les services utilisés dans cette implémentation doivent être dans la même région de votre choix.

a. Créez l'ensemble de données "yoga_set" en suivant les étapes suivantes :

Accédez à l'éditeur BigQuery et saisissez la commande suivante :

CREATE SCHEMA `<<project_id>>.yoga_set`;

b. BigQuery Connection nous permet de connecter la source de données externe tout en conservant une sécurité et un contrôle des accès ultraprécis dans BigQuery, qui dans notre cas est Cloud Storage pour les données d'image. Nous utiliserons cette connexion pour lire les objets depuis Cloud Storage. Effectuez les étapes suivantes pour créer la BigQuery Connection.

Cliquez sur AJOUTER DES DONNÉES dans le volet de l'explorateur de la page BigQuery :

4cb42b1245bb0ba6.pngÉcran "Ajouter des données externes" de BigQuery

Cliquez sur Connexions à des sources de données externes et sélectionnez l'option "BigLake et fonctions à distance" :

9ffec2b2bfcc3cd5.pngConfigurer une connexion à une source de données externe

Indiquez l'ID de connexion et créez la connexion. N'oubliez pas de noter l'ID du compte de service qui apparaît à l'écran une fois la connexion créée <<SERVICE_ACCOUNT>>. Dans notre exemple, l'ID de connexion est "yoga-pose-conn". N'oubliez pas non plus de noter la région.

4. Créer le bucket Google Cloud Storage et accorder les autorisations

Nous allons utiliser le bucket Google Cloud Storage devant contenir les fichiers image des postures de yoga sur lesquelles nous voulons créer le modèle. Les buckets sont des conteneurs Cloud Storage où stocker les images que nous allons analyser.

a. Accédez à Google Cloud Storage en le recherchant dans la console, puis cliquez sur "Buckets" pour accéder à la page d'accueil "Buckets" et cliquez sur CRÉER.

a6f6b26cffb53ae0.pngPage "Buckets" dans Google Cloud Storage

b. Sur la page "Créer un bucket", saisissez les informations de votre bucket (un nom unique) et continuez. Assurez-vous qu'il se trouve dans la même région que l'ensemble de données et la connexion abordés aux étapes précédentes, puis cliquez sur "Créer".

1280366a42b7bdf6.pngPage "Créer un bucket" dans Google Cloud Storage

Avant de passer à l'étape suivante, assurez-vous d'avoir noté vos compte de service, nom de bucket et chemin d'accès.

c. Une fois le bucket créé, stockez vos images (via la console, des commandes Cloud Shell ou de manière programmatique). Accordez ensuite au compte de service (enregistré précédemment) de la connexion les autorisations nécessaires pour accéder aux images.

> export sa=<<"SERVICE_ACCOUNT">>
> gsutil iam ch serviceAccount:$sa:objectViewer "gs://<<bucket>>"

5. Créer une table d'objets

Créez une table d'objets externe à partir de BigQuery pour accéder aux données non structurées dans le bucket à l'aide de la connexion que nous avons créée. Exécutez le code SQL "CREATE" suivant dans l'éditeur BigQuery :

CREATE OR REPLACE EXTERNAL TABLE `<<dataset>>.<<table_name>>`
WITH CONNECTION `us.<<connection-name>>`
OPTIONS(
object_metadata="SIMPLE", uris=["gs://<<bucket>>/<<folder_if_exists>>/*.jpg"]);

La table externe est créée comme indiqué ci-dessous :

bda48f566e0c292f.png

Effectuons une requête rapide sur une posture depuis la table externe que nous venons de créer :

SELECT data , uri
FROM `yoga_set.yoga_poses`
WHERE REGEXP_CONTAINS(uri, 'gs://yoga_images/Downdog')
Limit 1;

Comme vous le voyez dans l'écran ci-dessous, vous pouvez créer et exploiter des images non structurées comme s'il s'agissait de données structurées :

7d1784122b5013f.png

Exportons maintenant les résultats de la requête ci-dessus dans un petit extrait de code Python pour visualiser les résultats :

Cliquez sur ENREGISTRER LES RÉSULTATS et sélectionnez l'option "CSV (local file)" pour exporter les résultats. Ouvrez ensuite votre notebook Colab (ou créez-en un) et saisissez le code ci-dessous :

from IPython.display import display
from PIL import Image
import io
import pandas as pd
import base64
df = pd.read_csv('/content/sample_data/<<your_csv>>')
imgdata = base64.b64decode(str(df.data[0]))
image = Image.open(io.BytesIO(imgdata))
display(image)

Exécutez ce code pour voir les résultats comme ci-dessous :

b8edd68cb281786a.png

Maintenant que vous avez créé la table externe et consulté les images à partir de Cloud Storage en utilisant uniquement des requêtes SQL, passons à la section suivante où nous allons créer le modèle de classification.

6. Créer le modèle et l'importer dans Google Cloud Storage

Pour cette implémentation, nous allons utiliser le modèle ResNet 50 pré-entraîné pour exécuter l'inférence sur la table d'objets que nous venons de créer. Le modèle ResNet 50 analyse les fichiers image et génère un lot de vecteurs représentant la probabilité qu'une image appartienne à la classe correspondante (fonctions logit).

Avant de passer à cette étape, assurez-vous que vous disposez de toutes les autorisations nécessaires. Effectuez ensuite les étapes suivantes :

  1. Téléchargez le modèle à cet emplacement et enregistrez-le en local.
  2. Il devrait être décompressé en un fichier saved_model.pb et un dossier de variables.
  3. Importez le fichier et le dossier dans le bucket créé dans la section précédente.

2629ff3eda214946.pngBucket Google Cloud Storage "yoga_images" avec les fichiers de modèle ResNet importés

Une fois cette étape terminée, les fichiers associés à votre modèle devraient se trouver dans le même bucket que vos images, comme dans l'image ci-dessus.

7. Importer le modèle dans BQML et effectuer une inférence

Pour cette étape, nous allons importer le modèle dans le même ensemble de données BigQuery que la table externe créée précédemment. Nous l'appliquerons ensuite pour les images que nous avons stockées dans Cloud Storage.

a. Dans l'éditeur BigQuery, exécutez l'instruction SQL suivante :

CREATE MODEL `<<Dataset>>.<<Model_Name>>`
OPTIONS(
model_type = 'TENSORFLOW',
model_path = 'gs://<<Bucket>>/*');

Une fois l'exécution terminée (l'opération peut prendre un certain temps en fonction de votre ensemble de données), le modèle devrait être affiché dans la section de votre ensemble de données dans BigQuery.

435fa0919aeb57a6.pngEnsemble de données BigQuery affichant le modèle créé

b. Inspectez le modèle pour afficher ses champs d'entrée et de sortie.

Développez l'ensemble de données et cliquez sur le modèle "yoga_poses_resnet" que nous venons de créer. Cliquez sur l'onglet "Schéma" :

e88928764f10f6ff.pngOnglet "Schéma" de la définition du modèle BigQuery

Dans la section "Étiquettes", vous voyez le champ "activation_49" qui représente le champ de sortie. Dans la section "Fonctionnalités", vous pouvez voir "input_1" qui représente le champ devant être l'entrée du modèle. Vous utiliserez "input_1" dans votre requête d'inférence (ou requête de prédiction) comme champ que vous transmettez pour vos données de "test".

c. Effectuer une inférence sur les postures de yoga

Utilisons le modèle que nous venons de créer pour classer nos données d'image de test. Assurez-vous que vous disposez d'images de test (postures de yoga) identifiées depuis votre bucket Cloud Storage et qui ont été transmises dans la table externe lorsque nous l'avons créée. Nous allons envoyer une requête de manière sélective pour ces images de test dans BigQuery afin d'effectuer l'inférence à l'aide de notre modèle BQML. Utilisez la requête ci-dessous pour déclencher le test.

SELECT *
FROM ML.PREDICT(
MODEL yoga_set.yoga_poses_resnet,
(SELECT uri, ML.DECODE_IMAGE(data) AS input_1
FROM yoga_set.yoga_poses where REGEXP_CONTAINS(uri,
'gs://yoga_images/Downdog/00000097.jpg')));

Dans la requête ci-dessus, nous sélectionnons une image de test identifiée comme contenant une valeur d'URI spécifique (00000097.jpg) dans la table externe. En outre, la partie SELECT utilise la structure ML.DECODE_IMAGE comme champ "input_1" pour permettre à la fonction ML.PREDICT de fonctionner.

Une fois l'exécution terminée, les résultats sont affichés comme suit :

867018993845e943.png

Si vous connaissez bien le modèle ResNet, ceci devrait vous aider à comprendre la classification. Sinon, codons un petit extrait pour comprendre la classification de manière visuelle.

d. Aplatir le résultat

Vous pouvez visualiser la sortie ci-dessus en aplatissant les valeurs du champ activation_49 à l'aide de la structure UNNEST de BigQuery SQL. Reportez-vous à la requête ci-dessous pour aplatir le résultat obtenu à l'étape précédente. Si vous voulez étiqueter la classe obtenue avec davantage de texte, vous pouvez introduire la logique à la place de l'espace réservé <<LABEL_LOGIC>> dans la requête (annulez la mise en commentaire lorsque vous l'utilisez).

with predictions as (
SELECT
Uri, data, SPLIT(uri, "/")[OFFSET(ARRAY_LENGTH(SPLIT(uri, "/")) - 1)] as img,
i as label_i,
<<LABEL_LOGIC>> label,
Score
FROM ML.PREDICT(
MODEL yoga_set.yoga_poses_resnet,
(SELECT data, uri, ML.DECODE_IMAGE(data) AS input_1
FROM yoga_set.yoga_poses
WHERE
REGEXP_CONTAINS(uri,'gs://yoga_images/Goddess/00000007.jpg'))),
UNNEST(activation_49) as score WITH OFFSET i)
SELECT * FROM predictions
ORDER BY score DESC
LIMIT  5;

Sans la logique d'étiquetage de la classe, la sortie de la requête ressemble à ceci :

71f580f41f0811f3.png

Toutefois dans mon cas, j'ai appliqué un exemple de logique et obtenu le résultat suivant :

1c6df6ecd14fba1.png

Vous pouvez approfondir vos connaissances sur le modèle, et appliquer la logique la mieux adaptée à vos données et à la sortie du modèle.

e. Visualiser l'inférence

Pour finir, un bref extrait de code Python vous permettra de visualiser le résultat de la classification. Exportez le résultat de la requête ci-dessus dans un fichier CSV et référencez-le dans le code Python.

68756e7e4b8d7a29.png

La sortie d'image ci-dessus correspond à la posture de yoga "chien tête en bas" qui est exactement la même entrée de test transmise dans la requête ML.PREDICT pour la classification à l'aide de BQML.

8. Unifier les données structurées et non structurées

Enfin, ce que je préfère dans cette implémentation c'est unifier les champs de ma table relationnelle structurée avec ces données d'image non structurées. J'ai créé une table BigQuery structurée dans le même ensemble de données que la table externe de façon à contenir la posture et ses données de santé.

125bdf848c86fbe.pngSchéma de la table structurée "yoga_health" dans BigQuery

L'image ci-dessus montre le schéma de la table de données structurée nommée "yoga_health", et les champs sont "pose", "focus", "health_benefit" et "breath". La requête ci-dessous joint les données structurées et non structurées :

SELECT SPLIT(uri, "/")[OFFSET(ARRAY_LENGTH(SPLIT(uri, "/")) - 2)] as pose,
a.health_benefit, breath, focus, data
FROM `abis-345004.yoga_set.yoga_health` a, yoga_set.yoga_poses b
WHERE a.pose = SPLIT(uri, "/")[OFFSET(ARRAY_LENGTH(SPLIT(uri, "/")) - 2)];

Le résultat est le suivant :

469bdfcffa9e19fd.png

Remarque : Vous pouvez exécuter toutes les requêtes que nous avons abordées dans ce blog directement dans votre notebook Python à l'aide des commandes magiques BigQuery.

9. Effectuer un nettoyage

Pour éviter que les ressources utilisées dans cet atelier soient facturées sur votre compte Google Cloud, procédez comme suit :

  1. Dans la console Google Cloud, accédez à la page Gérer les ressources.
  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur "Supprimer".
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur "Arrêter" pour supprimer le projet.

10. Félicitations

Félicitations ! Vous avez stocké et interrogé des données non structurées dans BigQuery, créé un modèle de classification à l'aide de BQML et prédit les postures de yoga de test avec le modèle. Si vous voulez implémenter ce que vous avez appris, commencez avec votre projet Google Cloud. Si vous souhaitez également en savoir plus sur les bases de données ou sur d'autres implémentations d'application de bout en bout dans Google Cloud, veuillez consulter mes blogs.