1. סקירה כללית
מטרות
Firebase ML מאפשר לך לפרוס את הדגם שלך באוויר. זה מאפשר לך לשמור על גודל האפליקציה קטן ולהוריד רק את מודל ה-ML בעת הצורך, להתנסות במספר דגמים, או לעדכן את מודל ה-ML שלך מבלי שתצטרך לפרסם מחדש את האפליקציה כולה.
במעבדת קוד זה תמיר אפליקציית iOS באמצעות מודל TFLite סטטי לאפליקציה באמצעות מודל המוגש באופן דינמי מ-Firebase. תלמד כיצד:
- פרוס דגמי TFLite ל-Firebase ML וגשת אליהם מהאפליקציה שלך
- רישום מדדים הקשורים למודל עם Analytics
- בחר איזה דגם נטען דרך Remote Config
- בדיקת A/B דגמים שונים
דרישות מוקדמות
לפני שתתחיל מעבדת קוד זה ודא שהתקנת:
- Xcode 11 (או יותר)
- CocoaPods 1.9.1 (או יותר)
2. צור פרוייקט מסוף Firebase
הוסף את Firebase לפרויקט
- עבור אל מסוף Firebase .
- בחר צור פרויקט חדש ותן שם לפרויקט שלך "Firebase ML iOS Codelab".
3. קבל את הפרויקט לדוגמה
הורד את הקוד
התחל בשיבוט הפרויקט לדוגמה והפעלת pod update
בספריית הפרויקט:
git clone https://github.com/FirebaseExtended/codelab-digitclassifier-ios.git cd codelab-digitclassifier-ios pod install --repo-update
אם לא התקנת git, אתה יכול גם להוריד את הפרויקט לדוגמה מדף GitHub שלו או על ידי לחיצה על הקישור הזה . לאחר שהורדת את הפרויקט, הפעל אותו ב-Xcode ושחק עם מסווג הספרות כדי לקבל תחושה כיצד הוא עובד.
הגדר את Firebase
עקוב אחר התיעוד כדי ליצור פרויקט Firebase חדש. לאחר שקיבלת את הפרויקט שלך, הורד את קובץ GoogleService-Info.plist
של הפרויקט ממסוף Firebase וגרור אותו לשורש פרויקט Xcode.
הוסף את Firebase ל-Podfile שלך והפעל את התקנת הפוד.
pod 'FirebaseMLModelDownloader', '9.3.0-beta'
בשיטת didFinishLaunchingWithOptions
של AppDelegate
שלך, ייבא את Firebase בחלק העליון של הקובץ
import FirebaseCore
והוסף קריאה כדי להגדיר את Firebase.
FirebaseApp.configure()
הפעל את הפרויקט שוב כדי לוודא שהאפליקציה מוגדרת כהלכה ואינה קורסת בעת ההשקה.
4. פרוס מודל ל-Firebase ML
פריסת מודל ל-Firebase ML שימושית משתי סיבות עיקריות:
- אנחנו יכולים לשמור על גודל התקנת האפליקציה קטן ולהוריד את הדגם רק במידת הצורך
- ניתן לעדכן את הדגם באופן שוטף ועם מחזור שחרור שונה מכל האפליקציה
לפני שנוכל להחליף את המודל הסטטי באפליקציה שלנו במודל שהורד באופן דינמי מ-Firebase, עלינו לפרוס אותו ל-Firebase ML. ניתן לפרוס את המודל דרך המסוף, או פרוגרמטית, באמצעות Firebase Admin SDK. בשלב זה נפרוס דרך המסוף.
כדי שהדברים יהיו פשוטים, נשתמש במודל TensorFlow Lite שכבר נמצא באפליקציה שלנו. ראשית, פתח את Firebase ולחץ על Machine Learning בחלונית הניווט השמאלית. לאחר מכן נווט אל "מותאם אישית" ולחץ על כפתור "הוסף דגם".
כשתתבקש, תן לדגם שם תיאורי כמו mnist_v1
והעלה את הקובץ מספריית פרויקט codelab.
5. הורד דגם מ-Firebase ML
הבחירה מתי להוריד את הדגם המרוחק מ-Firebase לאפליקציה שלך יכולה להיות מסובכת מכיוון שדגמי TFLite יכולים לגדול יחסית. באופן אידיאלי אנו רוצים להימנע מטעינת הדגם מיד עם השקת האפליקציה, שכן אם הדגם שלנו משמש לתכונה אחת בלבד והמשתמש לעולם לא ישתמש בתכונה זו, נוריד כמות משמעותית של נתונים ללא סיבה. אנו יכולים גם להגדיר אפשרויות הורדה כמו שליפת דגמים בלבד כאשר הם מחוברים ל- wifi. אם אתם רוצים להבטיח שהדגם זמין גם ללא חיבור לרשת, כדאי גם לאגד את הדגם כחלק מהאפליקציה כגיבוי.
למען הפשטות, נסיר את דגם ברירת המחדל המצורף ותמיד מורידים דגם מ-Firebase כשהאפליקציה מתחילה. בדרך זו בעת הפעלת זיהוי ספרות, אתה יכול להיות בטוח שהמסק פועל עם המודל שסופק מ-Firebase.
בחלק העליון של ModelLoader.swift
, ייבא את מודול Firebase.
import FirebaseCore import FirebaseMLModelDownloader
לאחר מכן יישם את השיטה הבאה.
static func downloadModel(named name: String, completion: @escaping (CustomModel?, DownloadError?) -> Void) { guard FirebaseApp.app() != nil else { completion(nil, .firebaseNotInitialized) return } guard success == nil && failure == nil else { completion(nil, .downloadInProgress) return } let conditions = ModelDownloadConditions(allowsCellularAccess: false) ModelDownloader.modelDownloader().getModel(name: name, downloadType: .localModelUpdateInBackground, conditions: conditions) { result in switch (result) { case .success(let customModel): // Download complete. // The CustomModel object contains the local path of the model file, // which you can use to instantiate a TensorFlow Lite classifier. return completion(customModel, nil) case .failure(let error): // Download was unsuccessful. Notify error message. completion(nil, .downloadFailed(underlyingError: error)) } } }
ב- viewDidLoad
של ViewController.swift
, החלף את קריאת האתחול DigitClassifier בשיטת הורדת הדגם החדשה שלנו.
// Download the model from Firebase print("Fetching model...") ModelLoader.downloadModel(named: "mnist_v1") { (customModel, error) in guard let customModel = customModel else { if let error = error { print(error) } return } print("Model download complete") // Initialize a DigitClassifier instance DigitClassifier.newInstance(modelPath: customModel.path) { result in switch result { case let .success(classifier): self.classifier = classifier case .error(_): self.resultLabel.text = "Failed to initialize." } } }
הפעל מחדש את האפליקציה שלך. לאחר מספר שניות, אתה אמור לראות כניסה ל-Xcode המציין שהדגם המרוחק הורד בהצלחה. נסה לצייר ספרה ואשר שהתנהגות האפליקציה לא השתנתה.
6. עקוב אחר משוב והמרה של משתמשים כדי למדוד את דיוק המודל
אנו נמדוד את הדיוק של המודל על ידי מעקב אחר משוב משתמשים על תחזיות המודל. אם משתמש ילחץ על "כן", זה יציין שהתחזית הייתה מדויקת.
אנו יכולים לרשום אירוע Analytics כדי לעקוב אחר הדיוק של המודל שלנו. ראשית, עלינו להוסיף את Analytics ל-Podfile לפני שניתן יהיה להשתמש בו בפרויקט:
pod 'FirebaseAnalytics'
לאחר מכן ב- ViewController.swift
ייבוא Firebase בחלק העליון של הקובץ
import FirebaseAnalytics
והוסיפו את שורת הקוד הבאה בשיטה correctButtonPressed
.
Analytics.logEvent("correct_inference", parameters: nil)
הפעל שוב את האפליקציה וצייר ספרה. לחץ על כפתור "כן" מספר פעמים כדי לשלוח משוב שהמסק היה מדויק.
ניתוח באגים
בדרך כלל, אירועים שנרשמו על ידי האפליקציה שלך נקבצים יחדיו על פני תקופה של כשעה אחת ומועלים יחד. גישה זו חוסכת את הסוללה במכשירי משתמשי הקצה ומפחיתה את השימוש בנתוני הרשת. עם זאת, למטרות אימות הטמעת הניתוח שלך (וכדי להציג את הניתוח שלך בדוח DebugView), אתה יכול להפעיל את מצב Debug במכשיר הפיתוח שלך כדי להעלות אירועים בהשהייה מינימלית.
כדי להפעיל מצב ניפוי באגים של Analytics במכשיר הפיתוח שלך, ציין את הארגומנט הבא של שורת הפקודה ב-Xcode:
-FIRDebugEnabled
הפעל שוב את האפליקציה וצייר ספרה. לחץ על כפתור "כן" מספר פעמים כדי לשלוח משוב שהמסק היה מדויק. כעת תוכל להציג את אירועי היומן כמעט בזמן אמת דרך תצוגת ניפוי הבאגים במסוף Firebase. לחץ על Analytics > DebugView בסרגל הניווט הימני.
7. עקוב אחר זמן ההסקה באמצעות Firebase Performance
בעת בדיקת המודל שלך, מדדי ביצועים שנעשו במכשירי פיתוח אינם מספיקים כדי לתעד את ביצועי המודל בידי המשתמשים שלך, מכיוון שקשה לדעת על איזו חומרה משתמשי חומרה יפעילו את האפליקציה שלך. למרבה המזל, אתה יכול למדוד את ביצועי הדגם שלך במכשירים של משתמשים באמצעות Firebase Performance כדי לקבל תמונה טובה יותר של ביצועי הדגם שלך.
כדי למדוד את הזמן שלוקח להפעיל הסקה, תחילה ייבא את Firebase ב- DigitClassifier.swift:
import FirebasePerformance
לאחר מכן התחל מעקב אחר ביצועים בשיטת הסיווג והפסק את המעקב כאשר ההסקה הושלמה. ודא שאתה מוסיף את שורות הקוד הבאות בתוך סגירת DispatchQueue.global.async ולא ישירות מתחת להצהרת השיטה.
let inferenceTrace = Performance.startTrace(name: "tflite inference") defer { inferenceTrace?.stop() }
אם אתה סקרן, אתה יכול לאפשר רישום באגים באמצעות ההוראות כאן כדי לאשר שעקבות הביצועים שלך נרשמים. לאחר זמן מה, עקבות הביצועים יהיו גלויים גם ב-Firebase Console.
8. פרוס מודל שני ל-Firebase ML
כשממציאים גרסה חדשה של המודל שלך, כמו אחת עם ארכיטקטורת מודל טובה יותר או גרסה שהוכשרה על מערך נתונים גדול יותר או מעודכן, אנו עשויים להתפתות להחליף את המודל הנוכחי שלנו בגרסה החדשה. עם זאת, מודל עם ביצועים טובים בבדיקה לא בהכרח מתפקד באותה מידה בייצור. לכן, בואו נעשה בדיקות A/B בייצור כדי להשוות את הדגם המקורי שלנו לדגם החדש.
אפשר Firebase Model Management API
בשלב זה, נאפשר ל-API לניהול מודלים של Firebase לפרוס גרסה חדשה של מודל TensorFlow Lite שלנו באמצעות קוד Python.
צור דלי לאחסון דגמי ה-ML שלך
במסוף Firebase שלך, עבור אל אחסון ולחץ על התחל.
עקוב אחר הדיאלוג כדי להגדיר את הדלי שלך.
הפעל את Firebase ML API
עבור לדף Firebase ML API ב-Google Cloud Console ולחץ על הפעל.
בחר את אפליקציית Digit Classifier כאשר תתבקש.
כעת נאמן גרסה חדשה של המודל באמצעות מערך נתונים גדול יותר, ולאחר מכן נפרוס אותו באופן תוכניתי ישירות ממחברת ההדרכה באמצעות Firebase Admin SDK.
הורד את המפתח הפרטי עבור חשבון השירות
לפני שנוכל להשתמש ב-Firebase Admin SDK, נצטרך ליצור חשבון שירות. פתח את החלונית חשבונות שירות של מסוף Firebase על ידי לחיצה על קישור זה ולחץ על הלחצן כדי ליצור חשבון שירות חדש עבור Firebase Admin SDK. כאשר תתבקש, לחץ על הלחצן צור מפתח פרטי חדש. נשתמש במפתח חשבון השירות לאימות הבקשות שלנו מהמחברת של colab.
כעת נוכל לאמן ולפרוס את המודל החדש.
- פתח את מחברת ה-Colab הזו וצור עותק שלה ב-Drive שלך.
- הפעל את התא הראשון "אימון מודל TensorFlow Lite משופר" על ידי לחיצה על כפתור ההפעלה משמאל לו. פעולה זו תכשיר דגם חדש ועשויה לקחת זמן מה.
- הפעלת התא השני תיצור הנחיה להעלאת קובץ. העלה את קובץ ה-json שהורדת מ-Firebase Console בעת יצירת חשבון השירות שלך.
- הפעל את שני התאים האחרונים.
לאחר הפעלת המחברת של colab, אתה אמור לראות דגם שני במסוף Firebase. ודא שהדגם השני נקרא mnist_v2
.
9. בחר דגם באמצעות Remote Config
כעת, כשיש לנו שני דגמים נפרדים, נוסיף פרמטר לבחירת הדגם להוריד בזמן הריצה. הערך של הפרמטר שהלקוח יקבל יקבע איזה דגם הלקוח מוריד. ראשית, פתח את מסוף Firebase ולחץ על כפתור Remote Config בתפריט הניווט השמאלי. לאחר מכן, לחץ על כפתור "הוסף פרמטר".
תן שם לפרמטר החדש model_name
ותן לו ערך ברירת מחדל של mnist_v1
. לחץ על פרסם שינויים כדי להחיל את העדכונים. על ידי הכנסת שם הדגם בפרמטר התצורה המרוחקת, נוכל לבדוק מספר דגמים מבלי להוסיף פרמטר חדש עבור כל דגם שאנו רוצים לבדוק.
לאחר הוספת הפרמטר, אתה אמור לראות אותו ב-Console:
בקוד שלנו, נצטרך להוסיף סימון בעת טעינת הדגם המרוחק. כאשר נקבל את הפרמטר מ-Remote Config, נביא את הדגם המרוחק עם השם המתאים; אחרת ננסה לטעון mnist_v1
. לפני שנוכל להשתמש ב-Remote Config, עלינו להוסיף אותו לפרויקט שלנו על ידי ציון אותו כתלות ב-Podfile:
pod 'FirebaseRemoteConfig'
הפעל את התקנת הפוד ופתח מחדש את פרויקט Xcode. ב- ModelLoader.swift
, יישם את שיטת fetchParameterizedModel
.
static func fetchParameterizedModel(completion: @escaping (CustomModel?, DownloadError?) -> Void) { RemoteConfig.remoteConfig().fetchAndActivate { (status, error) in DispatchQueue.main.async { if let error = error { let compositeError = DownloadError.downloadFailed(underlyingError: error) completion(nil, compositeError) return } let modelName: String if let name = RemoteConfig.remoteConfig().configValue(forKey: "model_name").stringValue { modelName = name } else { let defaultName = "mnist_v1" print("Unable to fetch model name from config, falling back to default \(defaultName)") modelName = defaultName } downloadModel(named: modelName, completion: completion) } } }
לבסוף, ב- ViewController.swift
, החלף את הקריאה downloadModel
בשיטה החדשה שיישמנו זה עתה.
// Download the model from Firebase print("Fetching model...") ModelLoader.fetchParameterizedModel { (customModel, error) in guard let customModel = customModel else { if let error = error { print(error) } return } print("Model download complete") // Initialize a DigitClassifier instance DigitClassifier.newInstance(modelPath: customModel.path) { result in switch result { case let .success(classifier): self.classifier = classifier case .error(_): self.resultLabel.text = "Failed to initialize." } } }
הפעל מחדש את האפליקציה וודא שהיא עדיין טוענת את הדגם בצורה נכונה.
10. A/B בדוק את שני הדגמים
לבסוף, אנו יכולים להשתמש בהתנהגות A/B Testing המובנית של Firebase כדי לראות איזה משני הדגמים שלנו מניב ביצועים טובים יותר. עבור אל Analytics -> אירועים במסוף Firebase. אם אירוע correct_inference
מופיע, סמן אותו כ"אירוע המרה", אם לא, אתה יכול ללכת ל-Analytics -> אירועי המרה וללחוץ על "צור אירוע המרה חדש" ולשים את correct_inference.
כעת עבור אל "תצורה מרחוק במסוף Firebase, בחר את כפתור "A/B test" מתפריט אפשרויות נוספות בפרמטר "model_name" שזה עתה הוספנו.
בתפריט שלאחר מכן, קבל את שם ברירת המחדל.
בחר את האפליקציה שלך בתפריט הנפתח ושנה את קריטריוני המיקוד ל-50% מהמשתמשים הפעילים.
אם הצלחת להגדיר את אירוע correct_inference
כהמרה קודם לכן, השתמש באירוע זה כמדד העיקרי למעקב. אחרת, אם אינך רוצה להמתין עד שהאירוע יופיע ב-Analytics, תוכל להוסיף correct_inference
באופן ידני.
לבסוף, במסך וריאנטים, הגדר את וריאנט קבוצת הבקרה שלך לשימוש mnist_v1
ואת קבוצת וריאנט A שלך להשתמש mnist_v2
.
לחץ על כפתור סקירה בפינה השמאלית התחתונה.
מזל טוב, יצרת בהצלחה מבחן A/B עבור שני הדגמים הנפרדים שלך! בדיקת A/B נמצאת כעת במצב טיוטה וניתן להתחיל אותה בכל עת על ידי לחיצה על כפתור "התחל ניסוי".
למבט מקרוב על בדיקות A/B, עיין בתיעוד A/B Testing .
11. מסקנה
במעבדת הקוד הזה, למדת כיצד להחליף נכס tflite מאגד סטטי באפליקציה שלך במודל TFLite נטען דינמית מ-Firebase. למידע נוסף על TFLite ו-Firebase, עיין בדוגמאות אחרות של TFLite ובמדריכי ההתחלה של Firebase.