[轻量化网络] MobileNet V3
1. 前言
google团队MobileNet系列的第三个版本,在论文《Searching for MobileNetV3》中提出。感觉主要在Mnasnet和MobileNetV2上进行改进,主要工作有以下几点:
- 更新V2中的倒残差结构(bneck),重新设计激活函数
- 使用NAS搜索参数
- 重新设计耗时层结构
2. 更新Block和激活函数
2.1. 基本模块
如上图所示是MobilenetV2 的倒残差结构,输入先经过一个1*1卷积进行升维,然后接bn,relu6, dw卷积,然后再接一个3*3的dw卷积,bn,relu6,最后通过一个1*1的卷积进行降维,后接bn,最后再将输入与结果进行相加操作(注意只有dw卷积中的stride=1的时候且输入通道等于输出通道的时候才有shortcut),具体可以看博文《[轻量化网络]MobileNet V2学习笔记》。
如上图是V3的Block,其实就是在v2的基础上增加了通道注意力SE,这里SE模块的缩放因子r为0.25(和Mnasnet一样)。然后替换了激活函数,图中的NL表示非线性激活函数,由于不同的层使用的激活函数不一样,所以统一用这个符号表示。关于SE模块,可以查看博文《[重读经典论文]SENet——ILSVRC收官之作》。
2.2. 激活函数
首先引入一种非线性激活函数swish,用来替代RELU函数,证明可以提高网络性能,公式如下:
其中σ(x)为sigmoid函数:
虽然网络性能提高了,但是计算、求导复杂,而且对量化过程不友好。
于是本文将sigmod函数替换成h-sigmoid激活函数:
代入swish中,替换成h-swish:
替换前后能够对swish进行一个很好的近似,如下图所示:
替换之后,作者发现从部署的角度来看具有多种优势。首先,ReLU6 的优化实现几乎可以在所有软件和硬件框架上使用。其次,在量化模式下,它消除了由近似 sigmoid 的不同实现引起的潜在数值精度损失。最后,在实践中,h-swish 可以实现为分段函数,以减少内存访问次数,从而大幅降低延迟成本。
3. 重新设计耗时层的结构
首先,减少网络第一个卷积层的卷积核个数,从32减到16,无论是使用RELU还是swish激活函数,准确率和原来都是一样的,这一步节省了2毫秒和1000万的乘加次数。
然后,精简了最后的Stage,如下图所示:
图上为原来搜索到的最后阶段的网络结构,图下为人工精简后的结构,删除了多余的卷积层,将延迟较少了7毫秒,将近全部运行时间的11%,并减少了3000万的乘加操作次数,几乎没有损失准确性。
4. 网络结构
V3有针对占用的资源设计了两个网路结构,Large和Small,下面是Large模型:
Input:输入的特征矩阵的形状,如第一层的输入为224^2*3。
#out:该stage输出通道数。
Operator:具体的操作函数,然后
- bneck 3*3:表示是一个bneck模块,然后dw卷积的卷积核大小为3*3.
- NBN:没有接BN层。
exp size:第一个1*1
升维的卷积核个数,也就是输出通道数。(由于第一个bneck的input_channel和exp size的channel的大小一致,所以第一个bneck中没有1*1升维的卷积核)
SE :表示模块中是否存在SE模块。
NL:激活函数,HS 表示 h-swish,RE 表示 ReLU。
s :stride,步长,指的是dw卷积的步长,
另外,和V2类似,bneck中只有Stride=1且input channel=output channel时才有shortcut连接。
5. 参考
(完)