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 / Stride | Filter Shape | Input Size |
---|---|---|
Conv / s2 | 3*3*3*32 | 224*224*3 |
Conv dw / s1 | 3*3*32 dw | 112*112*32 |
Conv / s1 | 1*1*32*64 | 112*112*32 |
Conv dw / s2 | 3*3*64 dw | 112*112*64 |
Conv / s1 | 1*1*64*128 | 56*56*64 |
Conv dw / s1 | 3*3*128 dw | 56*56*128 |
Conv / s1 | 1*1*128*128 | 56*56*128 |
Conv dw / s2 | 3*3*128 dw | 56*56*128 |
Conv / s1 | 1*1*128*256 | 28*28*128 |
Conv dw / s1 | 3*3*256 dw | 28*28*256 |
Conv / s1 | 1*1*256*256 | 28*28*256 |
Conv dw / s2 | 3*3*256 dw | 28*28*256 |
Conv / s1 | 1*1*256*512 | 14*14*256 |
5 * Conv dw / s1 Conv / s1 | 3*3*512 dw 1*1*512*512 | 14*14*512 14*14*512 |
Conv dw / s2 | 3*3*512 dw | 14*14*512 |
Conv / s1 | 1*1*512*1024 | 7*7*1024 |
Conv dw / s2 | 3*3*1024 dw | 7*7*1024 |
Conv / s1 | 1*1*1024*1024 | 7*7*1024 |
Avg Pool / s1 | Pool 7*7 | 7*7*1024 |
FC | 1024*1000 | 1*1*1024 |
Softmax | Classfier | 1*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。
stride=1,此时残差连接为identity connection,另一分支为1*1 group conv ReLU->channel shuffle -> 3*3 dw conv(st=1) -> 1*1 group conv,两个分支add后ReLU。
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卷积。
Layer | Output size | KSize | Stride | Repeat | Ouput channels( |
---|---|---|---|---|---|
Image | 224*224 | 3 3 3 3 3 | |||
Conv1 MaxPool | 112*112 56*56 | 2 1 | 1 3 | 24 24 24 24 24 | |
Stage2 | 28*28 28*28 | 2 1 | 1 3 | 144 200 240 272 384 | |
Stage3 | 14*14 14*14 | 2 1 | 1 3 | 288 400 480 544 768 | |
Stage4 | 7*7 7*7 | 2 1 | 1 7 | 576 800 960 1088 1536 | |
GlobalPool | 1*1 | 7*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相同的两个超参数探索性能,不同的是当
α<1\alpha<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中匹配
RMSprop, momentum=decay=0.9
init lr=0.045 decay by 0.98 per epoch,
l2 regularizarion=4e-5
16 GPU异步更新, batch size=96
stride=1,此时残差连接为identity connection,另一分支为1*1 conv,ReLU6 -> 3*3 dw conv(st=1) -> 1*1 conv, Linear,两个分支add。
stride=2,此时没有残差连接,另一分支为1*1 conv,ReLU6 -> 3*3 dw conv(st=2) -> 1*1 conv, Linear。
bottleneck
Input | Operator | Output |
---|---|---|
1*1 Conv, ReLU6 | ||
3*3 dw Conv st= | ||
Linear 1*1 Conv |
Architecture
Input | Operator | ||||
---|---|---|---|---|---|
224*224*3 | Conv 3*3 | - | 32 | 1 | 2 |
112*112*32 | bottleneck | 1 | 16 | 1 | 1 |
112*112*16 | bottleneck | 6 | 24 | 2 | 2 |
56*56*24 | bottleneck | 6 | 32 | 3 | 2 |
28*28*32 | bottleneck | 6 | 64 | 4 | 2 |
14*14*64 | bottleneck | 6 | 96 | 3 | 1 |
14*14*96 | bottleneck | 6 | 160 | 3 | 2 |
7*7*160 | bottleneck | 6 | 320 | 1 | 1 |
7*7*320 | Conv 1*1 | - | 1280 | 1 | 1 |
7*7*1280 | avgpool 7*7 | - | - | 1 | - |
1*1*1280 | conv 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:
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,后者的连接会有很大一部分冗余的,而在这里这种连接密度会随着连接距离呈指数递减,降低了冗余。
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。
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,
Network fragmentation reduces degree of parallelism,网络细分会导致并行度下降从而是的速度降低,在GPU上影响比较大,细分包括同一个block里面的1*1卷积操作,pooling操作等等。
Element-wise operations are non-negligible,元素级的操作带来的速度影响不能忽略,element-wise的操作一般有较高d的MAC/FLOPS,比如ReLU,resnet中的跳接(Add操作),因为dw conv也有较高的MAC/FLOPS,这里也把它归为一种element-wise的操作。
Layer | Output Size | KSize | Stride | Repeat | Output channels 0.5* 1.0* 1.5* 2.0* |
---|---|---|---|---|---|
Image | 224*224 | 3 3 3 3 | |||
Conv1 MaxPool | 112*112 56*56 | 3*3 | 2 2 | 1 | 24 24 24 24 |
Stage2 | 28*28 28*28 | 2 1 | 1 3 | 48 116 176 244 | |
Stage3 | 14*14 14*14 | 2 1 | 1 7 | 96 232 352 488 | |
Stage4 | 7*7 7*7 | 2 1 | 1 3 | 192 464 704 976 | |
Conv5 | 7*7 | 1*1 | 1024 1024 1024 2048 | ||
GlobalPool | 1*1 | 7*7 | |||
FC | 1000 1000 1000 1000 | ||||
FLOPS | 41M 146M 299M 591M | ||||
# of Weights | 1.4M 2.3M 3.5M 7.4M |
Compare
Model | TOP-1 Accuary | Million Muli-Adds | Million Parameters |
---|---|---|---|
GoogleNet | 69.8% | 1550 | 6.8 |
VGG 16 | 71.5% | 15300 | 138 |
Inception V3 | 84% | 5000 | 23.2 |
1.0 MobileNet-224 | 70.6% | 569 | 4.2 |
ShuffleNet 1.5*(g=3) | 71.5% | 292 | 3.4 |
ShuffleNet 2*(g=3) | 73.7% | 524 | 5.4 |
MobileNet v2 | 72.0% | 300 | 3.4 |
MobileNet v2(1.4) | 74.7% | 585 | 6.9 |
ShuffleNet v2 2* | 74.9% | 591 | 6.7 |
限定FLOPS
Model | MFLOPS | TOP1-err | GPU Speed(Batches\sec.) |
---|---|---|---|
ShuffleNet v2 0.5* | 41 | 39.7 | 417 |
ShuffleNet v1 (g=3) 0.5* | 38 | 55.1 | 351 |
0.25 MobileNet v1 | 41 | 49.7 | 502 |
0.15 MobileNet v2 | 39 | 55.1 | 351 |
0.4 MobileNet v2 | 43 | 43.4 | 333 |
ShuffleNet v2 1.0* | 146 | 30.6 | 341 |
ShuffleNet v1(g=3) 1.0* | 140 | 32.6 | 213 |
0.5 MobileNet v1 | 149 | 36.3 | 382 |
0.75 MobileNet v2 | 145 | 32.1 | 235 |
0.6 MobileNet v2 | 141 | 33.3 | 249 |
ShuffleNet v2 1.5* | 299 | 27.4 | 255 |
ShuffleNet v1(g=3) 1.5* | 292 | 28.5 | 164 |
0.75 MobileNet v1 | 325 | 31.6 | 314 |
1.0 MobileNet v2 | 300 | 28 | 180 |