Bir TensorFlow Lite modeliyle cihaz üzerinde çıkarım gerçekleştirmek için ML Kit'i kullanabilirsiniz.
Bu API, Android SDK seviye 16 (Jelly Bean) veya daha yenisini gerektirir.
Sen başlamadan önce
- Henüz yapmadıysanız, Firebase'i Android projenize ekleyin .
- ML Kit Android kitaplıklarının bağımlılıklarını modülünüze (uygulama düzeyi) Gradle dosyasına (genellikle
app/build.gradle
) ekleyin:apply plugin: 'com.android.application' apply plugin: 'com.google.gms.google-services' dependencies { // ... implementation 'com.google.firebase:firebase-ml-model-interpreter:22.0.3' }
- Kullanmak istediğiniz TensorFlow modelini TensorFlow Lite formatına dönüştürün. Bkz. TOCO: TensorFlow Lite Dönüştürücüyü Optimize Etme.
Modelinizi barındırın veya paketleyin
Uygulamanızda çıkarım yapmak için bir TensorFlow Lite modelini kullanabilmeniz için önce modeli ML Kit'in kullanımına sunmalısınız. ML Kit, Firebase kullanılarak uzaktan barındırılan, uygulama ikili programıyla birlikte gelen veya her ikisini birden içeren TensorFlow Lite modellerini kullanabilir.
Firebase'de bir model barındırarak, yeni bir uygulama sürümü yayınlamadan modeli güncelleyebilir ve farklı kullanıcı gruplarına farklı modelleri dinamik olarak sunmak için Remote Config ve A/B Testing'i kullanabilirsiniz.
Modeli yalnızca Firebase'de barındırarak sağlamayı ve uygulamanızla birlikte paketlememeyi seçerseniz, uygulamanızın ilk indirme boyutunu azaltabilirsiniz. Ancak, model uygulamanızla birlikte verilmemişse, uygulamanız modeli ilk kez indirene kadar modelle ilgili herhangi bir işlevin kullanılamayacağını unutmayın.
Modelinizi uygulamanızla paketleyerek, Firebase tarafından barındırılan model mevcut olmadığında uygulamanızın makine öğrenimi özelliklerinin çalışmaya devam etmesini sağlayabilirsiniz.
Modelleri Firebase'de barındırma
TensorFlow Lite modelinizi Firebase'de barındırmak için:
- Firebase konsolunun ML Kit bölümünde Özel sekmesini tıklayın.
- Özel model ekle'ye (veya Başka bir model ekle'ye ) tıklayın.
- Firebase projenizde modelinizi tanımlamak için kullanılacak bir ad belirtin, ardından TensorFlow Lite model dosyasını yükleyin (genellikle
.tflite
veya.lite
ile biter). - Uygulamanızın bildiriminde İNTERNET izninin gerekli olduğunu beyan edin:
<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 bir sonraki yeniden başlatıldığında onu 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 uygulama ile paketleyin
TensorFlow Lite modelinizi uygulamanızla bir araya getirmek için model dosyasını (genellikle .tflite
veya .lite
ile biten) uygulamanızın assets/
klasörüne kopyalayın. (Önce app/
klasöre sağ tıklayıp ardından Yeni > Klasör > Varlıklar Klasörü seçeneğine tıklayarak klasörü oluşturmanız gerekebilir.)
Ardından, Gradle'ın uygulamayı oluştururken modelleri sıkıştırmamasını sağlamak için uygulamanızın build.gradle
dosyasına aşağıdakini ekleyin:
android {
// ...
aaptOptions {
noCompress "tflite" // Your model's file extension: "tflite", "lite", etc.
}
}
Model dosyası, uygulama paketine dahil edilecek ve ML Kit'e ham varlık olarak sunulacaktır.
modeli yükle
TensorFlow Lite modelinizi uygulamanızda kullanmak için önce ML Kit'i modelinizin mevcut olduğu konumlarla yapılandırın: uzaktan Firebase kullanarak, yerel depolamada veya her ikisini birden. Hem yerel hem de uzak bir model belirtirseniz, varsa uzak modeli kullanabilir ve uzak model yoksa yerel olarak depolanan modele geri dönebilirsiniz.Firebase tarafından barındırılan bir model yapılandırın
Modelinizi Firebase ile barındırdıysanız, yüklediğinizde modele atadığınız adı belirterek bir FirebaseCustomRemoteModel
nesnesi oluşturun:
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 yoksa veya modelin daha yeni bir sürümü varsa 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 kendi başlatma kodunda başlatır, ancak bunu, modeli kullanmadan önce herhangi bir noktada yapabilirsiniz.
Yerel bir model yapılandırın
Modeli uygulamanızla birlikte paketlediyseniz, TensorFlow Lite modelinin dosya adını belirterek bir FirebaseCustomLocalModel
nesnesi oluşturun:
Java
FirebaseCustomLocalModel localModel = new FirebaseCustomLocalModel.Builder()
.setAssetFilePath("your_model.tflite")
.build();
Kotlin+KTX
val localModel = FirebaseCustomLocalModel.Builder()
.setAssetFilePath("your_model.tflite")
.build()
Modelinizden bir yorumlayıcı oluşturun
Model kaynaklarınızı yapılandırdıktan sonra, bunlardan birinden bir FirebaseModelInterpreter
nesnesi oluşturun.
Yalnızca yerel olarak paketlenmiş bir modeliniz varsa, FirebaseCustomLocalModel
nesnenizden bir yorumlayıcı oluşturmanız yeterlidir:
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 indirilip indirilmediğini kontrol etmeniz gerekir. Model yöneticisinin isModelDownloaded()
yöntemini kullanarak model indirme görevinin durumunu kontrol edebilirsiniz.
Bunu yalnızca yorumlayıcıyı çalıştırmadan önce onaylamanız gerekse de, hem uzaktan barındırılan bir modeliniz hem de yerel olarak paketlenmiş bir modeliniz varsa, model yorumlayıcısını başlatırken bu kontrolü yapmanız mantıklı olabilir: eğer uzak modelden bir yorumlayıcı oluşturun. aksi takdirde yerel modelden indirilmiştir.
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ırakmanız (örneğin, kullanıcı arabiriminizin bir bölümünü grileştirme veya gizleme) gerekir. Bunu, model yöneticisinin download()
yöntemine bir dinleyici ekleyerek yapabilirsiniz:
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 girdisini ve çıktısını belirtin
Ardından, model yorumlayıcısının giriş ve çıkış biçimlerini yapılandırın.
Bir TensorFlow Lite modeli girdi olarak alır ve bir veya daha fazla çok boyutlu diziyi çıktı olarak üretir. Bu diziler byte
, int
, long
veya float
değerleri içerir. 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'>
Modelinizin girdi ve çıktısının biçimini belirledikten sonra, bir FirebaseModelInputOutputOptions
nesnesi oluşturarak uygulamanızın model yorumlayıcısını yapılandırabilirsiniz.
Örneğin, bir kayan noktalı görüntü sınıflandırma modeli, N 224x224 üç kanallı (RGB) görüntülerin bir grubunu temsil eden bir N x224x224x3 float
değer dizisini girdi float
alabilir ve çıktı olarak her biri 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()
Girdi 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 dizisini elde etmek için gerekli olan tüm dönüşümleri veriler üzerinde gerçekleştirin. Örneğin, [1 224 224 3] kayan nokta değerleri giriş şekline sahip bir görüntü sınıflandırma modeliniz varsa, aşağıdaki örnekte gösterildiği gibi bir Bitmap
nesnesinden bir giriş dizisi oluşturabilirsiniz:
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 } }
Ardından, girdi verilerinizle bir FirebaseModelInputs
nesnesi oluşturun ve onu ve modelin girdi ve çıktı belirtimini model yorumlayıcısının run
yöntemine iletin:
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, başarı dinleyicisine iletilen nesnenin getOutput()
yöntemini çağırarak çıktı alabilirsiniz. Ö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'e nasıl sunduğunuzdan bağımsız olarak, ML Kit bunları yerel depolamada standart seri hale getirilmiş protobuf formatında saklar.
Teorik olarak bu, herkesin modelinizi kopyalayabileceği anlamına gelir. Bununla birlikte, uygulamada, çoğu model uygulamaya o kadar özeldir ve optimizasyonlarla karmaşıktır ki, kodunuzu parçalarına ayırıp yeniden kullanan rakiplerin riskine benzer. Yine de, uygulamanızda özel bir model kullanmadan önce bu riskin farkında olmalısınız.
Android API seviye 21 (Lollipop) ve daha yeni sürümlerde model, otomatik yedeklemenin dışında bırakılan bir dizine indirilir.
Android API düzeyi 20 ve daha eski sürümlerde model, uygulamaya özel dahili depolama alanında com.google.firebase.ml.custom.models
adlı bir dizine indirilir. BackupAgent
kullanarak dosya yedeklemeyi etkinleştirdiyseniz, bu dizini hariç tutmayı seçebilirsiniz.