Реализация искусственных нейронных сетей на языке описания аппаратуры VHDL. Учебное пособие
.pdf
Рис. 9. Отчет о занимаемых проектом ресурсах
Этап 7. Моделирование работы сети. Результаты моделирования показаны на рис. 10.
Рис. 10. Результаты моделирования сети
Варианты заданий
Функция активации первого слоя: линейная (все варианты). Функция активации второго слоя: пороговая (все варианты). Тип данных: целые числа (все варианты).
Таблица 2 Варианты заданий на реализацию двухслойного персептрона
Ва- |
Число |
Число |
Количество |
Диапазон |
Диапазон |
Диапазон |
|||
входов |
выходов 1-го |
нейронов |
входов |
|
весовых |
параметров |
|||
ри- |
персеп- |
(скрытого) |
2-го (выход- |
|
|
коэффици- |
активац. |
||
ант |
|
|
|||||||
|
трона |
слоя |
ного) слоя |
|
|
ентов |
|
функции |
|
1 |
6 |
4 |
2 |
-256 |
+255 |
-256 |
+255 |
-16 |
+15 |
2 |
6 |
3 |
2 |
-512 |
+511 |
-128 |
+127 |
-32 |
+31 |
3 |
6 |
5 |
2 |
-1024 |
+1023 |
-16 |
+15 |
-64 |
+63 |
4 |
6 |
4 |
2 |
-2048 |
+2047 |
-32 |
+31 |
-16 |
+15 |
5 |
6 |
3 |
2 |
-4096 |
+4095 |
-64 |
+63 |
-32 |
+31 |
6 |
5 |
4 |
3 |
-512 |
+511 |
-32 |
+31 |
-64 |
+63 |
7 |
5 |
5 |
3 |
-1024 |
+1023 |
-64 |
+63 |
-16 |
+15 |
8 |
5 |
4 |
3 |
-2048 |
+2047 |
-256 |
+255 |
-32 |
+31 |
9 |
5 |
3 |
3 |
-4096 |
+4095 |
-128 |
+127 |
-64 |
+63 |
10 |
4 |
4 |
3 |
-512 |
+511 |
-16 |
+15 |
-16 |
+15 |
11 |
4 |
5 |
3 |
-1024 |
+1023 |
-32 |
+31 |
-32 |
+31 |
12 |
4 |
3 |
3 |
-2048 |
+2047 |
-64 |
+63 |
-64 |
+63 |
13 |
4 |
4 |
3 |
-4096 |
+4095 |
-256 |
+255 |
-16 |
+15 |
14 |
3 |
6 |
3 |
-2048 |
+2047 |
-128 |
+127 |
-32 |
+31 |
15 |
3 |
5 |
3 |
-4096 |
+4095 |
-16 |
+15 |
-64 |
+63 |
16 |
3 |
3 |
2 |
-128 |
+127 |
-32 |
+31 |
-32 |
+31 |
17 |
3 |
4 |
3 |
-256 |
+255 |
-64 |
+63 |
-32 |
+31 |
3. Моделирование многослойного персептрона с последовательной загрузкой весовых коэффициентов
Пример задания. Реализовать двухслойный персептрон с 3-мя входами, 2-мя нейронами скрытого слоя и 2-мя выходами с последовательной загрузкой весовых коэффициентов в сеть. Требования (пункты 1 – 6 взяты из задания № 2):
1)тип данных: целые знаковые числа;
2)диапазон входов: xi 128;127 , диапазон весов для 1-го и 2-го слоев
сети: wi 16;15 ;
3)тип функции активации 1-го слоя: линейная;
4)тип функции активации 2-го слоя: пороговая;
5)диапазон коэффициентов (a, b) линейной активационной функции: a,b 16;15 ;
6)быстродействие проекта: 100 МГц;
7)для загрузки весовых коэффициентов использовать один вход данных. Этап 1. Разработка структурной схемы нейронной сети (см. рис. 4).
Этап 2. Разработка функциональной схемы сети без учета количества
разрядов (см. рис. 5).
Этап 3. Уточнение параметров функциональной схемы сети (см. рис. 6). Этап 4. Добавление конвейерных регистров в функциональную схему для
обеспечения требуемой производительности схемы (см. рис. 7).
Этап 5. Добавление схемы последовательной загрузки весовых коэффициентов и порогов сети (рис. 11).
Рис. 11. Схема последовательной загрузки весовых коэффициентов сети
Этап 6. Разработка программы.
LIBRARY ieee;
USE ieee.std_logic_1164.all; LIBRARY altera_mf;
USE altera_mf.altera_mf_components.all;
entity laba1 is Port (
c : in std_logic; -- тактовая частота -- x1, x2, x3 -- входы сети
x1:in std_logic_vector (7 downto 0); x2:in std_logic_vector (7 downto 0); x3:in std_logic_vector (7 downto 0);
din:in std_logic_vector (4 downto 0); -- вход для последовательной загрузки весов
--входы разрешения загрузки весов en_w1 : in std_logic;
en_w2 : in std_logic; en_w3 : in std_logic; en_v1 : in std_logic; en_v2 : in std_logic; en_v3 : in std_logic; en_k1_1 : in std_logic; en_k1_2 : in std_logic; en_k2_1 : in std_logic; en_k2_2 : in std_logic;
--a, b – коэффициенты функции активации 1-го слоя сети a: in std_logic_vector (4 downto 0);
b: in std_logic_vector (4 downto 0);
--por1, por2 – пороговые значения нейронов 2-го слоя сети por1: in std_logic_vector (26 downto 0);
por2: in std_logic_vector (26 downto 0); f1, f2: out std_logic -- выходы сети
);
end laba1;
architecture Behavioral of laba1 is signal data : std_logic_vector(4 downto 0);
signal w1,w2,w3,v1,v2,v3,k1_1,k1_2,k2_1,k2_2 : std_logic_vector(4 downto 0); signal en_w1_t, en_w2_t, en_w3_t, en_v1_t, en_v2_t, en_v3_t : std_logic; signal en_k1_1_t, en_k1_2_t, en_k2_1_t, en_k2_2_t : std_logic;
-- s1, s2, s3, s4 -- выходы суммирующих устройств нейронов signal S1, S2: std_logic_vector (14 downto 0);
signal S3, S4: std_logic_vector (26 downto 0);
signal y1, y2, y3 : std_logic_vector (12 downto 0); -- y1, y2, y3 -- произведения w*x signal p1, p2, p3: std_logic_vector (12 downto 0); -- p1, p2, p3 -- произведения v*x signal z1, q1: std_logic_vector (13 downto 0);
signal y3b, p3b: std_logic_vector (13 downto 0); signal z2, q2, bb: std_logic_vector (19 downto 0); signal t1, t2: std_logic_vector (20 downto 0);
signal m1, m2, m3, m4: std_logic_vector (25 downto 0);
component mul8_5 IS |
|
PORT ( |
|
dataa |
: IN STD_LOGIC_VECTOR (7 DOWNTO 0); |
datab |
: IN STD_LOGIC_VECTOR (4 DOWNTO 0); |
result |
: OUT STD_LOGIC_VECTOR (12 DOWNTO 0); |
clock |
: in std_logic); |
END component; |
|
component add13 |
|
PORT ( |
|
dataa |
: IN STD_LOGIC_VECTOR (12 DOWNTO 0); |
datab |
: IN STD_LOGIC_VECTOR (12 DOWNTO 0); |
clock |
: IN STD_LOGIC; |
result |
: OUT STD_LOGIC_VECTOR (12 DOWNTO 0); |
cout |
: OUT STD_LOGIC); |
end component; |
|
component add14 |
|
PORT ( |
|
dataa |
: IN STD_LOGIC_VECTOR (13 DOWNTO 0); |
datab |
: IN STD_LOGIC_VECTOR (13 DOWNTO 0); |
clock |
: IN STD_LOGIC; |
result |
: OUT STD_LOGIC_VECTOR (13 DOWNTO 0); |
cout |
: OUT STD_LOGIC); |
end component; |
|
component mul15_5 |
|
PORT ( |
|
dataa |
: IN STD_LOGIC_VECTOR (14 DOWNTO 0); |
datab |
: IN STD_LOGIC_VECTOR (4 DOWNTO 0); |
clock |
: IN STD_LOGIC; |
result |
: OUT STD_LOGIC_VECTOR (19 DOWNTO 0)); |
end component; |
|
component add20 |
|
PORT ( |
|
dataa |
: IN STD_LOGIC_VECTOR (19 DOWNTO 0); |
datab |
: IN STD_LOGIC_VECTOR (19 DOWNTO 0); |
clock |
: IN STD_LOGIC ; |
result |
: OUT STD_LOGIC_VECTOR (19 DOWNTO 0); |
cout |
: OUT STD_LOGIC); |
end component; |
|
component mul21_5 |
|
PORT ( |
|
dataa |
: IN STD_LOGIC_VECTOR (20 DOWNTO 0); |
datab |
: IN STD_LOGIC_VECTOR (4 DOWNTO 0); |
clock |
: IN STD_LOGIC; |
result |
: OUT STD_LOGIC_VECTOR (25 DOWNTO 0)); |
end component; |
|
component add26 |
|
PORT ( |
|
dataa |
: IN STD_LOGIC_VECTOR (25 DOWNTO 0); |
datab |
: IN STD_LOGIC_VECTOR (25 DOWNTO 0); |
clock |
: IN STD_LOGIC ; |
result |
: OUT STD_LOGIC_VECTOR (25 DOWNTO 0); |
cout |
: OUT STD_LOGIC); |
end component; |
|
component comp_eq27 |
|
PORT ( |
|
dataa |
: IN STD_LOGIC_VECTOR (26 DOWNTO 0); |
datab |
: IN STD_LOGIC_VECTOR (26 DOWNTO 0); |
clock |
: IN STD_LOGIC; |
AgeB |
: OUT STD_LOGIC); |
end component; |
|
begin |
|
process(c) begin
if (c='1' and c'event)
then data(4 downto 0) <= din(4 downto 0); end if;
end process;
process(c) begin
if (c='1' and c'event) then en_w1_t <= en_w1;
en_w2_t <= en_w2; en_w3_t <= en_w3; en_v1_t <= en_v1; en_v2_t <= en_v2; en_v3_t <= en_v3; en_k1_1_t <= en_k1_1; en_k1_2_t <= en_k1_2; en_k2_1_t <= en_k2_1; en_k2_2_t <= en_k2_2;
end if; end process;
process(c) begin
if (c='1' and c'event) then if (en_w1_t = '1')
then w1(4 downto 0) <= data(4 downto 0); end if;
end if; end process;
process(c)
begin
if (c='1' and c'event) then if (en_w2_t = '1')
then w2(4 downto 0) <= data(4 downto 0); end if;
end if; end process;
process(c) begin
if (c='1' and c'event) then if (en_w3_t = '1')
then w3(4 downto 0) <= data(4 downto 0); end if;
end if; end process;
process(c) begin
if (c='1' and c'event) then if (en_v1_t = '1')
then v1(4 downto 0) <= data(4 downto 0); end if;
end if; end process;
process(c) begin
if (c='1' and c'event) then if (en_v2_t = '1')
then v2(4 downto 0) <= data(4 downto 0); end if;
end if; end process;
process(c) begin
if (c='1' and c'event) then if (en_v3_t = '1')
then v3(4 downto 0) <= data(4 downto 0); end if;
end if; end process;
process(c) begin
if (c='1' and c'event) then if (en_k1_1_t = '1')
then k1_1(4 downto 0) <= data(4 downto 0); end if;
end if;
end process; process(c) begin
if (c='1' and c'event) then if (en_k1_2_t = '1')
then k1_2(4 downto 0) <= data(4 downto 0); end if;
end if; end process;
process(c) begin
if (c='1' and c'event) then if (en_k2_1_t = '1')
then k2_1(4 downto 0) <= data(4 downto 0); end if;
end if; end process;
process(c) begin
if (c='1' and c'event) then if (en_k2_2_t = '1')
then k2_2(4 downto 0) <= data(4 downto 0); end if;
end if; end process;
-- block1
block1: mul8_5 PORT MAP( dataa => x1 (7 downto 0), datab => w1 (4 downto 0), clock => c,
result => y1 (12 downto 0));
-- block2
block2: mul8_5 PORT MAP( dataa => x2 (7 downto 0), datab => w2 (4 downto 0), clock => c,
result => y2 (12 downto 0));
-- block3
block3: mul8_5 PORT MAP( dataa => x3 (7 downto 0), datab => w3 (4 downto 0), clock => c,
result => y3 (12 downto 0));
-- block4
block4: mul8_5 PORT MAP( dataa => x1 (7 downto 0),
datab => v1 (4 downto 0), clock => c,
result => p1 (12 downto 0));
-- block5
block5: mul8_5 PORT MAP( dataa => x2 (7 downto 0), datab => v2 (4 downto 0), clock => c,
result => p2 (12 downto 0));
-- block6
block6: mul8_5 PORT MAP( dataa => x3 (7 downto 0), datab => v3 (4 downto 0), clock => c,
result => p3 (12 downto 0));
-- block7
block7 : add13 PORT MAP (
dataa |
=> y1 (12 downto 0), |
|
datab |
=> y2 (12 downto 0), |
|
clock |
=> c, |
|
result |
=> z1 |
(12 downto 0), |
cout |
=> z1 |
(13)); |
-- block9
block9 : add13 PORT MAP (
dataa |
=> p1 (12 downto 0), |
|
datab |
=> p2 |
(12 downto 0), |
clock |
=> c, |
|
result |
=> q1 |
(12 downto 0), |
cout |
=> q1 |
(13)); |
--block8
process(c) begin
if (c='1' and c'event) then
y3b(12 downto 0) <= y3(12 downto 0); y3b(13) <= '0';
end if; end process;
--block10
process(c) begin
if (c='1' and c'event) then
p3b(12 downto 0) <= p3(12 downto 0); p3b(13) <= '0';
end if; end process;
-- block11
block11 : add14 PORT MAP (
dataa |
=> z1 |
(13 downto 0), |
datab |
=> y3b (13 downto 0), |
|
clock |
=> c, |
|
result |
=> s1 |
(13 downto 0), |
cout |
=> s1 |
(14)); |
-- block12
block12 : add14 PORT MAP (
dataa |
=> q1 (13 downto 0), |
|
datab |
=> p3b (13 downto 0), |
|
clock |
=> c, |
|
result |
=> s2 |
(13 downto 0), |
cout |
=> s2 |
(14)); |
-- block13
block13: mul15_5 PORT MAP( dataa => s1 (14 downto 0), datab => a (4 downto 0), clock => c,
result => z2 (19 downto 0));
-- block15
block15: mul15_5 PORT MAP( dataa => s2 (14 downto 0), datab => a (4 downto 0), clock => c,
result => q2 (19 downto 0));
--block14
process(c) begin
if (c='1' and c'event) then
bb(4 downto 0) <= b(4 downto 0); bb(19 downto 5) <= "000000000000000"; end if;
end process;
--block17
block17 : add20 PORT MAP (
dataa |
=> z2 (19 downto 0), |
|
datab |
=> bb (19 downto 0), |
|
clock |
=> c, |
|
result |
=> t1 |
(19 downto 0), |
cout |
=> t1 |
(20)); |
-- block18
block18 : add20 PORT MAP (
dataa => q2 (19 downto 0), datab => bb (19 downto 0), clock => c,
