def transition_block(ip, nb_filter, dropout_rate=None, weight_decay=1E-4): ''' Apply BatchNorm, Relu 1x1, Conv2D, optional dropout and Maxpooling2D Args: ip: keras tensor nb_filter: number of filters dropout_rate: dropout rate weight_decay: weight decay factor Returns: keras tensor, after applying batch_norm, relu-conv, dropout, maxpool ''' concat_axis = 1 if K.image_dim_ordering() == "th" else -1 x = Convolution2D(nb_filter, 1, 1, padding="same", use_bias=False, kernel_regularizer=l2(weight_decay))(ip) if dropout_rate: x = Dropout(dropout_rate)(x) x = AveragePooling2D((2, 2), strides=(2, 2))(x) x = BatchNormalization(axis=concat_axis, gamma_regularizer=l2(weight_decay), beta_regularizer=l2(weight_decay))(x) return x
def conv_block(ip, nb_filter, dropout_rate=None, weight_decay=1E-4): ''' Apply BatchNorm, Relu 3x3, Conv2D, optional dropout Args: ip: Input keras tensor nb_filter: number of filters dropout_rate: dropout rate weight_decay: weight decay factor Returns: keras tensor with batch_norm, relu and convolution2d added ''' x = Activation('relu')(ip) x = Convolution2D(nb_filter, 3, 3, padding="same", use_bias=False, kernel_regularizer=l2(weight_decay))(x) if dropout_rate: x = Dropout(dropout_rate)(x) return x
def SqueezeNet(include_top=True, weights='imagenet', input_tensor=None, input_shape=None, pooling=None, classes=1000): """Instantiates the SqueezeNet architecture. """ if weights not in {'imagenet', None}: raise ValueError('The `weights` argument should be either ' '`None` (random initialization) or `imagenet` ' '(pre-training on ImageNet).') if weights == 'imagenet' and classes != 1000: raise ValueError('If using `weights` as imagenet with `include_top`' ' as true, `classes` should be 1000') input_shape = _obtain_input_shape(input_shape, default_size=227, min_size=48, data_format=K.image_data_format(), require_flatten=include_top) if input_tensor is None: img_input = Input(shape=input_shape) else: if not K.is_keras_tensor(input_tensor): img_input = Input(tensor=input_tensor, shape=input_shape) else: img_input = input_tensor x = Convolution2D(64, (3, 3), strides=(2, 2), padding='valid', name='conv1')(img_input) x = Activation('relu', name='relu_conv1')(x) x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool1')(x) x = fire_module(x, fire_id=2, squeeze=16, expand=64) x = fire_module(x, fire_id=3, squeeze=16, expand=64) x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool3')(x) x = fire_module(x, fire_id=4, squeeze=32, expand=128) x = fire_module(x, fire_id=5, squeeze=32, expand=128) x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool5')(x) x = fire_module(x, fire_id=6, squeeze=48, expand=192) x = fire_module(x, fire_id=7, squeeze=48, expand=192) x = fire_module(x, fire_id=8, squeeze=64, expand=256) x = fire_module(x, fire_id=9, squeeze=64, expand=256) if include_top: # It's not obvious where to cut the network... # Could do the 8th or 9th layer... some work recommends cutting earlier layers. x = Dropout(0.5, name='drop9')(x) x = Convolution2D(classes, (1, 1), padding='valid', name='conv10')(x) x = Activation('relu', name='relu_conv10')(x) x = GlobalAveragePooling2D()(x) x = Activation('softmax', name='loss')(x) else: if pooling == 'avg': x = GlobalAveragePooling2D()(x) elif pooling == 'max': x = GlobalAveragePooling2D()(x) elif pooling == None: pass else: raise ValueError("Unknown argument for 'ppoling'=" + pooling) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = get_source_inputs(input_tensor) else: inputs = img_input model = Model(inputs, x, name='squeezenet') # load weights if weights == 'imagenet': if include_top: weights_path = '/tmp/squeezenet_weights_tf_dim_ordering_tf_kernels.h5' else: weights_path = get_file( 'squeezenet_weights_tf_dim_ordering_tf_kernels_notop.h5', WEIGHTS_PATH_NO_TOP, cache_dir='/tmp/') model.load_weights(weights_path) if K.backend() == 'theano': layer_utils.convert_all_kernels_in_model(model) if K.image_daata_format() == 'channels_first': pass return model
def MobileNet(input_shape=None, alpha=1.0, depth_multiplier=1, dropout=1e-3, include_top=True, weights='imagenet', input_tensor=None, pooling=None, classes=1000): """Instantiates the MobileNet architecture. Note that only TensorFlow is supported for now, therefore it only works with the data format `image_data_format='channels_last'` in your Keras config at `~/.keras/keras.json`. To load a MobileNet model via `load_model`, import the custom objects `relu6` and `DepthwiseConv2D` and pass them to the `custom_objects` parameter. E.g. model = load_model('mobilenet.h5', custom_objects={ 'relu6': mobilenet.relu6, 'DepthwiseConv2D': mobilenet.DepthwiseConv2D}) 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. - 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 (also called the resolution multiplier) 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 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. RuntimeError: If attempting to run this model with a backend that does not support separable convolutions. """ if K.backend() != 'tensorflow': raise RuntimeError('Only TensorFlow backend is currently supported, ' 'as other backends do not support ' 'depthwise convolution.') 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 K.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=K.image_data_format(), require_flatten=include_top, weights=weights) if K.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]: raise ValueError('If imagenet weights are being loaded, ' 'input must have a static square shape (one of ' '(128,128), (160,160), (192,192), or (224, 224)).' ' Input shape provided = %s' % (input_shape, )) if K.image_data_format() != 'channels_last': logging.warning( '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.') K.set_image_data_format('channels_last') old_data_format = 'channels_first' else: old_data_format = None if input_tensor is None: img_input = Input(shape=input_shape) else: if not K.is_keras_tensor(input_tensor): img_input = 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 K.image_data_format() == 'channels_first': shape = (int(1024 * alpha), 1, 1) else: shape = (1, 1, int(1024 * alpha)) x = GlobalAveragePooling2D()(x) x = Reshape(shape, name='reshape_1')(x) x = Dropout(dropout, name='dropout')(x) x = Conv2D(classes, (1, 1), padding='same', name='conv_preds')(x) x = Activation('softmax', name='act_softmax')(x) x = Reshape((classes, ), name='reshape_2')(x) else: if pooling == 'avg': x = GlobalAveragePooling2D()(x) elif pooling == 'max': x = GlobalMaxPooling2D()(x) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = get_source_inputs(input_tensor) else: inputs = img_input # Create model. model = Model(inputs, x, name='mobilenet_%0.2f_%s' % (alpha, rows)) # load weights if weights == 'imagenet': if K.image_data_format() == 'channels_first': raise ValueError('Weights for "channels_last" format ' 'are not available.') 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) weigh_path = BASE_WEIGHT_PATH + model_name weights_path = get_file(model_name, weigh_path, cache_subdir='models') else: model_name = 'mobilenet_%s_%d_tf_no_top.h5' % (alpha_text, rows) weigh_path = BASE_WEIGHT_PATH + model_name weights_path = 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: K.set_image_data_format(old_data_format) return model
def get_model(nb_classes=10, add_peer=True): model = Sequential() model.add( Conv2D(64, (3, 3), padding='same', input_shape=(32, 32, 3), name='img')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Conv2D(64, (3, 3), padding='same', name='block1_conv2')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')) model.add(Conv2D(128, (3, 3), padding='same', name='block2_conv1')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Conv2D(128, (3, 3), padding='same', name='block2_conv2')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')) model.add(Conv2D(256, (3, 3), padding='same', name='block3_conv1')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Conv2D(256, (3, 3), padding='same', name='block3_conv2')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Conv2D(256, (3, 3), padding='same', name='block3_conv3')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Conv2D(256, (3, 3), padding='same', name='block3_conv4')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')) model.add(Conv2D(512, (3, 3), padding='same', name='block4_conv1')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Conv2D(512, (3, 3), padding='same', name='block4_conv2')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Conv2D(512, (3, 3), padding='same', name='block4_conv3')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Conv2D(512, (3, 3), padding='same', name='block4_conv4')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')) model.add(Conv2D(512, (3, 3), padding='same', name='block5_conv1')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Conv2D(512, (3, 3), padding='same', name='block5_conv2')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Conv2D(512, (3, 3), padding='same', name='block5_conv3')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Conv2D(512, (3, 3), padding='same', name='block5_conv4')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Flatten()) model.add(Dense(4096)) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(4096, name='fc2')) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(nb_classes)) model.add(BatchNormalization()) model.add(Activation('softmax')) return model
def build_model(): input_h, input_w, input_d = 572, 572, 1 def Conv3x3(filters, name=None): return Conv2D(filters=filters, kernel_size=(3, 3), padding='valid', activation='relu', name=name) def MaxPool2x2(name=None): return MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name=name) def combine_enc_dec(encoder_tensor, decoder_tensor, block_n): encoder_shape = encoder_tensor.get_shape().as_list() decoder_shape = decoder_tensor.get_shape().as_list() filters = decoder_shape[3] // 2 assert decoder_shape[3] % 2 == 0 # TODO attention! should I use dilation_rate instead of strides? deconvolved = Conv2DTranspose( filters=filters, kernel_size=(2, 2), strides=2, activation='relu', name='block{}_deconv'.format(block_n + 1))(decoder_tensor) border_v = (encoder_shape[1] - decoder_shape[1] * 2) // 2 assert (encoder_shape[1] - decoder_shape[1] * 2) % 2 == 0 border_h = (encoder_shape[2] - decoder_shape[2] * 2) // 2 assert (encoder_shape[2] - decoder_shape[2] * 2) % 2 == 0 cropped = Cropping2D( (border_v, border_h), name='enc_block{}_output_cropped'.format(block_n))(encoder_tensor) concatenated = Concatenate(name='dec_block{}_concat'.format(block_n))( [cropped, deconvolved]) return concatenated inputs = Input(shape=(input_h, input_w, input_d), name='input') x = Conv3x3(filters=64, name='enc_block1_conv1')(inputs) enc_block1_output = Conv3x3(filters=64, name='enc_block1_conv2')(x) x = MaxPool2x2(name='enc_block1_maxp')(enc_block1_output) x = Conv3x3(filters=128, name='enc_block2_conv1')(x) enc_block2_output = Conv3x3(filters=128, name='enc_block2_conv2')(x) x = MaxPool2x2(name='enc_block2_maxp')(enc_block2_output) x = Conv3x3(filters=256, name='enc_block3_conv1')(x) enc_block3_output = Conv3x3(filters=256, name='enc_block3_conv2')(x) x = MaxPool2x2(name='enc_block3_maxp')(enc_block3_output) x = Conv3x3(filters=512, name='enc_block4_conv1')(x) x = Conv3x3(filters=512, name='enc_block4_conv2')(x) enc_block4_output = Dropout(rate=.5)(x) x = MaxPool2x2(name='enc_block4_maxp')(enc_block4_output) x = Conv3x3(filters=1024, name='enc_block5_conv1')(x) x = Conv3x3(filters=1024, name='enc_block5_conv2')(x) encoded = Dropout(rate=.5)(x) x = combine_enc_dec(encoder_tensor=enc_block4_output, decoder_tensor=encoded, block_n=4) x = Conv3x3(filters=512, name='dec_block4_conv1')(x) x = Conv3x3(filters=512, name='dec_block4_conv2')(x) x = combine_enc_dec(encoder_tensor=enc_block3_output, decoder_tensor=x, block_n=3) x = Conv3x3(filters=256, name='dec_block3_conv1')(x) x = Conv3x3(filters=256, name='dec_block3_conv2')(x) x = combine_enc_dec(encoder_tensor=enc_block2_output, decoder_tensor=x, block_n=2) x = Conv3x3(filters=128, name='dec_block2_conv1')(x) x = Conv3x3(filters=128, name='dec_block2_conv2')(x) x = combine_enc_dec(encoder_tensor=enc_block1_output, decoder_tensor=x, block_n=1) x = Conv3x3(filters=64, name='dec_block1_conv1')(x) x = Conv3x3(filters=64, name='dec_block1_conv2')(x) x = Conv2D(filters=2, kernel_size=(1, 1), padding='valid', activation='softmax', name='classifier')(x) model = tf.keras.Model(inputs=inputs, outputs=x) return model
def VGG16(include_top=True, weights='imagenet', input_tensor=None, input_shape=None, pooling=None, classes=1000): if weights not in {'imagenet', None}: raise ValueError('The `weights` argument should be either ' '`None` (random initialization) or `imagenet` ' '(pre-training on ImageNet).') # Determine proper input shape input_shape = _obtain_input_shape(input_shape, default_size=224, min_size=48, data_format=K.image_data_format(), require_flatten=include_top, weights=weights) if input_tensor is None: img_input = Input(shape=input_shape) else: img_input = Input(tensor=input_tensor, shape=input_shape) # Block 1 x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv1')(img_input) x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv2')(x) x = MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(x) # Block 2 x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv1')(x) x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv2')(x) x = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x) # Block 3 x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv1')(x) x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv2')(x) x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv3')(x) x = MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x) # Block 4 x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv1')(x) x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv2')(x) x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv3')(x) x = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x) # Block 5 x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv1')(x) x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv2')(x) x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3')(x) x = MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x) if include_top: # Classification block x = Flatten(name='flatten')(x) x = Dense(4096, activation='relu', name='fc1')(x) x = Dropout(x, 0.5) x = Dense(4096, activation='relu', name='fc2')(x) x = Dropout(x, 0.5) x = Dense(classes, activation='softmax', name='predictions')(x) else: if pooling == 'avg': x = GlobalAveragePooling2D()(x) elif pooling == 'max': x = GlobalMaxPooling2D()(x) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = get_source_inputs(input_tensor) else: inputs = img_input # Create model. model = Model(inputs, x, name='vgg16') # load weights if weights == 'imagenet': if include_top: weights_path = get_file( 'vgg16_weights_tf_dim_ordering_tf_kernels.h5', WEIGHTS_PATH, cache_subdir='models') else: weights_path = get_file( 'vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5', WEIGHTS_PATH_NO_TOP, cache_subdir='models') model.load_weights(weights_path) # Truncate and replace softmax layer for transfer learning model.layers.pop() model.outputs = [model.layers[-1].output] model.layers[-1].outbound_nodes = [] model.add(Dense(5089, activation='softmax', name='predictions')) # Learning rate is changed to 0.001 sgd = SGD(lr=1e-3, decay=1e-6, momentum=0.9, nesterov=True) model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy']) """ if K.backend() == 'theano': layer_utils.convert_all_kernels_in_model(model) if K.image_data_format() == 'channels_first': if include_top: maxpool = model.get_layer(name='block5_pool') shape = maxpool.output_shape[1:] dense = model.get_layer(name='fc1') layer_utils.convert_dense_weights_data_format(dense, shape, 'channels_first') """ return model