Uygulamanız özel TensorFlow Lite modelleri kullanıyorsa modellerinizi dağıtmak için Firebase ML'i kullanabilirsiniz. Firebase ile model dağıtarak uygulamanızın ilk indirme boyutunu düşürebilir 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ı kullanıcı gruplarına dinamik olarak farklı modeller sunabilirsiniz.
TensorFlow Lite modelleri
TensorFlow Lite modelleri, mobil cihazlarda çalışacak şekilde optimize edilmiş ML modelleridir. TensorFlow Lite modeli almak için:
- Resmi TensorFlow Lite modellerinden biri gibi önceden oluşturulmuş bir model kullanın.
- Bir TensorFlow modelini, Keras modelini veya somut işlevi TensorFlow Lite'a dönüştürün.
Başlamadan önce
- Henüz yapmadıysanız Firebase'i Android projenize ekleyin.
-
Modül (uygulama düzeyinde) Gradle dosyanıza (genellikle
<project>/<app-module>/build.gradle.kts
veya<project>/<app-module>/build.gradle
) Android için Firebase ML model indirici kitaplığının bağımlılığını ekleyin. Kitaplık sürümlendirmesini kontrol etmek için Firebase Android BoM simgesini kullanmanızı öneririz.Ayrıca, Firebase ML model indiricisini ayarlama kapsamında TensorFlow Lite SDK'sını uygulamanıza eklemeniz gerekir.
dependencies { // Import the BoM for the Firebase platform implementation(platform("com.google.firebase:firebase-bom:33.7.0")) // Add 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 add the dependency for the TensorFlow Lite library and specify its version implementation("org.tensorflow:tensorflow-lite:2.3.0") }Firebase Android BoM kullanıldığında uygulamanız Firebase Android kitaplıklarının daima uyumlu sürümlerini kullanır.
(Alternatif) BoM
Firebase BoM kullanmamayı seçerseniz her Firebase kitaplık sürümünü bağımlılık satırında belirtmeniz gerekir.
Uygulamanızda birden fazla Firebase kitaplığı kullanıyorsanız kitaplık sürümlerini yönetmek için BoM'ı kullanmanızı önemle tavsiye ederiz. Bu, tüm sürümlerin uyumlu olmasını sağlar.
dependencies { // Add 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:25.0.1")
// Also add the dependency for the TensorFlow Lite library and specify its version implementation("org.tensorflow:tensorflow-lite:2.3.0") } - Uygulamanızın manifest dosyasında INTERNET izninin gerekli olduğunu beyan edin:
<uses-permission android:name="android.permission.INTERNET" />
1. Modelinizi dağıtma
Özel TensorFlow modellerinizi Firebase konsolunu veya Firebase Admin Python ve Node.js SDK'larını kullanarak dağıtın. Özel modelleri dağıtma ve yönetme başlıklı makaleyi inceleyin.
Firebase projenize özel bir model ekledikten sonra, belirttiğiniz adı kullanarak bu modele uygulamalarınızda referans verebilirsiniz. İstediğiniz zaman getModel()
işlevini çağırarak yeni bir TensorFlow Lite modeli dağıtabilir ve yeni modeli kullanıcıların cihazlarına indirebilirsiniz (aşağıya bakın).
2. Modeli cihaza indirip TensorFlow Lite yorumlayıcısını başlatın
TensorFlow Lite modelinizi uygulamanızda kullanmak için önce Firebase ML SDK'sını kullanarak modelin en son sürümünü cihaza indirin. Ardından, modelle bir TensorFlow Lite yorumlayıcısı oluşturun.Model indirme işlemini başlatmak için model indiricinin getModel()
yöntemini çağırın. Bu yöntemi çağırırken modeli yüklerken atadığınız adı, her zaman en son modeli indirmek isteyip istemediğinizi ve indirmeye izin vermek istediğiniz koşulları belirtin.
Üç indirme davranışı arasından seçim yapabilirsiniz:
İndirme türü | Açıklama |
---|---|
LOCAL_MODEL | Cihazdan yerel modeli alın.
Yerel model yoksa bu, LATEST_MODEL gibi davranır. Model güncellemelerini kontrol etmek istemiyorsanız bu indirme türünü kullanın. Örneğin, model adlarını almak için Remote Config'i kullanıyorsanız ve modelleri her zaman yeni adlar altında yüklüyorsanız (önerilir). |
LOCAL_MODEL_UPDATE_IN_BACKGROUND | Cihazdan yerel modeli alın ve modeli arka planda güncellemeye başlayın.
Yerel model yoksa bu, LATEST_MODEL gibi davranır. |
LATEST_MODEL | En son modeli edinin. 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 ihtiyacınız olduğu durumlarda kullanın. |
Modelin indirildiğini onaylayana kadar modelle ilgili işlevleri devre dışı bırakmanız (ör. kullanıcı arayüzünüzün bir kısmını devre dışı bırakma veya gizleme) gerekir.
Kotlin
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)
}
}
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);
}
}
});
Birçok uygulama, indirme görevini başlatma kodunda başlatır ancak modeli kullanmadan önce istediğiniz zaman bu işlemi yapabilirsiniz.
3. Giriş verilerinde çıkarım yapma
Modelinizin giriş ve çıkış şekillerini alma
TensorFlow Lite model yorumlayıcısı, 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ğerlerinden birini içerir. Bir modele veri iletebilmeniz veya modelin sonucunu kullanabilmeniz için modelinizin kullandığı dizilerin sayısını ve boyutlarını ("şeklini") 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:
Python
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 çıkış:
1 input(s): [ 1 224 224 3] <class 'numpy.float32'> 1 output(s): [1 1000] <class 'numpy.float32'>
Çevirmeni çalıştırma
Modelinizin giriş ve çıkış biçimini belirledikten sonra giriş verilerinizi alın ve modeliniz için doğru biçimde bir giriş almak üzere veriler üzerinde gerekli dönüşümleri gerçekleştirin.Örneğin, [1 224 224 3]
kayan noktalı değer giriş şekline sahip bir resim sınıflandırma modeliniz varsa aşağıdaki örnekte gösterildiği gibi bir Bitmap
nesnesinden giriş ByteBuffer
oluşturabilirsiniz:
Kotlin
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)
}
}
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);
}
}
Ardından, modelin çıkışını içerecek kadar büyük bir ByteBuffer
ayırın ve giriş arabelleğini ve çıkış arabelleğini TensorFlow Lite yorumcusunun run()
yöntemine iletin. Örneğin, [1 1000]
kayan nokta değerlerinin çıkış şekli için:
Kotlin
val bufferSize = 1000 * java.lang.Float.SIZE / java.lang.Byte.SIZE
val modelOutput = ByteBuffer.allocateDirect(bufferSize).order(ByteOrder.nativeOrder())
interpreter?.run(input, modelOutput)
Java
int bufferSize = 1000 * java.lang.Float.SIZE / java.lang.Byte.SIZE;
ByteBuffer modelOutput = ByteBuffer.allocateDirect(bufferSize).order(ByteOrder.nativeOrder());
interpreter.run(input, modelOutput);
Çı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:
Kotlin
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?
}
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?
}
Ek: Model güvenliği
TensorFlow Lite modellerinizi Firebase ML'e nasıl sunduğunuzdan bağımsız olarak Firebase ML, 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.