自从深度卷积神经网络出现以来,大多数人都在考虑怎样能提升网络的性能,却忽略了网络的实用性。在实际情况下,计算性能和存储空间的限制和速度的要求,使得网络在精度的基础上尽量达到轻量化。
如果想了解各种卷积神经网络的性能及参数可以访问:[所有卷积神经网络的性能对比]。下图是我在此项目中摘取的部分网络的性能,要求是网络的参数量小于30M,这些结果都是项目作者实验得到的。网络的实用性并不只有参数量决定,还有深度等问题,这些在接下来的内容中会进行讨论。
从上图可以看出,轻量化的网络的性能与普通网络在Top-1上会相差15个点,但是这些都是满座实际要求的。接下来将讨论几种有名的轻量化网络,之后总结以下它们的创新点。
[SqueezeNet (2017)]
? - [SQUEEZENET:ALEXNET-LEVEL ACCURACY WITH50X FEWER PARAMETERS AND<0.5MBMODEL SIZE]
? - [SqueezeNet代码]
[创新点]
SqueezeNet最大的创新点就是提出了一个Fire Module的结构,一种新的卷积方式,而这个创新点主要来源于Inception。下图是Fire Module的结构图,其分为两部分:squeeze和expand。在squeeze中,上层的featuremap经过1×1的卷积核,用来改变featuremap的通道数。在expand中,用两种卷积核,大小为1×1和3×3,所以通过expand后生成featuremap的通道数为两种卷积核的总通道数。总的来说,Fire Module就是用来改变featuremap的通道数,并不会改变大小。
另一个创新点就是提出了SqueezeNet,结构如下图所示。作者并没有用普通的卷积操作,而是全部使用了Fire Module。SqueezeNet有三种版本,左边的是普通的SqueezeNet,中间是由简单旁路的SqueezeNet,右边是复杂旁路的SqueezeNet。
下表所示为普通的SqueezeNet的结构和参数,每一个Fire Module都有三个参数,squeeze中1×1的通道数 S 1 × 1 S_{1×1} S1×1,expand中的1×1卷积核通道数 e 1 × 1 e_{1×1} e1×1和3×3卷积核通道数 e 3 × 3 e_{3×3} e3×3。例如,fire2中输入为55×55×96的featuremap,先进入16层的1×1卷积层,这里是多通道卷积,16曾每层都是1×1×96,所以这一层的参数量为: ( 1 × 1 × 96 + 1 ) × 16 + ( 1 × 1 × 16 + 1 ) × 64 + ( 3 × 3 × 16 + 1 ) × 64 = 11920 (1×1×96+1)×16+(1×1×16+1)×64+(3×3×16+1)×64=11920 (1×1×96+1)×16+(1×1×16+1)×64+(3×3×16+1)×64=11920 之后作者对网络进行剪枝,后面的百分比代表作者保留的通道数的比例,因为3×3的卷积核包含大量的参数,所以作者主要对3×3进行剪枝。
[MobileNet]
? - [MobileNets: Efficient Convolutional Neural Networks for Mobile VisionApplications]
? - [Inverted Residuals and Linear Bottlenecks: Mobile Networks for Classification, Detection and Segmentation]
? - [Searching for MobileNetV3]
[MobileNet v1]
[创新点]
为了减小参数量提升运算速度,作者抛弃了传统的卷积方法,采用了深度可分离卷积。这种卷积的特点就是逐通道卷积,并且为了使所有通道的featuremap都包含所有信息,作者又加了一层逐点卷积,如下图所示:
当输入featuremap通道数为 M M M,输出为通道数为 N N N的featuremap时,对于标准卷积操作,其需要 N N N个 D K × D K × M D_K×D_K×M DK×DK×M通道的卷积核。利用作者提出的深度可分离卷积和逐点卷积,首先经过通道数相同 D K × D K × M × 1 D_K×D_K×M×1 DK×DK×M×1的卷积核,逐通道卷积,生成 M M M维的featuremap,之后接一个1×1的卷积层,维数为 N N N,就能够生成通道数为 N N N的featuremap,这样参数量大大减少。下面就计算了参数量较少的倍数,分子是作者提出新的卷积方式,分母是标准卷积: D K ⋅ D K ⋅ M + M ⋅ N D K ⋅ D K ⋅ M ⋅ N = 1 N + 1 D K 2 \begin{aligned} & \frac{D_{K} \cdot D_{K} \cdot M +M \cdot N}{D_{K} \cdot D_{K} \cdot M \cdot N} \\=& \frac{1}{N}+\frac{1}{D_{K}^{2}} \end{aligned} =DK⋅DK⋅M⋅NDK⋅DK⋅M+M⋅NN1+DK21
作者在MobileNet v1中没有采用池化层,而是采用了步长为2的深度可分离卷积进行下采样,如下图所示:
[MobileNet v2]
[创新点]
残差模块在ResNet中大放异彩,其过程就是先用1×1的卷积核对通道进行降维,之后3×3的卷积层进行特征提取,最后用1×1的卷积核升维。但是在MobileNet v2中,作者引入了残差模块,但是是倒残差模块。先升维再降维。这是因为深度可分离卷积本身的通道数很少了,在减少对提取特征不利,如下图左侧所示。同样作者没有采用池化层,仍然采用了步长为2的深度可分离卷积进行下采样,这里没有残差形式,但是由先升维再降维的操作。
作者没有采用普通的ReLU函数,而是采用用了ReLU6,特点就是,限制输出的最大值为6。作者认为不断的经过ReLU函数会丢失很多的特征,所以最后采用了Linear函数。下图就是一个模块的结构,其中 t t t为通道上扩张的倍数,一般为6。
[MobileNet v3]
[创新点]
作者在MobileNet v2的基础上,继续使用倒残差模块,又结合了MnasNet模型的基于squeeze and excitation结构,如下图所示为新的模块结构。作者通过减小升维的通道数来弥补引入squeeze and excitation所带来的延时。[SENet]
原先作者设计的激活函数是 swish x = x ⋅ σ ( x ) \text { swish } x=x \cdot \sigma(x) swish x=x⋅σ(x)但是 σ ( x ) \sigma(x) σ(x)计算量很大,所以作者设计了: h -swish [ x ] = x ReLU 6 ( x + 3 ) 6 h \text { -swish }[x]=x \frac{\operatorname{ReLU} 6(x+3)}{6} h -swish [x]=x6ReLU6(x+3)
在平均池化之前,作者利用1×1的卷积层提高维度,导致了巨大的计算量。作者取消了后面的卷积层,先利用平均池化将featuremap的大小从7×7降到1×1再通过1×1的卷积层升维,经过作者实验证明,这样对精度没有影响,反而降低了15ms的运行时间。
[ShuffleNet (2017)]
? - [ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices]
[创新点]
[Xception (2017)]
? - [Xception: Deep Learning with Depth-wise Separable Convolutions]
[创新点]
再Inception v3中,如下图第一张所示,结构较为复杂;作者先去除了平均池化层如下图第二张所示;之后有融合了所有的1×1卷积层的输出结果,如下图第三张所示,这里会拿出多个通道分别送入3×3的卷积层中;最终作者设计了下图第四张的结构,1×1卷积层的输出结果每一层分别输入3×3的卷积层中。
奇妙的是,其他网络采用的深度可分离卷积是先将进行3×3的卷积层再接1×1的卷积层,而Xception正好相反,先1×1后3×3。由于这些结构都是再同一年发出的,并没有人做两种结构的对比试验。
作者基于ResNet设计了三种网络结构Entry,Middle和Exit,三个结构相连组成了Xception网络的结构。由下图看来,Xception比较深并不能说是真正意义上的轻量化网络,但是它改进的Inception v3值得借鉴。
[MixNet (2019)]
? - [MixConv: Mixed Depthwise Convolutional Kernels]
? - [MixNet代码]
? - [参考博文:MixNet学习笔记]
[创新点]
前面提到的所有网络都是采用的1×1和3×3的卷积核尺寸,本文作者就对卷积核尺寸进行研究,探索究竟什么尺寸的卷积核更有利于提高模型的精度和速度。下图是作者在MobileNet上进行的实验:
从上图可以得出,更大的卷积核并不能带来更好的精度,随着尺寸的增加,精度先上升后下降。另外大家都知道,低分辨率的图片适合使用小卷积核,高分辨率的图片适合用大卷积核。所以作者提出MDConv模块:
左边是普通的深度可分离卷积,每一个通道都是和相同的卷积核卷积。而再右边的MDConv中,将通道分组,不同组的featuremap和不同大小的卷积核卷积,于是这里又产生了新的问题,分成多少组合适?每组多少通道数?卷积核的尺寸范围是多少?
作者针对这些问题也做了很多实验。首先,当分组数为1时或者每组的卷积核相同时,都等价于深度可分离卷积。于是作者从分组数为2开始,卷积核大小为3×3开始,按奇数取值不断增加。最后作者,采用的是平分通道的方式进行MDConv。
作者设计了MDConv,并利用AutoML设计了三种合适的网络结构MixNet-S、MixNet-M和MixNet-L
,结构图如下图所示:
下图为MixNet与其他网络的对比图:
[EfficientNet (2019)]
? - [EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks]
? - [EfficientNet代码]
[创新点]
作者利用AutoML的方法对模型的深度、宽度、分辨率进行自适应调整。首先作者提出一个Baseline模型,如下图最左侧,第二到第四张是对模型宽度、深度和分辨率进行调整,最后一张是组合调整。
作者将卷积层的运算定义为
Y
i
=
F
i
(
X
i
)
Y_{i}=F_{i}\left(X_{i}\right)
Yi=Fi(Xi) 其中
F
i
F_{i}
Fi是卷积运算,
X
i
X_{i}
Xi是输入featuremap,
Y
i
Y_{i}
Yi是输出featuremap。
<
H
i
,
W
i
,
C
i
>
<H_{i}, W_{i}, C_{i}>
<Hi,Wi,Ci>是featuremap的尺寸,那么卷积神经网络可以表示为:
N
=
F
k
⊙
…
⊙
F
2
⊙
F
1
(
X
1
)
=
⨀
j
=
1
…
k
F
j
(
X
1
)
\mathcal{N}=\mathcal{F}_{k} \odot \ldots \odot \mathcal{F}_{2} \odot \mathcal{F}_{1}\left(X_{1}\right)=\bigodot_{j=1 \ldots k} \mathcal{F}_{j}\left(X_{1}\right)
N=Fk⊙…⊙F2⊙F1(X1)=j=1…k⨀Fj(X1)
如果网络可以划分多个模块,那么相同的模块定义为
F
L
i
(
X
i
)
\mathcal{F}^{L_{i}}\left(X_{i}\right)
FLi(Xi),那么s个模块的卷积神经网络可以定义为:
N
=
⨀
i
=
1
…
s
F
i
L
i
(
X
⟨
H
i
,
W
i
,
C
i
⟩
)
\mathcal{N}=\bigodot_{i=1 \ldots s} \mathcal{F}_{i}^{L_{i}}\left(X_{\left\langle H_{i}, W_{i}, C_{i}\right\rangle}\right)
N=i=1…s⨀FiLi(X⟨Hi,Wi,Ci⟩)
AutoML的优化目标:
max
d
,
w
,
r
Accuracy
(
N
(
d
,
w
,
r
)
)
s.t.
N
(
d
,
w
,
r
)
=
⨀
i
=
1
…
s
F
^
i
d
⋅
L
^
i
(
X
⟨
r
⋅
H
^
i
,
r
⋅
W
^
i
,
w
⋅
C
^
i
)
)
Memory
(
N
)
≤
target
memory
FLOPS
(
N
)
≤
target. flops
\begin{array}{ll}{\max _{d, w, r}} & {\operatorname{Accuracy}(\mathcal{N}(d, w, r))} \\ {\text {s.t.}} & {\mathcal{N}(d, w, r)=\bigodot_{i=1 \ldots s} \hat{\mathcal{F}}_{i}^{d \cdot \hat{L}_{i}}\left(X_{\left\langle r\cdot\hat{H}_{i}, r \cdot \hat{W}_{i}, w \cdot \hat{C}_{i}\right)}\right)} \\ {} & {\text { Memory }(\mathcal{N}) \leq \operatorname{target} \text { memory }} \\ {} & {\text { FLOPS }(\mathcal{N}) \leq \text { target. flops }}\end{array}
maxd,w,rs.t.Accuracy(N(d,w,r))N(d,w,r)=⨀i=1…sF^id⋅L^i(X⟨r⋅H^i,r⋅W^i,w⋅C^i)) Memory (N)≤target memory FLOPS (N)≤ target. flops
其中
w
,
d
,
r
w, d, r
w,d,r是缩放系数,
F
^
i
\hat{F}_{i}
F^i是卷积操作,
L
^
i
\hat{L}_{i}
L^i是网络深度,
H
^
i
\hat{H}_{i}
H^i和
W
^
i
\hat{W}_{i}
W^i是分辨率大小,
C
^
i
\hat{C}_{i}
C^i是网络宽度,都是baseline模型预先训练好的参数。但是,在缩放过程中作者定义一个符合参数
ϕ
\phi
ϕ来统一缩放:
depth:
d
=
α
ϕ
width:
w
=
β
ϕ
resolution:
r
=
γ
ϕ
s.t.
α
⋅
β
2
⋅
γ
2
≈
2
α
≥
1
,
β
≥
1
,
γ
≥
1
\begin{array}{c}{\text { depth: } d=\alpha^{\phi}} \\ {\text { width: } w=\beta^{\phi}} \\ {\text { resolution: } r=\gamma^{\phi}} \\ {\text { s.t. } \alpha \cdot \beta^{2} \cdot \gamma^{2} \approx 2} \\ {\alpha \geq 1, \beta \geq 1, \gamma \geq 1}\end{array}
depth: d=αϕ width: w=βϕ resolution: r=γϕ s.t. α⋅β2⋅γ2≈2α≥1,β≥1,γ≥1其中
α
,
β
,
γ
\alpha, \beta, \gamma
α,β,γ都是通过约束条件,在范围内找到的常数。当
w
,
d
,
r
w, d, r
w,d,r分别增加一倍时,网络的FLOPS分别增加
w
,
d
2
,
r
2
w, d^2, r^2
w,d2,r2倍,所以当变化
ϕ
\phi
ϕ时,网络的计算量变化
(
α
⋅
β
2
⋅
γ
2
)
ϕ
\left(\alpha \cdot \beta^{2} \cdot \gamma^{2}\right)^{\phi}
(α⋅β2⋅γ2)ϕ倍也就约等于
2
ϕ
2^{\phi}
2ϕ。
下图是网络调整对网络性能影响:
模型的缩放不会改变 F i {F}_{i} Fi,所以要找个好的卷积策略,作者利用了MnasNet,同样也是通过AutoML方法生成网络结构,如下图所示:
作者并没有直接使用这种结构,而是生成一种类似的网络,取名叫EfficientNet-B0。以EfficientNet-B0为baseline,对模型进行调整:
①固定
ϕ
=
1
\phi=1
ϕ=1,计算量相比之前会有2倍增加,进行小范围搜索,最终得到
α
=
1.2
,
β
=
1.1
,
γ
=
1.15
\alpha=1.2, \beta=1.1, \gamma=1.15
α=1.2,β=1.1,γ=1.15
②固定
α
=
1.2
,
β
=
1.1
,
γ
=
1.15
\alpha=1.2, \beta=1.1, \gamma=1.15
α=1.2,β=1.1,γ=1.15,调整
ϕ
\phi
ϕ,获得Efficient-B1到Efficient-B7。
网络性能对比: