במסמך הפריסה הזה מוסבר איך לפרוס צינור (pipeline) של Dataflow כדי לעבד קובצי תמונות בהיקף גדול באמצעות Cloud Vision API. הצינור הזה שומר את התוצאות של הקבצים שעברו עיבוד ב-BigQuery. אפשר להשתמש בקבצים למטרות ניתוח או כדי לאמן מודלים של BigQuery ML.
צינור ה-Dataflow שיוצרים בפריסה הזו יכול לעבד מיליוני תמונות ביום. המגבלה היחידה היא המכסה של Vision API. אתם יכולים להגדיל את המכסה של Vision API בהתאם לדרישות שלכם.
ההוראות האלה מיועדות למהנדסי נתונים ולמדעני נתונים. הנחת המוצא במסמך הזה היא שיש לכם ידע בסיסי בבניית צינורות Dataflow באמצעות Java SDK של Apache Beam, GoogleSQL ל-BigQuery וסקריפטים בסיסיים של Shell. בנוסף, אנחנו מניחים שאתם מכירים את Vision API.
ארכיטקטורה
בתרשים הבא מוצג תהליך המערכת ליצירת פתרון לניתוח נתונים של ראייה ממוחשבת (ML).
בתרשים שלמעלה, המידע זורם בארכיטקטורה באופן הבא:
- לקוח מעלה קובצי תמונות לקטגוריה של Cloud Storage.
- Cloud Storage שולח הודעה לגבי העלאת הנתונים אל Pub/Sub.
- Pub/Sub שולח ל-Dataflow התראה על ההעלאה.
- צינור הנתונים של Dataflow שולח את התמונות אל Vision API.
- Vision API מעבד את התמונות ואז מחזיר את ההערות.
- הצינור שולח את הקבצים עם ההערות ל-BigQuery כדי שתוכלו לנתח אותם.
מטרות
- יצירת צינור Apache Beam לניתוח תמונות שנטענו ב-Cloud Storage.
- משתמשים ב-Dataflow Portable Runner כדי להריץ את צינור עיבוד הנתונים של Apache Beam במצב סטרימינג, כדי לנתח את התמונות ברגע שהן מועלות.
- משתמשים ב-Vision API כדי לנתח תמונות לפי קבוצה של סוגי תכונות.
- ניתוח הערות באמצעות BigQuery.
עלויות
במסמך הזה משתמשים ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:
כדי להעריך את ההוצאות בהתאם לתחזית השימוש שלכם, אתם יכולים להיעזר במחשבון העלויות.
כדי להימנע מחיובים נוספים אחרי שסיימתם ליצור את האפליקציה לדוגמה, תוכלו למחוק את המשאבים שיצרתם. מידע נוסף זמין בקטע הסרת המשאבים.
לפני שמתחילים
- נכנסים לחשבון Google Cloud . אם אתם משתמשים חדשים ב- Google Cloud, צרו חשבון כדי שתוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
במסוף Google Cloud , מפעילים את Cloud Shell.
בחלק התחתון של Google Cloud המסוף יתחיל סשן של Cloud Shell ותופיע הודעה של שורת הפקודה. Cloud Shell היא סביבת מעטפת שבה ה-CLI של Google Cloud מותקן ומוגדרים ערכים לפרויקט הקיים. הסשן יופעל תוך כמה שניות.
- משכפלים את המאגר ב-GitHub שמכיל את קוד המקור של צינור Dataflow:
git clone https://github.com/GoogleCloudPlatform/dataflow-vision-analytics.git - עוברים לתיקיית הבסיס של המאגר:
cd dataflow-vision-analytics - פועלים לפי ההוראות שבקטע תחילת העבודה במאגר dataflow-vision-analytics ב-GitHub כדי לבצע את המשימות הבאות:
- מפעילים כמה ממשקי API.
- יצירת קטגוריה של Cloud Storage.
- יוצרים נושא ומינוי ב-Pub/Sub.
- יוצרים מערך נתונים ב-BigQuery.
- מגדירים כמה משתני סביבה לפריסה הזו.
הרצת צינור עיבוד הנתונים של Dataflow לכל התכונות שהוטמעו ב-Vision API
צינור הנתונים של Dataflow מבקש ומעבד קבוצה ספציפית של תכונות ומאפיינים של Vision API בקבצים עם ההערות.
הפרמטרים שמפורטים בטבלה הבאה ספציפיים לצינור Dataflow בפריסה הזו. רשימה מלאה של פרמטרים סטנדרטיים להרצת Dataflow מופיעה במאמר הגדרת אפשרויות של צינור עיבוד נתונים ב-Dataflow.
| שם הפרמטר | תיאור |
|---|---|
|
מספר התמונות שייכללו בבקשה ל-Vision API. ערך ברירת המחדל הוא 1. אפשר להגדיל את הערך הזה עד 16. |
|
השם של מערך הנתונים ב-BigQuery שבו יאוחסנו התוצאות. |
|
רשימה של תכונות לעיבוד תמונות. הצינור תומך בתכונות של תוויות, ציוני דרך, לוגו, פנים, הצעות לחיתוך ומאפייני תמונה. |
|
הפרמטר שמגדיר את המספר המקסימלי של קריאות מקבילות ל-Vision API. ערך ברירת המחדל הוא 1. |
|
פרמטרים של מחרוזות עם שמות של טבלאות להערות שונות. ערכי ברירת המחדל מופיעים בכל טבלה – לדוגמה, label_annotation. |
|
משך הזמן להמתנה לפני עיבוד תמונות כשיש קבוצת תמונות לא שלמה. ברירת המחדל היא 30 שניות. |
|
המזהה של מינוי Pub/Sub שמקבל התראות קלט מ-Cloud Storage. |
|
מזהה הפרויקט שבו רוצים להשתמש ב-Vision API. |
ב-Cloud Shell, מריצים את הפקודה הבאה כדי לעבד תמונות לכל סוגי התכונות שנתמכים על ידי צינור הנתונים של Dataflow:
./gradlew run --args=" \ --jobName=test-vision-analytics \ --streaming \ --runner=DataflowRunner \ --enableStreamingEngine \ --diskSizeGb=30 \ --project=${PROJECT} \ --datasetName=${BIGQUERY_DATASET} \ --subscriberId=projects/${PROJECT}/subscriptions/${GCS_NOTIFICATION_SUBSCRIPTION} \ --visionApiProjectId=${PROJECT} \ --features=IMAGE_PROPERTIES,LABEL_DETECTION,LANDMARK_DETECTION,LOGO_DETECTION,CROP_HINTS,FACE_DETECTION"לחשבון השירות הייעודי צריכה להיות גישת קריאה לקטגוריה שמכילה את התמונות. במילים אחרות, לחשבון הזה צריך להיות התפקיד
roles/storage.objectViewerבקטגוריה הזו.מידע נוסף על שימוש בחשבון שירות ייעודי זמין במאמר אבטחה והרשאות ב-Dataflow.
פותחים את כתובת ה-URL שמוצגת בכרטיסייה חדשה בדפדפן, או עוברים לדף Dataflow Jobs ובוחרים את צינור הנתונים test-vision-analytics.
אחרי כמה שניות, הגרף של משימת Dataflow מופיע:
צינור הנתונים של Dataflow פועל עכשיו וממתין לקבלת התראות קלט מהמינוי ל-Pub/Sub.
כדי להפעיל את עיבוד התמונות ב-Dataflow, מעלים את ששת קובצי הדוגמה לקטגוריית הקלט:
gcloud storage cp data-sample/* gs://${IMAGE_BUCKET}במסוף Google Cloud , מאתרים את החלונית Custom Counters (מונים בהתאמה אישית) ומשתמשים בה כדי לבדוק את המונים בהתאמה אישית ב-Dataflow ולוודא ש-Dataflow עיבד את כל ששת התמונות. אפשר להשתמש בפונקציונליות של הסינון בחלונית כדי לנווט למדדים הנכונים. כדי להציג רק את המונים שמתחילים בקידומת
numberOf, מקלידיםnumberOfבמסנן.
ב-Cloud Shell, מוודאים שהטבלאות נוצרו באופן אוטומטי:
bq query --nouse_legacy_sql "SELECT table_name FROM ${BIGQUERY_DATASET}.INFORMATION_SCHEMA.TABLES ORDER BY table_name"הפלט אמור להיראות כך:
+----------------------+ | table_name | +----------------------+ | crop_hint_annotation | | face_annotation | | image_properties | | label_annotation | | landmark_annotation | | logo_annotation | +----------------------+
צפייה בסכימה של הטבלה
landmark_annotation. התכונהLANDMARK_DETECTIONמתעדת את המאפיינים שמוחזרים מהקריאה ל-API.bq show --schema --format=prettyjson ${BIGQUERY_DATASET}.landmark_annotationהפלט אמור להיראות כך:
[ { "name":"gcs_uri", "type":"STRING" }, { "name":"feature_type", "type":"STRING" }, { "name":"transaction_timestamp", "type":"STRING" }, { "name":"mid", "type":"STRING" }, { "name":"description", "type":"STRING" }, { "name":"score", "type":"FLOAT" }, { "fields":[ { "fields":[ { "name":"x", "type":"INTEGER" }, { "name":"y", "type":"INTEGER" } ], "mode":"REPEATED", "name":"vertices", "type":"RECORD" } ], "name":"boundingPoly", "type":"RECORD" }, { "fields":[ { "fields":[ { "name":"latitude", "type":"FLOAT" }, { "name":"longitude", "type":"FLOAT" } ], "name":"latLon", "type":"RECORD" } ], "mode":"REPEATED", "name":"locations", "type":"RECORD" } ]כדי לראות את נתוני ההערות שנוצרו על ידי ה-API, מריצים את הפקודות הבאות של
bq queryכדי לראות את כל ציוני הדרך שנמצאו בשש התמונות האלה, לפי סדר הסבירות של הציון:bq query --nouse_legacy_sql "SELECT SPLIT(gcs_uri, '/')[OFFSET(3)] file_name, description, score, locations FROM ${BIGQUERY_DATASET}.landmark_annotation ORDER BY score DESC"הפלט אמור להיראות כך:
+------------------+-------------------+------------+---------------------------------+ | file_name | description | score | locations | +------------------+-------------------+------------+---------------------------------+ | eiffel_tower.jpg | Eiffel Tower | 0.7251996 | ["POINT(2.2944813 48.8583701)"] | | eiffel_tower.jpg | Trocadéro Gardens | 0.69601923 | ["POINT(2.2892823 48.8615963)"] | | eiffel_tower.jpg | Champ De Mars | 0.6800974 | ["POINT(2.2986304 48.8556475)"] | +------------------+-------------------+------------+---------------------------------+
תיאורים מפורטים של כל העמודות שספציפיות להערות מופיעים במאמר בנושא
AnnotateImageResponse.כדי לעצור את צינור הנתונים של הסטרימינג, מריצים את הפקודה הבאה. הצינור ממשיך לפעול גם אם אין יותר התראות Pub/Sub לעיבוד.
gcloud dataflow jobs cancel --region ${REGION} $(gcloud dataflow jobs list --region ${REGION} --filter="NAME:test-vision-analytics AND STATE:Running" --format="get(JOB_ID)")בקטע הבא מופיעות עוד שאילתות לדוגמה שמנתחות תכונות שונות של התמונות.
ניתוח מערך נתונים של Flickr30K
בקטע הזה, תזהו תוויות וציוני דרך במערך הנתונים של תמונות Flickr30k שגלוי לכולם ומאוחסן ב-Kaggle.
ב-Cloud Shell, משנים את הפרמטרים של צינור הנתונים של Dataflow כך שהוא יהיה מותאם למערך נתונים גדול. כדי לאפשר תפוקה גבוהה יותר, צריך גם להגדיל את הערכים של
batchSizeושלkeyRange. Dataflow משנה את מספר העובדים לפי הצורך:./gradlew run --args=" \ --runner=DataflowRunner \ --jobName=vision-analytics-flickr \ --streaming \ --enableStreamingEngine \ --diskSizeGb=30 \ --autoscalingAlgorithm=THROUGHPUT_BASED \ --maxNumWorkers=5 \ --project=${PROJECT} \ --region=${REGION} \ --subscriberId=projects/${PROJECT}/subscriptions/${GCS_NOTIFICATION_SUBSCRIPTION} \ --visionApiProjectId=${PROJECT} \ --features=LABEL_DETECTION,LANDMARK_DETECTION \ --datasetName=${BIGQUERY_DATASET} \ --batchSize=16 \ --keyRange=5"מערך הנתונים גדול, ולכן אי אפשר להשתמש ב-Cloud Shell כדי לאחזר את התמונות מ-Kaggle ולשלוח אותן לקטגוריה של Cloud Storage. כדי לעשות את זה, צריך להשתמש במכונה וירטואלית עם גודל דיסק גדול יותר.
כדי לאחזר תמונות מ-Kaggle ולשלוח אותן לקטגוריית Cloud Storage, פועלים לפי ההוראות שבקטע Simulate the images being uploaded to the storage bucket במאגר GitHub.
כדי לעקוב אחר התקדמות תהליך ההעתקה באמצעות מדדים מותאמים אישית שזמינים בממשק המשתמש של Dataflow, עוברים לדף Dataflow Jobs ובוחרים את צינור עיבוד הנתונים
vision-analytics-flickr. הערכים של מוני הלקוחות צריכים להשתנות מעת לעת עד שצינור הנתונים של Dataflow יעבד את כל הקבצים.הפלט דומה לצילום המסך הבא של החלונית Custom Counters. אחד מהקבצים במערך הנתונים הוא מסוג שגוי, וזה משתקף בדלפק
rejectedFiles. ערכי המונה האלה הם משוערים. יכול להיות שתראו מספרים גבוהים יותר. בנוסף, סביר להניח שמספר ההערות ישתנה בגלל הדיוק הגבוה יותר של העיבוד באמצעות Vision API.
כדי לבדוק אם אתם מתקרבים למגבלות המשאבים הזמינים או חורגים מהן, אפשר לעיין בדף המכסות של Vision API.
בדוגמה שלנו, צינור עיבוד הנתונים של Dataflow השתמש רק בכ-50% מהמכסה שלו. על סמך אחוז הניצול של המכסה, אפשר להגדיל את רמת המקביליות של צינור הנתונים על ידי הגדלת הערך של הפרמטר
keyRange.מכבים את הצינור:
gcloud dataflow jobs list --region $REGION --filter="NAME:vision-analytics-flickr AND STATE:Running" --format="get(JOB_ID)"
ניתוח הערות ב-BigQuery
בפריסה הזו, עיבדתם יותר מ-30,000 תמונות לתווית ולהערות של ציוני דרך. בקטע הזה אפשר לראות נתונים סטטיסטיים לגבי הקבצים האלה. אפשר להריץ את השאילתות האלה בסביבת העבודה של GoogleSQL ל-BigQuery או להשתמש בכלי bq של שורת הפקודה.
חשוב לדעת שהמספרים שאתם רואים יכולים להיות שונים מתוצאות השאילתה לדוגמה בהטמעה הזו. הדיוק של הניתוח ב-Vision API משתפר כל הזמן. הוא יכול להפיק תוצאות עשירות יותר על ידי ניתוח אותה תמונה אחרי שבודקים את הפתרון בפעם הראשונה.
במסוף Google Cloud , עוברים לדף Query editor של BigQuery ומריצים את הפקודה הבאה כדי לראות את 20 התוויות המובילות במערך הנתונים:
SELECT description, count(*)ascount \ FROM vision_analytics.label_annotation GROUP BY description ORDER BY count DESC LIMIT 20הפלט אמור להיראות כך:
+------------------+-------+ | description | count | +------------------+-------+ | Leisure | 7663 | | Plant | 6858 | | Event | 6044 | | Sky | 6016 | | Tree | 5610 | | Fun | 5008 | | Grass | 4279 | | Recreation | 4176 | | Shorts | 3765 | | Happy | 3494 | | Wheel | 3372 | | Tire | 3371 | | Water | 3344 | | Vehicle | 3068 | | People in nature | 2962 | | Gesture | 2909 | | Sports equipment | 2861 | | Building | 2824 | | T-shirt | 2728 | | Wood | 2606 | +------------------+-------+
קביעה אילו תוויות אחרות מופיעות בתמונה עם תווית מסוימת, מדורגות לפי תדירות:
DECLARE label STRING DEFAULT 'Plucked string instruments'; WITH other_labels AS ( SELECT description, COUNT(*) count FROM vision_analytics.label_annotation WHERE gcs_uri IN ( SELECT gcs_uri FROM vision_analytics.label_annotation WHERE description = label ) AND description != label GROUP BY description) SELECT description, count, RANK() OVER (ORDER BY count DESC) rank FROM other_labels ORDER BY rank LIMIT 20;הפלט אמור להיראות כך: לתווית Plucked string instruments שמשמשת בפקודה הקודמת, אמורות להופיע התוצאות הבאות:
+------------------------------+-------+------+ | description | count | rank | +------------------------------+-------+------+ | String instrument | 397 | 1 | | Musical instrument | 236 | 2 | | Musician | 207 | 3 | | Guitar | 168 | 4 | | Guitar accessory | 135 | 5 | | String instrument accessory | 99 | 6 | | Music | 88 | 7 | | Musical instrument accessory | 72 | 8 | | Guitarist | 72 | 8 | | Microphone | 52 | 10 | | Folk instrument | 44 | 11 | | Violin family | 28 | 12 | | Hat | 23 | 13 | | Entertainment | 22 | 14 | | Band plays | 21 | 15 | | Jeans | 17 | 16 | | Plant | 16 | 17 | | Public address system | 16 | 17 | | Artist | 16 | 17 | | Leisure | 14 | 20 | +------------------------------+-------+------+
למטה מופיעים 10 האתרים המפורסמים שזוהו.
SELECT description, COUNT(description) AS count FROM vision_analytics.landmark_annotation GROUP BY description ORDER BY count DESC LIMIT 10הפלט אמור להיראות כך:
+--------------------+-------+ | description | count | +--------------------+-------+ | Times Square | 55 | | Rockefeller Center | 21 | | St. Mark's Square | 16 | | Bryant Park | 13 | | Millennium Park | 13 | | Ponte Vecchio | 13 | | Tuileries Garden | 13 | | Central Park | 12 | | Starbucks | 12 | | National Mall | 11 | +--------------------+-------+
זיהוי התמונות שסביר להניח שמכילות מפלים:
SELECT SPLIT(gcs_uri, '/')[OFFSET(3)] file_name, description, score FROM vision_analytics.landmark_annotation WHERE LOWER(description) LIKE '%fall%' ORDER BY score DESC LIMIT 10הפלט אמור להיראות כך:
+----------------+----------------------------+-----------+ | file_name | description | score | +----------------+----------------------------+-----------+ | 895502702.jpg | Waterfall Carispaccha | 0.6181358 | | 3639105305.jpg | Sahalie Falls Viewpoint | 0.44379658 | | 3672309620.jpg | Gullfoss Falls | 0.41680416 | | 2452686995.jpg | Wahclella Falls | 0.39005348 | | 2452686995.jpg | Wahclella Falls | 0.3792498 | | 3484649669.jpg | Kodiveri Waterfalls | 0.35024035 | | 539801139.jpg | Mallela Thirtham Waterfall | 0.29260656 | | 3639105305.jpg | Sahalie Falls | 0.2807213 | | 3050114829.jpg | Kawasan Falls | 0.27511594 | | 4707103760.jpg | Niagara Falls | 0.18691841 | +----------------+----------------------------+-----------+
תמצא תמונות של ציוני דרך במרחק של עד 3 קילומטרים מהקולוסיאום ברומא (הפונקציה
ST_GEOPOINTמשתמשת בקו האורך ובקו הרוחב של הקולוסיאום):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כשמריצים את השאילתה, רואים שיש כמה תמונות של הקולוסאום, אבל גם תמונות של קשת קונסטנטינוס, גבעת פלטין ומספר מקומות אחרים שמצולמים לעיתים קרובות.
אפשר להציג את הנתונים באופן חזותי ב-BigQuery Geo Viz על ידי הדבקת השאילתה הקודמת. בוחרים נקודה במפה כדי לראות את הפרטים שלה. במאפיין
Image_urlמציינים קישור לקובץ התמונה.
הערה אחת לגבי תוצאות השאילתה. בדרך כלל יש מידע על מיקום של ציוני דרך. אותה תמונה יכולה להכיל כמה מיקומים של אותו ציון דרך.
הפונקציונליות הזו מתוארת בסוג AnnotateImageResponse.
יכולים להיות כמה רכיבים של LocationInfo כי מיקום אחד יכול לציין את המיקום של הסצנה בתמונה. מיקום אחר יכול לציין איפה התמונה צולמה.
הסרת המשאבים
כדי להימנע מחיובים בחשבון Google Cloud על המשאבים שבהם השתמשתם במדריך הזה, אתם יכולים למחוק את הפרויקט שמכיל את המשאבים או להשאיר את הפרויקט ולמחוק את המשאבים הספציפיים.
מחיקת הפרויקט Google Cloud
הדרך הקלה ביותר לבטל את החיוב היא למחוק את Google Cloud הפרויקט שיצרתם בשביל המדריך.
- במסוף Google Cloud , נכנסים לדף Manage resources.
- ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
- כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.
אם מחליטים למחוק משאבים בנפרד, פועלים לפי השלבים שבקטע ניקוי במאגר GitHub.
המאמרים הבאים
- לדוגמאות נוספות של ארכיטקטורות, תרשימים ושיטות מומלצות, עיינו במאמר Cloud Architecture Center.
שותפים ביצירת התוכן
מחברים:
- מסוד חסן (Masud Hasan) | מנהל Site Reliability Engineering
- Sergei Lilichenko | Solutions Architect
- Lakshmanan Sethu | מנהל חשבונות טכני
תורמי תוכן אחרים:
- ג'יון קאנג (Jiyeon Kang) | Customer Engineer
- Sunil Kumar Jang Bahadur | Customer Engineer