背景:最近在写一个基于opencl的正向神经网络框架,项目地址 https://github.com/aktiger/YoloOCLInference ,我从这里https://github.com/pengdada/YoloOCLInference fork了一个基本的脚手架,但是原始的项目只支持windows的版本,首先把它移植到linux下,由于需要支持resnet18,还缺少7*7的卷积,需要自己搞一个,在搞之前,先对3*3的卷积计算进行了梳理,后面7*7的也就顺理成章。基于opencl做的目的也是为了能够上嵌入式设备,不想一直生活在服务器的世界里,所以该造的轮子还是要自己造。

虽然学术圈还是工业界都在说卷积神经网络,但是到了底层要么是转换为矩阵的运算,要么是转换为频域上的计算。要将卷积操作转换为矩阵乘积的第一步是要做img2col操作,如下图,想详细了解看这里:https://petewarden.com/2015/04/20/why-gemm-is-at-the-heart-of-deep-learning/

在执行convertImageTocolumn操作的时候,传入的原始图片Img的大小为3*416*416,填充数为1,stride为1,如果填充的块都为1, 那么将Img变成column形式后,里面会有多少个零呢?答案是14964个,这是程序给出的结果,那么这个是怎么来的呢?首先将14964做质数分解:14963=43*3*2*2*29 ,这里我们发现有3,那么这个3可以看做是三个通道,这样就只需要看14963=3*4988, 一个通道上有4988个零是怎么来的。如下图所示,如果通道大小是3*3,卷积核大小是3*3,填充为1,步长(stride)为1,那么填充后的大小为5*5,现在要用3*3的卷积在其上进行块转换,我们知道转换成块后的大小将是原来大小的9倍。我们来计算5*5的通道上进行块转换后,里面具有0的数量,首先4个角上,每个角上获得的填充数为5,共20个,每一条边上获得的填充数量为3,共4条边,共12个填充,总共为1*3*4+20 = 32个。 以此类推,如果单个通道的大小变为416*416,卷积核依然为3*3,那么每条边上获得的填充数量为(416-3+1)*3 *4+ 4*5 = 4988个,如果通道数量为3,那么就为3*4988=14964。 由此可以得到如下的计算公式:

假设,通道数为C,通道高度为H,通道宽度为W,卷积核大小为K,填充为1,步长为1,假设H=W,那么获得填充数量为:3*[(W-K+1)*3*4 + 5*4].

程序验证:

将卷积核、所有输入通道出了填充之外的值都全部设置成1,填充的值设置为0,对3*416*416的输入,利用GEMM进行卷积计算,卷积核大小为3*3,步长和

填充都为1,输出通道数量为16,计算完后,得到不同值的分布如下,结果为12的数量为64,值为18的数量为26496,值为27的为2742336。 可以知道,输出

元素的个数为:16*416*416,即有16个通道,每一个通道的大小为416*416。

现在我们来分析上面每一个值数量的来由: 首先分析,结果为12的数量64,由于有16个输出通道,那么相当于每一个输出通道有4个12的值,这正好对应于在每个输入通道的4个角上卷积后的结果,因为四个角上,有5个值是被填充的,还剩下4个数为1,乘以输入通道数3,得到的数值正好为12。 然后分析值为18的数量26496,同样道理,由于输出通道有16,相当于每一个输出通道上有26496/16=1656个值为18的数。对应于每一个输入通道边上的卷积(不包括4个角)的数量为(416-3+1)*4=1656,而每一个这样的卷积中,有3个数是被填充的,3个通道就是有9个数是被填充的,本来是27个1,但是这里有9个1被填充为0,所以最后的数值就位18。最后分析值为27的数量:2742336,同样,由于有16个输出通道,那么每一个通道27的数量为2742336/16=171396个,在输入通道上除了边上和和4个角上的卷积(内部卷积,每个位置都是1)的数量为414*414,正好等于171396个。

可以用这个在线质数分解器:http://www.atool.org/quality_factor.php

计算im2col输出元素个数的公式为: in_ch * k_size * k_size * out_w * out * out_h

其中:

in_ch:  输入通道大小

k_size:  卷积核大小

out_w: 在输入图片上做卷积后,输出通道的宽,计算公式为:out_w = (in_w + 2*pad  - k_size )/stride + 1

out_h: 在输入图片上做卷积后,输出通道的高, 计算公式为: out_h = (in_h + 2*pad –k_size )/stride + 1

下面是运行3*3卷积和7*7卷积的日志:

/home/ubuntu/zhangchao/cvs/YoloOCLInference/cmake-build-debug/test/test
Running 2 test cases...
CL_COMPUTE DEVICES: 2
CL_DEVICE_ID: 0x2594750
CL_DEVICE_NAME:: Tesla K40m
CL_DEVICE_VENDOR:: NVIDIA Corporation
CL_DRIVER_VERSION:: 375.26
CL_DEVICE_VERSION:: OpenCL 1.2 CUDA
CL_DEVICE_OPENCL_C_VERSION:: OpenCL C 1.2
CL_DEVICE_TYPE::CL_DEVICE_TYPE_GPU
CL_DEVICE_MAX_COMPUTE_UNITS: 15
clCreateProgramWithSource success
clGetProgramBuildInfo() success
buildProgram kernels success
Kernel No: 1, name - image2columarray3x3
buildProgram kernels success
Kernel No: 2, name - image2columarray1x1
buildProgram kernels success
Kernel No: 3, name - resetarray
buildProgram kernels success
Kernel No: 4, name - normalizearray
buildProgram kernels success
Kernel No: 5, name - scalebias
buildProgram kernels success
Kernel No: 6, name - addbias
buildProgram kernels success
Kernel No: 7, name - scaleaddbias
buildProgram kernels success
Kernel No: 8, name - normscaleaddbias
buildProgram kernels success
Kernel No: 9, name - leakyactivatearray
buildProgram kernels success
Kernel No: 10, name - linearactivatearray
buildProgram kernels success
Kernel No: 11, name - flattenarray
buildProgram kernels success
Kernel No: 12, name - softmax
buildProgram kernels success
Kernel No: 13, name - maxpool
buildProgram kernels success
Kernel No: 14, name - image2columarray7x7
Number of kernel Arguments : 11 image2columarray3x3
Number of kernel Arguments : 11 image2columarray1x1
Number of kernel Arguments : 7 normalizearray
Number of kernel Arguments : 4 scalebias
Number of kernel Arguments : 4 addbias
Number of kernel Arguments : 5 scaleaddbias
Number of kernel Arguments : 7 normscaleaddbias
Number of kernel Arguments : 4 leakyactivatearray
Number of kernel Arguments : 4 linearactivatearray
Number of kernel Arguments : 6 flattenarray
Number of kernel Arguments : 7 softmax
Number of kernel Arguments : 9 maxpool
Number of kernel Arguments : 3 resetarray
Number of kernel Arguments : 11 image2columarray7x7
In bufImg_before7x7.bin. Total count is : 519168;   Zero count is :0. Percent is: 0
In bufImg9x_before7x7.bin. Total count is : 24952368;   Zero count is :0. Percent is: 0
In buf_out_before7x7.bin. Total count is : 2715904;   Zero count is :2715904. Percent is: 1
In weights_gpu7x7.bin. Total count is : 2352;   Zero count is :0. Percent is: 0
Total kernel time was {-42898.564} msecs - image2columarray7x7
CL_Status is not CL_SUCCESS
get_local_size(0):8, get_num_groups(0): 63655, get_global_id(0): 509239
In bufImg9x_after.bin. Total count is : 24952368;   Zero count is :34596. Percent is: 0.00138648
Total kernel time was { 0.00} msecs - ComputeGEMM()
In buf_out_after7x7.bin. Total count is : 2715904;   Zero count is :0. Percent is: 0
data_img zero count is: 0. data_img_count: 519168
data_in zero count is: 0
data_out zero count is: 2768896
kernel_weights zero count is: 0
CL_COMPUTE DEVICES: 2
CL_DEVICE_ID: 0x2594750
CL_DEVICE_NAME:: Tesla K40m
CL_DEVICE_VENDOR:: NVIDIA Corporation
CL_DRIVER_VERSION:: 375.26
CL_DEVICE_VERSION:: OpenCL 1.2 CUDA
CL_DEVICE_OPENCL_C_VERSION:: OpenCL C 1.2
CL_DEVICE_TYPE::CL_DEVICE_TYPE_GPU
CL_DEVICE_MAX_COMPUTE_UNITS: 15
clCreateProgramWithSource success
clGetProgramBuildInfo() success
buildProgram kernels success
Kernel No: 1, name - image2columarray3x3
buildProgram kernels success
Kernel No: 2, name - image2columarray1x1
buildProgram kernels success
Kernel No: 3, name - resetarray
buildProgram kernels success
Kernel No: 4, name - normalizearray
buildProgram kernels success
Kernel No: 5, name - scalebias
buildProgram kernels success
Kernel No: 6, name - addbias
buildProgram kernels success
Kernel No: 7, name - scaleaddbias
buildProgram kernels success
Kernel No: 8, name - normscaleaddbias
buildProgram kernels success
Kernel No: 9, name - leakyactivatearray
buildProgram kernels success
Kernel No: 10, name - linearactivatearray
buildProgram kernels success
Kernel No: 11, name - flattenarray
buildProgram kernels success
Kernel No: 12, name - softmax
buildProgram kernels success
Kernel No: 13, name - maxpool
buildProgram kernels success
Kernel No: 14, name - image2columarray7x7
Number of kernel Arguments : 11 image2columarray3x3
Number of kernel Arguments : 11 image2columarray1x1
Number of kernel Arguments : 7 normalizearray
Number of kernel Arguments : 4 scalebias
Number of kernel Arguments : 4 addbias
Number of kernel Arguments : 5 scaleaddbias
Number of kernel Arguments : 7 normscaleaddbias
Number of kernel Arguments : 4 leakyactivatearray
Number of kernel Arguments : 4 linearactivatearray
Number of kernel Arguments : 6 flattenarray
Number of kernel Arguments : 7 softmax
Number of kernel Arguments : 9 maxpool
Number of kernel Arguments : 3 resetarray
Number of kernel Arguments : 11 image2columarray7x7
In bufImg_before.bin. Total count is : 519168;   Zero count is :0. Percent is: 0
In bufImg9x_before.bin. Total count is : 4672512;   Zero count is :0. Percent is: 0
In databuf_out_before.bin. Total count is : 2768896;   Zero count is :2768896. Percent is: 1
In weights_gpu.bin. Total count is : 432;   Zero count is :0. Percent is: 0
Total kernel time was {-42882.983} msecs - image2columarray3x3
CL_Status is not CL_SUCCESS
get_local_size(0):8, get_num_groups(0): 64897, get_global_id(0): 519175
In bufImg9x_after.bin. Total count is : 4672512;   Zero count is :14964. Percent is: 0.00320256
Total kernel time was { 0.00} msecs - ComputeGEMM()
In databuf_out_after.bin. Total count is : 2768896;   Zero count is :0. Percent is: 0*** No errors detectedProcess finished with exit code 0

卷积转换为矩阵运算中填充数的计算-GEMM相关推荐

  1. 卷积计算过程中的减少计算量的优化方式

    大卷积转化为小卷积:根据VGG的思想,对于大的卷积核可以转换为多个相同卷积串联的方式来减少.具体如下: 由图可以看出一个5X5的卷积核可以换成两个3X3的卷积,此时参数的个数由25变成了18(2X3X ...

  2. 卷积在计算机中实现+pool作用+数据预处理目的+特征归一化+理解BN+感受野理解与计算+梯度回传+NMS/soft NMS

    一.卷积在计算机中实现 1.卷积 将其存入内存当中再操作(按照"行先序"): 这样就造成混乱. 故需要im2col操作,将特征图转换成庞大的矩阵来进行卷积计算,利用矩阵加速来实现, ...

  3. 名词解释 算法的有限性_欲借助 FFT 算法快速计算两有限长序列的线性卷积,则过程中要调用 ( ) 次 FFT 算法_学小易找答案...

    [单选题]计算 N=2 L ( L 为整数)点的按时间抽取基 -2FFT 需要 ( ) 级蝶形运算 [单选题]Les étudiants chinois, une fois arrivés en Fr ...

  4. 理解CNN卷积层与池化层计算

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 概述 深度学习中CNN网络是核心,对CNN网络来说卷积层与池化层的 ...

  5. Visformer: The Vision-friendly Transformer实现transformer和基于卷积的模型中的设计特性

    Visformer: The Vision-friendly Transformer 视觉友好型transformer 摘要 近年来,将transformer模块应用于视觉问题迅速发展.虽然一些研究人 ...

  6. 卷积神经网络的参数量和计算量

    <卷积神经网络的参数量和计算量>   对于在端部署的模型来说,模型的参数量以及计算量是锱铢必较的,使用什么样的激活函数,会有多大的计算成本.对于模型的压缩量化等都是模型的参数量和计算量的准 ...

  7. 使用Excel中的公式计算日期

    所有问题的计算,都基于以下原理: 在Excel中,日期是以序列号的形式存储的,而序列号的起始值是 1(所以,在Excel中可以进行1900年1月1日及其之后的日期计算),其代表的日期是1900年1月1 ...

  8. 硬件中的三角函数计算 Cordic算法入门

    三角函数的计算是个复杂的主题,有计算机之前,人们通常通过查找三角函数表来计算任意角度的三角函数的值.这种表格在人们刚刚产生三角函数的概念的时候就已经有了,它们通常是通过从已知值(比如sin(π/2)= ...

  9. 初识OFDM(八):OFDM中的PAPR计算和通频带仿真

    文章目录 初识OFDM(八):OFDM中的PAPR计算和通频带仿真 零.代码地址 一. OFDM信号CF的CCFD 1. 代码展示 2.代码分析 为什么ifft后×sqrt(Nfft)? σ\sigm ...

最新文章

  1. 使用示例_使用 COMSOL 软件模拟不规则形状并构建几何模型示例
  2. 【译】Immutable.js : 操作 Set -8
  3. 稳压电源的设计与制作_电子爱好设计的直流可调压电源电路,太完美了,有图,亲测可用...
  4. 上机演练 幸运抽奖活动
  5. GenerateResource”任务意外失败的解决方法
  6. atitit.userService 用户系统设计 v6 q413
  7. c++ 海战棋_编程入门须知:都说零基础不好学编程,那么什么是编程基础?
  8. 编程老司机带你玩转 CompletableFuture 异步编程
  9. 06 Python爬虫之Re(正则表达式)库
  10. 每日10行代码173:测试下yafu的质因数分解能力
  11. HS系列USB数据采集卡,及高速多通道数据分析软件详解
  12. markdown图片显示
  13. 声网发布极速直播、低码高清 首创轻互动直播,节省50%带宽成本
  14. java输出GPA,简单的C GPA计算器问题
  15. 微信小程序开发之——个人中心-介绍(1)
  16. 【联邦学习】联邦学习
  17. 8个巧用iOS备忘录的方法,别浪费了几千块的iPhone手机
  18. WordPress文章内容编辑,wp文章在线批量编辑,wp文章内容可视化编辑器
  19. 叽叽歪歪乱七八糟的标签——web(一)
  20. Linux无法初始化sftp协议,winscp:无法初始化SFTP协议。主机是SFTP服务器吗?

热门文章

  1. RTOS之uCOS-II源码下载及源码目录结构、常见的RTOS!
  2. linux 系统中 /etc/passwd 和 /etc/shadow文件详解
  3. 内存分配成功,但并未初始化
  4. CentOS7援救模式下更改密码
  5. OSS- OSS brower 登陆失败
  6. SaaS平台只是传统管理软件的试衣间
  7. 四层负载均衡——LVS
  8. Javascript OrderBy
  9. C++ 容易犯错误的模型
  10. 删除唯一性约束unique