7.6. האנטומיה של predict

Model.predict(inputs, *, callback=None) הוא המקום שבו אובייקט המודל הטעון עושה את העבודה בפועל. בין הקלטים הנכנסים לבין התוצאה היוצאת, רצים שלושה שלבים ברצף: קדם-עיבוד, שיגור למנוע, פוסט-עיבוד. שניים מבין השלושה מקבלים פרמטרים שהסקריפט שולט בהם ישירות; המנוע שבאמצע נקבע על ידי המצלמה.

A horizontal flow of five connected boxes from left to right. The leftmost is "Image input"; an arrow leads to "Pre-process" subtitled "Normalization"; an arrow leads to "Engine" subtitled "TFLM / STAI"; an arrow leads to "Post-process" subtitled "postprocess="; and a final arrow leads to "Result". The three middle stages carry a tag underneath -- "user-controllable" beneath Pre-process, "automatic" beneath Engine, and "user-controllable" beneath Post-process.

שלושת השלבים של predict(). קדם-העיבוד והפוסט-עיבוד מקבלים פרמטרים שהסקריפט שולט בהם; המנוע שבאמצע קבוע על ידי המצלמה.

7.6.1. קדם-עיבוד

שלב קדם-העיבוד הופך כל קלט אל הטנזור הצפוף שהרשת מצפה לו. הקלט הנפוץ ביותר הוא image.Image, שנלכד ב-RGB565. השלב חותך אותו ומשנה את גודלו אל input_shape של הרשת, ממיר מ-RGB565 אל פורמט הערוצים שעליו הרשת אומנה (RGB888 לרוב רשתות הראייה), מיישם קנה מידה והיסט (offset) לכל ערוץ, וכאשר הרשת מצפה לקלט שלם (integer) – מקוונטז אל input_dtype של המודל באותו מעבר. רשתות שאומנו לקלט float מדלגות על שלב הקוונטיזציה ומקבלות את תוצאת קנה המידה וההיסט ישירות.

ברירת המחדל ml.preprocessing.Normalization קוראת את ה-input dtype של המודל ומריצה את הטרנספורמציה הנכונה באופן אוטומטי. Normalization מכוונן ידנית גובר על ערכי קנה המידה, הממוצע, וסטיית התקן עבור מודלים שאומנו מול סטטיסטיקות ערוצים מותאמות אישית (הממוצעים וסטיות התקן הנגזרים מ-ImageNet הם מקרה נפוץ). ישות בת-קריאה (callable) פשוטה גוברת על השלב כולו – שימושית כאשר הקלט אינו תמונה כלל או כאשר היישום כבר ייצר בעצמו את הטנזור הצפוף.

7.6.2. שיגור למנוע

שלב המנוע מריץ את הרשת. לאיזה מנוע הוא משגר נקבע על ידי המצלמה: ה-H7 וה-RT1062 מריצים TFLM (מפרש TensorFlow Lite for Microcontrollers, המשגר ליבות (kernels) CMSIS-NN מותאמות-ARM היכן שהן קיימות); ה-AE3 מריץ את אותו מפרש TFLM עם נסיגת (fallback) ה-Cortex-M55 שלו וה-NPU מסוג Ethos-U המטפל בכל אופרטור שמהדר Vela הלא-מקוון תייג למאיץ; ה-N6 מריץ את STAI, סביבת הריצה של ST עבור ה-NPU המיועד-לתכלית של ה-N6.

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

7.6.3. פוסט-עיבוד

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

הסקריפט שולט בשלב הזה בשתי דרכים. מילת המפתח postprocess= בבנאי רושמת פוסט-מעבד שרץ בכל קריאה. מילת המפתח callback= ב-predict() גוברת על הפוסט-מעבד הרשום עבור קריאה אחת בלבד – שימושית למעבר בין כמה מפענחים מבלי לטעון מחדש את המודל. כל אחת מהצורות מקבלת (model, inputs, outputs) ומחזירה כל מה שהיישום מצפה לו.

7.6.4. במה הסקריפט שולט

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