זיהוי דיבור באמצעות AI באמצעות TensorFlow Lite למיקרו-בקרים ו-SparkFun Edge

1. מבוא

מה תפַתחו

בשיעור ה-Codelab הזה נלמד להשתמש בכלי TensorFlow Lite For Microcontrollers כדי להריץ מודל למידה עמוקה (Deep Learning) ב-SparkFun Edge Development Board. נעבוד עם מודל זיהוי הדיבור המובנה של הלוח, שמשתמש ברשת עצבית מתקפלת כדי לזהות את המילים "כן" וגם 'לא' באמצעות שני המיקרופונים של הלוח.

bf256d403a1821af.gif

למידת מכונה במיקרו-בקרים

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

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

1360b61fbfa33657.jpeg

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

TensorFlow Lite למיקרו-בקרים (תוכנה)

358ffdb9eb758b90.png

TensorFlow היא מסגרת הקוד הפתוח של Google ללמידת מכונה ואימון של מודלים. TensorFlow Lite היא תוכנת framework, גרסה משופרת של TensorFlow, שמטרתה להריץ מודלים של tensorflow במכשירים קטנים יחסית, עם מתח נמוך יחסית, כמו טלפונים ניידים.

TensorFlow Lite For Microcontrollers היא מסגרת תוכנה, גרסה אופטימלית של TensorFlow, שמטרתה להריץ מודלים של tensorflow בחומרה זעירה בעוצמה נמוכה כמו מיקרו-בקרים. הוא פועל בהתאם למגבלות הנדרשות בסביבות המוטמעות האלה, כלומר, יש לו גודל בינארי קטן, הוא לא דורש תמיכה במערכת ההפעלה, ספריות C או C++ רגילות, או הקצאת זיכרון דינמית וכו'.

SparkFun Edge (Hardware)

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

aa4493835a2338c6.png

בניגוד למחשב, מיקרו-בקר לא מפעיל מערכת הפעלה. במקום זאת, התוכנות שכותבים פועלות ישירות על החומרה. כותבים את הקוד במחשב ומורידים אותו אל המיקרו-בקר באמצעות מכשיר שנקרא "מתכנת".

מיקרו-בקרים הם לא מחשבים חזקים. יש בהם מעבדים קטנים, ואין הרבה זיכרון. אבל מכיוון שהן תוכננו להיות פשוטות ככל האפשר, מיקרו-בקר יכול לצרוך מעט מאוד אנרגיה. בהתאם למה שהתוכנית שלכם עושה, SparkFun Edge יכול לפעול במשך שבועות על סוללה עם תא מטבע אחד!

מה תלמדו

  • יוצרים במחשב את התוכנית לדוגמה של SparkFun Edge
  • פורסים את התוכנית במכשיר
  • צריך לבצע שינויים בתוכנית ולפרוס אותה שוב

מה צריך להכין

יש צורך בחומרה הבאה:

לשם כך תצטרכו את התוכנות הבאות:

2. הגדרת החומרה

המיקרו-בקר של SparkFun Edge כולל בינארי מותקן מראש שיכול להפעיל את מודל הדיבור. לפני שנחליף את הדוגמה הזו בגרסה משלנו, נריץ את המודל הזה.

הנעת לוח באמצעות:

  1. הכנסת סוללת תא מטבע למחבר הסוללה בגב הלוח (כשהצלע + של הסוללה פונה כלפי מעלה. אם הלוח הגיע עם סוללה שכבר הוכנסה אליו, יש להוציא את לשונית הפלסטיק ולדחוף אותה כדי לוודא שהיא הוכנסה במלואה)

25a6cc6b208e8a4e.png

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

b140822f0019f92a.png

לאחר הפעלת הלוח באמצעות הכנסת הסוללה או חיבור מתכנת ה-USB, הלוח יתעורר ויתחיל להאזין למיקרופונים. האור הכחול אמור להתחיל להבהב.

מודל למידת המכונה על הלוח אומן לזהות את המילים 'כן'. ו'לא', ולזהות נוכחות והיעדר דיבור. הוא מעביר את התוצאות שלו באמצעות נורות LED צבעוניות. בטבלה הבאה מוצגת המשמעות של כל צבע LED:

תוצאת הזיהוי

צבע LED

"כן"

צהוב

"לא"

אדום

דיבור לא ידוע

ירוק

לא זוהה דיבור

אין נורות LED דולקות

כדאי לנסות

מחזיקים את הלוח מול הפה ואומרים "כן" כמה פעמים. הפלאש הצהוב יופיע. אם לא קורה כלום כשאומרים "כן", אפשר לנסות את הפעולות הבאות:

  • יש להחזיק את הלוח במרחק של כ-10 אינץ' מהפה
  • הימנעות מרעשי רקע מוגזמים
  • חזרה על 'כן' כמה פעמים ברצף מהיר (נסו לומר "yes yes yes")

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. עכשיו נריץ פקודה נוספת כדי ליצור גרסה סופית של הקובץ, שיכולה לשמש כדי לעדכן את המכשיר שלנו באמצעות סקריפט תוכנת האתחול שבו נשתמש בשלב הבא:

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 מאחסן את התוכנית שפועלת כרגע בזיכרון ה-Flash של 512KB. אם אנחנו רוצים שהלוח יפעיל תוכנית חדשה, צריך לשלוח אותו ללוח. הוא יאחסן אותו בזיכרון ה-Flash ויחליף כל תוכנית שנשמרה בעבר.

תהליך זה נקרא הבהוב (הבהוב), ואנו נשתמש בו כדי לשלוח את התוכנית שלנו ללוח.

חיבור המתכנת ללוח

כדי להוריד תוכניות חדשות ללוח, נשתמש במתכנת הטורי מסוג USB-C של SparkFun. המכשיר הזה מאפשר למחשב לתקשר עם המיקרו-בקר באמצעות USB.

כדי לחבר את המכשיר הזה ללוח, מבצעים את השלבים הבאים:

  1. מאתרים את הכותרת עם שישה פינים בצד של SparkFun Edge.
  2. מחברים את SparkFun USB-C Series Basic אל הפינים האלה, ומוודאים שהסיכות מסומנות בתווית BLK. ו-GRN שכל מכשיר מיושר כראוי.

b140822f0019f92a.png

מחברים את המתכנת למחשב

אנחנו נחבר את הלוח למחשב באמצעות 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

בשלב הבא ניצור משתנה סביבה כדי לציין את קצב הבאוד, שהוא המהירות שבה נתונים יישלחו למכשיר:

export BAUD_RATE=921600

6. הבזק את הקובץ הבינארי

מריצים את הסקריפט כדי לשדרג את הלוח

כדי להבהב את הלוח, צריך להכניס אותו ל"תוכנת אתחול" מיוחדת שמכין אותו לקבל את הקובץ הבינארי החדש. לאחר מכן נריץ סקריפט לשלוח את הקובץ הבינארי ללוח.

נכיר את הלחצנים הבאים על הלוח:

64c620570b9d2f83.png

כדי לאפס את הלוח ולהבזק אותו, מבצעים את השלבים הבאים:

  1. חשוב לוודא שהלוח מחובר למתכנת ושכל ההגדרה מחוברת למחשב באמצעות USB.
  2. מתחילים לוחצים לחיצה ארוכה על הלחצן 14 על הלוח. ממשיכים ללחוץ עליו עד שלב 6.
  3. עדיין לוחצים על הלחצן 14. כדי לאפס את הלוח למצב תוכנת האתחול, צריך ללחוץ על הלחצן RST כדי לאפס את הלוח.
  4. עדיין מחזיקים את הלחצן בשם 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
  1. עדיין לוחצים לחיצה ארוכה על הלחצן 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...]
  1. עצירה: לחיצה ארוכה על הלחצן 14 בלוח העריכה אחרי שרואים את Sending Data Packet of length 8180 (אבל זה בסדר אם ממשיכים להחזיק אותו). התוכנית תמשיך להדפיס קווים בטרמינל. בסופו של דבר זה ייראה בערך כך:
[...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 הותקן לצד מנהל ההתקן הטורי הקיים, וניתן לפתור את הבעיה באופן הבא:

שלב 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 הכחולה מתחילה להבהב, סימן שההבהוב הצליחה. אם לא, גוללים למטה לקטע מה אפשר לעשות אם זה לא עבד?.

bf256d403a1821af.gif

מודל למידת המכונה על הלוח אומן לזהות את המילים 'כן'. ו'לא', ולזהות נוכחות והיעדר דיבור. הוא מעביר את התוצאות שלו באמצעות נורות LED צבעוניות. בטבלה הבאה מוצגת המשמעות של כל צבע LED:

תוצאת הזיהוי

צבע LED

"כן"

צהוב

"לא"

אדום

דיבור לא ידוע

ירוק

לא זוהה דיבור

אין נורות LED דולקות

כדאי לנסות

מחזיקים את הלוח מול הפה ואומרים "כן" כמה פעמים. הפלאש הצהוב יופיע. אם לא קורה כלום כשאומרים "כן", אפשר לנסות את הפעולות הבאות:

  • יש להחזיק את הלוח במרחק של כ-10 אינץ' מהפה
  • הימנעות מרעשי רקע מוגזמים
  • חזרה על 'כן' כמה פעמים ברצף מהיר (נסו לומר "yes yes yes")

מה לעשות אם זה לא עבד?

ריכזנו כאן כמה בעיות אפשריות ודרכים לנפות באגים:

הבעיה: אחרי הפלאש, נורית ה-LED לא נדלקת.

הפתרון: אפשר לנסות ללחוץ על הלחצן RST, או לנתק את הלוח ולחבר אותו מחדש מהמתכנת. אם אף אחד מהצעדים האלה לא עובד, אפשר לנסות להבהב שוב את הלוח.

בעיה: נורית ה-LED הכחולה מאירה, אבל היא מעומכת מאוד.

הפתרון:מחליפים את הסוללה כי היא חלשה. לחלופין, אפשר להפעיל את הלוח באמצעות מחשב באמצעות המתכנת והכבל.

8. קריאת הפלט של ניפוי הבאגים (אופציונלי)

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

פתיחת חיבור סידורי

כברירת מחדל, הקוד לדוגמה של SparkFun Edge מתעד כל פקודות קוליות, לשמור על רמת ביטחון שלהן. כדי להציג את הפלט של הלוח, מריצים את הפקודה הבאה:

screen ${DEVICENAME} 115200

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

Apollo3 Burst Mode is Available

                               Apollo3 operating in Burst Mode (96MHz)

אפשר לנסות לבצע כמה פקודות על ידי אמירת "yes" או 'לא'. אתם אמורים לראות את המידע על ניפוי הבאגים של הדפסת הלוח עבור כל פקודה:

 Heard yes (202) @65536ms

ביומן שלמעלה, yes מתייחס לפקודה. המספר 202 מתייחס לרמת הביטחון שהפקודה נשמעה (כאשר 200 הוא הערך המינימלי). לבסוף, 65536ms מתייחס לפרק הזמן שעבר מאז האיפוס האחרון של המיקרו-בקר.

כדי להפסיק את הצגת הפלט של ניפוי הבאגים, מקישים על Ctrl+A, ומיד אחר כך על המקש K, ואז על המקש Y.

כתיבה של יומני ניפוי באגים

אפשר לראות את הקוד שרושם את המידע הזה בקובץ train_replyer.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, אתם יכולים להתחיל לשחק עם הקוד ולפרוס אותו במכשיר כדי לראות את התוצאות.

לקריאת הקוד

הקובץ הבא הוא מקום טוב להתחיל בקריאת הקוד, 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 ידליק.

ל-method ResponseToCommand קוראים מספר ארגומנטים:

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 האלה רק אם המילה "כן" היא נאמרת. אם מזוהה מילה נוספת, נוריות ה-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.

בנייה מחדש ו-Flash

אחרי ביצוע השינויים בקוד, בודקים אותו על ידי הרצת כל השלבים מפיתוח והכנת הקובץ הבינארי.

10. השלבים הבאים

מזל טוב, הצלחת לבנות את גלאי הדיבור הראשון שלך במיקרו-בקר!

אנחנו מקווים שנהניתם מהמבוא הקצר הזה לפיתוח עם TensorFlow Lite למיקרו-בקרים. הרעיון של למידה עמוקה (Deep Learning) על מיקרו-בקרים הוא חדש ומרגש, ואנחנו ממליצים לצאת ולהתנסות!

מסמכי עזר

26699b18f2b199f.png

תודה, ושיהיה לכם כיף לבנות!