查看原文
其他

【模型压缩】关于MobileNet和ShuffleNet v1v2一些理解

草yang年华 机器学习与python集中营 2021-09-10

转自:https://blog.csdn.net/qsczse943062710/article/details/88125351

python进阶教程

机器学习

深度学习

长按二维码关注



  • 1. MobileNet(2017):

    • 将传统卷积改成depthwise separable convolutions(每个kernel只和对应的一个channel的feature map进行卷积操作) && pointwise 1*1 convolutions(常规的1*1卷积),大大降低参数量和计算量,压缩比:

      1N+1D2k,N=output_channels,Dk=kernel_size\frac{1}{N} + \frac{1}{D_k^2}, N=output\_channels, D_k=kernel\_sizeN1+Dk21,N=output_channels,Dk=kernel_size

    • 除首层采用常规卷积,其余层均为dw conv && pw conv的组合。

    • 所有的pooling操作用stride=2的卷积代替。

    • 所有增加channel的卷积皆为1*1 pointwise conv。

    • fc之前使用avg pooling将feature map的大小变为1。

    • 1*1的卷积在卷积实现(GEMM)时效率高(考虑到稀疏矩阵)。

    • RMSprop,异步更新。

    • no data augumentation and l2 regularization on dw conv。

    • 使用超参数 α∈(0,1]\alpha \in (0,1]α∈(0,1]控制feature map的channels数,使用超参数 ρ∈(0,1]\rho \in (0,1]ρ∈(0,1]控制图像和feature map的大小,更加灵活的压缩模型:
      1αN+1D2k\frac{1}{\alpha N} + \frac{1}{D_k^2}αN1+Dk21

    • PS:在某些实验中ρ\rhoρ对性能的影响要大于α\alphaα,下表中的dw只指3*3的那层卷积。

    • ImageNet, Large Scale Geolocalizaton, Face Attributes, Object Detection

Type / StrideFilter ShapeInput Size
Conv / s23*3*3*32224*224*3
Conv dw / s13*3*32 dw112*112*32
Conv / s11*1*32*64112*112*32
Conv dw / s23*3*64 dw112*112*64
Conv / s11*1*64*12856*56*64
Conv dw / s13*3*128 dw56*56*128
Conv / s11*1*128*12856*56*128
Conv dw / s23*3*128 dw56*56*128
Conv / s11*1*128*25628*28*128
Conv dw / s13*3*256 dw28*28*256
Conv / s11*1*256*25628*28*256
Conv dw / s23*3*256 dw28*28*256
Conv / s11*1*256*51214*14*256
5 * Conv dw / s1
Conv / s1
3*3*512 dw
1*1*512*512
14*14*512
14*14*512
Conv dw / s23*3*512 dw14*14*512
Conv / s11*1*512*10247*7*1024
Conv dw / s23*3*1024 dw7*7*1024
Conv / s11*1*1024*10247*7*1024
Avg Pool / s1Pool 7*77*7*1024
FC1024*10001*1*1024
SoftmaxClassfier1*1*1000
  • 2. ShuffleNet(2017):

    • 当前主流的SOTA模型只对3*3的卷积进行了group conv或者dw conv的操作而忽略了1*1的卷积,实际上这对设计小模型是非常不利的,因为这些1*1的卷积占据了绝大部分的计算量,这个从MobileNet的原文统计中也可以看到。

    • 但是如果直接用group conv对所有1*1的卷积操作,会导致某个输出channel的信息仅仅来于输入的某些固定的channel,解决方案:pointwise group convolution && channel shuffle, 即对group conv操作的feature map进行channel shuffle后作为下一层的输入。

    • 模型主要由3个stage组成,每个stage有多个unit,unit分为两种:

    • stage2的第一个卷积为常规卷积,因为此时channel过少。

    • 每个stage内channel数不变,stage后channel数double, bottleneck 的值为1/4(如果fusion为add,bottleneck的channel直接为1/4,如果为concat,bottleneck的channelw为输出的channel数-输入的channel数除以4)。

    • less data augumentation and 4e-5 l2 regularization。

    • 性能优于MobileNet 7.8% ImageNet。

  1. stride=1,此时残差连接为identity connection,另一分支为1*1 group conv ReLU->channel shuffle -> 3*3 dw conv(st=1) -> 1*1 group conv,两个分支add后ReLU。

  2. stride=2,此时残差连接为3*3 avg pooling,另一分支为1*1 group conv ReLU->channel shuffle -> 3*3 dw conv(st=2) -> 1*1 group conv,两个分支concat后ReLU

    PS:g=3为最有tride-off, 这里的dw是完整的,包含3*3和1*1卷积。

LayerOutput sizeKSizeStrideRepeatOuput channels(ggg groups)
ggg=1  ggg=2  ggg=3  ggg=4  ggg=8
Image224*224


3   3   3   3   3
Conv1
MaxPool
112*112
56*56

2
1
1
3
24    24    24    24    24
Stage228*28
28*28

2
1
1
3
144  200  240  272  384
Stage314*14
14*14

2
1
1
3
288  400  480  544  768
Stage47*7
7*7

2
1
1
7
576    800    960    1088    1536
GlobalPool1*17*7


FC



1000  1000  1000  1000  1000
Complexity



143M 140M 137M 133M 137M
  • 3. MobileNet v2(2018):

    • bottleneck认为高维的特征能够嵌入一个低维的流形,文中说明,虽然Relu对导致小于0的部分died,但是它仍然具备保留所有信息的能力,前提是输入的流形确实能够嵌入输入空间一个低维的子空间。

    • 但是当维度很低的时候,非线性(e.g. ReLU)会严重导致数据坍塌,因此channel少的feature map后面不应该接ReLU,如果在bottleneck使用了非线性,会影响性能,因此在bottleneck的地方移除了Relu。

    • 基于上,bottleneck已经保留了几乎所有有用的信息,因此现有的一些后面紧接的expansion layer是不必要的,MobileNets v2直接用跳接连接bottleneck。

    • 实验结果表明,expansion rate取5-10较好,且模型越大取值应该越大。

    • 使用和MobileNet相同的两个超参数探索性能,不同的是当α&lt;1\alpha&lt;1α<1时,v2不在最后一个卷积层降低channel,实验证明这对小模型的性能有所提升。

    • MobileNet v2能够只保留很少的中间变量(在求非残差分支的时候,分为t路,2-5,太大会因为cache miss导致性能下降),因为(1)最中间的变换是per-channel的dw conv(2)其余的变换输入和输出的channel比率都很大(bottleneck的压缩和还原)。虽然这样做并不会减少总的multiply-add的操作次数

    • bottleneck分为两种:

    • ImageNet:

    • Object Detection: SSDLite(把ssd的预测层的卷积替换为dw conv)

    • 特别重要的一点!第一个stage的t=1,结构不再是131,而是31,dw conv 前没有 1*1的conv,官方给出的tf源码,论文中没有提及,同时只要按照官方tf的代码,mb v2的FLOP才能和shufflenet v2中匹配

  1. RMSprop, momentum=decay=0.9

  2. init lr=0.045 decay by 0.98 per epoch,

  3. l2 regularizarion=4e-5

  4. 16 GPU异步更新, batch size=96

  1. stride=1,此时残差连接为identity connection,另一分支为1*1 conv,ReLU6 -> 3*3 dw conv(st=1) -> 1*1 conv, Linear,两个分支add。

  2. stride=2,此时没有残差连接,另一分支为1*1 conv,ReLU6 -> 3*3 dw conv(st=2) -> 1*1 conv, Linear。

bottleneck

InputOperatorOutput
h∗w∗kh*w*kh∗w∗k1*1 Conv, ReLU6h∗w∗tkh*w*tkh∗w∗tk
h∗w∗tkh*w*tkh∗w∗tk3*3 dw Conv st=sss, ReLU6hs∗ws∗tk\frac{h}{s}*\frac{w}{s}*tksh∗sw∗tk
hs∗ws∗tk\frac{h}{s}*\frac{w}{s}*tksh∗sw∗tkLinear 1*1 Convh∗w∗k∗h*w*k^*h∗w∗k∗

Architecture

InputOperatortttcccnnnsss
224*224*3Conv 3*3-3212
112*112*32bottleneck11611
112*112*16bottleneck62422
56*56*24bottleneck63232
28*28*32bottleneck66442
14*14*64bottleneck69631
14*14*96bottleneck616032
7*7*160bottleneck632011
7*7*320Conv 1*1-128011
7*7*1280avgpool 7*7--1-
1*1*1280conv 1*1-k-
  • Each line describes a sequence of 1 or more identical (modulo stride) layers, repeated n times. All layers in the same sequence have the same number c of output channels. The first layer of each sequence has a stride s and all others use stride 1. All spatial convolutions use 3 × 3 kernels. The expansion factor t is always applied to the input size

  • 4. ShuffleNet v2(2018):

    • 此类网络的评价不能仅仅考虑FLOPS,同时要考虑运行速度,相同的FLOPS也会有速度上的差异,因此提出了四个新的评价指标:

        c1,c2c_1,c_2c1,c2  are  input/output  channel  . corresponding

        且实验证明当c1=c2c_1=c_2c1=c2时MAC最小,速度最快(相等规模的FLOPS下)

      2. Excessive group convolution increases MAC.考虑到group。 conv降低了FLOPS但是提高了MAC,这里考虑1*1的group conv:
      MAC=hw(c1+c2)+c1c2g=hwc1+Bgc1+Bhw,B=hwc1c2g,g=#groupMAC = hw(c_1 + c_2) + \frac{c_1c_2}{g}=hwc_1 + \frac{Bg}{c_1} + \frac{B}{hw}, B=\frac{hwc_1c_2}{g},g=\#groupMAC=hw(c1+c2)+gc1c2=hwc1+c1Bg+hwB,B=ghwc1c2,g=#group
        且实验证明group越大速度越慢,两者非线性负相关。

      给出设计轻量网络的建议:(1)卷积层不要频繁变换channel维度,保证输入输出一致(2)使用group conv时精心选择g的大小(3)减少不必要的网络细分(4)减少不必要的element-wise操作。

    • 常用的两种技术用来解决给定FLOPS的情况下增加特征的channel数:group conv和bottleneck,但是这俩会增加MAC,本文采取channel split的方式来缓解这个问题。同样包含两种unit:

  1. stride=1,在unit开始的时候,进行channel split(一般等分),一个分支为identity(满足c),另一个分支:1*1 conv,ReLU -> 3*3 dw conv(st=1) -> 1*1 conv, ReLU后concat,然后channel shuffle,将1*1 group conv 变成常规conv满足b,一个unit输入输出采用concat保证channel一致满足a,同时ReLU这样的element-wise的操作只放到一个分支满足d。这样split还有一个好处就是对比densenet,后者的连接会有很大一部分冗余的,而在这里这种连接密度会随着连接距离呈指数递减,降低了冗余。

  2. stride=2, 一个分支:1*1 conv,ReLU -> 3*3 dw conv(st=1) -> 1*1 conv ReLU,另一个分支为3*3 dw conv(st=2) -> 1*1 conv ReLU后两者concat,然后channel shuffle。

  1. MAC(Equal channel width minimizes memory access cost),等量channel下能最小化的内存访问成本,考虑到大部分网络使用dw conv,而dw conv中1*1的conv占据了绝大部分的计算量,因此这里只考虑常规1*1参与的计算:

    MAC≥2hwB−−−−√+Bhw,B=hwc1c2=#FLOPS,MAC \ge 2 \sqrt{hwB} + \frac{B}{hw}, B=hwc_1c_2=\#FLOPS,MAC≥2hwB+hwB,B=hwc1c2=#FLOPS,

  1. Network fragmentation reduces degree of parallelism,网络细分会导致并行度下降从而是的速度降低,在GPU上影响比较大,细分包括同一个block里面的1*1卷积操作,pooling操作等等。

  2. Element-wise operations are non-negligible,元素级的操作带来的速度影响不能忽略,element-wise的操作一般有较高d的MAC/FLOPS,比如ReLU,resnet中的跳接(Add操作),因为dw conv也有较高的MAC/FLOPS,这里也把它归为一种element-wise的操作。

LayerOutput SizeKSizeStrideRepeatOutput channels
0.5*  1.0*  1.5*  2.0*
Image224*224


3   3   3   3
Conv1
MaxPool
112*112
56*56
3*32
2
124   24   24   24
Stage228*28
28*28

2
1
1
3
48  116  176  244
Stage314*14
14*14

2
1
1
7
96  232  352  488
Stage47*7
7*7

2
1
1
3
192    464    704    976
Conv57*71*1

1024  1024  1024  2048
GlobalPool1*17*7


FC



1000  1000  1000  1000
FLOPS



41M  146M  299M  591M
# of Weights



1.4M  2.3M  3.5M  7.4M

Compare

ModelTOP-1 AccuaryMillion Muli-AddsMillion Parameters
GoogleNet69.8%15506.8
VGG 1671.5%15300138
Inception V384%500023.2
1.0 MobileNet-22470.6%5694.2
ShuffleNet 1.5*(g=3)71.5%2923.4
ShuffleNet 2*(g=3)73.7%5245.4
MobileNet v272.0%3003.4
MobileNet v2(1.4)74.7%5856.9
ShuffleNet v2 2*74.9%5916.7

限定FLOPS

ModelMFLOPSTOP1-errGPU Speed(Batches\sec.)
ShuffleNet v2 0.5*4139.7417
ShuffleNet v1 (g=3) 0.5*3855.1351
0.25 MobileNet v14149.7502
0.15 MobileNet v23955.1351
0.4 MobileNet v24343.4333




ShuffleNet v2 1.0*14630.6341
ShuffleNet v1(g=3) 1.0*14032.6213
0.5 MobileNet v114936.3382
0.75 MobileNet v214532.1235
0.6 MobileNet v214133.3249




ShuffleNet v2 1.5*29927.4255
ShuffleNet v1(g=3) 1.5*29228.5164
0.75 MobileNet v132531.6314
1.0 MobileNet v230028180



推 荐 阅 读

推荐几个各个领域多年IT从业经验大佬的公众号
深度学习——各种优化器算法Optimizer详解
一文总览CNN网络架构演进:从LeNet到DenseNet

一问总览机器学习中各种【熵】的含义及本质

python绘图骚操作之plotly(一)——plotly的基本绘图方式

码农资源|这里有机器学习、架构、py学习等信息!~总有一个适合你!

有趣的灵魂终究会相遇

好看的皮囊风干在路上

扫码即可相遇哦


: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存