1. מבוא
ב-Codelab הזה נדון בתרחיש לדוגמה של אחסון וניתוח של תמונות של תנוחות יוגה ב-BigQuery, ובהטמעה של מודל סיווג באמצעות BigQuery ML כדי לתייג את התנוחות באמצעות מבני SQL בלבד, ללא שימוש בצורות אחרות של קוד.
BigQuery ו-BQML
BigQuery הוא מחסן נתונים בענן מרובה עננים (multi-cloud), ללא שרת (serverless), שאפשר להגדיל את הקיבולת שלו מבתים ועד פטה-בייט ללא תקורה תפעולית. לכן, זו בחירה מצוינת לאחסון נתוני אימון של למידת מכונה (ML). בנוסף, היכולות המובנות של למידת מכונה ב-BigQuery ( BQML) וניתוח הנתונים מאפשרות לכם ליצור תחזיות ללא צורך בכתיבת קוד, באמצעות שאילתות SQL בלבד. בנוסף, אפשר לגשת לנתונים ממקורות חיצוניים באמצעות שאילתות מאוחדות, כך שאין צורך בצינורות ETL מורכבים. מידע נוסף על כל מה ש-BigQuery מציע זמין בדף BigQuery.
עד עכשיו, הכרנו את BigQuery כמחסן נתונים בענן מנוהל לחלוטין, שעוזר למשתמשים לנתח נתונים מובְנים ונתונים חצי-מובְנים. אבל,
- היכולות של BigQuery הורחבו כך שהוא יכול לבצע את כל הניתוחים ואת כל פעולות ה-ML גם על נתונים לא מובְנים
- אנחנו יכולים להשתמש בשאילתות SQL כדי לבצע ניתוח מעמיק, ניתוח נתונים ולמידת מכונה על תמונות, סרטונים, אודיו וכו' בהיקף גדול, בלי לכתוב קוד נוסף
- יש לנו אפשרות לשלב נתונים מובְנים ולא מובְנים כאילו כולם קיימים יחד בטבלה
נדון בהם בתרחיש לדוגמה של סיווג תנוחות יוגה שמופיע בקטע הבא.
סיווג נתוני תמונות באמצעות BigQuery ML
היכולת לעבד ולנתח תמונות באמצעות שאילתות מובנות כאילו היו נתונים מובנים היא הראשונה מסוגה. עכשיו אנחנו יכולים אפילו לחזות תוצאות באמצעות מודלים של סיווג ללמידת מכונה באמצעות BigQuery ML. כדי להקל על ההבנה, חילקתי את השלבים ל-5:

השלבים שלמעלה יכולים להיות מסובכים אם מסתכלים עליהם רק כתוויות. הפרטים של כל אחד מהרכיבים שמעורבים בתהליך, כמו מערך נתונים ב-BigQuery, Lakehouse לחיבור Apache Iceberg, Cloud Storage Buckets (מאגרי נתונים), Object Table (מקור נתונים חיצוני), BQML וכו', מוגדרים כולם בקטע ההטמעה. לכן, אל תתייאשו אם אתם עדיין לא מכירים את המונחים האלה.
מה תפַתחו
תלמדו ליצור מודל לסיווג נתוני תמונות באמצעות BQML, שיכלול את הנושאים הבאים:
- מערך נתונים ב-BigQuery שיכיל את הטבלה ואת רכיבי המודל
- קטגוריה של Google Cloud Storage (GCS) לאחסון תמונות של Yoga עבור המודל
- טבלה חיצונית לגישה לתמונות ב-Cloud Storage
- חיבור Lakehouse לטבלה החיצונית כדי לגשת לתמונות ב-GCS
- מודל ResNet ב-BigQuery ML
- הסקת מסקנות באמצעות המודל שנוצר
- BigQuery SQL לניתוח נתוני תמונות
- BigQuery SQL כדי לשלוח שאילתות לנתונים המובְנים והלא מובְנים ביחד
מה תלמדו
- איך יוצרים קטגוריה של Cloud Storage ומאחסנים בה תמונות
- איך יוצרים מערך נתונים, טבלה וחיבור ב-BigQuery
- איך ליצור מודל לסיווג נתוני תמונות באמצעות BQML
- איך לבצע חיזויים באמצעות המודל שנוצר באמצעות BigQuery ML
- איך שולחים שאילתות לתמונות ומשלבים אותן עם נתונים מובְנים באמצעות BigQuery SQL
2. דרישות
3. יצירת מערך נתונים וחיבור Lakehouse
לצורך תרחיש השימוש שלנו לזיהוי תמונות של 5 תנוחות יוגה, השתמשתי במערך נתונים שזמין לציבור, ואפשר לגשת אליו ממאגר זה. תנוחות היוגה שאנחנו מזהים מוגבלות לתנוחות הבאות: כלב מביט למטה, אלת המלחמה, פלאנק, עץ ולוחם 2. לפני שמתחילים ליצור את מערך הנתונים ב-BigQuery, חשוב לבחור או ליצור פרויקט ב-Google Cloud ולבדוק אם החיוב מופעל בפרויקט. מפעילים את BigQuery API ואת BigQuery Connection API. חשוב לשים לב שכל השירותים שבהם נעשה שימוש בהטמעה הזו צריכים להיות באותו אזור.
א. יוצרים את מערך הנתונים yoga_set באמצעות השלבים שמוצגים בהמשך:
עוברים אל עורך BigQuery ומקלידים את הפקודה:
CREATE SCHEMA `<<project_id>>.yoga_set`;
ב. חיבור Lakehouse מאפשר לנו לחבר את מקור הנתונים החיצוני תוך שמירה על בקרת גישה ואבטחה פרטניות ב-BigQuery, שבמקרה שלנו הוא Cloud Storage לנתוני התמונות. החיבור הזה ישמש לקריאת אובייקטים מ-Cloud Storage. כדי ליצור את החיבור ל-Lakehouse, פועלים לפי השלבים הבאים.
לוחצים על ADD DATA (הוספת נתונים) בחלונית Explorer (סייר) בדף BigQuery:
מסך 'הוספת נתונים חיצוניים' ב-BigQuery
לוחצים על Connections to external data sources (חיבורים למקורות נתונים חיצוניים) ובוחרים באפשרות Lakehouse and Remote functions (פונקציות של Lakehouse ופונקציות מרוחקות):
הגדרת חיבור למקור נתונים חיצוני
מזינים את מזהה החיבור ויוצרים את החיבור. חשוב לרשום את מזהה חשבון השירות שיוצג במסך אחרי יצירת החיבור <<SERVICE_ACCOUNT>>. בדוגמה שלנו, מזהה החיבור הוא yoga-pose-conn. חשוב לציין את האזור.
4. יצירת קטגוריה של Google Cloud Storage והענקת הרשאות
אנחנו נשתמש בקטגוריה של Google Cloud Storage כדי לאחסן את קובצי התמונות של תנוחות היוגה שעליהן אנחנו רוצים ליצור את המודל. קטגוריות הן קונטיינרים ב-Cloud Storage שמכילים את התמונות שאנחנו הולכים לנתח.
א. נכנסים ל-Google Cloud Storage על ידי חיפוש שלו במסוף, ואז לוחצים על Buckets כדי להגיע לדף הבית של Buckets ולוחצים על CREATE.
דף הקטגוריות של Google Cloud Storage
ב. בדף 'יצירת קטגוריה', מזינים את פרטי הקטגוריה (שם ייחודי) וממשיכים. חשוב לוודא שהקטגוריה נמצאת באותו אזור כמו מערך הנתונים והחיבור שמוזכרים בשלבים שלמעלה. לאחר מכן לוחצים על 'יצירה'.
דף ליצירת קטגוריה ב-Google Cloud Storage
לפני שעוברים לשלב הבא, חשוב לוודא שרשמתם את חשבון השירות, שם הדלי והנתיב.
ג. אחרי שיוצרים את ה-bucket, מאחסנים בו את התמונות (באמצעות פקודות במסוף או ב-Cloud Shell, או באופן פרוגרמטי) ומעניקים את ההרשאות הנדרשות לחשבון השירות של החיבור (ששמרנו קודם) כדי לגשת לתמונות.
> export sa=<<"SERVICE_ACCOUNT">>
> gsutil iam ch serviceAccount:$sa:objectViewer "gs://<<bucket>>"
5. יצירת טבלת אובייקטים
יוצרים טבלת אובייקטים חיצונית מ-BigQuery כדי לגשת לנתונים הלא מובנים בדלי באמצעות החיבור שיצרנו. מריצים את פקודת ה-SQL הבאה של CREATE מכלי העריכה של 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"]);
טבלה חיצונית נוצרת כמו שמוצג בהמשך:

בואו נשאל שאילתה במהירות לגבי תנוחה מהטבלה החיצונית החדשה שיצרנו:
SELECT data , uri
FROM `yoga_set.yoga_poses`
WHERE REGEXP_CONTAINS(uri, 'gs://yoga_images/Downdog')
Limit 1;
כפי שאפשר לראות בצילום המסך שלמטה, אתם יכולים ליצור תמונות לא מובנות ולבצע בהן פעולות כאילו הן נתונים מובנים:

עכשיו נבצע ייצוא של תוצאת השאילתה שלמעלה לקטע קוד קטן ב-Python כדי להציג את התוצאה:
לוחצים על SAVE RESULTS (שמירת תוצאות) ובוחרים באפשרות CSV Localfile (קובץ CSV מקומי) כדי לייצא את התוצאה. לאחר מכן פותחים את ה-Notebook של Colab (או יוצרים אחד) ומקלידים את הקוד שבהמשך.
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)
מריצים את הפקודה כדי לראות את התוצאה כמו בדוגמה הבאה:

אחרי שיצרנו את הטבלה החיצונית וניגשנו לתמונות מ-Cloud Storage רק באמצעות שאילתות SQL, נעבור לקטע הבא שמתייחס ליצירת מודל הסיווג.
6. יצירת המודל והעלאה שלו ל-Google Cloud Storage
ביישום הזה, נשתמש במודל ResNet 50 שעבר אימון מראש כדי להריץ הסקה על טבלת האובייקטים שיצרנו. מודל ResNet 50 מנתח קובצי תמונות ומפיק קבוצה של וקטורים שמייצגים את הסבירות שתמונה שייכת לסיווג המתאים (לוגיטים).
לפני שממשיכים לשלב הזה, חשוב לוודא שיש לכם את כל ההרשאות הנדרשות. ואז מבצעים את השלבים הבאים:
- מורידים את המודל מהמיקום הזה ושומרים אותו בתיקייה המקומית
- הוא אמור להיפרק לקובץ saved_model.pb ולתיקיית משתנים
- מעלים את שני הפריטים האלה (הקובץ והתיקייה) לקטגוריה שיצרנו בקטע הקודם.
קטגוריה של Google Cloud Storage (Bucket) בשם yoga_images עם קבצים של מודל ResNet שהועלו
אחרי השלמת השלב הזה, הקבצים שקשורים למודל צריכים להיות באותו מאגר כמו התמונות, כמו שרואים בתמונה שלמעלה.
7. טעינת המודל ל-BQML והסקת מסקנות
בשלב הזה נטען את המודל לאותו מערך נתונים ב-BigQuery כמו הטבלה החיצונית שיצרנו קודם, ונחיל אותו על התמונות שאחסנו ב-Cloud Storage.
א. בעורך של BigQuery, מריצים את הצהרת ה-SQL הבאה
CREATE MODEL `<<Dataset>>.<<Model_Name>>`
OPTIONS(
model_type = 'TENSORFLOW',
model_path = 'gs://<<Bucket>>/*');
אחרי שההרצה תסתיים (היא עשויה להימשך זמן מה, בהתאם למערך הנתונים), המודל יופיע בקטע Dataset ב-BigQuery.
רשימת מערכי נתונים ב-BigQuery שכוללת את המודל שנוצר
ב. בודקים את המודל כדי לראות את שדות הקלט והפלט שלו.
מרחיבים את מערך הנתונים ולוחצים על המודל שיצרנו הרגע, yoga_poses_resnet. לוחצים על הכרטיסייה Schema (סכימה):
הכרטיסייה 'סכימת הגדרת מודל BigQuery'
בקטע Labels (תוויות), מופיע השדה activation_49 (הפעלה_49) שמייצג את שדה הפלט. בקטע Features (מאפיינים), אפשר לראות את input_1 שמייצג את השדה שאמור להיות קלט למודל. תציינו את input_1 בשאילתת ההיסק (או בשאילתת החיזוי) כשדה שמועבר לנתוני הבדיקה.
ג. הסיקו את תנוחת היוגה!
נשתמש במודל שיצרנו כדי לסווג את נתוני תמונות הבדיקה. צריך לוודא שיש לכם כמה תמונות בדיקה (תנוחות יוגה) שזוהו מקטגוריית Cloud Storage ונכללו בטבלה החיצונית שיצרנו. נשלח שאילתה סלקטיבית לתמונות הבדיקה האלה ב-BigQuery כדי לבצע את ההסקה באמצעות מודל BQML שיצרנו. משתמשים בשאילתה שלמטה כדי להפעיל את הבדיקה.
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')));
בשילתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתתת
אחרי שההפעלה תסתיים, תראו את התוצאה כמו שמוצג למטה:

עכשיו, למי שמכיר לעומק את מודל ResNet, זה אמור לעזור להבין את הסיווג. אחרת, נכתוב קטע קוד קטן כדי להבין את הסיווג באופן חזותי.
ד. השטחת התוצאה
דרך אחת להציג את הפלט שלמעלה היא לשטח את הערכים של השדה activation_49 באמצעות מבנה UNNEST של BigQuery SQL. כדי לשטח את התוצאה מהשלב הקודם, אפשר להשתמש בשאילתה שבהמשך. אם רוצים להוסיף עוד תווית טקסטואלית לסיווג שמתקבל, אפשר להוסיף את הלוגיקה במקום ה-placeholder <<LABEL_LOGIC>> בשאילתה (צריך לבטל את ההערה כשמשתמשים).
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;
ללא לוגיקת התיוג של הכיתה, הפלט של השאילתה הוא:

אבל במקרה שלי, יישמתי לוגיקה לדוגמה והתוצאה מופיעה בהמשך:

אפשר לקרוא עוד על המודל ולהחיל את הלוגיקה שהכי מתאימה לנתונים שלכם ולפלט של המודל.
ה. הצגה חזותית של ההיקש
לבסוף, קטע קוד קצר ב-Python להצגת התוצאה מהסיווג! תייצא את תוצאת השאילתה שלמעלה לקובץ CSV ותפנה אליה בקוד Python.

התמונה שנוצרה למעלה היא של תנוחת היוגה 'כלב מביט למטה', שהיא בדיוק אותה תמונה שהעברנו כקלט לבקשת ML.PREDICT לצורך סיווג באמצעות BQML.
8. איחוד של נתונים מובנים ולא מובנים
לבסוף, החלק האהוב עליי בהטמעה הזו הוא איחוד השדות מהטבלה היחסית המובנית שלי עם נתוני התמונות הלא מובנים האלה. יצרתי טבלה מובנית ב-BigQuery באותו מערך נתונים כמו הטבלה החיצונית, כדי להכיל את התנוחה ואת הנתונים שקשורים לבריאות.
סכימה של טבלה מובנית ב-BigQuery yoga_health
התמונה שלמעלה מייצגת את הסכימה של טבלת הנתונים המובנים בשם yoga_health, והשדות הם pose, focus, health_benefit ו-breath. השאילתה שלמטה מצטרפת לנתונים מובנים ולא מובנים:
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)];
זו התוצאה:

הערה: אפשר להריץ את כל השאילתות שמופיעות בפוסט הזה בבלוג ישירות מ-Python Notebook באמצעות הפקודות של BigQuery Magic.
9. הסרת המשאבים
כדי לא לצבור חיובים לחשבון Google Cloud על המשאבים שבהם השתמשתם במאמר הזה:
- במסוף Google Cloud, עוברים לדף Manage resources.
- ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על סמל המחיקה.
- כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.
10. מזל טוב
מעולה! אחסנתם נתונים לא מובנים ב-BigQuery, ביצעתם עליהם שאילתות, יצרתם מודל סיווג באמצעות BQML וניבאתם תנוחות יוגה לבדיקה באמצעות המודל. כדי להטמיע את התכונה הזו, צריך להתחיל עם פרויקט Google Cloud. בנוסף, אם תרצו לקבל מידע נוסף על מסדי נתונים או על הטמעות אחרות של אפליקציות מקצה לקצה ב-Google Cloud, תוכלו לעיין בבלוגים שלי.