2 """Inception-ResNet V2 model for Keras. 4 Model naming and structure follows TF-slim implementation (which has some additional 5 layers and different number of filters from the original arXiv paper): 6 https://github.com/tensorflow/models/blob/master/research/slim/nets/inception_resnet_v2.py 8 Pre-trained ImageNet weights are also converted from TF-slim, which can be found in: 9 https://github.com/tensorflow/models/tree/master/research/slim#pre-trained-models 12 - [Inception-v4, Inception-ResNet and the Impact of 13 Residual Connections on Learning](https://arxiv.org/abs/1602.07261) 16 from __future__
import absolute_import
17 from __future__
import division
18 from __future__
import print_function
23 from keras.models
import Model
24 from keras.layers
import Activation
25 from keras.layers
import AveragePooling2D
26 from keras.layers
import BatchNormalization
27 from keras.layers
import Concatenate
28 from keras.layers
import Conv2D
29 from keras.layers
import Dense
30 from keras.layers
import GlobalAveragePooling2D
31 from keras.layers
import GlobalMaxPooling2D
32 from keras.layers
import Input
33 from keras.layers
import Lambda
34 from keras.layers
import MaxPooling2D
35 from keras.utils.data_utils
import get_file
36 from keras.engine
import get_source_inputs
39 sys.path.append(
"/home/salonsom/cvn_tensorflow/networks")
42 from imagenet_utils
import _obtain_input_shape
43 from imagenet_utils
import decode_predictions
44 from keras
import backend
as K
47 BASE_WEIGHT_URL =
'https://github.com/fchollet/deep-learning-models/releases/download/v0.7/' 51 """Preprocesses a numpy array encoding a batch of images. 54 x: a 4D numpy array consists of RGB values within [0, 255]. 70 """Utility function to apply conv + BN. 74 filters: filters in `Conv2D`. 75 kernel_size: kernel size as in `Conv2D`. 76 strides: strides in `Conv2D`. 77 padding: padding mode in `Conv2D`. 78 activation: activation in `Conv2D`. 79 use_bias: whether to use a bias in `Conv2D`. 80 name: name of the ops; will become `name + '_ac'` for the activation 81 and `name + '_bn'` for the batch norm layer. 84 Output tensor after applying `Conv2D` and `BatchNormalization`. 93 bn_axis = 1
if K.image_data_format() ==
'channels_first' else 3
94 bn_name =
None if name
is None else name +
'_bn' 95 x = BatchNormalization(axis=bn_axis, scale=
False, name=bn_name)(x)
96 if activation
is not None:
97 ac_name =
None if name
is None else name +
'_ac' 98 x = Activation(activation, name=ac_name)(x)
103 """Adds a Inception-ResNet block. 105 This function builds 3 types of Inception-ResNet blocks mentioned 106 in the paper, controlled by the `block_type` argument (which is the 107 block name used in the official TF-slim implementation): 108 - Inception-ResNet-A: `block_type='block35'` 109 - Inception-ResNet-B: `block_type='block17'` 110 - Inception-ResNet-C: `block_type='block8'` 114 scale: scaling factor to scale the residuals (i.e., the output of 115 passing `x` through an inception module) before adding them 116 to the shortcut branch. Let `r` be the output from the residual branch, 117 the output of this block will be `x + scale * r`. 118 block_type: `'block35'`, `'block17'` or `'block8'`, determines 119 the network structure in the residual branch. 120 block_idx: an `int` used for generating layer names. The Inception-ResNet blocks 121 are repeated many times in this network. We use `block_idx` to identify 122 each of the repetitions. For example, the first Inception-ResNet-A block 123 will have `block_type='block35', block_idx=0`, ane the layer names will have 124 a common prefix `'block35_0'`. 125 activation: activation function to use at the end of the block 126 (see [activations](../activations.md)). 127 When `activation=None`, no activation is applied 128 (i.e., "linear" activation: `a(x) = x`). 131 Output tensor for the block. 134 ValueError: if `block_type` is not one of `'block35'`, 135 `'block17'` or `'block8'`. 137 if block_type ==
'block35':
144 branches = [branch_0, branch_1, branch_2]
145 elif block_type ==
'block17':
148 branch_1 =
conv2d_bn(branch_1, 160, [1, 7])
149 branch_1 =
conv2d_bn(branch_1, 192, [7, 1])
150 branches = [branch_0, branch_1]
151 elif block_type ==
'block8':
154 branch_1 =
conv2d_bn(branch_1, 224, [1, 3])
155 branch_1 =
conv2d_bn(branch_1, 256, [3, 1])
156 branches = [branch_0, branch_1]
158 raise ValueError(
'Unknown Inception-ResNet block type. ' 159 'Expects "block35", "block17" or "block8", ' 160 'but got: ' +
str(block_type))
162 block_name = block_type +
'_' +
str(block_idx)
163 channel_axis = 1
if K.image_data_format() ==
'channels_first' else 3
164 mixed = Concatenate(axis=channel_axis, name=block_name +
'_mixed')(branches)
166 K.int_shape(x)[channel_axis],
170 name=block_name +
'_conv')
172 x = Lambda(
lambda inputs, scale: inputs[0] + inputs[1] * scale,
173 output_shape=K.int_shape(x)[1:],
174 arguments={
'scale': scale},
175 name=block_name)([x, up])
176 if activation
is not None:
177 x = Activation(activation, name=block_name +
'_ac')(x)
187 """Instantiates the Inception-ResNet v2 architecture. 189 Optionally loads weights pre-trained on ImageNet. 190 Note that when using TensorFlow, for best performance you should 191 set `"image_data_format": "channels_last"` in your Keras config 192 at `~/.keras/keras.json`. 194 The model and the weights are compatible with TensorFlow, Theano and 195 CNTK backends. The data format convention used by the model is 196 the one specified in your Keras config file. 198 Note that the default input image size for this model is 299x299, instead 199 of 224x224 as in the VGG16 and ResNet models. Also, the input preprocessing 200 function is different (i.e., do not use `imagenet_utils.preprocess_input()` 201 with this model. Use `preprocess_input()` defined in this module instead). 204 include_top: whether to include the fully-connected 205 layer at the top of the network. 206 weights: one of `None` (random initialization), 207 'imagenet' (pre-training on ImageNet), 208 or the path to the weights file to be loaded. 209 input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) 210 to use as image input for the model. 211 input_shape: optional shape tuple, only to be specified 212 if `include_top` is `False` (otherwise the input shape 213 has to be `(299, 299, 3)` (with `'channels_last'` data format) 214 or `(3, 299, 299)` (with `'channels_first'` data format). 215 It should have exactly 3 inputs channels, 216 and width and height should be no smaller than 139. 217 E.g. `(150, 150, 3)` would be one valid value. 218 pooling: Optional pooling mode for feature extraction 219 when `include_top` is `False`. 220 - `None` means that the output of the model will be 221 the 4D tensor output of the last convolutional layer. 222 - `'avg'` means that global average pooling 223 will be applied to the output of the 224 last convolutional layer, and thus 225 the output of the model will be a 2D tensor. 226 - `'max'` means that global max pooling will be applied. 227 classes: optional number of classes to classify images 228 into, only to be specified if `include_top` is `True`, and 229 if no `weights` argument is specified. 232 A Keras `Model` instance. 235 ValueError: in case of invalid argument for `weights`, 236 or invalid input shape. 238 if not (weights
in {
'imagenet',
None}
or os.path.exists(weights)):
239 raise ValueError(
'The `weights` argument should be either ' 240 '`None` (random initialization), `imagenet` ' 241 '(pre-training on ImageNet), ' 242 'or the path to the weights file to be loaded.')
244 if weights ==
'imagenet' and include_top
and classes != 1000:
245 raise ValueError(
'If using `weights` as imagenet with `include_top`' 246 ' as true, `classes` should be 1000')
253 data_format=K.image_data_format(),
254 require_flatten=
False,
257 if input_tensor
is None:
258 img_input = Input(shape=input_shape)
260 if not K.is_keras_tensor(input_tensor):
261 img_input = Input(tensor=input_tensor, shape=input_shape)
263 img_input = input_tensor
266 x =
conv2d_bn(img_input, 32, 3, strides=2, padding=
'valid')
269 x = MaxPooling2D(3, strides=2)(x)
271 x =
conv2d_bn(x, 192, 3, padding=
'valid')
272 x = MaxPooling2D(3, strides=2)(x)
281 branch_pool = AveragePooling2D(3, strides=1, padding=
'same')(x)
282 branch_pool =
conv2d_bn(branch_pool, 64, 1)
283 branches = [branch_0, branch_1, branch_2, branch_pool]
284 channel_axis = 1
if K.image_data_format() ==
'channels_first' else 3
285 x = Concatenate(axis=channel_axis, name=
'mixed_5b')(branches)
288 for block_idx
in range(1, 11):
291 block_type=
'block35',
295 branch_0 =
conv2d_bn(x, 384, 3, strides=2, padding=
'valid')
298 branch_1 =
conv2d_bn(branch_1, 384, 3, strides=2, padding=
'valid')
299 branch_pool = MaxPooling2D(3, strides=2, padding=
'valid')(x)
300 branches = [branch_0, branch_1, branch_pool]
301 x = Concatenate(axis=channel_axis, name=
'mixed_6a')(branches)
304 for block_idx
in range(1, 21):
307 block_type=
'block17',
312 branch_0 =
conv2d_bn(branch_0, 384, 3, strides=2, padding=
'valid')
314 branch_1 =
conv2d_bn(branch_1, 288, 3, strides=2, padding=
'valid')
317 branch_2 =
conv2d_bn(branch_2, 320, 3, strides=2, padding=
'valid')
318 branch_pool = MaxPooling2D(3, strides=2, padding=
'valid')(x)
319 branches = [branch_0, branch_1, branch_2, branch_pool]
320 x = Concatenate(axis=channel_axis, name=
'mixed_7a')(branches)
323 for block_idx
in range(1, 10):
335 x =
conv2d_bn(x, 1536, 1, name=
'conv_7b')
339 x = GlobalAveragePooling2D(name=
'avg_pool')(x)
340 x = Dense(classes, activation=
'softmax', name=
'predictions')(x)
343 x = GlobalAveragePooling2D()(x)
344 elif pooling ==
'max':
345 x = GlobalMaxPooling2D()(x)
349 if input_tensor
is not None:
350 inputs = get_source_inputs(input_tensor)
355 model = Model(inputs, x, name=
'inception_resnet_v2')
358 if weights ==
'imagenet':
360 fname =
'inception_resnet_v2_weights_tf_dim_ordering_tf_kernels.h5' 361 weights_path = get_file(fname,
362 BASE_WEIGHT_URL + fname,
363 cache_subdir=
'models',
364 file_hash=
'e693bd0210a403b3192acc6073ad2e96')
366 fname =
'inception_resnet_v2_weights_tf_dim_ordering_tf_kernels_notop.h5' 367 weights_path = get_file(fname,
368 BASE_WEIGHT_URL + fname,
369 cache_subdir=
'models',
370 file_hash=
'd19885ff4a710c122648d3b5c3b684e4')
371 model.load_weights(weights_path)
372 elif weights
is not None:
373 model.load_weights(weights)
def conv2d_bn(x, filters, kernel_size, strides=1, padding='same', activation='relu', use_bias=False, name=None)
def InceptionResNetV2(include_top=True, weights='imagenet', input_tensor=None, input_shape=None, pooling=None, classes=1000)
def _obtain_input_shape(input_shape, default_size, min_size, data_format, require_flatten, weights=None)
def inception_resnet_block(x, scale, block_type, block_idx, activation='relu')
def preprocess_input(x, data_format=None, mode='caffe')