TensorFlow Lite modeliyle cihaz üzerinde çıkarım yapmak için ML Kit'i kullanabilirsiniz.
Bu API için Android SDK düzeyi 16 (Jelly Bean) veya daha yeni bir sürüm gerekir.
Başlamadan önce
- Henüz yapmadıysanız Firebase'i Android projenize ekleyin.
- ML Kit Android kitaplıklarının bağımlılıkları modülünüzün (uygulama düzeyinde) Gradle dosyasına (genellikle
app/build.gradle
) eklenmelidir: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 biçimine dönüştürün. Bkz. TOCO: TensorFlow Lite Optimizing Converter.
Modelinizi barındırma veya paketleme
Uygulamanızda çıkarım yapmak için TensorFlow Lite modelini kullanabilmenizden önce modeli ML Kit'e sunmanız gerekir. ML Kit, Firebase kullanılarak uzaktan barındırılan, uygulama ikilisiyle birlikte paketlenmiş veya her ikisi de olan 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 dinamik olarak farklı modeller sunmak için Remote Config ve A/B Testing'ü kullanabilirsiniz.
Modeli yalnızca Firebase ile barındırarak sağlamak ve uygulamanızla birlikte paketlemek istemiyorsanız uygulamanızın ilk indirme boyutunu azaltabilirsiniz. Ancak model uygulamanızla birlikte paketlenmemişse uygulamanız modeli ilk kez indirene kadar modelle ilgili işlevlerin kullanılamayacağını unutmayın.
Modelinizi uygulamanızla birlikte paketleyerek Firebase'da barındırılan model kullanılamadığında uygulamanızın ML özelliklerinin çalışmaya devam etmesini sağlayabilirsiniz.
Firebase'de model barındırma
TensorFlow Lite modelinizi Firebase'de barındırmak için:
- Firebase Konsolu'nun ML Kiti bölümünde Özel sekmesini tıklayın.
- Özel model ekle'yi (veya Başka bir model ekle'yi) tıklayın.
- Firebase projenizde modelinizi tanımlamak için kullanılacak bir ad belirtin, ardından TensorFlow Lite model dosyasını (genellikle
.tflite
veya.lite
ile biter) yükleyin. - Uygulamanızın manifest dosyasında INTERNET izninin gerekli olduğunu beyan edin:
<uses-permission android:name="android.permission.INTERNET" />
Firebase projenize özel bir model ekledikten sonra, belirttiğiniz adı kullanarak bu modele uygulamalarınızda referans verebilirsiniz. İstediğiniz zaman yeni bir TensorFlow Lite modeli yükleyebilirsiniz. Uygulamanız yeni modeli indirir ve bir sonraki yeniden başlatmada kullanmaya başlar. Uygulamanızın modeli güncellemeyi denemesi için gereken cihaz koşullarını tanımlayabilirsiniz (aşağıya bakın).
Modelleri uygulamayla paketleme
TensorFlow Lite modelinizi uygulamanızla paketlemek için model dosyasını (genellikle .tflite
veya .lite
ile biter) uygulamanızın assets/
klasörüne kopyalayın. (Önce app/
klasörünü sağ tıklayıp Yeni > Klasör > Öğeler Klasörü'nü tıklayarak klasörü oluşturmanız gerekebilir.)
Ardından, Gradle'in uygulamayı oluştururken modelleri sıkıştırmamasını sağlamak için uygulamanızın build.gradle
dosyasına aşağıdakileri ekleyin:
android {
// ...
aaptOptions {
noCompress "tflite" // Your model's file extension: "tflite", "lite", etc.
}
}
Model dosyası uygulama paketine dahil edilir ve ham öğe olarak ML Kit'e sunulur.
Modeli yükleme
TensorFlow Lite modelinizi uygulamanızda kullanmak için önce ML Kit'i, modelinizin bulunduğu konumlarla yapılandırın: Firebase'i kullanarak uzaktan, yerel depolama alanında veya her ikisini birden. Hem yerel hem de uzak bir model belirtirseniz uzak model mevcutsa uzak modeli kullanabilir, uzak model mevcut değilse yerel olarak depolanan modele geri dönebilirsiniz.Firebase tarafından barındırılan bir modeli yapılandırma
Modelinizi Firebase ile barındırdıysanız modeli yüklerken atadığınız adı belirterek bir FirebaseCustomRemoteModel
nesnesi oluşturun:
Java
FirebaseCustomRemoteModel remoteModel =
new FirebaseCustomRemoteModel.Builder("your_model").build();
Kotlin
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
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 modeli kullanmadan önce istediğiniz zaman bu işlemi yapabilirsiniz.
Yerel bir model yapılandırma
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
val localModel = FirebaseCustomLocalModel.Builder()
.setAssetFilePath("your_model.tflite")
.build()
Modelinizden yorumcu oluşturma
Model kaynaklarınızı yapılandırdıktan sonra bunlardan birinde FirebaseModelInterpreter
nesnesi oluşturun.
Yalnızca yerel olarak paketlenmiş bir modeliniz varsa FirebaseCustomLocalModel
nesnenizle 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
val options = FirebaseModelInterpreterOptions.Builder(localModel).build()
val interpreter = FirebaseModelInterpreter.getInstance(options)
Uzaktan barındırılan bir modeliniz varsa çalıştırmadan önce modelin indirildiğinden emin olmanız 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 gerekir. Ancak hem uzaktan barındırılan hem de yerel olarak paketlenmiş bir modeliniz varsa model yorumlayıcısını örneklendirirken bu kontrolü gerçekleştirmeniz yararlı olabilir: İndirilmişse uzak modelden, aksi takdirde yerel modelden bir yorumlayıcı oluşturun.
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)
}
Yalnızca uzaktan barındırılan bir modeliniz varsa modelin indirildiğini onaylayana kadar modelle ilgili işlevleri (ör. kullanıcı arayüzünüzün bir bölümünü devre dışı bırakma veya gizleme) devre dışı bırakmanız 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
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şini ve çıkışını belirtme
Ardından model yorumlayıcısının giriş ve çıkış biçimlerini yapılandırın.
TensorFlow Lite modeli, giriş olarak bir veya daha fazla çok boyutlu dizi alır ve çıkış olarak bir veya daha fazla çok boyutlu dizi oluşturur. Bu diziler byte
,
int
, long
veya float
değerleri içerir. ML Kit'i, modelinizin kullandığı dizilerin sayısı ve boyutlarıyla ("şekil") 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 giriş ve çıkış biçimini belirledikten sonra FirebaseModelInputOutputOptions
nesnesi oluşturarak uygulamanızın model yorumlayıcısını yapılandırabilirsiniz.
Örneğin, kayan noktalı bir resim sınıflandırma modeli, giriş olarak N 224x224 üç kanallı (RGB) resim grubunu temsil eden float
x224x224x3 float
değeri dizisi alabilir ve çıkış olarak her biri resmin, modelin tahmin ettiği 1.000 kategoriden birinin üyesi olma olasılığını temsil eden 1.000 float
değeri listesi oluşturabilir.N
Bu tür bir model için model yorumlayıcının girişini ve çıkışını aşağıdaki 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
val inputOutputOptions = FirebaseModelInputOutputOptions.Builder() .setInputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 224, 224, 3)) .setOutputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 5)) .build()
Giriş verilerinde çıkarım yapma
Son olarak, modeli kullanarak çıkarım yapmak için giriş verilerinizi alın ve modeliniz için doğru biçimde bir giriş dizisi elde etmek üzere veriler üzerinde gerekli tüm dönüşümleri gerçekleştirin.Örneğin, [1 224 224 3] kayan nokta değerleri giriş şekline sahip bir resim sınıflandırma modeliniz varsa aşağıdaki örnekte gösterildiği gibi bir Bitmap
nesnesinden 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
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, giriş verilerinizle bir FirebaseModelInputs
nesnesi oluşturun ve bu nesneyi ile modelin giriş ve çıkış spesifikasyonunu 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
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 çıkışı alabilirsiniz. Örneğin:
Java
float[][] output = result.getOutput(0); float[] probabilities = output[0];
Kotlin
val output = result.getOutput<Array<FloatArray>>(0) val probabilities = output[0]
Çıktıyı kullanma şekliniz, kullandığınız modele bağlıdır.
Örneğin, sınıflandırma işlemi yapıyorsanız sonraki adımda 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
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 depolama alanında standart serileştirilmiş protobuf biçiminde depolar.
Teorik olarak bu, herkesin modelinizi kopyalayabileceği anlamına gelir. Ancak uygulamada çoğu model uygulamaya o kadar özeldir ve optimizasyonlarla o kadar karartılmıştır ki risk, rakiplerin kodunuzu söküp yeniden kullanması riskine benzer. Yine de uygulamanızda özel bir model kullanmadan önce bu riskin farkında olmanız gerekir.
Android API düzeyi 21 (Lollipop) ve sonraki sürümlerde model, otomatik yedekleme kapsamından hariç tutulan bir dizine indirilir.
Android API düzeyi 20 ve önceki sürümlerde model, uygulamaya özel dahili depolama alanındaki com.google.firebase.ml.custom.models
adlı bir dizine indirilir. Dosya yedeklemeyi BackupAgent
kullanarak etkinleştirdiyseniz bu dizini hariç tutmayı seçebilirsiniz.