def Linknet_bottleneck_crop(backbone_name='vgg16', input_shape=(None, None, 3), classification_classes=1, segmentation_classes=1, classification_activation='sigmoid', segmentation_activation='sigmoid', weights=None, encoder_weights='imagenet', encoder_freeze=False, encoder_features='default', decoder_block_type='upsampling', decoder_filters=(None, None, None, None, 16), decoder_use_batchnorm=True, **kwargs): global backend, layers, models, keras_utils backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if decoder_block_type == 'upsampling': decoder_block = DecoderUpsamplingX2Block elif decoder_block_type == 'transpose': decoder_block = DecoderTransposeX2Block else: raise ValueError( 'Decoder block type should be in ("upsampling", "transpose"). ' 'Got: {}'.format(decoder_block_type)) backbone = Backbones.get_backbone( backbone_name, input_shape=input_shape, weights=encoder_weights, include_top=False, **kwargs, ) if encoder_features == 'default': encoder_features = Backbones.get_feature_layers(backbone_name, n=4) model = build_linknet_bottleneck_crop( backbone=backbone, decoder_block=decoder_block, skip_connection_layers=encoder_features, decoder_filters=decoder_filters, classification_classes=classification_classes, segmentation_classes=segmentation_classes, classification_activation=classification_activation, segmentation_activation=segmentation_activation, n_upsample_blocks=len(decoder_filters), use_batchnorm=decoder_use_batchnorm, ) # lock encoder weights for fine-tuning if encoder_freeze: freeze_model(backbone, **kwargs) # loading model weights if weights is not None: model.load_weights(weights) return model
def _preprocess_numpy_input(x, data_format, **kwargs): """Preprocesses a Numpy array encoding a batch of images changing RGB to BGR. # Arguments x: Input array, 3D or 4D. data_format: Data format of the image array. # Returns Preprocessed Numpy array. """ backend, _, _, _ = get_submodules_from_kwargs(kwargs) if not issubclass(x.dtype.type, np.floating): x = x.astype(backend.floatx(), copy=False) if data_format == 'channels_first': # 'RGB'->'BGR' if x.ndim == 3: x = x[::-1, ...] else: x = x[:, ::-1, ...] else: # 'RGB'->'BGR' x = x[..., ::-1] return x
def freeze_model(model, **kwargs): """Set all layers non trainable, excluding BatchNormalization layers""" _, layers, _, _ = get_submodules_from_kwargs(kwargs) for layer in model.layers: if not isinstance(layer, layers.BatchNormalization): layer.trainable = False return
def __init__(self, filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, use_batchnorm=False, **kwargs): super(Conv2dBn, self).__init__() conv_name, act_name, bn_name = None, None, None block_name = kwargs.pop('name', None) backend, layers, models, keras_utils = get_submodules_from_kwargs( kwargs) if block_name is not None: conv_name = block_name + '_conv' if block_name is not None and activation is not None: act_str = activation.__name__ if callable(activation) else str( activation) act_name = block_name + '_' + act_str if block_name is not None and use_batchnorm: bn_name = block_name + '_bn' bn_axis = 3 if tf.keras.backend.image_data_format( ) == 'channels_last' else 1 self.conv = tf.keras.layers.Conv2D( filters=filters, kernel_size=kernel_size, strides=strides, padding=padding, data_format=data_format, dilation_rate=dilation_rate, activation=None, use_bias=not (use_batchnorm), kernel_initializer=kernel_initializer, bias_initializer=bias_initializer, kernel_regularizer=kernel_regularizer, bias_regularizer=bias_regularizer, activity_regularizer=activity_regularizer, kernel_constraint=kernel_constraint, bias_constraint=bias_constraint, name=conv_name, ) self.batch = tf.keras.layers.BatchNormalization(axis=bn_axis, name=bn_name) self.act = tf.keras.layers.Activation(activation, name=act_name)
def freeze_model(model, fraction=1.0, **kwargs): """Set layers non trainable, excluding BatchNormalization layers. If a fraction is specified, only a fraction of the layers are frozen (starting with the earliest layers)""" _, layers, _, _ = get_submodules_from_kwargs(kwargs) for layer in model.layers[:int(len(model.layers) * fraction)]: if not isinstance(layer, layers.BatchNormalization): layer.trainable = False return
def set_regularization(model, kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, beta_regularizer=None, gamma_regularizer=None, **kwargs): """Set regularizers to all layers Note: Returned model's config is updated correctly Args: model (``keras.models.Model``): instance of keras model kernel_regularizer(``regularizer`): regularizer of kernels bias_regularizer(``regularizer``): regularizer of bias activity_regularizer(``regularizer``): regularizer of activity gamma_regularizer(``regularizer``): regularizer of gamma of BatchNormalization beta_regularizer(``regularizer``): regularizer of beta of BatchNormalization Return: out (``Model``): config updated model """ _, _, models, _ = get_submodules_from_kwargs(kwargs) for layer in model.layers: # set kernel_regularizer if kernel_regularizer is not None and hasattr(layer, 'kernel_regularizer'): layer.kernel_regularizer = kernel_regularizer # set bias_regularizer if bias_regularizer is not None and hasattr(layer, 'bias_regularizer'): layer.bias_regularizer = bias_regularizer # set activity_regularizer if activity_regularizer is not None and hasattr( layer, 'activity_regularizer'): layer.activity_regularizer = activity_regularizer # set beta and gamma of BN layer if beta_regularizer is not None and hasattr(layer, 'beta_regularizer'): layer.beta_regularizer = beta_regularizer if gamma_regularizer is not None and hasattr(layer, 'gamma_regularizer'): layer.gamma_regularizer = gamma_regularizer out = models.model_from_json(model.to_json()) out.set_weights(model.get_weights()) return out
def Cascadenet(backbone_name='resnet34', input_shape=(None, None, 3), classes=1, channel_scale=[1, 1, 1, 1, 1], activation='sigmoid', encoder_weights='imagenet', encoder_freeze=False, encoder_features='default', decoder_use_batchnorm=True, **kwargs): global backend, layers, models, keras_utils backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) backbone = Backbones.get_backbone( backbone_name, input_shape=input_shape, weights=encoder_weights, include_top=False, **kwargs, ) if encoder_features == 'default': encoder_features = Backbones.get_feature_layers(backbone_name, n=4) model = build_cascadenet(backbone, classes, encoder_features, activation=activation, channel_scale=channel_scale, use_batchnorm=decoder_use_batchnorm) # lock encoder weights for fine-tuning if encoder_freeze: freeze_model(backbone) model.name = 'cascadenet-{}'.format(backbone_name) return model
def _preprocess_symbolic_input(x, data_format, **kwargs): """Preprocesses a tensor encoding a batch of images changing RGB to BGR. # Arguments x: Input tensor, 3D or 4D. data_format: Data format of the image tensor. # Returns Preprocessed tensor. """ backend, _, _, _ = get_submodules_from_kwargs(kwargs) if data_format == 'channels_first': # 'RGB'->'BGR' if backend.ndim(x) == 3: x = x[::-1, ...] else: x = x[:, ::-1, ...] else: # 'RGB'->'BGR' x = x[..., ::-1] return x
def MobileNetV2(input_shape=None, alpha=1.0, include_top=True, weights='imagenet', input_tensor=None, pooling=None, classes=1000, output_stride=None, seperate_softmax=True, **kwargs): """Instantiates the MobileNetV2 architecture. # Arguments input_shape: optional shape tuple, to be specified if you would like to use a model with an input img resolution that is not (224, 224, 3). It should have exactly 3 inputs channels (224, 224, 3). You can also omit this option if you would like to infer input_shape from an input_tensor. If you choose to include both input_tensor and input_shape then input_shape will be used if they match, if the shapes do not match then we will throw an error. E.g. `(160, 160, 3)` would be one valid value. alpha: controls the width of the network. This is known as the width multiplier in the MobileNetV2 paper, but the name is kept for consistency with MobileNetV1 in Keras. - If `alpha` < 1.0, proportionally decreases the number of filters in each layer. - If `alpha` > 1.0, proportionally increases the number of filters in each layer. - If `alpha` = 1, default number of filters from the paper are used at each layer. include_top: whether to include the fully-connected layer at the top of the network. weights: one of `None` (random initialization), 'imagenet' (pre-training on ImageNet), or the path to the weights file to be loaded. input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) to use as image input for the model. pooling: Optional pooling mode for feature extraction when `include_top` is `False`. - `None` means that the output of the model will be the 4D tensor output of the last convolutional block. - `avg` means that global average pooling will be applied to the output of the last convolutional block, and thus the output of the model will be a 2D tensor. - `max` means that global max pooling will be applied. classes: optional number of classes to classify images into, only to be specified if `include_top` is True, and if no `weights` argument is specified. output_stride: An integer that specifies the requested ratio of input to output spatial resolution. If not None, then we invoke atrous convolution if necessary to prevent the network from reducing the spatial resolution of the activation maps. Allowed values are 1 or any even number, excluding zero. Typical values are 8 (accurate fully convolutional mode), 16 (fast fully convolutional mode), and 32 (classification mode). NOTE- output_stride relies on all consequent operators to support dilated operators via "rate" parameter. This might require wrapping non-conv operators to operate properly. # Returns A Keras model instance. # Raises ValueError: in case of invalid argument for `weights`, or invalid input shape or invalid alpha, rows when weights='imagenet' """ global backend, layers, models, keras_utils backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if not (weights in {'imagenet', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') if weights == 'imagenet' and include_top and classes != 1000: raise ValueError( 'If using `weights` as `"imagenet"` with `include_top` ' 'as true, `classes` should be 1000') # Determine proper input shape and default size. # If both input_shape and input_tensor are used, they should match if input_shape is not None and input_tensor is not None: try: is_input_t_tensor = backend.is_keras_tensor(input_tensor) except ValueError: try: is_input_t_tensor = backend.is_keras_tensor( keras_utils.get_source_inputs(input_tensor)) except ValueError: raise ValueError('input_tensor: ', input_tensor, 'is not type input_tensor') if is_input_t_tensor: if backend.image_data_format == 'channels_first': if backend.int_shape(input_tensor)[1] != input_shape[1]: raise ValueError( 'input_shape: ', input_shape, 'and input_tensor: ', input_tensor, 'do not meet the same shape requirements') else: if backend.int_shape(input_tensor)[2] != input_shape[1]: raise ValueError( 'input_shape: ', input_shape, 'and input_tensor: ', input_tensor, 'do not meet the same shape requirements') else: raise ValueError('input_tensor specified: ', input_tensor, 'is not a keras tensor') # If input_shape is None, infer shape from input_tensor if input_shape is None and input_tensor is not None: try: backend.is_keras_tensor(input_tensor) except ValueError: raise ValueError('input_tensor: ', input_tensor, 'is type: ', type(input_tensor), 'which is not a valid type') if input_shape is None and not backend.is_keras_tensor(input_tensor): default_size = 224 elif input_shape is None and backend.is_keras_tensor(input_tensor): if backend.image_data_format() == 'channels_first': rows = backend.int_shape(input_tensor)[2] cols = backend.int_shape(input_tensor)[3] else: rows = backend.int_shape(input_tensor)[1] cols = backend.int_shape(input_tensor)[2] if rows == cols and rows in [96, 128, 160, 192, 224]: default_size = rows else: default_size = 224 # If input_shape is None and no input_tensor elif input_shape is None: default_size = 224 # If input_shape is not None, assume default size else: if backend.image_data_format() == 'channels_first': rows = input_shape[1] cols = input_shape[2] else: rows = input_shape[0] cols = input_shape[1] if rows == cols and rows in [96, 128, 160, 192, 224]: default_size = rows else: default_size = 224 input_shape = _obtain_input_shape(input_shape, default_size=default_size, min_size=32, data_format=backend.image_data_format(), require_flatten=include_top, weights=weights) if backend.image_data_format() == 'channels_last': row_axis, col_axis = (0, 1) else: row_axis, col_axis = (1, 2) rows = input_shape[row_axis] cols = input_shape[col_axis] if weights == 'imagenet': if alpha not in [0.35, 0.50, 0.75, 1.0, 1.3, 1.4]: raise ValueError('If imagenet weights are being loaded, ' 'alpha can be one of `0.35`, `0.50`, `0.75`, ' '`1.0`, `1.3` or `1.4` only.') if rows != cols or rows not in [96, 128, 160, 192, 224]: rows = 224 warnings.warn('`input_shape` is undefined or non-square, ' 'or `rows` is not in [96, 128, 160, 192, 224].' ' Weights for input shape (224, 224) will be' ' loaded as the default.') if input_tensor is None: img_input = layers.Input(shape=input_shape) else: if not backend.is_keras_tensor(input_tensor): img_input = layers.Input(tensor=input_tensor, shape=input_shape) else: img_input = input_tensor channel_axis = 1 if backend.image_data_format() == 'channels_first' else -1 first_block_filters = _make_divisible(32 * alpha, 8) x = layers.ZeroPadding2D(padding=correct_pad(backend, img_input, 3), name='Conv_pad')(img_input) x = layers.Conv2D(first_block_filters, kernel_size=3, strides=(2, 2), padding='valid', use_bias=False, name='Conv')(x) x = layers.BatchNormalization(axis=channel_axis, epsilon=1e-3, momentum=0.999, name='Conv_BN')(x) x = layers.ReLU(6., name='Conv_relu')(x) rate = 1 x = _inverted_res_block(x, filters=16, alpha=alpha, stride=1, expansion=1, block_id=0, rate=rate) x = _inverted_res_block(x, filters=24, alpha=alpha, stride=2, expansion=6, block_id=1, rate=rate) x = _inverted_res_block(x, filters=24, alpha=alpha, stride=1, expansion=6, block_id=2, rate=rate) x = _inverted_res_block(x, filters=32, alpha=alpha, stride=2, expansion=6, block_id=3, rate=rate) x = _inverted_res_block(x, filters=32, alpha=alpha, stride=1, expansion=6, block_id=4, rate=rate) x = _inverted_res_block(x, filters=32, alpha=alpha, stride=1, expansion=6, block_id=5, rate=rate) if output_stride == 8 or output_stride == 16: x = _inverted_res_block(x, filters=64, alpha=alpha, stride=1, expansion=6, block_id=6, rate=rate) rate = 2 else: x = _inverted_res_block(x, filters=64, alpha=alpha, stride=2, expansion=6, block_id=6, rate=rate) x = _inverted_res_block(x, filters=64, alpha=alpha, stride=1, expansion=6, block_id=7, rate=rate) x = _inverted_res_block(x, filters=64, alpha=alpha, stride=1, expansion=6, block_id=8, rate=rate) x = _inverted_res_block(x, filters=64, alpha=alpha, stride=1, expansion=6, block_id=9, rate=rate) x = _inverted_res_block(x, filters=96, alpha=alpha, stride=1, expansion=6, block_id=10, rate=rate) x = _inverted_res_block(x, filters=96, alpha=alpha, stride=1, expansion=6, block_id=11, rate=rate) x = _inverted_res_block(x, filters=96, alpha=alpha, stride=1, expansion=6, block_id=12, rate=rate) if output_stride == 8: x = _inverted_res_block(x, filters=160, alpha=alpha, stride=1, expansion=6, block_id=13, rate=rate) rate += 2 else: x = _inverted_res_block(x, filters=160, alpha=alpha, stride=2, expansion=6, block_id=13, rate=rate) x = _inverted_res_block(x, filters=160, alpha=alpha, stride=1, expansion=6, block_id=14, rate=rate) x = _inverted_res_block(x, filters=160, alpha=alpha, stride=1, expansion=6, block_id=15, rate=rate) x = _inverted_res_block(x, filters=320, alpha=alpha, stride=1, expansion=6, block_id=16, rate=rate) # no alpha applied to last conv as stated in the paper: # if the width multiplier is greater than 1 we # increase the number of output channels if alpha > 1.0: last_block_filters = _make_divisible(1280 * alpha, 8) else: last_block_filters = 1280 if not output_stride: x = layers.Conv2D(last_block_filters, kernel_size=1, use_bias=False, name='Conv_1')(x) x = layers.BatchNormalization(axis=channel_axis, epsilon=1e-3, momentum=0.999, name='Conv_1_bn')(x) x = layers.ReLU(6., name='out_relu')(x) if include_top: x = layers.GlobalAveragePooling2D()(x) if seperate_softmax: x = layers.Dense(classes, activation=None, use_bias=True, name='Logits')(x) x = layers.Activation('softmax', name='softmax')(x) else: x = layers.Dense(classes, activation='softmax', use_bias=True, name='Logits')(x) else: if pooling == 'avg': x = layers.GlobalAveragePooling2D()(x) elif pooling == 'max': x = layers.GlobalMaxPooling2D()(x) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = keras_utils.get_source_inputs(input_tensor) else: inputs = img_input # Create model. model = models.Model(inputs, x, name='mobilenetv2_%0.2f_%s' % (alpha, rows)) # Load weights. if weights == 'imagenet': if include_top: model_name = ('mobilenet_v2_weights_tf_dim_ordering_tf_kernels_' + str(alpha) + '_' + str(rows) + '.h5') weight_path = BASE_WEIGHT_PATH + model_name weights_path = keras_utils.get_file(model_name, weight_path, cache_subdir='models') else: model_name = ('mobilenet_v2_weights_tf_dim_ordering_tf_kernels_' + str(alpha) + '_' + str(rows) + '_no_top' + '.h5') weight_path = BASE_WEIGHT_PATH + model_name weights_path = keras_utils.get_file(model_name, weight_path, cache_subdir='models') model.load_weights(weights_path) elif weights is not None: model.load_weights(weights) return model
def Conv2dBn(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, use_batchnorm=False, **kwargs): """Extension of Conv2D layer with batchnorm""" conv_name, act_name, bn_name = None, None, None block_name = kwargs.pop('name', None) backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if block_name is not None: conv_name = block_name + '_conv' if block_name is not None and activation is not None: act_str = activation.__name__ if callable(activation) else str( activation) act_name = block_name + '_' + act_str if block_name is not None and use_batchnorm: bn_name = block_name + '_bn' bn_axis = 3 if backend.image_data_format() == 'channels_last' else 1 def wrapper(input_tensor): x = layers.Conv2D( filters=filters, kernel_size=kernel_size, strides=strides, padding=padding, data_format=data_format, dilation_rate=dilation_rate, activation=None, use_bias=not (use_batchnorm), kernel_initializer=kernel_initializer, bias_initializer=bias_initializer, kernel_regularizer=kernel_regularizer, bias_regularizer=bias_regularizer, activity_regularizer=activity_regularizer, kernel_constraint=kernel_constraint, bias_constraint=bias_constraint, name=conv_name, )(input_tensor) if use_batchnorm: x = layers.BatchNormalization(axis=bn_axis, name=bn_name)(x) if activation: x = layers.Activation(activation, name=act_name)(x) return x return wrapper
def InceptionV3(include_top=True, weights='imagenet', input_tensor=None, input_shape=None, pooling=None, classes=1000, **kwargs): """Instantiates the Inception v3 architecture. Optionally loads weights pre-trained on ImageNet. Note that the data format convention used by the model is the one specified in your Keras config at `~/.keras/keras.json`. # Arguments include_top: whether to include the fully-connected layer at the top of the network. weights: one of `None` (random initialization), 'imagenet' (pre-training on ImageNet), or the path to the weights file to be loaded. input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) to use as image input for the model. input_shape: optional shape tuple, only to be specified if `include_top` is False (otherwise the input shape has to be `(299, 299, 3)` (with `channels_last` data format) or `(3, 299, 299)` (with `channels_first` data format). It should have exactly 3 inputs channels, and width and height should be no smaller than 75. E.g. `(150, 150, 3)` would be one valid value. pooling: Optional pooling mode for feature extraction when `include_top` is `False`. - `None` means that the output of the model will be the 4D tensor output of the last convolutional block. - `avg` means that global average pooling will be applied to the output of the last convolutional block, and thus the output of the model will be a 2D tensor. - `max` means that global max pooling will be applied. classes: optional number of classes to classify images into, only to be specified if `include_top` is True, and if no `weights` argument is specified. # Returns A Keras model instance. # Raises ValueError: in case of invalid argument for `weights`, or invalid input shape. """ global backend, layers, models, keras_utils backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if not (weights in {'imagenet', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') if weights == 'imagenet' and include_top and classes != 1000: raise ValueError( 'If using `weights` as `"imagenet"` with `include_top`' ' as true, `classes` should be 1000') # Determine proper input shape input_shape = imagenet_utils._obtain_input_shape( input_shape, default_size=299, min_size=75, data_format=backend.image_data_format(), require_flatten=include_top, weights=weights) if input_tensor is None: img_input = layers.Input(shape=input_shape) else: if not backend.is_keras_tensor(input_tensor): img_input = layers.Input(tensor=input_tensor, shape=input_shape) else: img_input = input_tensor if backend.image_data_format() == 'channels_first': channel_axis = 1 else: channel_axis = 3 x = conv2d_bn(img_input, 32, 3, 3, strides=(2, 2), padding='same') x = conv2d_bn(x, 32, 3, 3, padding='same') x = conv2d_bn(x, 64, 3, 3, padding='same') x = layers.MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x) x = conv2d_bn(x, 80, 1, 1, padding='same') x = conv2d_bn(x, 192, 3, 3, padding='same') x = layers.MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x) # mixed 0: 35 x 35 x 256 branch1x1 = conv2d_bn(x, 64, 1, 1) branch5x5 = conv2d_bn(x, 48, 1, 1) branch5x5 = conv2d_bn(branch5x5, 64, 5, 5) branch3x3dbl = conv2d_bn(x, 64, 1, 1) branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3) branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3) branch_pool = layers.AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x) branch_pool = conv2d_bn(branch_pool, 32, 1, 1) x = layers.concatenate([branch1x1, branch5x5, branch3x3dbl, branch_pool], axis=channel_axis, name='mixed0') # mixed 1: 35 x 35 x 288 branch1x1 = conv2d_bn(x, 64, 1, 1) branch5x5 = conv2d_bn(x, 48, 1, 1) branch5x5 = conv2d_bn(branch5x5, 64, 5, 5) branch3x3dbl = conv2d_bn(x, 64, 1, 1) branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3) branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3) branch_pool = layers.AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x) branch_pool = conv2d_bn(branch_pool, 64, 1, 1) x = layers.concatenate([branch1x1, branch5x5, branch3x3dbl, branch_pool], axis=channel_axis, name='mixed1') # mixed 2: 35 x 35 x 288 branch1x1 = conv2d_bn(x, 64, 1, 1) branch5x5 = conv2d_bn(x, 48, 1, 1) branch5x5 = conv2d_bn(branch5x5, 64, 5, 5) branch3x3dbl = conv2d_bn(x, 64, 1, 1) branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3) branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3) branch_pool = layers.AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x) branch_pool = conv2d_bn(branch_pool, 64, 1, 1) x = layers.concatenate([branch1x1, branch5x5, branch3x3dbl, branch_pool], axis=channel_axis, name='mixed2') # mixed 3: 17 x 17 x 768 branch3x3 = conv2d_bn(x, 384, 3, 3, strides=(2, 2), padding='same') branch3x3dbl = conv2d_bn(x, 64, 1, 1) branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3) branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3, strides=(2, 2), padding='same') branch_pool = layers.MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x) x = layers.concatenate([branch3x3, branch3x3dbl, branch_pool], axis=channel_axis, name='mixed3') # mixed 4: 17 x 17 x 768 branch1x1 = conv2d_bn(x, 192, 1, 1) branch7x7 = conv2d_bn(x, 128, 1, 1) branch7x7 = conv2d_bn(branch7x7, 128, 1, 7) branch7x7 = conv2d_bn(branch7x7, 192, 7, 1) branch7x7dbl = conv2d_bn(x, 128, 1, 1) branch7x7dbl = conv2d_bn(branch7x7dbl, 128, 7, 1) branch7x7dbl = conv2d_bn(branch7x7dbl, 128, 1, 7) branch7x7dbl = conv2d_bn(branch7x7dbl, 128, 7, 1) branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7) branch_pool = layers.AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x) branch_pool = conv2d_bn(branch_pool, 192, 1, 1) x = layers.concatenate([branch1x1, branch7x7, branch7x7dbl, branch_pool], axis=channel_axis, name='mixed4') # mixed 5, 6: 17 x 17 x 768 for i in range(2): branch1x1 = conv2d_bn(x, 192, 1, 1) branch7x7 = conv2d_bn(x, 160, 1, 1) branch7x7 = conv2d_bn(branch7x7, 160, 1, 7) branch7x7 = conv2d_bn(branch7x7, 192, 7, 1) branch7x7dbl = conv2d_bn(x, 160, 1, 1) branch7x7dbl = conv2d_bn(branch7x7dbl, 160, 7, 1) branch7x7dbl = conv2d_bn(branch7x7dbl, 160, 1, 7) branch7x7dbl = conv2d_bn(branch7x7dbl, 160, 7, 1) branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7) branch_pool = layers.AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x) branch_pool = conv2d_bn(branch_pool, 192, 1, 1) x = layers.concatenate( [branch1x1, branch7x7, branch7x7dbl, branch_pool], axis=channel_axis, name='mixed' + str(5 + i)) # mixed 7: 17 x 17 x 768 branch1x1 = conv2d_bn(x, 192, 1, 1) branch7x7 = conv2d_bn(x, 192, 1, 1) branch7x7 = conv2d_bn(branch7x7, 192, 1, 7) branch7x7 = conv2d_bn(branch7x7, 192, 7, 1) branch7x7dbl = conv2d_bn(x, 192, 1, 1) branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 7, 1) branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7) branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 7, 1) branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7) branch_pool = layers.AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x) branch_pool = conv2d_bn(branch_pool, 192, 1, 1) x = layers.concatenate([branch1x1, branch7x7, branch7x7dbl, branch_pool], axis=channel_axis, name='mixed7') # mixed 8: 8 x 8 x 1280 branch3x3 = conv2d_bn(x, 192, 1, 1) branch3x3 = conv2d_bn(branch3x3, 320, 3, 3, strides=(2, 2), padding='same') branch7x7x3 = conv2d_bn(x, 192, 1, 1) branch7x7x3 = conv2d_bn(branch7x7x3, 192, 1, 7) branch7x7x3 = conv2d_bn(branch7x7x3, 192, 7, 1) branch7x7x3 = conv2d_bn(branch7x7x3, 192, 3, 3, strides=(2, 2), padding='same') branch_pool = layers.MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x) x = layers.concatenate([branch3x3, branch7x7x3, branch_pool], axis=channel_axis, name='mixed8') # mixed 9: 8 x 8 x 2048 for i in range(2): branch1x1 = conv2d_bn(x, 320, 1, 1) branch3x3 = conv2d_bn(x, 384, 1, 1) branch3x3_1 = conv2d_bn(branch3x3, 384, 1, 3) branch3x3_2 = conv2d_bn(branch3x3, 384, 3, 1) branch3x3 = layers.concatenate([branch3x3_1, branch3x3_2], axis=channel_axis, name='mixed9_' + str(i)) branch3x3dbl = conv2d_bn(x, 448, 1, 1) branch3x3dbl = conv2d_bn(branch3x3dbl, 384, 3, 3) branch3x3dbl_1 = conv2d_bn(branch3x3dbl, 384, 1, 3) branch3x3dbl_2 = conv2d_bn(branch3x3dbl, 384, 3, 1) branch3x3dbl = layers.concatenate([branch3x3dbl_1, branch3x3dbl_2], axis=channel_axis) branch_pool = layers.AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x) branch_pool = conv2d_bn(branch_pool, 192, 1, 1) x = layers.concatenate( [branch1x1, branch3x3, branch3x3dbl, branch_pool], axis=channel_axis, name='mixed' + str(9 + i)) if include_top: # Classification block x = layers.GlobalAveragePooling2D(name='avg_pool')(x) x = layers.Dense(classes, activation='softmax', name='predictions')(x) else: if pooling == 'avg': x = layers.GlobalAveragePooling2D()(x) elif pooling == 'max': x = layers.GlobalMaxPooling2D()(x) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = keras_utils.get_source_inputs(input_tensor) else: inputs = img_input # Create model. model = models.Model(inputs, x, name='inception_v3') # Load weights. if weights == 'imagenet': if include_top: weights_path = keras_utils.get_file( 'inception_v3_weights_tf_dim_ordering_tf_kernels.h5', WEIGHTS_PATH, cache_subdir='models', file_hash='9a0d58056eeedaa3f26cb7ebd46da564') else: weights_path = keras_utils.get_file( 'inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5', WEIGHTS_PATH_NO_TOP, cache_subdir='models', file_hash='bcbd6486424b2319ff4ef7d526e38f63') model.load_weights(weights_path) elif weights is not None: model.load_weights(weights) return model
def FPN(backbone_name='vgg16', input_shape=(None, None, 3), classes=21, activation='softmax', activation_dtype=None, weights=None, encoder_weights='imagenet', encoder_freeze=False, encoder_features='default', pyramid_block_filters=256, pyramid_use_batchnorm=True, pyramid_aggregation='concat', pyramid_dropout=None, **kwargs): """FPN_ is a fully convolution neural network for image semantic segmentation Args: backbone_name: name of classification model (without last dense layers) used as feature extractor to build segmentation model. input_shape: shape of input data/image ``(H, W, C)``, in general case you do not need to set ``H`` and ``W`` shapes, just pass ``(None, None, C)`` to make your model be able to process images af any size, but ``H`` and ``W`` of input images should be divisible by factor ``32``. classes: a number of classes for output (output shape - ``(h, w, classes)``). weights: optional, path to model weights. activation: name of one of ``keras.activations`` for last model layer (e.g. ``sigmoid``, ``softmax``, ``linear``). activation_dtype: Optional type parameter to force activations to be treated in certain type. Used when mixed_precision is enabled. encoder_weights: one of ``None`` (random initialization), ``imagenet`` (pre-training on ImageNet). encoder_freeze: if ``True`` set all layers of encoder (backbone model) as non-trainable. If a float, freezes just that fraction of the encoder layers (starting with the earliest layers) encoder_features: a list of layer numbers or names starting from top of the model. Each of these layers will be used to build features pyramid. If ``default`` is used layer names are taken from ``DEFAULT_FEATURE_PYRAMID_LAYERS``. pyramid_block_filters: a number of filters in Feature Pyramid Block of FPN_. pyramid_use_batchnorm: if ``True``, ``BatchNormalisation`` layer between ``Conv2D`` and ``Activation`` layers is used. pyramid_aggregation: one of 'sum' or 'concat'. The way to aggregate pyramid blocks. pyramid_dropout: spatial dropout rate for feature pyramid in range (0, 1). Returns: ``keras.models.Model``: **FPN** .. _FPN: http://presentations.cocodataset.org/COCO17-Stuff-FAIR.pdf """ global backend, layers, models, keras_utils submodule_args = filter_keras_submodules(kwargs) backend, layers, models, keras_utils = get_submodules_from_kwargs( submodule_args) backbone = Backbones.get_backbone( backbone_name, input_shape=input_shape, weights=encoder_weights, include_top=False, **kwargs, ) if encoder_features == 'default': encoder_features = Backbones.get_feature_layers(backbone_name, n=4) model = build_fpn( backbone=backbone, skip_connection_layers=encoder_features, pyramid_filters=pyramid_block_filters, segmentation_filters=pyramid_block_filters // 2, use_batchnorm=pyramid_use_batchnorm, dropout=pyramid_dropout, activation=activation, activation_dtype=activation_dtype, classes=classes, aggregation=pyramid_aggregation, ) # lock encoder weights for fine-tuning if encoder_freeze: fraction = encoder_freeze if isinstance(encoder_freeze, float) else 1.0 freeze_model(backbone, fraction=fraction, **kwargs) # loading model weights if weights is not None: model.load_weights(weights) return model
def InceptionResNetV2(include_top=True, weights='imagenet', input_tensor=None, input_shape=None, pooling=None, classes=1000, **kwargs): """Instantiates the Inception-ResNet v2 architecture. Optionally loads weights pre-trained on ImageNet. Note that the data format convention used by the model is the one specified in your Keras config at `~/.keras/keras.json`. # Arguments include_top: whether to include the fully-connected layer at the top of the network. weights: one of `None` (random initialization), 'imagenet' (pre-training on ImageNet), or the path to the weights file to be loaded. input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) to use as image input for the model. input_shape: optional shape tuple, only to be specified if `include_top` is `False` (otherwise the input shape has to be `(299, 299, 3)` (with `'channels_last'` data format) or `(3, 299, 299)` (with `'channels_first'` data format). It should have exactly 3 inputs channels, and width and height should be no smaller than 75. E.g. `(150, 150, 3)` would be one valid value. pooling: Optional pooling mode for feature extraction when `include_top` is `False`. - `None` means that the output of the model will be the 4D tensor output of the last convolutional block. - `'avg'` means that global average pooling will be applied to the output of the last convolutional block, and thus the output of the model will be a 2D tensor. - `'max'` means that global max pooling will be applied. classes: optional number of classes to classify images into, only to be specified if `include_top` is `True`, and if no `weights` argument is specified. # Returns A Keras `Model` instance. # Raises ValueError: in case of invalid argument for `weights`, or invalid input shape. """ global backend, layers, models, keras_utils backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if not (weights in {'imagenet', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') if weights == 'imagenet' and include_top and classes != 1000: raise ValueError( 'If using `weights` as `"imagenet"` with `include_top`' ' as true, `classes` should be 1000') # Determine proper input shape input_shape = imagenet_utils._obtain_input_shape( input_shape, default_size=299, min_size=32, data_format=backend.image_data_format(), require_flatten=include_top, weights=weights) if input_tensor is None: img_input = layers.Input(shape=input_shape) else: if not backend.is_keras_tensor(input_tensor): img_input = layers.Input(tensor=input_tensor, shape=input_shape) else: img_input = input_tensor # Stem block: 35 x 35 x 192 x = conv2d_bn(img_input, 32, 3, strides=2, padding='same') x = conv2d_bn(x, 32, 3, padding='same') x = conv2d_bn(x, 64, 3, padding='same') x = layers.MaxPooling2D(3, strides=2, padding='same')(x) x = conv2d_bn(x, 80, 1, padding='same') x = conv2d_bn(x, 192, 3, padding='same') x = layers.MaxPooling2D(3, strides=2, padding='same')(x) # Mixed 5b (Inception-A block): 35 x 35 x 320 branch_0 = conv2d_bn(x, 96, 1, padding='same') branch_1 = conv2d_bn(x, 48, 1, padding='same') branch_1 = conv2d_bn(branch_1, 64, 5, padding='same') branch_2 = conv2d_bn(x, 64, 1, padding='same') branch_2 = conv2d_bn(branch_2, 96, 3, padding='same') branch_2 = conv2d_bn(branch_2, 96, 3, padding='same') branch_pool = layers.AveragePooling2D(3, strides=1, padding='same')(x) branch_pool = conv2d_bn(branch_pool, 64, 1, padding='same') branches = [branch_0, branch_1, branch_2, branch_pool] channel_axis = 1 if backend.image_data_format() == 'channels_first' else 3 x = layers.Concatenate(axis=channel_axis, name='mixed_5b')(branches) # 10x block35 (Inception-ResNet-A block): 35 x 35 x 320 for block_idx in range(1, 11): x = inception_resnet_block(x, scale=0.17, block_type='block35', block_idx=block_idx) # Mixed 6a (Reduction-A block): 17 x 17 x 1088 branch_0 = conv2d_bn(x, 384, 3, strides=2, padding='same') branch_1 = conv2d_bn(x, 256, 1, padding='same') branch_1 = conv2d_bn(branch_1, 256, 3, padding='same') branch_1 = conv2d_bn(branch_1, 384, 3, strides=2, padding='same') branch_pool = layers.MaxPooling2D(3, strides=2, padding='same')(x) branches = [branch_0, branch_1, branch_pool] x = layers.Concatenate(axis=channel_axis, name='mixed_6a')(branches) # 20x block17 (Inception-ResNet-B block): 17 x 17 x 1088 for block_idx in range(1, 21): x = inception_resnet_block(x, scale=0.1, block_type='block17', block_idx=block_idx) # Mixed 7a (Reduction-B block): 8 x 8 x 2080 branch_0 = conv2d_bn(x, 256, 1, padding='same') branch_0 = conv2d_bn(branch_0, 384, 3, strides=2, padding='same') branch_1 = conv2d_bn(x, 256, 1, padding='same') branch_1 = conv2d_bn(branch_1, 288, 3, strides=2, padding='same') branch_2 = conv2d_bn(x, 256, 1, padding='same') branch_2 = conv2d_bn(branch_2, 288, 3, padding='same') branch_2 = conv2d_bn(branch_2, 320, 3, strides=2, padding='same') branch_pool = layers.MaxPooling2D(3, strides=2, padding='same')(x) branches = [branch_0, branch_1, branch_2, branch_pool] x = layers.Concatenate(axis=channel_axis, name='mixed_7a')(branches) # 10x block8 (Inception-ResNet-C block): 8 x 8 x 2080 for block_idx in range(1, 10): x = inception_resnet_block(x, scale=0.2, block_type='block8', block_idx=block_idx) x = inception_resnet_block(x, scale=1., activation=None, block_type='block8', block_idx=10) # Final convolution block: 8 x 8 x 1536 x = conv2d_bn(x, 1536, 1, name='conv_7b') if include_top: # Classification block x = layers.GlobalAveragePooling2D(name='avg_pool')(x) x = layers.Dense(classes, activation='softmax', name='predictions')(x) else: if pooling == 'avg': x = layers.GlobalAveragePooling2D()(x) elif pooling == 'max': x = layers.GlobalMaxPooling2D()(x) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = keras_utils.get_source_inputs(input_tensor) else: inputs = img_input # Create model. model = models.Model(inputs, x, name='inception_resnet_v2') # Load weights. if weights == 'imagenet': if include_top: fname = 'inception_resnet_v2_weights_tf_dim_ordering_tf_kernels.h5' weights_path = keras_utils.get_file( fname, BASE_WEIGHT_URL + fname, cache_subdir='models', file_hash='e693bd0210a403b3192acc6073ad2e96') else: fname = ('inception_resnet_v2_weights_' 'tf_dim_ordering_tf_kernels_notop.h5') weights_path = keras_utils.get_file( fname, BASE_WEIGHT_URL + fname, cache_subdir='models', file_hash='d19885ff4a710c122648d3b5c3b684e4') model.load_weights(weights_path) elif weights is not None: model.load_weights(weights) return model
def Unet(backbone_name='vgg16', input_shape=(None, None, 3), classes=1, activation='sigmoid', weights=None, encoder_weights='imagenet', encoder_freeze=False, encoder_features='default', decoder_block_type='upsampling', decoder_filters=(256, 128, 64, 32, 16), decoder_use_batchnorm=True, backbone=None, **kwargs): """ Unet_ is a fully convolution neural network for image semantic segmentation Args: backbone_name: name of classification model (without last dense layers) used as feature extractor to build segmentation model. input_shape: shape of input data/image ``(H, W, C)``, in general case you do not need to set ``H`` and ``W`` shapes, just pass ``(None, None, C)`` to make your model be able to process images af any size, but ``H`` and ``W`` of input images should be divisible by factor ``32``. classes: a number of classes for output (output shape - ``(h, w, classes)``). activation: name of one of ``keras.activations`` for last model layer (e.g. ``sigmoid``, ``softmax``, ``linear``). weights: optional, path to model weights. encoder_weights: one of ``None`` (random initialization), ``imagenet`` (pre-training on ImageNet). encoder_freeze: if ``True`` set all layers of encoder (backbone model) as non-trainable. encoder_features: a list of layer numbers or names starting from top of the model. Each of these layers will be concatenated with corresponding decoder block. If ``default`` is used layer names are taken from ``DEFAULT_SKIP_CONNECTIONS``. decoder_block_type: one of blocks with following layers structure: - `upsampling`: ``UpSampling2D`` -> ``Conv2D`` -> ``Conv2D`` - `transpose`: ``Transpose2D`` -> ``Conv2D`` decoder_filters: list of numbers of ``Conv2D`` layer filters in decoder blocks decoder_use_batchnorm: if ``True``, ``BatchNormalisation`` layer between ``Conv2D`` and ``Activation`` layers is used. Returns: ``keras.models.Model``: **Unet** .. _Unet: https://arxiv.org/pdf/1505.04597 """ global backend, layers, models, keras_utils submodule_args = filter_keras_submodules(kwargs) backend, layers, models, keras_utils = get_submodules_from_kwargs( submodule_args) if decoder_block_type == 'upsampling': decoder_block = DecoderUpsamplingX2Block elif decoder_block_type == 'transpose': decoder_block = DecoderTransposeX2Block else: raise ValueError( 'Decoder block type should be in ("upsampling", "transpose"). ' 'Got: {}'.format(decoder_block_type)) backbone = backbone or Backbones.get_backbone( backbone_name, input_shape=input_shape, weights=encoder_weights, include_top=False, **kwargs, ) if encoder_features == 'default': encoder_features = Backbones.get_feature_layers(backbone_name, n=4) ef = encoder_features encoder_features = [ ll for ll in encoder_features if ll in [ll.name for ll in backbone.layers] ] decoder_filters = decoder_filters[-len(encoder_features) - 1:] diff = set(ef).difference(set(encoder_features)) if diff: log.warning( f"UNet model: the following encoder_features are not in backbone {', '.join(diff)} \nFound and using: {', '.join(encoder_features)}" ) model = build_unet( backbone=backbone, decoder_block=decoder_block, skip_connection_layers=encoder_features, decoder_filters=decoder_filters, classes=classes, activation=activation, n_upsample_blocks=len(decoder_filters), use_batchnorm=decoder_use_batchnorm, ) # lock encoder weights for fine-tuning if encoder_freeze: freeze_model(backbone, **kwargs) # loading model weights if weights is not None: model.load_weights(weights) return model
def __init__(self, backbone_name='vgg16', input_shape=(None, None, 3), classes=1, activation='sigmoid', weights=None, encoder_weights='imagenet', encoder_freeze=False, encoder_features='default', decoder_block_type='upsampling', decoder_filters=(256, 128, 64, 32, 16), decoder_use_batchnorm=True, **kwargs): super(Unet, self).__init__(name="Unet") backend, layers, models, keras_utils = get_submodules_from_kwargs( kwargs) if decoder_block_type == 'upsampling': decoder_block = DecoderUpsamplingX2Block elif decoder_block_type == 'transpose': decoder_block = DecoderTransposeX2Block else: raise ValueError( 'Decoder block type should be in ("upsampling", "transpose"). ' 'Got: {}'.format(decoder_block_type)) self.backbone = Backbones.get_backbone( backbone_name, input_shape=input_shape, weights=encoder_weights, include_top=False, **kwargs, ) # backbone=backbone, # decoder_block=decoder_block, # skip_connection_layers=encoder_features, # decoder_filters=decoder_filters, # classes=classes, # activation=activation, # n_upsample_blocks=len(decoder_filters), # use_batchnorm=decoder_use_batchnorm, self.n_upsample_blocks = len(decoder_filters) if encoder_features == 'default': self.encoder_features = Backbones.get_feature_layers(backbone_name, n=4) if isinstance(self.backbone.layers[-1], tf.keras.layers.MaxPooling2D): self.conv3x3_1 = Conv3x3BnReLU(512, decoder_use_batchnorm, name='center_block1') self.conv3x3_2 = Conv3x3BnReLU(512, decoder_use_batchnorm, name='center_block2') # self.skips = ([ # self.backbone.get_layer(name=i).output # if isinstance(i, str) else self.backbone.get_layer(index=i).output # for i in self.encoder_features # ]) self.decoder = [] for i in range(self.n_upsample_blocks): self.decoder.append( decoder_block(decoder_filters[i], stage=i, use_batchnorm=decoder_use_batchnorm)) self.final_conv = tf.keras.layers.Conv2D( filters=classes, kernel_size=(3, 3), padding='same', use_bias=True, kernel_initializer='glorot_uniform', name='final_conv', ) self.final_act = tf.keras.layers.Activation(activation, name=activation) self.intermediate_layers = []
def __init__( self, include_top=True, weights='imagenet', input_tensor=None, input_shape=None, pooling=None, classes=1000, **kwargs): """Instantiates the VGG19 architecture. Optionally loads weights pre-trained on ImageNet. Note that the data format convention used by the model is the one specified in your Keras config at `~/.keras/keras.json`. # Arguments include_top: whether to include the 3 fully-connected layers at the top of the network. weights: one of `None` (random initialization), 'imagenet' (pre-training on ImageNet), or the path to the weights file to be loaded. input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) to use as image input for the model. input_shape: optional shape tuple, only to be specified if `include_top` is False (otherwise the input shape has to be `(224, 224, 3)` (with `channels_last` data format) or `(3, 224, 224)` (with `channels_first` data format). It should have exactly 3 inputs channels, and width and height should be no smaller than 32. E.g. `(200, 200, 3)` would be one valid value. pooling: Optional pooling mode for feature extraction when `include_top` is `False`. - `None` means that the output of the model will be the 4D tensor output of the last convolutional block. - `avg` means that global average pooling will be applied to the output of the last convolutional block, and thus the output of the model will be a 2D tensor. - `max` means that global max pooling will be applied. classes: optional number of classes to classify images into, only to be specified if `include_top` is True, and if no `weights` argument is specified. # Returns A Keras model instance. # Raises ValueError: in case of invalid argument for `weights`, or invalid input shape. """ backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) self.include_top = include_top self.pooling = pooling self.weights = weights self.backend = backend self.layers = layers self.classes = classes if not (weights in {'imagenet', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') if weights == 'imagenet' and include_top and classes != 1000: raise ValueError('If using `weights` as `"imagenet"` with `include_top`' ' as true, `classes` should be 1000') # Block 1 self.block1_conv1 = layers.Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv1') self.block1_conv2 = layers.Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv2') self.block1_pool = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool') # Block 2 self.block2_conv1 = layers.Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv1') self.block2_conv2 = layers.Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv2') self.block2_pool = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool') # Block 3 self.block3_conv1 = layers.Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv1') self.block3_conv2 = layers.Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv2') self.block3_conv3 = layers.Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv3') self.block3_conv4 = layers.Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv4') self.block3_pool = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool') # Block 4 self.block4_conv1 = layers.Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv1') self.block4_conv2 = layers.Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv2') self.block4_conv3 = layers.Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv3') self.block4_conv4 = layers.Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv4') self.block4_pool = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool') # Block 5 self.block5_conv1 = layers.Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv1') self.block5_conv2 = layers.Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv2') self.block5_conv3 = layers.Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3') self.block5_conv4 = layers.Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv4') self.block5_pool = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool') if include_top: # Classification block self.flatten = layers.Flatten(name='flatten') self.fc1 = layers.Dense(4096, activation='relu', name='fc1') self.fc2 = layers.Dense(4096, activation='relu', name='fc2') self.predict = layers.Dense(classes, activation='softmax', name='predictions') else: if pooling == 'avg': self.pool = layers.GlobalAveragePooling2D() elif pooling == 'max': self.pool = layers.GlobalMaxPooling2D()
def vggmax(include_top=True, weights='imagenet', input_tensor=None, input_shape=None, pooling=None, classes=1000, cfg=None, **kwargs): """Instantiates the VGG16 architecture. Optionally loads weights pre-trained on ImageNet. Note that the data format convention used by the model is the one specified in your Keras config at `~/.keras/keras.json`. # Arguments include_top: whether to include the 3 fully-connected layers at the top of the network. weights: one of `None` (random initialization), 'imagenet' (pre-training on ImageNet), or the path to the weights file to be loaded. input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) to use as image input for the model. input_shape: optional shape tuple, only to be specified if `include_top` is False (otherwise the input shape has to be `(224, 224, 3)` (with `channels_last` data format) or `(3, 224, 224)` (with `channels_first` data format). It should have exactly 3 input channels, and width and height should be no smaller than 32. E.g. `(200, 200, 3)` would be one valid value. pooling: Optional pooling mode for feature extraction when `include_top` is `False`. - `None` means that the output of the model will be the 4D tensor output of the last convolutional layer. - `avg` means that global average pooling will be applied to the output of the last convolutional layer, and thus the output of the model will be a 2D tensor. - `max` means that global max pooling will be applied. classes: optional number of classes to classify images into, only to be specified if `include_top` is True, and if no `weights` argument is specified. fusion_blocks: list of indexes giving the blocks where radar and image is concatenated. Input Layer is targeted by 0. # Returns A Keras model instance. # Raises ValueError: in case of invalid argument for `weights`, or invalid input shape. """ backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if not (weights in {'imagenet', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') if weights == 'imagenet' and include_top and classes != 1000: raise ValueError( 'If using `weights` as `"imagenet"` with `include_top`' ' as true, `classes` should be 1000') # Determine proper input shape input_shape = _obtain_input_shape(input_shape, default_size=224, min_size=32, data_format=backend.image_data_format(), require_flatten=include_top, weights=weights) if input_tensor is None: all_input = layers.Input(shape=input_shape) else: if not backend.is_keras_tensor(input_tensor): all_input = layers.Input(tensor=input_tensor, shape=input_shape) else: all_input = input_tensor ## Read config variables fusion_blocks = cfg.fusion_blocks ## Model # Seperate input if len(cfg.channels) > 3: image_input = Lambda(lambda x: x[:, :, :, :3], name='image_channels')(all_input) radar_input = Lambda(lambda x: x[:, :, :, 3:], name='radar_channels')(all_input) # Bock 0 Fusion if len(cfg.channels) > 3: if 0 in fusion_blocks: x = Concatenate(axis=3, name='concat_0')([image_input, radar_input]) else: x = image_input else: x = all_input # Block 1 - Image x = layers.Conv2D(int(64 * cfg.network_width), (3, 3), activation='relu', padding='same', name='block1_conv1')(x) x = layers.Conv2D(int(64 * cfg.network_width), (3, 3), activation='relu', padding='same', name='block1_conv2')(x) if cfg.pooling == 'maxmin': x = Lambda(min_max_pool2d, name='block1_pool')(x) else: x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(x) # Block 1 - Radar if len(cfg.channels) > 3: if cfg.pooling == 'min': y = Lambda(min_pool2d, name='rad_block1_pool')(radar_input) elif cfg.pooling == 'maxmin': y = Lambda(min_max_pool2d, name='rad_block1_pool')(radar_input) elif cfg.pooling == 'conv': y = layers.Conv2D(int(64 * cfg.network_width), (3, 3), activation='relu', padding='same', strides=(2, 2), name='rad_block1_pool')(radar_input) else: y = layers.MaxPooling2D((2, 2), strides=(2, 2), name='rad_block1_pool')(radar_input) ## Concatenate Block 1 Radar to image if 1 in fusion_blocks: x = Concatenate(axis=3, name='concat_1')([x, y]) # Block 2 x = layers.Conv2D(int(128 * cfg.network_width), (3, 3), activation='relu', padding='same', name='block2_conv1')(x) x = layers.Conv2D(int(128 * cfg.network_width), (3, 3), activation='relu', padding='same', name='block2_conv2')(x) if cfg.pooling == 'maxmin': x = Lambda(min_max_pool2d, name='block2_pool')(x) else: x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x) # Block 2 - Radar if len(cfg.channels) > 3: if cfg.pooling == 'min': y = Lambda(min_pool2d, name='rad_block2_pool')(y) elif cfg.pooling == 'maxmin': y = Lambda(min_max_pool2d, name='rad_block2_pool')(y) elif cfg.pooling == 'conv': y = layers.Conv2D(int(64 * cfg.network_width), (3, 3), activation='relu', padding='same', strides=(2, 2), name='rad_block2_pool')(y) else: y = layers.MaxPooling2D((2, 2), strides=(2, 2), name='rad_block2_pool')(y) ## Concatenate Block 2 Radar to image if 2 in fusion_blocks: x = Concatenate(axis=3, name='concat_2')([x, y]) # Block 3 x = layers.Conv2D(int(256 * cfg.network_width), (3, 3), activation='relu', padding='same', name='block3_conv1')(x) x = layers.Conv2D(int(256 * cfg.network_width), (3, 3), activation='relu', padding='same', name='block3_conv2')(x) x = layers.Conv2D(int(256 * cfg.network_width), (3, 3), activation='relu', padding='same', name='block3_conv3')(x) if cfg.pooling == 'maxmin': x = Lambda(min_max_pool2d, name='block3_pool')(x) else: x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x) # Block 3 - Radar if len(cfg.channels) > 3: if cfg.pooling == 'min': y = Lambda(min_pool2d, name='rad_block3_pool')(y) elif cfg.pooling == 'maxmin': y = Lambda(min_max_pool2d, name='rad_block3_pool')(y) elif cfg.pooling == 'conv': y = layers.Conv2D(int(64 * cfg.network_width), (3, 3), activation='relu', padding='same', strides=(2, 2), name='rad_block3_pool')(y) else: y = layers.MaxPooling2D((2, 2), strides=(2, 2), name='rad_block3_pool')(y) ## Concatenate Block 3 Radar to image if 3 in fusion_blocks: x = Concatenate(axis=3, name='concat_3')([x, y]) # Block 4 x = layers.Conv2D(int(512 * cfg.network_width), (3, 3), activation='relu', padding='same', name='block4_conv1')(x) x = layers.Conv2D(int(512 * cfg.network_width), (3, 3), activation='relu', padding='same', name='block4_conv2')(x) x = layers.Conv2D(int(512 * cfg.network_width), (3, 3), activation='relu', padding='same', name='block4_conv3')(x) if cfg.pooling == 'maxmin': x = Lambda(min_max_pool2d, name='block4_pool')(x) else: x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x) # Block 4 - Radar if len(cfg.channels) > 3: if cfg.pooling == 'min': y = Lambda(min_pool2d, name='rad_block4_pool')(y) elif cfg.pooling == 'maxmin': y = Lambda(min_max_pool2d, name='rad_block4_pool')(y) elif cfg.pooling == 'conv': y = layers.Conv2D(int(64 * cfg.network_width), (2, 2), activation='relu', padding='valid', strides=(2, 2), name='rad_block4_pool')(y) else: y = layers.MaxPooling2D((2, 2), strides=(2, 2), name='rad_block4_pool')(y) ## Concatenate Block 4 Radar to image if 4 in fusion_blocks: x = Concatenate(axis=3, name='concat_4')([x, y]) # Block 5 x = layers.Conv2D(int(512 * cfg.network_width), (3, 3), activation='relu', padding='same', name='block5_conv1')(x) x = layers.Conv2D(int(512 * cfg.network_width), (3, 3), activation='relu', padding='same', name='block5_conv2')(x) x = layers.Conv2D(int(512 * cfg.network_width), (3, 3), activation='relu', padding='same', name='block5_conv3')(x) x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x) # Block 5 - Radar if len(cfg.channels) > 3: if cfg.pooling == 'min': y = Lambda(min_pool2d, name='rad_block5_pool')(y) elif cfg.pooling == 'maxmin': y = Lambda(min_max_pool2d, name='rad_block5_pool')(y) elif cfg.pooling == 'conv': y = layers.Conv2D(int(64 * cfg.network_width), (2, 2), activation='relu', padding='valid', strides=(2, 2), name='rad_block5_pool')(y) else: y = layers.MaxPooling2D((2, 2), strides=(2, 2), name='rad_block5_pool')(y) ## Concatenate Block 5 Radar to image if 5 in fusion_blocks: x = Concatenate(axis=3, name='concat_5')([x, y]) if include_top: # Classification block x = layers.Flatten(name='flatten')(x) x = layers.Dense(4096, activation='relu', name='fc1')(x) x = layers.Dense(4096, activation='relu', name='fc2')(x) x = layers.Dense(classes, activation='softmax', name='predictions')(x) else: if pooling == 'avg': x = layers.GlobalAveragePooling2D()(x) elif pooling == 'max': x = layers.GlobalMaxPooling2D()(x) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = keras_utils.get_source_inputs(input_tensor) else: inputs = all_input # Create model. model = models.Model(inputs, x, name='vgg16') # Load weights. if weights == 'imagenet': if include_top: weights_path = keras_utils.get_file( 'vgg16_weights_tf_dim_ordering_tf_kernels.h5', WEIGHTS_PATH, cache_subdir='models', file_hash='64373286793e3c8b2b4e3219cbf3544b') else: weights_path = keras_utils.get_file( 'vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5', WEIGHTS_PATH_NO_TOP, cache_subdir='models', file_hash='6d6bbae143d832006294945121d1f1fc') model.load_weights(weights_path) if backend.backend() == 'theano': keras_utils.convert_all_kernels_in_model(model) elif weights is not None: model.load_weights(weights) return model
def Dnestnet(backbone_name='vgg16', input_shape=(None, None, 3), input_tensor=None, encoder_weights='imagenet', freeze_encoder=False, skip_connections='default', decoder_block_type='upsampling', decoder_filters=(256,128,64,32,16), decoder_use_batchnorm=True, n_upsample_blocks=5, upsample_rates=(2,2,2,2,2), classes=1, activation='sigmoid', **kwargs ): """ Args: backbone_name: (str) look at list of available backbones. input_shape: (tuple) dimensions of input data (H, W, C) input_tensor: keras tensor encoder_weights: one of `None` (random initialization), 'imagenet' (pre-training on ImageNet), 'dof' (pre-training on DoF) freeze_encoder: (bool) Set encoder layers weights as non-trainable. Useful for fine-tuning skip_connections: if 'default' is used take default skip connections, else provide a list of layer numbers or names starting from top of model decoder_block_type: (str) one of 'upsampling' and 'transpose' (look at blocks.py) decoder_filters: (int) number of convolution layer filters in decoder blocks decoder_use_batchnorm: (bool) if True add batch normalisation layer between `Conv2D` ad `Activation` layers n_upsample_blocks: (int) a number of upsampling blocks upsample_rates: (tuple of int) upsampling rates decoder blocks classes: (int) a number of classes for output activation: (str) one of keras activations for last model layer Returns: keras.models.Model instance """ global backend, layers, models, keras_utils submodule_args = filter_keras_submodules(kwargs) backend, layers, models, keras_utils = get_submodules_from_kwargs(submodule_args) # if decoder_block_type == 'upsampling': # decoder_block = DecoderUpsamplingX2Block # elif decoder_block_type == 'transpose': # decoder_block = DecoderTransposeX2Block # else: # raise ValueError('Decoder block type should be in ("upsampling", "transpose"). ' # 'Got: {}'.format(decoder_block_type)) backbone = Backbones.get_backbone( backbone_name, input_shape=input_shape, weights=encoder_weights, include_top=False, **kwargs, ) # backbone = Backbones.get_backbone(backbone_name, # input_shape=input_shape, # input_tensor=input_tensor, # weights=encoder_weights, # include_top=False) if skip_connections == 'default': skip_connections = Backbones.get_feature_layers(backbone_name, n=4) # skip_connections = DEFAULT_SKIP_CONNECTIONS[backbone_name] # n_upsample_blocks = len(skip_connections) model = build_nestnet(backbone, classes, skip_connections, decoder_filters=decoder_filters, block_type=decoder_block_type, activation=activation, n_upsample_blocks=n_upsample_blocks, upsample_rates=upsample_rates, use_batchnorm=decoder_use_batchnorm) # lock encoder weights for fine-tuning if freeze_encoder: freeze_model(backbone, **kwargs) # model.name = 'nest-{}'.format(backbone_name) return model
def Punet(backbone_name='vgg16', input_shape=(None, None, 3), classes=1, activation='sigmoid', weights=None, encoder_weights='imagenet', encoder_freeze=False, encoder_features='default', feature_version=None, decoder_block_type='upsampling', decoder_filters=(256, 128, 64, 32, 16), decoder_use_batchnorm=True, **kwargs): """ Unet_ is a fully convolution neural network for image semantic segmentation Args: backbone_name: name of classification model (without last dense layers) used as feature extractor to build segmentation model. input_shape: shape of input data/image ``(H, W, C)``, in general case you do not need to set ``H`` and ``W`` shapes, just pass ``(None, None, C)`` to make your model be able to process images af any size, but ``H`` and ``W`` of input images should be divisible by factor ``32``. classes: a number of classes for output (output shape - ``(h, w, classes)``). activation: name of one of ``keras.activations`` for last model layer (e.g. ``sigmoid``, ``softmax``, ``linear``). weights: optional, path to model weights. encoder_weights: one of ``None`` (random initialization), ``imagenet`` (pre-training on ImageNet). encoder_freeze: if ``True`` set all layers of encoder (backbone model) as non-trainable. encoder_features: a list of layer numbers or names starting from top of the model. Each of these layers will be concatenated with corresponding decoder block. If ``default`` is used layer names are taken from ``DEFAULT_SKIP_CONNECTIONS``. decoder_block_type: one of blocks with following layers structure: - `upsampling`: ``UpSampling2D`` -> ``Conv2D`` -> ``Conv2D`` - `transpose`: ``Transpose2D`` -> ``Conv2D`` decoder_filters: list of numbers of ``Conv2D`` layer filters in decoder blocks decoder_use_batchnorm: if ``True``, ``BatchNormalisation`` layer between ``Conv2D`` and ``Activation`` layers is used. Returns: ``keras.models.Model``: **Unet** .. _Unet: https://arxiv.org/pdf/1505.04597 """ global backend, layers, models, keras_utils submodule_args = filter_keras_submodules(kwargs) backend, layers, models, keras_utils = get_submodules_from_kwargs( submodule_args) if decoder_block_type == 'upsampling': decoder_block = DecoderUpsamplingX2Block elif decoder_block_type == 'transpose': decoder_block = DecoderTransposeX2Block else: raise ValueError( 'Decoder block type should be in ("upsampling", "transpose"). ' 'Got: {}'.format(decoder_block_type)) backbone = Backbones.get_backbone( backbone_name, input_shape=(None, None, 3), weights=encoder_weights, include_top=False, **kwargs, ) if encoder_features == 'default': if feature_version and 'efficientnetb' in backbone_name: print('Feature version: {}'.format(feature_version)) encoder_features = Backbones.get_feature_layers( backbone_name + '_v{}'.format(feature_version), n=4) else: encoder_features = Backbones.get_feature_layers(backbone_name, n=4) # physical layer r_l1 = 1e-4 img_input = layers.Input(shape=input_shape, name='main_input') physical = layers.Conv2D(1, (1, 1), activation='linear', name='physical', kernel_initializer='he_normal', padding='same', kernel_regularizer=keras.regularizers.l1(r_l1), use_bias=False)(img_input) nb_axis = 3 input = layers.concatenate([physical, physical, physical], name='efficient_input', axis=nb_axis) model = build_unet( input, backbone=backbone, decoder_block=decoder_block, skip_connection_layers=encoder_features, decoder_filters=decoder_filters, classes=classes, activation=activation, n_upsample_blocks=len(decoder_filters), use_batchnorm=decoder_use_batchnorm, ) # lock encoder weights for fine-tuning if encoder_freeze: freeze_model(backbone, **kwargs) # loading model weights if weights is not None: model.load_weights(weights) return model # from segmentation_models_v1 import Punet # model = Punet('efficientnetb0') # model.summary()
def PSPNet(backbone_name='vgg16', input_shape=(384, 384, 3), classes=21, activation='softmax', weights=None, encoder_weights='imagenet', encoder_freeze=False, downsample_factor=8, psp_conv_filters=512, psp_pooling_type='avg', psp_use_batchnorm=True, psp_dropout=None, **kwargs): """PSPNet_ is a fully convolution neural network for image semantic segmentation Args: backbone_name: name of classification model used as feature extractor to build segmentation model. input_shape: shape of input data/image ``(H, W, C)``. ``H`` and ``W`` should be divisible by ``6 * downsample_factor`` and **NOT** ``None``! classes: a number of classes for output (output shape - ``(h, w, classes)``). activation: name of one of ``keras.activations`` for last model layer (e.g. ``sigmoid``, ``softmax``, ``linear``). weights: optional, path to model weights. encoder_weights: one of ``None`` (random initialization), ``imagenet`` (pre-training on ImageNet). encoder_freeze: if ``True`` set all layers of encoder (backbone model) as non-trainable. downsample_factor: one of 4, 8 and 16. Downsampling rate or in other words backbone depth to construct PSP module on it. psp_conv_filters: number of filters in ``Conv2D`` layer in each PSP block. psp_pooling_type: one of 'avg', 'max'. PSP block pooling type (maximum or average). psp_use_batchnorm: if ``True``, ``BatchNormalisation`` layer between ``Conv2D`` and ``Activation`` layers is used. psp_dropout: dropout rate between 0 and 1. Returns: ``keras.models.Model``: **PSPNet** .. _PSPNet: https://arxiv.org/pdf/1612.01105.pdf """ global backend, layers, models, keras_utils submodule_args = filter_keras_submodules(kwargs) backend, layers, models, keras_utils = get_submodules_from_kwargs( submodule_args) # control image input shape check_input_shape(input_shape, downsample_factor) backbone = Backbones.get_backbone(backbone_name, input_shape=input_shape, weights=encoder_weights, include_top=False, **kwargs) feature_layers = Backbones.get_feature_layers(backbone_name, n=3) if downsample_factor == 16: psp_layer_idx = feature_layers[0] elif downsample_factor == 8: psp_layer_idx = feature_layers[1] elif downsample_factor == 4: psp_layer_idx = feature_layers[2] else: raise ValueError('Unsupported factor - `{}`, Use 4, 8 or 16.'.format( downsample_factor)) model = build_psp( backbone, psp_layer_idx, pooling_type=psp_pooling_type, conv_filters=psp_conv_filters, use_batchnorm=psp_use_batchnorm, final_upsampling_factor=downsample_factor, classes=classes, activation=activation, dropout=psp_dropout, ) # lock encoder weights for fine-tuning if encoder_freeze: freeze_model(backbone, **kwargs) # loading model weights if weights is not None: model.load_weights(weights) return model
def Vgg16(include_top=False, weights='imagenet', input_tensor=None, input_shape=None, num_classes=1000, final_point='block5_conv2', feature_maps='pool4', attention_maps='pool5', num_parts=32, is_training=True, spatial_squeeze=True, global_pools=False, **kwargs): ''' :param include_top: :param weights: :param input_tensor: :param input_shape: :param num_classes: :param final_point: :param feature_maps: :param attention_maps: :param num_parts: :param is_training: :param spatial_squeeze: :param global_pools: :param kwargs: :return: model : a keras model bap_features: 同 vgg_16 end_points: 同 vgg_16 ''' backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if not (weights in {'imagenet', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') if weights == 'imagenet' and include_top and num_classes != 1000: raise ValueError( 'If using `weights` as `"imagenet"` with `include_top`' ' as true, `classes` should be 1000') # Determine proper input shape input_shape = _obtain_input_shape(input_shape, default_size=224, min_size=32, data_format=backend.image_data_format(), require_flatten=include_top, weights=weights) if input_tensor is None: img_input = layers.Input(shape=input_shape) else: if not backend.is_keras_tensor(input_tensor): img_input = layers.Input(tensor=input_tensor, shape=input_shape) else: img_input = input_tensor net, end_points = Vgg16_base(img_input, final_point='block5_conv2') x = keras.layers.Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3')(net) x = keras.layers.MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x) if input_tensor is not None: inputs = keras_utils.get_source_inputs(input_tensor) else: inputs = img_input feature_maps = end_points[feature_maps] attention_maps = end_points[attention_maps] attention_maps = attention_maps[:, :, :, :num_parts] attention_image = tf.compat.v1.py_func(generate_attention_image, [inputs[0], attention_maps[0]], tf.uint8) tf.summary.image('attention_image', tf.expand_dims(attention_image, 0)) tf.summary.image('input_image', inputs[0:1]) if is_training: tf.summary.image( 'attention_maps', tf.reduce_mean(attention_maps[0:1], axis=-1, keepdims=True)) tf.summary.image( 'feature_maps', tf.reduce_mean(feature_maps[0:1], axis=-1, keepdims=True)) end_points['attention_maps'] = attention_maps end_points['feature_maps'] = feature_maps bap_features, end_points = bilinear_attention_pooling( feature_maps, attention_maps, end_points, 'embeddings') if global_pools: bap_features = tf.reduce_mean(bap_features, [1, 2], keep_dims=True, name='global_pool') end_points['global_pool'] = bap_features if num_classes: x = layers.Flatten(name='flatten')(bap_features) x = layers.Dense(4096, activation='relu', name='fc1')(x) x = layers.Dense(4096, activation='relu', name='fc2')(x) bap_features = layers.Dense(num_classes, activation='softmax', name='predictions')(x) if spatial_squeeze: bap_features = tf.squeeze(bap_features, [1, 2], name='fc8/squeezed') end_points['vgg_16' + '/fc8'] = bap_features # Create model. model = models.Model(inputs, bap_features, name='vgg16') if weights == 'imagenet': if include_top: weights_path = keras_utils.get_file( 'vgg16_weights_tf_dim_ordering_tf_kernels.h5', WEIGHTS_PATH, cache_subdir='models', file_hash='64373286793e3c8b2b4e3219cbf3544b') else: weights_path = keras_utils.get_file( 'vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5', WEIGHTS_PATH_NO_TOP, cache_subdir='models', file_hash='6d6bbae143d832006294945121d1f1fc') model.load_weights(weights_path) if backend.backend() == 'theano': keras_utils.convert_all_kernels_in_model(model) elif weights is not None: model.load_weights(weights) return model, bap_features, end_points
def ResNet50(include_top=True, weights='imagenet', input_tensor=None, input_shape=None, pooling=None, classes=1000, **kwargs): """Instantiates the ResNet50 architecture. Optionally loads weights pre-trained on ImageNet. Note that the data format convention used by the model is the one specified in your Keras config at `~/.keras/keras.json`. # Arguments include_top: whether to include the fully-connected layer at the top of the network. weights: one of `None` (random initialization), 'imagenet' (pre-training on ImageNet), or the path to the weights file to be loaded. input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) to use as image input for the model. input_shape: optional shape tuple, only to be specified if `include_top` is False (otherwise the input shape has to be `(224, 224, 3)` (with `channels_last` data format) or `(3, 224, 224)` (with `channels_first` data format). It should have exactly 3 inputs channels, and width and height should be no smaller than 32. E.g. `(200, 200, 3)` would be one valid value. pooling: Optional pooling mode for feature extraction when `include_top` is `False`. - `None` means that the output of the model will be the 4D tensor output of the last convolutional block. - `avg` means that global average pooling will be applied to the output of the last convolutional block, and thus the output of the model will be a 2D tensor. - `max` means that global max pooling will be applied. classes: optional number of classes to classify images into, only to be specified if `include_top` is True, and if no `weights` argument is specified. # Returns A Keras model instance. # Raises ValueError: in case of invalid argument for `weights`, or invalid input shape. """ global backend, layers, models, keras_utils backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if not (weights in {'imagenet', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') if weights == 'imagenet' and include_top and classes != 1000: raise ValueError('If using `weights` as `"imagenet"` with `include_top`' ' as true, `classes` should be 1000') # Determine proper input shape input_shape = _obtain_input_shape(input_shape, default_size=224, min_size=32, data_format=backend.image_data_format(), require_flatten=include_top, weights=weights) if input_tensor is None: img_input = layers.Input(shape=input_shape) else: if not backend.is_keras_tensor(input_tensor): img_input = layers.Input(tensor=input_tensor, shape=input_shape) else: img_input = input_tensor if backend.image_data_format() == 'channels_last': bn_axis = 3 else: bn_axis = 1 x = layers.ZeroPadding2D(padding=(3, 3), name='conv1_pad')(img_input) x = layers.Conv2D(64, (7, 7), strides=(2, 2), padding='valid', kernel_initializer='he_normal', name='conv1')(x) x = layers.BatchNormalization(axis=bn_axis, name='bn_conv1')(x) x = layers.Activation('relu')(x) x = layers.ZeroPadding2D(padding=(1, 1), name='pool1_pad')(x) x = layers.MaxPooling2D((3, 3), strides=(2, 2))(x) x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1)) x = identity_block(x, 3, [64, 64, 256], stage=2, block='b') x = identity_block(x, 3, [64, 64, 256], stage=2, block='c') x = conv_block(x, 3, [128, 128, 512], stage=3, block='a') x = identity_block(x, 3, [128, 128, 512], stage=3, block='b') x = identity_block(x, 3, [128, 128, 512], stage=3, block='c') x = identity_block(x, 3, [128, 128, 512], stage=3, block='d') x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a') x = identity_block(x, 3, [256, 256, 1024], stage=4, block='b') x = identity_block(x, 3, [256, 256, 1024], stage=4, block='c') x = identity_block(x, 3, [256, 256, 1024], stage=4, block='d') x = identity_block(x, 3, [256, 256, 1024], stage=4, block='e') x = identity_block(x, 3, [256, 256, 1024], stage=4, block='f') x = conv_block(x, 3, [512, 512, 2048], stage=5, block='a') x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b') x = identity_block(x, 3, [512, 512, 2048], stage=5, block='c') if include_top: x = layers.GlobalAveragePooling2D(name='avg_pool')(x) x = layers.Dense(classes, activation='softmax', name='fc1000')(x) else: if pooling == 'avg': x = layers.GlobalAveragePooling2D()(x) elif pooling == 'max': x = layers.GlobalMaxPooling2D()(x) else: warnings.warn('The output shape of `ResNet50(include_top=False)` ' 'has been changed since Keras 2.2.0.') # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = keras_utils.get_source_inputs(input_tensor) else: inputs = img_input # Create model. model = models.Model(inputs, x, name='resnet50') # Load weights. if weights == 'imagenet': if include_top: weights_path = keras_utils.get_file( 'resnet50_weights_tf_dim_ordering_tf_kernels.h5', WEIGHTS_PATH, cache_subdir='models', md5_hash='a7b3fe01876f51b976af0dea6bc144eb') else: weights_path = keras_utils.get_file( 'resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5', WEIGHTS_PATH_NO_TOP, cache_subdir='models', md5_hash='a268eb855778b3df3c7506639542a6af') model.load_weights(weights_path) if backend.backend() == 'theano': keras_utils.convert_all_kernels_in_model(model) elif weights is not None: model.load_weights(weights) return model
def MobileNetV2(input_shape=None, alpha=1.0, include_top=True, weights='imagenet', input_tensor=None, pooling=None, classes=1000, **kwargs): """Instantiates the MobileNetV2 architecture. # Arguments input_shape: optional shape tuple, to be specified if you would like to use a model with an input img resolution that is not (224, 224, 3). It should have exactly 3 inputs channels (224, 224, 3). You can also omit this option if you would like to infer input_shape from an input_tensor. If you choose to include both input_tensor and input_shape then input_shape will be used if they match, if the shapes do not match then we will throw an error. E.g. `(160, 160, 3)` would be one valid value. alpha: controls the width of the network. This is known as the width multiplier in the MobileNetV2 paper, but the name is kept for consistency with MobileNetV1 in Keras. - If `alpha` < 1.0, proportionally decreases the number of filters in each layer. - If `alpha` > 1.0, proportionally increases the number of filters in each layer. - If `alpha` = 1, default number of filters from the paper are used at each layer. include_top: whether to include the fully-connected layer at the top of the network. weights: one of `None` (random initialization), 'imagenet' (pre-training on ImageNet), or the path to the weights file to be loaded. input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) to use as image input for the model. pooling: Optional pooling mode for feature extraction when `include_top` is `False`. - `None` means that the output of the model will be the 4D tensor output of the last convolutional block. - `avg` means that global average pooling will be applied to the output of the last convolutional block, and thus the output of the model will be a 2D tensor. - `max` means that global max pooling will be applied. classes: optional number of classes to classify images into, only to be specified if `include_top` is True, and if no `weights` argument is specified. # Returns A Keras model instance. # Raises ValueError: in case of invalid argument for `weights`, or invalid input shape or invalid alpha, rows when weights='imagenet' """ global backend, layers, models, keras_utils backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if not (weights in {'imagenet', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') if weights == 'imagenet' and include_top and classes != 1000: raise ValueError( 'If using `weights` as `"imagenet"` with `include_top` ' 'as true, `classes` should be 1000') # Determine proper input shape and default size. # If both input_shape and input_tensor are used, they should match if input_shape is not None and input_tensor is not None: try: is_input_t_tensor = backend.is_keras_tensor(input_tensor) except ValueError: try: is_input_t_tensor = backend.is_keras_tensor( keras_utils.get_source_inputs(input_tensor)) except ValueError: raise ValueError('input_tensor: ', input_tensor, 'is not type input_tensor') if is_input_t_tensor: if backend.image_data_format == 'channels_first': if backend.int_shape(input_tensor)[1] != input_shape[1]: raise ValueError( 'input_shape: ', input_shape, 'and input_tensor: ', input_tensor, 'do not meet the same shape requirements') else: if backend.int_shape(input_tensor)[2] != input_shape[1]: raise ValueError( 'input_shape: ', input_shape, 'and input_tensor: ', input_tensor, 'do not meet the same shape requirements') else: raise ValueError('input_tensor specified: ', input_tensor, 'is not a keras tensor') # If input_shape is None, infer shape from input_tensor if input_shape is None and input_tensor is not None: try: backend.is_keras_tensor(input_tensor) except ValueError: raise ValueError('input_tensor: ', input_tensor, 'is type: ', type(input_tensor), 'which is not a valid type') if input_shape is None and not backend.is_keras_tensor(input_tensor): default_size = 224 elif input_shape is None and backend.is_keras_tensor(input_tensor): if backend.image_data_format() == 'channels_first': rows = backend.int_shape(input_tensor)[2] cols = backend.int_shape(input_tensor)[3] else: rows = backend.int_shape(input_tensor)[1] cols = backend.int_shape(input_tensor)[2] if rows == cols and rows in [96, 128, 160, 192, 224]: default_size = rows else: default_size = 224 # If input_shape is None and no input_tensor elif input_shape is None: default_size = 224 # If input_shape is not None, assume default size else: if backend.image_data_format() == 'channels_first': rows = input_shape[1] cols = input_shape[2] else: rows = input_shape[0] cols = input_shape[1] if rows == cols and rows in [96, 128, 160, 192, 224]: default_size = rows else: default_size = 224 input_shape = _obtain_input_shape(input_shape, default_size=default_size, min_size=32, data_format=backend.image_data_format(), require_flatten=include_top, weights=weights) if backend.image_data_format() == 'channels_last': row_axis, col_axis = (0, 1) else: row_axis, col_axis = (1, 2) rows = input_shape[row_axis] cols = input_shape[col_axis] if weights == 'imagenet': if alpha not in [0.35, 0.50, 0.75, 1.0, 1.3, 1.4]: raise ValueError('If imagenet weights are being loaded, ' 'alpha can be one of `0.35`, `0.50`, `0.75`, ' '`1.0`, `1.3` or `1.4` only.') if rows != cols or rows not in [96, 128, 160, 192, 224]: if rows is None: rows = 224 warnings.warn('MobileNet shape is undefined.' ' Weights for input shape' '(224, 224) will be loaded.') else: raise ValueError('If imagenet weights are being loaded, ' 'input must have a static square shape' '(one of (96, 96), (128, 128), (160, 160),' '(192, 192), or (224, 224)).' 'Input shape provided = %s' % (input_shape, )) if backend.image_data_format() != 'channels_last': warnings.warn('The MobileNet family of models is only available ' 'for the input data format "channels_last" ' '(width, height, channels). ' 'However your settings specify the default ' 'data format "channels_first" (channels, width, height).' ' You should set `image_data_format="channels_last"` ' 'in your Keras config located at ~/.keras/keras.json. ' 'The model being returned right now will expect inputs ' 'to follow the "channels_last" data format.') backend.set_image_data_format('channels_last') old_data_format = 'channels_first' else: old_data_format = None if input_tensor is None: img_input = layers.Input(shape=input_shape) else: if not backend.is_keras_tensor(input_tensor): img_input = layers.Input(tensor=input_tensor, shape=input_shape) else: img_input = input_tensor first_block_filters = _make_divisible(32 * alpha, 8) x = layers.ZeroPadding2D(padding=correct_pad(backend, img_input, 3), name='Conv1_pad')(img_input) x = layers.Conv2D(first_block_filters, kernel_size=3, strides=(2, 2), padding='valid', use_bias=False, name='Conv1')(x) x = layers.BatchNormalization(epsilon=1e-3, momentum=0.999, name='bn_Conv1')(x) x = layers.ReLU(6., name='Conv1_relu')(x) x = _inverted_res_block(x, filters=16, alpha=alpha, stride=1, expansion=1, block_id=0) x = _inverted_res_block(x, filters=24, alpha=alpha, stride=2, expansion=6, block_id=1) x = _inverted_res_block(x, filters=24, alpha=alpha, stride=1, expansion=6, block_id=2) x = _inverted_res_block(x, filters=32, alpha=alpha, stride=2, expansion=6, block_id=3) x = _inverted_res_block(x, filters=32, alpha=alpha, stride=1, expansion=6, block_id=4) x = _inverted_res_block(x, filters=32, alpha=alpha, stride=1, expansion=6, block_id=5) x = _inverted_res_block(x, filters=64, alpha=alpha, stride=2, expansion=6, block_id=6) x = _inverted_res_block(x, filters=64, alpha=alpha, stride=1, expansion=6, block_id=7) x = _inverted_res_block(x, filters=64, alpha=alpha, stride=1, expansion=6, block_id=8) x = _inverted_res_block(x, filters=64, alpha=alpha, stride=1, expansion=6, block_id=9) x = _inverted_res_block(x, filters=96, alpha=alpha, stride=1, expansion=6, block_id=10) x = _inverted_res_block(x, filters=96, alpha=alpha, stride=1, expansion=6, block_id=11) x = _inverted_res_block(x, filters=96, alpha=alpha, stride=1, expansion=6, block_id=12) x = _inverted_res_block(x, filters=160, alpha=alpha, stride=2, expansion=6, block_id=13) x = _inverted_res_block(x, filters=160, alpha=alpha, stride=1, expansion=6, block_id=14) x = _inverted_res_block(x, filters=160, alpha=alpha, stride=1, expansion=6, block_id=15) x = _inverted_res_block(x, filters=320, alpha=alpha, stride=1, expansion=6, block_id=16) # no alpha applied to last conv as stated in the paper: # if the width multiplier is greater than 1 we # increase the number of output channels # if alpha > 1.0: # last_block_filters = _make_divisible(1280 * alpha, 8) # else: # last_block_filters = 1280 # x = layers.Conv2D(last_block_filters, # kernel_size=1, # use_bias=False, # name='Conv_1')(x) # x = layers.BatchNormalization(epsilon=1e-3, # momentum=0.999, # name='Conv_1_bn')(x) # x = layers.ReLU(6., name='out_relu')(x) if include_top: x = layers.GlobalAveragePooling2D()(x) x = layers.Dropout(.2)(x) x = layers.Dense(256, activation='relu')(x) x = layers.Dropout(.5)(x) x = layers.Dense(classes, activation='softmax')(x) else: if pooling == 'avg': x = layers.GlobalAveragePooling2D()(x) elif pooling == 'max': x = layers.GlobalMaxPooling2D()(x) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = keras_utils.get_source_inputs(input_tensor) else: inputs = img_input # Create model. model = models.Model(inputs, x, name='mobilenetv2_%0.2f_%s' % (alpha, rows)) # Load weights. if weights == 'imagenet': if backend.image_data_format() == 'channels_first': raise ValueError('Weights for "channels_first" format ' 'are not available.') if include_top: model_name = ('mobilenet_v2_weights_tf_dim_ordering_tf_kernels_' + str(alpha) + '_' + str(rows) + '.h5') weigh_path = BASE_WEIGHT_PATH + model_name weights_path = keras_utils.get_file(model_name, weigh_path, cache_subdir='models') else: model_name = ('mobilenet_v2_weights_tf_dim_ordering_tf_kernels_' + str(alpha) + '_' + str(rows) + '_no_top' + '.h5') weigh_path = BASE_WEIGHT_PATH + model_name weights_path = keras_utils.get_file(model_name, weigh_path, cache_subdir='models') model.load_weights(weights_path) elif weights is not None: model.load_weights(weights) if old_data_format: backend.set_image_data_format(old_data_format) return model
def Conv2dGn( filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, use_groupnorm=False, groupnorm_groups=None, drop_rate=None, **kwargs ): """Extension of Conv2D layer with groupnorm""" conv_name, act_name, gn_name = None, None, None block_name = kwargs.pop('name', None) backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if block_name is not None: conv_name = block_name + '_conv' if block_name is not None and activation is not None: act_str = activation.__name__ if callable(activation) else str(activation) act_name = block_name + '_' + act_str if block_name is not None and use_groupnorm: gn_name = block_name + '_gn' if block_name is not None and drop_rate != None: drop_name = block_name + '_drop' gn_axis = 3 if backend.image_data_format() == 'channels_last' else 1 def wrapper(input_tensor): x = layers.Conv2D( filters=filters, kernel_size=kernel_size, strides=strides, padding=padding, data_format=data_format, dilation_rate=dilation_rate, activation=None, use_bias=not (use_groupnorm), kernel_initializer=kernel_initializer, bias_initializer=bias_initializer, kernel_regularizer=kernel_regularizer, bias_regularizer=bias_regularizer, activity_regularizer=activity_regularizer, kernel_constraint=kernel_constraint, bias_constraint=bias_constraint, name=conv_name, )(input_tensor) if groupnorm_groups == None and use_groupnorm: raise ValueError('Conflict in params detected. Check groupnorm_groups and use_groupnorm are coherent') if use_groupnorm and groupnorm_groups != None: x = tfa.layers.GroupNormalization(groups=groupnorm_groups, axis=gn_axis, name=gn_name)(x) if drop_rate != None: x = layers.Dropout(rate=drop_rate, name=drop_name)(x) if activation: x = layers.Activation(activation, name=act_name)(x) return x return wrapper
def ResNet(stack_fn, preact, use_bias, model_name='resnet', include_top=True, weights='imagenet', input_tensor=None, input_shape=None, pooling=None, classes=1000, **kwargs): """Instantiates the ResNet, ResNetV2, and ResNeXt architecture. Optionally loads weights pre-trained on ImageNet. Note that the data format convention used by the model is the one specified in your Keras config at `~/.keras/keras.json`. # Arguments stack_fn: a function that returns output tensor for the stacked residual blocks. preact: whether to use pre-activation or not (True for ResNetV2, False for ResNet and ResNeXt). use_bias: whether to use biases for convolutional layers or not (True for ResNet and ResNetV2, False for ResNeXt). model_name: string, model name. include_top: whether to include the fully-connected layer at the top of the network. weights: one of `None` (random initialization), 'imagenet' (pre-training on ImageNet), or the path to the weights file to be loaded. input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) to use as image input for the model. input_shape: optional shape tuple, only to be specified if `include_top` is False (otherwise the input shape has to be `(224, 224, 3)` (with `channels_last` data format) or `(3, 224, 224)` (with `channels_first` data format). It should have exactly 3 inputs channels. pooling: optional pooling mode for feature extraction when `include_top` is `False`. - `None` means that the output of the model will be the 4D tensor output of the last convolutional layer. - `avg` means that global average pooling will be applied to the output of the last convolutional layer, and thus the output of the model will be a 2D tensor. - `max` means that global max pooling will be applied. classes: optional number of classes to classify images into, only to be specified if `include_top` is True, and if no `weights` argument is specified. # Returns A Keras model instance. # Raises ValueError: in case of invalid argument for `weights`, or invalid input shape. """ global backend, layers, models, keras_utils # pylint: disable=global-statement backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if not (weights in {'imagenet', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') if weights == 'imagenet' and include_top and classes != 1000: raise ValueError( 'If using `weights` as `"imagenet"` with `include_top`' ' as true, `classes` should be 1000') # Determine proper input shape input_shape = _obtain_input_shape(input_shape, default_size=224, min_size=32, data_format=backend.image_data_format(), require_flatten=include_top, weights=weights) if input_tensor is None: img_input = layers.Input(shape=input_shape) else: if not backend.is_keras_tensor(input_tensor): img_input = layers.Input(tensor=input_tensor, shape=input_shape) else: img_input = input_tensor bn_axis = 3 if backend.image_data_format() == 'channels_last' else 1 x = layers.ZeroPadding2D(padding=((3, 3), (3, 3)), name='conv1_pad')(img_input) x = layers.Conv2D(64, 7, strides=2, use_bias=use_bias, name='conv1_conv')(x) if preact is False: x = layers.BatchNormalization(axis=bn_axis, epsilon=1.001e-5, name='conv1_bn')(x) x = layers.Activation('relu', name='conv1_relu')(x) x = layers.ZeroPadding2D(padding=((1, 1), (1, 1)), name='pool1_pad')(x) x = layers.MaxPooling2D(3, strides=2, name='pool1_pool')(x) x = stack_fn(x) if preact is True: x = layers.BatchNormalization(axis=bn_axis, epsilon=1.001e-5, name='post_bn')(x) x = layers.Activation('relu', name='post_relu')(x) if include_top: x = layers.GlobalAveragePooling2D(name='avg_pool')(x) x = layers.Dense(classes, activation='softmax', name='probs')(x) else: if pooling == 'avg': x = layers.GlobalAveragePooling2D(name='avg_pool')(x) elif pooling == 'max': x = layers.GlobalMaxPooling2D(name='max_pool')(x) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = keras_utils.get_source_inputs(input_tensor) else: inputs = img_input # Create model. model = models.Model(inputs, x, name=model_name) # Load weights. if (weights == 'imagenet') and (model_name in WEIGHTS_HASHES): if include_top: file_name = model_name + '_weights_tf_dim_ordering_tf_kernels.h5' file_hash = WEIGHTS_HASHES[model_name][0] else: file_name = model_name + '_weights_tf_dim_ordering_tf_kernels_notop.h5' file_hash = WEIGHTS_HASHES[model_name][1] weights_path = keras_utils.get_file(file_name, BASE_WEIGHTS_PATH + file_name, cache_subdir='models', file_hash=file_hash) model.load_weights(weights_path) elif weights is not None: model.load_weights(weights) return model
def VGG16(include_top=True, weights='imagenet', input_tensor=None, input_shape=None, pooling=None, classes=1000, **kwargs): """Instantiates the VGG16 architecture. Optionally loads weights pre-trained on ImageNet. Note that the data format convention used by the model is the one specified in your Keras config at `~/.keras/keras.json`. # Arguments include_top: whether to include the 3 fully-connected layers at the top of the network. weights: one of `None` (random initialization), 'imagenet' (pre-training on ImageNet), or the path to the weights file to be loaded. input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) to use as image input for the model. input_shape: optional shape tuple, only to be specified if `include_top` is False (otherwise the input shape has to be `(224, 224, 3)` (with `channels_last` data format) or `(3, 224, 224)` (with `channels_first` data format). It should have exactly 3 input channels, and width and height should be no smaller than 32. E.g. `(200, 200, 3)` would be one valid value. pooling: Optional pooling mode for feature extraction when `include_top` is `False`. - `None` means that the output of the model will be the 4D tensor output of the last convolutional block. - `avg` means that global average pooling will be applied to the output of the last convolutional block, and thus the output of the model will be a 2D tensor. - `max` means that global max pooling will be applied. classes: optional number of classes to classify images into, only to be specified if `include_top` is True, and if no `weights` argument is specified. # Returns A Keras model instance. # Raises ValueError: in case of invalid argument for `weights`, or invalid input shape. """ backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if not (weights in {'imagenet', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') # Determine proper input shape input_shape = _obtain_input_shape(input_shape, default_size=224, min_size=32, data_format=backend.image_data_format(), require_flatten=include_top, weights=weights) if input_tensor is None: img_input = layers.Input(shape=input_shape) else: if not backend.is_keras_tensor(input_tensor): img_input = layers.Input(tensor=input_tensor, shape=input_shape) else: img_input = input_tensor x = layers.Lambda(lambda z: z / 128.0)(img_input) # Block 1 x = layers.Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv1')(x) x = layers.Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv2')(x) x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(x) # Block 2 x = layers.Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv1')(x) x = layers.Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv2')(x) x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x) # Block 3 x = layers.Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv1')(x) x = layers.Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv2')(x) x = layers.Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv3')(x) x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x) # Block 4 x = layers.Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv1')(x) x = layers.Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv2')(x) x = layers.Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv3')(x) x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x) # Block 5 x = layers.Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv1')(x) x = layers.Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv2')(x) x = layers.Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3')(x) x = layers.MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x) if include_top: # Classification block x = layers.Flatten(name='flatten')(x) x = layers.Dense(4096, activation='relu', name='fc1')(x) x = layers.Dense(4096, activation='relu', name='fc2')(x) x = layers.Dense(classes, activation='softmax', name='predictions2')(x) else: if pooling == 'avg': x = layers.GlobalAveragePooling2D()(x) elif pooling == 'max': x = layers.GlobalMaxPooling2D()(x) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = keras_utils.get_source_inputs(input_tensor) else: inputs = img_input # Create model. model = models.Model(inputs, x, name='vgg16') # Load weights. if weights == 'imagenet': if include_top: weights_path = keras_utils.get_file( 'vgg16_weights_tf_dim_ordering_tf_kernels.h5', WEIGHTS_PATH, cache_subdir='models', file_hash='64373286793e3c8b2b4e3219cbf3544b') else: weights_path = keras_utils.get_file( 'vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5', WEIGHTS_PATH_NO_TOP, cache_subdir='models', file_hash='6d6bbae143d832006294945121d1f1fc') model.load_weights(weights_path,by_name=True) if backend.backend() == 'theano': keras_utils.convert_all_kernels_in_model(model) elif weights is not None: model.load_weights(weights) return model
def Linknet(backbone_name='vgg16', input_shape=(None, None, 3), classes=1, activation='sigmoid', weights=None, encoder_weights='imagenet', encoder_freeze=False, encoder_features='default', decoder_block_type='upsampling', decoder_filters=(None, None, None, None, 16), decoder_use_batchnorm=True, **kwargs): """Linknet_ is a fully convolution neural network for fast image semantic segmentation Note: This implementation by default has 4 skip connections (original - 3). Args: backbone_name: name of classification model (without last dense layers) used as feature extractor to build segmentation model. input_shape: shape of input data/image ``(H, W, C)``, in general case you do not need to set ``H`` and ``W`` shapes, just pass ``(None, None, C)`` to make your model be able to process images af any size, but ``H`` and ``W`` of input images should be divisible by factor ``32``. classes: a number of classes for output (output shape - ``(h, w, classes)``). activation: name of one of ``keras.activations`` for last model layer (e.g. ``sigmoid``, ``softmax``, ``linear``). weights: optional, path to model weights. encoder_weights: one of ``None`` (random initialization), ``imagenet`` (pre-training on ImageNet). encoder_freeze: if ``True`` set all layers of encoder (backbone model) as non-trainable. encoder_features: a list of layer numbers or names starting from top of the model. Each of these layers will be concatenated with corresponding decoder block. If ``default`` is used layer names are taken from ``DEFAULT_SKIP_CONNECTIONS``. decoder_filters: list of numbers of ``Conv2D`` layer filters in decoder blocks, for block with skip connection a number of filters is equal to number of filters in corresponding encoder block (estimates automatically and can be passed as ``None`` value). decoder_use_batchnorm: if ``True``, ``BatchNormalisation`` layer between ``Conv2D`` and ``Activation`` layers is used. decoder_block_type: one of - `upsampling`: use ``UpSampling2D`` keras layer - `transpose`: use ``Transpose2D`` keras layer Returns: ``keras.models.Model``: **Linknet** .. _Linknet: https://arxiv.org/pdf/1707.03718.pdf """ global backend, layers, models, keras_utils backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if decoder_block_type == 'upsampling': decoder_block = DecoderUpsamplingX2Block elif decoder_block_type == 'transpose': decoder_block = DecoderTransposeX2Block else: raise ValueError( 'Decoder block type should be in ("upsampling", "transpose"). ' 'Got: {}'.format(decoder_block_type)) backbone = Backbones.get_backbone( backbone_name, input_shape=input_shape, weights=encoder_weights, include_top=False, **kwargs, ) if encoder_features == 'default': encoder_features = Backbones.get_feature_layers(backbone_name, n=4) model = build_linknet( backbone=backbone, decoder_block=decoder_block, skip_connection_layers=encoder_features, decoder_filters=decoder_filters, classes=classes, activation=activation, n_upsample_blocks=len(decoder_filters), use_batchnorm=decoder_use_batchnorm, ) # lock encoder weights for fine-tuning if encoder_freeze: freeze_model(backbone, **kwargs) # loading model weights if weights is not None: model.load_weights(weights) return model
def DenseNet(blocks, include_top=True, weights='vggface2', input_tensor=None, input_shape=None, pooling=None, classes=1000, lpf_size=1, **kwargs): """Instantiates the DenseNet architecture. Optionally loads weights pre-trained on ImageNet. Note that the data format convention used by the model is the one specified in your Keras config at `~/.keras/keras.json`. # Arguments blocks: numbers of building blocks for the four dense layers. include_top: whether to include the fully-connected layer at the top of the network. weights: one of `None` (random initialization), 'imagenet' (pre-training on ImageNet), or the path to the weights file to be loaded. input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) to use as image input for the model. input_shape: optional shape tuple, only to be specified if `include_top` is False (otherwise the input shape has to be `(224, 224, 3)` (with `'channels_last'` data format) or `(3, 224, 224)` (with `'channels_first'` data format). It should have exactly 3 inputs channels, and width and height should be no smaller than 32. pooling: optional pooling mode for feature extraction E.g. `(200, 200, 3)` would be one valid value. when `include_top` is `False`. - `None` means that the output of the model will be the 4D tensor output of the last convolutional block. - `avg` means that global average pooling will be applied to the output of the last convolutional block, and thus the output of the model will be a 2D tensor. - `max` means that global max pooling will be applied. classes: optional number of classes to classify images into, only to be specified if `include_top` is True, and if no `weights` argument is specified. # Returns A Keras model instance. # Raises ValueError: in case of invalid argument for `weights`, or invalid input shape. """ global backend, layers, models, keras_utils backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if not (weights in {'imagenet', 'vggface2', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') if weights == 'imagenet' and include_top and classes != 1000: raise ValueError( 'If using `weights` as `"imagenet"` with `include_top`' ' as true, `classes` should be 1000') # Determine proper input shape input_shape = _obtain_input_shape(input_shape, default_size=224, min_size=32, data_format=backend.image_data_format(), require_flatten=include_top, weights=weights) if input_tensor is None: img_input = layers.Input(shape=input_shape) else: if not backend.is_keras_tensor(input_tensor): img_input = layers.Input(tensor=input_tensor, shape=input_shape) else: img_input = input_tensor bn_axis = 3 if backend.image_data_format() == 'channels_last' else 1 x = layers.ZeroPadding2D(padding=((3, 3), (3, 3)))(img_input) x = LPFConv2D(64, 7, strides=2, use_bias=False, name='conv1/conv', lpf_size=lpf_size)(x) x = layers.BatchNormalization(axis=bn_axis, epsilon=1.001e-5, name='conv1/bn')(x) x = layers.Activation('relu', name='conv1/relu')(x) x = layers.ZeroPadding2D(padding=((1, 1), (1, 1)))(x) x = LPFMaxPooling2D(3, strides=2, name='pool1', lpf_size=lpf_size)(x) x = dense_block(x, blocks[0], name='conv2') x = transition_block(x, 0.5, name='pool2', lpf_size=lpf_size) x = dense_block(x, blocks[1], name='conv3') x = transition_block(x, 0.5, name='pool3', lpf_size=lpf_size) x = dense_block(x, blocks[2], name='conv4') x = transition_block(x, 0.5, name='pool4', lpf_size=lpf_size) x = dense_block(x, blocks[3], name='conv5') x = layers.BatchNormalization(axis=bn_axis, epsilon=1.001e-5, name='bn')(x) x = layers.Activation('relu', name='relu')(x) if include_top: x = layers.GlobalAveragePooling2D(name='avg_pool')(x) x = layers.Dense(classes, activation='softmax', name='fc%d' % classes)(x) else: if pooling == 'avg': x = layers.GlobalAveragePooling2D(name='avg_pool')(x) elif pooling == 'max': x = layers.GlobalMaxPooling2D(name='max_pool')(x) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = keras_utils.get_source_inputs(input_tensor) else: inputs = img_input # Create model. if blocks == [6, 12, 24, 16]: model = models.Model(inputs, x, name='densenet121') elif blocks == [6, 12, 32, 32]: model = models.Model(inputs, x, name='densenet169') elif blocks == [6, 12, 48, 32]: model = models.Model(inputs, x, name='densenet201') else: model = models.Model(inputs, x, name='densenet') # Load weights. if weights == 'imagenet': if include_top: if blocks == [6, 12, 24, 16]: weights_path = keras_utils.get_file( 'densenet121_weights_tf_dim_ordering_tf_kernels.h5', DENSENET121_WEIGHT_PATH, cache_subdir='models', file_hash='9d60b8095a5708f2dcce2bca79d332c7') elif blocks == [6, 12, 32, 32]: weights_path = keras_utils.get_file( 'densenet169_weights_tf_dim_ordering_tf_kernels.h5', DENSENET169_WEIGHT_PATH, cache_subdir='models', file_hash='d699b8f76981ab1b30698df4c175e90b') elif blocks == [6, 12, 48, 32]: weights_path = keras_utils.get_file( 'densenet201_weights_tf_dim_ordering_tf_kernels.h5', DENSENET201_WEIGHT_PATH, cache_subdir='models', file_hash='1ceb130c1ea1b78c3bf6114dbdfd8807') else: if blocks == [6, 12, 24, 16]: weights_path = keras_utils.get_file( 'densenet121_weights_tf_dim_ordering_tf_kernels_notop.h5', DENSENET121_WEIGHT_PATH_NO_TOP, cache_subdir='models', file_hash='30ee3e1110167f948a6b9946edeeb738') elif blocks == [6, 12, 32, 32]: weights_path = keras_utils.get_file( 'densenet169_weights_tf_dim_ordering_tf_kernels_notop.h5', DENSENET169_WEIGHT_PATH_NO_TOP, cache_subdir='models', file_hash='b8c4d4c20dd625c148057b9ff1c1176b') elif blocks == [6, 12, 48, 32]: weights_path = keras_utils.get_file( 'densenet201_weights_tf_dim_ordering_tf_kernels_notop.h5', DENSENET201_WEIGHT_PATH_NO_TOP, cache_subdir='models', file_hash='c13680b51ded0fb44dff2d8f86ac8bb1') model.load_weights(weights_path) elif weights == 'vggface2' and blocks == [6, 12, 24, 16]: weights_path = keras_utils.get_file( basename(DENSENET121_VGGFACE_WEIGHT_PATH), DENSENET121_VGGFACE_WEIGHT_PATH, cache_subdir='models', file_hash='8bb1ea084bc86ca5c1c55c8417da32b0') model.load_weights(weights_path, by_name=True) elif weights is not None: model.load_weights(weights, by_name=True) return model
def Xception(include_top=True, weights='vggface2', input_tensor=None, input_shape=None, pooling=None, classes=1000, lpf_size=1, **kwargs): """Instantiates the Xception architecture. Optionally loads weights pre-trained on ImageNet. Note that the data format convention used by the model is the one specified in your Keras config at `~/.keras/keras.json`. Note that the default input image size for this model is 299x299. # Arguments include_top: whether to include the fully-connected layer at the top of the network. weights: one of `None` (random initialization), 'imagenet' (pre-training on ImageNet), or the path to the weights file to be loaded. input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) to use as image input for the model. input_shape: optional shape tuple, only to be specified if `include_top` is False (otherwise the input shape has to be `(299, 299, 3)`. It should have exactly 3 inputs channels, and width and height should be no smaller than 71. E.g. `(150, 150, 3)` would be one valid value. pooling: Optional pooling mode for feature extraction when `include_top` is `False`. - `None` means that the output of the model will be the 4D tensor output of the last convolutional block. - `avg` means that global average pooling will be applied to the output of the last convolutional block, and thus the output of the model will be a 2D tensor. - `max` means that global max pooling will be applied. classes: optional number of classes to classify images into, only to be specified if `include_top` is True, and if no `weights` argument is specified. # Returns A Keras model instance. # Raises ValueError: in case of invalid argument for `weights`, or invalid input shape. RuntimeError: If attempting to run this model with a backend that does not support separable convolutions. """ backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if not (weights in {'imagenet', 'vggface2', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') if weights == 'imagenet' and include_top and classes != 1000: raise ValueError('If using `weights` as `"imagenet"` with `include_top`' ' as true, `classes` should be 1000') # Determine proper input shape input_shape = _obtain_input_shape(input_shape, default_size=299, min_size=71, data_format=backend.image_data_format(), require_flatten=include_top, weights=weights) if input_tensor is None: img_input = layers.Input(shape=input_shape) else: if not backend.is_keras_tensor(input_tensor): img_input = layers.Input(tensor=input_tensor, shape=input_shape) else: img_input = input_tensor channel_axis = 1 if backend.image_data_format() == 'channels_first' else -1 x = LPFConv2D(32, (3, 3), strides=(2, 2), lpf_size=lpf_size, use_bias=False, name='block1_conv1')(img_input) x = layers.BatchNormalization(axis=channel_axis, name='block1_conv1_bn')(x) x = layers.Activation('relu', name='block1_conv1_act')(x) x = layers.Conv2D(64, (3, 3), use_bias=False, name='block1_conv2')(x) x = layers.BatchNormalization(axis=channel_axis, name='block1_conv2_bn')(x) x = layers.Activation('relu', name='block1_conv2_act')(x) residual = LPFConv2D(128, (1, 1), strides=(2, 2), lpf_size=lpf_size, padding='same', use_bias=False)(x) residual = layers.BatchNormalization(axis=channel_axis)(residual) x = layers.SeparableConv2D(128, (3, 3), padding='same', use_bias=False, name='block2_sepconv1')(x) x = layers.BatchNormalization(axis=channel_axis, name='block2_sepconv1_bn')(x) x = layers.Activation('relu', name='block2_sepconv2_act')(x) x = layers.SeparableConv2D(128, (3, 3), padding='same', use_bias=False, name='block2_sepconv2')(x) x = layers.BatchNormalization(axis=channel_axis, name='block2_sepconv2_bn')(x) x = LPFMaxPooling2D((3, 3), strides=(2, 2), lpf_size=lpf_size, padding='same', name='block2_pool')(x) x = layers.add([x, residual]) residual = LPFConv2D(256, (1, 1), strides=(2, 2), lpf_size=lpf_size, padding='same', use_bias=False)(x) residual = layers.BatchNormalization(axis=channel_axis)(residual) x = layers.Activation('relu', name='block3_sepconv1_act')(x) x = layers.SeparableConv2D(256, (3, 3), padding='same', use_bias=False, name='block3_sepconv1')(x) x = layers.BatchNormalization(axis=channel_axis, name='block3_sepconv1_bn')(x) x = layers.Activation('relu', name='block3_sepconv2_act')(x) x = layers.SeparableConv2D(256, (3, 3), padding='same', use_bias=False, name='block3_sepconv2')(x) x = layers.BatchNormalization(axis=channel_axis, name='block3_sepconv2_bn')(x) x = LPFMaxPooling2D((3, 3), strides=(2, 2), lpf_size=lpf_size, padding='same', name='block3_pool')(x) x = layers.add([x, residual]) residual = LPFConv2D(728, (1, 1), strides=(2, 2), lpf_size=lpf_size, padding='same', use_bias=False)(x) residual = layers.BatchNormalization(axis=channel_axis)(residual) x = layers.Activation('relu', name='block4_sepconv1_act')(x) x = layers.SeparableConv2D(728, (3, 3), padding='same', use_bias=False, name='block4_sepconv1')(x) x = layers.BatchNormalization(axis=channel_axis, name='block4_sepconv1_bn')(x) x = layers.Activation('relu', name='block4_sepconv2_act')(x) x = layers.SeparableConv2D(728, (3, 3), padding='same', use_bias=False, name='block4_sepconv2')(x) x = layers.BatchNormalization(axis=channel_axis, name='block4_sepconv2_bn')(x) x = LPFMaxPooling2D((3, 3), strides=(2, 2), lpf_size=lpf_size, padding='same', name='block4_pool')(x) x = layers.add([x, residual]) for i in range(8): residual = x prefix = 'block' + str(i + 5) x = layers.Activation('relu', name=prefix + '_sepconv1_act')(x) x = layers.SeparableConv2D(728, (3, 3), padding='same', use_bias=False, name=prefix + '_sepconv1')(x) x = layers.BatchNormalization(axis=channel_axis, name=prefix + '_sepconv1_bn')(x) x = layers.Activation('relu', name=prefix + '_sepconv2_act')(x) x = layers.SeparableConv2D(728, (3, 3), padding='same', use_bias=False, name=prefix + '_sepconv2')(x) x = layers.BatchNormalization(axis=channel_axis, name=prefix + '_sepconv2_bn')(x) x = layers.Activation('relu', name=prefix + '_sepconv3_act')(x) x = layers.SeparableConv2D(728, (3, 3), padding='same', use_bias=False, name=prefix + '_sepconv3')(x) x = layers.BatchNormalization(axis=channel_axis, name=prefix + '_sepconv3_bn')(x) x = layers.add([x, residual]) residual = LPFConv2D(1024, (1, 1), strides=(2, 2), lpf_size=lpf_size, padding='same', use_bias=False)(x) residual = layers.BatchNormalization(axis=channel_axis)(residual) x = layers.Activation('relu', name='block13_sepconv1_act')(x) x = layers.SeparableConv2D(728, (3, 3), padding='same', use_bias=False, name='block13_sepconv1')(x) x = layers.BatchNormalization(axis=channel_axis, name='block13_sepconv1_bn')(x) x = layers.Activation('relu', name='block13_sepconv2_act')(x) x = layers.SeparableConv2D(1024, (3, 3), padding='same', use_bias=False, name='block13_sepconv2')(x) x = layers.BatchNormalization(axis=channel_axis, name='block13_sepconv2_bn')(x) x = LPFMaxPooling2D((3, 3), strides=(2, 2), lpf_size=lpf_size, padding='same', name='block13_pool')(x) x = layers.add([x, residual]) x = layers.SeparableConv2D(1536, (3, 3), padding='same', use_bias=False, name='block14_sepconv1')(x) x = layers.BatchNormalization(axis=channel_axis, name='block14_sepconv1_bn')(x) x = layers.Activation('relu', name='block14_sepconv1_act')(x) x = layers.SeparableConv2D(2048, (3, 3), padding='same', use_bias=False, name='block14_sepconv2')(x) x = layers.BatchNormalization(axis=channel_axis, name='block14_sepconv2_bn')(x) x = layers.Activation('relu', name='block14_sepconv2_act')(x) if include_top: x = layers.GlobalAveragePooling2D(name='avg_pool')(x) x = layers.Dense(classes, activation='softmax', name='predictions%s'%('' if classes=='' else str(classes)) )(x) else: if pooling == 'avg': x = layers.GlobalAveragePooling2D()(x) elif pooling == 'max': x = layers.GlobalMaxPooling2D()(x) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = keras_utils.get_source_inputs(input_tensor) else: inputs = img_input # Create model. model = models.Model(inputs, x, name='xception') # Load weights. if weights == 'imagenet': if include_top: weights_path = keras_utils.get_file( 'xception_weights_tf_dim_ordering_tf_kernels.h5', TF_WEIGHTS_PATH, cache_subdir='models', file_hash='0a58e3b7378bc2990ea3b43d5981f1f6') else: weights_path = keras_utils.get_file( 'xception_weights_tf_dim_ordering_tf_kernels_notop.h5', TF_WEIGHTS_PATH_NO_TOP, cache_subdir='models', file_hash='b0042744bf5b25fce3cb969f33bebb97') model.load_weights(weights_path) if backend.backend() == 'theano': keras_utils.convert_all_kernels_in_model(model) elif weights == 'vggface2': weights_path = keras_utils.get_file( basename(TF_VGGFACE_WEIGHTS_PATH), TF_VGGFACE_WEIGHTS_PATH, cache_subdir='models', file_hash='ca2c965451caa231c68baac819512f1f') elif weights is not None: model.load_weights(weights, by_name=True) return model
def myMobileNet(input_shape=None, alpha=1.0, depth_multiplier=1, dropout=1e-3, include_top=True, weights='imagenet', input_tensor=None, pooling=None, classes=1000, **kwargs): """Instantiates the MobileNet architecture. # Arguments input_shape: optional shape tuple, only to be specified if `include_top` is False (otherwise the input shape has to be `(224, 224, 3)` (with `channels_last` data format) or (3, 224, 224) (with `channels_first` data format). It should have exactly 3 inputs channels, and width and height should be no smaller than 32. E.g. `(200, 200, 3)` would be one valid value. alpha: controls the width of the network. This is known as the width multiplier in the MobileNet paper. - If `alpha` < 1.0, proportionally decreases the number of filters in each layer. - If `alpha` > 1.0, proportionally increases the number of filters in each layer. - If `alpha` = 1, default number of filters from the paper are used at each layer. depth_multiplier: depth multiplier for depthwise convolution. This is called the resolution multiplier in the MobileNet paper. dropout: dropout rate include_top: whether to include the fully-connected layer at the top of the network. weights: one of `None` (random initialization), 'imagenet' (pre-training on ImageNet), or the path to the weights file to be loaded. input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) to use as image input for the model. pooling: Optional pooling mode for feature extraction when `include_top` is `False`. - `None` means that the output of the model will be the 4D tensor output of the last convolutional block. - `avg` means that global average pooling will be applied to the output of the last convolutional block, and thus the output of the model will be a 2D tensor. - `max` means that global max pooling will be applied. classes: optional number of classes to classify images into, only to be specified if `include_top` is True, and if no `weights` argument is specified. # Returns A Keras model instance. # Raises ValueError: in case of invalid argument for `weights`, or invalid input shape. RuntimeError: If attempting to run this model with a backend that does not support separable convolutions. """ global backend, layers, models, keras_utils backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs) if not (weights in {'imagenet', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') if weights == 'imagenet' and include_top and classes != 1000: raise ValueError( 'If using `weights` as `"imagenet"` with `include_top` ' 'as true, `classes` should be 1000') # Determine proper input shape and default size. if input_shape is None: default_size = 224 else: if backend.image_data_format() == 'channels_first': rows = input_shape[1] cols = input_shape[2] else: rows = input_shape[0] cols = input_shape[1] if rows == cols and rows in [128, 160, 192, 224]: default_size = rows else: default_size = 224 input_shape = _obtain_input_shape(input_shape, default_size=default_size, min_size=32, data_format=backend.image_data_format(), require_flatten=include_top, weights=weights) if backend.image_data_format() == 'channels_last': row_axis, col_axis = (0, 1) else: row_axis, col_axis = (1, 2) rows = input_shape[row_axis] cols = input_shape[col_axis] if weights == 'imagenet': if depth_multiplier != 1: raise ValueError('If imagenet weights are being loaded, ' 'depth multiplier must be 1') if alpha not in [0.25, 0.50, 0.75, 1.0]: raise ValueError('If imagenet weights are being loaded, ' 'alpha can be one of' '`0.25`, `0.50`, `0.75` or `1.0` only.') if rows != cols or rows not in [128, 160, 192, 224]: rows = 224 warnings.warn('`input_shape` is undefined or non-square, ' 'or `rows` is not in [128, 160, 192, 224]. ' 'Weights for input shape (224, 224) will be' ' loaded as the default.') if input_tensor is None: img_input = layers.Input(shape=input_shape) else: if not backend.is_keras_tensor(input_tensor): img_input = layers.Input(tensor=input_tensor, shape=input_shape) else: img_input = input_tensor x = _conv_block(img_input, 32, alpha, strides=(2, 2)) x = _depthwise_conv_block(x, 64, alpha, depth_multiplier, block_id=1) x = _depthwise_conv_block(x, 128, alpha, depth_multiplier, strides=(2, 2), block_id=2) x = _depthwise_conv_block(x, 128, alpha, depth_multiplier, block_id=3) x = _depthwise_conv_block(x, 256, alpha, depth_multiplier, strides=(2, 2), block_id=4) x = _depthwise_conv_block(x, 256, alpha, depth_multiplier, block_id=5) x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, strides=(2, 2), block_id=6) x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=7) x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=8) x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=9) x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=10) x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=11) x = _depthwise_conv_block(x, 1024, alpha, depth_multiplier, strides=(2, 2), block_id=12) x = _depthwise_conv_block(x, 1024, alpha, depth_multiplier, block_id=13) if include_top: if backend.image_data_format() == 'channels_first': shape = (int(1024 * alpha), 1, 1) else: shape = (1, 1, int(1024 * alpha)) x = layers.GlobalAveragePooling2D()(x) x = layers.Reshape(shape, name='reshape_1')(x) x = layers.Dropout(dropout, name='dropout')(x) x = layers.Conv2D(classes, (1, 1), padding='same', name='conv_preds')(x) x = layers.Reshape((classes, ), name='reshape_2')(x) x = layers.Activation('softmax', name='act_softmax')(x) else: if pooling == 'avg': x = layers.GlobalAveragePooling2D()(x) elif pooling == 'max': x = layers.GlobalMaxPooling2D()(x) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = keras_utils.get_source_inputs(input_tensor) else: inputs = img_input # Create model. model = models.Model(inputs, x, name='mobilenet_%0.2f_%s' % (alpha, rows)) # Load weights. if weights == 'imagenet': if alpha == 1.0: alpha_text = '1_0' elif alpha == 0.75: alpha_text = '7_5' elif alpha == 0.50: alpha_text = '5_0' else: alpha_text = '2_5' if include_top: model_name = 'mobilenet_%s_%d_tf.h5' % (alpha_text, rows) weight_path = BASE_WEIGHT_PATH + model_name weights_path = keras_utils.get_file(model_name, weight_path, cache_subdir='models') else: model_name = 'mobilenet_%s_%d_tf_no_top.h5' % (alpha_text, rows) weight_path = BASE_WEIGHT_PATH + model_name weights_path = keras_utils.get_file(model_name, weight_path, cache_subdir='models') model.load_weights(weights_path) elif weights is not None: model.load_weights(weights) return model