1 MobileNet V1
1.1 综述
结构特点:小且高效,应用场景(如移动设备、嵌入式设备)
building small and efficient neural networks.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E1WGJIXj-1582188517692)(http://owv7la1di.bkt.clouddn.com/blog/180129/8hJA2kbHag.png)]
如何解决:
- 通过depthwise separable convolutions替代传统卷积网络,减少计算量。
- 在网络中设置两个参数(width multiplier, resolution multiplier)来平衡准确率与模型大小。
1.2 Depthwise Separable Convolution
1.2.1 问题描述
- Depthwise Separable Convolution与普通卷积的输入与输出均相同,中间过程不同。
- 输入: D F ⋅ D F ⋅ M D_F \cdot D_F \cdot M DF⋅DF⋅M ,其中 D F D_F DF 为原始图片尺寸, M M M 为输入channel数量。
- 输出: D F ⋅ D F ⋅ N D_F \cdot D_F \cdot N DF⋅DF⋅N ,其中 D F D_F DF 为输出图片尺寸, N N N 为输出channel数量。
1.2.2 普通卷积过程
- 卷积核: D K ⋅ D K ⋅ M ⋅ N D_K \cdot D_K \cdot M \cdot N DK⋅DK⋅M⋅N
1.2.3 Depthwise Separable Convolution
整个过程分为两个步骤:depthwise卷积和pointwise卷积。
depthwise卷积:
- 输入: D F ⋅ D F ⋅ M , 输 出 D F ⋅ D F ⋅ M D_F \cdot D_F \cdot M ,输出 D_F \cdot D_F \cdot M DF⋅DF⋅M,输出DF⋅DF⋅M
- 卷积核: M 个 D K ⋅ D K ⋅ 1 ⋅ 1 M个 D_K \cdot D_K \cdot 1 \cdot 1 M个DK⋅DK⋅1⋅1
理解:
- 将输入的每张 D F ⋅ D F ⋅ M D_F \cdot D_F \cdot M DF⋅DF⋅M 的特征图,看成是 M 张 D F ⋅ D F ⋅ 1 D_F \cdot D_F \cdot 1 DF⋅DF⋅1 的特征图。
- 对 M 张 D F ⋅ D F ⋅ 1 D_F \cdot D_F \cdot 1 DF⋅DF⋅1 的特征图分别进行 D K ⋅ D K ⋅ 1 ⋅ 1 D_K \cdot D_K \cdot 1 \cdot 1 DK⋅DK⋅1⋅1 的普通卷积操作。这也就是:对channel进行分解,分别进行普通卷积操作。
pointwise卷积:
- 输入 D F ⋅ D F ⋅ M D_F \cdot D_F \cdot M DF⋅DF⋅M ,输出 D F ⋅ D F ⋅ N D_F \cdot D_F \cdot N DF⋅DF⋅N。
- 卷积核:
1
⋅
1
⋅
M
⋅
N
1 \cdot 1 \cdot M \cdot N
1⋅1⋅M⋅N 。
- 普通的卷积操作。
1.2.4 标准卷积和MobileNet中使用的深度分离卷积结构对比
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xo21J3T4-1582188517694)(http://owv7la1di.bkt.clouddn.com/blog/180129/2djHJ1F1Ld.png)]
1.2.5 普通卷积与Depthwise Separable卷积的计算量比较
-
Depthwise Separable Convolution: D K ⋅ D K ⋅ M ⋅ D F ⋅ D F + M ⋅ N ⋅ D F ⋅ D F D_K \cdot D_K \cdot M \cdot D_F \cdot D_F + M \cdot N \cdot D_F \cdot D_F DK⋅DK⋅M⋅DF⋅DF+M⋅N⋅DF⋅DF(仅计算乘法)
-
普通卷积过程: D K ⋅ D K ⋅ M ⋅ N ⋅ D F ⋅ D F D_K \cdot D_K \cdot M \cdot N \cdot D_F \cdot D_F DK⋅DK⋅M⋅N⋅DF⋅DF(仅计算乘法)
-
分子为Depthwise Separable卷积,分母为普通卷积:
宽度因子 α α α(Width multiplier ),用于控制输入和输出的通道数,即输入通道从M变为αM,输出通道从N变为αN。
1.3 实例
输入为
(
h
=
12
,
w
=
12
,
c
=
4
)
(h=12,w=12,c=4)
(h=12,w=12,c=4),卷积为
3
∗
3
3*3
3∗3,输出为
(
h
=
12
,
w
=
12
,
c
=
2
)
(h=12,w=12,c=2)
(h=12,w=12,c=2)前向计算中,普通卷积的参数量、乘法计算次数如下图所示:
depthwise的参数量、乘法计算次数如下图所示:
可以看到,mobilenet的参数和乘法计算次数明显比普通卷积要小。这还只是在如此小的卷积运算中,在实际网络中,几十层的网络很常见,feature map也是远远大于 12 ∗ 12 ∗ 4 12*12*4 12∗12∗4。一般普通100M的网络模型,将所有卷积替换成mobilenet后,能降到20M以下,计算速度更是不在一个量级。
1.4 MobileNet结构
- MobileNet优化的重点放在优化延迟(latency),兼顾模型大小。
- 网络参数、计算量分布:
- MobileNet中大多数计算量和参数都在1*1的卷积中,可以使用高度优化的。
- 由于模型较小,所以可以减少使用正则化,因为模型小不容易过拟合。
1.5 控制MobileNet模型大小的两个超参数
- Width Multiplier, 宽度因子
α
\alpha
α :
- 该参数用于控制特征图的channel数量,即纬度。
- 对于depthwise卷积操作,其计算量为:
- 可设置 α ∈ ( 0 , 1 ] α∈(0,1] α∈(0,1],通常取1,0.75,0.5和0.25
- 宽度因子将计算量和参数降低了约
α
2
α^2
α2倍,可很方便的控制模型大小.:
D K ⋅ D K ⋅ α M ⋅ D F ⋅ D F + α M ⋅ α N ⋅ D F ⋅ D F D K ⋅ D K ⋅ M ⋅ N ⋅ D F ⋅ D F = α N + α 2 D K 2 \frac{D_K·D_K·\alpha M·D_F·D_F + \alpha M· \alpha N·D_F·D_F }{D_K·D_K·M·N·D_F·D_F}=\frac{\alpha}{N} + \frac{\alpha^2}{D_K^2} DK⋅DK⋅M⋅N⋅DF⋅DFDK⋅DK⋅αM⋅DF⋅DF+αM⋅αN⋅DF⋅DF=Nα+DK2α2
- Resolution Multiplier, 分辨率因子
ρ
\rho
ρ :
- 即用分辨率因子控制输入的分辨率
- 对于depthwise卷积操作,其计算量为:
D K ⋅ D K ⋅ α M ⋅ D F ⋅ D F + α M ⋅ α N ⋅ D F ⋅ D F D_K·D_K·\alpha M·D_F·D_F + \alpha M· \alpha N·D_F·D_F DK⋅DK⋅αM⋅DF⋅DF+αM⋅αN⋅DF⋅DF - 可设置 ρ ∈ ( 0 , 1 ] ρ∈(0,1] ρ∈(0,1],通常设置输入分辨率为224,192,160和128。
- 分辨率因子将计算量和参数降低了约
ρ
2
ρ^2
ρ2倍,可很方便的控制模型大小.
D K ⋅ D K ⋅ α M ⋅ ρ D F ⋅ ρ D F + α M ⋅ α N ⋅ ρ D F ⋅ ρ D F D K ⋅ D K ⋅ M ⋅ N ⋅ D F ⋅ D F = α ρ N + α 2 ρ 2 D K 2 \frac{D_K·D_K·\alpha M·\rho D_F·\rho D_F + \alpha M· \alpha N·\rho D_F·\rho D_F }{D_K·D_K·M·N·D_F·D_F}=\frac{\alpha \rho}{N} + \frac{\alpha^2 \rho^2}{D_K^2} DK⋅DK⋅M⋅N⋅DF⋅DFDK⋅DK⋅αM⋅ρDF⋅ρDF+αM⋅αN⋅ρDF⋅ρDF=Nαρ+DK2α2ρ2
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wpcNBnlH-1582188517698)(http://owv7la1di.bkt.clouddn.com/blog/180129/DLK805LDHJ.png)]
1.6 比较
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lj0GkERv-1582188517699)(http://owv7la1di.bkt.clouddn.com/blog/180129/fb4c76F9j6.png)]
1.7 还存在什么问题?
-
结构问题:
MobileNet1.0 的结构非常简单, 是一个非常复古的直筒结构, 类似于VGG一样。 这种结构的性价比其实不高, 后续一系列的ResNet, DenseNet等结构已经证明通过复用图像特征, 使用concat/eltwise+ 等操作进行融合, 能极大提升网络的性价比。 -
Depthwise Convolution 的潜在问题:
Depthwise Conv确实是大大降低了计算量, 而且性能上也能接近普通卷积。 但在实际使用的时候, 会发生Depthwise 中部分的kernel训练废掉的问题: 训完之后depthwise训出来的kernel有不少是空的。
可能是因为depthwise每个kernel dim 相对于正常conv要小得多, 过小的kernel_dim, 易受到ReLU的影响, 使得神经元输出很容易变为0, 所以就废了。(ReLU对于0的输出的梯度为0, 所以一旦陷入了0输出, 就没法恢复了) 。 我们还发现,这个问题在定点化低精度训练的时候会进一步放大。
用ReLu中 不同的Output/dim比值,对特征的分部空间可视化, 来直观解释特征/神经元退化问题。
2 MobileNet V2
相比于v2 ,v1主要引入了两个改动:Linear Bottleneck 和 Inverted Residual Blocks。
2.1 对比 MobileNet V1 与 V2 的微结构
相同点
- 都采用 Depth-wise (DW) 卷积搭配 Point-wise (PW) 卷积的方式来提特征。这两个操作合起来也被称为 Depth-wise Separable Convolution,优点是理论上可以成倍的减少卷积层的时间复杂度和空间复杂度。由下式可知,因为卷积核的尺寸 K 通常远小于输出通道数 C o u t C_{out} Cout,因此标准卷积的计算复杂度近似为 D W + P W DW + PW DW+PW 组合卷积的 K 2 K^2 K2 倍。
不同点:Linear Bottleneck
-
V2 在 DW 卷积之前新加了一个 PW 卷积。这么做的原因,是因为 DW 卷积由于本身的计算特性决定它自己没有改变通道数的能力,上一层给它多少通道,它就只能输出多少通道。
如果上一层给的通道数本身很少的话,DW 也只能很委屈的在低维空间提特征,这样效果不够好。
现在 V2 为了改善这个问题,给每个 DW 之前都配备了一个 PW,专门用来升维,定义升维系数 t = 6 t = 6 t=6,这样不管输入通道数 C i n C_{in} Cin 是多是少,经过第一个 PW 升维之后,DW 都是在相对的更高维 ( t ⋅ C i n t \cdot C_{in} t⋅Cin ) 进行着辛勤工作的。
-
V2 去掉了第二个 PW 的激活函数,即 Linear Bottleneck。这么做的原因是激活函数在高维空间能够有效的增加非线性,而在低维空间时则会破坏特征,不如线性的效果好。由于第二个 PW 的主要功能就是降维,因此按照上面的理论,降维之后就不宜再使用 ReLU6 了。
2.2 对比 ResNet 与 MobileNet V2 的微结构
相同点
- MobileNet V2 借鉴 ResNet,都采用了 1 × 1 → 3 × 3 → 1 × 1 1 \times 1 \to 3 \times 3 \to 1 \times 1 1×1→3×3→1×1的模式。
- MobileNet V2 借鉴 ResNet,同样使用 Shortcut 将输出与输入相加(未在上图画出)
不同点
- ResNet 使用 标准卷积 提特征,MobileNet 始终使用 DW卷积 提特征。
- ResNet 先降维 (0.25倍)、卷积、再升维,而 MobileNet V2 则是 先升维 (6倍)、卷积、再降维。直观的形象上来看,ResNet 的微结构是沙漏形,而 MobileNet V2 则是纺锤形,刚好相反。因此称为 Inverted Residual Block。这么做也是因为使用DW卷积而作的适配,希望特征提取能够在高维进行。
Inverted Residual Block优点:
- 复用特征
- 旁支block内先通过 1 ∗ 1 1*1 1∗1升维, 再接depthwise conv以及ReLU, 通过增加ReLU的InputDim, 来缓解特征的退化情况.
2.3 整体结构
其中:t表示“扩张”倍数,c表示输出通道数,n表示重复次数,s表示步长stride。
-
两点有误之处:
- 第五行,也就是第7~10个bottleneck,stride=2,分辨率应该从28降低到14;如果不是分辨率出错,那就应该是stride=1;
- 文中提到共计采用19个bottleneck,但是这里只有17个。
-
一个bottleneck由如下三个部分构成:
- 针对stride=1 和stride=2,在block上有稍微不同,主要是为了与shortcut的维度匹配,因此,stride=2时,不采用shortcut。 具体如下图:
- 除了最后的avgpool,整个网络并没有采用pooling进行下采样,而是利用stride=2来下采样,此法已经成为主流。