1. מבוא
מה תפַתחו
ב-codelab הזה נלמד איך להשתמש ב-TensorFlow Lite For Microcontrollers כדי להפעיל מודל למידה עמוקה ב-SparkFun Edge Development Board. אנחנו נשתמש במודל המובנה לזיהוי דיבור בלוח, שמבוסס על רשת נוירונים קונבולוציונית כדי לזהות את המילים 'כן' ו'לא' שנאמרות דרך שני המיקרופונים של הלוח.

למידת מכונה במיקרו-בקרים
אפשר להשתמש בלמידת מכונה כדי ליצור כלים חכמים שמקלים על חיי המשתמשים, כמו Google Assistant. אבל הרבה פעמים הפעילויות האלה דורשות הרבה חישובים או משאבים, שיכולים לכלול שרת ענן חזק או מחשב שולחני. עם זאת, עכשיו אפשר להריץ הסקה של למידת מכונה על חומרה קטנה עם צריכת חשמל נמוכה, כמו מיקרו-בקרים.
מיקרו-בקרים נפוצים מאוד, זולים, צורכים מעט מאוד אנרגיה ואמינים מאוד. הם חלק מכל מיני מכשירים ביתיים: מכשירי חשמל, מכוניות וצעצועים. למעשה, מדי שנה מיוצרים כ-30 מיליארד מכשירים שמבוססים על מיקרו-בקרים.

הוספת למידת מכונה למיקרו-בקרים קטנים מאפשרת לנו לשפר את האינטליגנציה של מיליארדי מכשירים שאנחנו משתמשים בהם בחיי היום-יום, בלי להסתמך על חומרה יקרה או על חיבורים אמינים לאינטרנט. תארו לעצמכם מכשירי חשמל חכמים שיכולים להתאים את עצמם לשגרה היומיומית שלכם, חיישנים תעשייתיים חכמים שמבינים את ההבדל בין בעיות לבין פעולה רגילה, וצעצועים קסומים שיכולים לעזור לילדים ללמוד בדרכים מהנות ומרתקות.
TensorFlow Lite For Microcontrollers (תוכנה)

TensorFlow הוא פלטפורמה של Google ללמידת מכונה בקוד פתוח, שמאפשרת לאמן ולהפעיל מודלים. TensorFlow Lite היא מסגרת תוכנה, גרסה שעברה אופטימיזציה של TensorFlow, שמיועדת להרצת מודלים של TensorFlow במכשירים קטנים יחסית עם הספק נמוך, כמו טלפונים ניידים.
TensorFlow Lite For Microcontrollers היא מסגרת תוכנה, גרסה שעברה אופטימיזציה של TensorFlow, שמיועדת להרצת מודלים של TensorFlow על חומרה קטנה וחלשה, כמו מיקרו-בקרים. הוא עומד במגבלות הנדרשות בסביבות המוטמעות האלה, כלומר, גודל הבינארי שלו קטן, הוא לא דורש תמיכה במערכת ההפעלה, בספריות C או C++ רגילות או בהקצאת זיכרון דינמית וכו'.
SparkFun Edge (חומרה)
SparkFun Edge היא פלטפורמה שמבוססת על מיקרו-בקר: מחשב קטן על לוח מעגלים יחיד. יש לו מעבד, זיכרון וחומרה של קלט/פלט שמאפשרים לו לשלוח ולקבל אותות דיגיטליים למכשירים אחרים. יש לו ארבע נוריות LED שאפשר לשלוט בהן באמצעות תוכנה, בצבעים האהובים של Google.

בניגוד למחשב, מיקרו-בקר לא מריץ מערכת הפעלה. במקום זאת, התוכניות שאתם כותבים פועלות ישירות על החומרה. כותבים את הקוד במחשב ומורידים אותו למיקרו-בקר באמצעות מכשיר שנקרא מתכנת.
מיקרו-בקרים הם לא מחשבים חזקים. המעבדים שלהם קטנים ואין להם הרבה זיכרון. אבל מכיוון שהם מתוכננים להיות פשוטים ככל האפשר, מיקרו-בקר יכול להשתמש במעט מאוד אנרגיה. בהתאם לפעולות שהתוכנה מבצעת, לוח SparkFun Edge יכול לפעול במשך שבועות על סוללת כפתור אחת!
מה תלמדו
- קומפילציה של תוכנית לדוגמה עבור SparkFun Edge במחשב
- פריסת התוכנית במכשיר
- לבצע שינויים בתוכנית ולפרוס אותה מחדש
מה תצטרכו
תצטרכו את הציוד הבא:
- מחשב עם Linux או MacOS
- לוח SparkFun Edge
- מתכנת SparkFun USB-C Serial Basic
- כבל USB-C ל-USB-A (אם יש לכם מחשב עם USB-C, קנו במקום זאת כבל USB-C ל-USB-C)
- (אופציונלי) סוללת ליתיום שטוחה (CR2032) של 3V בקוטר 20 מ"מ להפעלת הסקת מסקנות ללא מתכנת וכבל
תצטרכו את התוכנות הבאות:
- Git (כדי לבדוק אם הוא מותקן, מריצים את הפקודה
gitבשורת הפקודה) - Python 3 (כדי לבדוק אם היא מותקנת, מריצים את הפקודה
python3אוpython --versionבשורת הפקודה) - Pip ל-Python 3 ( תשובה מועילה ב-StackOverflow)
- גרסה 4.2.1 ומעלה (כדי לבדוק אם היא מותקנת, מריצים את הפקודה
make --versionבשורת הפקודה) - SparkFun Serial Basic drivers
2. הגדרת הציוד
במיקרו-בקר SparkFun Edge מותקן מראש קובץ בינארי שיכול להריץ את מודל הדיבור. לפני שנחליף את הגרסה הזו בגרסה משלנו, נריץ קודם את המודל הזה.
כדי להפעיל את הלוח:
- מכניסים סוללת מטבע למחבר הסוללה בחלק האחורי של הלוח (כשהצד עם הסימן '+' של הסוללה פונה כלפי מעלה). אם הלוח הגיע עם סוללה שכבר הוכנסה, מושכים את לשונית הפלסטיק ודוחפים את הסוללה כדי לוודא שהיא הוכנסה עד הסוף)

- אם אין לכם סוללת מטבע, אתם יכולים להשתמש במכשיר התכנות SparkFun USB-C Serial Basic כדי להפעיל את הלוח. כדי לצרף את המכשיר ללוח, פועלים לפי השלבים הבאים:
- מאתרים את מחבר הפינים בן ששת הפינים בצד של SparkFun Edge.
- מחברים את SparkFun USB-C Serial Basic לפינים האלה, ומוודאים שהפינים עם התוויות BLK ו-GRN בכל מכשיר מיושרים בצורה נכונה.
- מחברים כבל USB-C בין SparkFun USB-C Serial Basic לבין המחשב.

אחרי שמפעילים את הלוח על ידי הכנסת הסוללה או חיבור מתכנת ה-USB, הלוח יתעורר ויתחיל להאזין באמצעות המיקרופונים שלו. הנורית הכחולה אמורה להתחיל להבהב.
מודל הלמידה החישובית בלוח מאומן לזהות את המילים 'כן' ו'לא', ולזהות את נוכחות הדיבור ואת היעדרו. הוא מעביר את התוצאות באמצעות מנורות לד צבעוניות. בטבלה הבאה מוסבר מה המשמעות של כל צבע של נורית ה-LED:
תוצאת הזיהוי | צבע ה-LED |
"כן" | צהוב |
"לא" | אדום |
דיבור לא ידוע | ירוק |
לא זוהה דיבור | אף נורית LED לא דולקת |
כדאי לנסות
מצמידים את הלוח לפה ואומרים "כן" כמה פעמים. נורית ה-LED הצהובה תהבהב. אם לא קורה כלום כשאתם אומרים "כן", הנה כמה דברים שאפשר לנסות:
- מחזיקים את הלוח במרחק של כ-25 ס"מ מהפה
- איך נמנעים מרעשי רקע חזקים מדי
- חוזרים על המילה 'כן' כמה פעמים ברצף מהיר (אפשר לומר 'כן כן כן')
3. הגדרת התוכנה
עכשיו נוריד, נתקין ונפעיל את מודל הדיבור במיקרו-בקר בעצמנו. לשם כך, קודם מורידים את קוד המקור של התוכנית הזו ואת יחסי התלות שדרושים לבנייתה. התוכנית כתובה ב-C++, ולפני שמורידים אותה ללוח צריך לקמפל אותה לקובץ בינארי. קובץ בינארי הוא קובץ שמכיל את התוכנית בצורה שאפשר להריץ ישירות על חומרת SparkFun Edge.
ההוראות הבאות מיועדות ל-Linux או ל-MacOS.
הורדת מאגר TensorFlow
הקוד זמין במאגר TensorFlow ב-GitHub, במיקום הבא:
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/micro
פותחים טרמינל במחשב, עוברים לספרייה שבה בדרך כלל מאחסנים פרויקטים של קידוד, מורידים את מאגר TensorFlow ונכנסים לספרייה שנוצרה, כמו שמוצג בהמשך:
cd ~ # change into your home (or any other) directory git clone --depth 1 https://github.com/tensorflow/tensorflow.git cd tensorflow
הורדת יחסי תלות של Python
נשתמש ב-Python 3 כדי להכין את הקובץ הבינארי ולצרוב אותו למכשיר. הסקריפטים של Python תלויים בזמינות של ספריות מסוימות. מריצים את הפקודה הבאה כדי להתקין את יחסי התלות האלה:
pip3 install pycrypto pyserial --user
4. בנייה והכנה של הקובץ הבינארי
אנחנו ניצור את הקובץ הבינארי ונריץ פקודות שיכינו אותו להורדה למכשיר.
יצירת הקובץ הבינארי
כדי להוריד את כל יחסי התלות הנדרשים וליצור את הקובץ הבינארי, מריצים את הפקודה הבאה:
make -f tensorflow/lite/micro/tools/make/Makefile TARGET=sparkfun_edge micro_speech_bin
אם ה-build פועל בהצלחה, השורה האחרונה של הפלט אמורה להיראות כך:
arm-none-eabi-objcopy tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech.bin -O binary
כדי לוודא שהקובץ הבינארי נוצר בהצלחה, מריצים את הפקודה הבאה:
test -f \ tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech.bin && \ echo "Binary was successfully created" || echo "Binary is missing"
הערך Binary was successfully created אמור להיות מודפס במסוף. אם מופיעה השגיאה Binary is missing, הייתה בעיה בתהליך build וצריך לבצע ניפוי באגים.
הכנת הקובץ הבינארי
כדי לפרוס את הקובץ הבינארי במכשיר, צריך לחתום עליו באמצעות מפתחות קריפטוגרפיים. עכשיו נריץ כמה פקודות שיחתמו על הקובץ הבינארי שלנו כדי שיהיה אפשר להוריד אותו ל-SparkFun Edge.
מזינים את הפקודה הבאה כדי להגדיר כמה מפתחות קריפטוגרפיים פיקטיביים שאפשר להשתמש בהם לפיתוח:
cp tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/keys_info0.py tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/keys_info.py
עכשיו מריצים את הפקודה הבאה כדי ליצור קובץ בינארי חתום:
python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/create_cust_image_blob.py \ --bin tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech.bin \ --load-address 0xC000 \ --magic-num 0xCB \ -o main_nonsecure_ota \ --version 0x0
הפעולה הזו תיצור את הקובץ main_nonsecure_ota.bin. עכשיו נריץ עוד פקודה כדי ליצור גרסה סופית של הקובץ, שאפשר להשתמש בה כדי לצרוב ROM (flash) במכשיר באמצעות סקריפט תוכנת האתחול שנשתמש בו בשלב הבא:
python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/create_cust_wireupdate_blob.py \ --load-address 0x20000 \ --bin main_nonsecure_ota.bin \ -i 6 \ -o main_nonsecure_wire \ --options 0x1
עכשיו אמור להיות קובץ בשם main_nonsecure_wire.bin בספרייה שבה הפעלתם את הפקודות. זה הקובץ שנצרוב במכשיר.
5. מכינים את הקרקע להצגת הקובץ הבינארי
מה זה פלאשינג?
התוכנית שפועלת כרגע ב-SparkFun Edge מאוחסנת בזיכרון הפלאש של המכשיר, בנפח של 512 קילובייט. אם רוצים שהלוח יריץ תוכנית חדשה, צריך לשלוח אותה ללוח, והוא ישמור אותה בזיכרון פלאש וידרוס כל תוכנית שנשמרה קודם.
התהליך הזה נקרא 'העברה', ונשתמש בו כדי לשלוח את התוכנית שלנו ללוח.
חיבור המתכנת ללוח
כדי להוריד תוכניות חדשות ללוח, נשתמש ב-SparkFun USB-C Serial Basic serial programmer. המכשיר הזה מאפשר למחשב לתקשר עם המיקרו-בקר באמצעות USB.
כדי לצרף את המכשיר ללוח, פועלים לפי השלבים הבאים:
- מאתרים את מחבר הפינים בן ששת הפינים בצד של SparkFun Edge.
- מחברים את SparkFun USB-C Serial Basic לפינים האלה, ומוודאים שהפינים עם התוויות BLK ו-GRN בכל מכשיר מיושרים בצורה נכונה.

חיבור המתכנת למחשב
נחבר את הלוח למחשב באמצעות USB. כדי לתכנת את הלוח, נצטרך לדעת את השם שהמחשב נותן למכשיר. הדרך הכי טובה לעשות את זה היא ליצור רשימה של כל המכשירים במחשב לפני ואחרי החיבור, ולבדוק איזה מכשיר חדש.
לפני שמחברים את המכשיר באמצעות USB, מריצים את הפקודה הבאה:
If you are using Linux: ls /dev/tty* If you are using MacOS: ls /dev/cu*
הפלט צריך להיות רשימה של מכשירים מחוברים, שדומה לרשימה הבאה:
/dev/cu.Bluetooth-Incoming-Port /dev/cu.MALS /dev/cu.SOC
עכשיו מחברים את המתכנת ליציאת ה-USB במחשב. מזינים שוב את הפקודה הבאה:
If you are using Linux: ls /dev/tty* If you are using MacOS: ls /dev/cu*
הפלט אמור לכלול פריט נוסף, כמו בדוגמה שלמטה. יכול להיות שהפריט החדש יקבל שם אחר. הפריט החדש הזה הוא השם של המכשיר.
/dev/cu.Bluetooth-Incoming-Port /dev/cu.MALS /dev/cu.SOC /dev/cu.wchusbserial-1450
קודם כל, ניצור משתנה סביבה כדי לזהות את שם המכשיר:
export DEVICENAME=put your device name here
בשלב הבא, ניצור משתנה סביבה כדי לציין את קצב העברת הנתונים (baud rate), שהוא המהירות שבה הנתונים יישלחו למכשיר:
export BAUD_RATE=921600
6. צריבת הקוד הבינארי
הרצת הסקריפט לצריבת הלוח
כדי לצרוב את הלוח, צריך להעביר אותו למצב מיוחד של 'תוכנת אתחול' שמכין אותו לקבלת הקובץ הבינארי החדש. לאחר מכן נפעיל סקריפט כדי לשלוח את הקובץ הבינארי ללוח.
כדאי להכיר את הלחצנים הבאים בלוח:

בצע את השלבים הבאים כדי לאפס ולצרוב את הלוח:
- מוודאים שהלוח מחובר למתכנת, ושההגדרה כולה מחוברת למחשב באמצעות USB.
- מתחילים בלחיצה ממושכת על הלחצן שמסומן ב-
14בלוח. ממשיכים להחזיק את המכשיר עד שמגיעים לשלב 6. - עדיין לוחצים על הכפתור שמסומן ב-
14. כדי לאפס את הלוח למצב bootloader, לוחצים על הכפתור שמסומן ב-RST. - עדיין לוחצים על הלחצן שמסומן ב-
14, מדביקים את הפקודה הבאה במסוף ולוחצים על Enter כדי להריץ אותה (לנוחותכם, אפשר להדביק את הפקודה הזו במסוף לפני שמתחילים ללחוץ על הלחצן, אבל לא לוחצים על Enter עד שמגיעים לשלב הזה)
python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/uart_wired_update.py -b ${BAUD_RATE} ${DEVICENAME} -r 1 -f main_nonsecure_wire.bin -i 6
- עדיין לוחצים על הלחצן שמסומן ב-
14, ועכשיו אמור להופיע במסך משהו כמו הדוגמה הבאה:
Connecting with Corvette over serial port /dev/cu.usbserial-1440... Sending Hello. Received response for Hello Received Status length = 0x58 version = 0x3 Max Storage = 0x4ffa0 Status = 0x2 State = 0x7 AMInfo = 0x1 0xff2da3ff 0x55fff 0x1 0x49f40003 0xffffffff [...lots more 0xffffffff...] Sending OTA Descriptor = 0xfe000 Sending Update Command. number of updates needed = 1 Sending block of size 0x158b0 from 0x0 to 0x158b0 Sending Data Packet of length 8180 Sending Data Packet of length 8180 [...lots more Sending Data Packet of length 8180...]
- אחרי שרואים את
Sending Data Packet of length 8180, מפסיקים ללחוץ על הלחצן שמסומן ב-14בלוח (אבל אפשר להמשיך ללחוץ). התוכנית תמשיך להדפיס שורות ב-Terminal. בסופו של דבר, הוא ייראה בערך כך:
[...lots more Sending Data Packet of length 8180...] Sending Data Packet of length 8180 Sending Data Packet of length 6440 Sending Reset Command. Done.
אם מופיע Done, סימן שההבהוב הצליח. אם הפלט של התוכנית מסתיים בשגיאה, בודקים אם הודפס Sending Reset Command. אם כן, סביר להניח שההפעלה הצליחה למרות השגיאה.
במחשב Linux, יכול להיות שתיתקלו בNoResponse Error. הסיבה לכך היא שהדרייבר ch34x serial driver הותקן לצד הדרייבר הקיים, ואפשר לפתור את הבעיה כך:
שלב 1: מתקינים מחדש את הגרסה הנכונה של ספריית ch34x. מוודאים שהמכשיר לא מחובר למחשב במהלך ההתקנה.
git clone https://github.com/juliagoda/CH341SER.git cd CH341SER/ make sudo insmod ch34x.ko sudo rmmod ch341
שלב 2: מחברים את ה-USB של הלוח ומריצים את הפקודה:
dmesg | grep "ch34x"
אמורה להופיע הודעה כזו:
[ 1299.444724] ch34x_attach+0x1af/0x280 [ch34x] [ 1299.445386] usb 2-13.1: ch34x converter now attached to ttyUSB0
אם הדרייבר שבו נעשה שימוש לא נקרא ch34x (לדוגמה: ch341), מנסים להשבית את הדרייבר השני על ידי הרצת הפקודה:
rmmod <non-ch34x driver name>
מנתקים את המכשיר ומחברים אותו מחדש, ומוודאים שהדרייבר שבו נעשה שימוש הוא ch34x.
7. הדגמה (דמו)
רוצים לנסות את התוכנית?
אחרי שהלוח מוטמע בהצלחה, לוחצים על הלחצן שמסומן ב
RST כדי להפעיל מחדש את הלוח ולהתחיל את התוכנית. אם נורית ה-LED הכחולה מתחילה להבהב, ההבהוב הצליח. אם לא, גוללים למטה לקטע מה קורה אם זה לא עבד?.

מודל הלמידה החישובית בלוח מאומן לזהות את המילים 'כן' ו'לא', ולזהות את נוכחות הדיבור ואת היעדרו. הוא מעביר את התוצאות באמצעות מנורות לד צבעוניות. בטבלה הבאה מוסבר מה המשמעות של כל צבע של נורית ה-LED:
תוצאת הזיהוי | צבע ה-LED |
"כן" | צהוב |
"לא" | אדום |
דיבור לא ידוע | ירוק |
לא זוהה דיבור | אף נורית LED לא דולקת |
כדאי לנסות
מצמידים את הלוח לפה ואומרים "כן" כמה פעמים. נורית ה-LED הצהובה תהבהב. אם לא קורה כלום כשאתם אומרים "כן", הנה כמה דברים שאפשר לנסות:
- מחזיקים את הלוח במרחק של כ-25 ס"מ מהפה
- איך נמנעים מרעשי רקע חזקים מדי
- חוזרים על המילה 'כן' כמה פעמים ברצף מהיר (אפשר לומר 'כן כן כן')
מה עושים אם זה לא עבד?
ריכזנו כאן כמה בעיות אפשריות והסבר איך לפתור אותן:
בעיה: אחרי ההבהוב, אף אחת מנוריות ה-LED לא נדלקת.
פתרון: מנסים ללחוץ על הלחצן RST, או לנתק את הלוח מהמתכנת ולחבר אותו מחדש. אם אף אחת מהאפשרויות האלה לא עובדת, נסו להפעיל מחדש את הלוח.
בעיה: נורית ה-LED הכחולה נדלקת, אבל היא חלשה מאוד.
פתרון: צריך להחליף את הסוללה כי היא חלשה. אפשרות אחרת היא להפעיל את הלוח באמצעות המחשב, באמצעות המתכנת והכבל.
8. קריאת פלט הניפוי באגים (אופציונלי)
אם נתקלתם בבעיות ואתם צריכים לנפות באגים בקוד שלכם, כדאי לעיין בקטע הזה. כדי להבין מה קורה במיקרו-בקר כשמריצים את הקוד, אפשר להדפיס מידע על תוצאות ניפוי הבאגים דרך החיבור הטורי של הלוח. אתם משתמשים במחשב כדי להתחבר ללוח ולהציג את הנתונים שהלוח שולח.
פתיחת חיבור סדרתי
כברירת מחדל, הקוד לדוגמה של SparkFun Edge מתעד את כל הפקודות המדוברות, יחד עם רמת הביטחון שלהן. כדי לראות את הפלט של הלוח, אפשר להריץ את הפקודה הבאה:
screen ${DEVICENAME} 115200
יכול להיות שבהתחלה תראו פלט שנראה בערך כך: (הפלט הזה מופיע רק אם הלוח מאופס אחרי החיבור, אחרת יכול להיות שתתחילו לראות מידע על ניפוי באגים)
Apollo3 Burst Mode is Available
Apollo3 operating in Burst Mode (96MHz)
אפשר לנסות לתת פקודות באמצעות אמירת 'כן' או 'לא'. אמורה להופיע לכם הודעת ניפוי באגים לגבי כל פקודה:
Heard yes (202) @65536ms
בלוג שלמעלה, yes מתייחס לפקודה. המספר 202 מתייחס לרמת הסמך שהפקודה נשמעה (המינימום הוא 200). לבסוף, 65536ms מתייחס לכמות הזמן שעברה מאז שהמיקרו-בקר אופס לאחרונה.
כדי להפסיק את הצגת פלט הניפוי באגים, לוחצים על Ctrl+A, ואז מיד על המקש K, ואז על המקש Y.
כתיבת יומני ניפוי באגים
אפשר לראות את הקוד שמתעד את המידע הזה בקובץ command_responder.cc שעבדתם איתו קודם:
tensorflow/lite/micro/examples/micro_speech/sparkfun_edge/command_responder.cc
כדי לרשום נתונים ביומן, אפשר להפעיל את השיטה error_reporter->Report(). הוא תומך בטוקנים הסטנדרטיים printf לאינטרפולציה של מחרוזות, שבהם אפשר להשתמש כדי לכלול מידע חשוב ביומני הרישום:
error_reporter->Report("Heard %s (%d) @%dms", found_command, score, current_time);
השיטה הזו תהיה שימושית כשמבצעים שינויים בקוד שמוסבר בקטע הבא.
9. הרחבת הקוד (אופציונלי)
עכשיו, אחרי שלמדתם איך לבנות את SparkFun Edge ולצרוב אליו ROM (flash), אתם יכולים להתחיל לשחק עם הקוד ולפרוס אותו במכשיר כדי לראות את התוצאות.
קריאת הקוד
כדאי להתחיל לקרוא את הקוד בקובץ הבא, command_responder.cc.
tensorflow/lite/micro/examples/micro_speech/sparkfun_edge/command_responder.cc
אפשר לראות את הקובץ ב-GitHub כאן.
ה-method בקובץ הזה, RespondToCommand, מופעלת כשמזוהה פקודה קולית. הקוד הקיים מפעיל נורית LED אחרת בהתאם לתשובה שנשמעה: 'כן', 'לא' או פקודה לא מוכרת. בקטע הקוד הבא אפשר לראות איך זה עובד:
if (found_command[0] == 'y') {
am_hal_gpio_output_set(AM_BSP_GPIO_LED_YELLOW);
}
if (found_command[0] == 'n') {
am_hal_gpio_output_set(AM_BSP_GPIO_LED_RED);
}
if (found_command[0] == 'u') {
am_hal_gpio_output_set(AM_BSP_GPIO_LED_GREEN);
}
הארגומנט found_command מכיל את שם הפקודה שזוהתה. הקבוצה הזו של if הצהרות בודקת את התו הראשון כדי לקבוע איזו נורית LED להדליק.
השיטה RespondToCommand מופעלת עם כמה ארגומנטים:
void RespondToCommand(tflite::ErrorReporter* error_reporter,
int32_t current_time, const char* found_command,
uint8_t score, bool is_new_command) {
- הפונקציה
error_reporterמשמשת לרישום מידע לניפוי באגים (פרטים נוספים בהמשך). -
current_timeמייצג את הזמן שבו הפקודה זוהתה. -
found_commandמציין איזו פקודה זוהתה. scoreמציין את מידת הוודאות שלנו לגבי זיהוי הפקודה.-
is_new_commandמאפשר לנו לדעת אם זו הפעם הראשונה שבה נשמעת הפקודה.
הערך score הוא מספר שלם בין 0 ל-255 שמייצג את ההסתברות לזיהוי פקודה. קוד הדוגמה מחשיב פקודה כתקינה רק אם הניקוד שלה גבוה מ-200. על סמך הבדיקות שלנו, רוב הפקודות התקינות הן בטווח של 200-210.
שינוי הקוד
ללוח SparkFun Edge יש ארבע נוריות LED. בשלב הזה, נורית ה-LED הכחולה מהבהבת כדי לציין שהזיהוי מתבצע. אפשר לראות את זה בקובץ command_responder.cc:
static int count = 0;
// Toggle the blue LED every time an inference is performed.
++count;
if (count & 1) {
am_hal_gpio_output_set(AM_BSP_GPIO_LED_BLUE);
} else {
am_hal_gpio_output_clear(AM_BSP_GPIO_LED_BLUE);
}
יש לנו ארבע נוריות LED, אז נשנה את התוכנית כדי להשתמש בהן כאינדיקטור חזותי של score של פקודה נתונה. ציון נמוך יגרום להדלקת נורית LED אחת, וציון גבוה יגרום להדלקת כמה נוריות.
כדי לוודא שיש לנו דרך לדעת שהתוכנה פועלת, נגרום לנורית ה-LED האדומה להבהב באופן רציף במקום הכחולה. נשתמש בנוריות ה-LED הכחולות, הירוקות והצהובות הסמוכות כדי להציג את העוצמה של score האחרון שלנו. כדי לפשט את התהליך, נדליק את נוריות ה-LED רק אם נאמרת המילה yes. אם תזוהה מילה אחרת, נוריות ה-LED יכבו.
כדי לבצע את השינוי הזה, מחליפים את כל הקוד בקובץ command_responder.cc בקטע הקוד הבא:
#include "tensorflow/lite/micro/examples/micro_speech/command_responder.h"
#include "am_bsp.h"
// This implementation will light up the LEDs on the board in response to different commands.
void RespondToCommand(tflite::ErrorReporter* error_reporter,
int32_t current_time, const char* found_command,
uint8_t score, bool is_new_command) {
static bool is_initialized = false;
if (!is_initialized) {
// Setup LEDs as outputs
am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_RED, g_AM_HAL_GPIO_OUTPUT_12);
am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_BLUE, g_AM_HAL_GPIO_OUTPUT_12);
am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_GREEN, g_AM_HAL_GPIO_OUTPUT_12);
am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_YELLOW, g_AM_HAL_GPIO_OUTPUT_12);
// Ensure all pins are cleared
am_hal_gpio_output_clear(AM_BSP_GPIO_LED_RED);
am_hal_gpio_output_clear(AM_BSP_GPIO_LED_BLUE);
am_hal_gpio_output_clear(AM_BSP_GPIO_LED_GREEN);
am_hal_gpio_output_clear(AM_BSP_GPIO_LED_YELLOW);
is_initialized = true;
}
static int count = 0;
// Toggle the red LED every time an inference is performed.
++count;
if (count & 1) {
am_hal_gpio_output_set(AM_BSP_GPIO_LED_RED);
} else {
am_hal_gpio_output_clear(AM_BSP_GPIO_LED_RED);
}
if (is_new_command) {
// Clear the last three LEDs
am_hal_gpio_output_clear(AM_BSP_GPIO_LED_BLUE);
am_hal_gpio_output_clear(AM_BSP_GPIO_LED_GREEN);
am_hal_gpio_output_clear(AM_BSP_GPIO_LED_YELLOW);
error_reporter->Report("Heard %s (%d) @%dms", found_command, score,
current_time);
// Only indicate a 'yes'
if (found_command[0] == 'y') {
// Always light the blue LED
am_hal_gpio_output_set(AM_BSP_GPIO_LED_BLUE);
// Light the other LEDs depending on score
if (score >= 205) {
am_hal_gpio_output_set(AM_BSP_GPIO_LED_GREEN);
}
if(score >= 210) {
am_hal_gpio_output_set(AM_BSP_GPIO_LED_YELLOW);
}
}
}
}
אם מזוהה פקודה חדשה, הערך של is_new_command יהיה true. ננקה את נוריות ה-LED הכחולות, הירוקות והצהובות, ואז נדליק אותן שוב בהתאם לערכים של found_command ושל score.
בנייה מחדש וצריבת ROM
אחרי שמבצעים שינויים בקוד, בודקים אותו על ידי הפעלת כל השלבים מתוך יצירה והכנה של הקובץ הבינארי.
10. השלבים הבאים
כל הכבוד, יצרת בהצלחה את גלאי הדיבור הראשון שלך במיקרו-בקר!
אנחנו מקווים שנהניתם מההקדמה הקצרה הזו לפיתוח באמצעות TensorFlow Lite למיקרו-בקרים. הרעיון של למידה עמוקה במיקרו-בקרים הוא חדש ומלהיב, ואנחנו ממליצים לכם לצאת ולנסות!
מאמרי עזרה
- לאמן מודל משלכם כדי להבין פקודות שונות, אחרי שצברתם ניסיון בעבודה עם התוכנית הבסיסית. הערה: ההדרכה תימשך כמה שעות.
- מידע נוסף על TensorFlow Lite for Microcontrollers ( אתר, GitHub).
- אפשר לנסות דוגמאות אחרות ולהריץ אותן ב-SparkFun Edge, אם יש תמיכה בכך.
- מומלץ לעיין בספר של O'Reilly TinyML: Machine Learning with TensorFlow on Arduino and Ultra-Low Power Micro-Controllers, שבו מוצגת למידת מכונה במכשירים קטנים, ומוסבר על כמה פרויקטים מעניינים. ה-Codelab הזה מבוסס על פרקים 7 ו-8 בספר.

תודה, ותהנה מהבנייה!