背景:着手深度学习的FPGA实现的项目半年以来,实现了大量工作,现在需要移交项目,所以总结项目所有的情况,以及移交。
目录
一、项目概览
二、python端
2.1 MTCNN与训练过程
2.2 mAP的测试
2.3 网络结构的更改
2.4 输出python训练的权重到c代码端
python之中的顺序
c代码之中的顺序
三、c代码端
3.1 文件描述
程序文件
权重文件
更改结构顺序
3.2 卷积的更改
初始的依赖openBLAS的卷积函数
重新运用定义编写卷积代码
加入bias和ReLU
存储顺序
四、硬件端
4.1 卷积IPcore
4.2 IPcore报告
时间资源
空间资源
4.3 ARM端工作
五、交接后续需要的工作
项目分为python端,c代码端,硬件端。
python端用于确定相应的网络模型结构,训练模型。从而根据相应的权重进行保存。
c++端用于实现神经网络的推断,也就是只有前馈的预测运算。根据相应的python端的权重,和输入图片,预测得出相应的bounding box。一是因为c++代码执行效率高,并且省去了训练的过程,只有前馈运算过程。二是实现为c++代码可以方便于后面的HLS部署于FPGA上。
硬件端用于部署相应的网络结构。分为ARM端和FPGA端,ARM端就是arm架构,可以用c++代码直接交叉编译即可,FPGA端为FPGA架构,需要将相应的程序通过HLS实现为IPcore,烧写到FPGA上,然后用ARM控制进行运算。
https://github.com/wangbm/MTCNN-Tensorflow
MTCNN是三个级联的网络,Pnet用于生成备选框,Rnet用于对备选框初次筛选,Onet用于确定最终输出的备选框。
所以训练过程需要训练三个网络。
训练流程见上面连接的内容。
mAP为目标检测领域的基础指标。
首先标签相同交并比IoU>0.5表示网络检测正确。
然后画出相应的查全率与查准率的曲线,积分得到的蓝色区域即为mAP。
各类的平均AP即mAP
测试mAP需要将程序做一定的修改,将所有图像的预测标签与groundTruth放入文件夹之中。然后测试。
这一系列过程被封装好,封装到test_all.py之中。
在原始结构的基础上,
python权重与c权重顺序很不一样。python之中权重为四维张量,c代码之中为线性存储的。
因为是线性存储,所以需要一系列偏移地址找到权重位置:
c代码的网络结构需要与python代码的结构一致。每次更改网络结构之后,需要做以下的修改。
openBLAS为线性代数实现的函数。
卷积的运用滑窗函数实现为一个二维矩阵,然后与权重排列成的二维矩阵实现矩阵乘。这也是大多数卷积的实现方式。但是这种方法无法实现于FPGA之上。并且每次进行取框函数会加大运算量。
Convolution in 2D matrix multiplication format:
// input Weight matrix * input feature matrix(Trans) = output feature matrix
// height (outChannels) height (3D_KernelSize) height (outChannels)
// width (3D_KernelSize) width (outFeatureSize) width (outFeatureSize)
我们需要从卷积的定义出发,编写卷积函数。
Without feature_2_matrix process:
// outpBox [out_ChannelNum][out_height][out_width]
// +=weightIn[out_ChannelNum][in_ChannelNum][kernelWidth][kernelHeight]
// *pboxIn[in_ChannelNum][width][height]
伪代码如上,这样,既不用滑窗函数,而且生成的output也可以被下层当作feature直接运用。
定义出发的卷积方便zynqNet改为FPGA内并行的结构。实现加速。
卷积后的过程并入卷积函数利用并行化,尽可能多的将任务给FPGA实现。
卷积IPcore的实现参考zynqNet的结构,在DDR上搬运数据,传入BRAM上,然后通过并行实现加速。
关于IPcore的实现有很多内容,可以参考之前的博客
•Validated in MTCNN code 嵌入入MTCNN代码之中验证
•Validated in HLS test bench (C-simulation) 嵌入HLS的test Bench之中验证。也就是实现c仿真。
•Validated in synthesis and generate report 通过synthesisi和生成相应的报告
•Export RTL 输出RTL代码
•C-RTL co-simulation C与RTL协同仿真。
https://blog.csdn.net/weixin_36474809/article/details/85271940
zynqNet的时钟周期如下,基本与卷积IPcore为同一个数量级。
从MACC的次数考虑
zynqNet的MACC次数固定为 : 152,731,648,整个网络运行时间为2s
MTCNN:
从43,543,288 到85,176,568
按照此时间预测,MTCNN的时间为:
From 0.57sec – 1.12sec
即使占用的资源比zynqNet少很多,但是MIZ7020平台上资源超出预期。
在7035平台上资源够用。
刚开始的MTCNN代码分开的开辟每层的卷积,对于调用IPcore来讲非常耗时。
所以需要更改为在DDR一次性的开辟所有的内存反复调用。
模型压缩,使资源可以在7020平台上运行