7.1. O que é uma rede neural

Uma rede neural é um algoritmo cujo comportamento é aprendido a partir de exemplos, em vez de codificado manualmente. A mesma arquitetura de rede, ao receber um milhão de imagens de rostos, aprende a detectar rostos. A mesma arquitetura, ao receber um milhão de imagens de mãos, aprende a detectar mãos. A mesma arquitetura, ao receber um conjunto rotulado que cobre muitas categorias de objetos, aprende a detectar todas elas de uma só vez. Apenas os pesos mudam entre os alvos, e os pesos são produzidos por um processo de treinamento externo (off-board) que compara as previsões da rede com exemplos rotulados e ajusta os pesos até que coincidam.

7.1.1. O mecanismo

Uma rede neural é uma pilha de camadas. Cada camada multiplica a saída da camada anterior por uma matriz de pesos, soma um vetor de viés (bias) e aplica uma função não linear ao resultado. A saída de uma camada é a entrada da seguinte. Uma imagem capturada entra no topo da pilha, percorre dezenas ou centenas de camadas para baixo e emerge na base como um tensor cujas entradas descrevem o que havia na imagem.

O que os pesos de cada camada fazem depende daquilo em que a rede foi treinada. Uma matriz de pesos de camada inicial em uma rede de visão pode disparar diante de uma borda horizontal curta; uma um pouco mais profunda pode disparar diante de um canto; outra mais profunda pode disparar diante de uma forma circular de olho; as camadas mais profundas podem disparar diante de arranjos de um rosto inteiro. Nada disso foi escrito manualmente. O processo de treinamento iterou sobre milhões de exemplos rotulados, empurrou os pesos ladeira abaixo em uma função de perda, e a hierarquia borda-depois-canto-depois-olho-depois-rosto emergiu dos dados.

A vertical stack of nine labelled boxes representing the layers of a small classification network. The top box is labelled "Input image" with a tensor shape of (192, 192, 3). An arrow leads down to a "Conv + ReLU" box with shape (96, 96, 32). Another arrow leads to a second "Conv + ReLU" box with shape (48, 48, 64). A "MaxPool" box follows with shape (24, 24, 64). Two more "Conv + ReLU" boxes follow with shapes (12, 12, 128) and (6, 6, 256). A "Global average pool" box has shape (256,). A "Fully connected" box has shape (1000,). The bottom box is labelled "Class scores" with shape (1000,). The tensor flow is top to bottom.

Uma pequena rede de classificação como uma pilha de camadas. O tensor de entrada entra no topo com o formato da imagem capturada e flui para baixo através das camadas, sendo que cada uma transforma as dimensões do tensor. O tensor de saída na base tem uma entrada por classe. As redes de detecção e de pontos-chave compartilham a mesma forma de pilha de camadas; apenas a interpretação do tensor de saída muda.

A arquitetura da rede – como as camadas estão dispostas, quais operações as conectam – é o que a rede pode fazer. Os pesos são o que a rede aprendeu. A parte da câmera nisso é carregar o arquivo de pesos produzido pelo treinamento e executar a mesma aritmética que o treinador executou, mas sobre o quadro capturado em vez do conjunto de treinamento.

7.1.2. O que entra, o que sai

Ambas as extremidades da rede são tensores – arrays multidimensionais de números, o mesmo tipo de objeto que o capítulo sobre numpy acabou de apresentar. O tensor de entrada de uma rede de visão é a imagem capturada reorganizada no layout que a rede espera: tipicamente um formato de 4-tupla (B, H, W, C) onde B é a dimensão de lote (sempre 1 na câmera, já que um quadro é processado por vez), H e W são a altura e a largura em pixels esperadas pela rede, e C é a contagem de canais (3 para uma rede RGB, 1 para escala de cinza).

O tensor de saída depende da finalidade da rede:

  • Uma rede de classificação produz um tensor unidimensional de pontuações de confiança, uma por classe. O índice da maior pontuação é a classe prevista. O detector de pessoas derivado do MobileNet que vem na maioria das câmeras é desta forma: duas pontuações, uma para “pessoa”, outra para “não pessoa”.

  • Uma rede de detecção produz um tensor bidimensional cujas entradas descrevem uma lista de caixas delimitadoras mais probabilidades de classe. O YOLOv8 é desta forma: um tensor (84, N) onde 4 das 84 linhas são valores de regressão de caixa e as outras 80 são probabilidades por classe, repetidas ao longo de N posições de âncora.

  • Uma rede de pontos-chave produz um tensor cujas entradas são posições em pixels de pontos de referência nomeados. O modelo de pontos de referência faciais do MediaPipe é desta forma: 468 pontos-chave por rosto detectado.

  • Uma rede de segmentação produz um tensor bidimensional cujas entradas são rótulos de classe por pixel – as mesmas dimensões da entrada, com um índice de categoria em cada posição.

  • Uma rede de regressão produz um único número ou um vetor curto de números – uma estimativa de profundidade, um ângulo, uma temperatura.

Cada forma tem seu próprio pós-processador na câmera que converte o tensor de saída bruto de volta na forma de resultado que o restante da aplicação usa – caixas delimitadoras, listas de pontos-chave, rótulos de classe, estimativas numéricas. O pós-processador é código do lado da aplicação que conhece o layout de saída da rede; a rede em si é apenas a aritmética que produz o tensor.

7.1.3. Por que isso funciona em uma câmera

Duas operações aritméticas tornam isso prático para uma peça da classe de microcontroladores. A primeira é a quantização. O treinamento acontece em aritmética de ponto flutuante de 32 bits; a inferência pode rodar em aritmética inteira de 8 bits com quase nenhuma perda de precisão para a maioria das redes. Os pesos de oito bits ocupam um quarto do armazenamento e rodam várias vezes mais rápido que os floats de 32 bits. Todo modelo que vem na câmera já foi quantizado externamente (off-board).

A segunda é a aceleração por hardware. A mesma aritmética que a CPU de um microcontrolador processa lentamente, uma instrução por vez, um acelerador de redes neurais executa em centenas de operações simultâneas. As câmeras mais novas (a AE3 e a N6) trazem uma unidade de processamento neural (NPU) dedicada – um acelerador de tensores no SoC – que transforma um modelo que levaria um segundo para rodar na CPU em um que roda em dezenas de milissegundos. O capítulo Motores de inferência cobre como é a parte da câmera nisso.

7.1.4. O que o capítulo cobre

O treinamento não é tarefa da câmera. Um modelo treinado chega à câmera como um arquivo .tflite; a câmera o carrega, passa cada quadro capturado por ele e decodifica o tensor resultante em um resultado sobre o qual a aplicação pode agir. Tudo o que se segue trata de cada uma dessas etapas:

  • carregar e inspecionar um modelo;

  • a partição flash onde os arquivos de modelo residem;

  • os quatro estágios de uma chamada de inferência;

  • os motores que de fato realizam a aritmética;

  • e os pós-processadores que transformam um tensor de saída de volta em uma lista de caixas, pontos-chave ou classes.

Os detectores no capítulo sobre imagem eram cada um delimitado a um alvo específico. Os que o restante deste capítulo cobre são treinados a partir de dados, com o mesmo motor executando qualquer modelo que o script carregue. A mudança de fluxo de trabalho que veio com eles – um algoritmo específico de alvo substituído por um arquivo de pesos específico de alvo – é a próxima coisa a destacar.