MobileNet v1 v2 v3 网络详解笔记

学习视频来自:

7.1 MobileNet网络详解_哔哩哔哩_bilibili

在移动端部署深度卷积网络,无论什么视觉任务,选择高精度的计算量少和参数少的骨干网是必经之路。轻量化网络是移动端的研究重点。

MobileNet_v1

传统卷积神经网络,内存需求大、运算量大 导致无法在移动设备以及嵌入式设备上运行

MobileNet网络是由google团队在2017年提出的,专注于移动端或者嵌入 式设备中的轻量级CNN网络。相比传统卷积神经网络,在准确率小幅降 低的前提下大大减少模型参数与运算量。(相比VGG16准确率减少了0.9%, 但模型参数只有VGG的1/32)

论文:

 网络的亮点:

  • Depthwise Convolution(大大减少运算量和参数数量) 
  • 增加超参数α、β

一、卷积

传统卷积:

  • 卷积核channel=输入特征矩阵channel
  • 输出特征矩阵channel=卷积核个数

DW卷积—Depthwise  Conv:

  •  卷积核channel=1
  •  输入特征矩阵channel=卷积核个数=输出特 征矩阵channel

Depthwise Separable Conv:由 DW 卷积和 PW 卷积组成

Pointwise Conv:

  • 就是普通的卷积,只不过卷积核大小为 1 
  • 卷积核channel=输入特征矩阵channel
  • 输出特征矩阵channel=卷积核个数

 理解:常规的卷积(标准卷积)是把每一个卷积核作用在输入图像的所有通道,并将他们整合在一起,形成一个通道输出。

二、使用Depthwise Separable Conv比普通卷积到底能节省多少参数

如下图所示,普通卷积和深度可分卷积最后同样得到深度为4的特征矩阵

 

 D_{F} :输入特征矩阵的高和宽

 D_{K}: 卷积核的大小

 M :   输入特征矩阵的深度

 N :    输出特征矩阵的深度,对应卷积核的个数

普通卷积: D_{K} ·  D_{K}  ·  M  ·  N  ·  D_{F}  ·  D_{F}

这个公式的理解是: 前面四个是计算出参数的个数,后面两个DF是每个参数要参与计算的次数,得出来计算量

DW+PW:    D_{K} ·  D_{K} ·  M   ·  D_{F}  ·  D_{F}  +   M  ·  N  ·  D_{F}  ·  D_{F}

理论上普通卷积计算量是 DW + PW 的8到9倍 

三、MobileNet

和vgg网络比较相似,是大量卷积核的堆叠组成

 Multiply-Add 计算量

 超参数  \large \alpha  Width Multiplie   \large \beta  Resolution Multiplier

 正确率小幅度的下降换来计算量的大幅度减少

缺点:depthwise部分的卷积核容易费掉,即卷积核参数大部分为零。

MobileNet_v2

MobileNet v2网络是由google团队在2018年提出的,相比MobileNet V1网 络,准确率更高,模型更小

论文:

网络中的亮点:

  • Inverted Residuals(倒残差结构)
  • Linear Bottlenecks

一、倒残差结构

 1. 左侧为ResNet网络提供的残差结构:对于输入特征矩阵,采用1 *  1 的卷积核对输入特征矩阵进行压缩,也就是减少输入特征矩阵的channel,再通过3 * 3 的卷积核进行卷积处理,最后采用     1 * 1的卷积核对channel进行扩充,就形成了两头大,中间小的一个瓶颈结构。

        使用的激活函数为Relu

2. 右侧为MobileNet_v2 结构的倒残差结构,首先采用1 * 1 的卷积核进行升维操作,将channel便的更深,在通过卷积核大小为3 * 3 的 DW 操作进行卷积,最后通过1 * 1的卷积进行降维处理。

        使用的激活函数是Relu6

Relu6

 下图为Relu函数,小于0时置零,大于0不做处理

下图为 Relu6 激活函数,小于0时置零,在0-6这个区间同样不做处理,当输入值大于6时就将输入值全部置为6

二、Linear Bottlenecks

在原文中,针对倒残差结构的最后一个1 * 1 的卷积层,使用了线性的激活函数,而不是之前所说的 Relu 激活函数,为什么这样做,原文做了一个实验:

 首先输入是一个二维矩阵,它的channel等于1;

        采用不同维度的矩阵matrix T 将它进行变换,把它变到更高的维度;

        在使用一个Relu激活函数得到一个输出值;

        在使用 T 矩阵的逆矩阵  \large T^{-1},将输出矩阵还原回二维的特征矩阵;

        当matrix T =2,3 的时候,如上图2,3,可以发现,此时丢失了很多信息;

        当matrix T 不断变大时,丢失的信息越来越少了。

结论:ReLU激活函数对低维特征信息照 成大量损失,对高维特征信息造成的损失很少。因为倒残差结构是两边细,中间粗的结构,所以输出时是低维的特征向量,所以要使用一个线性的激活函数替代relu函数来避免信息损失。

三、论文中的结构图

 对应下图中的结构信息

第一层:h,w,k分别为高宽和深度,1 * 1的卷积核进行升维处理,t 为扩展因子,1 * 1的卷积个数等于tk,所以输出特征矩阵的深度为tk;

第二层:输入为上一层的输出,3 * 3大小的DW卷积核,步距为s,输出特征矩阵的深度和输入特征矩阵的深度是一样的,由于步距为s,所以高和宽变为原来的s分之一倍;

第三层:1 *1 的卷积层进行降维,卷积核个数为k’,将特征矩阵的深度由tk变为k‘

 当stride=1且输入特征矩阵与输出特征矩阵shape相同时才有shortcut连接,不满足这个条件时都是没有shortcut连接的。

网络结构的参数: 

 t 为扩展因子

c为输出特征矩阵的channel,为前文中的k’

n代表bottleneck重复的次数,bottleneck其实就是论文中的倒残差结构

s是步距(针对第一层,其他层为1)

性能对比:

Classification 

 Object Detection

MobileNet_v3

论文: 

改进:

  • 更新Block(bneck)
  • 使用NAS搜索参数 (Neural Architecture Search)
  • 重新设计耗时层结构

由下图可以看出,v3 更准确,更高效

一、更新Block(bneck)

1.加入SE模块(注意力机制)

2.更新了激活函数 

当stride == 1且 input_c == output_c 才有shortcut连接 

 Mobilenet V3 的注意力机制如图黄色部分所示​​​​​​

        对得到的特征矩阵的每个channel进行池化处理, 特征矩阵的channel有多少,得到的一维向量就有多少个元素,再通过两个全连接层得到输出的向量;

        第一个全连接层的节点个数就等于特征矩阵channel的1/4,第二个全连接层的节点个数和特征矩阵的channel个数保持一致;

        输出的向量就是对每一个channel分析出一个权重关系,它认为比较重要的channel就赋予更大的权重,它认为不是很重要的channel就赋予小的权重。

用下面的图加深理解 

假设特征矩阵的channel等于2;

首先采用平均池化操作求每个channel的平均值,得到元素个数为2的一个向量;

再依次经过两个全连接层:

        FC1的节点个数是特征矩阵channel的1/4,使用的是Relu激活函数

        FC2的节点个数和特征矩阵的channel保持一致,使用的是H-sig激活函数

得到有两个元素的向量,对应每个channel的权重,用第一个权重0.5和第一个channel中的所有元素相乘,得到一个新的channel数据

注意:最后1*1的降维卷积层没有使用激活函数

二、重新设计耗时层结构

1.减少第一个卷积层的卷积核个数(32->16)

2.精简Last Stage

原文中说用更少的卷积核个数可以达到一样的准确率 

Efficient Last Stage 和上面比起来明显少了很多结构,调整之后再准确率上是没有变化的,但节省了7ms的时间

三、重新设计激活函数 

使用swish确实可以提高网络的准确率,但是计算、求导复杂, 对量化过程不友好,特别是对移动端设备非常不友好,所以作者提出了h-swish激活函数,但需要先看h-sigmoid激活函数;

如图 h-sigmoid 和 sigmoid 函数比较接近,所以再很多场合就用 h-sigmoid 替代了sigmoid

所以就从h-sigmoid替代 \large \sigma (x) 函数,得到 h-swish 激活函数;

如图swish和h-swish曲线非常相似,替换后再速度上是有一定帮助的,对于量化过程也非常友好。

 四、网络结构

 out:输出特征矩阵的channel,降维后对应的channel;

 NL :激活函数,分为两种;

 s : 步距;

exp size:升维的卷积,给的值是多少,就利用1 * 1的卷积升维;

SE:代表是否使用注意力机制;

NBN:表示不适用BN结构

注意:第一个bneck和输入特征矩阵的channel是一样的,并没有升维,所以在第一个bneck中是没有第一个1 * 1的卷积层的,直接对特征矩阵进行DW操作的

猜你喜欢

转载自blog.csdn.net/weixin_45897172/article/details/128482645