1 """Squeeze and Excite Inception V3 model 3 Major portions of this code is adapted from the applications folder of Keras. 5 Note that the input image format for this model is different than for 6 the VGG16 and ResNet models (299x299 instead of 224x224), 7 and that the input preprocessing function is also different (same as Xception). 10 - [Rethinking the Inception Architecture for Computer Vision](http://arxiv.org/abs/1512.00567) 11 - []() # added when paper is published on Arxiv 14 from __future__
import print_function
15 from __future__
import absolute_import
19 from keras.models
import Model
20 from keras
import layers
21 from keras.layers
import Activation
22 from keras.layers
import Dense
23 from keras.layers
import Reshape
24 from keras.layers
import Input
25 from keras.layers
import BatchNormalization
26 from keras.layers
import Conv2D
27 from keras.layers
import MaxPooling2D
28 from keras.layers
import AveragePooling2D
29 from keras.layers
import GlobalAveragePooling2D
30 from keras.layers
import GlobalMaxPooling2D
31 from keras.layers
import concatenate
32 from keras.engine.topology
import get_source_inputs
33 from keras.utils.data_utils
import get_file
34 from keras
import backend
as K
35 from keras.applications.imagenet_utils
import decode_predictions
36 from keras.applications.imagenet_utils
import _obtain_input_shape
38 from se
import squeeze_excite_block
41 WEIGHTS_PATH_NO_TOP =
'' 51 """Utility function to apply conv + BN. 55 filters: filters in `Conv2D`. 56 num_row: height of the convolution kernel. 57 num_col: width of the convolution kernel. 58 padding: padding mode in `Conv2D`. 59 strides: strides in `Conv2D`. 60 name: name of the ops; will become `name + '_conv'` 61 for the convolution and `name + '_bn'` for the 65 Output tensor after applying `Conv2D` and `BatchNormalization`. 68 bn_name = name +
'_bn' 69 conv_name = name +
'_conv' 73 if K.image_data_format() ==
'channels_first':
78 filters, (num_row, num_col),
83 x = BatchNormalization(axis=bn_axis, scale=
False, name=bn_name)(x)
84 x = Activation(
'relu', name=name)(x)
94 """Instantiates the Squeeze and Excite Inception v3 architecture. 97 include_top: whether to include the fully-connected 98 layer at the top of the network. 99 weights: one of `None` (random initialization) 100 or "imagenet" (pre-training on ImageNet). 101 input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) 102 to use as image input for the model. 103 input_shape: optional shape tuple, only to be specified 104 if `include_top` is False (otherwise the input shape 105 has to be `(299, 299, 3)` (with `channels_last` data format) 106 or `(3, 299, 299)` (with `channels_first` data format). 107 It should have exactly 3 inputs channels, 108 and width and height should be no smaller than 139. 109 E.g. `(150, 150, 3)` would be one valid value. 110 pooling: Optional pooling mode for feature extraction 111 when `include_top` is `False`. 112 - `None` means that the output of the model will be 113 the 4D tensor output of the 114 last convolutional layer. 115 - `avg` means that global average pooling 116 will be applied to the output of the 117 last convolutional layer, and thus 118 the output of the model will be a 2D tensor. 119 - `max` means that global max pooling will 121 classes: optional number of classes to classify images 122 into, only to be specified if `include_top` is True, and 123 if no `weights` argument is specified. 126 A Keras model instance. 129 ValueError: in case of invalid argument for `weights`, 130 or invalid input shape. 132 if weights
not in {
'imagenet',
None}:
133 raise ValueError(
'The `weights` argument should be either ' 134 '`None` (random initialization) or `imagenet` ' 135 '(pre-training on ImageNet).')
137 if weights ==
'imagenet' and include_top
and classes != 1000:
138 raise ValueError(
'If using `weights` as imagenet with `include_top`' 139 ' as true, `classes` should be 1000')
146 data_format=K.image_data_format(),
147 require_flatten=include_top)
149 if input_tensor
is None:
150 img_input = Input(shape=input_shape)
152 if not K.is_keras_tensor(input_tensor):
153 img_input = Input(tensor=input_tensor, shape=input_shape)
155 img_input = input_tensor
157 if K.image_data_format() ==
'channels_first':
162 x =
_conv2d_bn(img_input, 32, 3, 3, strides=(2, 2), padding=
'valid')
165 x = MaxPooling2D((3, 3), strides=(2, 2))(x)
169 x = MaxPooling2D((3, 3), strides=(2, 2))(x)
178 branch3x3dbl =
_conv2d_bn(branch3x3dbl, 96, 3, 3)
179 branch3x3dbl =
_conv2d_bn(branch3x3dbl, 96, 3, 3)
181 branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding=
'same')(x)
182 branch_pool =
_conv2d_bn(branch_pool, 32, 1, 1)
183 x = layers.concatenate(
184 [branch1x1, branch5x5, branch3x3dbl, branch_pool],
198 branch3x3dbl =
_conv2d_bn(branch3x3dbl, 96, 3, 3)
199 branch3x3dbl =
_conv2d_bn(branch3x3dbl, 96, 3, 3)
201 branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding=
'same')(x)
202 branch_pool =
_conv2d_bn(branch_pool, 64, 1, 1)
203 x = layers.concatenate(
204 [branch1x1, branch5x5, branch3x3dbl, branch_pool],
218 branch3x3dbl =
_conv2d_bn(branch3x3dbl, 96, 3, 3)
219 branch3x3dbl =
_conv2d_bn(branch3x3dbl, 96, 3, 3)
221 branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding=
'same')(x)
222 branch_pool =
_conv2d_bn(branch_pool, 64, 1, 1)
223 x = layers.concatenate(
224 [branch1x1, branch5x5, branch3x3dbl, branch_pool],
232 branch3x3 =
_conv2d_bn(x, 384, 3, 3, strides=(2, 2), padding=
'valid')
235 branch3x3dbl =
_conv2d_bn(branch3x3dbl, 96, 3, 3)
237 branch3x3dbl, 96, 3, 3, strides=(2, 2), padding=
'valid')
239 branch_pool = MaxPooling2D((3, 3), strides=(2, 2))(x)
240 x = layers.concatenate(
241 [branch3x3, branch3x3dbl, branch_pool], axis=channel_axis, name=
'mixed3')
254 branch7x7dbl =
_conv2d_bn(branch7x7dbl, 128, 7, 1)
255 branch7x7dbl =
_conv2d_bn(branch7x7dbl, 128, 1, 7)
256 branch7x7dbl =
_conv2d_bn(branch7x7dbl, 128, 7, 1)
257 branch7x7dbl =
_conv2d_bn(branch7x7dbl, 192, 1, 7)
259 branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding=
'same')(x)
260 branch_pool =
_conv2d_bn(branch_pool, 192, 1, 1)
261 x = layers.concatenate(
262 [branch1x1, branch7x7, branch7x7dbl, branch_pool],
278 branch7x7dbl =
_conv2d_bn(branch7x7dbl, 160, 7, 1)
279 branch7x7dbl =
_conv2d_bn(branch7x7dbl, 160, 1, 7)
280 branch7x7dbl =
_conv2d_bn(branch7x7dbl, 160, 7, 1)
281 branch7x7dbl =
_conv2d_bn(branch7x7dbl, 192, 1, 7)
283 branch_pool = AveragePooling2D(
284 (3, 3), strides=(1, 1), padding=
'same')(x)
285 branch_pool =
_conv2d_bn(branch_pool, 192, 1, 1)
286 x = layers.concatenate(
287 [branch1x1, branch7x7, branch7x7dbl, branch_pool],
289 name=
'mixed' +
str(5 + i))
302 branch7x7dbl =
_conv2d_bn(branch7x7dbl, 192, 7, 1)
303 branch7x7dbl =
_conv2d_bn(branch7x7dbl, 192, 1, 7)
304 branch7x7dbl =
_conv2d_bn(branch7x7dbl, 192, 7, 1)
305 branch7x7dbl =
_conv2d_bn(branch7x7dbl, 192, 1, 7)
307 branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding=
'same')(x)
308 branch_pool =
_conv2d_bn(branch_pool, 192, 1, 1)
309 x = layers.concatenate(
310 [branch1x1, branch7x7, branch7x7dbl, branch_pool],
320 strides=(2, 2), padding=
'valid')
323 branch7x7x3 =
_conv2d_bn(branch7x7x3, 192, 1, 7)
324 branch7x7x3 =
_conv2d_bn(branch7x7x3, 192, 7, 1)
326 branch7x7x3, 192, 3, 3, strides=(2, 2), padding=
'valid')
328 branch_pool = MaxPooling2D((3, 3), strides=(2, 2))(x)
329 x = layers.concatenate(
330 [branch3x3, branch7x7x3, branch_pool], axis=channel_axis, name=
'mixed8')
340 branch3x3_1 =
_conv2d_bn(branch3x3, 384, 1, 3)
341 branch3x3_2 =
_conv2d_bn(branch3x3, 384, 3, 1)
342 branch3x3 = layers.concatenate(
343 [branch3x3_1, branch3x3_2], axis=channel_axis, name=
'mixed9_' +
str(i))
346 branch3x3dbl =
_conv2d_bn(branch3x3dbl, 384, 3, 3)
347 branch3x3dbl_1 =
_conv2d_bn(branch3x3dbl, 384, 1, 3)
348 branch3x3dbl_2 =
_conv2d_bn(branch3x3dbl, 384, 3, 1)
349 branch3x3dbl = layers.concatenate(
350 [branch3x3dbl_1, branch3x3dbl_2], axis=channel_axis)
352 branch_pool = AveragePooling2D(
353 (3, 3), strides=(1, 1), padding=
'same')(x)
354 branch_pool =
_conv2d_bn(branch_pool, 192, 1, 1)
355 x = layers.concatenate(
356 [branch1x1, branch3x3, branch3x3dbl, branch_pool],
358 name=
'mixed' +
str(9 + i))
365 x = GlobalAveragePooling2D(name=
'avg_pool')(x)
366 x = Dense(classes, activation=
'softmax', name=
'predictions')(x)
369 x = GlobalAveragePooling2D()(x)
370 elif pooling ==
'max':
371 x = GlobalMaxPooling2D()(x)
375 if input_tensor
is not None:
376 inputs = get_source_inputs(input_tensor)
380 model = Model(inputs, x, name=
'inception_v3')
def squeeze_excite_block(input, ratio=16)
def _obtain_input_shape(input_shape, default_size, min_size, data_format, require_flatten, weights=None)
def _conv2d_bn(x, filters, num_row, num_col, padding='same', strides=(1, 1), name=None)
def SEInceptionV3(include_top=True, weights=None, input_tensor=None, input_shape=None, pooling=None, classes=1000)