Si su aplicación usa modelos TensorFlow Lite personalizados, puede usar Firebase ML para implementar sus modelos. Al implementar modelos con Firebase, puede reducir el tamaño de descarga inicial de su aplicación y actualizar los modelos ML de su aplicación sin lanzar una nueva versión de su aplicación. Y, con Remote Config y A/B Testing, puede servir dinámicamente diferentes modelos a diferentes conjuntos de usuarios.
Modelos de TensorFlow Lite
Los modelos TensorFlow Lite son modelos ML que están optimizados para ejecutarse en dispositivos móviles. Para obtener un modelo TensorFlow Lite:
- Usa un modelo prediseñado, como uno de los modelos oficiales de TensorFlow Lite .
- Convierta un modelo de TensorFlow, un modelo de Keras o una función concreta a TensorFlow Lite.
Antes de que empieces
- Si aún no lo ha hecho, agregue Firebase a su proyecto de Android .
- En el archivo Gradle de tu módulo (nivel de aplicación) (generalmente
<project>/<app-module>/build.gradle
), agrega la dependencia para la biblioteca de Android del descargador de modelos de Firebase ML. Recomendamos usar Firebase Android BoM para controlar el control de versiones de la biblioteca.Además, como parte de la configuración del descargador de modelos de Firebase ML, debe agregar el SDK de TensorFlow Lite a su aplicación.
Kotlin+KTX
dependencies { // Import the BoM for the Firebase platform implementation platform('com.google.firebase:firebase-bom:31.2.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-ktx'
// Also add the dependency for the TensorFlow Lite library and specify its version implementation 'org.tensorflow:tensorflow-lite:2.3.0' }Al usar Firebase Android BoM , su aplicación siempre usará versiones compatibles de las bibliotecas de Firebase Android.
(Alternativa) Agregar dependencias de la biblioteca de Firebase sin usar el BoM
Si elige no usar Firebase BoM, debe especificar cada versión de la biblioteca de Firebase en su línea de dependencia.
Tenga en cuenta que si usa varias bibliotecas de Firebase en su aplicación, le recomendamos enfáticamente que use la lista de materiales para administrar las versiones de la biblioteca, lo que garantiza que todas las versiones sean compatibles.
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-ktx:24.1.2'
// Also add the dependency for the TensorFlow Lite library and specify its version implementation 'org.tensorflow:tensorflow-lite:2.3.0' }Java
dependencies { // Import the BoM for the Firebase platform implementation platform('com.google.firebase:firebase-bom:31.2.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' }Al usar Firebase Android BoM , su aplicación siempre usará versiones compatibles de las bibliotecas de Firebase Android.
(Alternativa) Agregar dependencias de la biblioteca de Firebase sin usar el BoM
Si elige no usar Firebase BoM, debe especificar cada versión de la biblioteca de Firebase en su línea de dependencia.
Tenga en cuenta que si usa varias bibliotecas de Firebase en su aplicación, le recomendamos enfáticamente que use la lista de materiales para administrar las versiones de la biblioteca, lo que garantiza que todas las versiones sean compatibles.
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:24.1.2'
// Also add the dependency for the TensorFlow Lite library and specify its version implementation 'org.tensorflow:tensorflow-lite:2.3.0' }- En el manifiesto de su aplicación, declare que se requiere permiso de INTERNET:
<uses-permission android:name="android.permission.INTERNET" />
1. Implementa tu modelo
Implemente sus modelos personalizados de TensorFlow con Firebase console o Firebase Admin Python y Node.js SDK. Consulte Implementar y administrar modelos personalizados .
Después de agregar un modelo personalizado a su proyecto de Firebase, puede hacer referencia al modelo en sus aplicaciones con el nombre que especificó. En cualquier momento, puede implementar un nuevo modelo de TensorFlow Lite y descargar el nuevo modelo en los dispositivos de los usuarios llamando a
getModel()
(consulte a continuación).2. Descargue el modelo al dispositivo e inicialice un intérprete de TensorFlow Lite
Para usar su modelo de TensorFlow Lite en su aplicación, primero use el SDK de Firebase ML para descargar la última versión del modelo en el dispositivo. Luego, crea una instancia de un intérprete de TensorFlow Lite con el modelo.Para iniciar la descarga del modelo, llame al método
getModel()
del descargador de modelos, especificando el nombre que asignó al modelo cuando lo cargó, si desea descargar siempre el último modelo y las condiciones bajo las cuales desea permitir la descarga.Puede elegir entre tres comportamientos de descarga:
Tipo de descarga Descripción MODELO_LOCAL Obtenga el modelo local del dispositivo. Si no hay un modelo local disponible, se comporta como LATEST_MODEL
. Use este tipo de descarga si no está interesado en buscar actualizaciones de modelos. Por ejemplo, está utilizando Remote Config para recuperar nombres de modelos y siempre carga modelos con nuevos nombres (recomendado).LOCAL_MODEL_UPDATE_IN_BACKGROUND Obtenga el modelo local del dispositivo y comience a actualizar el modelo en segundo plano. Si no hay un modelo local disponible, se comporta como LATEST_MODEL
.ULTIMO MODELO Consigue el último modelo. Si el modelo local es la última versión, devuelve el modelo local. De lo contrario, descargue el último modelo. Este comportamiento se bloqueará hasta que se descargue la última versión (no recomendado). Use este comportamiento solo en los casos en que necesite explícitamente la última versión. Debe deshabilitar la funcionalidad relacionada con el modelo, por ejemplo, atenuar u ocultar parte de su interfaz de usuario, hasta que confirme que se ha descargado el modelo.
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) } }
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); } } });
Muchas aplicaciones inician la tarea de descarga en su código de inicialización, pero puede hacerlo en cualquier momento antes de que necesite usar el modelo.
3. Realizar inferencias sobre los datos de entrada
Obtenga las formas de entrada y salida de su modelo
El intérprete de modelos TensorFlow Lite toma como entrada y produce como salida una o más matrices multidimensionales. Estas matrices contienen valores
byte
,int
,long
ofloat
. Antes de que pueda pasar datos a un modelo o usar su resultado, debe conocer el número y las dimensiones ("forma") de las matrices que usa su modelo.Si creó el modelo usted mismo, o si el formato de entrada y salida del modelo está documentado, es posible que ya tenga esta información. Si no conoce la forma y el tipo de datos de la entrada y la salida de su modelo, puede usar el intérprete de TensorFlow Lite para inspeccionar su modelo. Por ejemplo:
Pitón
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']))
Salida de ejemplo:
1 input(s): [ 1 224 224 3] <class 'numpy.float32'> 1 output(s): [1 1000] <class 'numpy.float32'>
Ejecutar el intérprete
Una vez que haya determinado el formato de entrada y salida de su modelo, obtenga sus datos de entrada y realice las transformaciones en los datos que sean necesarias para obtener una entrada con la forma correcta para su modelo.Por ejemplo, si tiene un modelo de clasificación de imágenes con una forma de entrada de
[1 224 224 3]
valores de punto flotante, podría generar unByteBuffer
de entrada a partir de un objetoBitmap
como se muestra en el siguiente ejemplo: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) } }
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); } }
Luego, asigne un
ByteBuffer
lo suficientemente grande como para contener la salida del modelo y pase el búfer de entrada y el búfer de salida al métodorun()
del intérprete de TensorFlow Lite. Por ejemplo, para una forma de salida de[1 1000]
valores de punto flotante: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)
Java
int bufferSize = 1000 * java.lang.Float.SIZE / java.lang.Byte.SIZE; ByteBuffer modelOutput = ByteBuffer.allocateDirect(bufferSize).order(ByteOrder.nativeOrder()); interpreter.run(input, modelOutput);
La forma en que utilice la salida depende del modelo que esté utilizando.
Por ejemplo, si está realizando una clasificación, como siguiente paso, puede asignar los índices del resultado a las etiquetas que representan:
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? }
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? }
Apéndice: Modelo de seguridad
Independientemente de cómo haga que sus modelos de TensorFlow Lite estén disponibles para Firebase ML, Firebase ML los almacena en el formato protobuf serializado estándar en el almacenamiento local.
En teoría, esto significa que cualquiera puede copiar su modelo. Sin embargo, en la práctica, la mayoría de los modelos son tan específicos de la aplicación y están tan ofuscados por las optimizaciones que el riesgo es similar al de los competidores que desensamblan y reutilizan su código. No obstante, debe tener en cuenta este riesgo antes de utilizar un modelo personalizado en su aplicación.
En el nivel 21 de la API de Android (Lollipop) y posteriores, el modelo se descarga en un directorio que está excluido de la copia de seguridad automática .
En el nivel de API de Android 20 y anteriores, el modelo se descarga en un directorio llamado
com.google.firebase.ml.custom.models
en el almacenamiento interno privado de la aplicación. Si habilitó la copia de seguridad de archivos medianteBackupAgent
, puede optar por excluir este directorio.Salvo que se indique lo contrario, el contenido de esta página está sujeto a la licencia Atribución 4.0 de Creative Commons, y los ejemplos de código están sujetos a la licencia Apache 2.0. Para obtener más información, consulta las políticas del sitio de Google Developers. Java es una marca registrada de Oracle o sus afiliados.
Last updated 2023-02-03 UTC.
[] [] - En el manifiesto de su aplicación, declare que se requiere permiso de INTERNET: