7.1. O que é uma rede neuronal

Uma rede neuronal é um algoritmo cujo comportamento é aprendido a partir de exemplos, em vez de ser programado manualmente. A mesma arquitetura de rede, treinada com um milhão de imagens de rostos, aprende a detetar rostos. A mesma arquitetura, treinada com um milhão de imagens de mãos, aprende a detetar mãos. A mesma arquitetura, treinada com um conjunto de dados com etiquetas que cobre muitas categorias de objetos, aprende a detetar todas elas em simultâneo. Apenas os pesos variam conforme os objetivos, e os pesos são produzidos por um processo de treino externo que compara as previsões da rede com os exemplos etiquetados e ajusta os pesos até que coincidam.

7.1.1. O mecanismo

Uma rede neuronal é uma pilha de camadas. Cada camada multiplica a saída da camada anterior por uma matriz de pesos, adiciona um vetor de polarização 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 e emerge na base como um tensor cujas entradas descrevem o conteúdo da imagem.

O que os pesos de cada camada fazem depende do treino da rede. Uma matriz de pesos de uma camada inicial numa rede de visão pode ativar numa aresta horizontal curta; uma ligeiramente mais profunda pode ativar num canto; uma mais profunda ainda pode ativar numa forma circular de olho; as camadas mais profundas podem ativar em arranjos de rosto completo. Nada disto foi escrito manualmente. O processo de treino iterou sobre milhões de exemplos etiquetados, ajustou os pesos minimizando uma função de perda, e a hierarquia de arestas, cantos, olhos e rostos 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 representada como uma pilha de camadas. O tensor de entrada entra no topo com a forma da imagem capturada e percorre as camadas, com cada uma a transformar as dimensões do tensor. O tensor de saída no fundo tem uma entrada por classe. As redes de deteção e de pontos-chave partilham 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, que operações as ligam – define o que a rede pode fazer. Os pesos definem o que a rede aprendeu. A parte da câmara nisto consiste em carregar o ficheiro de pesos produzido pelo treino e executar a mesma aritmética que o processo de treino executou, mas sobre o fotograma capturado em vez do conjunto de treino.

7.1.2. O que entra e o que sai

Ambas as extremidades da rede são tensores – arrays multidimensionais de números, do mesmo tipo de objetos introduzidos no capítulo do numpy. O tensor de entrada para uma rede de visão é a imagem capturada reorganizada no layout que a rede espera: tipicamente uma forma de 4-tuplo (B, H, W, C) em que B é a dimensão do lote (sempre 1 na câmara, pois processa-se um fotograma de cada vez), H e W são a altura e largura em pixels esperadas pela rede, e C é o número de canais (3 para uma rede RGB, 1 para escala de cinzentos).

O tensor de saída depende do objetivo da rede:

  • Uma rede de classificação produz um tensor 1-D de pontuações de confiança, uma por classe. O índice da maior pontuação é a classe prevista. O detetor de pessoas derivado do MobileNet que acompanha a maioria das câmaras é desta forma: duas pontuações, uma para «pessoa» e outra para «não pessoa».

  • Uma rede de deteção produz um tensor 2-D cujas entradas descrevem uma lista de caixas delimitadoras mais probabilidades de classe. O YOLOv8 é desta forma: um tensor (84, N) em que 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 ancoragem.

  • Uma rede de pontos-chave produz um tensor cujas entradas são posições de pixel de marcos com nome. O modelo de marcos faciais do MediaPipe é desta forma: 468 pontos-chave por rosto detetado.

  • Uma rede de segmentação produz um tensor 2-D cujas entradas são etiquetas 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 o seu próprio pós-processador na câmara que converte o tensor de saída bruto de volta para a forma de resultado que o resto da aplicação utiliza – caixas delimitadoras, listas de pontos-chave, etiquetas 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 própria rede é apenas a aritmética que produz o tensor.

7.1.3. Porque isto funciona numa câmara

Dois elementos aritméticos tornam isto prático para um microcontrolador. O primeiro é a quantização. O treino ocorre em aritmética de vírgula flutuante de 32 bits; a inferência pode correr em aritmética de inteiros de 8 bits com perda de precisão quase nula para a maioria das redes. Pesos de 8 bits ocupam um quarto do armazenamento e são várias vezes mais rápidos do que os floats de 32 bits. Todos os modelos fornecidos com a câmara já foram quantizados externamente.

O segundo é a aceleração por hardware. A mesma aritmética que o CPU de um microcontrolador executa instrução a instrução, um acelerador de redes neuronais executa centenas de operações em simultâneo. As câmaras mais recentes (a AE3 e a N6) incluem uma unidade de processamento neuronal (NPU) dedicada – um acelerador de tensores no SoC – que transforma um modelo que levaria um segundo a correr no CPU num que corre em dezenas de milissegundos. O capítulo sobre motores de inferência cobre o que a parte da câmara nisto parece.

7.1.4. O que o capítulo aborda

O treino não é da responsabilidade da câmara. Um modelo treinado chega à câmara como um ficheiro .tflite; a câmara carrega-o, executa cada fotograma capturado através dele e descodifica o tensor resultante num resultado sobre o qual a aplicação pode agir. Tudo o que se segue trata de cada um desses passos:

  • carregar e inspecionar um modelo;

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

  • as quatro etapas de uma chamada de inferência;

  • os motores que executam efetivamente a aritmética;

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

Os detetores no capítulo da imagem tinham cada um um âmbito específico. Os que o restante deste capítulo cobre são treinados a partir de dados, com o mesmo motor a executar qualquer modelo que o script carregue. A mudança de fluxo de trabalho que os acompanhou – um algoritmo específico para um objetivo substituído por um ficheiro de pesos específico para um objetivo – é o próximo ponto a destacar.