您当前的位置: 首页 >  网络

FPGA硅农

暂无认证

  • 4浏览

    0关注

    282博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

基于FPGA的Yolov4 tiny目标检测网络加速器

FPGA硅农 发布时间:2022-02-27 16:47:54 ,浏览量:4

简介

之前实现了基于FPGA的Winograd CNN加速器(VGG16)和基于FPGA的MobileNet v2加速器,但这两个算法在本质上区别不大:一个是VGG16,另一个是轻量级的MobileNet v2,所实现的功能都是图像分类。因此,为了尝试更多的应用,本文在FPGA上实现了一个目标检测网络----Yolov4 tiny。yolo4 tiny的结构是YOLOv4的精简版,属于轻量化模型,参数只有600万相当于原来的十分之一,这类网络不仅能实现对图像的分类任务,还可以找出目标的位置,因此,更加贴近实际应用中的需求,如行人检测、口罩检测等。

网络结构

对于该部分的内容,已经在博主的另一篇文章中进行了详细的介绍,此处略去。

FPGA IP核的设计

根据对网络结构的分析,我们发现,yolo4 tiny主要由以下几个计算组成: 1.3x3标准卷积 2.1x1point-wise卷积 3.上采样、下采样(2x2最大池化) 4.concat操作 我们将上述计算分成两类,第一类是需要重点加速的,如3x3标准卷积和1x1point-wise卷积,它们占网络总体计算量的95%以上,因此是我们需要重点关注的地方。第二类是一些轻量级的运算,如上采样、下采样和concat操作,其中concat可以通过设置起始地址偏移的方式实现,因此不予以考虑,而其他两个运算,计算量相对于整个网络来说,也是微乎其微的,因此简单的在FPGA上实现即可。

3x3标准卷积设计

关于这部分的设计,我们很大程度上参考了论文。

访存部分

由于FPGA片上存储资源(BRAM)十分有限,而卷积神经网络的权重以及中间计算结果特征图都具有较大的存储占用,因此,缓存整幅特征图显然是不现实的,因此,我们采取了循环分块策略。 具体如下: 假 设 输 入 特 征 图 I 为 N × H i n × W i n , 权 重 为 M × N × K × K ( K = 3 ) , 输 出 特 征 图 O 为 M × H × W , 假设输入特征图I为N\times H_{in}\times W_{in},权重为M\times N\times K\times K(K=3),输出特征图O为M\times H\times W, 假设输入特征图I为N×Hin​×Win​,权重为M×N×K×K(K=3),输出特征图O为M×H×W,令输入通道、输出通道、输出特征图高、宽的分块因子分别为 T n , T m , T r , T c T_n,T_m,T_r,T_c Tn​,Tm​,Tr​,Tc​,则每次计算的时候,我们加载 T n × ( T r + K − 1 ) × ( T c + K − 1 ) T_n\times (T_r+K-1)\times (T_c+K-1) Tn​×(Tr​+K−1)×(Tc​+K−1)大小的输入特征图块, T m × T n × K × K T_m\times T_n \times K \times K Tm​×Tn​×K×K大小的权重,然后进行卷积计算,得到 T m × T r × T c T_m\times T_r\times T_c Tm​×Tr​×Tc​大小的输出特征块(部分和或者最终结果),本次计算完成后,我们再读取下一块输入特征和权重,再进行计算。如下图所示(下图中load output feature maps可以省去,部分和一直存储在片上即可) 在这里插入图片描述

计算部分

计算部分就是一个标准的3x3卷积,而卷积运算的并行度共有4个维度,分别是 1.输入通道并行。即同时计算多个输入通道的特征图和权重的卷积。 2.输出通道并行。即同时计算多个输出特征图的结果或部分和。 3.卷积窗口内并行。即卷积窗口内 K × K K\times K K×K个神经元和权重之间乘法的并行。 4.输出像素之间的并行。即同时计算输出特征图上多个神经元。 其中后两者的实现较为不易,例如3需要使用行缓冲,4的设计则更加复杂,因此,在本加速器的设计中,我们采用1,2这两种并行方式。假设并行度为 T n , T m T_n,T_m Tn​,Tm​,则有 在这里插入图片描述 不难想象,其硬件架构应该是一个并行乘法单元+一个加法树,如下图所示 在这里插入图片描述

总结

上面已经分别讲了计算部分和访存部分的设计方式,因此可以得到整个加速过程,用伪代码表示,即

for(r=0;rbackbone->load_weight(dir);
        //conv_forP5
        this->conv_forP5_conv->load_weight(dir+"\\conv_forP5");
        //yolo_headP4
        read_params(dir+"\\yolo_headP4\\w1.bin",this->yolo_headP4_basic_conv1->weight,256*384*3*3);
        read_params(dir+"\\yolo_headP4\\b1.bin",this->yolo_headP4_basic_conv1->bias,256);
        read_params(dir+"\\yolo_headP4\\w2.bin",this->yolo_headP4_w2,75*256*1*1);
        read_params(dir+"\\yolo_headP4\\b2.bin",this->yolo_headP4_b2,75);
        //yolo_headP5
        read_params(dir+"\\yolo_headP5\\w1.bin",this->yolo_headP5_basic_conv1->weight,512*256*9);
        read_params(dir+"\\yolo_headP5\\b1.bin",this->yolo_headP5_basic_conv1->bias,512);
        read_params(dir+"\\yolo_headP5\\w2.bin",this->yolo_headP5_w2,75*512*1*1);
        read_params(dir+"\\yolo_headP5\\b2.bin",this->yolo_headP5_b2,75);
        //upsample
        this->upsample_conv->load_weight(dir+"\\upsample");
    }
    //
    void forward(data_t* in,data_t* out0,data_t* out1){
    	static data_t feat1[256*26*26];
		static data_t feat2[512*13*13];
		static data_t P5[256*13*13];
		static data_t out0_tmp[512*13*13];
		static data_t P5_Upsample[128*13*13];
		static data_t P4[384*26*26];
		static data_t out1_tmp[256*26*26];
        //compute
        this->backbone->forward(in,P4+128*26*26,feat2);                 //相当于concat,P4=concat(Upsample_out,feat1)
        //coutforward(feat2,P5);
        //out0
        this->yolo_headP5_basic_conv1->forward(P5,out0_tmp);
        conv_leakyrelu(512,75,0,1,1,13,13,out0_tmp,this->yolo_headP5_w2,this->yolo_headP5_b2,out0,0);
        //upsample_conv
        this->upsample_conv->forward(P5,P5_Upsample);
        //upsample
        sampling(P5_Upsample,P4,128,13,0);
        //out1
        this->yolo_headP4_basic_conv1->forward(P4,out1_tmp);
        conv_leakyrelu(256,75,0,1,1,26,26,out1_tmp,this->yolo_headP4_w2,this->yolo_headP4_b2,out1,0);
    }
};
模型训练及导出

由于算力的限制,模型并没有训练,而是直接使用训练好的权重(数据集为VOC),详细可参见链接 在送入加速器之前,我们进行了卷积-BN融合操作,从而节省了一部分的计算量,经过编写的python脚本融合后的权重按如下形式存储 在这里插入图片描述

结果展示

展示:本工程只加速了yolo4 tiny网络本身,并将yolo4 tiny网络的输出存储在SD卡上,后续的解码以及可视化则是在PC上完成的,下图是结果展示,可以看到,虽然进行了16bit定点数量化,但对最终目标检测的结果并无很大影响。 在这里插入图片描述 模型的性能: 模型部署在zynq7020(xc7z020clg400-2)开发板上,单张图片的推理时间为383ms

附录

整个工程文件夹结构如下 在这里插入图片描述 包含HLS源码(hls)、CPU端源码(sdk)、已经处理好的权重(folded_weights)以及解码、可视化工具(tools),令附有一个演示视频,且可更换为自己的数据集。

关注
打赏
1658642721
查看更多评论
立即登录/注册

微信扫码登录

0.0385s