Se seu aplicativo usa modelos personalizados do TensorFlow Lite , você pode usar o Firebase ML para implantar seus modelos. Ao implantar modelos com o Firebase, você pode reduzir o tamanho inicial do download do seu aplicativo e atualizar os modelos de ML do seu aplicativo sem lançar uma nova versão do seu aplicativo. E, com Configuração Remota e Teste A/B, você pode servir dinamicamente diferentes modelos para diferentes conjuntos de usuários.
Modelos do TensorFlow Lite
Os modelos do TensorFlow Lite são modelos de ML otimizados para execução em dispositivos móveis. Para obter um modelo do TensorFlow Lite:
- Use um modelo pré-criado, como um dos modelos oficiais do TensorFlow Lite .
- Converta um modelo TensorFlow, modelo Keras ou função concreta em TensorFlow Lite.
Antes de você começar
- Se ainda não o fez, adicione o Firebase ao seu projeto Android .
- No arquivo Gradle do módulo (nível do aplicativo) (geralmente
<project>/<app-module>/build.gradle
), adicione a dependência para a biblioteca Android do downloader de modelo do Firebase ML. Recomendamos usar o Firebase Android BoM para controlar o controle de versão da biblioteca.Além disso, como parte da configuração do downloader de modelo do Firebase ML, você precisa adicionar o TensorFlow Lite SDK ao seu aplicativo.
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' }Ao usar o Firebase Android BoM , seu aplicativo sempre usará versões compatíveis das bibliotecas do Firebase Android.
(Alternativa) Adicionar dependências da biblioteca Firebase sem usar o BoM
Se você optar por não usar o Firebase BoM, deverá especificar cada versão da biblioteca Firebase em sua linha de dependência.
Observe que, se você usar várias bibliotecas do Firebase em seu aplicativo, recomendamos usar o BoM para gerenciar as versões da biblioteca, o que garante que todas as versões sejam compatíveis.
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' }Ao usar o Firebase Android BoM , seu aplicativo sempre usará versões compatíveis das bibliotecas do Firebase Android.
(Alternativa) Adicionar dependências da biblioteca Firebase sem usar o BoM
Se você optar por não usar o Firebase BoM, deverá especificar cada versão da biblioteca Firebase em sua linha de dependência.
Observe que, se você usar várias bibliotecas do Firebase em seu aplicativo, recomendamos usar o BoM para gerenciar as versões da biblioteca, o que garante que todas as versões sejam compatíveis.
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' }- No manifesto do seu aplicativo, declare que a permissão de INTERNET é necessária:
<uses-permission android:name="android.permission.INTERNET" />
1. Implante seu modelo
Implante seus modelos personalizados do TensorFlow usando o Firebase console ou os SDKs Firebase Admin Python e Node.js. Consulte Implantar e gerenciar modelos personalizados .
Depois de adicionar um modelo personalizado ao seu projeto do Firebase, você pode fazer referência ao modelo em seus aplicativos usando o nome especificado. A qualquer momento, você pode implantar um novo modelo do TensorFlow Lite e fazer download do novo modelo nos dispositivos dos usuários chamando
getModel()
(veja abaixo).2. Baixe o modelo para o dispositivo e inicialize um interpretador TensorFlow Lite
Para usar seu modelo do TensorFlow Lite em seu aplicativo, primeiro use o Firebase ML SDK para baixar a versão mais recente do modelo para o dispositivo. Em seguida, instancie um interpretador do TensorFlow Lite com o modelo.Para iniciar o download do modelo, chame o método
getModel()
do downloader de modelo, especificando o nome que você atribuiu ao modelo quando o carregou, se deseja sempre baixar o modelo mais recente e as condições sob as quais deseja permitir o download.Você pode escolher entre três comportamentos de download:
tipo de download Descrição LOCAL_MODEL Obtenha o modelo local do dispositivo. Se não houver nenhum modelo local disponível, isso se comportará como LATEST_MODEL
. Use este tipo de download se não estiver interessado em verificar as atualizações do modelo. Por exemplo, você está usando o Remote Config para recuperar nomes de modelos e sempre carrega modelos com novos nomes (recomendado).LOCAL_MODEL_UPDATE_IN_BACKGROUND Obtenha o modelo local do dispositivo e comece a atualizar o modelo em segundo plano. Se não houver nenhum modelo local disponível, isso se comportará como LATEST_MODEL
.LATEST_MODEL Obtenha o modelo mais recente. Se o modelo local for a versão mais recente, retorna o modelo local. Caso contrário, baixe o modelo mais recente. Esse comportamento será bloqueado até que a versão mais recente seja baixada (não recomendado). Use esse comportamento apenas nos casos em que você precisa explicitamente da versão mais recente. Você deve desabilitar a funcionalidade relacionada ao modelo — por exemplo, esmaecer ou ocultar parte de sua IU — até confirmar que o modelo foi baixado.
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); } } });
Muitos aplicativos iniciam a tarefa de download em seu código de inicialização, mas você pode fazer isso a qualquer momento antes de precisar usar o modelo.
3. Realize inferência nos dados de entrada
Obtenha as formas de entrada e saída do seu modelo
O interpretador de modelos do TensorFlow Lite recebe como entrada e produz como saída um ou mais arrays multidimensionais. Essas matrizes contêm valores
byte
,int
,long
oufloat
. Antes de passar dados para um modelo ou usar seu resultado, você deve saber o número e as dimensões ("forma") das matrizes que seu modelo usa.Se você mesmo construiu o modelo ou se o formato de entrada e saída do modelo estiver documentado, talvez você já tenha essas informações. Se você não conhece a forma e o tipo de dados de entrada e saída do seu modelo, pode usar o interpretador TensorFlow Lite para inspecionar seu modelo. Por exemplo:
Pitão
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']))
Saída de exemplo:
1 input(s): [ 1 224 224 3] <class 'numpy.float32'> 1 output(s): [1 1000] <class 'numpy.float32'>
Execute o interpretador
Depois de determinar o formato de entrada e saída de seu modelo, obtenha seus dados de entrada e execute as transformações necessárias nos dados para obter uma entrada com a forma correta para seu modelo.Por exemplo, se você tiver um modelo de classificação de imagem com uma forma de entrada de
[1 224 224 3]
valores de ponto flutuante, poderá gerar umByteBuffer
de entrada de um objetoBitmap
, conforme mostrado no exemplo a seguir: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); } }
Em seguida, aloque um
ByteBuffer
grande o suficiente para conter a saída do modelo e passe o buffer de entrada e o buffer de saída para o métodorun()
do interpretador do TensorFlow Lite. Por exemplo, para uma forma de saída de[1 1000]
valores de ponto flutuante: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);
Como você usa a saída depende do modelo que está usando.
Por exemplo, se você estiver realizando uma classificação, como próximo passo, você pode mapear os índices do resultado para os rótulos que eles representam:
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: segurança do modelo
Independentemente de como você disponibiliza seus modelos do TensorFlow Lite para o Firebase ML, o Firebase ML os armazena no formato protobuf serializado padrão no armazenamento local.
Em teoria, isso significa que qualquer pessoa pode copiar seu modelo. No entanto, na prática, a maioria dos modelos é tão específica do aplicativo e ofuscada por otimizações que o risco é semelhante ao de concorrentes desmontando e reutilizando seu código. No entanto, você deve estar ciente desse risco antes de usar um modelo personalizado em seu aplicativo.
No Android API nível 21 (Lollipop) e mais recente, o download do modelo é feito em um diretório excluído do backup automático .
Na API do Android nível 20 e anteriores, o download do modelo é feito em um diretório chamado
com.google.firebase.ml.custom.models
no armazenamento interno privado do aplicativo. Se você ativou o backup de arquivo usandoBackupAgent
, pode optar por excluir esse diretório.Exceto em caso de indicação contrária, o conteúdo desta página é licenciado de acordo com a Licença de atribuição 4.0 do Creative Commons, e as amostras de código são licenciadas de acordo com a Licença Apache 2.0. Para mais detalhes, consulte as políticas do site do Google Developers. Java é uma marca registrada da Oracle e/ou afiliadas.
Last updated 2023-02-03 UTC.
[{ "type": "thumb-down", "id": "missingTheInformationINeed", "label":"Não contém as informações de que eu preciso" },{ "type": "thumb-down", "id": "tooComplicatedTooManySteps", "label":"Muito complicado / etapas demais" },{ "type": "thumb-down", "id": "outOfDate", "label":"Desatualizado" },{ "type": "thumb-down", "id": "translationIssue", "label":"Problema na tradução" },{ "type": "thumb-down", "id": "samplesCodeIssue", "label":"Problema com as amostras / o código" },{ "type": "thumb-down", "id": "otherDown", "label":"Outro" }] [{ "type": "thumb-up", "id": "easyToUnderstand", "label":"Fácil de entender" },{ "type": "thumb-up", "id": "solvedMyProblem", "label":"Meu problema foi resolvido" },{ "type": "thumb-up", "id": "otherUp", "label":"Outro" }] - No manifesto do seu aplicativo, declare que a permissão de INTERNET é necessária: