From 1d57dd3c63eab5b181c412436c9fcffc748cc72e Mon Sep 17 00:00:00 2001 From: Somshubra Majumdar Date: Sat, 15 Apr 2017 12:18:10 -0500 Subject: [PATCH] [Bugfix] Corrects activation for DenseNetFCNs (#55) * Bugfix for DenseNetFCN + Activation parameter + revert to Keras 1 model * Correct ordering of parameters (input_shape) for DenseNet models * Updated to Keras 2 API * Changed image_dim_ordering to image_data_format * Corrected "th" to channels_first and "tf" to channels_last * Fixed " to ' * PEP 8 fixes * Fix PEP 8 again --- keras_contrib/applications/densenet.py | 228 ++++++++++++------------- 1 file changed, 105 insertions(+), 123 deletions(-) diff --git a/keras_contrib/applications/densenet.py b/keras_contrib/applications/densenet.py index 6154651..6217061 100644 --- a/keras_contrib/applications/densenet.py +++ b/keras_contrib/applications/densenet.py @@ -1,11 +1,9 @@ # -*- coding: utf-8 -*- -"""DenseNet models for Keras. - +'''DenseNet models for Keras. # Reference - - [Densely Connected Convolutional Networks](https://arxiv.org/pdf/1608.06993.pdf) - [The One Hundred Layers Tiramisu: Fully Convolutional DenseNets for Semantic Segmentation](https://arxiv.org/pdf/1611.09326.pdf) -""" +''' from __future__ import print_function from __future__ import absolute_import from __future__ import division @@ -14,11 +12,11 @@ import warnings from keras.models import Model from keras.layers.core import Dense, Dropout, Activation, Reshape -from keras.layers import Deconvolution2D, AtrousConvolution2D, UpSampling2D -from keras.layers.merge import concatenate +from keras.layers.convolutional import Conv2D, Conv2DTranspose, UpSampling2D from keras.layers.pooling import AveragePooling2D from keras.layers.pooling import GlobalAveragePooling2D -from keras.layers import Input, Conv2D +from keras.layers import Input +from keras.layers.merge import concatenate from keras.layers.normalization import BatchNormalization from keras.regularizers import l2 from keras.utils.layer_utils import convert_all_kernels_in_model @@ -35,23 +33,28 @@ TH_WEIGHTS_PATH_NO_TOP = 'https://github.com/titu1994/DenseNet/releases/download TF_WEIGHTS_PATH_NO_TOP = 'https://github.com/titu1994/DenseNet/releases/download/v2.0/DenseNet-40-12-Tensorflow-Backend-TF-dim-ordering-no-top.h5' -def DenseNet(depth=40, nb_dense_block=3, growth_rate=12, nb_filter=16, nb_layers_per_block=-1, +def DenseNet(input_shape=None, depth=40, nb_dense_block=3, growth_rate=12, nb_filter=16, nb_layers_per_block=-1, bottleneck=False, reduction=0.0, dropout_rate=0.0, weight_decay=1E-4, - include_top=True, weights='cifar10', input_tensor=None, input_shape=None, - classes=10): - """Instantiate the DenseNet architecture, + include_top=True, weights='cifar10', input_tensor=None, + classes=10, activation='softmax'): + '''Instantiate the DenseNet architecture, optionally loading weights pre-trained on CIFAR-10. Note that when using TensorFlow, for best performance you should set - `image_dim_ordering="tf"` in your Keras config + `image_data_format='channels_last'` in your Keras config at ~/.keras/keras.json. - The model and the weights are compatible with both TensorFlow and Theano. The dimension ordering convention used by the model is the one specified in your Keras config file. - # Arguments + input_shape: optional shape tuple, only to be specified + if `include_top` is False (otherwise the input shape + has to be `(32, 32, 3)` (with `channels_last` dim ordering) + or `(3, 32, 32)` (with `channels_first` dim ordering). + It should have exactly 3 inputs channels, + and width and height should be no smaller than 8. + E.g. `(200, 200, 3)` would be one valid value. depth: number or layers in the DenseNet nb_dense_block: number of dense blocks to add to end (generally = 3) growth_rate: number of filters to add per dense block @@ -59,7 +62,7 @@ def DenseNet(depth=40, nb_dense_block=3, growth_rate=12, nb_filter=16, nb_layers number of filters is 2 * growth_rate nb_layers_per_block: number of layers in each dense block. Can be a -1, positive integer or a list. - If -1, calculates nb_layer_per_block from the depth of the network. + If -1, calculates nb_layer_per_block from the network depth. If positive integer, a set number of layers per dense block. If list, nb_layer is used as provided. Note that list size must be (nb_dense_block + 1) @@ -71,23 +74,17 @@ def DenseNet(depth=40, nb_dense_block=3, growth_rate=12, nb_filter=16, nb_layers include_top: whether to include the fully-connected layer at the top of the network. weights: one of `None` (random initialization) or - "cifar10" (pre-training on CIFAR-10).. + 'cifar10' (pre-training on CIFAR-10).. 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 `(32, 32, 3)` (with `tf` dim ordering) - or `(3, 32, 32)` (with `th` dim ordering). - It should have exactly 3 inputs channels, - and width and height should be no smaller than 8. - E.g. `(200, 200, 3)` would be one valid value. 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. - + activation: Type of activation at the top layer. Can be one of 'softmax' or 'sigmoid'. + Note that if sigmoid is used, classes must be 1. # Returns A Keras model instance. - """ + ''' if weights not in {'cifar10', None}: raise ValueError('The `weights` argument should be either ' @@ -98,11 +95,17 @@ def DenseNet(depth=40, nb_dense_block=3, growth_rate=12, nb_filter=16, nb_layers raise ValueError('If using `weights` as CIFAR 10 with `include_top`' ' as true, `classes` should be 10') + if activation not in ['softmax', 'sigmoid']: + raise ValueError('activation must be one of "softmax" or "sigmoid"') + + if activation == 'sigmoid' and classes != 1: + raise ValueError('sigmoid activation can only be used when classes = 1') + # Determine proper input shape input_shape = _obtain_input_shape(input_shape, default_size=32, min_size=8, - data_format=K.image_dim_ordering(), + data_format=K.image_data_format(), include_top=include_top) if input_tensor is None: @@ -115,7 +118,7 @@ def DenseNet(depth=40, nb_dense_block=3, growth_rate=12, nb_filter=16, nb_layers x = __create_dense_net(classes, img_input, include_top, depth, nb_dense_block, growth_rate, nb_filter, nb_layers_per_block, bottleneck, reduction, - dropout_rate, weight_decay) + dropout_rate, weight_decay, activation) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. @@ -132,7 +135,7 @@ def DenseNet(depth=40, nb_dense_block=3, growth_rate=12, nb_filter=16, nb_layers (bottleneck is False) and (reduction == 0.0) and (dropout_rate == 0.0) and (weight_decay == 1E-4): # Default parameters match. Weights for this model exist: - if K.image_dim_ordering() == 'th': + if K.image_data_format() == 'channels_first': if include_top: weights_path = get_file('densenet_40_12_th_dim_ordering_th_kernels.h5', TH_WEIGHTS_PATH, @@ -148,9 +151,9 @@ def DenseNet(depth=40, nb_dense_block=3, growth_rate=12, nb_filter=16, nb_layers warnings.warn('You are using the TensorFlow backend, yet you ' 'are using the Theano ' 'image dimension ordering convention ' - '(`image_dim_ordering="th"`). ' + '(`image_data_format="channels_first"`). ' 'For best performance, set ' - '`image_dim_ordering="tf"` in ' + '`image_data_format="channels_last"` in ' 'your Keras config ' 'at ~/.keras/keras.json.') convert_all_kernels_in_model(model) @@ -174,14 +177,13 @@ def DenseNet(depth=40, nb_dense_block=3, growth_rate=12, nb_filter=16, nb_layers def DenseNetFCN(input_shape, nb_dense_block=5, growth_rate=16, nb_layers_per_block=4, reduction=0.0, dropout_rate=0.0, weight_decay=1E-4, init_conv_filters=48, - include_top=True, weights=None, input_tensor=None, classes=1, - upsampling_conv=128, upsampling_type='upsampling', batchsize=None): - """Instantiate the DenseNet FCN architecture. + include_top=True, weights=None, input_tensor=None, classes=1, activation='softmax', + upsampling_conv=128, upsampling_type='upsampling'): + '''Instantiate the DenseNet FCN architecture. Note that when using TensorFlow, for best performance you should set - `image_dim_ordering="tf"` in your Keras config + `image_data_format='channels_last'` in your Keras config at ~/.keras/keras.json. - # Arguments nb_dense_block: number of dense blocks to add to end (generally = 3) growth_rate: number of filters to add per dense block @@ -198,30 +200,31 @@ def DenseNetFCN(input_shape, nb_dense_block=5, growth_rate=16, nb_layers_per_blo include_top: whether to include the fully-connected layer at the top of the network. weights: one of `None` (random initialization) or - "cifar10" (pre-training on CIFAR-10).. + 'cifar10' (pre-training on CIFAR-10).. 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 `(32, 32, 3)` (with `tf` dim ordering) - or `(3, 32, 32)` (with `th` dim ordering). + has to be `(32, 32, 3)` (with `channels_last` dim ordering) + or `(3, 32, 32)` (with `channels_first` dim ordering). It should have exactly 3 inputs channels, and width and height should be no smaller than 8. E.g. `(200, 200, 3)` would be one valid value. 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. + activation: Type of activation at the top layer. Can be one of 'softmax' or 'sigmoid'. + Note that if sigmoid is used, classes must be 1. upsampling_conv: number of convolutional layers in upsampling via subpixel convolution - upsampling_type: Can be one of 'upsampling', 'deconv', 'atrous' and + upsampling_type: Can be one of 'upsampling', 'deconv' and 'subpixel'. Defines type of upsampling algorithm used. batchsize: Fixed batch size. This is a temporary requirement for computation of output shape in the case of Deconvolution2D layers. Parameter will be removed in next iteration of Keras, which infers output shape of deconvolution layers automatically. - # Returns A Keras model instance. - """ + ''' if weights not in {None}: raise ValueError('The `weights` argument should be ' @@ -230,13 +233,9 @@ def DenseNetFCN(input_shape, nb_dense_block=5, growth_rate=16, nb_layers_per_blo upsampling_type = upsampling_type.lower() - if upsampling_type not in ['upsampling', 'deconv', 'atrous', 'subpixel']: + if upsampling_type not in ['upsampling', 'deconv', 'subpixel']: raise ValueError('Parameter "upsampling_type" must be one of "upsampling", ' - '"deconv", "atrous" or "subpixel".') - - if upsampling_type == 'deconv' and batchsize is None: - raise ValueError('If "upsampling_type" is deconvoloution, then a fixed ' - 'batch size must be provided in batchsize parameter.') + '"deconv" or "subpixel".') if input_shape is None: raise ValueError('For fully convolutional models, input shape must be supplied.') @@ -245,17 +244,33 @@ def DenseNetFCN(input_shape, nb_dense_block=5, growth_rate=16, nb_layers_per_blo raise ValueError('Number of dense layers per block must be greater than 1. Argument ' 'value was %d.' % (nb_layers_per_block)) - if upsampling_type == 'atrous': - warnings.warn('Atrous Convolution upsampling does not correctly work (see https://github.com/fchollet/keras/issues/4018).\n' - 'Switching to `upsampling` type upscaling.') - upsampling_type = 'upsampling' + if activation not in ['softmax', 'sigmoid']: + raise ValueError('activation must be one of "softmax" or "sigmoid"') + + if activation == 'sigmoid' and classes != 1: + raise ValueError('sigmoid activation can only be used when classes = 1') # Determine proper input shape - input_shape = _obtain_input_shape(input_shape, - default_size=32, - min_size=16, - data_format=K.image_dim_ordering(), - include_top=include_top) + min_size = 2 ** nb_dense_block + + if K.image_data_format() == 'channels_first': + if input_shape is not None: + if ((input_shape[1] is not None and input_shape[1] < min_size) or + (input_shape[2] is not None and input_shape[2] < min_size)): + raise ValueError('Input size must be at least ' + + str(min_size) + 'x' + str(min_size) + ', got ' + '`input_shape=' + str(input_shape) + '`') + else: + input_shape = (classes, None, None) + else: + if input_shape is not None: + if ((input_shape[0] is not None and input_shape[0] < min_size) or + (input_shape[1] is not None and input_shape[1] < min_size)): + raise ValueError('Input size must be at least ' + + str(min_size) + 'x' + str(min_size) + ', got ' + '`input_shape=' + str(input_shape) + '`') + else: + input_shape = (None, None, classes) if input_tensor is None: img_input = Input(shape=input_shape) @@ -268,7 +283,7 @@ def DenseNetFCN(input_shape, nb_dense_block=5, growth_rate=16, nb_layers_per_blo x = __create_fcn_dense_net(classes, img_input, include_top, nb_dense_block, growth_rate, reduction, dropout_rate, weight_decay, nb_layers_per_block, upsampling_conv, upsampling_type, - batchsize, init_conv_filters, input_shape) + init_conv_filters, input_shape, activation) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. @@ -284,18 +299,16 @@ def DenseNetFCN(input_shape, nb_dense_block=5, growth_rate=16, nb_layers_per_blo def __conv_block(ip, nb_filter, bottleneck=False, dropout_rate=None, weight_decay=1E-4): ''' Apply BatchNorm, Relu, 3x3 Conv2D, optional bottleneck block and dropout - Args: ip: Input keras tensor nb_filter: number of filters bottleneck: add bottleneck block dropout_rate: dropout rate weight_decay: weight decay factor - Returns: keras tensor with batch_norm, relu and convolution2d added (optional bottleneck) ''' - concat_axis = 1 if K.image_dim_ordering() == 'th' else -1 + concat_axis = 1 if K.image_data_format() == 'channels_first' else -1 x = BatchNormalization(axis=concat_axis, gamma_regularizer=l2(weight_decay), beta_regularizer=l2(weight_decay))(ip) @@ -310,12 +323,12 @@ def __conv_block(ip, nb_filter, bottleneck=False, dropout_rate=None, weight_deca if dropout_rate: x = Dropout(dropout_rate)(x) - x = BatchNormalization(mode=0, axis=concat_axis, gamma_regularizer=l2(weight_decay), + x = BatchNormalization(axis=concat_axis, gamma_regularizer=l2(weight_decay), beta_regularizer=l2(weight_decay))(x) x = Activation('relu')(x) x = Conv2D(nb_filter, (3, 3), kernel_initializer='he_uniform', padding='same', use_bias=False, - kernel_regularizer=l2(weight_decay))(x) + kenel_regularizer=l2(weight_decay))(x) if dropout_rate: x = Dropout(dropout_rate)(x) @@ -324,7 +337,6 @@ def __conv_block(ip, nb_filter, bottleneck=False, dropout_rate=None, weight_deca def __transition_block(ip, nb_filter, compression=1.0, dropout_rate=None, weight_decay=1E-4): ''' Apply BatchNorm, Relu 1x1, Conv2D, optional compression, dropout and Maxpooling2D - Args: ip: keras tensor nb_filter: number of filters @@ -332,16 +344,15 @@ def __transition_block(ip, nb_filter, compression=1.0, dropout_rate=None, weight in the transition block. 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 + concat_axis = 1 if K.image_data_format() == 'channels_first' else -1 x = BatchNormalization(axis=concat_axis, gamma_regularizer=l2(weight_decay), beta_regularizer=l2(weight_decay))(ip) x = Activation('relu')(x) - x = Conv2D(nb_filter, (3, 3), kernel_initializer='he_uniform', padding='same', use_bias=False, + x = Conv2D(int(nb_filter * compression), (1, 1), kernel_initializer='he_uniform', padding='same', use_bias=False, kernel_regularizer=l2(weight_decay))(x) if dropout_rate: x = Dropout(dropout_rate)(x) @@ -353,7 +364,6 @@ def __transition_block(ip, nb_filter, compression=1.0, dropout_rate=None, weight def __dense_block(x, nb_layers, nb_filter, growth_rate, bottleneck=False, dropout_rate=None, weight_decay=1E-4, grow_nb_filters=True, return_concat_list=False): ''' Build a dense_block where the output of each conv_block is fed to subsequent ones - Args: x: keras tensor nb_layers: the number of layers of conv_block to append to the model. @@ -364,11 +374,10 @@ def __dense_block(x, nb_layers, nb_filter, growth_rate, bottleneck=False, dropou weight_decay: weight decay factor grow_nb_filters: flag to decide to allow number of filters to grow return_concat_list: return the list of feature maps along with the actual output - Returns: keras tensor with nb_layers of conv_block appended ''' - concat_axis = 1 if K.image_dim_ordering() == 'th' else -1 + concat_axis = 1 if K.image_data_format() == 'channels_first' else -1 x_list = [x] @@ -376,53 +385,46 @@ def __dense_block(x, nb_layers, nb_filter, growth_rate, bottleneck=False, dropou x = __conv_block(x, growth_rate, bottleneck, dropout_rate, weight_decay) x_list.append(x) - x1 = concatenate(x_list, axis=concat_axis) + x = concatenate(x_list, axis=concat_axis) if grow_nb_filters: nb_filter += growth_rate if return_concat_list: - return x1, nb_filter, x_list + return x, nb_filter, x_list else: - return x1, nb_filter + return x, nb_filter -def __transition_up_block(ip, nb_filters, type='upsampling', output_shape=None, weight_decay=1E-4): +def __transition_up_block(ip, nb_filters, type='upsampling', weight_decay=1E-4): ''' SubpixelConvolutional Upscaling (factor = 2) - Args: ip: keras tensor nb_filters: number of layers - type: can be 'upsampling', 'subpixel', 'deconv', or 'atrous'. Determines type of upsampling performed - output_shape: required if type = 'deconv'. Output shape of tensor + type: can be 'upsampling', 'subpixel', 'deconv'. Determines type of upsampling performed weight_decay: weight decay factor - Returns: keras tensor, after applying upsampling operation. ''' if type == 'upsampling': x = UpSampling2D()(ip) elif type == 'subpixel': - x = Conv2D(nb_filters, (3, 3), padding='same', kernel_regularizer=l2(weight_decay), activation='relu', + x = Conv2D(nb_filters, (3, 3), activation='relu', padding='same', W_regularizer=l2(weight_decay), use_bias=False, kernel_initializer='he_uniform')(ip) x = SubPixelUpscaling(scale_factor=2)(x) - x = Conv2D(nb_filters, (3, 3), activation='relu', padding='same', kernel_regularizer=l2(weight_decay), + x = Conv2D(nb_filters, (3, 3), activation='relu', padding='same', W_regularizer=l2(weight_decay), use_bias=False, kernel_initializer='he_uniform')(x) - elif type == 'atrous': - # waiting on https://github.com/fchollet/keras/issues/4018 - x = AtrousConvolution2D(nb_filters, 3, 3, activation='relu', W_regularizer=l2(weight_decay), - bias=False, atrous_rate=(2, 2), init='he_uniform')(ip) else: - x = Deconvolution2D(nb_filters, 3, 3, output_shape, activation='relu', border_mode='same', - subsample=(2, 2), init='he_uniform')(ip) + x = Conv2DTranspose(nb_filters, (3, 3), activation='relu', padding='same', strides=(2, 2), + kernel_initializer='he_uniform')(ip) return x def __create_dense_net(nb_classes, img_input, include_top, depth=40, nb_dense_block=3, growth_rate=12, nb_filter=-1, - nb_layers_per_block=-1, bottleneck=False, reduction=0.0, dropout_rate=None, weight_decay=1E-4): + nb_layers_per_block=-1, bottleneck=False, reduction=0.0, dropout_rate=None, weight_decay=1E-4, + activation='softmax'): ''' Build the DenseNet model - Args: nb_classes: number of classes img_input: tuple of shape (channels, rows, columns) or (rows, columns, channels) @@ -441,11 +443,12 @@ def __create_dense_net(nb_classes, img_input, include_top, depth=40, nb_dense_bl reduction: reduction factor of transition blocks. Note : reduction value is inverted to compute compression dropout_rate: dropout rate weight_decay: weight decay - + activation: Type of activation at the top layer. Can be one of 'softmax' or 'sigmoid'. + Note that if sigmoid is used, classes must be 1. Returns: keras tensor with nb_layers of conv_block appended ''' - concat_axis = 1 if K.image_dim_ordering() == 'th' else -1 + concat_axis = 1 if K.image_data_format() == 'channels_first' else -1 assert (depth - 4) % 3 == 0, 'Depth must be 3 N + 4' if reduction != 0.0: @@ -479,8 +482,8 @@ def __create_dense_net(nb_classes, img_input, include_top, depth=40, nb_dense_bl compression = 1.0 - reduction # Initial convolution - x = Conv2D(nb_filter, (3, 3), kernel_initializer='he_uniform', padding='same', name='initial_conv2D', use_bias=False, - kernel_regularizer=l2(weight_decay))(img_input) + x = Conv2D(nb_filter, (3, 3), kernel_initializer='he_uniform', padding='same', name='initial_conv2D', + use_bias=False, kernel_regularizer=l2(weight_decay))(img_input) # Add dense blocks for block_idx in range(nb_dense_block - 1): @@ -501,7 +504,7 @@ def __create_dense_net(nb_classes, img_input, include_top, depth=40, nb_dense_bl x = GlobalAveragePooling2D()(x) if include_top: - x = Dense(nb_classes, activation='softmax', kernel_regularizer=l2(weight_decay), bias_regularizer=l2(weight_decay))(x) + x = Dense(nb_classes, activation=activation, W_regularizer=l2(weight_decay), b_regularizer=l2(weight_decay))(x) return x @@ -509,9 +512,8 @@ def __create_dense_net(nb_classes, img_input, include_top, depth=40, nb_dense_bl def __create_fcn_dense_net(nb_classes, img_input, include_top, nb_dense_block=5, growth_rate=12, reduction=0.0, dropout_rate=None, weight_decay=1E-4, nb_layers_per_block=4, nb_upsampling_conv=128, upsampling_type='upsampling', - batchsize=None, init_conv_filters=48, input_shape=None): + init_conv_filters=48, input_shape=None, activation='softmax'): ''' Build the DenseNet model - Args: nb_classes: number of classes img_input: tuple of shape (channels, rows, columns) or (rows, columns, channels) @@ -527,20 +529,17 @@ def __create_fcn_dense_net(nb_classes, img_input, include_top, nb_dense_block=5, If list, nb_layer is used as provided. Note that list size must be (nb_dense_block + 1) nb_upsampling_conv: number of convolutional layers in upsampling via subpixel convolution - upsampling_type: Can be one of 'upsampling', 'deconv', 'atrous' and - 'subpixel'. Defines type of upsampling algorithm used. - batchsize: Fixed batch size. This is a temporary requirement for - computation of output shape in the case of Deconvolution2D layers. - Parameter will be removed in next iteration of Keras, which infers - output shape of deconvolution layers automatically. + upsampling_type: Can be one of 'upsampling', 'deconv' and 'subpixel'. Defines + type of upsampling algorithm used. input_shape: Only used for shape inference in fully convolutional networks. - + activation: Type of activation at the top layer. Can be one of 'softmax' or 'sigmoid'. + Note that if sigmoid is used, classes must be 1. Returns: keras tensor with nb_layers of conv_block appended ''' - concat_axis = 1 if K.image_dim_ordering() == 'th' else -1 + concat_axis = 1 if K.image_data_format() == 'channels_first' else -1 - if concat_axis == 1: # th dim ordering + if concat_axis == 1: # channels_first dim ordering _, rows, cols = input_shape else: rows, cols, _ = input_shape @@ -601,36 +600,19 @@ def __create_fcn_dense_net(nb_classes, img_input, include_top, nb_dense_block=5, skip_list = skip_list[::-1] # reverse the skip list - if K.image_dim_ordering() == 'th': - out_shape = [batchsize, nb_filter, rows // 16, cols // 16] - else: - out_shape = [batchsize, rows // 16, cols // 16, nb_filter] - # Add dense blocks and transition up block for block_idx in range(nb_dense_block): n_filters_keep = growth_rate * nb_layers[nb_dense_block + block_idx] - if K.image_dim_ordering() == 'th': - out_shape[1] = n_filters_keep - else: - out_shape[3] = n_filters_keep - # upsampling block must upsample only the feature maps (concat_list[1:]), # not the concatenation of the input with the feature maps (concat_list[0]. l = concatenate(concat_list[1:], axis=concat_axis) - t = __transition_up_block(l, nb_filters=n_filters_keep, type=upsampling_type, output_shape=out_shape) + t = __transition_up_block(l, nb_filters=n_filters_keep, type=upsampling_type) # concatenate the skip connection with the transition block x = concatenate([t, skip_list[block_idx]], axis=concat_axis) - if K.image_dim_ordering() == 'th': - out_shape[2] *= 2 - out_shape[3] *= 2 - else: - out_shape[1] *= 2 - out_shape[2] *= 2 - # Dont allow the feature map size to grow in upsampling dense blocks _, nb_filter, concat_list = __dense_block(x, nb_layers[nb_dense_block + block_idx + 1], nb_filter=growth_rate, growth_rate=growth_rate, dropout_rate=dropout_rate, @@ -641,13 +623,13 @@ def __create_fcn_dense_net(nb_classes, img_input, include_top, nb_dense_block=5, x = Conv2D(nb_classes, (1, 1), activation='linear', padding='same', kernel_regularizer=l2(weight_decay), use_bias=False)(x) - if K.image_dim_ordering() == 'th': + if K.image_data_format() == 'channels_first': channel, row, col = input_shape else: row, col, channel = input_shape x = Reshape((row * col, nb_classes))(x) - x = Activation('softmax')(x) + x = Activation(activation)(x) x = Reshape((row, col, nb_classes))(x) return x