MobileNet-V2

MobileNet-V2

背景介绍

  MobileNet-V2:是MobileNet的升级版本,Google公司于2018年提出,是一个结构简单,参数量较少的轻量级深度学习网络模型。

MobileNet_V2

MobileNet-V2特点

  保留MobileNet的SeparableConv深度可分离卷积结构,并且在深度可分离卷积前通过1x1卷积提升通道数。
  引入了反残差结构,借鉴了ResNet的思想,联系了不同尺度的特征
  引入了线性瓶颈结构,在残差相加前不使用ReLU6激活函数,避免破坏特征

Separable Convolution

Xception
  Separable Convolution(深度可分离卷积):是上面两个卷积合二为一的卷积操作。
  第一步:DepthwiseConv,对每一个通道进行卷积
  第二步:PointwiseConv,对第一步得到的结果进行1x1卷积,实现通道融合
  主要作用是
大大降低网络的参数量
,并且可以调整为任意合适的通道数。第一步的目的是减少参数量,第二步是调整通道数,因此将两个卷积操作结合,组成深度可分离卷积。

MobileNet-V2图像分析

MobileNet_V2

TensorFlow2.0实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
from functools import reduce
import tensorflow.keras as keras


def compose(*funcs):
if funcs:
return reduce(lambda f, g: lambda *a, **kw: g(f(*a, **kw)), funcs)
else:
raise ValueError('Composition of empty sequence not supported.')


class Conv_Bn_Relu6(keras.layers.Layer):
def __init__(self, filters, kernel_size, strides, padding, name):
super(Conv_Bn_Relu6, self).__init__()
self._name = name
self.block = keras.Sequential()
if name.find('depthwise') == -1:
self.block.add(keras.layers.Conv2D(filters, kernel_size, strides, padding=padding))
else:
self.block.add(keras.layers.DepthwiseConv2D(kernel_size, strides, padding=padding))
self.block.add(keras.layers.BatchNormalization())
if name.find('relu') != -1:
self.block.add(keras.layers.ReLU(6))

def call(self, inputs, **kwargs):

return self.block(inputs)


def block(x, filters, t, strides, name):
shortcut = x

x = compose(Conv_Bn_Relu6(t * filters, (1, 1), (1, 1), 'same', name='{}_conv_bn_relu6'.format(name)),
Conv_Bn_Relu6(None, (3, 3), strides, 'same', name='{}_depthwiseconv_bn_relu6'.format(name)),
Conv_Bn_Relu6(filters, (1, 1), (1, 1), 'same', name='{}_conv_bn'.format(name)))(x)

if shortcut.shape[-1] == filters and strides == (1, 1):
x = keras.layers.Add(name='{}_add'.format(name))([x, shortcut])

return x


def add_block(x, filters, t, strides, n, name):
x = block(x, filters, t, strides, name='{}_1'.format(name))
for i in range(n - 1):
x = block(x, filters, t, (1, 1), name='{}_{}'.format(name, i + 2))

return x


def mobilenet_v2(input_shape):
input_tensor = keras.layers.Input(input_shape, name='input')
x = input_tensor

x = compose(keras.layers.ZeroPadding2D((1, 1), name='zeropadding'),
Conv_Bn_Relu6(32, (3, 3), (2, 2), 'valid', name='conv1'))(x)

x = add_block(x, 16, 1, (1, 1), 1, 'block1')
x = add_block(x, 24, 6, (2, 2), 2, 'block2')
x = add_block(x, 32, 6, (2, 2), 3, 'block3')
x = add_block(x, 64, 6, (2, 2), 4, 'block4')
x = add_block(x, 96, 6, (1, 1), 3, 'block5')
x = add_block(x, 160, 6, (2, 2), 3, 'block6')
x = add_block(x, 320, 6, (1, 1), 1, 'block7')

x = compose(Conv_Bn_Relu6(1280, (1, 1), (1, 1), 'same', name='conv2'),
keras.layers.GlobalAveragePooling2D(name='global_averagepool'),
keras.layers.Dense(1000, activation='softmax', name='dense'))(x)

model = keras.Model(input_tensor, x, name='MobileNet-V2')

return model


if __name__ == '__main__':

model = mobilenet_v2(input_shape=(224, 224, 3))
model.build(input_shape=(None, 224, 224, 3))
model.summary()

MobileNet_V2

MobileNet-V2小结

  MobileNet-V2是一种高效的轻量级深度学习网络,MobileNet-V2模型的参数量和MobileNet几乎相同,都是4M的参数量,因为其结合了不同尺度的特征,因此效果优于MobileNet。

-------------本文结束感谢您的阅读-------------
0%