MobileNet v1 & v2

MobileNet是Google推出的一种比较适合在移动设备上使用的小型化网络,具有较少的计算量和较低的带宽延迟。目前已经出到了第二版。本文会首先回顾一下v1的设计思想,然后与v2对比看看有什么升级的地方。

MobileNet v1

Depthwise Separable Convolution

传统的卷积神经网络(如alexnet,vgg等)使用的是标准的卷积层,我们首先计算一下传统的卷积一层的计算量,这里只考虑乘法的计算量:

  • input features: h*w*m
  • filters: k*k*m*n
  • output features: h*w*n
  • compute cost: h*w*k*k*m*n

相较于传统的标准卷积,MobileNet v1提出了一种叫Depthwise Separable Convolution的操作,它实际是把标准的卷积层拆分成了两层,第一层称为depthwise convolution,它实际上是在每一个channel(depth)上单独做卷积,可以理解为在一个平面上做卷积。每个卷积核的大小为k*k*1,一共有m个这样的卷积。对于h*w*m的输入,经过depthwise convolution layer之后,输出的feature map为h*w*m,这一层的计算量为h*w*m*k*k。第二层使用若n个1 *1*m的卷积核进行通道整合,称为pointwise convolution layer。这一层的输出为h*w*n,计算量为h*w*m*n。因此,对于Depthwise Separable Convolution,我们可以得到如下的计算量:

  • input features: h*w*m
  • depthwise filters: k*k*1*m
  • depthwise output: h*w*m
  • pointwise filters: 1*1*m*n
  • pointwise output: h*w*n
  • compute cost: h*w*k*k*m+h*w*m*n

如果我们把Depthwise Separable Convolution的计算量与标准卷积的相除,就可以得到以下的结论: $$\frac{h*w*k*k*m+h*w*m*n}{h*w*k*k*m*n}=\frac{1}{n}+\frac{1}{k^2}$$

论文中k=3,n为卷积核的数量,一般是个比较大的数,这样相比于标准卷积,深度分离的卷积计算量只有前者的1/9。较少的乘法计算量带来的好处就是计算的速度大大提升了。因为在卷积的具体实现时,最终调用的都是general matrix multiply (GEMM) functions。

Width Multiplier: Thinner Models

尽管使用深度分离卷积已经大大地减少了计算量,但是作者还另外引入了两个方法来进一步控制计算量。其中第一个参数为width multiplier,$\alpha \in(0,1]$,它的作用是使网络的每一层变得更“瘦”。原文中,作者对于一个channel为m的输入层,输入的channel为$\alpha m$,输出的channel为$\alpha n$。因此计算量变为$h*w*k*k* \alpha m+h*w*\alpha m*\alpha n$,但是从实际实现的代码来看,depthwise那层使用的是控制量为channel_multiplier,是个取值大于等于1的int型变量,只有pointwise那层才有width multiplier这个变量,所以不知道原文中这里是否是写错了?

Resolution Multiplier

这个比较好理解,就是把输入图片的分辨率进行缩放,$\rho$,这样就使后面每层的计算量都减少了$\rho^2$倍

Experiments

上面的两张表格将MobileNet v1与一些常见的标准卷积网络进行了对比,可以得到以下的几点结论:

  1. 完整版的MobileNet与VGG 16的性能相当,但是后者的参数量和计算量是前者的十几倍
  2. 0.5x的MobileNet与AlexNet的性能相当,但是后者的参数量与计算量也是前者的几十倍
  3. 同样主打轻量级应用的squeezenet,虽然拥有更少的参数量,但是计算量却非常高,因此看一个网络的大小不能单纯的只看网络的参数量

而在目标检测任务上,相比于使用VGG作为backbone,性能还是有一定差距的,不过与Inception v2差不多。

MobileNet v2

v2是Google时隔一年后推出的改进版,主要的变化是引入了一种叫inverted residual structure,下面首先介绍一下这种结构与传统的residual structure的异同。

Inverted Residual with Linear Bottlenecks

Inverted residual的输入为一个低维的压缩表征,首先会经过一个expansion layer将其在高维展开,然后将expand后的高维特征与之前介绍过的轻量级的lightweight depthwise convolution进行卷积,然后再将卷积后的特征重新映射回低维,其中要注意的是这一层卷积之后并没有跟随任何非线性的激活函数,作者将这个称为linear bottlenecks。我们知道,常见的卷积神经网络每个卷积层之后都会跟随一个非线性激活层,如常用的ReLU,那为什么这里最后一层不使用任何激活呢?

我们知道,ReLU会使特征中小于0的部分都变为0,当特征的channel数较低时,会有相对较高的概率导致某些channel被整体置0,而一旦某个channel都被置0,那么一定就会导致所能描述的特征容量的下降。同时也会使反向时梯度变为0,filter也就学不动了。除了理论上的分析证明,文中也用一个小小的例子对这一现象进行了描述,下图最左边是原始的输入特征,之后分别用一个随机矩阵$T$映射到n维空间,然后跟随一个ReLU激活,时候再用$T^-1$映射回原始的输入空间,可以看到当映射的空间维度较低时(如n=2,3,5)时,映射回原空间后信息丢失量比较多,而映射到较高维的空间后(n=15,30),则能保留大部分的特征信息。

这就引出了v2对传统residual structure的第二个改进,即首先会把输入的特征通过1x1的卷积映射到一个高维空间,通过expansion factor $t$进行控制,文中$t=6$,然后在这个高维空间进行depthwise convolution,这样即使使用了RuLU也可以确保大部分信息不丢失,最后再将其映射回输入的低维空间。下图是两种residual structure的对比示意图: 可以看到,传统的residual structure是输入和输出的channel较多,而中间部分的channel较少,而inverted residual structure则刚好相反,两边channe较少,中间的特征channel比较多。

下面这张图则给出了v2与其他几种网络在convolution blocks设计上的区别:

Running time cost

假设block的输入为h x w,expansion factor为t,输入的维度为d’,输出的维度为d”,中间的depthwise convolution filter size为k,那么总的计算量就是:h*w*d’*t*(d’+k*k+d”)。

Memory efficient inference

v2还有一个特点就是其对内存带宽比较友好,在文中的section 5.1作者说到

  • In what follows we show that if we treat a bottleneck residual block as a single operation (and treat inner convolution as a disposable tensor), the total amount of memory would be dominated by the size of bottleneck tensors, rather than the size of tensors that are internal to bottleneck (and much larger).

而v2采用的inverted residual structure在输入和输出的位置维度都比较低,相比于传统的residual structure输入和输出的维度较高,其对带宽的需求明显更少。

Experiments

作者首先对比了v2与其他网络在ImageNet上的表现,可以看出相比于v1,计算的速度更快了,精度也提高了1个多点。 对于不同的shortcut连接还有非线性激活对bottleneck layer的影响,作者分别进行了ablation study,可以看出使用线性激活和较低的维度进行shortcut连接有助于性能的提升。

Conclusions

MobileNet v1使用depthwise convolution+pointwise convolution在达到相近表达能力的情况下大大减少了卷积层的计算量,而v2提出的inverted residual structure则允许我们将网络的表达(通过expansion layers)与网络的容量(通过bottleneck inputs)进行了解耦。总的来说这是两篇非常不错的paper,推荐大家有时间可以再细细的去看一遍原文。


References

  1. MobileNet v1
  2. MobileNet v2
  3. official implement
  4. 知乎讨论