Anda dapat menggunakan Kit ML untuk melakukan perangkat inferensi-dalam-perangkat dengan model TensorFlow Lite .
API ini membutuhkan Android SDK level 16 (Jelly Bean) atau yang lebih baru.
Sebelum memulai
- Tambahkan Firebase ke project Android jika belum melakukannya.
- Tambahkan dependensi untuk library Android ML Kit ke file Gradle modul (level aplikasi), biasanya
app/build.gradle
:apply plugin: 'com.android.application' apply plugin: 'com.google.gms.google-services' dependencies { // ... implementation 'com.google.firebase:firebase-ml-model-interpreter:22.0.3' }
- Konversi model TensorFlow yang ingin Anda gunakan ke format TensorFlow Lite. Lihat TOCO: Konverter Optimalisasi TensorFlow Lite.
Menghosting atau memaketkan model
Sebelum dapat menggunakan model TensorFlow Lite untuk inferensi di aplikasi, Anda harus membuat model tersedia untuk ML Kit. ML Kit dapat menggunakan model TensorFlow Lite yang dihosting dari jarak jauh menggunakan Firebase, dipaketkan dengan biner aplikasi, atau keduanya.
Dengan menghosting model di Firebase, Anda dapat mengupdate model tanpa merilis versi baru aplikasi. Anda juga dapat menggunakan Remote Config dan A/B Testing untuk secara dinamis menyalurkan berbagai model ke berbagai kelompok pengguna.
Jika memilih untuk hanya menyediakan model dengan menghostingnya di Firebase, dan tidak memaketkannya dengan aplikasi, Anda dapat mengurangi ukuran download awal aplikasi. Namun, ingat bahwa jika model tidak dipaketkan dengan aplikasi, fungsi yang terkait dengan model tidak akan tersedia sebelum aplikasi mendownload model untuk pertama kalinya.
Dengan memaketkan model dengan aplikasi, Anda dapat memastikan bahwa fitur ML pada aplikasi tetap berfungsi jika model yang dihosting Firebase tidak tersedia.
Menghosting model di Firebase
Untuk menghosting model TensorFlow Lite di Firebase:
- Di bagian ML Kit pada Firebase console, klik tab Custom.
- Klik Add custom model (atau Add another model).
- Tentukan nama yang akan digunakan untuk mengidentifikasi model Anda di project Firebase,
lalu upload file model TensorFlow Lite
(biasanya diakhiri dengan
.tflite
atau.lite
). - Di manifes aplikasi Anda, deklarasikan bahwa izin INTERNET diperlukan:
<uses-permission android:name="android.permission.INTERNET" />
Setelah menambahkan model kustom ke project Firebase, Anda dapat mereferensikan model tersebut di aplikasi menggunakan nama yang Anda tentukan. Anda dapat mengupload model TensorFlow Lite baru kapan saja, dan aplikasi akan mendownloadnya, lalu mulai menggunakannya setelah aplikasi dimulai ulang. Anda dapat menentukan kondisi perangkat yang diperlukan aplikasi untuk mencoba mengupdate model (lihat di bawah ini).
Memaketkan model dengan aplikasi
Untuk memaketkan model TensorFlow Lite dengan aplikasi, salin file model
(biasanya diakhiri dengan .tflite
atau .lite
) ke folder assets/
aplikasi. (Anda mungkin perlu
membuat folder terlebih dahulu dengan mengklik kanan folder app/
, lalu mengklik
Baru > Folder > Folder Aset.)
Kemudian, tambahkan hal berikut ini ke file build.gradle
aplikasi untuk memastikan agar Gradle
tidak mengompresi model saat mem-build aplikasi:
android {
// ...
aaptOptions {
noCompress "tflite" // Your model's file extension: "tflite", "lite", etc.
}
}
File model akan disertakan ke dalam paket aplikasi dan tersedia untuk ML Kit sebagai aset mentah.
Memuat model
Untuk menggunakan model TensorFlow Lite di aplikasi, pertama-tama konfigurasi ML Kit dengan lokasi tempat model tersebut tersedia: menggunakan Firebase dari jarak jauh, di penyimpanan lokal, atau keduanya. Jika ML Kit dikonfigurasi dengan kedua model, Anda dapat menggunakan model jarak jauh jika tersedia, dan kembali ke model yang disimpan secara lokal jika model jarak jauh tidak tersedia.Mengonfigurasi model yang dihosting Firebase
Jika Anda menghosting model dengan Firebase, buat
objek FirebaseCustomRemoteModel
dengan menentukan nama yang ditetapkan pada model ketika Anda menguploadnya:
Java
FirebaseCustomRemoteModel remoteModel =
new FirebaseCustomRemoteModel.Builder("your_model").build();
Kotlin
val remoteModel = FirebaseCustomRemoteModel.Builder("your_model").build()
Kemudian, mulai tugas download model, dengan menentukan kondisi yang Anda inginkan untuk mengizinkan download. Jika model tidak ada di perangkat, atau jika versi model yang lebih baru tersedia, tugas ini akan mendownload model dari Firebase secara asinkron:
Java
FirebaseModelDownloadConditions conditions = new FirebaseModelDownloadConditions.Builder()
.requireWifi()
.build();
FirebaseModelManager.getInstance().download(remoteModel, conditions)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
// Success.
}
});
Kotlin
val conditions = FirebaseModelDownloadConditions.Builder()
.requireWifi()
.build()
FirebaseModelManager.getInstance().download(remoteModel, conditions)
.addOnCompleteListener {
// Success.
}
Banyak aplikasi memulai tugas download dalam kode inisialisasinya, tetapi Anda dapat melakukannya kapan saja sebelum menggunakan model.
Mengonfigurasi model lokal
Jika memaketkan model dengan aplikasi, buat objek FirebaseCustomLocalModel
, dengan
menyebutkan nama file model TensorFlow Lite:
Java
FirebaseCustomLocalModel localModel = new FirebaseCustomLocalModel.Builder()
.setAssetFilePath("your_model.tflite")
.build();
Kotlin
val localModel = FirebaseCustomLocalModel.Builder()
.setAssetFilePath("your_model.tflite")
.build()
Membuat penafsir dari model
Setelah mengonfigurasi sumber model, buat objek FirebaseModelInterpreter
dari salah satu sumber tersebut.
Jika hanya memiliki model yang dipaketkan secara lokal,
cukup buat penafsir dari objek FirebaseCustomLocalModel
:
Java
FirebaseModelInterpreter interpreter;
try {
FirebaseModelInterpreterOptions options =
new FirebaseModelInterpreterOptions.Builder(localModel).build();
interpreter = FirebaseModelInterpreter.getInstance(options);
} catch (FirebaseMLException e) {
// ...
}
Kotlin
val options = FirebaseModelInterpreterOptions.Builder(localModel).build()
val interpreter = FirebaseModelInterpreter.getInstance(options)
Jika Anda memiliki model yang dihosting dari jarak jauh, Anda harus memeriksa apakah model tersebut sudah didownload sebelum menjalankannya. Anda dapat memeriksa status tugas
download model menggunakan metode isModelDownloaded()
pengelola model.
Meskipun hanya perlu memastikan hal ini sebelum menjalankan penafsir, jika Anda memiliki model yang dihosting dari jarak jauh dan model yang dipaketkan secara lokal, mungkin pemeriksaan ini perlu dilakukan saat membuat instance penafsir model: buat penafsir dari model jarak jauh jika model tersebut sudah didownload, dan dari model lokal jika belum didownload.
Java
FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
.addOnSuccessListener(new OnSuccessListener<Boolean>() {
@Override
public void onSuccess(Boolean isDownloaded) {
FirebaseModelInterpreterOptions options;
if (isDownloaded) {
options = new FirebaseModelInterpreterOptions.Builder(remoteModel).build();
} else {
options = new FirebaseModelInterpreterOptions.Builder(localModel).build();
}
FirebaseModelInterpreter interpreter = FirebaseModelInterpreter.getInstance(options);
// ...
}
});
Kotlin
FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
.addOnSuccessListener { isDownloaded ->
val options =
if (isDownloaded) {
FirebaseModelInterpreterOptions.Builder(remoteModel).build()
} else {
FirebaseModelInterpreterOptions.Builder(localModel).build()
}
val interpreter = FirebaseModelInterpreter.getInstance(options)
}
Jika Anda hanya memiliki model yang dihosting dari jarak jauh, Anda harus menonaktifkan fungsionalitas terkait model, misalnya membuat sebagian UI berwarna abu-abu atau menyembunyikannya, hingga Anda mengonfirmasi model tersebut telah didownload. Anda dapat melakukannya dengan menambahkan pemroses
ke metode download()
pengelola model:
Java
FirebaseModelManager.getInstance().download(remoteModel, conditions)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void v) {
// Download complete. Depending on your app, you could enable
// the ML feature, or switch from the local model to the remote
// model, etc.
}
});
Kotlin
FirebaseModelManager.getInstance().download(remoteModel, conditions)
.addOnCompleteListener {
// Download complete. Depending on your app, you could enable the ML
// feature, or switch from the local model to the remote model, etc.
}
Menentukan input dan output model
Selanjutnya, konfigurasi format input dan output penafsir model.
Model TensorFlow Lite mengambil satu atau beberapa array multidimensi sebagai input
dan menghasilkannya sebagai output. Array ini berisi nilai
byte
, int
, long
, atau float
. Anda harus mengonfigurasi
ML Kit dengan jumlah dan dimensi ("bentuk") array yang
digunakan oleh model Anda.
Jika tidak tahu bentuk dan tipe data input dan output model, Anda dapat menggunakan penafsir TensorFlow Lite Python untuk memeriksa model. Misalnya:
import tensorflow as tf interpreter = tf.lite.Interpreter(model_path="my_model.tflite") interpreter.allocate_tensors() # Print input shape and type print(interpreter.get_input_details()[0]['shape']) # Example: [1 224 224 3] print(interpreter.get_input_details()[0]['dtype']) # Example: <class 'numpy.float32'> # Print output shape and type print(interpreter.get_output_details()[0]['shape']) # Example: [1 1000] print(interpreter.get_output_details()[0]['dtype']) # Example: <class 'numpy.float32'>
Setelah menentukan format input dan output model, Anda dapat mengonfigurasi penafsir model aplikasi dengan membuat objek FirebaseModelInputOutputOptions
.
Misalnya, model klasifikasi gambar floating point mungkin akan mengambil array
Nx224x224x3 berisi nilai float
sebagai input, yang mewakili sekumpulan gambar
N 224x224 tiga saluran (RGB), dan menghasilkan output berupa daftar berisi 1.000 nilai float
.
Setiap nilai mewakili probabilitas bahwa gambar tersebut merupakan anggota
salah satu di antara 1.000 kategori yang diprediksi oleh model.
Untuk model seperti itu, Anda akan mengonfigurasi input dan output penafsir model, seperti yang ditunjukkan di bawah ini:
Java
FirebaseModelInputOutputOptions inputOutputOptions = new FirebaseModelInputOutputOptions.Builder() .setInputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{1, 224, 224, 3}) .setOutputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{1, 5}) .build();
Kotlin
val inputOutputOptions = FirebaseModelInputOutputOptions.Builder() .setInputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 224, 224, 3)) .setOutputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 5)) .build()
Melakukan inferensi pada data input
Terakhir, untuk melakukan inferensi menggunakan model, dapatkan data input Anda, dan jalankan transformasi pada data yang diperlukan untuk mendapatkan array input bentuk yang tepat untuk model Anda.Misalnya, jika memiliki model klasifikasi gambar dengan bentuk input
nilai floating point [1 224 224 3], Anda dapat menghasilkan array input
dari objek Bitmap
seperti yang ditunjukkan dalam contoh berikut:
Java
Bitmap bitmap = getYourInputImage(); bitmap = Bitmap.createScaledBitmap(bitmap, 224, 224, true); int batchNum = 0; float[][][][] input = new float[1][224][224][3]; for (int x = 0; x < 224; x++) { for (int y = 0; y < 224; y++) { int pixel = bitmap.getPixel(x, y); // Normalize channel values to [-1.0, 1.0]. This requirement varies by // model. For example, some models might require values to be normalized // to the range [0.0, 1.0] instead. input[batchNum][x][y][0] = (Color.red(pixel) - 127) / 128.0f; input[batchNum][x][y][1] = (Color.green(pixel) - 127) / 128.0f; input[batchNum][x][y][2] = (Color.blue(pixel) - 127) / 128.0f; } }
Kotlin
val bitmap = Bitmap.createScaledBitmap(yourInputImage, 224, 224, true) val batchNum = 0 val input = Array(1) { Array(224) { Array(224) { FloatArray(3) } } } for (x in 0..223) { for (y in 0..223) { val pixel = bitmap.getPixel(x, y) // Normalize channel values to [-1.0, 1.0]. This requirement varies by // model. For example, some models might require values to be normalized // to the range [0.0, 1.0] instead. input[batchNum][x][y][0] = (Color.red(pixel) - 127) / 255.0f input[batchNum][x][y][1] = (Color.green(pixel) - 127) / 255.0f input[batchNum][x][y][2] = (Color.blue(pixel) - 127) / 255.0f } }
Kemudian, buat objek FirebaseModelInputs
dengan data input Anda, dan teruskan objek tersebut dengan spesifikasi model input dan output ke metode run
penafsir model:
Java
FirebaseModelInputs inputs = new FirebaseModelInputs.Builder() .add(input) // add() as many input arrays as your model requires .build(); firebaseInterpreter.run(inputs, inputOutputOptions) .addOnSuccessListener( new OnSuccessListener<FirebaseModelOutputs>() { @Override public void onSuccess(FirebaseModelOutputs result) { // ... } }) .addOnFailureListener( new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Task failed with an exception // ... } });
Kotlin
val inputs = FirebaseModelInputs.Builder() .add(input) // add() as many input arrays as your model requires .build() firebaseInterpreter.run(inputs, inputOutputOptions) .addOnSuccessListener { result -> // ... } .addOnFailureListener { e -> // Task failed with an exception // ... }
Jika panggilan berhasil, Anda bisa mendapatkan output dengan memanggil metode getOutput()
objek yang diteruskan ke pemroses peristiwa sukses. Contoh:
Java
float[][] output = result.getOutput(0); float[] probabilities = output[0];
Kotlin
val output = result.getOutput<Array<FloatArray>>(0) val probabilities = output[0]
Cara penggunaan output bergantung pada model yang Anda gunakan.
Misalnya, jika melakukan klasifikasi, sebagai langkah berikutnya, Anda mungkin dapat memetakan indeks hasil ke label yang diwakilinya:
Java
BufferedReader reader = new BufferedReader( new InputStreamReader(getAssets().open("retrained_labels.txt"))); for (int i = 0; i < probabilities.length; i++) { String label = reader.readLine(); Log.i("MLKit", String.format("%s: %1.4f", label, probabilities[i])); }
Kotlin
val reader = BufferedReader( InputStreamReader(assets.open("retrained_labels.txt"))) for (i in probabilities.indices) { val label = reader.readLine() Log.i("MLKit", String.format("%s: %1.4f", label, probabilities[i])) }
Lampiran: Keamanan model
Cara apa pun yang Anda lakukan guna menyediakan model TensorFlow Lite untuk ML Kit, ML Kit akan menyimpannya dalam format protobuf berseri standar di penyimpanan lokal.
Secara teori, ini artinya siapa saja dapat menyalin model Anda. Namun, dalam praktiknya, sebagian besar model bersifat spesifik aplikasi dan di-obfuscate melalui pengoptimalan sehingga risikonya serupa dengan jika pesaing membongkar dan menggunakan kembali kode Anda. Meskipun demikian, Anda harus menyadari risiko ini sebelum menggunakan model kustom di aplikasi Anda.
Pada Android API level 21 (Lollipop) dan yang lebih baru, model didownload ke direktori yang dikecualikan dari pencadangan otomatis.
Pada Android API level 20 dan yang lebih lama, model didownload
ke direktori bernama com.google.firebase.ml.custom.models
di penyimpanan internal
pribadi aplikasi. Jika mengaktifkan pencadangan file menggunakan BackupAgent
,
Anda dapat memilih untuk tidak menyertakan direktori ini.