בניית Vigil, הדגמת גילוי נפילות במכ"ם לדיור מוגן: על מערך סינתטי של 360 אירועים קו הבסיס הנאיבי השווה recall של 1.0 עם סגוליות של 0.167.
למידת מכונהטכנולוגיית בריאותבטיחות בינה מלאכותית

קו הבסיס הנאיבי בגלאי נפילות המכ"ם שלי הגיע לאותו recall של 1.0. הוא גם הפעיל שבע אזעקות שווא בלילה אחד.

Ashutosh SinghalAshutosh Singhal18 ביולי 202613 min

במשמרת הלילה הסינתטית שבניתי עבור Vigil, קו הבסיס המדפי מפעיל תשע התרעות בין 02:00 ל-06:00 ושבע מהן שגויות. מאוורר תקרה, שנתפס בשיא מהירות של 5.0 מ'/שנייה. כלב טיפולי, עם שטח חתך מכ"ם של 0.27. דייר שמתיישב בכבדות על מושב במהירות של 2.92 מ'/שנייה. שתיים מתשע ההתרעות הללו הן נפילות אמיתיות, ואחת מהן מתרחשת בחדר רחצה: עקבת צנטרואיד היורדת מ-1.53 מ' בעמידה דרך 1.07, 0.84, 0.625 ו-0.344 לפני שהיא מתייצבת ב-0.119 מ', מפלס הרצפה, נשימה קיימת, ללא התאוששות.

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

‏Vigil היא שכבת הבינה שבניתי כדי לשבת בין זרם מאפייני מכ"ם לבין מערכת קריאת אחות בדיור מוגן לקשישים. היא מחזירה ALERT,‏ SUPPRESS או ROUTE TO HUMAN, כאשר לכל אחת מהן מצורפת סיבה שהמוסד יכול לתעד. נתיב ההדגמה הוא https://veriprajna.com/demos/smart-facility-fall-detection. התחלתי את הפיתוח בהנחה שהחלק הקשה הוא לראות את הנפילה. מבחן הביצועים חלק עליי כבר בהרצה הראשונה.

‏Recall היה המספר שרציתי להוביל איתו

הרצתי את מבחן הביצועים בציפייה שרגישות הזיהוי לנפילות תהיה הכותרת הראשית, וזהו מספר טוב: ‏recall של 1.0 עבור הקסקדה על פני מערך קבוע של 360 אירועים סינתטיים מתויגים ורועשים. העמודה שלצדו היא זו ששינתה את המאמר שחשבתי שאני כותב. קו הבסיס הנאיבי מורכב משני פסוקי אריתמטיקה, כל תנועה מהירה או נמוכה היא נפילה (peak_v > 2.0 OR min_cz < 0.45), ועל אותו מערך הוא משיג גם כן recall של 1.0. רגישות היא המקום שבו שיווק גילוי הנפילות חי, ושני הגלאים מוצמדים לחלק העליון שלה.

ההפרדה נמצאת כולה בשורה שאף אחד אינו מציג בשקופית. סגוליות למערפלים של 1.0 עבור הקסקדה ו-0.167 עבור קו הבסיס, שיעור אזעקות שווא של 0.833 לכל אירוע שפיר. השליכו זאת על 30 טריגרי תנועה שפירה לחדר ליום שמבחן הביצועים מניח, וקו הבסיס מגיע ל-25.0 אזעקות שווא לחדר ליום. הטווח המפורסם של המערכות הקיימות מחיישני מדף הוא 5 עד 15 אזעקות שווא לחדר ליום, ועייפות אזעקות ולא רגישות החיישן מתועדת כסיבה המובילה לכך שהטמעות אלו נכשלות.

עליי לומר זאת לפני שקורא טכני יאמר זאת במקומי. משקולות ההיתוך ב-data/fall_model.json הותאמו על ידי tools/fit_fall_classifier.py על גבי מחוללי התרחישים של ההדגמה עצמה, אותם מחוללים שמייצרים את מערך 360 האירועים. זוהי ההתנגדות החזקה ביותר שמישהו יכול להעלות נגד שני ציוני ה-1.0 שלי, וזו גם הסיבה שבגללה אכפת לי יותר מציון ה-0.167 מאשר מכל אחד מהם. הכישלון של קו הבסיס אינו תוצר לוואי של תצורת האימון שלי. זה מה שסף עושה כשהעולם מכיל מאווררי תקרה.

שבע אזעקות השווא קובעות האם מישהו עדיין יקשיב כשתגיע האזעקה האמיתית.

המערפלים נבנו כדי להביס מאפיין יחיד

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

כל מערפל נוצר כדי לחפוף לנפילה אמיתית במאפיין בודד כלשהו. הישיבה החבוטה ב-Cam 5 נושאת פרץ מהירות של 2.92 מ'/שנייה, בסדר גודל של נפילה, ומתייצבת ב-0.46 מ'. בת דודתה בחדר הרחצה ב-Cam 10 מגיעה לשיא של 3.31 מ'/שנייה ומתייצבת ב-0.44 מ'. כלב הטיפול וההתכופפות להרמת מגבת מורידים שניהם את הצנטרואיד, שזהו החצי השני של כלל קו הבסיס. כל בדיקה יחידה שיכולתי לכתוב הובסה מעצם התכנון, וזו הסיבה שקו הבסיס מוטעה באמת ב-0.167 ולא מוטעה על ידי איש קש שהגדרתי כדי שיפסיד.

מהירות הייתה המאפיין שבו הייתי הכי בטוח, והיא המאפיין שלא שרד לתוך המסווג. מה ששרד הוא מודל לוגיסטי על פני ארבעה מאפיינים: קרבה לרצפה, אנרגיית פגיעה, ירידת גובה וקירוב לחתך מכ"ם, המותכים יחד ל-(P(fall מכויל. שום איבר מהירות אינו מגיע כלל ל-(P(fall. עדיין ישנה שורה ישנה ב-docstring של המודול מהתקופה שחשבתי שיגיע. זהו numpy פשוט, קטן מספיק כדי שמישהו יוכל לפתוח את classifier.py ולהחזיק את העניין כולו בראש, מה שבמסלול של בטיחות חיים שווה עבורי יותר מעוד נקודת AUC.

הצגתי את דיכוי ההתרעה של Cam 10 בפני אנשים תחילה, מפני שהלוח מציג את כל אי-ההסכמה בשורה אחת.

לוח הפירוט של Cam 10 בחדר הרחצה ב-Vigil המציג החלטת SUPPRESS עם שורת הסיבה: פרץ מהירות אך הצנטרואיד התייצב ב-0.44 מ', גובה מושב, לא רצפה, ללא פגיעה חזקה.
‏Cam 10 · Bathroom הוא מקרה הישיבה החבוטה בחדר הרחצה, המגיע לשיא של 3.31 מ'/שנייה. ‏Vigil רושמת SUPPRESS כאשר המאפיין המכריע מופיע בשורת הסיבה: הצנטרואיד התייצב ב-0.44 מ', גובה מושב, לא רצפה, ללא פגיעה חזקה. המהירות הזו לבדה מקיימת את הפסוק `peak_v > 2.0` של קו הבסיס הנאיבי.

ארבעה תנאים, חלון יחיד של 8 שניות

כתבתי את מאמת הנרטיב הזמני כחלק שהייתי רוצה לקרוא כמי שמסתכל מבחוץ. temporal.py דורש ארבעה תנאים בתוך אותו חלון של 8 שניות, כאשר עמידה מבוססת בחמישית הראשונה שלו: צנטרואיד חציוני מעל 1.2 מ', ירידה של יותר מ-0.6 מ' יחד עם שיא מהירות מעל 1.8 מ'/שנייה איפשהו בחלון, פגיעה רחבת-סרט מתמשכת שהממוצע הנע שלה על פני 3 פריימים עולה על 0.50, והצנטרואיד שמגיע בפועל אל מתחת ל-0.30 מ'. מבחן הפגיעה המתמשכת קיים מפני שספייק בפריים בודד הוא זול, וגוף שפוגע ברצפה אינו כזה.

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

רק אז מוסיף השער אישור נשימה מעל 0.20 ורמת ביטחון בנפילה של לפחות 0.70. שלושת הערכים הללו – מפלס רצפה 0.30 מ', נשימה 0.20 ורצפת ביטחון של 0.70 – מתקיימים בקוד פשוט מחוץ לכל מודל. הכיוון הוא מה שקובע: התנאים הדטרמיניסטיים חייבים להתקיים לפני שמתייעצים כלל בציון המודל, כך שמספר ביטחון אינו יכול לייצר התרעה בכוחות עצמו לעולם. (P(fall נמוך יותר עדיין יכול להפוך ALERT ל-SUPPRESS, וזוהי האסימטריה הנכונה לשכבה שמותר לה לשתוק ואסור לה להמציא. סף קובע אחד נוסף יושב מחוץ לאותו בלוק מתועד, p_fall >= 0.40 מקודד בקשיחות ב-gate.py שיכול לשלוח אירוע מרובה-שוהים לבדיקה אנושית על סמך ציון המודל לבדו. אני מציין אותו מפני שאחרת "שלושה ספים מתועדים" עושה יותר עבודה ממה שמגיע לו.

הדיכויים הם התיעוד שביקורת פיקוח ממלכתית מבקשת בפועל

בניתי את פנקס ההחלטות (Decision Ledger) לפני שבניתי משהו שנראה כמו מוצר, מפני שהשאלה שלא יכולתי לענות עליה מעולם לא הייתה "האם תפסת את זה". היא הייתה "מדוע לא הופעלה התרעה בחדר 203 בשעה 2:13", והתשובה חייבת להימצא כבר ברשומה כתובה ברגע שמישהו שואל. עשרה מתוך שנים-עשר האירועים במשמרת הם דיכויים, וכל אחד נושא את ערך המאפיין שנרשם לגביו: המטרה הלא-אנושית ב-Cam 6 עם שטח חתך מכ"ם של 0.27 מול מינימום אנושי של 0.55, וההתכופפויות ב-Cam 7 וב-Cam 12 שבהן הצנטרואיד עוצר ב-0.60 מ' ו-0.59 מ' עם אנרגיית פגיעה של 0.07 מול סף של 0.50.

מבט הקומה ופנקס ההחלטות של Vigil, המפרט שורות SUPPRESS מ-Cam 12 ועד Cam 6, כל אחת עם טקסט הסיבה שלה.
פנקס ההחלטות לאחר המשמרת, עם האירוע הפעיל ב-Cam 3 · Bathroom ברמת ביטחון של 99%. כל שורה מדוכאת נושאת את הסיבה המכריעה שלה: התייצבות בגובה מושב של 0.44 מ' ב-Cam 10, שטח חתך מכ"ם של 0.27 מתחת למינימום האנושי ב-Cam 6, ותנועה כלפי מטה שחזרה לעמידה ב-Cam 7 וב-Cam 12.
אותן עשר שורות מדוכאות הן מה שמבקר הפיקוח שואל לגביו, מפני שהן האירועים שבהם דבר לא קרה ומישהו עדיין צריך להסביר מדוע.

רק חלק מהכיול הפרטני לחדר מחווט בפועל לתוך החלטה. מאוורר התקרה ב-Cam 1 מדוכא מפני שמפת ההפרעות של חדר 214 נושאת רשומת דופלר במיקום קבוע ב-(1.5, 1.5, 2.45 מ') ו-check_clutter ממסכת אותו באותו ווקסל. הנתיב הזה אמיתי. גבהי המושב והמיטה לכל חדר ב-rooms.json, ‏0.42 מ' בחדר הרחצה של חדר 118 ו-0.45 מ' בחדר 203, ורשומות מאחזי היד שלצידם, הם נתוני כיול ש-שום נתיב קוד ב-V1 אינו קורא; טווח המושב שבו אני משתמש כדי לתייג ישיבה חבוטה הוא בדיקה גלובלית אחת של 0.38 עד 0.60 מ'. יש אפילו מפתח long_lie_sec: 180.0 באותו קובץ ששום דבר אינו צורך. כיול לכל חדר הוא עבודת האינטגרציה שהטמעה אמיתית משלמת עליה, ובגרסה זו רק מסכות הדופלר מחוברות להחלטה.

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

ההתרעה שהתרתי לו להפעיל, והנפילה שלא אפשרתי לו לטעון

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

‏Cam 3 הוא אותו אירוע, ו-Vigil מחזירה ALERT, קטגוריית long_lie, רמת ביטחון 0.99, זמן על הרצפה 4.8 שניות, כאשר סולם ההסלמה דרוך ל-CNA כעת, אחות אחראית ב-90 שניות ו-DON ב-180 שניות. הטקסט בתג קריאת האחות מציין "Room 118B Bathroom: Fall Detected, 99% confidence. Resident on floor 5s. Breathing confirmed." השיגור פולט הן אות מגע יבש של מערכת Rauland מדור קודם והן מטען נתונים של Ascom/Austco MQTT/REST, ושניהם עוברים דרך stub מתאם מתועד. שום חומרת קריאת אחות אינה מחוברת לכל זה. הסיבה שבגללה כדאי לבנות זאת בכל מקרה היא השכיבה הממושכת: מחצית מהקשישים השוכבים על הרצפה מעל שעה נפטרים בתוך שישה חודשים.

פירוט האירוע בחדר הרחצה של Cam 3 ב-Vigil: תג קריאת האחות של חדר 118B, סולם ההסלמה, מטען הנתונים ברמת ביטחון 0.99, והערת האירוע הקליני.
התרעת Cam 3 · Bathroom במבט מורחב (חדר 118B בתג, במטען הנתונים ובהערה). מטען נתוני השיגור רושם רמת ביטחון 0.99, floor_time_sec של 4.8, breathing true ו-long_lie_risk true, כאשר סולם ה-CNA, האחות האחראית וה-DON לצידו והערת האירוע מנוסחת מתוך אותן ראיות מובנות.

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

האירוע שבו אני גאה יותר הוא זה שבו Vigil מסרבת. Cam 2 הוא נפילה אמיתית באמת הקרקע ו-(P(fall מגיע ל-0.99, ובכל זאת Vigil אינה טוענת זאת: החדר מכיל שתי מטרות, מעקב אחר אדם יחיד נמצא מחוץ לכיסוי של V1, והשער מחזיר ROUTE TO HUMAN ברמת ביטחון נמוכה. קו הבסיס הנאיבי יורה אוטומטית וגורף קרדיט על תפיסה שלא הרוויח ביושר. שתי נפילות אמיתיות התרחשו באותה משמרת. Vigil התריעה על אחת ושלחה את השנייה לבדיקת צוות, ולא אתאר זאת כתפיסת כל נפילה, כי זה פשוט לא המצב. לאורך מבחן הביצועים כולו, 40 מתוך 40 נפילות בתפוסה מרובה מנותבות לאדם, ללא התרעות יתר וללא החמצות.

מה שלוח התוצאות מורשה לטעון

שורת ההסתייגות מתחת לחלון תוצאות המשמרת היא החלק היחיד באותו לוח שניסחתי תחילה. החלון מדווח על 0 אזעקות שווא עבור המנוע לעומת 7 עבור המערכת הקיימת במשמרת זו, 1 מתוך 2 נפילות אמיתיות שנתפסה, 1 שנותבה לאדם, 100% סגוליות למערפלים על פני 360 אירועים מתויגים, ו-0.0 לעומת 25 אזעקות שווא חזויות לחדר ליום.

חלון תוצאות המשמרת של Vigil עבור משמרת הלילה בין 02:00 ל-06:00: 0.0 לעומת 25 אזעקות שווא לחדר ליום, 1 מתוך 2 נפילות אמיתיות שנתפסה, 1 שנותבה לאדם, 100% סגוליות למערפלים על פני 360 אירועים מתויגים.
לוח התוצאות של תוצאות המשמרת. 0.0 אזעקות שווא לחדר ליום של המנוע ניצב מול 25 של המערכת הקיימת, כאשר על 1 מתוך 2 נפילות אמיתיות הופעלה התרעה ו-1 נותבה לבדיקה אנושית. כותרת השוליים התחתונה מציינת את ההיקף: 360 אירועים רועשים מתויגים, זרם מאפייני מכ"ם סינתטי, ללא חיישנים חיים, ללא PHI, ללא מצלמה.

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

הרף שאליו אני מחייב כעת התרעת בטיחות חיים

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

המדריך המלא נמצא בכתובת https://veriprajna.com/demos/smart-facility-fall-detection, ועשר השורות המדוכאות בפנקס הן המקום שבו המשמרת מוכרעת בפועל.

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

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

מחקר קשור

פורסם גם ב

בנו את ה-AI שלכם בביטחון.

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

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