ShuffleNet 系列(2): ShuffleNet v2 理论讲解
ShuffleNet V2 概述
论文:ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design
shuffleNet v2这篇论文比较硬核,提出了不少新的思想,推荐大家可以看看论文原文。主要思想包括:
模型的计算复杂度不能只看FLOPs,还需要参考一些其他的指标
作者提出了4条如何设计高效网络的准则
基于该准则提出了新的block设置
FLOPS网上有两种:FLOPS和 FLOPs
:
FLOPS
:全大写,指每秒浮点运算次数,可以理解为计算的速度,是衡量硬件性能的一个指标 (硬件)FLOPs
:s小写,指浮点运算数,理解为计算量,可以用来衡量算法/模型的复杂度,(模型)在论文中常用GFLOPs(1 GFLOPs = 10^9FLOPs)
ShuffleNet V2 论文观点
(1) FLOPS不能准确的评价模型的推力的时间,还有其他因素影响
在我们网络设计过程中,比如mobienet, shuffleNet v1
我们经常使用FLOPs
,FLOPs
其实是衡量模型运算和复杂度的间接指标
,它并不是一个直接的指标。因为我们在实际使用过程中,我们直接
看的是模型的推理时间来看运算快慢
,这是一个直接的指标。
- 在影响我们模型推理速度的众多因素之间,其实我们并不能光看
FLOPs
,还有其他需要被考虑进来的因素,比如说memory access cost (MAC)
(内存访问的时间成本),它占我们模型推理中占非常大的一个比率。
- 在上图中给的时间统计,前所说的
FLOPs
其实主要还是计算关于卷积相关的参数指标,但是在ShuffleNet V1 GPU
统计到,卷积操作
其实只占时间消耗的50%
,另外50%
是用来处理其他任务,因此我们不能单独使FLOPs来评判我们模型的计算量和它的复杂度
。 - 除了
内存访问时间成本MAC
,作者还提到另外一个需要被考虑进来的因素叫做degree of parallelism
(并行等级),在相同FLOPs下并行更高的模型,其实要比并行度低的模型速度快
,这进一步说明了我们不能光看FLOPS。 - 接下来作者提到,相同的
FLOPs
在不同的平台上(如GPU以及ARM平台上的CPU
),他们的执行时间也是不一样的。从上图可以看出,对于ShuffleNet v1
,在同样的FLOPS
下,GPU
上卷积运算占50%
,在ARM
上卷积运算占87%
,所以在不同的平台上它的执行消耗时间也都是不一样的。 - 通过上图,我们可以发现其实
卷积占据了模型推理的绝大部分时间
,其他的操作比如:Data I/O,data shuffle,element-wise
等等,他们也占据了相当大的一部分推理时间。因此我们的FLOPS并不能正确的评判模型的推理时间
。
如何设计高效网络的4条建议
作者提出了如何设计高效网络的4条建议:
G1:Equal channel width minimizes memory access cost (MAC)
当卷积层的输入特征矩阵与输出特征矩阵相等的时候,MAC
最小(保持FLOPs不变时
),这里针对1x1的卷积层
B=hwc1c2B=hwc_1c_2B=hwc1c2
其中MAC值是如何计算得到的呢?,作者给出如下计算过程:
- MAC=hw(c1+c2)+c1∗c2MAC=hw(c_1+c_2)+c_1*c_2MAC=hw(c1+c2)+c1∗c2, hwc1hwc_1hwc1代表输入特征矩阵的内存消耗,hwc2hwc_2hwc2代表输出特征矩阵的内存消耗。后面的c1∗c2c1*c2c1∗c2表示卷积核的内存消耗
- 根据算数不等式:c1+c22≥c1c2\frac{c_1+c_2}{2} ≥ \sqrt{c_1c_2}2c1+c2≥c1c2,带入
MAC
计算公式可得:MAC≥2hwc1c2+c1c2MAC ≥2hw\sqrt{c_1c_2}+c_1c_2MAC≥2hwc1c2+c1c2,并且根据B=hwc1c2B=hwc_1c_2B=hwc1c2,最终可得到MAC≥2hwB+BhwMAC ≥2\sqrt{hwB}+\frac{B}{hw}MAC≥2hwB+hwB ,不等式相当当c1=c2c_1=c_2c1=c2的时候,MAC最小
作者在FLOPs保持不变的情况下,探究了c1c2\frac{c_1}{c_2}c2c1 对我们推理速度的影响,这里看GPU x1 与CPU x1这块,后面几个都是一样的,我们只关注规律就可以。 - 当c1/c2=1:1的时候,我们在GPU上每秒能够推理1480个Batches;当c1/c2=1:2的时候每秒能够推理1296个Batches,可以看出随着c1,c2两者的比值相差越大,推理速度越慢,同样在CPU上也是一样的。
G2: Excessive group convolution incresses MAC
- 当
GConv
的groups
增大时(保持FLOPs不变时),MAC
也会增大
其中hwc1c2/ghwc_1c_2/ghwc1c2/g (FLOPs) ,由于当输入特征矩阵一定的时候hwc1hw_c1hwc1是个常数想,FLOPs一定的时候B也是一个常数项。因此随着g越来越大,MAC值也越大。
作者针对第二点,也做了一系列的实验。
通过保持FLOPs
一定的情况下,改变g的数值,以GPU x1
与CPU x1
为例进行说明,当g=1
的时候,每秒能推理2451
个batches
;当g=2,每秒能推理1725
个batches
;当g=8
,每秒能推理634
个batches;当g有1到8,它的推理速度下降到原来的1/4
还是非常明显的。但在cpu上我们发现它下降的连一半都不到
。
G3: Network fragmentation reduces degree of parallelism
网络设计的碎片化程度越高,速度越慢。这里所说的碎片化可以理解为网络的分支的程度,很多网络在设计的时候分支越来越多。
- 分支可以是串联,可以是并联,在googlenet inception模块,它就并行了有
3x3
的卷积层,5x5
的卷积层,还有池化层等等,他们就很喜欢采用多分支的结构来进行网络的搭建。论文当中提到虽然碎片化结构能提升我们的精确率,但是它会降低模型的效率。因为这种碎片化的结构,对于像GPU这种具有非常强的并行计算能力的设备是非常不友好的,并且在多分支的情况下,还有kernel的启动和同步的问题。
比如图e中,有4个并行的分支,对于每个卷积层都需要有kernel的启动,如果四个并行结构计算时间差不多的话,其实还好。如果相差很大的话,运算快的运算完之后就一直等着运算比较慢的,只有等到大家全部结束之后,我们才能进行下一步计算,所以这个效率是比较低的。
同样作者针对G3
也做了一系列实验。
其中上图(a),(b),©对应的与1-fragement
,2-fragement
,3-fragement
,他们是简单的串行,同样是保持FLOPs不变的情况下,我们的串行的层数越多,碎片化程度越高我们的推理速度也是越来越慢的。对于图d,图e,对应的是2-fragement
,4-fragement
,也同样是碎片化程度越高,推理速度越慢。但是在cpu上其实变化是不大的,GPU变化非常明显。
G4:Element-wise operations are non-negligible
Element-wise
操作带来的影响是不可忽视的。
Element-wise
包括哪些操作呢,论文中提到它包含有:激活函数比如Relu,比如AddTensor如ResNet网络中的捷径分支与主分支的输出进行Add操作,还有卷积过程中使用到AddBias
等等这一系列。对于每一个元素型操作的都叫Element-wise operation
,这些操作的特点都是它的FLOPs很小,但是他们的MAC很大
。作者也说了向我们depthwise convolution
也可以看做为element-wise operator
.
作者也做了一系列的实验。比如我们采用short-cut
链接和不采用short-cut
链接,很明显我们不采用short-cut
链接会更快。采用Relu和不采用Relu,肯定是不采用Relu会更快。
这里肯定会有人要说,不采用这些操作肯定会更快,这里作者想突出的,这些element-wise
操作,它比我们想象当中要更耗时
。作者提到如果把Relu
和short-cut
移除后再GPU或ARM CPU上能提升20%
.如果我们仅仅通过FLOPs
来进行对比的话,其实这些element-wise
操作基本上是不会占用多少运算时间的。但是在实际使用过程中,其实它还是很耗时的
。
论文对四点总结
- 要使用一个平衡的convolution,尽可能让输入特征矩阵channel与输出矩阵channel等于或接近1.
- 注意groups convolution的计算成本,不能一味的去增大groups数,但增大groups能降低参数以及FLOPs或许还能提高我们的Accuracy,但是它会增加我们的计算成本。
- 降低网络的碎片程度,如果你想要有一个非常高效的网络的话,不要涉及那么多分支结构
- 尽可能减少使用
element-wise operator
根据准则设计我们的ShuffleNet V2
其中图(a)和图(b)就是shuffleNet V1,其中a是我们DW卷积步距为1,b是DW卷积步距为2的时候。右边的图c和图d,就是我们shuffleNet V2中对应步距为1和2的block.
- 图e,对于每个Block单元,我们会对于输入的channels 进行split,划分为两个branches,一个是c′c^{'}c′,一个是c−c′c-c^{'}c−c′,根据G3我们要减少模型的碎片化程度,所以在左边的分支上是没有进行任何操作的。在另外一个分支上我们有3个卷积层
(1x1 GConv, 3X3 Dconv, 1x1 Conv)
他们拥有相同的输入和输出channel
,并且将GConv换回了普通卷积,这就是为了满足我们的G2就是尽快能降低GConv中分组g的数值。在卷积之后,两个分支是通过concat进行拼接的这就能够满足输入channel和输出channel是一样的,因为我们在输入的时候在channel进行了split,所以只有concat的凭借才能保证channel是一样的。 - 在shuffleNet v2相比于v1没有在add之后,进行Relu,改为在右边分支进行Relu.就相当于原来来个分支都有Relu操作,改为只在右边分支有Relu操作
- 对于三个连续的
element-wise
操作,Concat
,Channel Shuffle
以及下一个block的Channel Split
,这三个操作可以合并为一个element-wise operation
,又变相的减少了element-wise
操作的个数,这就满足G4准则。 - 对于下采样为2,对应
图e
的情况,channel split
操作就不存在了,因此输出特征矩阵的channel就翻倍了
ShuffleNet V2 网络结构
- 作者提到,shuffleNet v1 v2,它的框架基本上都一样的。都有
Conv1 Maxpoo Stage 2~5 Global pool FC
,这里唯一的不同就是v2比v1多了一个1x1Conv5
,提供了shuffleNet v2 0.5x,shuffleNet v2 1x,shuffleNet v2 1.5x,shuffleNet v2 2x
四个不同的版本。 - 对于每个stage,它的第一个block是需要进行翻倍的,步距strip都是等于2的。
shuffleNet v1和v2对比
- shuffleNet v2相对于shuffleNet v1在stride=1的情况下,首先通过一个channel split的操作,将输入特征矩阵划分为2部分,1部分是我们的捷径分支,另一部分就对应于我们主分支。
- 对于主分支而言我们两个1x1的卷积层,又有v1的GConv变成了原来普通的卷积了。由于是普通卷积,主分支没有channel shuffle了,将它移到concat之后了。
- 对于v1的add操作,变为了v2的concat操作了。
- 并将v1中经过add,然后relu。v2将relu放到了右边的分支上了。
- 对于stride为2的情况下,对于v1的分支上用过3x3的平均池化,但V2版本中通过一个3x3DW卷积+1x1的普通卷积。
性能指标
`
- 首先看下ShuffleNet v2 0.5x这个版本,在这里对标了
MobileNet v1 0.25
,MobileNet v2 0.4版本
,还有MobileNet v2 0.15
版本,这些版本你能够发现其实,他们的Flops其实是差不多的,但准确率方面我们可以看到shuffleNet v2 0.5x是最高的。但在速度方面我们可以看到MobileNet v1 0.25速度是最快的,但准确率和shuffleNet v2 0.5x比起来,相差太远了。 - ShuffleNet V2 1x的版本,它对标
MobileNet v1 0.5
版本,还有MobileNet v2 0.75
版本,以及MobileNet v2 0.6
版本。可以看到他们的Flops其实也是差不多的。但是错误率上shuffleNet v2 1x是最小的,也就是最有效的。在速度方面,cpu上还是mobilleNet v1 0.5版本是最快的,但是它的错误率明显要高出很多,但是在我们的arm cpu上依旧是我们shuffleNet v2 1x是最快的 - 最后作者也将ShuffleNet v2 2x 加上了注意力机制SE,恨他对标的几个网络,在FLOPs相同的情况下,错误率最低,GPU以及CPU上推理速度也都是最快的。
ShuffleNet 系列(2): ShuffleNet v2 理论讲解相关推荐
- shuffleNet系列
目录 分组卷积 分组卷积的矛盾--计算量 分组卷积的矛盾--特征通信 channel shuffle ShuffleNet V1 ShuffleNet基本单元 ShuffleNet网络结构 对比实验 ...
- 第八课:ShuffleNet v1、ShuffleNet v2学习
前言 随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容.来源于哔哩哔哩博主"霹雳吧啦Wz",博主学习作为笔记记录,欢 ...
- 轻量化神经网络总结:SqueezeNet、Xception、MobileNet v1、MobileNet v2、ShuffleNet v1、ShuffleNet v2
2016.02 伯克利&斯坦福提出 SqueezeNet 在ImageNet上实现了与Alexnet相似的效果,参数只有其1/50 核心点: 1x1卷积核代替3x3卷积核 Squeeze La ...
- 线程安全的理论讲解(volatile)
参考:http://blog.csdn.net/xieyuooo/article/details/8639190 在J U C里面,要谈到并发,就必然就存在可见性问题,其实对于程序来讲,要说到锁,首 ...
- cass插件_南方CASS专题系列,全套教程+视频讲解+插件汇总,全部打包速带走
南方CASS专题系列,全套教程+视频讲解+插件汇总,全部打包速带走 CASS软件是基于CAD平台开发的一套集地形.地籍.空间数据建库.工程应用.土石方算量等功能为一体的软件系统:广泛应用于地形成图.地 ...
- MPC控制器设计,模型预测控制,线性时变模型预测控制,LTV MPC,提供理论讲解与应用实现
MPC控制器设计,模型预测控制,线性时变模型预测控制,LTV MPC,提供理论讲解与应用实现. 提供MPC算法.LTV MPC 算法在直升机和四旋翼中的应用实例. 提供模型预测控制资料. 提供matl ...
- 无迹(损)卡尔曼滤波(UKF)理论讲解与实例
无迹(损)卡尔曼滤波(UKF)理论讲解与实例 文章目录 无迹(损)卡尔曼滤波(UKF)理论讲解与实例 理论讲解 模型对比 UT变换 UKF算法步骤 预测部分 更新部分 应用实例 CTRV模型 预测处理 ...
- DCGAN理论讲解及代码实现
目录 DCGAN理论讲解 DCGAN的改进: DCGAN的设计技巧 DCGAN纯代码实现 导入库 导入数据和归一化 定义生成器 定义鉴别器 初始化和 模型训练 运行结果 DCGAN理论讲解 DCGAN ...
- 扩展卡尔曼滤波(EKF)理论讲解与实例(matlab、python和C++代码)
扩展卡尔曼滤波(EKF)理论讲解与实例(matlab.python和C++代码) 文章目录 扩展卡尔曼滤波(EKF)理论讲解与实例(matlab.python和C++代码) 理论讲解 KF和EKF模型 ...
最新文章
- 谢欣伦 - OpenDev原创教程 - 蓝牙设备查找类CxBthRemoteDeviceFind
- 如何准确看清用户需求?
- 高斯消去法c++_高斯消去法的算法改进
- 【JavaScript+JinJa2】表格中将后台传入的None值显示为空字符串,将数据显示为int类型值
- 如何查看、备份电脑隐藏的恢复分区
- C#8.0可空引用类型的使用注意要点 1
- flink和kafka区别_Apache Flink和Kafka入门
- python paramiko使用
- Magento(CE1.X)自带模块解析一
- Java异常:IllegalArgumentException Collections.sort报错
- linux 检验md5命令,linux命令行校验工具md5sum
- Oracle中set feedback 、 set heading off 、 set verify off、 set termout off解释
- 做小红书推广快速涨粉的技巧_云媒易
- Eclipse安装PMD插件
- 男人常吃6种食物当心伤精少精
- 【ps合成】给男票做个Q版大头像
- python QQ邮件发送
- elasticsearch7.6 + Oracle12 数据同步 logstatsh 无缝衔接一天同步一次
- (Android版)AR 现实增强 高通 Vuforia QCAR SDK学习笔记(一)
- python什么意思k_对python中的*args与**kwgs的含义与作用详解