TensorFlow Lite na API Java do Google Play Services

O TensorFlow Lite no Google Play Services também pode ser acessado usando APIs Java, além da API nativa. Em particular, o TensorFlow Lite no Google Play Services está disponível por meio da TensorFlow Lite Task API e da TensorFlow Lite Interpreter API . A biblioteca de tarefas fornece interfaces de modelo prontas para uso otimizadas para tarefas comuns de aprendizado de máquina usando dados visuais, de áudio e de texto. A API TensorFlow Lite Interpreter, fornecida pelo tempo de execução do TensorFlow, fornece uma interface de uso mais geral para criar e executar modelos de ML.

As seções a seguir fornecem instruções sobre como usar as APIs de intérprete e biblioteca de tarefas com o TensorFlow Lite no Google Play Services. Embora seja possível que um aplicativo use APIs de intérprete e APIs de biblioteca de tarefas, a maioria dos aplicativos deve usar apenas um conjunto de APIs.

Usando as APIs da Biblioteca de Tarefas

A API de tarefas do TensorFlow Lite envolve a API do interpretador e fornece uma interface de programação de alto nível para tarefas comuns de aprendizado de máquina que usam dados visuais, de áudio e de texto. Você deverá usar a Task API se seu aplicativo exigir uma das tarefas suportadas .

1. Adicione dependências do projeto

A dependência do seu projeto depende do seu caso de uso de aprendizado de máquina. As APIs de tarefas contêm as seguintes bibliotecas:

  • Biblioteca de visão: org.tensorflow:tensorflow-lite-task-vision-play-services
  • Biblioteca de áudio: org.tensorflow:tensorflow-lite-task-audio-play-services
  • Biblioteca de texto: org.tensorflow:tensorflow-lite-task-text-play-services

Adicione uma das dependências ao código do projeto do seu aplicativo para acessar a API Play Services para TensorFlow Lite. Por exemplo, use o seguinte para implementar uma tarefa de visão:

dependencies {
...
    implementation 'org.tensorflow:tensorflow-lite-task-vision-play-services:0.4.2'
...
}

2. Adicionar inicialização do TensorFlow Lite

Inicialize o componente TensorFlow Lite da API do Google Play Services antes de usar as APIs do TensorFlow Lite. O exemplo a seguir inicializa a biblioteca de visão:

Kotlin

init {
  TfLiteVision.initialize(context)
}

3. Execute inferências

Depois de inicializar o componente TensorFlow Lite, chame o método detect() para gerar inferências. O código exato dentro do método detect() varia dependendo da biblioteca e do caso de uso. O seguinte é um caso de uso simples de detecção de objetos com a biblioteca TfLiteVision :

Kotlin

fun detect(...) {
  if (!TfLiteVision.isInitialized()) {
    Log.e(TAG, "detect: TfLiteVision is not initialized yet")
    return
  }

  if (objectDetector == null) {
    setupObjectDetector()
  }

  ...

}

Dependendo do formato dos dados, você também pode precisar pré-processar e converter seus dados dentro do método detect() antes de gerar inferências. Por exemplo, os dados de imagem para um detector de objetos requerem o seguinte:

val imageProcessor = ImageProcessor.Builder().add(Rot90Op(-imageRotation / 90)).build()
val tensorImage = imageProcessor.process(TensorImage.fromBitmap(image))
val results = objectDetector?.detect(tensorImage)

Usando as APIs de intérprete

As APIs de intérprete oferecem mais controle e flexibilidade do que as APIs da biblioteca de tarefas. Você deverá usar as APIs de intérprete se sua tarefa de aprendizado de máquina não for compatível com a biblioteca de tarefas ou se precisar de uma interface de uso mais geral para criar e executar modelos de ML.

1. Adicione dependências do projeto

Adicione as seguintes dependências ao código do projeto do seu aplicativo para acessar a API Play Services para TensorFlow Lite:

dependencies {
...
    // Tensorflow Lite dependencies for Google Play services
    implementation 'com.google.android.gms:play-services-tflite-java:16.0.1'
    // Optional: include Tensorflow Lite Support Library
    implementation 'com.google.android.gms:play-services-tflite-support:16.0.1'
...
}

2. Adicionar inicialização do TensorFlow Lite

Inicialize o componente TensorFlow Lite da API do Google Play Services antes de usar as APIs do TensorFlow Lite:

Kotlin

val initializeTask: Task<Void> by lazy { TfLite.initialize(this) }

Java

Task<Void> initializeTask = TfLite.initialize(context);

3. Crie um intérprete e defina a opção de tempo de execução

Crie um interpretador usando InterpreterApi.create() e configure-o para usar o tempo de execução do Google Play Services, chamando InterpreterApi.Options.setRuntime() , conforme mostrado no código de exemplo a seguir:

Kotlin

import org.tensorflow.lite.InterpreterApi
import org.tensorflow.lite.InterpreterApi.Options.TfLiteRuntime
...
private lateinit var interpreter: InterpreterApi
...
initializeTask.addOnSuccessListener {
  val interpreterOption =
    InterpreterApi.Options().setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY)
  interpreter = InterpreterApi.create(
    modelBuffer,
    interpreterOption
  )}
  .addOnFailureListener { e ->
    Log.e("Interpreter", "Cannot initialize interpreter", e)
  }

Java

import org.tensorflow.lite.InterpreterApi
import org.tensorflow.lite.InterpreterApi.Options.TfLiteRuntime
...
private InterpreterApi interpreter;
...
initializeTask.addOnSuccessListener(a -> {
    interpreter = InterpreterApi.create(modelBuffer,
      new InterpreterApi.Options().setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY));
  })
  .addOnFailureListener(e -> {
    Log.e("Interpreter", String.format("Cannot initialize interpreter: %s",
          e.getMessage()));
  });

Você deve usar a implementação acima porque ela evita o bloqueio do thread da interface do usuário do Android. Se precisar gerenciar a execução do thread mais de perto, você pode adicionar uma chamada Tasks.await() para a criação do interpretador:

Kotlin

import androidx.lifecycle.lifecycleScope
...
lifecycleScope.launchWhenStarted { // uses coroutine
  initializeTask.await()
}

Java

@BackgroundThread
InterpreterApi initializeInterpreter() {
    Tasks.await(initializeTask);
    return InterpreterApi.create(...);
}

4. Execute inferências

Usando o objeto interpreter que você criou, chame o método run() para gerar uma inferência.

Kotlin

interpreter.run(inputBuffer, outputBuffer)

Java

interpreter.run(inputBuffer, outputBuffer);

Aceleraçao do hardware

O TensorFlow Lite permite acelerar o desempenho do seu modelo usando processadores de hardware especializados, como unidades de processamento gráfico (GPUs). Você pode aproveitar esses processadores especializados usando drivers de hardware chamados delegados . Você pode usar os seguintes delegados de aceleração de hardware com o TensorFlow Lite no Google Play Services:

  • Delegado de GPU (recomendado) - Este delegado é fornecido por meio do Google Play Services e é carregado dinamicamente, assim como as versões do Play Services da Task API e da Interpreter API.

  • Delegado NNAPI - Este delegado está disponível como uma dependência de biblioteca incluída no seu projeto de desenvolvimento Android e é incluído no seu aplicativo.

Para obter mais informações sobre aceleração de hardware com o TensorFlow Lite, consulte a página Delegados do TensorFlow Lite .

Verificando a compatibilidade do dispositivo

Nem todos os dispositivos suportam aceleração de hardware GPU com TFLite. Para mitigar erros e possíveis falhas, use o método TfLiteGpu.isGpuDelegateAvailable para verificar se um dispositivo é compatível com o delegado GPU.

Use este método para confirmar se um dispositivo é compatível com GPU e use a CPU ou o delegado NNAPI como substituto para quando a GPU não for suportada.

useGpuTask = TfLiteGpu.isGpuDelegateAvailable(context)

Depois de ter uma variável como useGpuTask , você poderá usá-la para determinar se os dispositivos usam o delegado da GPU. Os exemplos a seguir mostram como isso pode ser feito com as APIs da Biblioteca de Tarefas e do Interpretador.

Com a API de tarefas

Kotlin

lateinit val optionsTask = useGpuTask.continueWith { task ->
  val baseOptionsBuilder = BaseOptions.builder()
  if (task.result) {
    baseOptionsBuilder.useGpu()
  }
 ObjectDetectorOptions.builder()
          .setBaseOptions(baseOptionsBuilder.build())
          .setMaxResults(1)
          .build()
}
    

Java

Task<ObjectDetectorOptions> optionsTask = useGpuTask.continueWith({ task ->
  BaseOptions baseOptionsBuilder = BaseOptions.builder();
  if (task.getResult()) {
    baseOptionsBuilder.useGpu();
  }
  return ObjectDetectorOptions.builder()
          .setBaseOptions(baseOptionsBuilder.build())
          .setMaxResults(1)
          .build()
});
    

Com a API do intérprete

Kotlin

val interpreterTask = useGpuTask.continueWith { task ->
  val interpreterOptions = InterpreterApi.Options()
      .setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY)
  if (task.result) {
      interpreterOptions.addDelegateFactory(GpuDelegateFactory())
  }
  InterpreterApi.create(FileUtil.loadMappedFile(context, MODEL_PATH), interpreterOptions)
}
    

Java

Task<InterpreterApi.Options> interpreterOptionsTask = useGpuTask.continueWith({ task ->
  InterpreterApi.Options options =
      new InterpreterApi.Options().setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY);
  if (task.getResult()) {
     options.addDelegateFactory(new GpuDelegateFactory());
  }
  return options;
});
    

GPU com APIs de biblioteca de tarefas

Para usar o delegado GPU com as APIs de tarefas:

  1. Atualize as dependências do projeto para usar o delegado GPU do Play Services:

    implementation 'com.google.android.gms:play-services-tflite-gpu:16.1.0'
    
  2. Inicialize o delegado da GPU com setEnableGpuDelegateSupport . Por exemplo, você pode inicializar o delegado GPU para TfLiteVision com o seguinte:

    Kotlin

        TfLiteVision.initialize(context, TfLiteInitializationOptions.builder().setEnableGpuDelegateSupport(true).build())
        

    Java

        TfLiteVision.initialize(context, TfLiteInitializationOptions.builder().setEnableGpuDelegateSupport(true).build());
        
  3. Habilite a opção de delegado GPU com BaseOptions :

    Kotlin

        val baseOptions = BaseOptions.builder().useGpu().build()
        

    Java

        BaseOptions baseOptions = BaseOptions.builder().useGpu().build();
        
  4. Configure as opções usando .setBaseOptions . Por exemplo, você pode configurar a GPU no ObjectDetector com o seguinte:

    Kotlin

        val options =
            ObjectDetectorOptions.builder()
                .setBaseOptions(baseOptions)
                .setMaxResults(1)
                .build()
        

    Java

        ObjectDetectorOptions options =
            ObjectDetectorOptions.builder()
                .setBaseOptions(baseOptions)
                .setMaxResults(1)
                .build();
        

GPU com APIs de intérprete

Para usar o delegado GPU com as APIs de intérprete:

  1. Atualize as dependências do projeto para usar o delegado GPU do Play Services:

    implementation 'com.google.android.gms:play-services-tflite-gpu:16.1.0'
    
  2. Habilite a opção de delegado GPU na inicialização do TFlite:

    Kotlin

        TfLite.initialize(context,
          TfLiteInitializationOptions.builder()
           .setEnableGpuDelegateSupport(true)
           .build())
        

    Java

        TfLite.initialize(context,
          TfLiteInitializationOptions.builder()
           .setEnableGpuDelegateSupport(true)
           .build());
        
  3. Habilite o delegado GPU nas opções do interpretador: defina a fábrica de delegados como GpuDelegateFactory chamando addDelegateFactory() within InterpreterApi.Options()`:

    Kotlin

        val interpreterOption = InterpreterApi.Options()
         .setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY)
         .addDelegateFactory(GpuDelegateFactory())
        

    Java

        Options interpreterOption = InterpreterApi.Options()
          .setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY)
          .addDelegateFactory(new GpuDelegateFactory());
        

Migrando do TensorFlow Lite independente

Se você planeja migrar seu aplicativo do TensorFlow Lite independente para a API Play Services, revise as seguintes orientações adicionais para atualizar o código do projeto do seu aplicativo:

  1. Revise a seção Limitações desta página para garantir que seu caso de uso seja compatível.
  2. Antes de atualizar seu código, faça verificações de desempenho e precisão de seus modelos, especialmente se você estiver usando versões do TensorFlow Lite anteriores à versão 2.1, para ter uma linha de base para comparar com a nova implementação.
  3. Se você migrou todo o seu código para usar a API Play Services para TensorFlow Lite, remova as dependências existentes da biblioteca de tempo de execução do TensorFlow Lite (entradas com org.tensorflow: tensorflow-lite :* ) do arquivo build.gradle para que você pode reduzir o tamanho do seu aplicativo.
  4. Identifique todas as ocorrências de criação de new Interpreter em seu código e modifique cada uma delas para que usem a chamada InterpreterApi.create(). O novo TfLite.initialize é assíncrono, o que significa que na maioria dos casos não é um substituto imediato: você deve registrar um ouvinte para quando a chamada for concluída. Consulte o snippet de código no código da Etapa 3 .
  5. Adicionar import org.tensorflow.lite.InterpreterApi; e import org.tensorflow.lite.InterpreterApi.Options.TfLiteRuntime; para qualquer arquivo de origem usando as classes org.tensorflow.lite.Interpreter ou org.tensorflow.lite.InterpreterApi .
  6. Se alguma das chamadas resultantes para InterpreterApi.create() tiver apenas um único argumento, anexe new InterpreterApi.Options() à lista de argumentos.
  7. Anexe .setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY) ao último argumento de qualquer chamada para InterpreterApi.create() .
  8. Substitua todas as outras ocorrências da classe org.tensorflow.lite.Interpreter por org.tensorflow.lite.InterpreterApi .

Se quiser usar o TensorFlow Lite independente e a API do Play Services lado a lado, você deverá usar o TensorFlow Lite 2.9 (ou posterior). O TensorFlow Lite 2.8 e versões anteriores não são compatíveis com a versão da API do Play Services.