Como coloquei inteligência artificial dentro de um ESP32
Diante da evolução de modelos de inteligencia artificial modernos, para alguns inserir IA num sistema embarcado pode parecer uma tarefa impossível, e sim, tem suas claras limitações, microcontroladores não conseguem rodar modelos complexos.
Hoje vou demonstrar aqui o conceito de EdgeAI a inferência de machine learning (ML) diretamente no dispositivo (na "borda"), para isso vamos rodar um modelo simples de Machine Learning diretamente dentro de um ESP32.

Vou tentar resumir o máximo possível aqui. Vamos utilizar as bibliotecas Tensorflow (para o treinamento), a extensão Plataform.io para o VSCODE e a biblioteca TFLITE-MICRO para inferência. Estou utilizando um ESP-CYD (já vem pronto com um display que vamos usar para exibir visualmente o modelo rodando!).

Primeiramente, precisamos treinar nosso modelo que será usado no nosso projeto. Treinarei um MLP (Multilayer Perceptron) que é a forma mais simples de uma rede neural fastforward, via Tensorflow no Google Colab, o objetivo do treinamento será ensinar para o modelo a capacidade de classificação binária, com o intuito fazer a comparação entre dois números e dizer se um é maior que outro.

(Você pode ver como foi feito isso aqui!), depois de ter nosso modelo treinado vamos compilar, testar, salvar para .tflite e depois converter para código C++ que é o formato que a biblioteca TFLITE-MICRO aceita.
Agora com nosso modelo pronto podemos seguir para o nosso ambiente ESP que já deixei preparado, com a biblioteca instalada e tudo organizado.

O model_data.cc é o nosso modelo que treinamos e convertemos para C++ anteriormente, o NeuralNetwork.cpp é o wrapper para a biblioteca TFLITE-MICRO, com o intuito de facilitar nossa vida no main.cpp e deixar o código mais limpo.
Só vou explicar aqui o que o main.cpp faz, você tem a liberdade para fuçar o código depois.

Primeiro importamos a bibliotecas que vamos usar: Arduino.h, NeuralNetwork.h e TFT_eSPI.h.
O Arduino.h é o coração (ou a biblioteca principal) de todo o ambiente de desenvolvimento Arduino quando se programa em C++ puro ou usando PlatformIO (que é o nosso caso aqui).
O NeuralNetwork.h é o nosso wrapper.
O TFT_eSPI.h importa a biblioteca para controlar o display do ESP-CYD.
As variáveis buffer e buffer2 são apenas espaços de memória para guardar texto temporário antes de o escrever no display.
A função setup() faz duas coisas: Liga a comunicação com o computador para podermos ver mensagens de debug se precisarmos e aloca a memória (arena), carregando o modelo treinado e prepara o TensorFlow Lite para funcionar.
Dentro da função loop() é que fazemos a magia acontecer!
- Geramos dois números aleatórios em number1 e number2
- Alimentamos nossa rede neural com os números aleatórios que acabamos de gerar.
- Fazemos a previsão (inferência) com float result = nn->predict();
- Interpretamos o resultado:
Expected: Calcula a verdade absoluta (matemática simples) para sabermos se o modelo acertou.
Predicted: Traduz o "pálpite" do modelo. Como a saída é uma probabilidade (ex 0.8), definimos que qualquer coisa acima de 0.5 (50%) é considerado "True" (Verdadeiro). - Com sprintf vamos formatar o texto para ficar bonitinho.
- Com a biblioteca tft vamos mostrar no display o resultado!
Ok, agora vamos compilar via o Plataform.io e botar pra rodar no nosso ESP32.
Imagem 1: O caso "Falso"

Entrada: NUM 1: 0.79 e NUM 2: 0.72.
A Lógica: 0.72 é maior que 0.79? Não.
O que o Modelo pensou: 0.22 (ou 22%).
Como a camada final é uma Sigmoid, ela dá uma probabilidade. O modelo está a dizer: "Tenho apenas 22% de certeza que o número 2 é maior".
Como 0.22 é menor que o limiar de 0.5, a classificação final é False (Falso).
O modelo acertou ("Esperado False, Previsto False").
Imagem 2: O caso "Verdadeiro"

Entrada: NUM 1: 0.24 e NUM 2: 0.92.
A Lógica: 0.92 é maior que 0.24? Sim.
O que o Modelo pensou: 1.00 (ou 100%).
Aqui o modelo está extremamente confiante. A diferença entre os números é grande (quase 0.7 de diferença), o que torna muito fácil para a rede neural perceber que o segundo é maior.
Como 1.00 é maior que 0.5, a classificação final é True (Verdadeiro).
Conclusão: O modelo acertou novamente ("Esperado True, Previsto True").
Você pode acessar o repositório desse projeto no Github. Agradeceria se me ajudasse com o engajamento no LinkedIn também.
Lembrando, se você quiser fazer algo parecido no seu ESP com certeza terá que fazer algumas modificações no código. Indico os tutoriais do Expressif.