Neste artigo vamos aprender como integrar uma rede neural no SBC. Vamos criar uma rede neural de 3 camadas para aproximar a função sin(x).
O processo é dividido em duas partes: 1. treinamento da rede, que será feito no PC e; 2. rodar a rede, que será feito no SBC.
Parte 1. Treinamento de Rede Neural
Para esta parte, usaremos os notebooks Jupyter, com as bibliotecas Keras, Numpy e Pylab.
Etapa 1. Importe as bibliotecas necessárias

Etapa 2. Crie o conjunto de dados de treinamento
Nosso conjunto de dados consiste em 10000 números aleatórios no intervalo 0 – 2*pi como entrada X e sua função sin correspondente como entrada Y. Observe que ajustamos o intervalo de Y para variar de 0 a 1.

Etapa 3. Crie a rede neural
Para criar a rede neural, criamos um objeto modelo e adicionamos 3 camadas a ele. Isso é feito por meio da API fornecida pela biblioteca Keras.
O número de neurônios será 32 para a primeira camada, 32 para a camada intermediária e 1 para a saída.
Usaremos as ativações relu e sigmoid.
O otimizador usado é Adam e a função de erro MSE.
O número de parâmetros de rede é 1153.

Etapa 4. Treinamento
Ao treinar, a rede neural usa o conjunto de dados para ajustar seus parâmetros de forma que o erro seja minimizado.
Nesse caso, passamos todo o conjunto de dados pela rede 10 vezes, em lotes de 32 amostras.
Como podemos ver, ao final do treinamento, o erro é muito pequeno, 2.5e-5.

Etapa 5. Verificação
Agora vamos testar a rede neural uma última vez e compará-la com os valores esperados. Como visto no gráfico, a rede se aproxima muito bem da função seno.

Etapa 6. Exporte os dados
Esta função permite exportar os pesos da rede neural para um arquivo de texto e depois carregá-lo do SBC.

Parte 2. Execução no SBC
Em primeiro lugar, revisaremos a implementação da rede neural.
A rede neural é dividida em 4 classes: Neural_Network, Layer, Perceptron e Activation.
Cada classe tem basicamente 1 método chamado processo que se encarrega de fazer todo o trabalho, além de carregar e salvar os métodos.
A ativação classe, implementa as funções de ativação linear, relu, sigmoid e tanh.

A Perceptron A classe é responsável por realizar todas as multiplicações. Observe que a função de multiplicação vetorial é implementada no ASM para não sacrificar o desempenho.


Implementação de ASM vs Python
A multiplicação de vetores é responsável pela maior parte do uso da CPU, portanto implementá-la no ASM permite melhorar muito o desempenho da biblioteca. Neste exemplo, uma simples multiplicação vetorial 100×100 é realizada. Uma implementação python leva 1339 us, enquanto a implementação ASM leva apenas 28 us. Isso é cerca de 50x mais rápido, preservando os mesmos valores de saída.

A Camada classe agrupa alguns perceptrons em paralelo.

A classe Rede neural empilha todas as camadas da rede.

Por fim, podemos revisar/verificar o uso da rede.
Copiaremos o arquivo com os pesos para o SBC e executaremos o seguinte main.py.
Este código carrega a rede a partir do arquivo sine.unn e calcula o seno de 0.123 e então exibe o valor obtido pela rede e o seno real, bem como o tempo de cálculo em microssegundos.

saída:

Como vemos, a saída aproxima o valor esperado com 4 casas decimais.
Essa rede, com 1153 pesos, exigia 4612(1153*4) bytes de RAM para armazenar pesos em valor flutuante e 5.8ms para processar.