Adicionar recomendações ao app com o TensorFlow Lite e o Firebase: codelab para iOS

1. Visão geral

Este é o codelab Recomendações com o TensorFlow Lite e o Firebase. Neste codelab, você aprenderá a usar o TensorFlow Lite e o Firebase para implantar um modelo de recomendação no seu app. Este codelab é baseado neste exemplo do TensorFlow Lite.

As recomendações permitem que os apps usem o aprendizado de máquina para veicular de maneira inteligente o conteúdo mais relevante para cada usuário. Eles consideram o comportamento anterior do usuário para sugerir um conteúdo com que o usuário possa interagir no futuro usando um modelo treinado no comportamento agregado de um grande número de outros usuários.

Neste tutorial, mostramos como receber dados dos usuários do seu aplicativo com o Firebase Analytics, criar um modelo de machine learning para recomendações com base nesses dados e, em seguida, usar esse modelo em um app iOS para executar inferência e receber recomendações. Em particular, nossas recomendações vão sugerir a quais filmes um usuário provavelmente assistiria, considerando a lista de filmes que ele já gostou anteriormente.

Conteúdo

  • Integrar o Firebase Analytics a um aplicativo Android para coletar dados de comportamento do usuário
  • Exportar esses dados para o Google BigQuery
  • Pré-processar os dados e treinar um modelo de recomendações do TF Lite
  • Implante o modelo do TF Lite no Firebase ML e acesse-o pelo app
  • Executar inferências no dispositivo usando o modelo para sugerir recomendações aos usuários

Pré-requisitos

  • Xcode 11 (ou versão mais recente)
  • CocoaPods 1.9.1 (ou mais recente)

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 iOS?

Iniciante Intermediário Proficiente

2. Criar projeto do Console do Firebase

Adicionar o Firebase ao projeto

  1. Acesse o Console do Firebase.
  2. Selecione Criar novo projeto e dê a ele o nome "Firebase ML iOS Codelab".

3. Acesse o projeto de amostra

Faça o download do código

Comece clonando o projeto de amostra e executando pod update no diretório do projeto:

git clone https://github.com/FirebaseExtended/codelab-contentrecommendation-ios.git
cd codelab-contentrecommendation-ios/start
pod install --repo-update

Se o git não estiver instalado, faça o download do projeto de exemplo na página do GitHub ou clique neste link. Depois de fazer o download do projeto, execute-o no Xcode e teste a recomendação para ter uma ideia de como ele funciona.

Configurar o Firebase

Siga a documentação para criar um novo projeto do Firebase. Quando tiver seu projeto, faça o download do arquivo GoogleService-Info.plist dele no Console do Firebase e arraste-o para a raiz do projeto Xcode.

4a923d5c7ae0d8f3.png

Adicione o Firebase ao seu Podfile e execute a instalação do pod.

pod 'FirebaseAnalytics'
pod 'FirebaseMLModelDownloader', '9.3.0-beta'
pod 'TensorFlowLiteSwift'

No método didFinishLaunchingWithOptions do AppDelegate, importe o Firebase na parte de cima do arquivo.

import FirebaseCore

E adicionar uma chamada para configurar o Firebase.

FirebaseApp.configure()

Execute o projeto novamente para garantir que o app esteja configurado corretamente e não falhe após a inicialização.

  1. Verifique se a opção "Ativar o Google Analytics para este projeto" está ativada.
  2. 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).

4. Adicionar o Firebase Analytics ao app

Nesta etapa, você adicionará o Firebase Analytics ao aplicativo para registrar dados de comportamento do usuário (nesse caso, que filma um usuário gosta). Esses dados vão ser usados de forma agregada nas próximas etapas para treinar o modelo de recomendações.

Configurar o Firebase Analytics no app

O LikedMoviesViewModel contém funções para armazenar os filmes que o usuário gosta. Sempre que um usuário gosta de um novo filme, queremos também enviar um evento de registro de análise para registrar essa marcação.

Adicione o código abaixo para registrar um evento de análise quando o usuário clicar em um filme.

AllMoviesCollectionViewController.swift (em inglês)

import FirebaseAnalytics
//


override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
//

if movie.liked == nil {
      movie.liked = true
      Analytics.logEvent(AnalyticsEventSelectItem, parameters: [AnalyticsParameterItemID: movie.id])
    } else {
      movie.liked?.toggle()
    }
       
}

5. Testar sua integração com o Google Analytics

Nesta etapa, vamos gerar eventos do Analytics no app e verificar se eles estão sendo enviados para o Console do Firebase.

Ativar os registros de depuração do Analytics

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 Analytics no seu dispositivo de desenvolvimento, especifique o seguinte argumento de linha de comando no Xcode:

-FIRDebugEnabled

Você integrou o Firebase Analytics ao seu app. À medida que os usuários usarem o app e, como em filmes, as marcações "gostei" serão registradas de forma agregada. Usaremos esses dados agregados no restante deste codelab para treinar nosso modelo de recomendações. A etapa a seguir é opcional para que os mesmos eventos do Analytics encontrados no Logcat também sejam transmitidos para o Console do Firebase. Sinta-se à vontade para pular para a próxima página.

Opcional: confirme os eventos do Analytics no Console do Firebase

  1. Acesse o Console do Firebase.
  2. Selecione DebugView em Analytics.
  3. No Xcode, selecione Run para iniciar o app e adicionar alguns filmes à lista de marcações "Gostei".
  4. No DebugView do Console do Firebase, verifique se esses eventos estão sendo registrados à medida que você adiciona filmes no app.

6. Exportar dados do Google Analytics para o BigQuery

O Big Query é um produto do Google Cloud que permite examinar e processar grandes quantidades de dados. Nesta etapa, você conectará seu projeto do Console do Firebase ao BigQuery para que os dados do Analytics gerados pelo seu app sejam exportados automaticamente para o BigQuery.

Ativar a exportação do BigQuery

  1. Acesse o Console do Firebase.
  2. Selecione o ícone de engrenagem ao lado de Visão geral do projeto e depois Configurações do projeto.
  3. Selecione a guia Integrações.
  4. Selecione Vincular (ou Gerenciar) no bloco do BigQuery.
  5. Selecione Próxima na etapa Como vincular o Firebase ao BigQuery.
  6. Na seção Configurar integração, clique na chave para ativar o envio de dados do Google Analytics e selecione Vincular ao BigQuery.

Você ativou seu projeto do Console do Firebase para enviar automaticamente dados de eventos do Firebase Analytics para o BigQuery. Isso acontece automaticamente sem outras interações. No entanto, a primeira exportação que cria o conjunto de dados de análise no BigQuery pode levar até 24 horas. Após a criação do conjunto de dados, o Firebase exporta continuamente novos eventos do Analytics para o BigQuery na tabela intradiária e agrupa os eventos dos dias anteriores na tabela de eventos.

Treinar um modelo de recomendações requer muitos dados. Como ainda não temos um app que gera grandes quantidades de dados, na próxima etapa importaremos um conjunto de dados de amostra para o BigQuery para usar no restante deste tutorial.

7. Use o BigQuery para receber dados de treinamento de modelo

Agora que conectamos o console do Firebase para exportar para o BigQuery, os dados de eventos de análise de aplicativos aparecerão automaticamente no console do BigQuery após algum tempo. Para obter alguns dados iniciais para os propósitos deste tutorial, nesta etapa importaremos um conjunto de dados de amostra existente para seu console do BigQuery a fim de usar para treinar nosso modelo de recomendações.

Importar conjunto de dados de amostra para o BigQuery

  1. Acesse o painel do BigQuery no console do Google Cloud.
  2. Selecione o nome do projeto no menu.
  3. Selecione o nome do seu projeto na parte inferior do painel de navegação à esquerda do BigQuery para ver os detalhes.
  4. Selecione Criar conjunto de dados para abrir o painel de criação do conjunto de dados.
  5. Insira "firebase_recommendations_dataset" como o ID do conjunto de dados e selecione Criar conjunto de dados.
  6. O novo conjunto de dados vai aparecer no menu à esquerda, abaixo do nome do projeto. Clique nele.
  7. Selecione Criar tabela para abrir o painel de criação de tabelas.
  8. Em Criar tabela de, selecione "Google Cloud Storage".
  9. No campo Selecionar arquivo do bucket do GCS, insira "gs://firebase-recommendations/recommendations-test/formatted_data_filtered.txt".
  10. Selecione "JSONL" no menu suspenso Formato do arquivo.
  11. Insira "recommendations_table" como o Nome da tabela.
  12. Marque a caixa em Esquema > Detectar automaticamente > Parâmetros de esquema e entrada.
  13. Selecione Criar tabela.

Analisar o conjunto de dados de amostra

Neste ponto, é possível explorar o esquema e visualizar o conjunto de dados.

  1. Selecione firebase-recommendations-dataset no menu à esquerda para expandir as tabelas que ele contém.
  2. Selecione a tabela recommendations-table para ver o esquema dela.
  3. Selecione Visualizar para conferir os dados reais de eventos do Google Analytics que a tabela contém.

Criar credenciais de conta de serviço

Agora, vamos criar credenciais de conta de serviço no projeto do console do Google Cloud que podem ser usadas no ambiente do Colab na próxima etapa para acessar e carregar os dados do BigQuery.

  1. Verifique se a cobrança está ativada para o projeto do Google Cloud.
  2. Ative as APIs BigQuery e BigQuery Storage API. < clique aqui>
  3. Acesse a página Criar chave da conta de serviço.
  4. Na lista Conta de serviço, selecione Nova conta de serviço.
  5. No campo Nome da conta de serviço, insira um nome.
  6. Na lista Papel, selecione Projeto > Proprietário.
  7. Clique em Criar. O download de um arquivo JSON com sua chave é feito no seu computador.

Na próxima etapa, vamos usar o Google Colab para pré-processar esses dados e treinar nosso modelo de recomendações.

8. Pré-processar dados e treinar o modelo de recomendações

Nesta etapa, vamos usar um bloco do Colab para realizar as seguintes etapas:

  1. importar os dados do BigQuery para o bloco do Colab
  2. pré-processar os dados para prepará-los para o treinamento do modelo
  3. treinar o modelo de recomendações nos dados de análise
  4. exportar o modelo como TF Lite
  5. implantar o modelo no console do Firebase para que possamos usá-lo no nosso app

Antes de lançar o bloco de treinamento do Colab, vamos ativar a API Firebase Model Management para que o Colab possa implantar o modelo treinado no console do Firebase.

Ativar a API Firebase Model Management

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".

Usar o bloco do Colab para treinar e implantar o modelo

Abra o notebook do Colab usando o link abaixo e conclua as etapas nele. Depois de concluir as etapas no bloco do Colab, você terá um arquivo de modelo do TF Lite implantado no console do Firebase que poderá ser sincronizado com nosso app.

Abrir no Colab

9. Fazer o download do modelo no seu app

Nesta etapa, modificaremos nosso app para fazer o download do modelo que acabamos de treinar com o Firebase Machine Learning.

Adicionar dependência do Firebase ML

A dependência a seguir é necessária para usar modelos de machine learning do Firebase no seu app. Ela já deve ter sido adicionada (verificar).

Podfile

import FirebaseCore
import FirebaseMLModelDownloader

Fazer o download do modelo com a API Firebase Model Manager

Copie o código abaixo no ModelLoader.swift para configurar as condições em que o download do modelo ocorre e crie uma tarefa de download para sincronizar o modelo remoto com o app.

ModelLoader.swift (link em inglês)

static func downloadModel(named name: String,
                            completion: @escaping (CustomModel?, DownloadError?) -> Void) {
    guard FirebaseApp.app() != nil else {
      completion(nil, .firebaseNotInitialized)
      return
    }
    guard success == nil && failure == nil else {
      completion(nil, .downloadInProgress)
      return
    }
    let conditions = ModelDownloadConditions(allowsCellularAccess: false)
    ModelDownloader.modelDownloader().getModel(name: name, downloadType: .localModelUpdateInBackground, conditions: conditions) { result in
            switch (result) {
            case .success(let customModel):
                    // Download complete.
                    // The CustomModel object contains the local path of the model file,
                    // which you can use to instantiate a TensorFlow Lite classifier.
                    return completion(customModel, nil)
            case .failure(let error):
                // Download was unsuccessful. Notify error message.
              completion(nil, .downloadFailed(underlyingError: error))
            }
    }
  }

10. Integre o modelo de recomendação do Tensorflow Lite ao seu app

O ambiente de execução do Tensorflow Lite permite que você use seu modelo no app para gerar recomendações. Na etapa anterior, inicializamos um intérprete do TFlite com o arquivo de modelo que transferimos por download. Nesta etapa, primeiro vamos carregar um dicionário e rótulos para acompanhar nosso modelo na etapa de inferência. Depois, vamos adicionar o pré-processamento para gerar as entradas e o pós-processamento, em que vamos extrair os resultados da inferência.

Carregar dicionário e rótulos

Os rótulos usados para gerar os candidatos a recomendação pelo modelo de recomendações são listados no arquivo sorted_movie_vocab.json na pasta de recursos. Copie o código a seguir para carregar esses candidatos.

RecommendationsViewController.swift (em inglês)

  func getMovies() -> [MovieItem] {
    let barController = self.tabBarController as! TabBarController
    return barController.movies
  }

Implementar o pré-processamento

Na etapa de pré-processamento, alteramos a forma dos dados de entrada para corresponder ao que o modelo espera. Aqui, preenchemos o comprimento da entrada com um valor de marcador se ainda não tivermos gerado muitas curtidas do usuário. Copie o código abaixo:

RecommendationsViewController.swift (em inglês)

  // Given a list of selected items, preprocess to get tflite input.
  func preProcess() -> Data {
    let likedMovies = getLikedMovies().map { (MovieItem) -> Int32 in
      return MovieItem.id
    }
    var inputData = Data(copyingBufferOf: Array(likedMovies.prefix(10)))

    // Pad input data to have a minimum of 10 context items (4 bytes each)
    while inputData.count < 10*4 {
      inputData.append(0)
    }
    return inputData
  }

Executar o intérprete para gerar recomendações

Aqui, usamos o modelo salvo na etapa anterior para executar a inferência na entrada pré-processada. Definimos o tipo de entrada e saída do modelo e executamos inferência para gerar as recomendações de filmes. Copie o código a seguir no seu app.

RecommendationsViewController.swift (em inglês)

import TensorFlowLite

RecommendationsViewController.swift (em inglês)

 private var interpreter: Interpreter?

 func loadModel() {
    // Download the model from Firebase
    print("Fetching recommendations model...")
    ModelDownloader.fetchModel(named: "recommendations") { (filePath, error) in
      guard let path = filePath else {
        if let error = error {
          print(error)
        }
        return
      }
      print("Recommendations model download complete")
      self.loadInterpreter(path: path)
    }
  }

 func loadInterpreter(path: String) {
    do {
      interpreter = try Interpreter(modelPath: path)

      // Allocate memory for the model's input `Tensor`s.
      try interpreter?.allocateTensors()

      let inputData = preProcess()

      // Copy the input data to the input `Tensor`.
      try self.interpreter?.copy(inputData, toInputAt: 0)

      // Run inference by invoking the `Interpreter`.
      try self.interpreter?.invoke()

      // Get the output `Tensor`
      let confidenceOutputTensor = try self.interpreter?.output(at: 0)
      let idOutputTensor = try self.interpreter?.output(at: 1)

      // Copy output to `Data` to process the inference results.
      let confidenceOutputSize = confidenceOutputTensor?.shape.dimensions.reduce(1, {x, y in x * y})

      let idOutputSize = idOutputTensor?.shape.dimensions.reduce(1, {x, y in x * y})

      let confidenceResults =
        UnsafeMutableBufferPointer<Float32>.allocate(capacity: confidenceOutputSize!)
      let idResults =
        UnsafeMutableBufferPointer<Int32>.allocate(capacity: idOutputSize!)
      _ = confidenceOutputTensor?.data.copyBytes(to: confidenceResults)
      _ = idOutputTensor?.data.copyBytes(to: idResults)

      postProcess(idResults, confidenceResults)

      print("Successfully ran inference")
      DispatchQueue.main.async {
        self.tableView.reloadData()
      }
    } catch {
      print("Error occurred creating model interpreter: \(error)")
    }
  }

Implementar o pós-processamento

Por fim, nesta etapa, fazemos o pós-processamento da saída do modelo, selecionando os resultados com maior confiança e removendo os valores contidos (filmes que o usuário já gostou). Copie o código a seguir no seu app.

RecommendationsViewController.swift (em inglês)

  // Postprocess to get results from tflite inference.
  func postProcess(_ idResults: UnsafeMutableBufferPointer<Int32>, _ confidenceResults: UnsafeMutableBufferPointer<Float32>) {
    for i in 0..<10 {
      let id = idResults[i]
      let movieIdx = getMovies().firstIndex { $0.id == id }
      let title = getMovies()[movieIdx!].title
      recommendations.append(Recommendation(title: title, confidence: confidenceResults[i]))
    }
  }

Teste seu app

Execute o app novamente. Conforme você seleciona alguns filmes, ele faz o download automático do novo modelo e começa a gerar recomendações.

11. Parabéns!

Você criou um recurso de recomendações no app usando o TensorFlow Lite e o Firebase. As técnicas e o pipeline mostrados neste codelab podem ser generalizados e usados para disponibilizar outros tipos de recomendações.

O que aprendemos

  • Firebase ML
  • Firebase Analytics
  • Exportar eventos de análise para o BigQuery
  • Pré-processar eventos de análise
  • Treinar recomendações de modelo do TensorFlow
  • Exportar modelo e implantar no Console do Firebase
  • Veicular recomendações de filmes em um app

Próximas etapas

  • Implemente recomendações do Firebase ML no seu app.

Saiba mais

Perguntas?

Informar problemas