数学建模社区-数学中国
标题:
轻量级神经网络算法-SqueezeNet
[打印本页]
作者:
杨利霞
时间:
2022-9-5 16:42
标题:
轻量级神经网络算法-SqueezeNet
' Q# @" h4 [ C7 y
轻量级神经网络算法-SqueezeNet
; } X6 P7 q0 t. _$ T; T
4. 轻量级神经网络算法目录
& a! i, {% Z' u
轻量级神经网络算法
* n8 o) o* |* r' W
4.1 各轻量级神经网络算法总结对比
6 p s) b1 D/ ~' J
4.2 SqueezeNet
, t9 z' M) O, T
4.3 DenseNet
1 T, D. h; [9 s2 ~4 j
4.4 Xception
" ~2 W4 r7 m$ B, S
4.5 MobileNet v1
; T" w. o: k6 N5 J" ?; S; c& Q
4.6 IGCV
& W8 N1 \6 T' d4 \* f. h0 N; L" O
4.7 NASNet
) q& Z0 |0 X) j/ s, z
4.8 CondenseNet
6 z0 ?9 i. q. t1 g; i3 T( V
4.9 PNASNet
' i' v8 G5 ~" A4 M+ X# X
4.10 SENet
) X" e9 ]; b- M! ~
4.11 ShuffleNet v1
& I+ A9 x8 [2 o+ W
4.12 MobileNet v2
0 P3 `. Q& H# I0 V C4 \# v
4.13 AmoebaNet
! [* s" m, ]4 ] \) J
4.14 IGCV2
4 D( S) k6 H, r# R/ H/ ]
4.15 IGCV3
! a' D/ p: d3 l0 [
4.16 ShuffleNet v2
. ?8 x" f) P. `4 i/ ~; @( i) Y' b
4.17 MnasNet
* u. x& |3 Z# o& J6 E) l
4.18 MobileNet v3
% G: y( g& x( a5 j/ }2 c) ~
深度学习知识点总结
7 |3 d, ?3 U' t4 E. K
/ b. }) E9 L1 {& u
专栏链接:
- y+ ^# @/ `0 g
https://blog.csdn.net/qq_39707285/article/details/124005405
0 m1 Q, W) e( N9 p; G+ w
本专栏主要总结深度学习中的知识点,从各大数据集比赛开始,介绍历年冠军算法;同时总结深度学习中重要的知识点,包括损失函数、优化器、各种经典算法、各种算法的优化策略Bag of Freebies (BoF)等。
7 {: P/ n) _' }) ?( [- }
- p; v0 Q: A$ l0 Q* S1 a+ u' I' }
本章目录
! q: @; W! O* o( Z9 w
4. 轻量级神经网络算法目录
3 y0 t* l; \* M6 f5 L
4.2 SqueezeNet
! b7 J5 t; B! r3 ?. j: D' A
4.2.1 问题分析
! Y1 `: g" W, K
4.2.2 SqueezeNet的三大策略
' J. q/ q4 O; H! ]& U! z
4.2.3 Fire模块
( n$ [6 P9 R% ~7 Z
4.2.4 SqueezeNet整理结构
- u: @$ Z3 k9 Q" a$ g
4.2.5 代码实现SqueezeNet
$ }; I% J; W& @& C6 V
4.2.6 其他实现细节
; N. Z8 S1 O2 c, a
4.2.7 总结
# b5 g& _4 W+ _0 ?/ {
4.2 SqueezeNet
1 A& F3 X2 [1 c" d, u! [( [. S& X
4.2.1 问题分析
% m6 y" f$ N3 @! q/ r, ^. s6 w9 U
最近在卷积神经网络上的研究主要关注提高准确率。在给定相应的准确率之后,通常有多个CNN结构可以达到该准确率要求。在同等准确率的情况下,较小的CNN结构至少有三个优点:
$ v+ G+ {3 y# J4 R
& t- l1 l" x/ S6 I- a! c
在分布式训练期间,较小的CNN需要较少的跨服务器通信
# U: l7 g, q8 E8 J" o
在自动驾驶汽车等应用场景下,较小的CNN需要较少的带宽将新模型从云端导入
1 x. {; E3 |7 p7 `: e5 ?
较小的CNN更适合部署在FPGA和其他内存有限的硬件上
) t( b3 P) |' Z6 z) |7 v4 a
为了达到所有这些优点,本文提出了较小的CNN结构,称之为SqueezeNet。SqueezeNet在ImageNet上实现了AlexNet同级别的准确率,但参数减少了50倍。另外使用模型压缩技术,能够将SqueezeNet压缩到小于0.5MB(比AlexNet小近510倍)。
8 @4 Q" f: V3 k; i. b! H" m) r; Z
! S2 `% t, ^% M' U/ G2 [ C
4.2.2 SqueezeNet的三大策略
& }7 m. K2 J4 c+ w5 `
策略1:用1x1卷积代替3x3卷积
. |1 | n& {, x' e$ q
1x1卷积核的参数比3x3少9倍,所以网络中部分卷积核改为使用为1x1卷积。
8 h2 D: _( i! E6 q; m$ n
/ x k% X. n1 w, @1 b& `' ? _
策略2:减少输入到3*3卷积核的通道数量
" N ]. m# F" A7 z2 S
对于一个完全由3×3卷积核组成的卷积层来说,总参数量=输入通道数×卷积核数量×(3×3),所以仅仅替换3×3卷积核为1×1,还不能完全达到减少参数的目的,还需要减少输入到3×3卷积核的通道数。本文提出squeeze layer,来减少输入到3×3卷积核的通道数。
2 H! E/ C- Q: e# Y
9 j4 W! {1 n3 N# P; P9 B/ W( F
策略3:在网络后期再进行下采样,使卷积层具有较大的激活图
: q" z7 e \' ^- P1 h M& ^
这里的激活图(activate maps)指的是输出的特征图。在卷积网络中,每个卷积层产生空间分辨率至少为1×1(经常大于1×1)的输出激活图,激活图的宽和高主要是由1)输入的数据(例如256×256的图片) 2)CNN结构中下采样层方法 决定的。下采样通常是stride>1的卷积层或者池化层,如果在早期layer中有较大的stride,则后面大部分的layers中将是小的激活图,如果在早期layer中stride为1,在网络后期layer中stride>1,则大部分的layer将有一个大的激活图。本文的观点是,大的激活图能够产生更高的分类准确率,所以在网络设计中,stride>1往往设置在后期的layer中。
. E$ c5 {+ B, \, u2 W: a! \* I, R
0 H4 E* y* v/ f
策略1和策略2在试图保持准确性的同时,明智地减少CNN中的参数数量,策略3是在有限的参数预算上最大化准确率。
2 w6 l- \: U/ Y7 y1 o F
: M; h5 n; p* x! V
4.2.3 Fire模块
+ ~2 N$ [3 z* P- V% D5 i2 x
为实现这3大策略,提出了Fire模块,Fire模块中主要包含squeeze层和expand层。squeeze卷积如图橙色椭圆内所示,只使用1×1卷积(策略1优化点),然后进入到expand卷积,expand卷积包括1×1(策略1优化点)和3×3卷积,squeeze和expand整体构成Fire模块,该模块有三个超参数s1x1,e1x1,e3x3,其中s1x1是squeeze层卷积核的数量,e1x1是expand层中1×1卷积核的数量,e3x3是expand层中3×3卷积核的数量,另外设置s1x1<(e1x1+e3x3)(策略2优化点),这样就能限制输入到3×3卷积核通道数,实现策略2的想法。
' v+ F, ^* r5 _, e" a9 G F
3 [, g# c6 _9 A1 M+ w/ p
) a0 _/ i+ s5 Q% r0 ^" O
4.2.4 SqueezeNet整理结构
! f+ S$ h z0 w8 M
SqueezeNet整体网络结构图如下所示,其中maxpool(stride=2)分别设置在conv1/fire4/fire8/conv10之后,这些相对较晚的pool安排符合策略3的想法。
7 D( i* p* D& ~! w
/ n, V8 Y% M6 d5 U C6 u% ?& Z
3 o5 l* o( \7 h0 U7 k/ h
4.2.5 代码实现SqueezeNet
: P) c* ?+ i7 L% h9 v# y
Fire模块的代码如下:
# r7 ~; t. M7 ?, d- z0 z1 ?
, z7 ?/ i. k+ w' ^. A) p
class Fire(nn.Module):
' M B! l- c6 K4 L' F$ T' g7 r- r
$ V) D9 R% {" V/ c4 R, P( f
def __init__(
% |( G2 G' t; @
self,
0 a# r" x' \9 m
inplanes: int,
5 ^; `! r- y# O9 a* l: p' C
squeeze_planes: int,
) k* m: _ O a8 X& p
expand1x1_planes: int,
; E( p. V% G! y; j1 j
expand3x3_planes: int
* ]+ V$ Y; O- g) d9 N* I
) -> None:
+ H6 t/ H9 o9 x" O6 S( E
super(Fire, self).__init__()
4 |7 t* b3 K: A4 K+ K9 K) ~# _
self.inplanes = inplanes
" Y8 w. `) x+ q$ q
self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1)
. n1 a0 p" a8 N: z, N. E& r
self.squeeze_activation = nn.ReLU(inplace=True)
/ U% z, n i) p" S- K. [
self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes,
' g1 r( i" z* O% R. B7 n
kernel_size=1)
4 f$ [7 R, b& n& B4 R
self.expand1x1_activation = nn.ReLU(inplace=True)
/ o* _2 l% x ^3 Z3 A" S5 H5 U1 @2 [
self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes,
) f6 t9 h, N- r3 u% w8 {
kernel_size=3, padding=1)
8 ~4 z$ ]5 I0 j5 D6 c0 F
self.expand3x3_activation = nn.ReLU(inplace=True)
5 @5 g( _. E/ O9 `3 w
0 w0 p* I1 n4 z
def forward(self, x: torch.Tensor) -> torch.Tensor:
* F+ f* P, K9 R& H( b6 j
x = self.squeeze_activation(self.squeeze(x))
/ a( e+ l# j, B- r
return torch.cat([
. c+ c. O& N3 r+ d) ?' z
self.expand1x1_activation(self.expand1x1(x)),
" M0 r9 X' R9 f" M/ ? R: V" q4 i6 @
self.expand3x3_activation(self.expand3x3(x))
2 t! o( ^) s n
], 1)
, y3 E/ O$ U& D$ _; `8 r
. R* r+ O2 c* d0 d) f$ C1 h m9 ~
1
p0 Z f5 I. l: m& C! e' G; y9 ~( e! v
2
# o, @( h- f' N3 z+ X/ h
3
$ {) A' ?! y8 [7 D6 r4 K
4
# o. x+ f* S) s
5
) B% Z+ c. h9 x; {, R3 R) A5 U
6
+ \' x9 }6 g+ b/ M% }1 H
7
% u) L' C5 W: B9 J
8
2 }: A) B4 R7 x0 ~
9
5 t% t6 D$ i ?# H
10
0 x* ` q' W9 e) c7 y' j3 ?' i
11
5 d; ?" Z8 G- o! c3 ^2 K6 t$ [
12
7 ?1 ^ N4 y! Q
13
6 _: n, ^# n$ D1 _7 ]( {* ^
14
. U. Q, {3 C" ?4 t! L
15
+ \+ K1 c# e- Y& |
16
: b. d- f8 `1 H$ y& T, `. ^1 m2 M
17
0 Y, h4 [6 ]! `$ o
18
4 \0 h, |% k/ I8 G5 W
19
5 w2 [, x! R: e: G& b! u
20
0 K1 {9 a& N, @+ }: H" y* y' W
21
$ b$ `1 \# L( u! i2 ~5 W, \
22
' z3 b$ B) v0 [" m, Z0 x
23
4 V# y( d. Q# T! e
24
! B0 D1 `; _2 b" m
25
. R1 n4 k1 R( `1 N; _* M
26
7 Z2 S' }, c# K4 k
SqueezeNet主要有两个结构,SqueezeNet1_0和SqueezeNet1_1,SqueezeNet1_0即官方版本(图2左侧),SqueezeNet1_1与SqueezeNet1_0相比在没有减少准确率的情况下,节省近2.4倍的参数量和计算量。
' v$ [( _' i& Y# }/ p8 ^, w; q
/ y9 a' ~$ G, k8 |6 Y7 x
SqueezeNet1_0的网络结构如下:
5 ~3 v6 o; D: q2 P3 u
1 z7 C4 t' U3 N8 T
self.features = nn.Sequential(
; E3 |8 w/ M9 `$ ]1 Z& U0 H7 B4 y
nn.Conv2d(3, 96, kernel_size=7, stride=2),
3 V( p9 d; B: k+ l) t8 l$ P
nn.ReLU(inplace=True),
, G( ?% M1 K: }* ?9 ~; X
nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
6 R6 U& U" b: v" S, K) p- d0 M
Fire(96, 16, 64, 64),
w2 p# \4 E" |0 g# B4 t3 {9 k/ G
Fire(128, 16, 64, 64),
6 G2 j5 K6 ]" s* o% J3 p
Fire(128, 32, 128, 128),
- S! D {7 v0 H
nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
5 q1 j8 e- Y$ a2 `0 i
Fire(256, 32, 128, 128),
/ w; T6 \) m |9 ]9 z3 O* b0 p$ s, y( M
Fire(256, 48, 192, 192),
9 T& S# z: I$ k7 D, y& `: f
Fire(384, 48, 192, 192),
! S' B0 E z, V8 b& P* }
Fire(384, 64, 256, 256),
5 h q2 D+ }$ F# ~
nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
' I5 o3 @! A2 }
Fire(512, 64, 256, 256),
6 g/ y$ `& d" a. }
)
8 G4 q% A% |5 Q# Q. j
final_conv = nn.Conv2d(512, self.num_classes, kernel_size=1)
b' B2 I0 a( j; D4 }2 e* c
self.classifier = nn.Sequential(
( k) v6 x: h. M- b& _3 U% m0 F" ?# T
nn.Dropout(p=0.5),
- Y! `8 l. O! |2 g& c [+ M8 A: U
final_conv,
1 k8 ]; m. y7 }7 ~& o
nn.ReLU(inplace=True),
5 g: _2 S+ T* L" ?4 ~- Z7 O
nn.AdaptiveAvgPool2d((1, 1))
/ ^4 s1 T% g, `
)
g' s# }+ O7 P; [ D0 B
0 A( m: X9 M# l' y4 {
* y* E3 ^, b4 g7 e
1
4 _: a9 \ Q" ~+ O6 v, m
2
' U/ w* v% [4 P+ Z" H. }
3
& e) A1 Z; H0 Q8 z4 B0 t
4
" f! ~7 S+ X$ ^; p, i3 p( Z3 }
5
5 X' b/ p2 M' f# _% k2 A$ k- `
6
) H. F: N; X$ M/ O0 k5 I' G5 [6 G
7
. I! c( l3 a! ?# n; e( U4 [
8
, f+ B9 N/ x5 J; s! i. z5 c; L
9
( C8 ^' a+ `; n3 Z: O7 ?% _6 t8 W M
10
2 k$ ~: O b' i3 r
11
, y0 X+ c( m0 o. ~+ `" j
12
4 l4 c! H. I6 H1 l3 e
13
, u# R( @6 _& R2 ]& U2 ?4 c- i
14
5 l. X+ m& e$ G M' Z
15
5 c+ j- M' M; |! v
16
9 K' r$ G% n1 ]4 Y6 N) y
17
: \" |& v$ {/ z! e, Z3 @2 R7 m& Z
18
& Q" j/ X5 _7 A7 v- U7 ]2 J
19
+ p8 S) q. V& Y8 n( Q
20
6 }1 p1 h! b8 f" C- p( H. d( ]
21
* C; W% \7 N. S0 q* x
22
0 U2 b' d' |0 Y) w# y
23
6 N, f M# @4 h3 e% J; Z1 r! _4 l
SqueezeNet1_1的网络结构如下:
; W% u( ~) [) o# U: a
) G+ ^' E; v- O m9 h
self.features = nn.Sequential(
$ w1 P0 u, g- @5 ?8 O& h# w9 E
nn.Conv2d(3, 64, kernel_size=3, stride=2),
, i1 ~& |- r# B& F3 D* }/ ^) j
nn.ReLU(inplace=True),
+ F# N+ ~$ S6 i0 }
nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
* ~% B1 @! Z& h7 h% K, I7 c. V1 @
Fire(64, 16, 64, 64),
: F1 T$ x; N3 k# t
Fire(128, 16, 64, 64),
8 U/ b3 y* Y3 l: E
nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
) ?6 f& r) B8 c* S1 O6 P4 }
Fire(128, 32, 128, 128),
4 d& d+ A& _; A+ }' Z+ D) r
Fire(256, 32, 128, 128),
7 T5 n2 C; d% v' M0 g2 S( t
nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
+ ^% i, o6 v- d6 W
Fire(256, 48, 192, 192),
$ e5 I7 R& j8 d- ~+ l
Fire(384, 48, 192, 192),
D( E* T/ h$ o5 e
Fire(384, 64, 256, 256),
5 V/ L0 N! f, z! p8 e
Fire(512, 64, 256, 256),
- U- m |+ o3 b& a# q
)
0 D0 G4 h$ \' ^$ d) D
final_conv = nn.Conv2d(512, self.num_classes, kernel_size=1)
/ i+ P9 [- n$ I% E2 n
self.classifier = nn.Sequential(
( b& n; @. D8 w
nn.Dropout(p=0.5),
( l& f3 h( Z- s, w! k0 A$ ^- h( n
final_conv,
' E1 p! P0 t! o: Z1 d6 l9 E( ^
nn.ReLU(inplace=True),
& ^& }7 i# e0 `
nn.AdaptiveAvgPool2d((1, 1))
' L6 i* t9 S* c9 e3 Q: Z
)
+ }! l# M& L i5 P
. y2 \9 U# u9 ?; N# }" |
1
; C/ D8 q: F D9 o' O; o
2
3 I) f+ } H& F& R7 _( O' P, p
3
! S- V+ [! c: N
4
# r1 k$ Y5 g$ t1 [
5
0 |$ y+ f1 U r2 D
6
% }6 A5 ^7 A- U* N& n a
7
. z* ^) _: r9 P" f* l: \( t% |' h
8
. c G! q2 U; Y! B
9
( J4 _0 c& F. `# }; X# O3 }
10
* [1 U" R3 S5 g2 p, s) F
11
( G: ^$ Z/ _. q6 o$ N" o- a
12
7 ^9 I( F3 n/ t
13
. O) T6 J* \6 W) M9 ]% G
14
! H" R' M: }1 S: M
15
' p3 J/ C, Y! I# I6 r5 z3 T# M
16
* n/ c7 `3 `1 \3 W/ d/ l# U
17
" G7 ~9 h' g0 O+ I9 ]" _
18
4 v; M" M8 m( w4 I5 G( _) m
19
! W! b. V4 r; j$ R/ s7 ^
20
+ Y& D( {8 ?% \4 U/ |# f w" U' @
21
' w2 z3 h' F. g1 ]# m! v* O
22
% [* ~3 b" h! I9 r
SqueezeNet各层详细参数量及其输入输出如下表所示。
$ E2 X6 [; v3 I' W: K! O2 m6 M
# m1 V0 ?1 t p$ ?
( f' c8 D6 N* Z: _7 k
4.2.6 其他实现细节
. ]5 }4 w5 ?" Y$ p% I; |
1×1和3×3卷积的输出宽和高不同,所以3×3卷积设置1个为0的padding
8 Y! j. R9 g9 l A* ]& }' v4 ?
squeeze和expand层中使用ReLU
! ~ }! j0 D' y% [! _% _5 L% N
在fire9之后的layer中使用ratio为50%的Dropout
/ Q j( X5 H- G3 J- f
参考NiN算法想法,SqueezeNet中不含全连接层
c; G/ ^9 O/ W0 d4 J3 D
训练时,前期学习率设置为0.04,然后线性减少
, l% ]# S; p$ }4 k& B
4.2.7 总结
* P0 D: S& |7 V. }7 r' Q- {
本文最主要就是三点:
' U5 D$ F: n4 @: N' e: b- w
5 S* f8 u5 r& w5 S5 M! H
用1×1卷积代替部分3×3卷积,输出两种卷积级联的结果
2 c- d. l6 A# ?. L2 b8 O
减少输入到3×3卷积的特征图的通道数,减少参数量
3 q3 t4 K; v3 @& q. x! c8 ~7 d
不过早的使用pool,在网络结构后期再使用pool,这样能提高分类准确率
+ t a2 E* @2 c: H6 P
————————————————
' ^7 Z! f" U: q- o7 b5 Q% U
版权声明:本文为CSDN博主「Mr.小梅」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
( U/ F( R$ ?: \( k% D% k
原文链接:https://blog.csdn.net/qq_39707285/article/details/126498100
/ N# ~& z2 Z I/ W: f( C
' A- x# i# V6 f: S. N7 A
- k) {8 c& g3 j$ N5 e& ?4 u
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5