Implementación de redes neuronales en FPGAs usando VHDL
Dr. Carlos Hernandez-Gutierrez
En esto es parte de mi curso de HDL. Quiero mostrar cómo implementar una red neuronal utilizando VHDL. Si está interesado, puedo enseñarle cómo hacerlo o ayudarlo en sus proyectos, pero como freelance (no de forma gratuita).
puedes contactar conmigo en: [email protected]
Bueno, vamos a empezar.
Explicación: En este ejemplo, implemento un reconocimiento de los primeros 10 números primos, como 2, 3, 5, 7 de una pantalla de siete segmentos. Para implementar el algoritmo utilicé una FPU(Unidad de Punto Flotante) para sumas, multiplicaciones y divisiones de punto flotante.
puedes contactar conmigo en: [email protected]
Bueno, vamos a empezar.
Explicación: En este ejemplo, implemento un reconocimiento de los primeros 10 números primos, como 2, 3, 5, 7 de una pantalla de siete segmentos. Para implementar el algoritmo utilicé una FPU(Unidad de Punto Flotante) para sumas, multiplicaciones y divisiones de punto flotante.
Figura 1. Red neuronal. Donde el vector P son las 7 salidas del decodificador de 7 segmentos que son las entradas de la red neuronal.
Explicación: En este ejemplo, implemento un reconocimiento de los primeros 10 números primos, como 2, 3, 5, 7 de una pantalla de siete segmentos. Para implementar el algoritmo utilicé FPU para sumas, multiplicaciones y divisiones de punto flotante.
La red neuronal fue entrenada previamente por el siguiente código de Matlab:
% Este programa fue escrito por el Dr. Erik Zamora y editado para la implementación de FPGA por el Dr. Carlos Hernández
clear all
clc
% a b c d e f g
P =[1 0 0 0 0 0 0; %0
1 1 1 1 0 0 1; %1
0 1 0 0 1 0 0; %2
0 1 1 0 0 0 0; %3
0 0 1 1 0 0 1; %4
0 0 1 0 0 1 0; %5
0 0 0 0 0 1 0; %6
0 1 1 1 0 0 0; %7
0 0 0 0 0 0 0; %8
0 0 1 1 0 0 0]; %9
P = P';
tpar = [1 0 1 0 1 0 1 0 1 0]; % Numeros pares
tmay5 = [0 0 0 0 0 0 1 1 1 1]; % Mayores a 5
tprim = [0 0 1 1 0 1 0 1 0 0]; % Numeros Primos
t = tprim;
W = 2*rand(1,7)-1;
b = 2*rand(1)-1;
for Epocas = 1:500
for q = 1:10
e(q) = t(q) - hardlim(W*P(:,q) + b);
W = W + e(q)*P(:,q)';
b = b + e(q);
end
end
e
W
b
También, puedes ver el video de la implementación de Matlab en youtube (español):
La red neuronal fue entrenada previamente por el siguiente código de Matlab:
% Este programa fue escrito por el Dr. Erik Zamora y editado para la implementación de FPGA por el Dr. Carlos Hernández
clear all
clc
% a b c d e f g
P =[1 0 0 0 0 0 0; %0
1 1 1 1 0 0 1; %1
0 1 0 0 1 0 0; %2
0 1 1 0 0 0 0; %3
0 0 1 1 0 0 1; %4
0 0 1 0 0 1 0; %5
0 0 0 0 0 1 0; %6
0 1 1 1 0 0 0; %7
0 0 0 0 0 0 0; %8
0 0 1 1 0 0 0]; %9
P = P';
tpar = [1 0 1 0 1 0 1 0 1 0]; % Numeros pares
tmay5 = [0 0 0 0 0 0 1 1 1 1]; % Mayores a 5
tprim = [0 0 1 1 0 1 0 1 0 0]; % Numeros Primos
t = tprim;
W = 2*rand(1,7)-1;
b = 2*rand(1)-1;
for Epocas = 1:500
for q = 1:10
e(q) = t(q) - hardlim(W*P(:,q) + b);
W = W + e(q)*P(:,q)';
b = b + e(q);
end
end
e
W
b
También, puedes ver el video de la implementación de Matlab en youtube (español):
Además, puede usar esta página para convertir del número de punto flotante al estándar IEEE74:
https://www.h-schmidt.net/FloatConverter/IEEE754.html
Después del entrenamiento, los pesos y bias resultantes son:
signal w0: std_logic_vector(31 downto 0):=X"bebdbf48";-- -0.3706
signal w1: std_logic_vector(31 downto 0):=X"3fe7e282";-- 1.8116
signal w2: std_logic_vector(31 downto 0):=X"3fa08312";-- 1.2540
signal w3: std_logic_vector(31 downto 0):=X"bf962b6b";-- -1.1732
signal w4: std_logic_vector(31 downto 0):=X"3e8786c2";--0.2647
signal w5: std_logic_vector(31 downto 0):=X"3e47c84b";--0.1951
signal w6: std_logic_vector(31 downto 0):=X"bfb8b439";-- -1.4430
-- b=-0.9062
signal bias: std_logic_vector(31 downto 0):=X"bf67fcb9";
Para implementar la red neuronal diseñamos FPU (float point unit), el decodificador de siete segmentos y el circuito sigmoide. Además para implementar el circuito sigmoide, utilize una aproximación reportada en otra parte [1].
https://www.h-schmidt.net/FloatConverter/IEEE754.html
Después del entrenamiento, los pesos y bias resultantes son:
signal w0: std_logic_vector(31 downto 0):=X"bebdbf48";-- -0.3706
signal w1: std_logic_vector(31 downto 0):=X"3fe7e282";-- 1.8116
signal w2: std_logic_vector(31 downto 0):=X"3fa08312";-- 1.2540
signal w3: std_logic_vector(31 downto 0):=X"bf962b6b";-- -1.1732
signal w4: std_logic_vector(31 downto 0):=X"3e8786c2";--0.2647
signal w5: std_logic_vector(31 downto 0):=X"3e47c84b";--0.1951
signal w6: std_logic_vector(31 downto 0):=X"bfb8b439";-- -1.4430
-- b=-0.9062
signal bias: std_logic_vector(31 downto 0):=X"bf67fcb9";
Para implementar la red neuronal diseñamos FPU (float point unit), el decodificador de siete segmentos y el circuito sigmoide. Además para implementar el circuito sigmoide, utilize una aproximación reportada en otra parte [1].
Figura 2. Diseño TOP de la red neuronal .
Figura 3. Arquitectura RTL neuronal.
Figura 4. Circuito sigmoide.
Figura 5. Arquitectura sigmoide RTL [1].
Figura 6. Simulación de Testbench.
Figura 7. Resumen de síntesis utilizando el chip Spartan 3E de Xilinx.
Por último, es importante ver que la red neuronal de punto flotante de una capa implica altos requisitos de hardware, pero produce un resultado solo despues de 6 clocks, lo cual es una ventaja muy importante si compramos con un microcontrolador. Nuestros circuitos toman 6 pusos de reloj que significan 6*20ns = 120ns, que es una latencia muy baja, como se puede ver en la simulación de la figura 6. Por lo tanto, se pueden utilizar técnicas avanzadas para reducir los requisitos de hardware sin pérdida de precisión y manteniendo la latencia baja.
Referencias:
Thamer M.Jamel, IMPLEMENTATION OF A SIGMOID ACTIVATION FUNCTION FOR NEURAL NETWORK USING FPGA, Published in the 13th Scientific Conference of Al-Ma'moon University College -18 April 2012 – Baghdad , Iraq.
Referencias:
Thamer M.Jamel, IMPLEMENTATION OF A SIGMOID ACTIVATION FUNCTION FOR NEURAL NETWORK USING FPGA, Published in the 13th Scientific Conference of Al-Ma'moon University College -18 April 2012 – Baghdad , Iraq.