0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

从FPGA说起的深度学习

OpenFPGA 来源:OpenFPGA 2023-03-03 09:52 次阅读

这是新的系列教程,在本教程中,我们将介绍使用 FPGA 实现深度学习的技术,深度学习是近年来人工智能领域的热门话题

在本教程中,旨在加深对深度学习和 FPGA 的理解。

用 C/C++ 编写深度学习推理代码

高级综合 (HLS) 将 C/C++ 代码转换为硬件描述语言

FPGA 运行验证

在上一篇文章中,我们用C语言实现了一个卷积层,并查看了结果。在本文中,我们将实现其余未实现的层:全连接层、池化层和激活函数 ReLU。

每一层的实现

全连接层

全连接层是将输入向量X乘以权重矩阵W,然后加上偏置B的过程。下面转载第二篇的图,能按照这个图计算就可以了。

d1d45f6a-b8ec-11ed-bfe3-dac502259ad0.png

全连接层的实现如下。

voidlinear(constfloat*x,constfloat*weight,constfloat*bias,
int64_tin_features,int64_tout_features,float*y){
for(int64_ti=0;i< out_features; ++i) {
    float sum = 0.f;
    for (int64_t j = 0; j < in_features; ++j) {
      sum += x[j] * weight[i * in_features + j];
    }
    y[i] = sum + bias[i];
  }
}

该函数的接口和各个数据的内存布局如下。

考虑稍后设置 PyTorch 参数,内存布局与 PyTorch 对齐。

输入

x: 输入图像。shape=(in_features)

weight: 权重因子。shape=(out_features, in_features)

bias: 偏置值。shape=(out_features)

输出

y: 输出图像。shape=(out_features)

参数

in_features: 输入顺序

out_features: 输出顺序

在全连接层中,内部操作数最多为out_channels * in_channels一个,对于典型参数,操作数远低于卷积层。

另一方面,关注权重因子,卷积层为shape=(out_channels, in_channels, ksize, ksize),而全连接层为shape=(out_features, in_features)。例如,如果层从卷积层变为全连接层,in_features = channels * width * height则以下关系成立。width, height >> ksize考虑到这一点,在很多情况下,全连接层参数的内存需求大大超过了卷积层。

由于FPGA内部有丰富的SRAM缓冲区,因此擅长处理内存访问量大和内存数据相对于计算总量的大量复用。单个全连接层不会复用权重数据,但是在视频处理等连续处理中,这是一个优势,因为要进行多次全连接。

另一方面,本文标题中也提到的边缘环境使用小型FPGA,因此可能会出现SRAM容量不足而需要访问外部DRAM的情况。如果你有足够的内存带宽,你可以按原样访问它,但如果你没有足够的内存带宽,你可以在参数调整和训练后对模型应用称为剪枝和量化的操作。

池化层

池化层是对输入图像进行缩小的过程,这次使用的方法叫做2×2 MaxPooling。在这个过程中,取输入图像2x2区域的最大值作为输出图像一个像素的值。这个看第二张图也很容易理解,所以我再贴一遍。

d1e5c2dc-b8ec-11ed-bfe3-dac502259ad0.png

即使在池化层,输入图像有多个通道,但池化过程本身是针对每个通道独立执行的。因此,输入图像中的通道数和输出图像中的通道数在池化层中始终相等。

池化层的实现如下所示:

voidmaxpool2d(constfloat*x,int32_twidth,int32_theight,int32_tchannels,int32_tstride,float*y){
for(intch=0;ch< channels; ++ch) {
    for (int32_t h = 0; h < height; h += stride) {
      for (int32_t w = 0; w < width; w += stride) {
        float maxval = -FLT_MAX;

        for (int bh = 0; bh < stride; ++bh) {
          for (int bw = 0; bw < stride; ++bw) {
            maxval = std::max(maxval, x[(ch * height + h + bh) * width + w + bw]);
          }
        }

        y[(ch * (height / stride) + (h / stride)) * (width / stride) + w / stride] = maxval;
      }
    }
  }
}

这个函数的接口是:

此实现省略了边缘处理,因此图像的宽度和高度都必须能被stride整除。

输入

x: 输入图像。shape=(channels, height, width)

输出

y: 输出图像。shape=(channels, height/stride, width/stride)

参数

width: 图像宽度

height: 图像高度

stride:减速比

ReLU

ReLU 非常简单,因为它只是将负值设置为 0。

voidrelu(constfloat*x,int64_tsize,float*y){
for(int64_ti=0;i< size; ++i) {
    y[i] = std::max(x[i], .0f);
  }
}

由于每个元素的处理是完全独立的,x, y因此未指定内存布局。

硬件生成

到这里为止的内容,各层的功能都已经完成了。按照上一篇文章中的步骤,可以确认这次创建的函数也产生了与 libtorch 相同的输出。此外,Vivado HLS 生成了一个通过 RTL 仿真的电路。从这里开始,我将简要说明实际生成了什么样的电路。

如果将上述linear函数原样输入到 Vivado HLS,则会发生错误。这里,将输入输出设为指针->数组是为了决定在电路制作时用于访问数组的地址的位宽。另外,in_features的值为778=392,out_将features的值固定为32。这是为了避免Vivado HLS 在循环次数可变时输出性能不佳。

staticconststd::size_tkMaxSize=65536;

voidlinear_hls(constfloatx[kMaxSize],constfloatweight[kMaxSize],
constfloatbias[kMaxSize],floaty[kMaxSize]){
dnnk::linear(x,weight,bias,7*7*8,32,y);
}

linear_hls函数的综合报告中的“性能估计”如下所示:

d1fd7c74-b8ec-11ed-bfe3-dac502259ad0.png

在Timing -> Summary中写入了综合时指定的工作频率,此时的工作频率为5.00 ns = 200MHz。重要的是 Latency -> Summary 部分,它描述了执行此函数时的周期延迟(Latency(cycles))和实时延迟(Latency(absolute))。看看这个,我们可以看到这个全连接层在 0.566 ms内完成。

在 Latency -> Detail -> Loop 列中,描述了每个循环的一次迭代所需的循环次数(Iteration Latency)和该循环的迭代次数(Trip Count)。延迟(周期)包含Iteration Latency * Trip Count +循环初始化成本的值。Loop 1 是out_features循环到loop 1.1 in_features。在Loop1.1中进行sum += x[j] * weight[i * in_features + j]; 简单计算会发现需要 9 个周期才能完成 Loop 1.1 所做的工作。

使用HLS中的“Schedule Viewer”功能,可以更详细地了解哪些操作需要花费更多长时间。下图横轴的2~10表示Loop1.1的处理内容,大致分为x,weights等的加载2个循环,乘法(fmul)3个循环,加法(fadd)4个循环共计9个循环。

d21899a0-b8ec-11ed-bfe3-dac502259ad0.png

在使用 HLS 进行开发期间通过添加#pragma HLS pipeline指令,向此代码添加优化指令以指示它创建高效的硬件。与普通的 FPGA 开发类似,运算单元的流水线化和并行化经常用于优化。通过这些优化,HLS 报告证实了加速:

流水线:减少迭代延迟(min=1)

并行化:减少行程次数,删除循环

正如之前也说过几次的那样,这次的课程首先是以FPGA推理为目的,所以不会进行上述的优化。有兴趣进行什么样的优化的人,可以参考以下教程和文档。

教程

https://github.com/Xilinx/HLS-Tiny-Tutorials

文档

https://www.xilinx.com/support/documentation/sw_manuals/xilinx2019_2/ug902-vivado-high-level-synthesis.pdf

最后,该函数的接口如下所示。

d245d35c-b8ec-11ed-bfe3-dac502259ad0.png

由于本次没有指定接口,所以数组接口如x_ 等ap_memory对应FPGA上可以1个周期读写的存储器(BRAM/Distributed RAM)。在下一篇文章中,我们将连接每一层的输入和输出,但在这种情况下,我们计划连接 FPGA 内部的存储器作为每一层之间的接口,如本例所示。

总结

在本文中,我们实现了全连接层、池化层和 ReLU。现在我们已经实现了所有层,我们将在下一篇文章中组合它们。之后我们会实际给MNIST数据,确认我们可以做出正确的推论。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1602

    文章

    21320

    浏览量

    593194
  • C语言
    +关注

    关注

    180

    文章

    7530

    浏览量

    128610
  • 人工智能
    +关注

    关注

    1776

    文章

    43845

    浏览量

    230600
  • C++
    C++
    +关注

    关注

    21

    文章

    2066

    浏览量

    72900
  • 深度学习
    +关注

    关注

    73

    文章

    5237

    浏览量

    119908

原文标题:从FPGA说起的深度学习(四)

文章出处:【微信号:Open_FPGA,微信公众号:OpenFPGA】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    相比GPU和GPP,FPGA深度学习的未来?

    相比GPU和GPP,FPGA在满足深度学习的硬件需求上提供了具有吸引力的替代方案。凭借流水线并行计算的能力和高效的能耗,FPGA将在一般的深度
    发表于 07-28 12:16 7369次阅读

    FPGA深度学习应用中或将取代GPU

    现场可编程门阵列 (FPGA) 解决了 GPU 在运行深度学习模型时面临的许多问题 在过去的十年里,人工智能的再一次兴起使显卡行业受益匪浅。英伟达 (Nvidia) 和 AMD 等公司的股价也大幅
    发表于 03-21 15:19

    Nanopi深度学习之路(1)深度学习框架分析

    就能实现!还请关注我后面的日记。实际上我也是刚刚有时间学习深度学习,我是个纯初学者,但面对深度学习里的各种复杂理论和公式推导,自己实现个小功
    发表于 06-04 22:32

    【详解】FPGA深度学习的未来?

    的固定架构之外进行模型优化探究。同时,FPGA在单位能耗下性能更强,这对大规模服务器部署或资源有限的嵌入式应用的研究而言至关重要。本文硬件加速的视角考察深度学习
    发表于 08-13 09:33

    为什么说FPGA是机器深度学习的未来?

    都出现了重大突破。深度学习是这些领域中所最常使用的技术,也被业界大为关注。然而,深度学习模型需要极为大量的数据和计算能力,只有更好的硬件加速条件,才能满足现有数据和模型规模继续扩大的需
    发表于 10-10 06:45

    深度学习模型是如何创建的?

    嵌入式系统已被证明可以降低成本并增加各个行业的收入,包括制造工厂,供应链管理,医疗保健等等。本文将介绍有关深度学习嵌入式系统的信息。深度学习模型是如何创建的?创建
    发表于 10-27 06:34

    什么是深度学习?使用FPGA进行深度学习的好处?

    上述分类之外,还被用于多项任务(下面显示了四个示例)。在 FPGA 上进行深度学习的好处我们已经提到,许多服务和技术都使用深度学习,而 GP
    发表于 02-17 16:56

    FPGA深度学习的未来

    FPGA深度学习的未来,学习资料,感兴趣的可以看看。
    发表于 10-26 15:29 0次下载

    国内首款FPGA云服务器的深度学习算法背景及算法分析

    由腾讯云基础产品中心、腾讯架构平台部组成的腾讯云FPGA联合团队,在这里介绍国内首款FPGA云服务器的工程实现深度学习算法(AlexNet),讨论
    发表于 11-15 20:20 2503次阅读

    深度学习方案ASIC、FPGA、GPU比较 哪种更有潜力

    几乎所有深度学习的研究者都在使用GPU,但是对比深度学习硬鉴方案,ASIC、FPGA、GPU三种究竟哪款更被看好?主要是认清对
    发表于 02-02 15:21 1w次阅读
    <b class='flag-5'>深度</b><b class='flag-5'>学习</b>方案ASIC、<b class='flag-5'>FPGA</b>、GPU比较 哪种更有潜力

    FPGA深度学习领域的应用

    本文从硬件加速的视角考察深度学习FPGA,指出有哪些趋势和创新使得这些技术相互匹配,并激发对FPGA如何帮助深度
    的头像 发表于 06-28 17:31 6568次阅读

    微软最新发布FPGA深度学习云平台

    微软发布了 Project Brainwave,一个基于 FPGA 的低延迟深度学习云平台。微软官方测评显示,当使用英特尔的 Stratix 10 FPGA,Brainwave 不需要
    发表于 07-03 14:58 896次阅读

    FPGA深度学习领域有哪些优势?

    FPGA(Field-Programmable Gate Array)是一种灵活的可编程硬件设备,它在深度学习应用领域中具有许多优势。
    的头像 发表于 03-09 09:41 1439次阅读

    FPGA说起深度学习:任务并行性

    这是新的系列教程,在本教程中,我们将介绍使用 FPGA 实现深度学习的技术,深度学习是近年来人工智能领域的热门话题。
    的头像 发表于 04-12 10:19 596次阅读

    FPGA说起深度学习:数据并行性

    这是新的系列教程,在本教程中,我们将介绍使用 FPGA 实现深度学习的技术,深度学习是近年来人工智能领域的热门话题。
    的头像 发表于 05-04 11:22 825次阅读
    从<b class='flag-5'>FPGA</b><b class='flag-5'>说起</b>的<b class='flag-5'>深度</b><b class='flag-5'>学习</b>:数据并行性