没有合适的资源?快使用搜索试试~ 我知道了~
15061075_张安澜_lab31
需积分: 0 0 下载量 155 浏览量
2022-08-04
16:28:44
上传
评论
收藏 472KB PDF 举报
温馨提示
试读
27页
一、摘要在这个实验中,我在 Znqy 7020 板子上实现了一个大型 CNN 网络 VGG16 的前向传播过程。并进行了对于优化的思考。二、实验目的设计专门硬件
资源详情
资源评论
资源推荐
实验三:在 Zynq FPGA 上实现 VGG16 网络
实验报告
姓名:张安澜
学号:15061075
2018 年 1 月 27 日
小组成员与分工
成员:张安澜、游心、胡卓仑
分工:所有工作均由我(张安澜)一人完成,主要原因是队友不配合,也没有想做的决
心。在这里感谢司靖辉同学以及助教学长在我完成实验的过程中给我提供的帮助。
一、摘要
在这个实验中,我在 Znqy 7020 板子上实现了一个大型 CNN 网络 VGG16 的前向传播过
程。并进行了对于优化的思考。
二、实验目的
设计专门硬件结构,实现 VGG16 网络的前向传播过程,进行图片识别(inference):
1. 使用算法开发框架(Cafffe/TF/PyTorch/etc.)进行训练、测试,理解 VGG16 网络结构,熟知前向
传播的计算过程,并将训练好的模型数据整理出来,待硬件实现用。
2. 掌握使用 xilffs 库进行 SD 卡读写方法(参考实验附件二中 SD 卡读写部分)、使用 DMA 进
行 PS、PL 端数据交互的方法等。
3. 掌握进行分层前向传播计算的结构的设计方法。
4. 掌握系统设计、仿真、综合、验证、上板测试以及调试的方法
三、实验要求
1. 实验以小组为单位共同完成,每组 2~3 人。
2. 实验内容: PS 端将训练好的模型及测试数据读入,PL 端实现前向传播的计算过程,模型权值
存入 SD 卡,通过 DMA 传输至 PL 端的片上存储(BRAM),PS-PL 通过 AXI 接口连接,生成硬件
并导入 SDK 环境中,经过仿真、综合、验证之后,下载到开发板上进行实测。
3. 实验结束后撰写实验报告,要求包括项目架构设计介绍、关键实验步骤说明、关键部分源
代码、设计结果分析及优化思路与技巧。并将完整的工程文件提交到课程中心,助教会对工
程设计的源码等内容进行查重,并进行上板实测。
四、实验环境
1、算法开发框架(TF)
2、Vivado HLx 套装及 Vivado SDK。
3、AX7020 开发板。
4、Mini SD 卡读卡器及 USB 转接线。
五、设计方案
1、总框架设计
a、将助教提供的训练好的模型的参数以及测试样例的数据量化为定点数后以二进制补
码的形式存储在 SD 卡中,通过 Xilinx 提供的简易 fat32 文件系统库 Xilffs 进行读取,并采用
DMA 实现 PS 与 PL 端数据交互。
b、设计时的思考
(1)每层网络的计算都分为 loaddma、vgg16_calculate 和 storedma 三大状态;
(2)loaddma 表示从 PS 端向 PL 端传输数据,vgg16_calculate 表示 PL 端进行相应的运
算,storedma 表示从 PL 端向 PS 端传输数据;
(3)设计时采用了简化的思想,主要体现在:实例化了一块超大的 Block RAM,先将
每次计算用到的所有数据都从外面的小的 Block RAM 中存到大的这块 Block RAM 中之
后才进行相应的运算,因此外面的小 Block RAM 需要双端口模式;不管 PL 端寄存器资
源是否够用,在必要时都将结果存回内存, 这样主要是为了实现时写代码方便;
(4)由于网络太大,必须对每一层进行拆分,而拆分时势必涉及到根据通道数进行拆
分,比如原来是 64 通道的原始数据要拆成 16 个 4 通道的原始数据,因此在 PS 和 PL 端
必须要有一个信号 addbefore 来控制是否需要和之前计算的结果相加;而每次导入 bias
也会根据计算的过程进行改变,这个在 PS 端中写代码控制即可;
(5)由于 VGG16 这个 IP 核中的 Block RAM 需要从外面的小的 Block RAM 中读取数据
或向外面的小的 Block RAM 写入数据,因此需要 PS 端给它一个控制信号 base_addr 来控
制读到的数据要从这块大的 Block RAM 中的哪一个地址开始保存,或是将这块大的
Block RAM 中的哪一个地址开始的数据写入外面小的 Block RAM 中,以及另一个信号
num 表示读入或写入的数据个数,当然还有 PS 和 PL 端交互的控制信号 loaddma_start、
l oaddma_finish、storedma_start、storedma_finish;
(6)同时,PS 端还要控制 PL 端的计算,之前已经提到了一个 addbefore 信号,另外 PS
端还需要传入一个 layer 信号表示当前需要计算的是第几层,具体的编号方式在 d 中给出,
总之 PL 端读到这个这个 layer 信号就会进行对应的运算,当然还有 PS 和 PL 端交互的控
制信号 vgg16_start、vgg16_finish;
(7)基于(5)、(6),在封装 IP 时,需要 6 个寄存器,具体在 c 中说明。同时还需
要添加一些 User Ports:doutb_in、clkb_out、rstb_out、enb_out、web_out、addrb_out、
dinb_out 来和外面的小 Block RAM 的其中一个端口进行连接;
(8)对网络的每一层,PS 端每次都会直接先把该层用到的所有参数全部从 SD 卡中读
入内存(经过尝试应该是可以存下的),然后根据计算的具体情况将对应的数据和参数
从 PS 端传输至 PL 端,由于 PS 和 PL 之间传输的数据类型是 u32,而从 SD 卡中读取时
的数据类型是 u8,因此中间还需要进行一系列的转换,并且根据具体计算情况选择对应
的数据和参数也不是一件简单的事,因此这部分实际上是该实验中比较麻烦的一部分;
(9)为了简化处理,所有从 PL 端传回 PS 端的中间结果,都不写入 SD 卡中,只有最后
结果写入 SD 卡;
(10)每次 PS 端和 PL 端之间的数据传输也需要做好设计,因为不是一次性能传完的,
以及每次 PL 端运算时数据、参数和结果保存的基地址,这些都需要提前算好以参数的
形式写在代码中;
(11)为了追求实现的简单,暂时先不考虑流水、模型压缩、参数共享等优化了,至少
先能在板子上实现这个网络再说;
c、将经过仿真、验证后的 VGG16 inference 模块以及实例化的 1 块 BRAM 一起封装成
AXI Lite 接口的 IP 核。AXI Lite 共有 6 个寄存器。其中 slv_reg0 用于向 IP 核传输控制信号
vgg16_start(slv_reg0[0])、loaddma_start(slv_reg0[1])、storedma_start(slv_reg0[2]),slv_reg1 用
于存储 IP 核传出的结束信号 vgg16_finish(slv_reg1[0])、 loaddma_finish(slv_reg1[1])、
storedma_finish(slv_reg1[2]),slv_reg2 用于传输 addbefore 信号(sl_reg2[0]),slv_reg3 用于传
输 layer 信号(slv_reg3[4:0]),slv_reg4 用于传输 base_addr 信号(slv_reg4[19:0]),slv_reg5 用于
传输 num 信号(slv_reg5[31:0]),上述信号的意义在 b 中已经提到,最后,总的 block design 如
下:
d、顶层逻辑:
从 Conv1_1 开始按顺序对网络的层次进行编号,共编为 0 到 20 号(包括池化层)
for layercount: 0 to 21
begin
PS
端从
SD
卡中读入该层的参数(以及第一层需要读原始数据)
if
卷积层
for
每一层拆分出的小卷积
begin
PS
端从内存中选择当前需要的数据和参数通过
DMA
传输到
PL
端
对当前的小型网络进行运算
if
对某些
filter
已经做完所有通道的运算
将结果通过
DMA
从
PL
端传输到
PS
端,保存在内存中
end if
end for
end if
if
池化层
for
每一层拆分出的小池化
begin
PS
端从内存中选择当前需要的数据通过
DMA
传输到
PL
端
对当前的小型网络进行运算
将结果通过
DMA
从
PL
端传输到
PS
端,保存在内存中
end for
end if
if
全连接层
for
每一层拆分出的小全连接
PS
端从内存中选择当前需要的数据通过
DMA
传输到
PL
端
对当前的小型网络进行运算
将结果通过
DMA
从
PL
端传输到
PS
端,保存在内存中
end for
if
全连接层
3
已经完成
将内存中全连接层
3
的结果写入
SD
卡的文件中
exit(0)
end if
end if
end for
2、定点数量化
a、所有数据和参数被量化为 8 位定点纯小数:1 位符号位 + 1 位整数位 + 6 位小数位。
b、使用的工具是 Octave(Matlab 也可)。
c、量化算法:
input:
待量化的数
din,
量化后的小数位数
prec_f
output:
量化后的
8
位二进制补码形式
dout
algrithm:
beign
if din == 1 then
din ::= din * 2^prec_f - 1
else
din ::= din * 2^prec_f
end if
din ::= round(din) //
取
din
最近的整数
if din < 0
din ::= din + 2^(prec_f+1)
end if
douta ::= dec2bin(din, 7) //
将正整数转化为
7
位二进制形式
dout ::= {douta[0], douta}
end
3、VGG16 网络结构的分析与拆分
a、VGG16 的计算花费
Layer name data weight bias result
conv1_1 224*224*3 3*3*3*64 64 224*224*64
conv1_2 224*224*64 3*3*64*64 64 224*224*64
pool1 224*224*64 0 0 112*112*64
剩余26页未读,继续阅读
五月Eliy
- 粉丝: 33
- 资源: 305
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0