热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于FPGA的卷积神经网络实现(七)卷积模块

将卷积展开后要进行的运算实质上是大规模矩阵运算,因此卷积模块的实现时最容易的,什么都不需要考虑,数据按顺序来了就计算,而这个顺序是数据读取部分需要考虑的,计算完了输出去这部分是下一

将卷积展开后要进行的运算实质上是大规模矩阵运算,因此卷积模块的实现时最容易的,什么都不需要考虑,数据按顺序来了就计算,而这个顺序是数据读取部分需要考虑的,计算完了输出去这部分是下一层的数据数据存储部分需要考虑的。因此整体而言,整个网络模型中最容易实现的却是这里面最核心的计算部分。
言归正传。首先要对卷积的循环进行分析,这也是很多基于FPGA的CNN加速器里面所重点研究的。这里推荐一篇FPGA2017的论文,对循环的优化做了比较详细的分析。我们的demo就用最简单的方式进行了。
卷积循环分为四层,这里引用上面说的论文中的伪代码图。
基于FPGA的卷积神经网络实现(七)卷积模块
分别解释一下:

  1. Loop1:是指卷积核的xy方向计算
  2. Loop2:是指滤波器不同输入通道的卷积核
  3. Loop3:是指滤波器在特征图上面的滑动
  4. Loop4:是指多个滤波器

循环真正影响到的应该是数据的读取时序。循环1要做的是读取一个卷积核的参数和特征图中对应的部分进行乘加运算;循环2要做的是循环读取不同的输入通道的卷积核和特征图数据;循环3要做的是在特征图上滑动,也就是说循环的在特征图上读取以不同像素为中心的数据块;循环4要做的是循环读取不同的滤波器。而卷积模块中就是要针对于这些数据读取顺序进行相应的计算。
这部分优化的方法有很多,举个例子,对于大型的网络模型而言,大多数参数和特征图是要存在片外的,而片外访存的代价是很大的,因此尽可能的进行数据复用是非常有效的优化方式,因此有些研究对循环进行的顺序交替,来提升数据的复用效率,在此不再赘述,有兴趣的同学可以去看看17/18年的论文,对这部分的讨论已经很清晰了。
我们仅仅使用最简单的方式,也就是最原始的4层循环来进行。下面要做的就是在模块中设计一个乘法阵列,也就是很多研究中所说的PE阵列、脉动阵列之类的,都是相似的思想。
这里我们调用DSP单元用作定点数乘法器设计。注意,这里使用的是定点数乘法器,也就是说,我们前面提到的定点数量化在这里派上了用场,根据前面的量化位宽来对DSP乘法器进行设计。
这里有一个trick可以使用一个DSP进行多个定点乘法操作,详见这里。
得到的结果还需要进行位宽截断处理。举个例子。如果我们使用8bit进行量化,那么我们得到的乘法输出是16bit数据,再经过加法运算,会进一步增大位宽,假设 3 × 3 3 \times 3 3×3的卷积核,那么加法结果会变成20bit,而下一层的输入仍需要8bit位宽。这时候就需要在软件层面进行量化的时候就设计好,在这一层需要保留多少位小数位。假设需要保留4位小数位,而之前的8bit输入是3位小数位,那么结果应该是有6位小数位,也就是说我们需要去掉最后的2位(好像还是很大,这说明什么?要不然高位全是0,要不然就不可能存在3位4位小数的样子。总之这里要在软件层面量化的时候就要考虑好)。
要注意的是,我们除了卷积的乘加运算之外,还有bias 的加法运算,这里的量化也需要对小数位进行对齐。
最后,我们还可以在这一层加入**函数,如果是ReLU就很舒服了,直接判断一下输出的符号位,是1就输出0,是0就输出原始数据,其他的也一样,只需要在流水线的最后加上一级判断就可以得到**值。一般来说,如果使用了一些其他如sigmoid的**函数,是要使用分段线性函数进行拟合的,这样虽然会产生一定的误差,但是如果在软件模型就使用了分段线性函数,那么模型是可以学习到这种的误差的,而使用分段线性函数,那么这里的计算就又变成了和ReLU类似的选择和乘法运算。值得注意的是,一般而言为了减少乘法数量,我们会选择使用2的幂作为分段斜率,从而将乘法转化为移位运算。
理论说完了,我们来看一下程序中是如何做的。
首先是一个基础计算单元,这个单元中可以设置卷积核的尺寸,从而得知累加需要的时钟个数。也就是说PE单元中将会完成Loop1的内容。详细见这里。
在外层模块我们使用了generate来进行循环布线,这是verilog语法中一种比较便利的可以进行并行化布线的方式,即循环内的所有内容都会并行的进行布线。
第一组循环使用嵌套的方式完成了Loop2和Loop4的乘法计算内容。这里值得注意的是,存在着输入通道为1的特殊情况,如果不为1呢?可以参考这里。
第二组循环中对乘法的结果进行的顺序整合,以便于后面池化层进行池化操作。另外,这里还进行了截位处理和一次选择运算,也就是前面提到的位宽对齐和ReLU**函数。
第三组循环将输出进行整合,便于模块间通信。
第四组循环用于将输入数据进行拆分,分散给不同的基础计算单元。
第五组循环用于将输入的权重进行拆分,分散给不同的基础计算单元。
整个模块可以提供了大量的parameter,可以很方便的进行配置。
细心的朋友可能会发现,这里缺少了Loop3的计算部分。这是因为我们将Loop3和Loop4进行了交换,并将Loop3归入了上一节数据读写模块当中。
这就是卷积模块的全部内容了。这部分程序设计还是蛮容易的,因为涉及到的时序问题很少,都是一些并行问题。而这部分优化主要是结合数据读写部分的优化,如循环展开、交换等,还有DSP的复用技术,定点数量化bit位宽越低,DSP可以计算的定点数乘法个数越多。
另外一种优化策略涉及到整个模型的改变,也就是使用快速算法,如FFT、Winograd算法,很多文章对此进行了研究,比如FPGA2018的这篇就使用了Winograd算法。这方面我没有过多的研究,感兴趣的朋友可以自己研究一下。


推荐阅读
  • 【论文】ICLR 2020 九篇满分论文!!!
    点击上方,选择星标或置顶,每天给你送干货!阅读大概需要11分钟跟随小博主,每天进步一丢丢来自:深度学习技术前沿 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 无损压缩算法专题——LZSS算法实现
    本文介绍了基于无损压缩算法专题的LZSS算法实现。通过Python和C两种语言的代码实现了对任意文件的压缩和解压功能。详细介绍了LZSS算法的原理和实现过程,以及代码中的注释。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文由编程笔记#小编整理,主要介绍了关于数论相关的知识,包括数论的算法和百度百科的链接。文章还介绍了欧几里得算法、辗转相除法、gcd、lcm和扩展欧几里得算法的使用方法。此外,文章还提到了数论在求解不定方程、模线性方程和乘法逆元方面的应用。摘要长度:184字。 ... [详细]
  • Java 11相对于Java 8,OptaPlanner性能提升有多大?
    本文通过基准测试比较了Java 11和Java 8对OptaPlanner的性能提升。测试结果表明,在相同的硬件环境下,Java 11相对于Java 8在垃圾回收方面表现更好,从而提升了OptaPlanner的性能。 ... [详细]
  • 如何找到并加速缓慢的代码,提高性能
    本文讲述了如何找到并加速缓慢的代码,提高系统性能。作者通过优化内部循环、利用多处理器运行内部循环以及减少内部循环运行次数等方式来提高代码的执行效率。以一个游戏开发中的案例为例,作者介绍了如何通过调查和排查问题,找到导致帧率下降的设计缺陷,并进行修复。文章总结了优化代码的关键点,并提供了一些实用的方法和技巧。 ... [详细]
  • 本文介绍了一道经典的状态压缩题目——关灯问题2,并提供了解决该问题的算法思路。通过使用二进制表示灯的状态,并枚举所有可能的状态,可以求解出最少按按钮的次数,从而将所有灯关掉。本文还对状压和位运算进行了解释,并指出了该方法的适用性和局限性。 ... [详细]
  • ICRA2019最佳论文  Making Sense of Vision and Touch: SelfSupervised Learning of Multimodal Representatio
    文章目录摘要模型架构模态编码器自监督预测控制器设计策略学习控制器设计实验结论和展望会议:ICRA2019标题:《MakingSenseofVision ... [详细]
  • 人工智能推理能力与假设检验
    最近Google的Deepmind开始研究如何让AI做数学题。这个问题的提出非常有启发,逻辑推理,发现新知识的能力应该是强人工智能出现自我意识之前最需要发展的能力。深度学习目前可以 ... [详细]
  • 2017亚马逊人工智能奖公布:他们的AI有什么不同?
    事实上,在我们周围,“人工智能”让一切都变得更“智能”极具讽刺意味。随着人类与机器智能之间的界限变得模糊,我们的世界正在变成一个机器 ... [详细]
  • 程度|也就是_论文精读:Neural Architecture Search without Training
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了论文精读:NeuralArchitectureSearchwithoutTraining相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Visualizing and Understanding Convolutional Networks(ZFNet网络)论文阅读笔记
    VisualizingandUnderstandingConvolutionalNetworksZFNet网络架构论文阅读笔记2022.4.4论文地址https:arxiv ... [详细]
  • https:www.bilibili.comvideoav43996494?p61补充说明(修正前面代码存在问题):#先验框筛选defchoose_anchor_boxes(sel ... [详细]
author-avatar
多伦多打折优惠信息_205
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有