知方号

知方号

FPGA学习笔记

FPGA学习笔记

一、Lenet神经网络

Lenet 是一系列网络的合称,包括 Lenet1 - Lenet5,由 Yann LeCun 等人在 1990 年《Handwritten Digit Recognition with a Back-Propagation Network》中提出,是卷积神经网络的 HelloWorld。

神经网络部分我是看这位up主学习的。

Lenet是一个 7 层的神经网络,包含 2 个卷积层,2 个池化层,3 个全连接层。其中所有卷积层的所有卷积核都为 5x5,步长 strid=1,池化方法都为全局 pooling,激活函数为 Sigmoid。

使用pytorch实现如下:

对上述网络模型进行训练后,将模型参数进行保存,方便我们之后对参数的读取。

读取模型参数代码如下:

打印出来后,我们可以看到主要的几个参数模块分为:

conv1.weightconv1.biasconv2.weightconv2.biasfc1.weightfc1.biasfc2.weightfc2.biasfc3.weightfc3.bias之后我们便只需要一个一个打印并保存为单独的dat文件即可。

二、参数格式

打开我们的conv1_weight.dat文件可以看到,数据被以数个"[ ]"所分隔,如下:

其中最里层的"[ ]"是5x5卷积核参数,"[[ ]]"是3个通道(第一层输入则表示RGB3个通道),"[[[ ]]]"是16个卷积核。

但这种格式不利于我们在HLS中调取,因此需要对数据格式进行单独的调整,在HLS设计中卷积层的权重是由3维数组组成的,因此我们也要将dat数据也改成3维数组可读的形式。首先,我们需要知道3维数组在文件的形式,如下:

所以dat格式如下:

除了第一层卷积与第二层卷积是上述格式外,其余的数据均为如下:

将其保存在同一目录下:由于第一层全连接层参数过多,我将其分成了上下两部分,分开调用

三、HLS设计1)、conv函数设计

输入类型的是HLS中的半浮点型half(16位,能较为节省空间,需要更小的话可以使用8位定点数)。

input : 输入的图像数据(conv1是32x32,conv2是14x14)

weight : 输入权重

in_row : 输入大小(32或14)

out_row : 输出大小 (28或10)

core : 卷积核大小 (5)

3)、pool函数设计

这个函数是采用最大值池化

input : 输入数据(28或10)

output : 输出数据 (14或5)

in_row : 输入大小 (28或10)

out_row : 输出大小 (14或5)

4)、激活函数设计

sigmoid激活函数

a : 需要激活的数据 

size : 输入大小 (28x28等)

5)、端口设计

通过axi 总线调用模块,并借助bram来传递数据。

6)、仿真测试7)、HLS设计报告四、Block Design设计

需要用到的:SD卡、uart、HLS生成的IP核、两个bram模块以及bram controller(分别控制输入与输出)

如图:

Data address editor :

五、SDK设计

(没有读卡器 T_T)所以就模拟一下读卡的场景:将图像数据存入SD卡里成为txt文件,再从SD卡中读取并传到bram0里作为输入数据传输到lenet IP核中,再从bram1中读取结果并打印出来。

其中SD卡的操作部分就不赘述了,不熟悉的可以去看看正点原子的教程,里面讲得很详细。

将数组传入bram0:

初始化lenet IP核以及读取bram1数据并打印:

最终结果如图:

结果与仿真测试一致。

参考文章:

如何从零开始将神经网络移植到FPGA(ZYNQ7020)加速_Jarvis码员的博客-CSDN博客_zynq 神经网络

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至lizi9903@foxmail.com举报,一经查实,本站将立刻删除。