Reconhecer flores com o TensorFlow Lite no iOS

1. Introdução

657431be3173fa86.png

O TensorFlow é um framework de machine learning para várias finalidades. O TensorFlow pode ser usado de diversas formas, desde o treinamento de modelos enormes em clusters na nuvem até a execução local de modelos em um sistema incorporado, como seu smartphone.

Este codelab usa o TensorFlow Lite para executar um modelo de reconhecimento de imagem em um dispositivo iOS.

O que você vai aprender

  • Como otimizar seu modelo usando o conversor do TFLite.
  • Como executá-lo em um app iOS pré-criado usando o intérprete do TFLite.

O que você criará

Um app de câmera simples que executa um programa de reconhecimento de imagem do TensorFlow para identificar flores.

Pré-requisitos

Se você estiver fazendo este codelab no seu próprio hardware, confira se tem o seguinte instalado:

  • Xcode 10 ou mais recente
  • CocoaPods 1.8.0 ou mais recente

c45ecd122998622e.png

Licença: sem custo financeiro

2. Treinar um reconhecedor de flores usando o Colab

Este codelab usará o Colaboratory e o Xcode.

Abra o Colab, que usa o TensorFlow Lite Model Maker para treinar um classificador a fim de reconhecer flores usando o aprendizado por transferência e exportar um modelo TFLite a ser usado no app para dispositivos móveis.

3. Configurar o diretório de trabalho

Clonar o repositório Git

O comando a seguir vai clonar o repositório Git que contém os arquivos necessários para este codelab:

git clone https://github.com/tensorflow/examples.git

Agora cd na raiz do projeto do Xcode do clone que você acabou de criar. É nele que você trabalhará pelo restante deste codelab:

cd examples/lite/examples/image_classification/ios

4. Configurar o app para iOS

Instalar dependências

Usando o CocoaPods, instale as dependências do app iOS (incluindo o TensorFlow Lite). Quando o comando de instalação for concluído, abra ImageClassification.xcworkspace para abrir o projeto no Xcode.

pod install --repo-update
open ImageClassification.xcworkspace

5. Testar a execução do app

Para usar a câmera, o app precisa ser executado em um dispositivo real, já que o iOS Simulator não tem acesso à câmera do Mac. Para criar para um dispositivo iOS, você precisa se inscrever no Programa para desenvolvedores da Apple ou ter acesso a um dispositivo que outra pessoa tenha provisionado para você.

Se você quiser executar este codelab no simulador, copie as imagens para a área de transferência do Safari no próprio simulador. Siga estas etapas para processar uma imagem no simulador:

  1. Criar o app em um alvo do simulador de sua escolha.
  2. No simulador do iOS, pressione Cmd+Shift+H para minimizar o aplicativo.
  3. Toque em Safari na parte de baixo da tela inicial e pesquise uma imagem.
  4. Nos resultados da pesquisa de Imagens do Google, toque em um resultado e mantenha a imagem pressionada. Na caixa de diálogo que aparece, selecione "Copiar".
  5. Volte para o app TFL Classify. A imagem copiada deve aparecer automaticamente com os resultados de inferência. Caso contrário, certifique-se de ter copiado os dados da imagem e não o URL dela.

Testar o build e instalar o app

Antes de fazer qualquer mudança no app, execute a versão que acompanha o repositório. Selecione seu dispositivo iOS no menu suspenso no canto superior esquerdo:

275753d3a77a0df3.png

Em seguida, pressione Cmd+R ou pressione o botão Reproduzir f96cf117245c0fa6.png no Xcode para criar o app no dispositivo. O app será iniciado automaticamente assim que for instalado no dispositivo.

Esta versão do app usa a MobileNet padrão, pré-treinada nas 1000 categorias ImageNet. O código será semelhante a este:

d11436f0bb5a75db.jpeg

6. Executar o app personalizado

A configuração padrão do app classifica as imagens em uma das mil classes do ImageNet usando o MobileNet padrão.

Agora vamos modificar o app para que ele use o modelo treinado novamente para nossas categorias de imagens personalizadas treinadas no Colab.

7. Converter o app para executar o modelo

Adicionar arquivos de modelo ao projeto

Os recursos do modelo do projeto estão localizados em ImageClassification > Model no navegador do projeto do Xcode. Para substituí-los, primeiro exclua os dois arquivos existentes no grupo Model. Quando solicitado, selecione "Mover para o Lixo":

cf2f7fefb2e5075f.png

Em seguida, arraste os arquivos model.tflite e labels.txt que você transferiu por download do Colab para o grupo do modelo. Quando solicitado, verifique se Copy items if needed e Add to targets estão selecionados.

281d7eb72635bb5f.png

Modificar o código do app

Para que nosso app funcione, precisamos atualizar o caminho da lógica de carregamento do modelo para apontar para o novo modelo que adicionamos.

Abra ModelDataHandler.swift (caminho do navegador do Xcode: ImageClassification -> ModelDataHandler -> ModelDataHandler.swift) e altere linha 36 para

// before
static let modelInfo: FileInfo = (name: "mobilenet_quant_v1_224", extension: "tflite")

// after
static let modelInfo: FileInfo = (name: "model", extension: "tflite")

Salve todas as alterações.

8. Executar o app personalizado

Pressione Cmd+B ou pressione o botão Reproduzir f96cf117245c0fa6.png no Xcode para criar o app no dispositivo. Quando o app for iniciado, o código vai ficar assim:

c45ecd122998622e.png

Segure os botões liga/desliga e de aumentar volume juntos para fazer uma captura de tela.

Agora, tente fazer uma pesquisa na Web por flores, aponte a câmera para a tela do computador e veja se essas imagens estão classificadas corretamente.

Ou peça para um amigo tirar uma foto sua e descobrir que tipo de usuário do TensorFlow você é \\uf339 \\uf33b \\uf337!

9. Como funciona?

Agora que o app está em execução, vamos analisar o código específico do TensorFlow Lite.

TensorFlowLiteSwift

O app usa a biblioteca TensorFlowLite Swift via CocoaPods. A biblioteca Swift é um wrapper fino da API TFLite C, que é um wrapper da biblioteca C++ do TFLite.

As linhas a seguir no arquivo Podfile do módulo extraem a versão mais recente do repositório global de especificações CocoaPods do pod para o projeto.

Podfile (link em inglês)

target 'ImageClassification' do
  use_frameworks!

  # Pods for ImageClassification
   pod 'TensorFlowLiteSwift'
end

Como usar a API Swift do TensorFlow Lite

O código que interage com o TensorFlow Lite está todo contido em ModelDataHandler.swift.

Configuração

O primeiro bloco de interesse é o inicializador do ModelDataHandler:

ModelDataHandler.swift

/// A failable initializer for `ModelDataHandler`. A new instance is created if the model and
/// labels files are successfully loaded from the app's main bundle. Default `threadCount` is 1.
init?(modelFileInfo: FileInfo, labelsFileInfo: FileInfo, threadCount: Int = 1) {
  let modelFilename = modelFileInfo.name

  // Construct the path to the model file.
  guard let modelPath = Bundle.main.path(
    forResource: modelFilename,
    ofType: modelFileInfo.extension
  ) else {
    print("Failed to load the model file with name: \(modelFilename).")
    return nil
  }

  // Specify the options for the `Interpreter`.
  self.threadCount = threadCount
  var options = InterpreterOptions()
  options.threadCount = threadCount
  do {
    // Create the `Interpreter`.
    interpreter = try Interpreter(modelPath: modelPath, options: options)
    // Allocate memory for the model's input `Tensor`s.
    try interpreter.allocateTensors()
  } catch let error {
    print("Failed to create the interpreter with error: \(error.localizedDescription)")
    return nil
  }
  // Load the classes listed in the labels file.
  loadLabels(fileInfo: labelsFileInfo)
}

Há algumas linhas que precisam ser discutidas com mais detalhes.

A linha a seguir cria o intérprete de TFLite:

ModelDataHandler.swift

interpreter = try Interpreter(modelPath: modelPath, options: options)

O intérprete é responsável por transmitir as entradas de dados brutos pelo grafo do TensorFlow. Passamos ao interpretador o caminho para nosso modelo no disco, que o carrega como um FlatBufferModel.

A última linha carrega a lista de rótulos:

loadLabels(fileInfo: labelsFileInfo)

Tudo isso faz é carregar strings de um arquivo de texto na memória.

Executar o modelo

O segundo bloco de interesse é o método runModel. Ele usa uma CVPixelBuffer como entrada, executa o intérprete e retorna o texto a ser mostrado no app.

ModelDataHandler.swift

try interpreter.copy(rgbData, toInputAt: 0)
// ...
try interpreter.invoke()
// ...
outputTensor = try interpreter.output(at: 0)

10. A seguir

Aqui estão alguns links para mais informações: