基于FPGA的卷积神经网络实现(三)资源分配(1)

目录:

  1. 简介
  2. 框架
  3. 资源分配(1)
  4. 资源分配(2)
  5. 数据量化(1)
  6. 数据量化(2)
  7. 数据读写
  8. 卷积模块
  9. 池化、全连接与输出

我发现点下面的链接会跳到一个不知道是谁的CSDN下面需要付费下载,这个很迷惑,麻烦自行复制下面的链接。
Github:https://github.com/MasLiang/CNN-On-FPGA
那个不知道是谁的链接:https://download.csdn.net/download/weixin_42138780/18551586
没有下载不让举报,有办法的朋友麻烦举报一下

前面曾经说过这个demo使用最简单的方法,也就是对每一层都单独分配资源,所以需要提前设计好每一层所分配的资源数量。这里的资源主要是指DSP单元和片上存储资源,CNN的卷积层是计算密集型层,全连接层是存储密集型层,整个CNN所需要的计算资源(也就是我们使用DSP单元来实现)和存储资源远远大于对其他资源的需求。仍然是从最简单的方式开始,整个demo的网络结构很小而简单(网络结构在这里),再买上一块儿略屌的板子,比如说zynq7000-zc706(这板子确实很贵,但是一开始我们可以只是仿真,对于上板可以等基本掌握了这种设计思路之后,再进行优化,然后对于不同的板子进行不同的设),19.1M block RAM,900DSP单元(详细信息)。现在网络框架有了板子也有了,那么我们根据这些资源数据来设计。
整个网络结构的参数量如下表所示:

参数量(个)
卷积层15 * 5 * 1 * 4
卷积层25 * 5 * 4 * 8
卷积层35 * 5 * 8 * 16
全连接层14032 * 100
全连接层2100 * 4
全总计407700

假设我们使用全精度(32位浮点)来存储,那么总计需要片上存储空间13M(如果对参数进行低位宽量化,将会减小对存储的需求)。
下面考虑可能出现的运行缓存,这里的缓存是指,在每一层计算的时候,该层的结果在输入到下一层使用之前需要暂时存储起来。我们先不考虑优化问题,假设每一层的所有输出都需要缓存起来,并且一直不释放一直到整个前向传播过程结束,来计算最大需要的缓存空间。(事实上,每一部分缓存数据在使用完后可以得到释放,只需要单层最大缓存空间即可;另外,使用一定的优化方法可以进一步降低缓存占用空间)。每一层输入所需要的缓存空间如下表所示:

输入缓存空间
卷积层1256 * 100 * 1
卷积层2126 * 48 * 4
卷积层361 * 22 * 8
全连接层14032
全连接层2100
全总计64660

仍然假设使用全精度(32位浮点数)来存储,那么总计需要片上存储空间 2M。是不是就结束了?其实并没有,前面我们只是认为卷积层和全连接层这样的计算层需要缓存,实际上,池化层也需要单独拎出来,也就是说池化层的输入也需要缓存,每一个卷积层后面会接一个池化层,那么我们再重新来计算一下存储需求上限:

输入缓存空间
卷积层1256 * 100 * 1
池化层1252 * 96 * 4
卷积层2126 * 48 * 4
池化层2122 * 44 * 8
卷积层361 * 22 * 8
池化层356 * 18 * 16
全连接层14032
全连接层2100
全总计64660

这样一来缓存需要的存储空间上限为6.7M,也就是说,如果我们将所有的参数和缓存数据存储在片上存储空间,总计需要19.7M,ZC706是不可以cover的。但是呢这里有个值得注意的地方在于,我们所有的数据都是使用32bit的位宽进行存储,实际上我们可以使用更低bit来存储这些数据,这将缩小对空间是使用,关于量化的问提,进来的研究有很多,16bit定点数基本可以是无损的,pytorch1.4也提供了定点数量化工具,如果想在这方面进行研究的同学可以自行搜索一些相关论文(我有同学做这个,今年在CVPR2020有几篇低bit量化的工作做的已经很强了)。如果想快速做一个demo出来,最简单的办法就是训练出来的网络,将参数直接进行量化,不再retrain,这样会有一定精度损失。
回到FPGA的硬件资源继续分析,既然16bit定点数来存储各种数据我们认为是无损的,那么我们可以认为整个demo的存储需求上限是9.85M,也就是说这个板子能够cover整个网络的存储,所以就不需要在认为去分配每一层使用多少。这里要注意的是,我们说的是存储上限,也就是说实际设计的时候还会比这更低,这需要结合DSP资源的分配来设计结构,我们后面再进一步分析。
下面去考虑DSP单元的数量。DSP单元用于计算卷积,我们使用DSP计算乘法(乘加)运算,我们还是以最简单的来,就让一个DSP单元计算在一个时钟内计算一次乘法,加法再单独计算。
对于每个卷积核的卷积的计算有两种方式:

  1. 一些(或一个)DSP单元重复利用,每个时钟进行一定数量的(或一个)乘法运算,串行完成所有计算
  2. 多个DSP单元在一个时钟内完成所有乘法计算

对于不同的卷积核之间又有两种情况:

  1. 一层所有的卷积核并行进行
  2. 部分卷积核(也可能是一个卷积核)并行进行

对于本demo来说,如果我们在卷积核内选择第二种方式,卷积核间也选择第一种方式,那么每一层需要的DSP单元数量如下表所示:

DSP单元数量(个)
卷积层15 * 5 * 1 * 4
卷积层25 * 5 * 4 * 8
卷积层35 * 5 * 8 * 16

是不是非常眼熟?没错,这就是前面的卷积层参数量的表格,显然这种方式等价于我们给每个卷积层参数分配一个DSP单元。也就是说我们总计需要4100个DSP单元,显然这是远远超过板载DSP单元数量的,因此这是不可行的。那么我们来考虑降低卷积核之间的并行程度,降到最低的状态即为每一层都只并行计算一个卷积核,那么每一层需要的DSP数量变为:

DSP单元数量(个)
卷积层15 * 5 * 1
卷积层25 * 5 * 4
卷积层35 * 5 * 8

总计为325个,因此我们的卷积核内部是可以全部并行进行计算的。
另一种组合是卷积核间仍然是全并行的,而卷积核内部是部分并行的,这种方式是可行的,这种方式所需要的最小DSP单元个数是每个卷积核分配一个DSP单元,那么总计需要28个,我们仍可以进一步的增加卷积核内部的并行程度,以充分利用板载DSP资源。
最后一种组合方式是卷积核内部部分并行,卷积核见也部分并行,显然这种方式的最小DSP单元需求量更小,也是可以考虑的一种。

结论:我们在分配DSP单元的时候,应使得每一层卷积核内部的卷积运算部分并行,卷积核之间部分或完全并行

下一节我将对这两种方式进行对比,并将对缓存的优化纳入考量,最终确定DSP资源的分配。

  • 21
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 25
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值