Primeiros Passos com TensorFlow Lite no reTerminal

TensorFlow Lite é um conjunto de ferramentas que viabiliza aprendizado de máquina no dispositivo, ajudando desenvolvedores a executar seus modelos em dispositivos móveis, embarcados e de IoT. Os principais recursos do TensorFlow Lite são otimizados para aprendizado de máquina no dispositivo, com foco em latência, privacidade, conectividade, tamanho e consumo de energia. O framework é criado para oferecer suporte a várias plataformas, incluindo dispositivos Android e iOS, Linux embarcado e microcontroladores. Ele também possui suporte integrado para diversos idiomas, como Java, Swift, Objective-C, C++ e Python, e tem alto desempenho com aceleração de hardware e otimização de modelo. Ele fornece exemplos ponta a ponta para tarefas comuns de aprendizado de máquina, como classificação de imagens, detecção de objetos, estimativa de pose, resposta a perguntas e classificação de texto, em várias plataformas.
Instalação do Pacote TensorFlow Lite Runtime
O pacote tflite_runtime é um pacote Python menor e simplificado que inclui apenas o código mínimo necessário para executar inferência com TensorFlow Lite. Esse pacote é ideal quando tudo o que você quer fazer é executar modelos .tflite e evitar desperdiçar espaço em disco com a grande biblioteca TensorFlow.
Para melhor desempenho, recomenda-se usar um sistema operacional 64 bits e o pacote TFLite correspondente, com o delegate XNNPACK otimizado habilitado. Eles podem ser compilados a partir do código-fonte por você mesmo ou instalados com binários pré-compilados fornecidos pela Seeed studio. Como alternativa, você pode instalar a versão estável mais recente com pip
Versão estável mais recente (compilações oficiais)
pip3 install --index-url https://google-coral.github.io/py-repo/ tflite_runtime
Pacote otimizado para desempenho para SO 64 bits com XNNPACK habilitado
No momento da escrita deste artigo, não havia rodas oficiais pré-compiladas para Python 3.7 SO 64 bits com otimizações XNNPACK disponíveis, então nós as compilamos e compartilhamos nós mesmos.
wget www.files.seeedstudio.com/ml/TFLite/tflite_runtime-2.6.0-cp37-cp37m-linux_aarch64.whl
pip3 install tflite_runtime-2.6.0-cp37-cp37m-linux_aarch64.whl
Depois que a instalação for concluída, tente importar o pacote tflite:
pi@raspberrypi:~ $ python3
Python 3.7.3 (default, Jul 25 2020, 13:03:44)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tflite_runtime
>>> tflite_runtime.__version__
'2.6.0'
Exemplos
É possível usar o TFLite Converter para converter qualquer modelo Tensorflow para o formato .tflite, desde que ele consista apenas em operações suportadas pelo TFLite Runtime. A seguir está a lista de demonstrações atualmente testadas no reTerminal, que será expandida e completada no futuro:
Detecção de Objetos

Demo: Detecção de Veículos Jupyter Notebook Example scripts
- alfa 0.25 224x224 66.7 FPS (15 ms.)
- alfa 0.5 224x224 40 FPS (25 ms.)
- alfa 0.75 320x320 14.9 FPS (67 ms.)
- alfa 1.0 320x320 10.4 FPS (96 ms.)
Classificação de Imagens

Demo: Identificação de Rasgos em Esteira Industrial Jupyter Notebook Example scripts
Segmentação Semântica

Demo: Segmentação de Pulmão Jupyter Notebook Example scripts
Reconhecimento de Idade/Gênero de Rosto

Demo: Inferência em múltiplos estágios: MobileNet YOLOv3 alfa 0.25 -> MobileFaceNet Github repository Example scripts ~16-20 FPS (com ARM NN)
Reconhecimento de Expressão Facial

Demo: Inferência em múltiplos estágios: MobileNet YOLOv3 alfa 0.25 -> MobileFaceNet Github repository Example scripts ~11 FPS
Anti-spoofing Facial

Demo: Inferência em múltiplos estágios: MobileNet YOLOv3 alfa 0.25 -> MobileNet v1 alfa 0.25 Jupyter Notebook Example scripts ~23 FPS (ARM NN)
Reconhecimento Facial

Demo: Inferência em múltiplos estágios: Detector de Rosto Ultra Leve com Detecção de Pontos de Referência -> MobileFaceNet Jupyter Notebook Example scripts ~15 FPS (ARM NN)
Otimização adicional
Os FPS e resultados de inferência na tabela de Exemplos são fornecidos para inferência de modelos quantizados em INT8 no Tensorflow Lite, salvo indicação em contrário.
Como o reTerminal é baseado em Raspberry Pi 4, ele não possui aceleradores de hardware adicionais para inferência de redes neurais, portanto, apenas métodos de otimização padrão para inferência em CPU podem ser aplicados.
A visão geral em vídeo deste tópico é apresentada aqui:
Abaixo está uma breve visão geral dos métodos de otimização de inferência em CPU:
- Projetar redes menores. Se o objetivo for simples o suficiente (classificação de imagens de < 100 classes ou detecção de objetos de < 10 classes ou similar), uma rede menor pode alcançar precisão aceitável e executar muito rápido. Por exemplo, a rede MobileNet v1 alfa 0.25 YOLOv2 treinada para detectar apenas uma classe de objetos (rostos humanos) atinge 62.5 FPS sem qualquer otimização adicional.
Inferência FP32 Tensorflow Lite padrão: MobileNetv1(alpha 0.25) YOLOv2 1 class 0.89 MB 62.5 FPS MobileNetv1(alpha 1.0) YOLOv3 20 class 13.1 MB 7 FPS
- Quantização. Quantização é o processo de reduzir a precisão dos pesos da rede de RN, geralmente de FP32 para INT8. Ela reduz o tamanho em 4x e a latência em ~60-80% usando os kernels padrão do Tensorflow Lite. A perda de precisão pode ser minimizada usando QAT - treinamento ciente de quantização, que é o processo de ajustar finamente a rede com nós de quantização inseridos.
Inferência INT8 Tensorflow Lite padrão: MobileNetv1(alpha 0.25) YOLOv2 1 class 0.89 MB 77 FPS MobileNetv1(alpha 1.0) YOLOv3 20 class 13.1 MB 11.5 FPS
- Usar kernels otimizados. A velocidade de inferência pode ser melhorada utilizando frameworks que possuem kernels de CNN otimizados para conjuntos específicos de instruções de CPU, por exemplo, instruções NEON SIMD para ARM. Exemplos de tais redes incluem ARM NN e XNNPACK.
Arm NN SDK é um conjunto de softwares e ferramentas de código aberto que viabiliza cargas de trabalho de aprendizado de máquina em dispositivos com baixo consumo de energia. A descrição e os benchmarks fornecidos parecem promissores, mas o procedimento de instalação no Raspberry Pi OS mais recente é complicado no momento - a única maneira adequada de instalar a versão mais recente do ARM NN atualmente é compilando a partir do código-fonte. Existem binários disponíveis para Debian Bullseye, mas o Raspberry Pi OS ainda está em Debian Buster. Os resultados de teste de inferência com scripts de benchmark foram mistos; para um único modelo ele mostrou desempenho pior do que até mesmo o Tensorflow Lite padrão, mas acabou sendo mais rápido em inferência de múltiplos modelos, possivelmente devido a uma utilização mais eficiente de multiprocessamento.
Inferência ARM NN FP32: MobileNetv1(alpha 0.25) YOLOv2 1 class 0.89 MB 83 FPS MobileNetv1(alpha 1.0) YOLOv3 20 class 13.1 MB 7.2 FPS
XNNPACK é uma biblioteca para acelerar a inferência de rede neural para arquiteturas ARM, x86 e WebAssembly em ambientes Android, iOS, Windows, Linux e macOS. Ela é integrada ao Tensorflow Lite como um delegate, que é habilitado por padrão para compilação Android, mas para outros ambientes precisa ser habilitada manualmente - assim, se você quiser usar XNNPACK no Raspberry Pi 4, será necessário compilar o pacote TensorFlow Lite Interpreter a partir do código-fonte ou baixar um dos binários de terceiros, como o que fornecemos acima.
Inferência FP32 Tensorflow Lite com delegate XNNPACK: MobileNetv1(alpha 0.25) YOLOv2 1 class 0.89 MB 83 FPS MobileNetv1(alpha 1.0) YOLOv3 20 class 13.1 MB 7.2 FPS
O principal problema com kernels otimizados é o suporte desigual a diferentes arquiteturas/operadores de RN/tipos de precisão em diferentes frameworks. Por exemplo, kernels otimizados em INT8 estão em desenvolvimento tanto no ARM NN quanto no XNNPACK. O suporte para kernels otimizados em INT8 no XNNPACK foi adicionado muito recentemente e parece trazer uma melhoria modesta de desempenho, de cerca de ~30%, dependendo dos operadores usados no modelo. XNNPACK GitHub Issue
Outra linha promissora são os kernels otimizados para modelos quantizados dinamicamente, veja a conversa com o desenvolvedor aqui: TensorFlow GitHub PR
O desenvolvedor afirma uma melhora de latência de 3-4x, mas atualmente isso é limitado apenas a um conjunto muito específico de modelos. Um PR para permitir um uso mais conveniente está em desenvolvimento.
- Poda e inferência esparsa. Poda é um processo de ajuste fino de uma rede neural treinada para encontrar pesos que não contribuem para previsões corretas. Isso permite reduzir tanto o tamanho quanto a latência dos modelos – a redução de acurácia depende das configurações de esparsidade. Experimentalmente é possível obter até 80% de esparsidade com impacto negligenciável na acurácia. Veja detalhes aqui e um guia de poda com TensorFlow aqui. Infelizmente, na forma atual, apenas um conjunto muito limitado de modelos oferece suporte à poda e à inferência esparsa com XNNPACK.
F.A.Q
P1: A política da minha empresa não nos permite usar binários de terceiros
Você pode usar o pacote oficial do interpretador TFLite ou, alternativamente, compilá-lo a partir do código-fonte seguindo as instruções aqui.
Recursos
-
[Página Web] Página Oficial do TensorFlow Lite
-
[Página Web] Documentação Oficial do TensorFlow Lite