def senet_conv_block(input_tensor, kernel_size, filters, stage, block, bias=False, lpf_size=1, strides=(2, 2)): se = senet_residual_block(input_tensor, kernel_size, filters, stage, block, bias, lpf_size, strides) if len(filters) > 2: conv1_proj_name = 'conv' + str(stage) + "_" + str(block) + "_1x1_proj" shortcut = LPFConv2D(filters[2], (1, 1), use_bias=bias, strides=strides, name=conv1_proj_name, lpf_size=lpf_size)(input_tensor) shortcut = BatchNormalization(axis=bn_axis, name=conv1_proj_name + "/bn", epsilon=bn_eps)(shortcut) m = layers.add([se, shortcut]) m = Activation('relu')(m) else: m = se return m
def get_residual(img_input, lpf_size, resnet_type=50): conv = senet_conv_block identity = senet_identity_block x = LPFConv2D(64, (7, 7), use_bias=False, strides=(2, 2), padding='same', name='conv1/7x7_s2', lpf_size=lpf_size)(img_input) x = BatchNormalization(axis=bn_axis, name='conv1/7x7_s2/bn', epsilon=bn_eps)(x) x = Activation('relu')(x) x = LPFMaxPooling2D((3, 3), strides=(2, 2), lpf_size=lpf_size)(x) s = [64, 64, 256] if resnet_type < 50: s = s[:-1] x = conv(x, 3, s, stage=2, block=1, strides=(1, 1), lpf_size=lpf_size) x = identity(x, 3, s, stage=2, block=2) if resnet_type > 18: x = identity(x, 3, s, stage=2, block=3) s = [128, 128, 512] if resnet_type < 50: s = s[:-1] x = conv(x, 3, s, stage=3, block=1, lpf_size=lpf_size) x = identity(x, 3, s, stage=3, block=2) if resnet_type > 18: x = identity(x, 3, s, stage=3, block=3) x = identity(x, 3, s, stage=3, block=4) s = [256, 256, 1024] if resnet_type < 50: s = s[:-1] x = conv(x, 3, s, stage=4, block=1, lpf_size=lpf_size) x = identity(x, 3, s, stage=4, block=2) if resnet_type > 18: x = identity(x, 3, s, stage=4, block=3) x = identity(x, 3, s, stage=4, block=4) x = identity(x, 3, s, stage=4, block=5) x = identity(x, 3, s, stage=4, block=6) s = [512, 512, 2048] if resnet_type < 50: s = s[:-1] x = conv(x, 3, s, stage=5, block=1, lpf_size=lpf_size) x = identity(x, 3, s, stage=5, block=2) if resnet_type > 18: x = identity(x, 3, s, stage=5, block=3) x = AveragePooling2D((7, 7), name='avg_pool')(x) return x
def senet_residual_block(input_tensor, kernel_size, filters, stage, block, bias=False, lpf_size=0, strides=(1, 1)): conv1_reduce_name = 'conv' + str(stage) + "_" + str(block) + "_1x1_reduce" conv1_increase_name = 'conv' + str(stage) + "_" + str( block) + "_1x1_increase" conv3_name = 'conv' + str(stage) + "_" + str(block) + "_3x3" x = LPFConv2D(filters[0], (1, 1) if len(filters) > 2 else kernel_size, padding='same', use_bias=bias, strides=strides, name=conv1_reduce_name, lpf_size=lpf_size)(input_tensor) x = BatchNormalization(axis=bn_axis, name=conv1_reduce_name + "/bn", epsilon=bn_eps)(x) x = Activation('relu')(x) x = Conv2D(filters[1], kernel_size, padding='same', use_bias=bias, name=conv3_name)(x) x = BatchNormalization(axis=bn_axis, name=conv3_name + "/bn", epsilon=bn_eps)(x) x = Activation('relu')(x) if len(filters) > 2: x = Conv2D(filters[2], (1, 1), name=conv1_increase_name, use_bias=bias)(x) x = BatchNormalization(axis=bn_axis, name=conv1_increase_name + "/bn", epsilon=bn_eps)(x) se = senet_se_block(x, stage=stage, block=block, bias=True) return se
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 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