Menggunakan model TensorFlow Lite untuk inferensi dengan ML Kit di Android

Anda dapat menggunakan ML Kit untuk melakukan inferensi di perangkat dengan model TensorFlow Lite.

API ini membutuhkan SDK Android level 16 (Jelly Bean) atau yang lebih baru.

Lihat sampel quickstart ML Kit di GitHub untuk mengetahui contoh penggunaan API ini, atau coba gunakan codelab.

Sebelum memulai

  1. Jika Anda belum menambahkan Firebase ke aplikasi, lakukan dengan mengikuti langkah-langkahnya di panduan memulai.
  2. Sertakan dependensi untuk ML Kit dalam file build.gradle pada level aplikasi Anda:
    dependencies {
      // ...
    
      implementation 'com.google.firebase:firebase-ml-model-interpreter:17.0.3'
    }
    
  3. Konversikan model TensorFlow yang ingin Anda gunakan ke dalam format TensorFlow Lite. Baca bagian TOCO: Pengonversi Pengoptimalan TensorFlow Lite.

Menghosting atau membuat paket model Anda

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, dan Anda dapat menggunakan Remote Config serta Pengujian A/B untuk melayani berbagai model secara dinamis ke kumpulan pengguna yang berbeda.

Jika Anda memilih untuk hanya menyediakan model dengan menghostingnya dengan Firebase, dan tidak memaketkannya dengan aplikasi Anda, Anda dapat mengurangi ukuran download awal aplikasi Anda. Namun, perlu diingat bahwa jika model tidak dipaketkan dengan aplikasi Anda, fungsi yang terkait dengan model tidak akan tersedia hingga aplikasi Anda mendownload model untuk pertama kalinya.

Dengan memaketkan model dengan aplikasi, Anda dapat memastikan bahwa fitur ML pada aplikasi Anda masih berfungsi jika model yang dihosting Firebase tidak tersedia.

Menghosting model di Firebase

Untuk menghosting model TensorFlow Lite di Firebase:

  1. Di bagian ML Kit pada Firebase console, klik tab Kustom.
  2. Klik Tambahkan model kustom (atau Tambahkan model lain).
  3. Tentukan nama yang akan digunakan untuk mengidentifikasi model Anda di project Firebase, lalu upload file model TensorFlow Lite (biasanya diakhiri dengan .tflite atau .lite ).
  4. Di manifes aplikasi Anda, nyatakan 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 file model TensorFlow Lite baru kapan saja untuk sebuah model, dan aplikasi Anda akan mendownload model baru itu dan mulai menggunakannya saat berikutnya aplikasi dimulai ulang. Anda dapat menentukan kondisi perangkat yang diperlukan aplikasi untuk mencoba mengupdate model (lihat di bawah ini).

Paketkan model dengan aplikasi

Untuk membuat paket model TensorFlow Lite dengan aplikasi Anda, salin file model (biasanya diakhiri dengan .tflite atau .lite) ke folder assets/ aplikasi Anda. (Anda mungkin perlu membuat folder tersebut terlebih dahulu dengan mengklik kanan folder app/, lalu mengklik Baru > Folder > Folder Aset.)

Kemudian, tambahkan baris berikut ke file build.gradle aplikasi Anda untuk memastikan Gradle tidak mengompresi model saat membuat aplikasi:

android {

    // ...

    aaptOptions {
        noCompress "tflite"  // Your model's file extension: "tflite", "lite", etc.
    }
}

File model akan dimasukkan ke dalam paket aplikasi dan tersedia untuk ML Kit sebagai aset mentah.

Memuat model

Untuk menggunakan model TensorFlow Lite Anda di aplikasi, pertama-tama konfigurasikan ML Kit dengan lokasi di mana model Anda tersedia: di cloud menggunakan Firebase, di penyimpanan lokal, atau keduanya. Jika Anda menetapkan sumber model cloud dan sumber model lokal, ML Kit akan menggunakan model cloud jika tersedia, dan kembali ke model yang disimpan secara lokal jika sumber cloud tidak tersedia.

Mengonfigurasi sumber model yang dihosting Firebase

Jika Anda menghosting model dengan Firebase, buat objek FirebaseCloudModelSource, yang menentukan nama yang ditetapkan pada model ketika menguploadnya, serta kondisi saat ML Kit harus mendownload model di awal dan saat update tersedia.

Java
Android

FirebaseModelDownloadConditions.Builder conditionsBuilder =
        new FirebaseModelDownloadConditions.Builder().requireWifi();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    // Enable advanced conditions on Android Nougat and newer.
    conditionsBuilder = conditionsBuilder
            .requireCharging()
            .requireDeviceIdle();
}
FirebaseModelDownloadConditions conditions = conditionsBuilder.build();

// Build a FirebaseCloudModelSource object by specifying the name you assigned the model
// when you uploaded it in the Firebase console.
FirebaseCloudModelSource cloudSource = new FirebaseCloudModelSource.Builder("my_cloud_model")
        .enableModelUpdates(true)
        .setInitialDownloadConditions(conditions)
        .setUpdatesDownloadConditions(conditions)
        .build();
FirebaseModelManager.getInstance().registerCloudModelSource(cloudSource);

Kotlin
Android

var conditionsBuilder: FirebaseModelDownloadConditions.Builder =
        FirebaseModelDownloadConditions.Builder().requireWifi()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    // Enable advanced conditions on Android Nougat and newer.
    conditionsBuilder = conditionsBuilder
            .requireCharging()
            .requireDeviceIdle()
}
val conditions = conditionsBuilder.build()

// Build a FirebaseCloudModelSource object by specifying the name you assigned the model
// when you uploaded it in the Firebase console.
val cloudSource = FirebaseCloudModelSource.Builder("my_cloud_model")
        .enableModelUpdates(true)
        .setInitialDownloadConditions(conditions)
        .setUpdatesDownloadConditions(conditions)
        .build()
FirebaseModelManager.getInstance().registerCloudModelSource(cloudSource)

Mengonfigurasi sumber model lokal

Jika Anda memaketkan model dengan aplikasi, buat objek FirebaseLocalModelSource, yang menentukan nama file model TensorFlow Lite dan menetapkan nama pada model yang akan digunakan pada langkah berikutnya.

Java
Android

FirebaseLocalModelSource localSource =
        new FirebaseLocalModelSource.Builder("my_local_model")  // Assign a name to this model
                .setAssetFilePath("my_model.tflite")
                .build();
FirebaseModelManager.getInstance().registerLocalModelSource(localSource);

Kotlin
Android

val localSource = FirebaseLocalModelSource.Builder("my_local_model") // Assign a name to this model
        .setAssetFilePath("my_model.tflite")
        .build()
FirebaseModelManager.getInstance().registerLocalModelSource(localSource)

Membuat penafsir dari sumber model Anda

Setelah mengonfigurasi sumber model Anda, buat objek FirebaseModelOptions dengan nama sumber cloud, sumber lokal, atau keduanya, lalu gunakan untuk mendapatkan instance FirebaseModelInterpreter.

Java
Android

FirebaseModelOptions options = new FirebaseModelOptions.Builder()
        .setCloudModelName("my_cloud_model")
        .setLocalModelName("my_local_model")
        .build();
FirebaseModelInterpreter firebaseInterpreter =
        FirebaseModelInterpreter.getInstance(options);

Kotlin
Android

val options = FirebaseModelOptions.Builder()
        .setCloudModelName("my_cloud_model")
        .setLocalModelName("my_local_model")
        .build()
val interpreter = FirebaseModelInterpreter.getInstance(options)

Menentukan input dan output model

Selanjutnya, konfigurasikan 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 Anda tidak tahu bentuk dan tipe data dari 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, konfigurasikan penafsir model aplikasi Anda dengan membuat objek FirebaseModelInputOutputOptions.

Sebagai contoh, 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 1.000 nilai float. Setiap nilai ini mewakili probabilitas bahwa gambar adalah anggota dari salah satu dari 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
Android

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
Android

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 dari bentuk yang tepat untuk model Anda.

Misalnya, jika Anda memiliki model klasifikasi gambar dengan bentuk input dari nilai floating-point [1 224 224 3], Anda bisa menghasilkan array masukan dari objek Bitmap, seperti yang ditunjukkan pada contoh berikut:

Java
Android

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
Android

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 bersama dengan spesifikasi input dan output model ke metode run penafsir model:

Java
Android

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
Android

val inputs = FirebaseModelInputs.Builder()
        .add(input) // add() as many input arrays as your model requires
        .build()
firebaseInterpreter.run(inputs, inputOutputOptions)
        .addOnSuccessListener { result ->
            // ...
        }
        .addOnFailureListener(
                object : OnFailureListener {
                    override fun onFailure(e: Exception) {
                        // Task failed with an exception
                        // ...
                    }
                })

Jika panggilan berhasil, Anda bisa mendapatkan output dengan memanggil metode getOutput() dari objek yang diteruskan ke listener yang berhasil. Misalnya:

Java
Android

float[][] output = result.getOutput(0);
float[] probabilities = output[0];

Kotlin
Android

val output = result.getOutput<Array<FloatArray>>(0)
val probabilities = output[0]

Cara penggunaan output bergantung pada model yang Anda gunakan.

Misalnya, jika Anda melakukan klasifikasi, sebagai langkah berikutnya, Anda mungkin dapat memetakan indeks hasil ke label yang diwakilinya.

Java
Android

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
Android

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

Terlepas dari bagaimana Anda menyediakan model TensorFlow Lite untuk ML Kit, ML Kit akan menyimpannya dalam format protobuf serial standar di penyimpanan lokal.

Secara teori, ini berarti bahwa siapa saja dapat menyalin model Anda. Namun, dalam praktiknya, sebagian besar model bersifat khusus aplikasi dan dikaburkan oleh 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 backup 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 backup file menggunakan BackupAgent, Anda dapat memilih untuk tidak menyertakan direktori ini.

Kirim masukan tentang...

Butuh bantuan? Kunjungi halaman dukungan kami.