Catch up on everthing we announced at this year's Firebase Summit. Learn more

Android'de özel bir TensorFlow Lite modeli kullanın

Uygulamanız özel kullanıyorsa TensorFlow Lite modelleri, Modelleri dağıtmak için Firebase ML kullanabilirsiniz. Modelleri Firebase ile dağıtarak, uygulamanızın ilk indirme boyutunu küçültebilir ve uygulamanızın yeni bir sürümünü yayınlamadan uygulamanızın ML modellerini güncelleyebilirsiniz. Ayrıca Remote Config ve A/B Testing ile farklı modelleri farklı kullanıcı gruplarına dinamik olarak sunabilirsiniz.

TensorFlow Lite modelleri

TensorFlow Lite modelleri, mobil cihazlarda çalışacak şekilde optimize edilmiş ML modelleridir. Bir TensorFlow Lite modeli almak için:

Sen başlamadan önce

  1. Eğer henüz yapmadıysanız, Android projeye Firebase ekleyin .
  2. Kullanılması Firebase Android Bom , senin modülü (uygulama düzeyinde) Gradle dosyası (genellikle Android kütüphanesinde indirici Firebase ML model için bağımlılık beyan app/build.gradle ).

    Ayrıca, Firebase ML model indiricisini kurmanın bir parçası olarak, uygulamanıza TensorFlow Lite SDK'yı eklemeniz gerekir.

    Java

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:29.0.1')
    
        // Declare 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 declare the dependency for the TensorFlow Lite library and specify its version implementation 'org.tensorflow:tensorflow-lite:2.3.0'
    }

    Kullanarak Firebase Android Bom , uygulamanızın her zaman Firebase Android kütüphanelerin uyumlu versiyonlarını kullanacak.

    (Alternatif) Bom kullanmadan Firebase kütüphane bağımlılıklarını beyan

    Firebase Malzeme Listesini kullanmamayı seçerseniz, her bir Firebase kitaplık sürümünü bağımlılık satırında belirtmeniz gerekir.

    Eğer uygulamanızda birden Firebase kitaplıkları kullanırsanız, biz çok tüm versiyonlar uyumlu olmasını sağlar kütüphane sürümlerini yönetmek için Bom kullanmanızı öneririz olduğunu unutmayın.

    dependencies {
        // Declare 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.0.1'
    // Also declare the dependency for the TensorFlow Lite library and specify its version implementation 'org.tensorflow:tensorflow-lite:2.3.0'
    }

    Kotlin+KTX

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:29.0.1')
    
        // Declare 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 declare the dependency for the TensorFlow Lite library and specify its version implementation 'org.tensorflow:tensorflow-lite:2.3.0'
    }

    Kullanarak Firebase Android Bom , uygulamanızın her zaman Firebase Android kütüphanelerin uyumlu versiyonlarını kullanacak.

    (Alternatif) Bom kullanmadan Firebase kütüphane bağımlılıklarını beyan

    Firebase Malzeme Listesini kullanmamayı seçerseniz, her bir Firebase kitaplık sürümünü bağımlılık satırında belirtmeniz gerekir.

    Eğer uygulamanızda birden Firebase kitaplıkları kullanırsanız, biz çok tüm versiyonlar uyumlu olmasını sağlar kütüphane sürümlerini yönetmek için Bom kullanmanızı öneririz olduğunu unutmayın.

    dependencies {
        // Declare 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.0.1'
    // Also declare the dependency for the TensorFlow Lite library and specify its version implementation 'org.tensorflow:tensorflow-lite:2.3.0'
    }
  3. : Uygulamanızın manifest, İNTERNET izni gerekli olduğunu beyan olarak
    <uses-permission android:name="android.permission.INTERNET" />

1. Modelinizi dağıtın

Firebase konsolunu veya Firebase Admin Python ve Node.js SDK'larını kullanarak özel TensorFlow modellerinizi dağıtın. Bkz dağıtma ve özel modeller yönetmek .

Firebase projenize özel bir model ekledikten sonra, belirttiğiniz adı kullanarak uygulamalarınızda modele başvurabilirsiniz. Herhangi bir zamanda, yeni bir TensorFlow Lite modeli dağıtabilir ve arayarak kullanıcıların cihazlarında üzerine yeni modeli indirmek getModel() (aşağıya bakınız).

2. Modeli cihaza indirin ve bir TensorFlow Lite yorumlayıcısını başlatın

TensorFlow Lite modelinizi uygulamanızda kullanmak için öncelikle modelin en son sürümünü cihaza indirmek için Firebase ML SDK'yı kullanın. Ardından, modelle bir TensorFlow Lite yorumlayıcısının örneğini oluşturun.

Model İndirme işlemini başlatmak için bir model Downloader çağrı getModel() her zaman en son modeli indirmek isteyip, onu yükleyen ve koşullarınız indirmeye izin vermek istediğinizde modeli atanan adı belirterek, yöntem.

Üç indirme davranışından birini seçebilirsiniz:

İndirme türü Açıklama
LOCAL_MODEL Cihazdan yerel modeli alın. Hiç yerel modeli gibi bu davranacağını varsa LATEST_MODEL . Model güncellemelerini kontrol etmekle ilgilenmiyorsanız bu indirme türünü kullanın. Örneğin, model adlarını almak için Remote Config kullanıyorsunuz ve modelleri her zaman yeni adlar altında yüklüyorsunuz (önerilir).
LOCAL_MODEL_UPDATE_IN_BACKGROUND Cihazdan yerel modeli alın ve arka planda modeli güncellemeye başlayın. Hiç yerel modeli gibi bu davranacağını varsa LATEST_MODEL .
SON MODEL En son modeli alın. Yerel model en son sürümse, yerel modeli döndürür. Aksi takdirde, en son modeli indirin. Bu davranış, en son sürüm indirilene kadar engellenir (önerilmez). Bu davranışı yalnızca en son sürüme açıkça ihtiyaç duyduğunuz durumlarda kullanın.

Modelin indirildiğini onaylayana kadar modelle ilgili işlevleri devre dışı bırakmalısınız (örneğin, kullanıcı arayüzünüzün gri renkte görünmesi veya bir kısmını gizleme).

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);
        }
      }
    });

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)
            }
        }

Birçok uygulama indirme görevini başlatma kodunda başlatır, ancak bunu modeli kullanmaya ihtiyaç duymadan önce herhangi bir noktada yapabilirsiniz.

3. Girdi verileri üzerinde çıkarım gerçekleştirin

Modelinizin giriş ve çıkış şekillerini alın

TensorFlow Lite model yorumlayıcısı girdi olarak alır ve çıktı olarak bir veya daha fazla çok boyutlu dizi üretir. Bu diziler birini içeren byte , int , long ya da float değerleri. Bir modele veri aktarmadan veya sonucunu kullanmadan önce, modelinizin kullandığı dizilerin sayısını ve boyutlarını ("şekil") bilmeniz gerekir.

Modeli kendiniz oluşturduysanız veya modelin giriş ve çıkış biçimi belgelenmişse, bu bilgilere zaten sahip olabilirsiniz. Modelinizin giriş ve çıkışının şeklini ve veri türünü bilmiyorsanız, modelinizi incelemek için TensorFlow Lite yorumlayıcısını kullanabilirsiniz. Örneğin:

piton

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']))

Örnek çıktı:

1 input(s):
[  1 224 224   3] <class 'numpy.float32'>

1 output(s):
[1 1000] <class 'numpy.float32'>

Tercümanı çalıştırın

Modelinizin girdi ve çıktısının biçimini belirledikten sonra, girdi verilerinizi alın ve modeliniz için doğru şekle sahip bir girdi elde etmek için gerekli olan tüm dönüşümleri veriler üzerinde gerçekleştirin.

Eğer bir giriş şekle sahip olan bir görüntü sınıflandırma modeli varsa, örneğin, [1 224 224 3] kayan nokta değerleri, bir giriş oluşturabilir ByteBuffer bir gelen Bitmap aşağıdaki örnekte gösterildiği gibi, nesne:

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);
    }
}

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)
    }
}

Daha sonra, bir tahsis ByteBuffer model çıkış içerir ve TensorFlow Lite tercüman giriş tamponu ve çıkış tamponu geçmek için yeterince büyük bir run() metodu. Örneğin, bir çıkış şekli için [1 1000] kayan nokta değerleri:

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

val bufferSize = 1000 * java.lang.Float.SIZE / java.lang.Byte.SIZE
val modelOutput = ByteBuffer.allocateDirect(bufferSize).order(ByteOrder.nativeOrder())
interpreter?.run(input, modelOutput)

Çıktıyı nasıl kullandığınız, kullandığınız modele bağlıdır.

Örneğin, sınıflandırma yapıyorsanız, sonraki adım olarak sonucun dizinlerini temsil ettikleri etiketlerle eşleyebilirsiniz:

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?
}

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?
}

Ek: Model güvenliği

TensorFlow Lite modellerinizi Firebase ML için nasıl kullanılabilir hale getirdiğinizden bağımsız olarak, Firebase ML bunları yerel depolamada standart serileştirilmiş protobuf biçiminde saklar.

Teoride bu, herkesin modelinizi kopyalayabileceği anlamına gelir. Bununla birlikte, pratikte, çoğu model uygulamaya o kadar özeldir ve optimizasyonlarla karıştırılmıştır ki, risk rakiplerinizin kodunuzu söküp yeniden kullanma riskine benzer. Yine de, uygulamanızda özel bir model kullanmadan önce bu riskin farkında olmalısınız.

Android API düzeyinde 21 (Lolipop) ve daha yeni günü, modeli bir dizine indirilir otomatik yedekleme dışında .

Android API düzeyinde 20 ve üstü günü, modeli bir dizin adında indirilir com.google.firebase.ml.custom.models app-özel dahili depolama. Eğer kullanarak dosya yedekleme etkin olursa BackupAgent , bu dizini dışlamak tercih edebilir.