当前位置: 首页 > 编程日记 > 正文

基于GEMM实现的CNN底层算法被改?Google提出全新间接卷积算法

640?wx_fmt=jpeg


作者 | Marat Dukhan from Google Research

译者 | 凯隐

责编 | Jane

出品 | AI科技大本营(ID: rgznai100)

 

【导读】本文介绍的内容主要聚焦Google 的一项最新工作:改变基于 GEMM 实现的 CNN底层算法提出的新方法。通用矩阵乘法(General Matrix Multiply, GEMM)是广泛用于线性代数、机器学习、统计学等各个领域的常见底层算法,其实现了基本的矩阵与矩阵相乘的功能,因此算法效率直接决定了所有上层模型性能,目前主流的卷积算法都是基于GEMM来实现的。来自谷歌的Peter Vajda在ECV2019中提出了一种全新的间接卷积算法,用于改进GEMM在实现卷积操作时存在的一些缺点,进而提升计算效率。

 

通用矩阵乘法

 

GEMM是基础线性代数子程序库(Basic Linear Algebra Subprograms, BLAS)中的一个函数。BLAS提供了实现矩阵和向量基本运算的函数,最早于1979年由C.L.LAWSON提出。BLAS的发展大致可以分为三个阶段(levels)的历程,这和函数定义,出版顺序,以及算法中多项式的阶数以及复杂性有关,第一阶段只包含与向量(vector)有关的运算,第二阶段添加了向量与矩阵进行运算的操作,第三阶段添加了矩阵与矩阵之间的运算,前两个阶段的BLAS都是用于向量处理器的,而第三阶段适用于矩阵处理器,所以BLAS的发展和硬件的发展密不可分。GEMM属于第三阶段的算法,正式公布于1990年,其迭代更新形式为:

 

640?wx_fmt=png

 

其中A和B可以进行转置或hermitian共轭转置,而A、B和C都可以被忽略(be strided),因此实际上这个公式就表示了任意矩阵之间所有可能的加法和乘法组合,例如最基本的A*B,可以将α置1,C置为全0矩阵即可,这也是其通用性的表现。

 

由于矩阵乘法相对于向量-向量乘法以及向量-矩阵乘法,有更低的时间复杂度,效率更高,因此其广泛用于许多科学任务中,与之相关的GEMM算法成为了目前BLAS设计者的主要优化对象。例如可以将A和B分解为分块矩阵,使得GEMM可以递归实现。有关GEMM的详细信息可以参见[1][2][3]。如何对GEMM进行优化,是BLAS相关工作的研究热点。

 

基于 GEMM 的卷积算法及其缺点

 

卷积神经网络(CNN)在CV问题中的表现很出色,有多种在算法层面对齐进行实现的方法:直接卷积算法,采用7层循环,快速卷积算法,利用傅里叶变换来进行卷积,以及基于GEMM的卷积算法。


通过将卷积操作用矩阵乘法来代替,进而使用GEMM算法来间接进行卷积操作,这使得卷积操作可以在任何包含GEMM的平台上进行,并且受益于矩阵乘法的高效性,任何针对GEMM的改进和研究都能有助于卷积运算效率的提升,从而提高模型的运算速度,因此目前大部分主流的神经网络框架,例如Tensorflow、Pytorch和Caffe都使用基于GEMM的方法来在底层代码中实现卷积。


具体的,基于GEMM的卷积方法需要借助于 im2col或im2row buffer来内存转换,使得数据格式满足GEMM算法的输入要求,从而将卷积操作转化为GEMM操作,然而这个转换过程是一个计算开销和内存开销都比较大的过程,特别是在输入channel数较小时,这个过程会在整个卷积过程中占有很大的比例。简言之,就是在卷积过程中,每个pixel都会被多次重复的转换,这是不必要的计算开销。因此有许多工作都在对这一过程进行改进,本文工作提出了一种改进算法——间接卷积算法(Indirect Convolution algorithm),主要有以下两个优点:

 

1、去掉了im2row的转换过程,这使得算法性能有了巨大的提升(up to 62%)。


2、用了一个更小的indirection buffer来代替原来的im2row buffer。不同于im2row buffer的大小随着输入channel数线性增加,indirection buffer没有这个特性,因此indirection buffer的内存占用特性非常有利于输入channel数较多时的卷积操作。

 

间接卷积算法

 

原始的GEMM通过如下计算来不断迭代进行矩阵运算操作并输出矩阵:

 

640?wx_fmt=png

 

其中A是输入张量,B是一个常量滤波器,C是输出矩阵,在传统的im2col+GEMM算法中,通常α=1而β=0,原始GEMM操作示意图如下:

 

640?wx_fmt=png

图1 原始GEMM操作

 

其中 im2col buffer 代表矩阵A,filter tensor 代表矩阵B,A和B的乘积就是输出copy表示将输入的张量展开为一个二维矩阵,也就是im2col buffer。可以看到buffer的每一行则是由固定个数(步长)的pixel展开成一维的向量组成的,这些pixel都在原始tensor中的一个patch内,在经过和filter tensor相乘后,由于矩阵行列相乘得到一个元素,因此这几个pixel的信息都被整合成了一个值,也就是对他们进行了卷积操作。最后在输出矩阵C中,行数rows代表输出的像素点个数,columns代表输出的channel数。可以看到buffer的columns是和输入channel数有关的。


为了降低buffer带来的开销,作者提出了一种间接矩阵乘法的思想,不把输入的tensor直接展开并存储在buffer中,而只是在buffer中存放每个pixel在input tensor的坐标,也就是从存数据变成了存地址(类似于指针pointer思想),这样不管channel数有多少,存的地址信息始终只有二维,极大的降低了buffer的计算和存储开销,如下图:

 

640?wx_fmt=png

图2 indirect convolution

 

当然,由于buffer中存的是地址信息,因此不能直接和filter做矩阵乘法,所以就只能通过在buffer的行间进行循环,根据该行的pointer找到对应的输入数据,再将输入数据与kernel相乘,并与之前循环的结果拼接起来,从而间接的实现矩阵乘法,因此叫做indirection buffer。


对于不同的卷积步长,只需要将不同步长对应的卷积patch位置确定即可。而对于padding策略,将指向填充位置的pointer对应的输入pixel的向量值全部设置为0。

 

间接卷积算法的缺点



间接卷积算法作为GEMM-BASED CNN算法的一种改进,能极大的提升计算效率,但是存在以下几个限制:

 

1. 这个算法是为NHWC layout设计的,也就是说应用范围比较窄,不能和目前的主流方法相比。

2. 算法适用于前向传播中的卷积操作,而在反向传播中作用不大,不及基于col2im和row2im的算法。

3. 具有和GEMM相同的缺点,在深度小卷积核的卷积操作中效率并不好。

 

实验测试结果


Efficient Deep Learning for Computer Vision主要聚焦于如何将深度学习部署到移动设备上,因此本文的工作主要在移动设备和移动芯片上进行测试,结果如下:

 

640?wx_fmt=png

 

可以看到一旦步长增加,那么Indirect convolution带来的性能提升就会明显下降,这是因为步长越大,在原始的GEMM算法中重复计算的量就会减小,因此原始GEMM的性能本身就会提升,而indirect convolution并不受益于步长增加。

 

延伸介绍:Efficient Deep Learning for Computer Vision Workshop

目前CV方向主流的研究都着重于如何提升算法和模型性能,并不是太注重模型速度,运算时间,内存消耗等与运算资源有关的性能指标,这不利于将模型部署在类似于移动设备等计算资源有限的平台上。CVPR的这个workshop主要关注评估模型的计算开销和存储开销有关的指标,以及如何将其应用到移动设备上,相关团队隶属于谷歌研究院,详见[4]。

 

参考资料: 

[1] https://spatial-lang.org/gemm 

[2] https://en.wikipedia.org/wiki/Vector_processor 

[3] https://petewarden.com/2015/04/20/why-gemm-is-at-the-heart-of-deep-learning/ 

[4] https://sites.google.com/view/ecv2019/home   


原文链接: 

https://arxiv.org/abs/1907.02129


(*本文为 AI科技大本营编译文章,转载请联系1092722531


精彩推荐


“只讲技术,拒绝空谈”2019 AI开发者大会将于9月6日-7日在北京举行,这一届AI开发者大会有哪些亮点?一线公司的大牛们都在关注什么?AI行业的风向是什么?2019 AI开发者大会,倾听大牛分享,聚焦技术实践,和万千开发者共成长。


目前,大会盲订票限量发售中~扫码购票,领先一步!

                       

640?wx_fmt=jpeg

推荐阅读

  • 码农们的「血与泪」:新零售「全渠道中台」的前世今身

  • 腾讯拥抱开源:首次公布开源路线图,技术研发向共享、复用和开源迈进

  • 混合云发展之路:前景广阔,巨头混战

  • 干货 | Python后台开发的高并发场景优化解决方案

  • 5G 浪潮来袭!程序员在风口中有何机遇?

  • 这次又坑多少人? 深度解析 Dash 钱包"关键"漏洞!

  • 壕!两万多名腾讯员工获 51 万港元股票奖励


640?wx_fmt=png你点的每个“在看”,我都认真当成了喜欢

相关文章:

共享内存跨进程通信

通过共享内存通信是最快的,不过既然是共享资源,那么就必须要有同步机制。 创建共享内存有两种方式shm和mmap的方式。 mmap是在磁盘上建立一个文件,每个进程地址空间中开辟出一块空间进行映射。而对于shm而言,shm每个进程最终会映射…

扶稳!四大步“上手”超参数调优教程,就等你出马了 | 附完整代码

作者 | Matthew Stewart译者 | Monanfei责编 | Jane出品 | AI科技大本营(ID: rgznai100)【导读】在本文中,我们将为大家介绍如何对神经网络的超参数进行优化调整,以便在 Beale 函数上获得更高性能,Beale 函数是评价优化…

读好书,写好程序

本人是做.NET开发的,以企业应用为主,以互联网为爱好,这里给大家推荐一些适合.NET程序员的书: 软件设计《企业应用架构模式》 Martin Fowler 的大作之一,总结了多种常见的企业应用架构模式,这些模式是脱离具…

SIFT特征点匹配中KD-tree与Ransac算法的使用

转自:http://blog.csdn.net/ijuliet/article/details/4471311 Step1:BBF算法,在KD-tree上找KNN。第一步做匹配咯~ 1.什么是KD-tree(fromwiki) K-Dimension tree,实际上是一棵平衡二叉树。 一般的KD-tree构造过程&a…

jQuery带缩略图的宽屏焦点图插件

在线演示 本地下载

追溯XLNet的前世今生:从Transformer到XLNet

作者丨李格映来源 | 转载自CSDN博客导读:2019 年 6 月,CMU 与谷歌大脑提出全新 XLNet,基于 BERT 的优缺点,XLNet 提出一种泛化自回归预训练方法,在 20 个任务上超过了 BERT 的表现,并在 18 个任务上取得了当…

微软MCITP系列课程

http://liushuo890.blog.51cto.com/5167996/d-1转载于:https://blog.51cto.com/showcart/1156172

在Ubuntu11.10中安装配置OpenCV2.3.1和CodeBlocks

1、 打开终端; 2、 执行指令,删除ffmpeg and x264旧版本:sudo apt-get removeffmpeg x264 libx264-dev 3、下载安装x264和ffmpeg所有的依赖:sudo apt-get update sudo apt-get installbuild-essential checkinstall git cmake…

深入浅出Rust Future - Part 1

本文译自Rust futures: an uneducated, short and hopefully not boring tutorial - Part 1,时间:2018-12-02,译者:motecshine, 简介:motecshine 欢迎向Rust中文社区投稿,投稿地址,好文将在以下地方直接展示 Rust中文社区首页Rust…

cmd 修改文件属性

现在的病毒基本都会采用一种方式,就是将病毒文件的属性设置为系统隐藏属性以逃避一般用户的眼睛,而且由于Windows系统的关系,这类文件在图形界面下是不能修改其属性的。但是好在Windows还算做点好事,留下了一个attrib命令可以让我…

Django 视图

Django之视图 目录 一个简单的视图CBV和FBV FBV版:CBV版:给视图加装饰器 使用装饰器装饰FBV使用装饰器装饰CBVrequest对象 请求相关的常用值属性方法Response对象 使用属性JsonResponse对象Django shortcut functions render()redirect()Django的View&am…

喜大普奔!GitHub官方文档推出中文版

原创整理 | Python开发者(ID:PythonCoder)最近程序员交友圈出了一个大新闻,GitHub 帮助文档正式推出中文版了,之前一直都是只有英文文档,看起来费劲不方便。这份中文文当非常详尽,可以说有了它 …

Linux中获取当前程序路径的方法

1、命令行实现:转自:http://www.linuxdiyf.com/viewarticle.php?id84177 #!/bin/sh cur_dir$(pwd) echo $cur_dir 注意:在cur_dir后没空格,后面也不能有空格,不然它会认为空格不是路径而报错 2、程序实现&#xf…

android 关于字符转化问题

今日在写android的客户端,发现字符转化是个大问题。 下面是Unicode转UTF-8的转化,便于以后使用 private static String decodeUnicode(String theString) { char aChar; int len theString.length(); StringBuffer outBuffer new Strin…

30分钟看懂XGBoost的基本原理

作者 | 梁云1991转载自Python与算法之美(ID: Python_Ai_Road)一、XGBoost和GBDTxgboost是一种集成学习算法,属于3类常用的集成方法(bagging,boosting,stacking)中的boosting算法类别。它是一个加法模型,基模型一般选择树模型&…

Linux下遍历文件夹的实现

转自&#xff1a;http://blog.csdn.net/wallwind/article/details/7528474 linux C 遍历目录及其子目录 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <dirent.h> #include <sys/stat.h> #include <unistd.h&…

如何用Python画一棵漂亮的树

Tree海龟绘图turtle 在1966年&#xff0c;Seymour Papert和Wally Feurzig发明了一种专门给儿童学习编程的语言——LOGO语言&#xff0c;它的特色就是通过编程指挥一个小海龟&#xff08;turtle&#xff09;在屏幕上绘图。 海龟绘图&#xff08;Turtle Graphics&#xff09;后来…

windows7下,Java中利用JNI调用c++生成的动态库的使用步骤

1、从http://www.oracle.com/technetwork/java/javase/downloads/jdk-7u2-download-1377129.html下载jdk-7u2-windows-i586.exe&#xff0c;安装到D:\ProgramFiles\Java&#xff0c;并将D:\ProgramFiles\Java\jdk1.7.0_02\bin添加到环境变量中&#xff1b; 2、从http://www.ec…

外观模式 - 设计模式学习

外观模式(Facade)&#xff0c;为子系统中的一组接口提供一个一致的界面&#xff0c;此模式定义了一个高层接口&#xff0c;这个接口使得这一子系统更加容易使用。 怎么叫更加容易使用呢&#xff1f;多个方法变成一个方法&#xff0c;在外观看来&#xff0c;只需知道这个功能完成…

Google最新论文:大规模深度推荐模型的特征嵌入问题有解了!

转载自深度传送门&#xff08;ID: gh_5faae7b50fc5&#xff09;导读&#xff1a;本文主要介绍下Google在大规模深度推荐模型上关于特征嵌入的最新论文。 一、背景大部分的深度学习模型主要包含如下的两大模块&#xff1a;输入模块以及表示学习模块。自从NAS[1]的出现以来&#…

[20181204]低版本toad 9.6直连与ora-12505.txt

[20181204]低版本toad 9.6直连与ora-12505.txt--//我们生产系统还保留有一台使用AMERICAN_AMERICA.US7ASCII字符集的数据库,这样由于toad新版本不支持该字符集的中文显示.--//我一直保留toad 9.6的版本,并且这个版本是32位的,我必须在我的机器另外安装10g 32位版本的客户端,这样…

Google揭露美国政府通过NSL索要用户资料

当美国联邦调查局FB或其他美国执法机构进行有关国家安全的调查时&#xff0c;能通过一种“国家安全密函National Security &#xff0c;NSL)”向服务商索取其用户的个人资料&#xff0c;由于事关国家安全&#xff0c;因此该密函并不需经法院同意。但根据美国电子通讯隐私法的规…

Ubuntu下,Java中利用JNI调用codeblocks c++生成的动态库的使用步骤

1、 打开新立得包管理器&#xff0c;搜索JDK&#xff0c;选择openjdk-6-jdk安装&#xff1b; 2、 打开Ubuntu软件中心&#xff0c;搜索Eclipse&#xff0c;选择Eclipse集成开发环境&#xff0c;安装&#xff1b; 3、 打开Eclipse&#xff0c;File-->New-->Java Proj…

比Hadoop快至少10倍的物联网大数据平台,我把它开源了

作者 | 陶建辉转载自爱倒腾的程序员&#xff08;ID: taosdata&#xff09;导读&#xff1a;7月12日&#xff0c;涛思数据的TDengine物联网大数据平台宣布正式开源。涛思数据希望尽最大努力打造开发者社区&#xff0c;维护这个开源的商业模式&#xff0c;他们相信不将最核心的代…

Script:挖掘AWR实现查询SCN历史增长走势

AWR中记录了快照时间内calls to kcmgas的统计值&#xff0c;calls to kcmgas的意义在于通过递归调用获得一个新的SCN&#xff0c;该统计值可以看做SCN增长速度的主要依据&#xff0c;通过挖掘AWR可以了解SCN的增长走势&#xff0c;对于我们诊断SCN HEADROOM问题有所帮助&#x…

运动目标检测__光流法

以下内容摘自一篇硕士论文《视频序列中运动目标检测与跟踪算法的研究》&#xff1a; 1950年Gibson首先提出了光流的概念&#xff0c;光流(optical flow)法是空间运动物体在观测成像面上的像素运动的瞬时速度。物体在运动的时候&#xff0c;它在图像上对应点的亮度模式也在做相…

读完这45篇论文,“没人比我更懂AI了”

作者 | 黄海广 转载自机器学习爱好者&#xff08;ID:ai-start-com&#xff09; 导读&#xff1a;AI领域的发展会是IT中最快的。我们所看到的那些黑科技&#xff0c;其后无不堆积了大量论文&#xff0c;而且都是最新、最前沿的论文。从某种角度来讲&#xff0c;它们所用的技术跟…

深入理解JVM——虚拟机GC

对象是否存活 Java的GC基于可达性分析算法(Python用引用计数法)&#xff0c;通过可达性分析来判定对象是否存活。这个算法的基本思想是通过一系列"GC Roots"的对象作为起始点&#xff0c;从这些节点开始向下搜索&#xff0c;搜索所走过的路径称为引用链&#xff0c;当…

​2019年最新华为、BAT、美团、头条、滴滴面试题目及答案汇总

作者 | 苏克1900来源 | 高级农民工&#xff08;ID&#xff1a;Mocun6&#xff09;【导语】最近 GitHub 上一个库火了&#xff0c;总结了 阿里、腾讯、百度、美团、头条等国内主流大厂的技术面试题目&#xff0c;目前 Star 2000&#xff0c;还在持续更新中&#xff0c;预计会火下…