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

时间:2022-09-10 22:10:20

背景:最近在写一个基于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/ 

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

在执行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].

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

程序验证:

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

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

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

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

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

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

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

现在我们来分析上面每一个值数量的来由: 首先分析,结果为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 detected Process finished with exit code 0

卷积转换为矩阵运算中填充数的计算-GEMM的更多相关文章

  1. SEPC:使用3D卷积从FPN中提取尺度不变特征,涨点神器 | CVPR 2020

    论文提出PConv为对特征金字塔进行3D卷积,配合特定的iBN进行正则化,能够有效地融合尺度间的内在关系,另外,论文提出SEPC,使用可变形卷积来适应实际特征间对应的不规律性,保持尺度均衡.PConv ...

  2. --关于null在oracle数据库中是否参与计算,进行验证,

    --关于null在oracle数据库中是否参与计算,进行验证,with td as (select null id,1 name from dual ),td1 as ( select null id ...

  3. 数据库SQL语句中根据当前日期计算其他日期小结

    问题描述:我们在写存储过程和函数的时候经常会碰到利用当前日期计算出上周开始日期.结束日期,或者计算上个月的开始日期结束日期等问题.最近写了几个存储过程和函数,其中都涉及到了日期计算问题,在这里简单做一 ...

  4. 第16/24周 SQL Server 2014中的基数计算

    大家好,欢迎回到性能调优培训.上个星期我们讨论在SQL Server里基数计算过程里的一些问题.今天我们继续详细谈下,SQL Server 2014里引入的新基数计算. 新基数计算 SQL Serve ...

  5. 【组合数学+动态规划】在如下8*6的矩阵中,请计算从A移动到B一共有____种走法。要求每次只能向上或向右移动一格,并且不能经过P。

    在如下8*6的矩阵中,请计算从A移动到B一共有__种走法.要求每次只能向上或向右移动一格,并且不能经过P. A:456 B:492 C:568 D:626 E:680 F:702 解析: 8*6的矩阵 ...

  6. openstack中彻底删除计算节点的操作记录

    在使用openstack的过程中,我们经常会添加好几台计算节点来部署虚拟机,在后续使用中由于某些原因,一些计算节点出现了问题,需要将这些出了问题的计算节点从openstack的控制节点中踢出去!但是很 ...

  7. GLSL 中的光照计算

    理论知识转载地址:http://blog.csdn.net/ym19860303/article/details/25545933 1.Lambert模型(漫反射) 环境光: Iambdiff = K ...

  8. Carmack在QUAKE3中使用的计算平方根的函数

    // // Carmack在QUAKE3中使用的计算平方根的函数 // float CarmSqrt(float x){ union{ int intPart; float floatPart; } ...

  9. Windows文件路径转换为java中可识别的文件路径的转义方法,(另附转义多种格式)

    ps:欢迎加qq好友:2318645572,交流学习 一:路径转化 Windows中的文件路径格式为 D:\eclipse\apache-tomcat-7.0.67\wtpwebapps\... Ja ...

随机推荐

  1. 【ZeroClipboard is not defined】的解决方法

    参考:http://www.cnblogs.com/jfw10973/p/3921899.html https://github.com/zeroclipboard/zeroclipboard 近期该 ...

  2. TortoiseHg简单的入门使用说明

    参考资料: 互普的 TortoiseHg使用说明_百度文库 Mercurial(Hg)基本操作 - Tim Gong - 博客园 Mercurial与TortoiseHg使用入门教程(转) - mee ...

  3. VS2012报表(RDLC)系列应用之单据批量打印

    一.前言 最近做的项目需要单据批量打印的功能,优先想到用RDLC来实现.经过Visual Studio几个版本的发展后,RDLC愈发成熟,操作方式也变得简洁,相比vs2005的版本,有质的提升,不过仍 ...

  4. javascrip笔记——图片加载

    var t_img; // 定时器 var isLoad = true; // 控制变量 // 判断图片加载状况,加载完成后回调 isImgLoad(function(){ // 加载完成 }); / ...

  5. uva 1510 - Neon Sign(计数)

    题目链接:uva 1510 - Neon Sign 题目大意:给定n个点,随意三点不共线,而且两两点之间有一条线,给定线的颜色.问说有多少个三角形三边同色. 解题思路:对于每一个点.记录该点黑色边的数 ...

  6. 内网port映射具体解释(花生壳)

    关于怎样建立服务器的解答. 一.花生壳的作用 首先,我们先来了解一下花生壳的究竟有什么作用.由于ADSL每次拨号上网所获得的IP地址每次都是不同的,花生壳起到的作用就是方便用户訪问我们的server( ...

  7. [翻译] 编写高性能 .NET 代码--第二章 GC -- 减少大对象堆的碎片,在某些情况下强制执行完整GC,按需压缩大对象堆,在GC前收到消息通知,使用弱引用缓存对象

    减少大对象堆的碎片 如果不能完全避免大对象堆的分配,则要尽量避免碎片化. 对于LOH不小心就会有无限增长,但LOH使用的空闲列表机制可以减轻增长的影响.利用这个空闲列表,我们可以在两块分配区域中间找到 ...

  8. Codeforces 915F Imbalance Value of a Tree

    Imbalance Value of a Tree 感觉这种题没啥营养, 排个序算算贡献就好啦. #include<bits/stdc++.h> #define LL long long ...

  9. python:turtle绘图模块

    turtle模块 海龟绘图(Turtle Graphics),python内置模块,非常简单好玩的一个库. 一.导入库 import turtle from turtle import * 二.画布的 ...

  10. dwr框架介绍

    转: [DWR框架]过时了吗? 置顶 2018年06月02日 11:59:02 许你笑颜 阅读数:4129   版权声明: https://blog.csdn.net/smileyan9/articl ...