Inception-V3

Inception-V3

背景介绍

  Inception-V3:谷歌公司2015年提出,初始版本是GoogleNet,是2014年ILSVRC竞赛的第一名,是一个较为复杂的图像特征提取模型。

Inception_V3

Inception-V3特点

  采用不同大小的卷积核,意味着不同大小的感受野,得到不同尺度的特征,最后将不同尺度的特征进行拼接融合
  提出卷积分解思想,将一个5x5的卷积,分解为两个3x3的卷积,而且将3x3的卷积分解成一个1x3的卷积和一个3*1的卷积

Spatial Separable Convolution

spatial
  Spatial Separable Convolution(空间可分离卷积):将3x3的卷积分解为3x1的卷积核1x3的卷积,将7x7的卷积分解为7x1的卷积核1x7的卷积.。
  主要作用是
大大降低网络的参数量
。如果一个64x64x256的特征图,经过7x7的卷积核后变为64x64x256的图像,经过普通卷积的参数量为256x(256x7x7+1)=3211520,而空间可分离卷积参数量为2x256x(256x7x1+1)=918016,参数量缩小了约3.5倍。

Inception-V3图像分析

Inception-V3网络结构较大,建议小伙伴们保存到本地放大观看。
Inception_V3

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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_Relu(keras.layers.Layer):
def __init__(self, filters, kernel_size, strides, padding, name):
super(Conv_Bn_Relu, self).__init__()
self._name = name
self.conv = keras.layers.Conv2D(filters, kernel_size, strides, padding)
self.bn = keras.layers.BatchNormalization()
self.relu = keras.layers.ReLU()

def call(self, inputs, **kwargs):
conv = self.conv(inputs)
bn = self.bn(conv)
output = self.relu(bn)

return output


def reduction_A(x, name):
x_1 = compose(keras.layers.MaxPooling2D((3, 3), (2, 2), name='{}_part1_maxpool'.format(name)))(x)

x_2 = compose(Conv_Bn_Relu(64, (1, 1), (1, 1), padding='same', name='{}_part2_conv_bn_relu1'.format(name)),
Conv_Bn_Relu(96, (3, 3), (1, 1), padding='same', name='{}_part2_conv_bn_relu2'.format(name)),
Conv_Bn_Relu(96, (3, 3), (2, 2), padding='valid', name='{}_part2_conv_bn_relu3'.format(name)))(x)

x_3 = compose(Conv_Bn_Relu(384, (3, 3), (2, 2), padding='valid', name='{}_part3_conv_bn_relu1'.format(name)))(x)

x = keras.layers.Concatenate(name='{}_concatenate'.format(name))([x_1, x_2, x_3])

return x


def reduction_B(x, name):
x_1 = compose(keras.layers.MaxPooling2D((3, 3), (2, 2), name='{}_part1_maxpool'.format(name)))(x)

x_2 = compose(Conv_Bn_Relu(192, (1, 1), (1, 1), padding='same', name='{}_part2_conv_bn_relu1'.format(name)),
Conv_Bn_Relu(192, (1, 7), (1, 1), padding='same', name='{}_part2_conv_bn_relu2'.format(name)),
Conv_Bn_Relu(192, (7, 1), (1, 1), padding='same', name='{}_part2_conv_bn_relu3'.format(name)),
Conv_Bn_Relu(192, (3, 3), (2, 2), padding='valid', name='{}_part2_conv_bn_relu4'.format(name)))(x)

x_3 = compose(Conv_Bn_Relu(192, (1, 1), (1, 1), padding='same', name='{}_part3_conv_bn_relu1'.format(name)),
Conv_Bn_Relu(320, (3, 3), (2, 2), padding='valid', name='{}_part3_conv_bn_relu2'.format(name)))(x)

x = keras.layers.Concatenate(name='{}_concatenate'.format(name))([x_1, x_2, x_3])

return x


def inception_A(x, filters, name):
x_1 = compose(keras.layers.AveragePooling2D((3, 3), (1, 1), padding='same', name='{}_averagepool'.format(name)),
Conv_Bn_Relu(filters, (1, 1), (1, 1), padding='same', name='{}_part1_conv_bn_relu1'.format(name)))(x)

x_2 = compose(Conv_Bn_Relu(64, (1, 1), (1, 1), padding='same', name='{}_part2_conv_bn_relu1'.format(name)),
Conv_Bn_Relu(96, (3, 3), (1, 1), padding='same', name='{}_part2_conv_bn_relu2'.format(name)),
Conv_Bn_Relu(96, (3, 3), (1, 1), padding='same', name='{}_part2_conv_bn_relu3'.format(name)))(x)

x_3 = compose(Conv_Bn_Relu(48, (1, 1), (1, 1), padding='same', name='{}_part3_conv_bn_relu1'.format(name)),
Conv_Bn_Relu(64, (5, 5), (1, 1), padding='same', name='{}_part3_conv_bn_relu2'.format(name)))(x)

x_4 = compose(Conv_Bn_Relu(64, (1, 1), (1, 1), padding='same', name='{}_part4_conv_bn_relu1'.format(name)))(x)

x = keras.layers.Concatenate(name='{}_concatenate'.format(name))([x_1, x_2, x_3, x_4])

return x


def inception_B(x, name):
x_1 = compose(keras.layers.AveragePooling2D((3, 3), (1, 1), padding='same', name='{}_averagepool'.format(name)),
Conv_Bn_Relu(192, (1, 1), (1, 1), padding='same', name='{}_part1_conv_bn_relu1'.format(name)))(x)

x_2 = compose(Conv_Bn_Relu(128, (1, 1), (1, 1), padding='same', name='{}_part2_conv_bn_relu1'.format(name)),
Conv_Bn_Relu(128, (1, 7), (1, 1), padding='same', name='{}_part2_conv_bn_relu2'.format(name)),
Conv_Bn_Relu(128, (7, 1), (1, 1), padding='same', name='{}_part2_conv_bn_relu3'.format(name)),
Conv_Bn_Relu(128, (1, 7), (1, 1), padding='same', name='{}_part2_conv_bn_relu4'.format(name)),
Conv_Bn_Relu(192, (7, 1), (1, 1), padding='same', name='{}_part2_conv_bn_relu5'.format(name)))(x)

x_3 = compose(Conv_Bn_Relu(128, (1, 1), (1, 1), padding='same', name='{}_part3_conv_bn_relu1'.format(name)),
Conv_Bn_Relu(128, (1, 7), (1, 1), padding='same', name='{}_part3_conv_bn_relu2'.format(name)),
Conv_Bn_Relu(192, (7, 1), (1, 1), padding='same', name='{}_part3_conv_bn_relu3'.format(name)))(x)

x_4 = compose(Conv_Bn_Relu(192, (1, 1), (1, 1), padding='same', name='{}_part4_conv_bn_relu1'.format(name)))(x)

x = keras.layers.Concatenate(name='{}_concatenate'.format(name))([x_1, x_2, x_3, x_4])

return x


def inception_C(x, name):
x_1 = compose(keras.layers.AveragePooling2D((3, 3), (1, 1), padding='same', name='{}_averagepool'.format(name)),
Conv_Bn_Relu(192, (1, 1), (1, 1), padding='same', name='{}_part1_conv_bn_relu1'.format(name)))(x)

x_2 = compose(Conv_Bn_Relu(448, (1, 1), (1, 1), padding='same', name='{}_part2_conv_bn_relu1'.format(name)),
Conv_Bn_Relu(384, (3, 3), (1, 1), padding='same', name='{}_part2_conv_bn_relu2'.format(name)))(x)

x_2_1 = compose(Conv_Bn_Relu(384, (1, 3), (1, 1), padding='same', name='{}_part2_1_conv_bn_relu1'.format(name)))(x_2)

x_2_2 = compose(Conv_Bn_Relu(384, (3, 1), (1, 1), padding='same', name='{}_part2_2_conv_bn_relu1'.format(name)))(x_2)

x_2 = keras.layers.Concatenate(name='{}_concatenate_2'.format(name))([x_2_1, x_2_2])

x_3 = compose(Conv_Bn_Relu(384, (1, 1), (1, 1), padding='same', name='{}_part3_conv_bn_relu1'.format(name)))(x)

x_3_1 = compose(Conv_Bn_Relu(384, (1, 3), (1, 1), padding='same', name='{}_part3_1_conv_bn_relu1'.format(name)))(x_3)

x_3_2 = compose(Conv_Bn_Relu(384, (3, 1), (1, 1), padding='same', name='{}_part3_2_conv_bn_relu1'.format(name)))(x_3)

x_3 = keras.layers.Concatenate(name='{}_concatenate_3'.format(name))([x_3_1, x_3_2])

x_4 = compose(Conv_Bn_Relu(320, (1, 1), (1, 1), padding='same', name='{}_part4_conv_bn_relu1'.format(name)))(x)

x = keras.layers.Concatenate(name='{}_concatenate'.format(name))([x_1, x_2, x_3, x_4])

return x


def inception_v3(input_shape):
input_tensor = keras.layers.Input(input_shape, name='input')
x = input_tensor
x = compose(Conv_Bn_Relu(32, (3, 3), (2, 2), padding='valid', name='conv_bn_relu1'),
Conv_Bn_Relu(32, (3, 3), (1, 1), padding='valid', name='conv_bn_relu2'),
Conv_Bn_Relu(64, (3, 3), (1, 1), padding='same', name='conv_bn_relu3'),
keras.layers.MaxPool2D((3, 3), (2, 2), name='maxpool1'),
Conv_Bn_Relu(80, (1, 1), (1, 1), padding='same', name='conv_bn_relu4'),
Conv_Bn_Relu(192, (3, 3), (1, 1), padding='valid', name='conv_bn_relu5'),
keras.layers.MaxPool2D((3, 3), (2, 2), name='maxpool2'))(x)
inception_A_part1_filters = [32, 64, 64]
for i in range(3):
x = inception_A(x, inception_A_part1_filters[i], name='inception_A_{}'.format(i + 1))
x = reduction_A(x, name='reduction_A')
for i in range(4):
x = inception_B(x, name='inception_B_{}'.format(i + 1))
x = reduction_B(x, name='reduction_B')
for i in range(2):
x = inception_C(x, name='inception_C_{}'.format(i + 1))
x = compose(keras.layers.GlobalAveragePooling2D(name='global_averagepool'),
keras.layers.Dense(1000, activation='softmax', name='dense'))(x)

model = keras.Model(input_tensor, x, name='Inception-V3')

return model


if __name__ == '__main__':

model = inception_v3(input_shape=(299, 299, 3))
model.build(input_shape=(None, 299, 299, 3))
model.summary()

Inception_V3

Inception-V3小结

  Inception-V3是一种复杂的深度学习网络,参数量为22M,由于其结构过于复杂,很少被其他网络所使用,但是其不同感受野和卷积分解的思想给其他网络提供了思路

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