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

Android'de ML Kit ile çıkarım için bir TensorFlow Lite modeli kullanın

Bir ile Cihazdaki çıkarım gerçekleştirmek için ML Kit kullanabilirsiniz TensorFlow Lite modeli.

Bu API, Android SDK seviye 16 (Jelly Bean) veya daha yenisini gerektirir.

Sen başlamadan önce

  1. Eğer henüz yapmadıysanız, Android projeye Firebase ekleyin .
  2. Senin modülü (uygulama düzeyinde) Gradle dosyası (genellikle ML Kiti Android kütüphaneler için bağımlılıkları ekleyin 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'
    }
    
  3. Kullanmak istediğiniz TensorFlow modelini TensorFlow Lite formatına dönüştürün. Bkz TensorFlow Lite Optimizasyon Converter: Toko .

Modelinizi barındırın veya paketleyin

Uygulamanızda çıkarım için bir TensorFlow Lite modeli kullanmadan önce modeli ML Kit'e sunmalısınız. ML Kit, uygulama ikili programıyla birlikte verilen Firebase kullanılarak uzaktan barındırılan TensorFlow Lite modellerini veya her ikisini kullanabilir.

Firebase'de bir model barındırarak, yeni bir uygulama sürümü yayınlamadan modeli güncelleyebilir ve farklı modelleri farklı kullanıcı gruplarına dinamik olarak sunmak için Remote Config ve A/B Testini kullanabilirsiniz.

Modeli yalnızca Firebase ile barındırarak sağlamayı ve uygulamanızla birlikte paketlemeyi seçerseniz, uygulamanızın ilk indirme boyutunu küçültebilirsiniz. Bununla birlikte, model uygulamanızla birlikte paketlenmemişse, uygulamanız modeli ilk kez indirene kadar modelle ilgili herhangi bir işlevin kullanılamayacağını unutmayın.

Modelinizi uygulamanızla bir araya getirerek, Firebase tarafından barındırılan model mevcut olmadığında uygulamanızın ML özelliklerinin çalışmaya devam etmesini sağlayabilirsiniz.

Firebase'deki modelleri barındırın

TensorFlow Lite modelinizi Firebase'de barındırmak için:

  1. ML Kiti bölümünde Firebase konsoluna , Özel sekmesini tıklayın.
  2. Click özel model ekleyin (veya başka bir modeli ekleyin).
  3. (Genellikle biten TensorFlow Lite modeli dosyasını, sonra Firebase projesinde modelinizi belirlemek yüklemek için kullanılacak bir ad belirleyin .tflite veya .lite ).
  4. : Uygulamanızın manifest, İNTERNET izni gerekli olduğunu beyan olarak
    <uses-permission android:name="android.permission.INTERNET" />
    

Firebase projenize özel bir model ekledikten sonra, belirttiğiniz adı kullanarak uygulamalarınızda modele başvurabilirsiniz. İstediğiniz zaman yeni bir TensorFlow Lite modeli yükleyebilirsiniz; uygulamanız yeni modeli indirecek ve uygulama yeniden başlatıldığında kullanmaya başlayacaktır. Uygulamanızın modeli güncellemeye çalışması için gereken cihaz koşullarını tanımlayabilirsiniz (aşağıya bakın).

Modelleri bir uygulamayla paketleyin

Uygulamanızla birlikte giderek TensorFlow Lite modeli paket için, model dosyası (genellikle biten kopyalamak .tflite veya .lite uygulamanızın kadar) assets/ klasörünün. (Bunu ilk klasör oluşturmak gerekebilir sağ tıklayarak app/ sonra, klasör tıklayarak Yeni> Klasör> Varlıklar Klasör.)

Ardından, uygulamanızın şunu ekleyin build.gradle uygulamayı oluştururken Gradle modellerini sıkıştırmak değil emin olmak için dosyanın:

android {

    // ...

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

Model dosyası, uygulama paketine dahil edilecek ve ham bir varlık olarak ML Kit'e sunulacak.

modeli yükle

TensorFlow Lite modelinizi uygulamanızda kullanmak için önce ML Kit'i modelinizin bulunduğu konumlarla yapılandırın: Firebase'i uzaktan kullanarak, yerel depolamada veya her ikisini birden. Hem yerel hem de uzak model belirtirseniz, varsa uzak modeli kullanabilir ve uzak model yoksa yerel olarak depolanan modele dönebilirsiniz.

Firebase tarafından barındırılan bir modeli yapılandırın

Eğer Firebase ile modelinizi barındırılan Eğer bir oluşturmak FirebaseCustomRemoteModel sen yüklerken modeli atanan adı belirterek, nesneyi:

Java

FirebaseCustomRemoteModel remoteModel =
        new FirebaseCustomRemoteModel.Builder("your_model").build();

Kotlin+KTX

val remoteModel = FirebaseCustomRemoteModel.Builder("your_model").build()

Ardından, indirmeye izin vermek istediğiniz koşulları belirterek model indirme görevini başlatın. Model cihazda değilse veya modelin daha yeni bir sürümü mevcutsa görev, modeli Firebase'den eşzamansız olarak indirir:

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+KTX

val conditions = FirebaseModelDownloadConditions.Builder()
    .requireWifi()
    .build()
FirebaseModelManager.getInstance().download(remoteModel, conditions)
    .addOnCompleteListener {
        // Success.
    }

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

Yerel bir model yapılandırın

Eğer uygulaması ile modelini birlikte olursa, oluşturmak FirebaseCustomLocalModel TensorFlow Lite modelinin dosya adını belirterek, nesneyi:

Java

FirebaseCustomLocalModel localModel = new FirebaseCustomLocalModel.Builder()
        .setAssetFilePath("your_model.tflite")
        .build();

Kotlin+KTX

val localModel = FirebaseCustomLocalModel.Builder()
    .setAssetFilePath("your_model.tflite")
    .build()

Modelinizden bir tercüman oluşturun

Eğer modeli kaynaklarını yapılandırmak sonra, oluşturmak FirebaseModelInterpreter bunlardan biri nesne.

Yalnızca yerel olarak paketlenmiş modeliniz varsa, sadece bir tercüman oluşturmak FirebaseCustomLocalModel nesnesi:

Java

FirebaseModelInterpreter interpreter;
try {
    FirebaseModelInterpreterOptions options =
            new FirebaseModelInterpreterOptions.Builder(localModel).build();
    interpreter = FirebaseModelInterpreter.getInstance(options);
} catch (FirebaseMLException e) {
    // ...
}

Kotlin+KTX

val options = FirebaseModelInterpreterOptions.Builder(localModel).build()
val interpreter = FirebaseModelInterpreter.getInstance(options)

Uzaktan barındırılan bir modeliniz varsa, çalıştırmadan önce indirildiğini kontrol etmeniz gerekir. Sen modeli yöneticinin kullanarak modeli indir görevin durumunu kontrol edebilirsiniz isModelDownloaded() yöntemini.

Bunu yalnızca yorumlayıcıyı çalıştırmadan önce onaylamanız gerekse de, hem uzaktan barındırılan hem de yerel olarak paketlenmiş bir modeliniz varsa, model yorumlayıcıyı başlatırken bu kontrolü yapmak mantıklı olabilir: aşağıdaki durumlarda uzak modelden bir yorumlayıcı oluşturun: indirildi ve aksi takdirde yerel modelden.

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+KTX

FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
    .addOnSuccessListener { isDownloaded -> 
    val options =
        if (isDownloaded) {
            FirebaseModelInterpreterOptions.Builder(remoteModel).build()
        } else {
            FirebaseModelInterpreterOptions.Builder(localModel).build()
        }
    val interpreter = FirebaseModelInterpreter.getInstance(options)
}

Yalnızca uzaktan barındırılan bir modeliniz varsa, 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 bir kısmını grileştirme veya gizleme). Sen modeli yöneticinin için bir dinleyici bağlayarak bunu yapabilirsiniz download() yöntemi:

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+KTX

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

Modelin giriş ve çıkışını belirtin

Ardından, model yorumlayıcının giriş ve çıkış biçimlerini yapılandırın.

Bir TensorFlow Lite modeli 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. Modelinizin kullandığı dizilerin sayısı ve boyutları ("şekil") ile ML Kit'i yapılandırmanız gerekir.

Modelinizin giriş ve çıkışının şeklini ve veri türünü bilmiyorsanız, modelinizi incelemek için TensorFlow Lite Python yorumlayıcısını kullanabilirsiniz. Örneğin:

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

Eğer modelin giriş ve çıkış biçimini belirledikten sonra, bir oluşturarak uygulamanızın modeli tercüman yapılandırabilirsiniz FirebaseModelInputOutputOptions nesneyi.

Örneğin, bir kayan noktalı görüntü sınıflandırma modeli girdi olarak bir alabilir N arasında x224x224x3 dizi float bir toplu temsil değerleri N 1000 listesini çıkışı olarak 224x224 üç kanal (RGB) görüntü ve üretim float her birini temsil eden değerler görüntünün, modelin öngördüğü 1000 kategoriden birinin üyesi olma olasılığı.

Böyle bir model için, model yorumlayıcısının giriş ve çıkışını aşağıda gösterildiği gibi yapılandırırsınız:

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+KTX

val inputOutputOptions = FirebaseModelInputOutputOptions.Builder()
        .setInputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 224, 224, 3))
        .setOutputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 5))
        .build()

Giriş verileri üzerinde çıkarım gerçekleştirin

Son olarak, modeli kullanarak çıkarım yapmak için girdi verilerinizi alın ve modeliniz için doğru şekle sahip bir girdi dizisi elde etmek için gerekli olan veriler üzerinde herhangi bir dönüşüm gerçekleştirin.

Eğer [1 224 224 3] kayan nokta değerlerinin bir girdi şekli ile bir resim sınıflandırma modeli varsa, örneğin, bir bir giriş dizisi oluşturabilir Bitmap aşağıdaki örnekte gösterildiği gibi, nesne:

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+KTX

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

Sonra, oluşturmak FirebaseModelInputs sizin veri girişi ile nesneyi ve geçmek ve modelin giriş ve çıkış şartname modeli tercüman s' run yönteminde:

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+KTX

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
            // ...
        }

Çağrı başarılı olursa, arayarak çıktı alabilirsiniz getOutput() başarı dinleyici geçirilir nesnenin yöntemini. Örneğin:

Java

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

Kotlin+KTX

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

Çı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

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+KTX

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

Ek: Model güvenliği

TensorFlow Lite modellerinizi ML Kit için nasıl kullanılabilir hale getirdiğinizden bağımsız olarak, ML Kit bunları yerel depolamada standart serileştirilmiş protobuf formatında 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.