إذا كان تطبيقك يستخدم تنسيقًا مخصّصًا TensorFlow النماذج البسيطة، يمكنك استخدام Firebase ML لنشر نماذجك. من ونشر نماذج باستخدام Firebase، يمكنك تقليل حجم التنزيل الأولي تطبيقك وتحديث نماذج تعلُّم الآلة في تطبيقك بدون طرح إصدار جديد من تطبيقك. وباستخدام Remote Config وA/B Testing، يمكنك إجراء ما يلي ديناميكيًا: نماذج مختلفة لمجموعات مختلفة من المستخدمين.
طُرز TensorFlow Lite
نماذج TensorFlow Lite هي نماذج تعلُّم الآلة التي تم تحسينها لتعمل على الأجهزة الجوّالة. الأجهزة. للحصول على نموذج TensorFlow Lite، اتّبِع الخطوات التالية:
- استخدم نموذجًا تم إنشاؤه مسبقًا، مثل أحد النماذج رسمي طُرز TensorFlow Lite
- تحويل نموذج TensorFlow أو نموذج Keras أو دالة خرسانية إلى TensorFlow Lite.
قبل البدء
- إذا لم تكن قد فعلت ذلك بالفعل، إضافة Firebase إلى مشروع Android
-
في ملف Gradle للوحدة (على مستوى التطبيق)
(عادةً
<project>/<app-module>/build.gradle.kts
أو<project>/<app-module>/build.gradle
)، إضافة الاعتمادية لمكتبة أدوات تنزيل النماذج Firebase ML لنظام التشغيل Android. ننصح باستخدام Firebase Android BoM للتحكم في إصدارات المكتبة.وكجزء من عملية إعداد أداة تنزيل نموذج Firebase ML، يجب إضافة السمة حزمة تطوير البرامج (SDK) من TensorFlow Lite إلى تطبيقك.
dependencies { // Import the BoM for the Firebase platform implementation(platform("com.google.firebase:firebase-bom:33.5.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، سيستخدم تطبيقك دائمًا إصدارات متوافقة من مكتبات Android في Firebase.
(بديل) إضافة اعتماديات مكتبة 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:25.0.1")
// Also add the dependency for the TensorFlow Lite library and specify its version implementation("org.tensorflow:tensorflow-lite:2.3.0") } - في بيان تطبيقك، عليك الإشارة إلى أنّه يجب الحصول على إذن INTERNET:
<uses-permission android:name="android.permission.INTERNET" />
1- نشر النموذج
انشر نماذج TensorFlow المخصّصة لديك باستخدام وحدة تحكّم "Firebase" أو حزم تطوير البرامج (SDK) الخاصة بمشرفي Firebase وهما Python وNode.js. عرض نشر النماذج المخصَّصة وإدارتها
بعد إضافة نموذج مخصّص إلى مشروعك على Firebase، يمكنك الرجوع إلى
النموذج في تطبيقاتك باستخدام الاسم الذي حددته. يمكنك في أي وقت نشر
نموذج TensorFlow Lite الجديد وتنزيل النموذج الجديد على الأجهزة بواسطة
الاتصال بـ getModel()
(انظر أدناه).
2- تنزيل النموذج على الجهاز وإعداد أداة الترجمة الفورية من TensorFlow Lite
لاستخدام نموذج TensorFlow Lite في تطبيقك، عليك أولاً استخدام حزمة تطوير البرامج (SDK) "Firebase ML" لتنزيل أحدث إصدار من الطراز على الجهاز. ثم، قم بإنشاء مثيل أداة الترجمة الفورية من TensorFlow Lite باستخدام النموذج.لبدء تنزيل النموذج، يمكنك استدعاء طريقة getModel()
لأداة تنزيل النموذج،
تحديد الاسم الذي عينته للنموذج عند تحميله، سواء
ترغب دائمًا في تنزيل أحدث طراز، والحالات التي بموجبها
يريدون السماح بالتنزيل.
يمكنك الاختيار من بين ثلاثة سلوكيات للتنزيل:
نوع عملية التنزيل | الوصف |
---|---|
النموذج المحلي | الحصول على الطراز المحلي من الجهاز
في حال عدم توفُّر نموذج محلي، سيتم
يتصرف مثل LATEST_MODEL . استخدام هذه المسودة
نوع التنزيل إذا لم تكن مهتمًا
البحث عن تحديثات النموذج. على سبيل المثال:
تستخدم "الإعداد عن بُعد" لاسترداد
أسماء النماذج ودائمًا تحميل النماذج
تحت أسماء جديدة (يُنصح بهذا الخيار) |
LOCAL_MODEL_UPDATE_IN_BACKGROUND | الحصول على الطراز المحلي من الجهاز
تحديث النموذج في الخلفية.
في حال عدم توفُّر نموذج محلي، سيتم
يتصرف مثل LATEST_MODEL . |
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 لفحص النموذج. على سبيل المثال:
Python
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
كبيرة بما يكفي لاحتواء ناتج النموذج
تمرير المخزن المؤقت للإدخال والمخزن المؤقت للمخرجات إلى مترجم TensorFlow Lite
طريقة run()
. على سبيل المثال، لشكل إخراج [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 بتنسيق النموذج الأوّلي المتسلسل القياسي في التخزين المحلي.
ومن الناحية النظرية، يعني هذا أنه بإمكان أي شخص نسخ نموذجك. ومع ذلك، عمليًا، تكون معظم النماذج خاصة بالتطبيقات ومشوَّشة بواسطة تتشابه المخاطر مع تلك الخاصة بالمنافسين الذين يقومون بتفكيكها إعادة استخدام التعليمات البرمجية. ومع ذلك، يجب أن تكون على دراية بهذا الخطر قبل استخدام نموذج مخصص في تطبيقك.
في المستوى 21 من واجهة برمجة تطبيقات Android (Lollipop) والإصدارات الأحدث، يتم تنزيل النموذج إلى الدليل استبعاده من ميزة الاحتفاظ بنسخة احتياطية تلقائيًا.
في المستوى 20 من واجهة برمجة تطبيقات Android والإصدارات الأقدم، يتم تنزيل النموذج إلى دليل.
باسم com.google.firebase.ml.custom.models
في خصوصية التطبيق
وحدة التخزين الداخلية. في حال تفعيل الاحتفاظ بنسخة احتياطية من الملفات باستخدام BackupAgent
،
يمكنك اختيار استبعاد هذا الدليل.