mirror of
https://github.com/wassname/keras-contrib.git
synced 2026-09-12 12:32:18 +08:00
[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
This commit is contained in:
committed by
Michael Oliver
parent
8ef69698b8
commit
1d57dd3c63
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user