Adicionar o Firebase ao seu app Android com TFLite

1. Visão geral

cd824ecfd05a2822.png

O Firebase ML permite que você implante seu modelo over the air. Assim, é possível manter o app pequeno e fazer o download do modelo de ML somente quando necessário, testar vários modelos ou atualizar seu modelo de ML sem precisar republicar o app inteiro.

Neste codelab, você converterá um app Android que usa um modelo estático do TFLite em um app usando um modelo disponibilizado dinamicamente pelo Firebase.

Conteúdo

  • Implante modelos do TFLite para o Firebase ML e acesse-os pelo seu app
  • Acompanhe o feedback dos usuários para medir a precisão do modelo com o Firebase Analytics
  • Gerar um perfil do desempenho do modelo com o Firebase Performance
  • Selecione qual dos vários modelos implantados é carregado pela Configuração remota
  • Teste modelos diferentes usando o Teste A/B do Firebase

O que é necessário

  • Versão mais recente do Android Studio
  • Exemplo de código.
  • Um dispositivo de teste com o Android 5.0 ou versões mais recentes e o Google Play Services 9.8 ou mais recente, ou um emulador com o Google Play Services 9.8 ou mais recente.
  • Se estiver usando um dispositivo, um cabo de conexão.

Como você vai usar este tutorial?

Apenas leitura Ler e fazer os exercícios

Como você classificaria sua experiência com a criação de apps Android?

Iniciante Intermediário Proficiente

2. Acessar o exemplo de código

Clone o repositório do GitHub na linha de comando.

$ git clone https://github.com/FirebaseExtended/codelab-digitclassifier-android.git

Se o git não estiver instalado, faça o download do projeto de exemplo na página do GitHub ou clique neste link.

3. Importar o app inicial

No Android Studio, selecione o diretório codelab-digitclassifier-android ( android_studio_folder.png) no download do exemplo de código (File > Open > .../codelab-digitalclassifier-android/start).

O projeto inicial está aberto no Android Studio.

4. Executar o app inicial

Agora que você importou o projeto para o Android Studio, está pronto para executar o app pela primeira vez. Conecte o dispositivo Android e clique em Run ( executar.png) na barra de ferramentas do Android Studio.

O app vai ser aberto no dispositivo. Nesse momento, se você tentar desenhar um dígito, o app será capaz de reconhecê-lo.

6e36e1b947b395f2.png

5. Criar projeto do Console do Firebase

Adicionar o Firebase ao projeto

  1. Acesse o Console do Firebase.
  2. Selecione Adicionar projeto.
  3. Selecione ou digite o nome do projeto.
  4. Siga as demais etapas de configuração no Console do Firebase e clique em "Criar projeto" (ou "Adicionar Firebase", se você estiver usando um projeto do Google).

6. Adicionar Firebase

  1. Na tela de visão geral do novo projeto, clique no ícone do Android para iniciar o fluxo de trabalho de configuração.
  2. Insira o nome do pacote do codelab: org.tensorflow.lite.examples.digitclassifier.

Adicionar o arquivo google-services.json ao seu app

Depois de registrar o nome do pacote e selecionar Próximo,clique em Fazer o download de google-services.json para receber o arquivo de configuração do Firebase para Android e copie o arquivo google-services.json no diretório app do seu projeto. Depois de fazer o download do arquivo, você pode clicar em Skip para pular as próximas etapas mostradas no console. Elas já foram realizadas no projeto build-android-start.

Adicionar o plug-in google-services ao app

O plug-in google-services usa o arquivo google-services.json para configurar seu aplicativo para usar o Firebase. Adicione a linha abaixo ao bloco plugins na parte de cima do arquivo build.gradle.kts no diretório app do projeto:

app/build.gradle.kts (link em inglês)

id("com.google.gms.google-services")

Em seguida, adicione a linha abaixo ao bloco plugins do arquivo build.gradle.kts no projeto:

project/build.gradle.kts (link em inglês)

id("com.google.gms.google-services") version "4.3.15" apply false

Sincronizar o projeto com arquivos do Gradle

Para garantir que todas as dependências estejam disponíveis para o app, sincronize seu projeto com os arquivos do Gradle nesse momento. Selecione File > Sync Project with Gradle Files na barra de ferramentas do Android Studio.

7. Executar o app com o Firebase

Agora que você configurou o plug-in google-services com o arquivo JSON, está pronto para executar o app com o Firebase. Conecte o dispositivo Android e clique em Run ( executar.png) na barra de ferramentas do Android Studio.

O app vai ser aberto no dispositivo. Nesse momento, o app ainda será criado.

8. Implantar um modelo no Firebase ML

A implantação de um modelo no Firebase ML é útil por dois motivos principais:

  1. Podemos manter o tamanho da instalação do app pequeno e fazer o download do modelo apenas se necessário
  2. O modelo pode ser atualizado regularmente e com um ciclo de lançamento diferente do que todo o app

Antes de substituir o modelo estático no app por um modelo baixado dinamicamente do Firebase, é preciso implantá-lo no Firebase ML. O modelo pode ser implantado por meio do console ou de forma programática com o SDK Admin do Firebase. Nesta etapa, vamos implantar pelo console.

Para simplificar, usaremos o modelo do TensorFlow Lite que já está no nosso app. Primeiro, abra o Console do Firebase e clique em Machine Learning no painel de navegação à esquerda. Clique em "Começar" se estiver abrindo esta página pela primeira vez. Depois navegue até "Personalizado" e clique no botão "Adicionar modelo personalizado".

Quando solicitado, dê um nome descritivo ao modelo, como mnist_v1, e faça upload do arquivo do diretório do projeto do codelab em start/app/src/main/assets/mnist.tflite. Em seguida, você pode excluir esse arquivo de modelo do TF Lite do projeto Android.

3c3c50e6ef12b3b.png

9. Fazer o download do modelo do Firebase ML

Escolher quando fazer o download do modelo remoto do Firebase para seu aplicativo pode ser complicado, já que os modelos do TFLite podem crescer relativamente. O ideal é evitar o carregamento do modelo imediatamente após a inicialização do app, já que se o modelo for usado para apenas um recurso e o usuário nunca utilizar esse recurso, uma quantidade significativa de dados será baixada sem motivo. Também é possível definir opções de download, como buscar modelos apenas quando conectado a uma rede Wi-Fi. Para garantir que o modelo esteja disponível mesmo sem uma conexão de rede, é importante agrupá-lo sem o app como backup.

Para simplificar, removeremos o modelo de pacote padrão e sempre faremos o download de um modelo do Firebase quando o app for iniciado. Dessa forma, ao executar o reconhecimento de dígitos, você tem certeza de que a inferência está sendo executada com o modelo fornecido pelo Firebase.

No arquivo app/build.gradle.kts, adicione a dependência do Firebase Machine Learning

app/build.gradle.kts (link em inglês)

implementation("com.google.firebase:firebase-ml-modeldownloader:24.1.2")

Em seguida, adicione lógica para fazer o download do modelo do Firebase.

Substituiremos digitClassifier.initialize(loadModelFile()) por downloadModel("mnist_v1") e implementaremos esse método.

MainActivity.kt (link em inglês)

  private fun downloadModel(modelName: String): Task<CustomModel> {
    val conditions = CustomModelDownloadConditions.Builder()
    .requireWifi()
    .build()
    return FirebaseModelDownloader.getInstance()
        .getModel(modelName, DownloadType.LOCAL_MODEL, conditions)
        .addOnCompleteListener {
          val model = it.result
          if (model == null) {
            showToast("Failed to get model file.")
          } else {
            showToast("Downloaded remote model: $modelName")
            digitClassifier.initialize(model)
          }
        }
      .addOnFailureListener {
        showToast("Model download failed for $modelName, please check your connection.")
      }
  }

Execute o app novamente e desenhe um dígito no classificador de dígitos. Quando o download terminar, você vai receber uma mensagem de aviso informando que o download do modelo remoto foi feito e um registro indicando que o novo modelo está sendo usado.

10. Acompanhe o feedback e a conversão dos usuários para medir a precisão do modelo

O Google Analytics para Firebase oferece uma maneira de entender como os usuários navegam pelo seu aplicativo, onde eles são bem-sucedidos e onde ficam presos e voltam. Ele também pode ser usado para entender as partes mais usadas do seu aplicativo.

Vamos medir a acurácia do modelo rastreando o feedback dos usuários sobre as previsões do modelo. Se o usuário clicar em "SIM", isso indicará que a previsão foi precisa.

Podemos registrar um evento do Analytics para acompanhar a acurácia do nosso modelo. Primeiro, precisamos adicionar o Analytics à dependência antes que ele possa ser usado no projeto:

Adicionar dependência do Firebase Analytics

app/build.gradle.kts (link em inglês)

implementation(platform("com.google.firebase:firebase-bom:32.0.0"))
implementation("com.google.firebase:firebase-analytics-ktx")

Registrar eventos

Em seguida, na função onCreate, definiremos o listener "onclick" para registrar o evento correct_inference no Firebase.

MainActivity.kt (onCreate)

// Setup YES button
yesButton?.setOnClickListener {
  Firebase.analytics.logEvent("correct_inference", null)
}

Execute o app novamente e desenhe um dígito. Pressione o botão "Yes" algumas vezes para enviar feedback informando que a inferência foi precisa.

Análise de depuração

Em geral, os eventos registrados pelo seu aplicativo são agrupados ao longo de aproximadamente uma hora e enviados juntos. Essa abordagem economiza a bateria dos dispositivos dos usuários finais e reduz o uso de dados de rede. No entanto, para validar sua implementação de análise (e para consultar sua análise no Relatório do DebugView), você pode ativar o modo de depuração no seu dispositivo de desenvolvimento para fazer upload de eventos com um atraso mínimo.

Para ativar o modo de depuração do Google Analytics em um dispositivo Android, execute os seguintes comandos:

adb shell setprop debug.firebase.analytics.app org.tensorflow.lite.examples.digitclassifier

Execute o app novamente e desenhe um dígito. Pressione o botão "Yes" algumas vezes para enviar feedback informando que a inferência foi precisa. Agora é possível exibir os eventos de registro quase em tempo real pela visualização de depuração no Console do Firebase. Clique em Analytics > DebugView na barra de navegação à esquerda.

5276199a086721fd.png

11. Analisar o desempenho do modelo

O Monitoramento de desempenho do Firebase é um serviço que ajuda a receber insights sobre as características de desempenho dos apps Apple, Android e da Web.

Use o SDK do Monitoramento de desempenho para coletar dados de desempenho do seu app, revisar e analisar esses dados no Console do Firebase. O Monitoramento de desempenho ajuda você a entender onde e quando o desempenho do seu app pode ser melhorado. Assim, você pode usar essas informações para corrigir problemas de desempenho.

Aqui, adicionamos rastros de performance para inferência e download

Isso é importante porque modelos maiores usados em aprendizado profundo têm o potencial de serem mais precisos, mas também podem levar mais tempo para retornar uma resposta. Em nossos testes, tentamos encontrar o equilíbrio certo entre acurácia e velocidade.

Adicionar dependência do Firebase Performance

project/build.gradle.kts (link em inglês)

plugins {
  // ...

  // Add the dependency for the Performance Monitoring plugin
  id("com.google.firebase.firebase-perf") version "1.4.2" apply false
}

app/build.gradle.kts (link em inglês)

plugins {
  // ...

  // Add the Performance Monitoring plugin
  id("com.google.firebase.firebase-perf")
}

// ...

dependencies {
  // ...

  // Add the dependency for the Performance Monitoring library
  implementation("com.google.firebase:firebase-perf")
}

Adicionar traces personalizados

Na função setupDigitClassifier(), crie um novo downloadTrace e inicie-o logo antes de fazer o download do modelo. Em seguida, adicione um listener onsuccess para interromper o rastro.

Na função classifyDrawing(), crie um novo classifyTrace e inicie-o imediatamente antes da classificação. Em seguida, interrompa o trace no listener onsuccess.

MainActivity.kt (link em inglês)

class MainActivity : AppCompatActivity() {
  // ...
  
  private val firebasePerformance = FirebasePerformance.getInstance()
  
  // ...

  private fun setupDigitClassifier() {
    // Add these lines to create and start the trace
    val downloadTrace = firebasePerformance.newTrace("download_model")
    downloadTrace.start()
    downloadModel("mnist_v1")
      // Add these lines to stop the trace on success
      .addOnSuccessListener {
        downloadTrace.stop()
      }
  }

// ...

  private fun classifyDrawing() {
    val bitmap = drawView?.getBitmap()

    if ((bitmap != null) && (digitClassifier.isInitialized)) {
      // Add these lines to create and start the trace
      val classifyTrace = firebasePerformance.newTrace("classify")
      classifyTrace.start()
      digitClassifier
        .classifyAsync(bitmap)
        .addOnSuccessListener { resultText -> 
          // Add this line to stop the trace on success
          classifyTrace.stop()
          predictedTextView?.text = resultText
        }
        .addOnFailureListener { e ->
          predictedTextView?.text = getString(
            R.string.tfe_dc_classification_error_message,
            e.localizedMessage
          )
          Log.e(TAG, "Error classifying drawing.", e)
        }
    }
  }

Exibir mensagens de registro de eventos de desempenho

  1. Ative a geração de registros de depuração do Monitoramento de desempenho no tempo de build adicionando um elemento <meta-data> ao arquivo AndroidManifest.xml do seu app da seguinte forma:

AndroidManifest.xml

<application>
    <meta-data
      android:name="firebase_performance_logcat_enabled"
      android:value="true" />
</application>
  1. Verifique se há mensagens de erro nas mensagens de registro.
  2. O Monitoramento de desempenho marca as mensagens de registro com FirebasePerformance. Ao usar a filtragem do logcat, é possível visualizar especificamente o registro de rastreamento de duração e de solicitações de rede HTTP/S. Basta executar o seguinte comando:
adb logcat -s FirebasePerformance
  1. Verifique os seguintes tipos de registro que indicam que o Monitoramento de desempenho está registrando eventos de desempenho:
  • Logging TraceMetric
  • Logging NetworkRequestMetric

12. Implantar um segundo modelo no Firebase ML

Ao criar uma nova versão do seu modelo, como uma com melhor arquitetura ou treinada com um conjunto de dados maior ou atualizado, podemos nos sentir tentados a substituir o modelo atual pela versão nova. No entanto, um modelo com bom desempenho em testes não necessariamente terá um desempenho tão bom na produção. Portanto, vamos fazer testes A/B na produção para comparar o modelo original e o novo.

Ativar a API Firebase Model Management

Nesta etapa, ativaremos a API Firebase Model Management para implantar uma nova versão do nosso modelo do TensorFlow Lite usando código Python.

Crie um bucket para armazenar seus modelos de ML

No Console do Firebase, acesse Storage e clique em "Começar". fbbea78f0eb3dc9f.png

Siga as mensagens para configurar o bucket.

19517c0d6d2aa14d.png

Ativar a API Firebase ML

Acesse a página da API Firebase ML no console do Google Cloud e clique em "Ativar".

2414fd5cced6c984.pngQuando solicitado, selecione o app Digit Classifier.

Treinar um novo modelo e publicar no Firebase ML

Agora vamos treinar uma nova versão do modelo usando um conjunto de dados maior. Depois, vamos fazer a implantação de maneira programática diretamente do notebook de treinamento usando o SDK Admin do Firebase.

Fazer o download da chave privada da conta de serviço

Para podermos usar o SDK Admin do Firebase, precisamos criar uma conta de serviço. Clique neste link para abrir o painel "Contas de serviço" do Console do Firebase e crie uma nova conta de serviço para o SDK Admin do Firebase. Quando solicitado, clique no botão Gerar nova chave privada. Usaremos a chave da conta de serviço para autenticar nossas solicitações do notebook do Colab.

c3b95de1e5508516.png

Agora podemos treinar e implantar o novo modelo.

  1. Abra este bloco do Colab e faça uma cópia dele no seu Drive.
  2. Execute a primeira célula "Treinar um modelo aprimorado do TensorFlow Lite" clicando no botão de reprodução à esquerda. Isso vai treinar um novo modelo e pode levar algum tempo.
  3. Executar a segunda célula cria um prompt de upload de arquivo. Faça upload do arquivo JSON que você baixou do console do Firebase ao criar sua conta de serviço.

71e847c6a85423b3.png

  1. Execute as duas últimas células.

Depois de executar o notebook do Colab, um segundo modelo será exibido no Console do Firebase. Verifique se o nome do segundo modelo é mnist_v2.

c316683bb4d75d57.png

13. Selecione um modelo usando a Configuração remota

Agora que temos dois modelos separados, vamos adicionar um parâmetro para selecionar o modelo que será transferido por download no tempo de execução. O valor do parâmetro que o cliente recebe determina de qual modelo o cliente faz o download.

Adicionar regras de configuração no Console do Firebase

Primeiro, abra o Console do Firebase e clique no botão Configuração remota no menu de navegação à esquerda. Depois, clique no botão "Adicionar parâmetro".

Nomeie o novo parâmetro como model_name e atribua a ele o valor padrão de "mnist_v1". Ao colocar o nome do modelo no parâmetro da Configuração remota, é possível testar vários modelos sem adicionar um novo parâmetro para cada um deles. Clique em Publicar alterações para aplicar as atualizações.

2949cb95c7214ca4.png

Adicionar dependência do Firebase RemoteConfig

app/build.gradle.kts (link em inglês)

implementation("com.google.firebase:firebase-config-ktx")

Definir a Configuração remota do Firebase

MainActivity.kt (link em inglês)

  private fun configureRemoteConfig() {
    remoteConfig = Firebase.remoteConfig
    val configSettings = remoteConfigSettings {
      minimumFetchIntervalInSeconds = 3600
    }
    remoteConfig.setConfigSettingsAsync(configSettings)
  }

Solicitar e usar configuração

Crie uma solicitação de busca para a configuração e adicione um gerenciador de conclusão para selecionar e usar os parâmetros de configuração.

MainActivity.kt (link em inglês)

 private fun setupDigitClassifier() {
    configureRemoteConfig()
    remoteConfig.fetchAndActivate()
      .addOnCompleteListener { task ->
        if (task.isSuccessful) {
          val modelName = remoteConfig.getString("model_name")
          val downloadTrace = firebasePerformance.newTrace("download_model")
          downloadTrace.start()
          downloadModel(modelName)
            .addOnSuccessListener {
              downloadTrace.stop()
            }
        } else {
          showToast("Failed to fetch model name.")
        }
      }
  }

Testar a Configuração remota

  1. Clique no botão 98205811bbed9d74.pngRun.
  2. Verifique se você vê a mensagem Toast informando que o download do modelo mnist_v1 foi feito.
  3. Volte para o Console do Firebase, altere o valor padrão para mnist_v2 e selecione Publicar alterações para aplicar as atualizações.
  4. Reinicie o app e confira a mensagem Toast informando que o download do modelo mnist_v2 foi feito desta vez.

14. Eficácia do modelo de teste A/B

O Teste A/B do Firebase ajuda você a otimizar a experiência no seu app. Com esse recurso, é fácil executar, analisar e escalonar experimentos de produtos e de marketing. Por fim, podemos usar o comportamento integrado do Teste A/B do Firebase para ver qual dos nossos dois modelos tem o melhor desempenho.

Acesse Analytics -> Eventos no Console do Firebase. Se o evento correct_inference estiver aparecendo, marque-o como "Evento de conversão". Caso contrário, acesse "Analytics -> Eventos de conversão", clique em "Criar um novo evento de conversão" e salve o correct_inference..

Agora acesse "Configuração remota no Console do Firebase" e selecione o botão "Teste A/B" no menu "Mais opções" no parâmetro "model_name" que acabamos de adicionar.

fad5ea36969d2aeb.png

No menu a seguir, aceite o nome padrão.

d7c006669ace6e40.png

Selecione seu app no menu suspenso e mude os critérios de segmentação para 50% de usuários ativos.

cb72dcc7d2666bd3.png

Se você conseguiu definir o evento correct_inference como uma conversão antes, use-o como a métrica principal de acompanhamento. Caso contrário, se você não quiser esperar o evento aparecer no Analytics, adicione correct_inference manually.

1ac9c94fb3159271.png

Por fim, na tela "Variantes", defina a variante do grupo de controle como mnist_v1 e o grupo da variante A como mnist_v2.

e4510434f8da31b6.png

Clique no botão "Revisar" no canto inferior direito.

Parabéns! Você criou um teste A/B para os dois modelos diferentes. No momento, o teste A/B está em estado de rascunho e pode ser iniciado a qualquer momento clicando no botão "Iniciar experimento".

Para saber mais sobre o teste A/B, consulte a documentação relacionada.

15. Parabéns!

Neste codelab, você aprendeu a substituir um recurso tflite estaticamente agrupado no seu app por um modelo TFLite carregado dinamicamente no Firebase. Para saber mais sobre o TFLite e o Firebase, confira outros exemplos do TFLite e os guias de iniciação do Firebase.

O que aprendemos

  • TensorFlow Lite
  • Firebase ML
  • Firebase Analytics
  • Monitoramento de desempenho do Firebase
  • Configuração remota do Firebase
  • Teste A/B do Firebase

Próximas etapas

  • Implemente a implantação do Firebase ML no seu app.

Saiba mais

Perguntas?

Informar problemas