CNN经典模型(六)轻量化网络MobileNet 系列

在实际中应用CNN受限于硬件运算能力与存储(比如几乎不可能在ARM芯片上跑ResNet-152)。所以必须有一种能在算法层面有效的压缩存储和计算量的方法。而MobileNet/ShuffleNet正为我们打开这扇窗。

假设有输入feature map,尺寸为HWC,同时有 k个 hw卷积核。对于一般卷积,输出feature map尺寸为H’W’k
而Group convolution的实质就是将convolution分为g个独立的组,分别计算。即:
把input feature分为g组,每组尺寸为 H
W
(C/g) ,假设可整除,下同
把kernel也分为g组,每组尺寸为 h
w*(k/g)
按顺序,每组input feature和kernel分别做普通卷积,输出g组H’W’(k/g) 特征,即一共H’*W’*k

其实Group convolution并不是什么新东西,早在AlexNet就使用了Group convolution,通过在conv2层设置group=2,将整个网络分为了两组。这是由于当时的GTX 580显存太小,没法放下整个网络,所以Alex采用Group convolution将整个网络分成两组后,分别放入一张卡进行训练而已。

MobileNet V1
Mobilenet v1核心是把卷积拆分为Depthwise+Pointwise两部分。

假设有NHWC 的输入,同时有k个 33 的卷积。如果设置pad=1 且 stride=1,那么普通卷积输出为NHW*k。

Depthwise是指将NHWC的输入分为 C 组(每个通道分别卷积),然后每一组做 33 卷积。这样相当于收集了每个Channel的空间特征,即Depthwise特征。

Pointwise是指对 NHWC 的输入做 k 个普通的 11 卷积。这样相当于收集了每个点的特征,即Pointwise特征。Depthwise+Pointwise最终输出也是NHW*k 。

普通卷积:3x3 Conv+BN+ReLU
Mobilenet卷积:3x3 Depthwise Conv+BN+ReLU 和 1x1 Pointwise Conv+BN+ReLU

from tensorflow.keras.layers import Input, DepthwiseConv2D, \
     Conv2D, BatchNormalization, ReLU, AvgPool2D, Flatten, Dense

#Mobilenet卷积:3x3 Depthwise Conv+BN+ReLU 和 1x1 Pointwise Conv+BN+ReLU
def mobilenet_block(x, filters, strides):
    x = DepthwiseConv2D(kernel_size=3, strides=strides, padding='same')(x)
    x = BatchNormalization()(x)
    x = ReLU()(x)

    x = Conv2D(filters=filters, kernel_size=1, strides=1, padding='same')(x)
    x = BatchNormalization()(x)
    x = ReLU()(x)
    return x

INPUT_SHAPE = 224, 224, 3

input = Input(INPUT_SHAPE)
x = Conv2D(filters=32, kernel_size=3, strides=2, padding='same')(input)
x = BatchNormalization()(x)
x = ReLU()(x)

x = mobilenet_block(x, filters=64, strides=1)
x = mobilenet_block(x, filters=128, strides=2)
x = mobilenet_block(x, filters=128, strides=1)

x = mobilenet_block(x, filters=256, strides=2)
x = mobilenet_block(x, filters=256, strides=1)
x = mobilenet_block(x, filters=512, strides=2)

for _ in range(5):
    x = mobilenet_block(x, filters=512, strides=1)
  
x = mobilenet_block(x, filters=1024, strides=2)
x = mobilenet_block(x, filters=1024, strides=1)

x = AvgPool2D(pool_size=7, strides=1)(x)
output = Dense(units=1000, activation='softmax')(x)

from tensorflow.keras import Model

model = Model(inputs=input, outputs=output)

MobileNet V2
1、主要改进点
(1)引入残差结构,先升维再降维,增强梯度的传播,显著减少推理期间所需的内存占用(Inverted Residuals)
(2)去掉 Narrow layer(low dimension or depth) 后的 ReLU,保留特征多样性,增强网络的表达能力(Linear Bottlenecks)
(3)网络为全卷积的,使得模型可以适应不同尺寸的图像;使用 RELU6(最高输出为 6)激活函数,使得模型在低精度计算下具有更强的鲁棒性
(4)MobileNetV2 building block 如下所示,若需要下采样,可在 DWise 时采用步长为 2 的卷积;小网络使用小的扩张系数(expansion factor),大网络使用大一点的扩张系数(expansion factor),推荐是5~10,论文中 t=6 t = 6t=6

你可能感兴趣的:(深度学习)