אם האפליקציה שלך משתמשת במודלים מותאמים אישית של TensorFlow Lite , תוכל להשתמש ב-Firebase ML כדי לפרוס את המודלים שלך. על ידי פריסת מודלים עם Firebase, אתה יכול להקטין את גודל ההורדה הראשונית של האפליקציה שלך ולעדכן את דגמי ה-ML של האפליקציה שלך מבלי לשחרר גרסה חדשה של האפליקציה שלך. בנוסף, עם תצורה מרחוק ובדיקת A/B, אתה יכול להגיש באופן דינמי דגמים שונים לקבוצות שונות של משתמשים.
דגמי TensorFlow Lite
דגמי TensorFlow Lite הם דגמי ML המותאמים להפעלה במכשירים ניידים. כדי להשיג דגם TensorFlow Lite:
- השתמש בדגם בנוי מראש, כגון אחד מהדגמים הרשמיים של TensorFlow Lite .
- המר מודל TensorFlow, מודל Keras או פונקציית בטון ל-TensorFlow Lite.
לפני שאתה מתחיל
- אם עדיין לא עשית זאת, הוסף את Firebase לפרויקט Android שלך .
- בקובץ Gradle של המודול (ברמת האפליקציה) (בדרך כלל
<project>/<app-module>/build.gradle.kts
או<project>/<app-module>/build.gradle
), הוסף את התלות עבור Firebase ML ספריית אנדרואיד של הורדת דגמים. אנו ממליצים להשתמש ב- Firebase Android BoM כדי לשלוט בגירסאות של הספרייה.כמו כן, כחלק מהגדרת הורדת מודל Firebase ML, עליך להוסיף את TensorFlow Lite SDK לאפליקציה שלך.
Kotlin+KTX
dependencies { // Import the BoM for the Firebase platform implementation(platform("com.google.firebase:firebase-bom:32.3.1")) // Add the dependency for the Firebase ML model downloader library // When using the BoM, you don't specify versions in Firebase library dependencies implementation("com.google.firebase:firebase-ml-modeldownloader-ktx")
// Also add the dependency for the TensorFlow Lite library and specify its version implementation("org.tensorflow:tensorflow-lite:2.3.0") }באמצעות Firebase Android BoM , האפליקציה שלך תמיד תשתמש בגרסאות תואמות של ספריות Firebase Android.
(אלטרנטיבי) הוסף תלות בספריית Firebase מבלי להשתמש ב-BoM
אם תבחר שלא להשתמש ב-Firebase BoM, עליך לציין כל גרסת ספריית Firebase בשורת התלות שלה.
שים לב שאם אתה משתמש במספר ספריות Firebase באפליקציה שלך, אנו ממליצים בחום להשתמש ב-BoM לניהול גרסאות ספרייה, מה שמבטיח שכל הגרסאות תואמות.
dependencies { // Add the dependency for the Firebase ML model downloader library // When NOT using the BoM, you must specify versions in Firebase library dependencies implementation("com.google.firebase:firebase-ml-modeldownloader-ktx:24.1.3")
// Also add the dependency for the TensorFlow Lite library and specify its version implementation("org.tensorflow:tensorflow-lite:2.3.0") }Java
dependencies { // Import the BoM for the Firebase platform implementation(platform("com.google.firebase:firebase-bom:32.3.1")) // Add the dependency for the Firebase ML model downloader library // When using the BoM, you don't specify versions in Firebase library dependencies implementation("com.google.firebase:firebase-ml-modeldownloader")
// Also add the dependency for the TensorFlow Lite library and specify its version implementation("org.tensorflow:tensorflow-lite:2.3.0") }באמצעות Firebase Android BoM , האפליקציה שלך תמיד תשתמש בגרסאות תואמות של ספריות Firebase Android.
(אלטרנטיבי) הוסף תלות בספריית Firebase מבלי להשתמש ב-BoM
אם תבחר שלא להשתמש ב-Firebase BoM, עליך לציין כל גרסת ספריית Firebase בשורת התלות שלה.
שים לב שאם אתה משתמש במספר ספריות Firebase באפליקציה שלך, אנו ממליצים בחום להשתמש ב-BoM לניהול גרסאות ספרייה, מה שמבטיח שכל הגרסאות תואמות.
dependencies { // Add the dependency for the Firebase ML model downloader library // When NOT using the BoM, you must specify versions in Firebase library dependencies implementation("com.google.firebase:firebase-ml-modeldownloader:24.1.3")
// Also add the dependency for the TensorFlow Lite library and specify its version implementation("org.tensorflow:tensorflow-lite:2.3.0") }- במניפסט של האפליקציה שלך, הצהיר כי נדרשת הרשאת אינטרנט:
<uses-permission android:name="android.permission.INTERNET" />
1. פרוס את המודל שלך
פרוס את דגמי TensorFlow המותאמים אישית שלך באמצעות קונסולת Firebase או Firebase Admin Python ו-SDKs Node.js. ראה פריסה וניהול מודלים מותאמים אישית .
לאחר שתוסיף מודל מותאם אישית לפרויקט Firebase שלך, תוכל להפנות לדגם באפליקציות שלך באמצעות השם שציינת. בכל עת, תוכל לפרוס דגם חדש של TensorFlow Lite ולהוריד את הדגם החדש למכשירים של המשתמשים על ידי קריאה ל-
getModel()
(ראה להלן).2. הורד את הדגם למכשיר ואתחל מתורגמן TensorFlow Lite
כדי להשתמש בדגם TensorFlow Lite שלך באפליקציה שלך, השתמש תחילה ב-Firebase ML SDK כדי להוריד את הגרסה העדכנית ביותר של הדגם למכשיר. לאחר מכן, הפעל מתורגמן TensorFlow Lite עם המודל.כדי להתחיל את הורדת המודל, קרא לשיטת
getModel()
של הורדת המודל, ציין את השם שהקצית לדגם כשהעלית אותו, האם ברצונך להוריד תמיד את הדגם העדכני ביותר, ואת התנאים שבהם ברצונך לאפשר הורדה.אתה יכול לבחור מתוך שלוש התנהגויות הורדה:
סוג הורדה תיאור LOCAL_MODEL קבל את הדגם המקומי מהמכשיר. אם אין דגם מקומי זמין, זה מתנהג כמו LATEST_MODEL
. השתמש בסוג הורדה זה אם אינך מעוניין לחפש עדכוני דגם. לדוגמה, אתה משתמש ב-Remote Config כדי לאחזר שמות של דגמים ואתה תמיד מעלה דגמים בשמות חדשים (מומלץ).LOCAL_MODEL_UPDATE_IN_BACKGROUND קבל את הדגם המקומי מהמכשיר והתחיל לעדכן את הדגם ברקע. אם אין דגם מקומי זמין, זה מתנהג כמו LATEST_MODEL
.הדגם האחרון קבל את הדגם העדכני ביותר. אם הדגם המקומי הוא הגרסה האחרונה, מחזיר את הדגם המקומי. אחרת, הורד את הדגם העדכני ביותר. התנהגות זו תיחסם עד להורדת הגרסה העדכנית ביותר (לא מומלץ). השתמש בהתנהגות זו רק במקרים שבהם אתה זקוק במפורש לגרסה העדכנית ביותר. עליך להשבית פונקציונליות הקשורה לדגם - לדוגמה, לאפור או להסתיר חלק מהממשק שלך - עד שתאשר שהדגם הורד.
Kotlin+KTX
val conditions = CustomModelDownloadConditions.Builder() .requireWifi() // Also possible: .requireCharging() and .requireDeviceIdle() .build() FirebaseModelDownloader.getInstance() .getModel("your_model", DownloadType.LOCAL_MODEL_UPDATE_IN_BACKGROUND, conditions) .addOnSuccessListener { model: CustomModel? -> // Download complete. Depending on your app, you could enable the ML // feature, or switch from the local model to the remote model, etc. // The CustomModel object contains the local path of the model file, // which you can use to instantiate a TensorFlow Lite interpreter. val modelFile = model?.file if (modelFile != null) { interpreter = Interpreter(modelFile) } }
Java
CustomModelDownloadConditions conditions = new CustomModelDownloadConditions.Builder() .requireWifi() // Also possible: .requireCharging() and .requireDeviceIdle() .build(); FirebaseModelDownloader.getInstance() .getModel("your_model", DownloadType.LOCAL_MODEL_UPDATE_IN_BACKGROUND, conditions) .addOnSuccessListener(new OnSuccessListener<CustomModel>() { @Override public void onSuccess(CustomModel model) { // Download complete. Depending on your app, you could enable the ML // feature, or switch from the local model to the remote model, etc. // The CustomModel object contains the local path of the model file, // which you can use to instantiate a TensorFlow Lite interpreter. File modelFile = model.getFile(); if (modelFile != null) { interpreter = new Interpreter(modelFile); } } });
אפליקציות רבות מתחילות את משימת ההורדה בקוד האתחול שלהן, אך תוכל לעשות זאת בכל שלב לפני שתצטרך להשתמש במודל.
3. בצע הסקה על נתוני קלט
קבל את צורות הקלט והפלט של הדגם שלך
מתורגמן המודל TensorFlow Lite מקבל כקלט ומפיק כפלט מערך רב-ממדי אחד או יותר. מערכים אלה מכילים ערכי
byte
,int
,long
אוfloat
. לפני שתוכל להעביר נתונים למודל או להשתמש בתוצאה שלו, עליך לדעת את המספר והממדים ("צורה") של המערכים שהמודל שלך משתמש בו.אם בנית את המודל בעצמך, או אם פורמט הקלט והפלט של הדגם מתועד, ייתכן שכבר יש לך מידע זה. אם אינך יודע את הצורה וסוג הנתונים של הקלט והפלט של המודל שלך, אתה יכול להשתמש במתורגמן TensorFlow Lite כדי לבדוק את המודל שלך. לדוגמה:
פִּיתוֹן
import tensorflow as tf interpreter = tf.lite.Interpreter(model_path="your_model.tflite") interpreter.allocate_tensors() # Print input shape and type inputs = interpreter.get_input_details() print('{} input(s):'.format(len(inputs))) for i in range(0, len(inputs)): print('{} {}'.format(inputs[i]['shape'], inputs[i]['dtype'])) # Print output shape and type outputs = interpreter.get_output_details() print('\n{} output(s):'.format(len(outputs))) for i in range(0, len(outputs)): print('{} {}'.format(outputs[i]['shape'], outputs[i]['dtype']))
פלט לדוגמה:
1 input(s): [ 1 224 224 3] <class 'numpy.float32'> 1 output(s): [1 1000] <class 'numpy.float32'>
הפעל את המתורגמן
לאחר שקבעתם את הפורמט של הקלט והפלט של המודל שלכם, קבל את נתוני הקלט ובצע כל טרנספורמציה בנתונים הדרושים כדי לקבל קלט של הצורה הנכונה עבור המודל שלך.לדוגמה, אם יש לך מודל סיווג תמונה עם צורת קלט של ערכי נקודה צפה
[1 224 224 3]
, תוכל ליצורByteBuffer
קלט מאובייקטBitmap
כפי שמוצג בדוגמה הבאה:Kotlin+KTX
val bitmap = Bitmap.createScaledBitmap(yourInputImage, 224, 224, true) val input = ByteBuffer.allocateDirect(224*224*3*4).order(ByteOrder.nativeOrder()) for (y in 0 until 224) { for (x in 0 until 224) { val px = bitmap.getPixel(x, y) // Get channel values from the pixel value. val r = Color.red(px) val g = Color.green(px) val b = Color.blue(px) // Normalize channel values to [-1.0, 1.0]. This requirement depends on the model. // For example, some models might require values to be normalized to the range // [0.0, 1.0] instead. val rf = (r - 127) / 255f val gf = (g - 127) / 255f val bf = (b - 127) / 255f input.putFloat(rf) input.putFloat(gf) input.putFloat(bf) } }
Java
Bitmap bitmap = Bitmap.createScaledBitmap(yourInputImage, 224, 224, true); ByteBuffer input = ByteBuffer.allocateDirect(224 * 224 * 3 * 4).order(ByteOrder.nativeOrder()); for (int y = 0; y < 224; y++) { for (int x = 0; x < 224; x++) { int px = bitmap.getPixel(x, y); // Get channel values from the pixel value. int r = Color.red(px); int g = Color.green(px); int b = Color.blue(px); // Normalize channel values to [-1.0, 1.0]. This requirement depends // on the model. For example, some models might require values to be // normalized to the range [0.0, 1.0] instead. float rf = (r - 127) / 255.0f; float gf = (g - 127) / 255.0f; float bf = (b - 127) / 255.0f; input.putFloat(rf); input.putFloat(gf); input.putFloat(bf); } }
לאחר מכן, הקצו
ByteBuffer
גדול מספיק כדי להכיל את הפלט של המודל ולהעביר את מאגר הקלט ומאגר הפלט לשיטתrun()
של מתורגמן TensorFlow Lite. לדוגמה, עבור צורת פלט של[1 1000]
ערכי נקודה צפה:Kotlin+KTX
val bufferSize = 1000 * java.lang.Float.SIZE / java.lang.Byte.SIZE val modelOutput = ByteBuffer.allocateDirect(bufferSize).order(ByteOrder.nativeOrder()) interpreter?.run(input, modelOutput)
Java
int bufferSize = 1000 * java.lang.Float.SIZE / java.lang.Byte.SIZE; ByteBuffer modelOutput = ByteBuffer.allocateDirect(bufferSize).order(ByteOrder.nativeOrder()); interpreter.run(input, modelOutput);
אופן השימוש בפלט תלוי בדגם שבו אתה משתמש.
לדוגמה, אם אתה מבצע סיווג, כשלב הבא, תוכל למפות את האינדקסים של התוצאה לתוויות שהם מייצגים:
Kotlin+KTX
modelOutput.rewind() val probabilities = modelOutput.asFloatBuffer() try { val reader = BufferedReader( InputStreamReader(assets.open("custom_labels.txt"))) for (i in probabilities.capacity()) { val label: String = reader.readLine() val probability = probabilities.get(i) println("$label: $probability") } } catch (e: IOException) { // File not found? }
Java
modelOutput.rewind(); FloatBuffer probabilities = modelOutput.asFloatBuffer(); try { BufferedReader reader = new BufferedReader( new InputStreamReader(getAssets().open("custom_labels.txt"))); for (int i = 0; i < probabilities.capacity(); i++) { String label = reader.readLine(); float probability = probabilities.get(i); Log.i(TAG, String.format("%s: %1.4f", label, probability)); } } catch (IOException e) { // File not found? }
נספח: אבטחת דגם
ללא קשר לאופן שבו תהפוך את דגמי TensorFlow Lite לזמינים ל-Firebase ML, Firebase ML מאחסן אותם בפורמט הפרוטובוף הסטנדרטי בסידרה באחסון מקומי.
בתיאוריה, זה אומר שכל אחד יכול להעתיק את המודל שלך. עם זאת, בפועל, רוב הדגמים הם כל כך ספציפיים ליישום ומעורפלים על ידי אופטימיזציות שהסיכון דומה לזה של מתחרים שמפרקים ומשתמשים מחדש בקוד שלך. עם זאת, עליך להיות מודע לסיכון זה לפני שאתה משתמש במודל מותאם אישית באפליקציה שלך.
ב-Android API רמה 21 (Lollipop) ואילך, הדגם מורד לספרייה שאינה נכללת בגיבוי אוטומטי .
ב-Android API רמה 20 ומעלה, הדגם יורדת לספרייה בשם
com.google.firebase.ml.custom.models
באחסון פנימי פרטי לאפליקציה. אם הפעלת גיבוי קבצים באמצעותBackupAgent
, ייתכן שתבחר לא לכלול את הספרייה הזו.אלא אם צוין אחרת, התוכן של דף זה הוא ברישיון Creative Commons Attribution 4.0 ודוגמאות הקוד הן ברישיון Apache 2.0. לפרטים, ניתן לעיין במדיניות האתר Google Developers. Java הוא סימן מסחרי רשום של חברת Oracle ו/או של השותפים העצמאיים שלה.
עדכון אחרון: 2023-09-20 (שעון UTC).
[{ "type": "thumb-down", "id": "missingTheInformationINeed", "label":"חסרים לי מידע או פרטים" },{ "type": "thumb-down", "id": "tooComplicatedTooManySteps", "label":"התוכן מורכב מדי או עם יותר מדי שלבים" },{ "type": "thumb-down", "id": "outOfDate", "label":"התוכן לא עדכני" },{ "type": "thumb-down", "id": "translationIssue", "label":"בעיה בתרגום" },{ "type": "thumb-down", "id": "samplesCodeIssue", "label":"בעיה בדוגמאות/בקוד" },{ "type": "thumb-down", "id": "otherDown", "label":"סיבה אחרת" }] [{ "type": "thumb-up", "id": "easyToUnderstand", "label":"התוכן קל להבנה" },{ "type": "thumb-up", "id": "solvedMyProblem", "label":"התוכן עזר לי לפתור בעיה" },{ "type": "thumb-up", "id": "otherUp", "label":"סיבה אחרת" }] - במניפסט של האפליקציה שלך, הצהיר כי נדרשת הרשאת אינטרנט: