1. מבוא
עדכון אחרון:11 באפריל 2022
ב-Codelab הזה, לומדים איך לאמן מודל לסיווג תמונות באמצעות Teachable Machine, ומריצים אותו עם שיפור מהירות באמצעות חומרה של Core באמצעות TensorFlow.js, ספרייה עוצמתית וגמישה ללמידת מכונה בשביל JavaScript. אתם בונים אפליקציית Electron שמציגה תמונות ממצלמת אינטרנט ומסווגת אותן באמצעות טכנולוגיית TPU מסוג Coral Edge. גרסה שפועלת באופן מלא של ה-Codelab הזה זמינה במאגר sig-tfjs GitHub.
נדרש מכשיר Coral?
לא. אפשר לנסות את ה-Codelab הזה בלי מכשיר Coral ועדיין לקבל ביצועים טובים במחשב בעזרת מאיץ WebNN.
מה תפַתחו
ב-Codelab הזה בונים אפליקציית Electron שמסווגת תמונות. האפליקציה שלך:
- סיווג תמונות ממצלמת האינטרנט לקטגוריות שהוגדרו במודל שאימנתם.
- נעשה שימוש במאיץ קורל כדי לשפר את הביצועים, אם יש כזה.
- נעשה שימוש ב-WebNN כדי לשפר את הביצועים, אם הוא נתמך בפלטפורמה שלכם.
מה תלמדו
- איך להתקין ולהגדיר את חבילת NPM tfjs-tflite-node כדי להריץ מודלים של TFLite ב-Node.js.
- איך להתקין את ספריית זמן הריצה של Edge TPU כדי להריץ מודלים במכשיר Coral.
- איך להאיץ את הסקת המסקנות של המודל באמצעות TPU עם קצה קורל.
- איך להאיץ את הסקת המודל באמצעות WebNN.
ה-codelab הזה מתמקד ב-TFLite ב-Node.js. מושגים ובלוקים של קוד שלא רלוונטיים מודגשים ואפשר פשוט להעתיק ולהדביק אותם.
מה צריך להכין
כדי להשלים את הקורס Codelab, צריך:
- מחשב עם מצלמת אינטרנט.
- ב-Coral מומלץ להשתמש ב-Raspberry Pi עם מערכת ההפעלה Raspberry Pi OS (64 ביט) עם מחשב.
- כדי להשתמש ב-WebNN, מומלץ להשתמש במכונת Intel x86-64 עם מערכת הפעלה Ubuntu מגרסה 20.04 או Windows 10.
- גרסת Node.js >= 12.
- ידע ב-JavaScript.
- (מומלץ) מאיץ USB אלמוג להאצת המודל.
2. להגדרה
לקבלת הקוד
הוספנו למאגר של Git את כל הקוד שדרוש לפרויקט הזה. כדי להתחיל, לוקחים את הקוד ופותחים אותו בסביבת הפיתוח המועדפת עליכם. לצורך ה-codelab הזה, מומלץ להשתמש ב-Raspberry Pi עם מערכת ההפעלה Raspberry Pi OS (64 ביט) עם מחשב. כך קל לחבר מאיץ אלמוגים.
מומלץ מאוד: משתמשים ב-Git כדי לשכפל את המאגר ב-Raspberry Pi
כדי לקבל את הקוד, פותחים חלון טרמינל חדש ומשכפלים את המאגר:
git clone https://github.com/tensorflow/sig-tfjs.git
כל הקבצים שצריך לערוך ב-Codelab נמצאים בספרייה tfjs-tflite-node-codelab
(בתוך sig-tfjs
). בספרייה הזו מופיעות ספריות משנה בשם starter_code
, cpu_inference_working
, coral_inference_working
ו-webnn_inference_working
. אלו נקודות ביקורת לשלבים ב-Codelab הזה.
בין הקבצים האחרים במאגר נמצאות חבילות ה-NPM ש-tfjs-tflite-node-codelab
תלויה בהן. לא תצטרכו לערוך אף אחד מהקבצים האלה, אבל תצטרכו להריץ כמה מהבדיקות שלהם כדי לוודא שהסביבה שלכם מוגדרת כראוי.
התקנת ספריית זמן הריצה של Edge TPU
במכשירי Coral צריך להתקין את ספריית זמן הריצה של Edge TPU לפני השימוש. כדי להתקין אותו, צריך לפעול לפי ההוראות שרלוונטיות לפלטפורמה שלכם.
ב-Linux או ב-Raspberry Pi
ב-Linux, הספרייה זמינה ב-PPA של Google כחבילת Debian, libedgetpu1-std, לארכיטקטורות x86-64 ו- Armv8 (64 ביט). אם המעבד משתמש בארכיטקטורה אחרת, תצטרכו להדר אותה מהמקור.
מריצים את הפקודה הזו כדי להוסיף את Coral PPA של Google ולהתקין את ספריית Edge TPU Runtime.
# None of this is needed on Coral boards
# This repo is needed for almost all packages below
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | sudo tee /etc/apt/sources.list.d/coral-edgetpu.list
# This repo is needed for only python3-coral-cloudiot and python3-coral-enviro
echo "deb https://packages.cloud.google.com/apt coral-cloud-stable main" | sudo tee /etc/apt/sources.list.d/coral-cloud.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo apt-get update
sudo apt-get install libedgetpu1-std
ב-Windows או במערכות הפעלה אחרות
קבצים בינאריים שעברו הידור מראש זמינים בגרסאות x86-64 של MacOS ו-Windows, וניתן להתקין אותם על ידי הרצת הסקריפט install.sh או install.bat בארכיון לאחר ההורדה.
הפעלה מחדש של המכשיר
אחרי שמתקינים את זמן הריצה של Edge TPU, מפעילים מחדש את המכשיר כדי להפעיל את הכלל החדש Coral Udev שהמתקין הוסיף.
איך מוודאים שמכשיר Coral זוהה
כדי לוודא שמכשיר Coral שלך זוהה ופועל, צריך להריץ את בדיקות השילוב של חבילת coral-tflite-delegate
. החבילה הזו נמצאת בספרייה הבסיסית (root) של המאגר. כדי להריץ את בדיקות השילוב, מחברים את מאיץ Coral ומריצים את הפקודות הבאות בספריית החבילה:
npx yarn
npx yarn build-deps
npx yarn test-integration
הפלט אמור להיראות כך:
yarn run v1.22.17
$ yarn build && yarn test-integration-dev
$ tsc
$ jasmine --config=jasmine-integration.json
Platform node has already been set. Overwriting the platform with node.
Randomized with seed 78904
Started
============================
Hi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.
============================
WARNING: converting 'int32' to 'uint8'
.
1 spec, 0 failures
Finished in 2.777 seconds
Randomized with seed 78904 (jasmine --random=true --seed=78904)
Done in 6.36s.
אין צורך בהתקנה של @tensorflow/tfjs-node,
כפי שצוין ביומנים, כי המודל ירוץ דרך TFLite.
אם הפלט מכיל Encountered unresolved custom op: edgetpu-custom-op
, סימן שמכשיר Coral שלך לא זוהה. עליכם לוודא שהתקנתם את ספריית סביבת זמן הריצה של TPU בקצה וחיברתם את מכשיר Coral למחשב. ניתן גם לפעול לפי המדריך לתחילת העבודה של Coral כדי לבדוק את גרסת Python של קישורי Coral. אם גרסת Python עובדת אבל הבדיקות האלה עדיין נכשלות, אפשר לשלוח דוח על באג כדי להודיע לנו על כך.
מריצים את הקוד לתחילת הפעולה
עכשיו הכול מוכן להרצת הקוד לתחילת הפעולה. כדי להתחיל, צריך לפעול לפי השלבים הבאים:
- עוברים לספרייה
starter_code
בספרייהtfjs-tflite-node-codelab
. - מריצים את הפקודה
npm install
כדי להתקין את יחסי התלות. - מריצים את הפקודה
npm start
כדי להפעיל את הפרויקט. אמורה להיפתח אפליקציה שמציגה פיד וידאו ממצלמת האינטרנט של המחשב.
מהי נקודת ההתחלה שלנו?
נקודת ההתחלה שלנו היא אפליקציית מצלמה בסיסית של Electron שמיועדת ל-Codelab הזה. המערכת יצרה את הקוד בצורה פשוטה יותר כדי להציג את המושגים ב-Codelab, והטיפול בשגיאות בו קטן מאוד. אם תבחרו להשתמש שוב בקוד כלשהו באפליקציה בסביבת הייצור, חשוב לטפל בשגיאות ולבדוק את כל הקוד באופן מלא.
בדיקת הקוד לתחילת הפעולה
יש הרבה קבצים בקוד הזה לתחילת פעולה, אבל צריך לערוך רק את הקובץ renderer.js
. המדיניות קובעת מה מוצג בדף, כולל פיד הווידאו ורכיבי ה-HTML, וזהו המקום שבו מוסיפים את המודל של למידת המכונה לאפליקציה. בין הקבצים האחרים יש קובץ index.html
, אבל הוא רק טוען את הקובץ renderer.js
. יש גם קובץ main.js
, שהוא נקודת הכניסה של Electron. המדיניות הזו קובעת את מחזור החיים של האפליקציה, כולל מה להציג כשהיא פתוחה ומה לעשות כשהיא סגורה, אבל לא תצטרכו לבצע בה שינויים.
פתיחת הכלי לניפוי באגים
ייתכן שתצטרכו לנפות באגים באפליקציה במהלך המעקב אחר ה-Codelab הזה. האפליקציה הזו מבוססת על Electron, ולכן הכלי לניפוי באגים ב-Chrome מובנה. ברוב הפלטפורמות אפשר לפתוח אותו באמצעות Ctrl + Shift + I. לוחצים על הכרטיסייה מסוף כדי לראות את היומנים ואת הודעות השגיאה מהאפליקציה.
אין כאן כל כך הרבה מידע, אז שנתחיל באימון של מסַווג התמונות!
3. אימון של מסווג תמונות
בקטע הזה, מאמנים גרסאות של TFLite ושל Coral של מודל לסיווג תמונות בהתאמה אישית.
אימון המסווג
מסווג תמונות משתמש בתמונות קלט ומקצה להן תוויות. ב-Codelab הזה, משתמשים ב-Teachable Machine כדי לאמן מודל בדפדפן. כדי לזרז את האימון בחלק הזה, תוכלו להשתמש במחשב שולחני או במחשב נייד במקום ב-Raspberry Pi, אבל תצטרכו להעתיק את הקבצים שיתקבלו ל-Pi.
עכשיו אתם מוכנים לאמן מודל. אם אתם לא בטוחים איזה סוג של מודל לאמן, מודל שקל לאמן הוא גלאי אדם, שמזהה רק אם אדם נמצא בפריים.
- פותחים את דף Teachable Machine training בכרטיסייה חדשה.
- בוחרים באפשרות Image Project (פרויקט תמונות) ואז באפשרות Standard image model (מודל תמונה רגיל).
- להוסיף דוגמאות של תמונות לכל כיתה. הדרך הקלה ביותר לעשות זאת היא שימוש בקלט מצלמת האינטרנט. אפשר גם לשנות את שמות הכיתות.
- אחרי שאוספים מספיק נתונים לכל כיתה (בדרך כלל מספיק 50 דגימות), לוחצים על מודל אימון.
כשהמודל מסיים את האימון, אמורה להופיע תצוגה מקדימה של הפלט של המודל.
אפשר לנסות להזין למודל מקורות קלט שונים. אם אתם מוצאים קלט שסווג באופן שגוי, אפשר להוסיף אותו לנתוני האימון ולאמן מחדש את המודל.
- כשמרוצים מהדיוק של המודל, לוחצים על ייצוא המודל. תצטרכו להוריד שתי גרסאות נפרדות של המודל.
- לייצא את המודל כמודל נקודה צפה (Floating) של Tensorflow Lite. תתבצע הורדה של קובץ בשם
converted_tflite.zip
. שרץ על המעבד (CPU). - מייצאים את המודל כמודל Tensorflow Lite EdgeTPU. הפעולה הזו מורידה קובץ בשם
converted_edgetpu.zip
שפועל ב-Coral Edge TPU.
4. הרצת מודל המעבד (CPU) באפליקציה
עכשיו, אחרי שאימון מודל, הגיע הזמן להוסיף אותו לאפליקציה. בסוף הקטע הזה, האפליקציה תוכל להריץ את המודל באמצעות המעבד של המכשיר.
הוספה של קובץ המודל לאפליקציה
מחלצים את קובץ המודל converted_tflite.zip שהורדתם כשאימנתם את המסווג. בארכיון יש שני קבצים. model_uquant.tflite
הוא מודל ה-TFLite השמור, כולל תרשים המודל והמשקלים. labels.txt
מכיל תוויות קריאות לאנשים למחלקות שהמודל חוזים. מציבים את שני הקבצים בmodeldirectory.
תלות בין התקנות
כדי לטעון מודל ומקורות קלט לעיבוד מראש, נדרשים כמה יחסי תלות מ-TensorFlow.js:
tfjs-tflite-node
: החבילה של TensorFlow.js להרצת מודלים של TFLite ב-Node.js.@tensorflow/tfjs
: החבילה הראשית של TensorFlow.js.
@tensorflow/tfjs כבר מותקן, אבל צריך להתקין את tfjs-tflite-node באמצעות הפקודה הבאה:
npm install --save tfjs-tflite-node
לאחר ההתקנה, מוסיפים אותו לאפליקציה בחלק העליון של renderer.js:
CODELAB חלק 1: ייבוא של tfjs-tflite-node.
const {loadTFLiteModel} = require('tfjs-tflite-node');
טעינת המודל
עכשיו אתה מוכן לטעון את המודל. לשם כך, tfjs-tflite-node
מספקת את הפונקציה loadTFLiteModel
. היא יכולה לטעון מודלים מנתיב קובץ, מ-ArrayBuffer או מכתובת URL של TFHub. כדי לטעון את המודל ואת המשקולות שלו, צריך להוסיף את קטע הקוד הבא לפונקציה main
:
CODELAB חלק 1: טוענים את המודל כאן.
const modelPath = './model/model_unquant.tflite';
const model = await loadTFLiteModel(modelPath);
const labels = fs.readFileSync('./model/labels.txt', 'utf8')
.split('\n');
הפעלת המודל
הפעלת המודל שלך כוללת שלושה שלבים. קודם כול, שולפים פריים ומעבדים אותו מראש ממצלמת האינטרנט. לאחר מכן, מריצים את המודל על המסגרת הזו ומקבלים חיזוי. לאחר מכן, החיזוי יוצג בדף.
עיבוד מראש של הקלט של מצלמת האינטרנט
בשלב זה, מצלמת האינטרנט היא רק רכיב HTML, והמסגרות שהיא מציגה לא זמינות לקובץ JavaScript שעובדו. כדי למשוך פריימים ממצלמת האינטרנט, TensorFlow.js מספק tf.data.webcam, שיטה capture()
קלה לשימוש לצילום פריימים מהמצלמה.
כדי להשתמש בו, צריך להוסיף את קוד ההגדרה הבא אל main()
:
CODELAB חלק 1: הגדרת tf.data.webcam כאן.
const tensorCam = await tf.data.webcam(webcam);
לאחר מכן, כדי לצלם תמונה בכל פריים, צריך להוסיף את הקוד הבא אל run()
:
CODELAB חלק 1: כאן אפשר לצלם פריימים של מצלמת אינטרנט.
const image = await tensorCam.capture();
בנוסף, צריך לבצע עיבוד מראש של כל פריים כדי שהוא יתאים למודל. למודל שבו נעשה שימוש ב-Codelab יש צורת קלט [1, 224, 224, 3], לכן היא צפויה לקבל תמונת RGB של 224 על 224 פיקסלים. tensorCam.capture()
יוצרת צורה של [224, 224, 3], כך שצריך להוסיף מימד נוסף בחלק הקדמי של החיישן באמצעות tf.expandDims. בנוסף, המודל של המעבד (CPU) מצפה לקלט Float32 בין -1 ל-1, אבל מצלמת האינטרנט מתעדת ערכים בין 0 ל-255. אפשר לחלק את טנזור הקלט ב-127 כדי לשנות את הטווח שלו מ-[0, 255] ל-[0, ~2] ואז להחסיר 1 כדי לקבל את הטווח הרצוי [ -1, ~1]. כדי לעשות זאת, מוסיפים את השורות הבאות אל tf.tidy()
בפונקציה run()
:
CODELAB חלק 1: עיבוד מראש של מסגרות מצלמת אינטרנט כאן.
const expanded = tf.expandDims(image, 0);
const divided = tf.div(expanded, tf.scalar(127));
const normalized = tf.sub(divided, tf.scalar(1));
חשוב להשליך את רכיבי הטנזור לאחר השימוש בהם. tf.tidy()
עושה זאת באופן אוטומטי עבור הקוד שנכלל בקריאה חוזרת (callback) שלו, אבל הוא לא תומך בפונקציות אסינכרוניות. עליך להסיר באופן ידני את רכיב ה-image_tensor שיצרת קודם באמצעות קריאה ל-method dispose()
.
CODELAB חלק 1: כאן אפשר להשמיט את הפריימים של מצלמת האינטרנט.
image.dispose();
הפעלת המודל והצגת התוצאות
כדי להריץ את המודל בקלט שעבר עיבוד מראש, מפעילים את הפונקציה model.predict()
במשתנה המנורמל. הפונקציה מחזירה t e n s o r f l o w שמכיל את ההסתברות החזויה של כל תווית. כדאי להכפיל את ההסתברות הזו ב-100 כדי לקבל את אחוז ההסתברות לכל תווית, ולהשתמש בפונקציה showPrediction
שכלולה בקוד הסימן לתחילת הפעולה כדי להציג במסך את החיזוי של המודל.
הקוד הזה גם משתמש ב-stats.js כדי לחשב את משך הזמן שנדרש לחיזוי על ידי ביצוע קריאות אל stats.begin
ו-stats.end
בסביבות model.predict
.
CODELAB חלק 1: מריצים את המודל ומציגים את התוצאות כאן.
stats.begin();
const prediction = model.predict(normalized);
stats.end();
const percentage = tf.mul(prediction, tf.scalar(100));
showPrediction(percentage.dataSync(), labels);
צריך להריץ שוב את האפליקציה באמצעות yarn start
. לאחר מכן אמורים להופיע סיווגים מהמודל.
ביצועים
המודל מוגדר כרגע במעבד (CPU). האפשרות הזו מתאימה למחשבים נייחים ולרוב המחשבים הניידים, אבל יכול להיות שזה לא רצוי אם אתם מריצים אותו ב-Raspberry Pi או במכשיר אחר בעל מתח נמוך. ב-Raspberry Pi 4, סביר להניח שתראו 10 FPS, דבר שעלול להיות לא מהיר מספיק באפליקציות מסוימות. כדי לקבל ביצועים טובים יותר בלי להשתמש במכונה מהירה יותר, אפשר להשתמש בסיליקון ספציפי לאפליקציה בצורת TPU של Coral Edge.
5. הפעלת מודל Coral באפליקציה
אם אין לך מכשיר Coral, אפשר לדלג על הקטע הזה.
השלב הזה ב-Codelab מבוסס על הקוד שכתבת בקטע האחרון, אבל אפשר להשתמש במקום זאת בנקודת הביקורת cpu_inference_working אם רוצים להתחיל מדף נקי.
השלבים להפעלת המודל קורל כמעט זהים לשלבים להפעלת מודל המעבד (CPU). ההבדל העיקרי הוא בפורמט של המודל. מכיוון שקורל תומך רק בקפיצים של uint8, המודל נכלל בכמות. ההגדרה הזו משפיעה על רכיבי הקלט (tensors) שמועברים למודל ועל הפרמטרים של הפלט שהוא מחזיר. הבדל נוסף הוא שצריך לבצע הידור של המודלים באמצעות המהדר של Edge TPU כדי לרוץ ב-Coral TPU. ב-TeachableMachine כבר בוצעו השלב הזה, אבל אפשר לקרוא איך לעשות זאת במודלים אחרים במסמכי התיעוד של Coral.
הוספה של קובץ מודל Coral לאפליקציה
מחלצים את קובץ המודל converted_edgetpu.zip שהורדתם כשאימנתם את המסווג. הארכיון כולל שני קבצים. model_edgetpu.tflite
הוא מודל ה-TFLite השמור, כולל תרשים המודל והמשקלים. labels.txt
מכיל תוויות קריאות לאנשים למחלקות שהמודל חוזים. מציבים את קובץ המודל בספרייה coral_model.
תלות בין התקנות
כדי להפעיל מודלים של Coral נדרשת ספריית זמן ריצה של Edge TPU. לפני שממשיכים, צריך לפעול לפי הוראות ההגדרה כדי לוודא שהתקנתם אותם.
הגישה למכשירי Coral מתבצעת כמקבלי הרשאה של TFLite. כדי לגשת אליהם מ-JavaScript, מתקינים את החבילה coral-tflite-lege:
npm install --save coral-tflite-delegate
לאחר מכן, מייבאים את בעל הגישה על ידי הוספת השורה הבאה לחלק העליון של הקובץ renderer.js:
CODELAB חלק 2: ייבוא של בעל הגישה לכאן.
const {CoralDelegate} = require('coral-tflite-delegate');
טעינת המודל
עכשיו אתה מוכן לטעון את מודל Coral. עושים זאת באותו אופן כמו במודל המעבד (CPU), אבל עכשיו צריך להעביר אפשרויות לפונקציה loadTFLiteModel
כדי לטעון את בעל הגישה של Coral.
CODELAB חלק 2: כאן טוענים את המודל להענקת גישה.
const coralModelPath = './coral_model/model_edgetpu.tflite';
const options = {delegates: [new CoralDelegate()]};
const coralModel = await loadTFLiteModel(coralModelPath, options);
אין צורך לטעון את התוויות כי הן זהות לדגם של המעבד (CPU).
הוספת לחצן למעבר בין המעבד (CPU) ל-Coral
מוסיפים את המודל Coral לצד המודל של המעבד (CPU) שהוספתם בקטע הקודם. אם מפעילים את שני הסוגים בו-זמנית, קשה לראות את ההבדלים בביצועים. לכן יש מתג למעבר בין הביצוע של Coral לבין הביצוע של המעבד (CPU).
מוסיפים את הלחצן עם הקוד הבא:
CODELAB חלק 2: יוצרים כאן את הלחצן להענקת גישה.
let useCoralDelegate = false;
const toggleCoralButton = document.createElement('button');
function toggleCoral() {
useCoralDelegate = !useCoralDelegate;
toggleCoralButton.innerText = useCoralDelegate
? 'Using Coral. Press to switch to CPU.'
: 'Using CPU. Press to switch to Coral.';
}
toggleCoralButton.addEventListener('click', toggleCoral);
toggleCoral();
document.body.appendChild(toggleCoralButton);
עכשיו נחבר את התנאי הזה לפונקציה run()
. אם הערך של useCoralDelegate
הוא False, צריך להריץ את גרסת המעבד (CPU). אחרת, הוא יריץ את גרסת קורל (אבל בינתיים הוא פשוט לא יבצע כלום). גורפים את הקוד מהרצת מודל המעבד (CPU) בהצהרת if. שימו לב שהארגומנט expanded
לא נכלל במשפט if כי מודל האלמוגים משתמש בו.
CODELAB חלק 2: בודקים אם להשתמש כאן במשתמש עם הרשאה.
// NOTE: Don't just copy-paste this code into the app.
// You'll need to edit the code from the CPU section.
const expanded = tf.expandDims(image, 0);
if (useCoralDelegate) {
// CODELAB part 2: Run Coral prediction here.
} else {
const divided = tf.div(expanded, tf.scalar(127));
const normalized = tf.sub(divided, tf.scalar(1));
stats.begin();
const prediction = model.predict(normalized);
stats.end();
const percentage = tf.mul(prediction, tf.scalar(100));
showPrediction(percentage.dataSync(), labels);
}
הפעלת המודל
גרסת האלמוגים של המודל מצפה ל-uint8 tensors מ-0 עד 255, כך שאין צורך לנרמל את הקלט שלה. עם זאת, הפלט הוא גם טינזור מסוג uint8 בטווח שבין 0 ל-255. יש להמיר אותו למספר צף מ-0 ל-100 לפני שהוא מוצג.
CODELAB חלק 2: הפעל חיזוי של Coral כאן. (זהו חלק מקטע הקוד שלמעלה)
stats.begin();
const prediction = coralModel.predict(expanded);
stats.end();
const percentage = tf.div(tf.mul(prediction, tf.scalar(100)), tf.scalar(255));
showPrediction(percentage.dataSync(), labels);
מפעילים שוב את האפליקציה באמצעות yarn start
, והיא אמורה להציג סיווגים ממאיץ אלמוגים.
לוחצים על הלחצן כדי לעבור בין ההיקש בין המעבד (CPU) לקורל. יכול להיות שתבחינו שדירוגי הסמך של המודל 'קורל' פחות מדויקים מאלה של המודל של המעבד (CPU), ובדרך כלל הם מסתיימים במקום עשרוני שווה יותר. אובדן הדיוק הזה מתפשר על הפעלת מודל כמותי על קורל. בדרך כלל אין חשיבות לעבודה, אבל חשוב לזכור את זה.
הערה לגבי הביצועים
קצב הפריימים שאתם רואים כולל עיבוד מראש ועיבוד לאחר מכן, כך שהוא לא מייצג את מה שחומרת Coral מסוגלת. כדי לקבל מושג טוב יותר לגבי הביצועים, אפשר ללחוץ על מד ה-FPS עד שיופיע זמן האחזור (באלפיות השנייה), שמודד רק את הקריאה ל-model.predict
. עם זאת, זה עדיין כולל את הזמן שלוקח להעביר את Tensor לקישורי ה-C המקוריים של TFLite ולאחר מכן למכשיר Coral, כך שזו לא מדידה מושלמת. ניתן למצוא נקודות השוואה מדויקות יותר לביצועים ב-C++ בדף ההשוואה לשוק של EdgeTPU.
כמו כן, חשוב לציין שהסרטון צולם במחשב נייד ולא ב-Raspberry Pi, ולכן ייתכן שקצב הפריימים לשנייה יהיה שונה.
האצה של עיבוד מראש של Coral
במקרים מסוימים, אפשר להאיץ את העיבוד מראש על ידי החלפת קצוות עורפיים של TFJS. הקצה העורפי שמוגדר כברירת מחדל הוא WebGL, והוא מתאים לפעולות גדולות שניתן לבצע במקביל, אבל האפליקציה הזו לא עושה חלק גדול מזה בשלב העיבוד מראש (האפשרות היחידה שהיא משתמשת בה היא expandDims
, שאינה מקבילה). אפשר לעבור לקצה העורפי של המעבד (CPU) כדי להימנע מזמן האחזור הנוסף של העברת מעבדי GPU אל ה-GPU וממנו, על ידי הוספת השורה הזו אחרי הייבוא בחלק העליון של הקובץ.
tf.setBackend(‘cpu');
יש לכך גם השפעה על העיבוד מראש של מודל מעבד (CPU) מסוג TFLite, שמקביל לאותו, כך שהמודל פועל לאט יותר עם השינוי הזה.
6. האצת מודל המעבד (CPU) באמצעות WebNN
אם אין לכם מאיץ קורל, או אם אתם רק רוצים לנסות דרך אחרת להאצת המודל, אפשר להשתמש בבעל הגישה ל-WebNN TFLite. נציג זה מורשה להשתמש בחומרה של למידת מכונה שמובנית במעבדי Intel כדי להאיץ את הסקת המסקנות בעזרת ערכת הכלים OpenVINO. כתוצאה מכך, יש לו דרישות נוספות שלא נכללו בקטע ההגדרה של Codelab זה, ותצטרכו להתקין את ערכת הכלים OpenVINO. לפני שממשיכים, חשוב לבדוק את ההגדרות מול פלטפורמות היעד של מערכת היעד, אבל חשוב לדעת שבעל הגישה ל-WebNN עדיין לא תומך ב-macOS.
התקנת ערכת הכלים OpenVINO
כדי להאיץ מודלים, ערכת הכלים OpenVINO מתבססת על חומרת למידת מכונה שמובנית במעבדי Intel. אפשר להוריד גרסה שעברה הידור מראש מ-Intel או ליצור אותה מקוד המקור. קיימות מספר דרכים להתקין את OpenVINO, אך לצורך ה-Codelab הזה מומלץ להשתמש בסקריפט של מנהל ההתקנה עבור Windows או Linux. חשוב להתקין את הגרסה של סביבת זמן הריצה של LTS בגרסה 2021.4.2, כי יכול להיות שגרסאות אחרות לא תואמות. אחרי שמפעילים את מנהל ההתקנה, חשוב להגדיר את משתני הסביבה של המעטפת כפי שמתואר בהוראות ההתקנה של Linux או Windows ( הפתרון הקבוע), או באמצעות הרצת הפקודה setupvars.sh
(Linux) או setupvars.bat
(Windows) ששמורה בספרייה webnn-tflite-delegate
.
איך מוודאים שבעל הגישה ל-WebNN פועל
כדי לוודא שהענקת הגישה ל-WebNN פועלת באופן תקין, מריצים את בדיקות השילוב של חבילת webnn-tflite-delegate
שנמצאת בספריית השורש של המאגר. כדי להריץ את בדיקות השילוב, מריצים את הפקודות הבאות בספריית החבילה:
# In webnn-tflite-delegate/
npx yarn
npx yarn test-integration
הפלט אמור להיראות כך:
WebNN delegate: WebNN device set to 0.
INFO: Created TensorFlow Lite WebNN delegate for device Default and power Default.
============================
Hi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.
============================
label: wine bottle
score: 0.934505045413971
.
1 spec, 0 failures
Finished in 0.446 seconds
Randomized with seed 58441 (jasmine --random=true --seed=58441)
Done in 8.07s.
אם מופיע פלט כזה, סימן שיש שגיאת הגדרה:
Platform node has already been set. Overwriting the platform with node.
Randomized with seed 05938
Started
error Command failed with exit code 3221225477.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
המשמעות של הפלט הזה היא ככל הנראה שלא הגדרתם את משתני הסביבה של OpenVINO. נכון לעכשיו, אפשר להגדיר אותם על ידי הרצת הפקודה setupvars.sh
(Linux) או setupvars.bat
(Windows), אבל יכול להיות שתרצו להגדיר אותם באופן קבוע לפי ההוראות של Linux או Windows ( פתרון קבוע). אם משתמשים ב-Windows, אפשר
setupvars.bat
הפקודה לא תומכת ב-Git bash, לכן ודאו שאתם מריצים אותו ופקודות אחרות מה-Codelab הזה משורת הפקודה של Windows.
איך מתקינים את הקצאת ההרשאות של WebNN
כש-OpenVINO מותקן, עכשיו אפשר להאיץ את מודל המעבד (CPU) באמצעות WebNN. הקטע הזה ב-Codelab מסתמך על הקוד שכתבת בקטע 'Run the CPU Model in Your App' . תוכלו להשתמש בקוד שכתבתם בשלב הזה, אבל אם כבר השלמתם את הקטע Coral, השתמשו בנקודת הביקורת cpu_inference_working כדי להתחיל מאפס.
החלק של Node.js של מקבל הגישה ל-WebNN מופץ ב-npmjs. כדי להתקין אותו, מריצים את הפקודה הבאה:
npm install --save webnn-tflite-delegate
לאחר מכן, מייבאים את בעל הגישה על ידי הוספת השורה הבאה לחלק העליון של הקובץ renderer.js:
CODELAB חלק 2: ייבוא של בעל הגישה לכאן.
const {WebNNDelegate, WebNNDevice} = require('webnn-tflite-delegate');
מקבל הגישה ל-WebNN תומך בהרצה במעבד (CPU) או ב-GPU; ב-WebNNDevice אפשר לבחור באיזה פורמט להשתמש.
טעינת המודל
עכשיו אתם מוכנים לטעון את המודל כשהענקת גישה ל-WebNN מופעלת. עבור Coral, הייתם צריכים לטעון קובץ מודל אחר, אבל WebNN תומך באותו פורמט מודל כמו TFLite. מוסיפים את WebNNDelegate לרשימת המשתמשים שקיבלו הרשאה להעברה למודל כדי להפעיל אותו:
CODELAB חלק 2: כאן טוענים את המודל להענקת גישה.
let webnnModel = await loadTFLiteModel(modelPath, {
delegates: [new WebNNDelegate({webnnDevice: WebNNDevice.DEFAULT})],
});
אין צורך לטעון את התוויות שוב כי זה אותו המודל.
הוספת לחצן למעבר בין מעבד TfLite ל-WebNN
עכשיו, כשגרסת ה-WebNN של המודל מוכנה, צריך להוסיף לחצן כדי לעבור בין ההֶקֵּשׁ ממעבדי WebNN ו-TfLite. הפעלת שני הפורמטים בו-זמנית מקשה על זיהוי ההבדלים בביצועים.
מוסיפים את הלחצן עם הקוד הזה (שימו לב שהוא עדיין לא יחליף מודל בפועל):
CODELAB חלק 2: יוצרים כאן את הלחצן להענקת גישה.
let useWebNNDelegate = false;
const divElem = document.createElement('div');
const toggleWebNNButton = document.createElement('button');
function toggleWebNN() {
useWebNNDelegate = !useWebNNDelegate;
toggleWebNNButton.innerHTML = useWebNNDelegate
? 'Using WebNN. Press to switch to TFLite CPU.'
: 'Using TFLite CPU. Press to switch to WebNN.';
divElem.hidden = useWebNNDelegate ? false : true;
}
toggleWebNNButton.addEventListener('click', toggleWebNN);
toggleWebNN();
document.body.appendChild(toggleWebNNButton);
document.body.appendChild(divElem);
הקוד הזה גם מוסיף רכיב div
שבו משתמשים כדי לקבוע הגדרות WebNN בקטע הבא.
הוספת תפריט נפתח כדי לעבור בין מכשירי WebNN
ב-WebNN יש תמיכה בהרצה על ידי מעבד (CPU) ו-GPU, לכן כדאי להוסיף תפריט נפתח כדי לעבור ביניהם. מוסיפים את הקוד הבא אחרי הקוד שיוצר את הלחצן:
// Create elements for WebNN device selection
divElem.innerHTML = '<br/>WebNN Device: ';
const selectElem = document.createElement('select');
divElem.appendChild(selectElem);
const webnnDevices = ['Default', 'GPU', 'CPU'];
// append the options
for (let i = 0; i < webnnDevices.length; i++) {
var optionElem = document.createElement('option');
optionElem.value = i;
optionElem.text = webnnDevices[i];
selectElem.appendChild(optionElem);
}
עכשיו, אם אתם מריצים את האפליקציה, יופיע תפריט נפתח עם הרשימה 'ברירת מחדל', 'GPU' ו'מעבד'. אם תבחרו באחד מהם, לא תהיה אפשרות לעשות כלום כרגע, כי התפריט הנפתח עדיין לא הוצג.
משנים את המכשיר בתפריט הנפתח
כדי לחבר את התפריט הנפתח כך שיתאים למכשיר ה-WebNN שבו משתמשים, מוסיפים האזנה לאירוע change של רכיב הבורר בתפריט הנפתח. כשהערך שנבחר ישתנה, צריך ליצור מחדש את מודל ה-WebNN עם מכשיר ה-WebNN התואם שנבחר באפשרויות של הענקת הגישה.
מוסיפים את הקוד הבא אחרי הקוד שהוסיף את התפריט הנפתח:
selectElem.addEventListener('change', async () => {
let webnnDevice;
switch(selectElem.value) {
case '1':
webnnDevice = WebNNDevice.GPU;
break;
case '2':
webnnDevice = WebNNDevice.CPU;
break;
default:
webnnDevice = WebNNDevice.DEFAULT;
break;
}
webnnModel = await loadTFLiteModel(modelPath, {
delegates: [new WebNNDelegate({webnnDevice})],
});
});
בעקבות השינוי הזה, התפריט הנפתח יוצר מודל חדש עם ההגדרות הנכונות בכל פעם שהוא משתנה. עכשיו הגיע הזמן לחבר את המודל WebNN ולהשתמש בו לצורך הסקת מסקנות.
הפעלת מודל WebNN
המודל WebNN מוכן לשימוש, אבל הלחצן למעבר בין WebNN ל-TfLite CPU עדיין לא מחליף את המודל. כדי להחליף את המודל, קודם צריך לשנות את השם של המשתנה model
מהמועד שבו טענתם את מודל המעבד של TfLite בקטע הראשון של ה-Codelab.
שינוי השורה הבאה...
const model = await loadTFLiteModel(modelPath);
...כך שהיא תואמת לשורה הזו.
const cpuModel = await loadTFLiteModel(modelPath);
כאשר השם של המשתנה model
הוא cpuModel
, צריך להוסיף אותו לפונקציה run
כדי לבחור את המודל הנכון בהתאם למצב הלחצן:
CODELAB חלק 2: בודקים אם להשתמש בבעל הגישה כאן.
let model;
if (useWebNNDelegate) {
model = webnnModel;
} else {
model = cpuModel;
}
עכשיו, כשמריצים את האפליקציה, הלחצן עובר בין מעבד TfLite ל-WebNN.
אם יש לכם גם יחידת GPU משולבת של Intel, אתם יכולים גם לעבור בין מעבדי WebNN לבין הסקת ה-GPU.
הערה לגבי הביצועים
קצב הפריימים שאתם רואים כולל עיבוד מראש ועיבוד לאחר מכן, כך שהוא לא מייצג את מה ש-WebNN יכול לבצע. כדי לקבל מושג טוב יותר לגבי הביצועים, אפשר ללחוץ על מד ה-FPS עד שיופיע זמן האחזור (באלפיות השנייה), שמודד רק את הקריאה ל-model.predict
. עם זאת, זה עדיין כולל את הזמן שנדרש כדי להעביר את Tensor לקישורי ה-C המקוריים של TFLite, כך שזו לא מדידה מושלמת.
7. מזל טוב
מעולה! סיימתם עכשיו את הפרויקט הראשון שלכם ב-Coral / WebNN באמצעות tfjs-tflite-node ב-Electr.
אפשר לנסות את הכלי ולבדוק אותו על מגוון תמונות. אתם יכולים גם לאמן מודל חדש ב-TeachableMachine כדי לסווג משהו אחר לגמרי.
סיכום
ב-Codelab הזה למדת:
- איך להתקין ולהגדיר את חבילת ה-npm tfjs-tflite-node כדי להריץ מודלים של TFLite ב-Node.js.
- איך להתקין את ספריית זמן הריצה של Edge TPU כדי להריץ מודלים במכשיר Coral.
- איך להאיץ את הסקת המסקנות של המודל באמצעות TPU עם קצה קורל.
- איך להאיץ את הסקת המודל באמצעות WebNN.
מה השלב הבא?
עכשיו, אחרי שיש לכם בסיס עבודה שאפשר להתחיל ממנו, אילו רעיונות יצירתיים תוכלו לחשוב עליהם כדי להרחיב את דוח המודל של למידת המכונה לתרחיש לדוגמה שאתם עובדים עליו בעולם האמיתי? אולי תוכלו לחולל מהפכה בתחום שבו אתם עובדים בעזרת מסקנות מהירות במחירים נוחים, או אולי לשנות טוסטר כדי שלא יפסיק לרקוד כשהלחם נראה כמו שצריך. האפשרויות הן אינסופיות.
כדי לקבל מידע נוסף על האופן שבו TeachableMachine אימן את המודל שהשתמשתם בו, אתם יכולים להיכנס ל-codelab בנושא העברת למידה. אם אתם מחפשים מודלים אחרים שפועלים עם קורל, כמו זיהוי דיבור והערכת תנוחה, כדאי לעיין בכתובת coral.ai/models. אפשר גם למצוא גרסאות מעבד (CPU) של הדגמים האלה והרבה גרסאות אחרות ב-TensorFlow Hub.
משתפים את היצירות שלכם איתנו
אתם יכולים להרחיב בקלות את מה שיצרתם היום גם לתרחישים יצירתיים אחרים, ואנחנו ממליצים לכם לחשוב מחוץ למסגרת ולהמשיך להאקינג.
אל תשכחו לתייג אותנו ברשתות החברתיות באמצעות ה-hashtag הבא: #MadeWithTFJS, כדי לקבל הזדמנות להציג את הפרויקט שלכם בבלוג של TensorFlow או אפילו באירועים עתידיים. נשמח לראות את הדמויות שלך.