mirror of
https://github.com/wassname/DenseNet-Keras.git
synced 2026-06-27 14:58:24 +08:00
Initial Commit
This commit is contained in:
@@ -87,3 +87,6 @@ ENV/
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
*.pyc
|
||||
*.swp
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
from keras import initializations
|
||||
from keras.engine import Layer, InputSpec
|
||||
|
||||
import keras.backend as K
|
||||
|
||||
class Scale(Layer):
|
||||
'''Custom Layer for DenseNet used for BatchNormalization.
|
||||
|
||||
Learns a set of weights and biases used for scaling the input data.
|
||||
the output consists simply in an element-wise multiplication of the input
|
||||
and a sum of a set of constants:
|
||||
|
||||
out = in * gamma + beta,
|
||||
|
||||
where 'gamma' and 'beta' are the weights and biases larned.
|
||||
|
||||
# Arguments
|
||||
axis: integer, axis along which to normalize in mode 0. For instance,
|
||||
if your input tensor has shape (samples, channels, rows, cols),
|
||||
set axis to 1 to normalize per feature map (channels axis).
|
||||
momentum: momentum in the computation of the
|
||||
exponential average of the mean and standard deviation
|
||||
of the data, for feature-wise normalization.
|
||||
weights: Initialization weights.
|
||||
List of 2 Numpy arrays, with shapes:
|
||||
`[(input_shape,), (input_shape,)]`
|
||||
beta_init: name of initialization function for shift parameter
|
||||
(see [initializations](../initializations.md)), or alternatively,
|
||||
Theano/TensorFlow function to use for weights initialization.
|
||||
This parameter is only relevant if you don't pass a `weights` argument.
|
||||
gamma_init: name of initialization function for scale parameter (see
|
||||
[initializations](../initializations.md)), or alternatively,
|
||||
Theano/TensorFlow function to use for weights initialization.
|
||||
This parameter is only relevant if you don't pass a `weights` argument.
|
||||
'''
|
||||
def __init__(self, weights=None, axis=-1, momentum = 0.9, beta_init='zero', gamma_init='one', **kwargs):
|
||||
self.momentum = momentum
|
||||
self.axis = axis
|
||||
self.beta_init = initializations.get(beta_init)
|
||||
self.gamma_init = initializations.get(gamma_init)
|
||||
self.initial_weights = weights
|
||||
super(Scale, self).__init__(**kwargs)
|
||||
|
||||
def build(self, input_shape):
|
||||
self.input_spec = [InputSpec(shape=input_shape)]
|
||||
shape = (int(input_shape[self.axis]),)
|
||||
|
||||
self.gamma = self.gamma_init(shape, name='{}_gamma'.format(self.name))
|
||||
self.beta = self.beta_init(shape, name='{}_beta'.format(self.name))
|
||||
self.trainable_weights = [self.gamma, self.beta]
|
||||
|
||||
if self.initial_weights is not None:
|
||||
self.set_weights(self.initial_weights)
|
||||
del self.initial_weights
|
||||
|
||||
def call(self, x, mask=None):
|
||||
input_shape = self.input_spec[0].shape
|
||||
broadcast_shape = [1] * len(input_shape)
|
||||
broadcast_shape[self.axis] = input_shape[self.axis]
|
||||
|
||||
out = K.reshape(self.gamma, broadcast_shape) * x + K.reshape(self.beta, broadcast_shape)
|
||||
return out
|
||||
|
||||
def get_config(self):
|
||||
config = {"momentum": self.momentum, "axis": self.axis}
|
||||
base_config = super(Scale, self).get_config()
|
||||
return dict(list(base_config.items()) + list(config.items()))
|
||||
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
from keras.models import Model
|
||||
from keras.layers import Input, merge, ZeroPadding2D
|
||||
from keras.layers.core import Dense, Dropout, Activation
|
||||
from keras.layers.convolutional import Convolution2D
|
||||
from keras.layers.pooling import AveragePooling2D, GlobalAveragePooling2D, MaxPooling2D
|
||||
from keras.layers.normalization import BatchNormalization
|
||||
import keras.backend as K
|
||||
|
||||
from custom_layers import Scale
|
||||
|
||||
def DenseNet(nb_dense_block=4, growth_rate=32, nb_filter=64, reduction=0.0, dropout_rate=0.0, weight_decay=1e-4, classes=1000, weights_path=None):
|
||||
'''Instantiate the DenseNet 121 architecture,
|
||||
# Arguments
|
||||
nb_dense_block: number of dense blocks to add to end
|
||||
growth_rate: number of filters to add per dense block
|
||||
nb_filter: initial number of filters
|
||||
reduction: reduction factor of transition blocks.
|
||||
dropout_rate: dropout rate
|
||||
weight_decay: weight decay factor
|
||||
classes: optional number of classes to classify images
|
||||
weights_path: path to pre-trained weights
|
||||
# Returns
|
||||
A Keras model instance.
|
||||
'''
|
||||
eps = 1.1e-5
|
||||
|
||||
# compute compression factor
|
||||
compression = 1.0 - reduction
|
||||
|
||||
# Handle Dimension Ordering for different backends
|
||||
global concat_axis
|
||||
if K.image_dim_ordering() == 'tf':
|
||||
concat_axis = 3
|
||||
img_input = Input(shape=(224, 224, 3), name='data')
|
||||
else:
|
||||
concat_axis = 1
|
||||
img_input = Input(shape=(3, 224, 224), name='data')
|
||||
|
||||
# From architecture for ImageNet (Table 1 in the paper)
|
||||
nb_filter = 64
|
||||
nb_layers = [6,12,24,16] # For DenseNet-121
|
||||
|
||||
# Initial convolution
|
||||
x = ZeroPadding2D((3, 3), name='conv1_zeropadding')(img_input)
|
||||
x = Convolution2D(nb_filter, 7, 7, subsample=(2, 2), name='conv1', bias=False)(x)
|
||||
x = BatchNormalization(epsilon=eps, axis=concat_axis, name='conv1_bn')(x)
|
||||
x = Scale(axis=concat_axis, name='conv1_scale')(x)
|
||||
x = Activation('relu', name='relu1')(x)
|
||||
x = ZeroPadding2D((1, 1), name='pool1_zeropadding')(x)
|
||||
x = MaxPooling2D((3, 3), strides=(2, 2), name='pool1')(x)
|
||||
|
||||
# Add dense blocks
|
||||
for block_idx in range(nb_dense_block - 1):
|
||||
stage = block_idx+2
|
||||
x, nb_filter = dense_block(x, stage, nb_layers[block_idx], nb_filter, growth_rate, dropout_rate=dropout_rate, weight_decay=weight_decay)
|
||||
|
||||
# Add transition_block
|
||||
x = transition_block(x, stage, nb_filter, compression=compression, dropout_rate=dropout_rate, weight_decay=weight_decay)
|
||||
nb_filter = int(nb_filter * compression)
|
||||
|
||||
final_stage = stage + 1
|
||||
x, nb_filter = dense_block(x, final_stage, nb_layers[-1], nb_filter, growth_rate, dropout_rate=dropout_rate, weight_decay=weight_decay)
|
||||
|
||||
x = BatchNormalization(epsilon=eps, axis=concat_axis, name='conv'+str(final_stage)+'_blk_bn')(x)
|
||||
x = Scale(axis=concat_axis, name='conv'+str(final_stage)+'_blk_scale')(x)
|
||||
x = Activation('relu', name='relu'+str(final_stage)+'_blk')(x)
|
||||
x = GlobalAveragePooling2D(name='pool'+str(final_stage))(x)
|
||||
|
||||
x = Dense(classes, name='fc6')(x)
|
||||
x = Activation('softmax', name='prob')(x)
|
||||
|
||||
model = Model(img_input, x, name='densenet')
|
||||
|
||||
if weights_path is not None:
|
||||
model.load_weights(weights_path)
|
||||
|
||||
return model
|
||||
|
||||
|
||||
def conv_block(x, stage, branch, nb_filter, dropout_rate=None, weight_decay=1e-4):
|
||||
'''Apply BatchNorm, Relu, bottleneck 1x1 Conv2D, 3x3 Conv2D, and option dropout
|
||||
# Arguments
|
||||
x: input tensor
|
||||
stage: index for dense block
|
||||
branch: layer index within each dense block
|
||||
nb_filter: number of filters
|
||||
dropout_rate: dropout rate
|
||||
weight_decay: weight decay factor
|
||||
'''
|
||||
eps = 1.1e-5
|
||||
conv_name_base = 'conv' + str(stage) + '_' + str(branch)
|
||||
relu_name_base = 'relu' + str(stage) + '_' + str(branch)
|
||||
|
||||
# 1x1 Convolution (Bottleneck layer)
|
||||
inter_channel = nb_filter * 4
|
||||
x = BatchNormalization(epsilon=eps, axis=concat_axis, name=conv_name_base+'_x1_bn')(x)
|
||||
x = Scale(axis=concat_axis, name=conv_name_base+'_x1_scale')(x)
|
||||
x = Activation('relu', name=relu_name_base+'_x1')(x)
|
||||
x = Convolution2D(inter_channel, 1, 1, name=conv_name_base+'_x1', bias=False)(x)
|
||||
|
||||
if dropout_rate:
|
||||
x = Dropout(dropout_rate)(x)
|
||||
|
||||
# 3x3 Convolution
|
||||
x = BatchNormalization(epsilon=eps, axis=concat_axis, name=conv_name_base+'_x2_bn')(x)
|
||||
x = Scale(axis=concat_axis, name=conv_name_base+'_x2_scale')(x)
|
||||
x = Activation('relu', name=relu_name_base+'_x2')(x)
|
||||
x = ZeroPadding2D((1, 1), name=conv_name_base+'_x2_zeropadding')(x)
|
||||
x = Convolution2D(nb_filter, 3, 3, name=conv_name_base+'_x2', bias=False)(x)
|
||||
|
||||
if dropout_rate:
|
||||
x = Dropout(dropout_rate)(x)
|
||||
|
||||
return x
|
||||
|
||||
|
||||
def transition_block(x, stage, nb_filter, compression=1.0, dropout_rate=None, weight_decay=1E-4):
|
||||
''' Apply BatchNorm, 1x1 Convolution, averagePooling, optional compression, dropout
|
||||
# Arguments
|
||||
x: input tensor
|
||||
stage: index for dense block
|
||||
nb_filter: number of filters
|
||||
compression: calculated as 1 - reduction. Reduces the number of feature maps in the transition block.
|
||||
dropout_rate: dropout rate
|
||||
weight_decay: weight decay factor
|
||||
'''
|
||||
|
||||
eps = 1.1e-5
|
||||
conv_name_base = 'conv' + str(stage) + '_blk'
|
||||
relu_name_base = 'relu' + str(stage) + '_blk'
|
||||
pool_name_base = 'pool' + str(stage)
|
||||
|
||||
x = BatchNormalization(epsilon=eps, axis=concat_axis, name=conv_name_base+'_bn')(x)
|
||||
x = Scale(axis=concat_axis, name=conv_name_base+'_scale')(x)
|
||||
x = Activation('relu', name=relu_name_base)(x)
|
||||
x = Convolution2D(int(nb_filter * compression), 1, 1, name=conv_name_base, bias=False)(x)
|
||||
|
||||
if dropout_rate:
|
||||
x = Dropout(dropout_rate)(x)
|
||||
|
||||
x = AveragePooling2D((2, 2), strides=(2, 2), name=pool_name_base)(x)
|
||||
|
||||
return x
|
||||
|
||||
|
||||
def dense_block(x, stage, nb_layers, nb_filter, growth_rate, dropout_rate=None, weight_decay=1e-4, grow_nb_filters=True):
|
||||
''' Build a dense_block where the output of each conv_block is fed to subsequent ones
|
||||
# Arguments
|
||||
x: input tensor
|
||||
stage: index for dense block
|
||||
nb_layers: the number of layers of conv_block to append to the model.
|
||||
nb_filter: number of filters
|
||||
growth_rate: growth rate
|
||||
dropout_rate: dropout rate
|
||||
weight_decay: weight decay factor
|
||||
grow_nb_filters: flag to decide to allow number of filters to grow
|
||||
'''
|
||||
|
||||
eps = 1.1e-5
|
||||
concat_feat = x
|
||||
|
||||
for i in range(nb_layers):
|
||||
branch = i+1
|
||||
x = conv_block(concat_feat, stage, branch, growth_rate, dropout_rate, weight_decay)
|
||||
concat_feat = merge([concat_feat, x], mode='concat', concat_axis=concat_axis, name='concat_'+str(stage)+'_'+str(branch))
|
||||
|
||||
if grow_nb_filters:
|
||||
nb_filter += growth_rate
|
||||
|
||||
return concat_feat, nb_filter
|
||||
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
from keras.models import Model
|
||||
from keras.layers import Input, merge, ZeroPadding2D
|
||||
from keras.layers.core import Dense, Dropout, Activation
|
||||
from keras.layers.convolutional import Convolution2D
|
||||
from keras.layers.pooling import AveragePooling2D, GlobalAveragePooling2D, MaxPooling2D
|
||||
from keras.layers.normalization import BatchNormalization
|
||||
import keras.backend as K
|
||||
|
||||
from custom_layers import Scale
|
||||
|
||||
def DenseNet(nb_dense_block=4, growth_rate=48, nb_filter=96, reduction=0.0, dropout_rate=0.0, weight_decay=1e-4, classes=1000, weights_path=None):
|
||||
'''Instantiate the DenseNet 161 architecture,
|
||||
# Arguments
|
||||
nb_dense_block: number of dense blocks to add to end
|
||||
growth_rate: number of filters to add per dense block
|
||||
nb_filter: initial number of filters
|
||||
reduction: reduction factor of transition blocks.
|
||||
dropout_rate: dropout rate
|
||||
weight_decay: weight decay factor
|
||||
classes: optional number of classes to classify images
|
||||
weights_path: path to pre-trained weights
|
||||
# Returns
|
||||
A Keras model instance.
|
||||
'''
|
||||
eps = 1.1e-5
|
||||
|
||||
# compute compression factor
|
||||
compression = 1.0 - reduction
|
||||
|
||||
# Handle Dimension Ordering for different backends
|
||||
global concat_axis
|
||||
if K.image_dim_ordering() == 'tf':
|
||||
concat_axis = 3
|
||||
img_input = Input(shape=(224, 224, 3), name='data')
|
||||
else:
|
||||
concat_axis = 1
|
||||
img_input = Input(shape=(3, 224, 224), name='data')
|
||||
|
||||
# From architecture for ImageNet (Table 1 in the paper)
|
||||
nb_filter = 96
|
||||
nb_layers = [6,12,36,24] # For DenseNet-161
|
||||
|
||||
# Initial convolution
|
||||
x = ZeroPadding2D((3, 3), name='conv1_zeropadding')(img_input)
|
||||
x = Convolution2D(nb_filter, 7, 7, subsample=(2, 2), name='conv1', bias=False)(x)
|
||||
x = BatchNormalization(epsilon=eps, axis=concat_axis, name='conv1_bn')(x)
|
||||
x = Scale(axis=concat_axis, name='conv1_scale')(x)
|
||||
x = Activation('relu', name='relu1')(x)
|
||||
x = ZeroPadding2D((1, 1), name='pool1_zeropadding')(x)
|
||||
x = MaxPooling2D((3, 3), strides=(2, 2), name='pool1')(x)
|
||||
|
||||
# Add dense blocks
|
||||
for block_idx in range(nb_dense_block - 1):
|
||||
stage = block_idx+2
|
||||
x, nb_filter = dense_block(x, stage, nb_layers[block_idx], nb_filter, growth_rate, dropout_rate=dropout_rate, weight_decay=weight_decay)
|
||||
|
||||
# Add transition_block
|
||||
x = transition_block(x, stage, nb_filter, compression=compression, dropout_rate=dropout_rate, weight_decay=weight_decay)
|
||||
nb_filter = int(nb_filter * compression)
|
||||
|
||||
final_stage = stage + 1
|
||||
x, nb_filter = dense_block(x, final_stage, nb_layers[-1], nb_filter, growth_rate, dropout_rate=dropout_rate, weight_decay=weight_decay)
|
||||
|
||||
x = BatchNormalization(epsilon=eps, axis=concat_axis, name='conv'+str(final_stage)+'_blk_bn')(x)
|
||||
x = Scale(axis=concat_axis, name='conv'+str(final_stage)+'_blk_scale')(x)
|
||||
x = Activation('relu', name='relu'+str(final_stage)+'_blk')(x)
|
||||
x = GlobalAveragePooling2D(name='pool'+str(final_stage))(x)
|
||||
|
||||
x = Dense(classes, name='fc6')(x)
|
||||
x = Activation('softmax', name='prob')(x)
|
||||
|
||||
model = Model(img_input, x, name='densenet')
|
||||
|
||||
if weights_path is not None:
|
||||
model.load_weights(weights_path)
|
||||
|
||||
return model
|
||||
|
||||
|
||||
def conv_block(x, stage, branch, nb_filter, dropout_rate=None, weight_decay=1e-4):
|
||||
'''Apply BatchNorm, Relu, bottleneck 1x1 Conv2D, 3x3 Conv2D, and option dropout
|
||||
# Arguments
|
||||
x: input tensor
|
||||
stage: index for dense block
|
||||
branch: layer index within each dense block
|
||||
nb_filter: number of filters
|
||||
dropout_rate: dropout rate
|
||||
weight_decay: weight decay factor
|
||||
'''
|
||||
eps = 1.1e-5
|
||||
conv_name_base = 'conv' + str(stage) + '_' + str(branch)
|
||||
relu_name_base = 'relu' + str(stage) + '_' + str(branch)
|
||||
|
||||
# 1x1 Convolution (Bottleneck layer)
|
||||
inter_channel = nb_filter * 4
|
||||
x = BatchNormalization(epsilon=eps, axis=concat_axis, name=conv_name_base+'_x1_bn')(x)
|
||||
x = Scale(axis=concat_axis, name=conv_name_base+'_x1_scale')(x)
|
||||
x = Activation('relu', name=relu_name_base+'_x1')(x)
|
||||
x = Convolution2D(inter_channel, 1, 1, name=conv_name_base+'_x1', bias=False)(x)
|
||||
|
||||
if dropout_rate:
|
||||
x = Dropout(dropout_rate)(x)
|
||||
|
||||
# 3x3 Convolution
|
||||
x = BatchNormalization(epsilon=eps, axis=concat_axis, name=conv_name_base+'_x2_bn')(x)
|
||||
x = Scale(axis=concat_axis, name=conv_name_base+'_x2_scale')(x)
|
||||
x = Activation('relu', name=relu_name_base+'_x2')(x)
|
||||
x = ZeroPadding2D((1, 1), name=conv_name_base+'_x2_zeropadding')(x)
|
||||
x = Convolution2D(nb_filter, 3, 3, name=conv_name_base+'_x2', bias=False)(x)
|
||||
|
||||
if dropout_rate:
|
||||
x = Dropout(dropout_rate)(x)
|
||||
|
||||
return x
|
||||
|
||||
|
||||
def transition_block(x, stage, nb_filter, compression=1.0, dropout_rate=None, weight_decay=1E-4):
|
||||
''' Apply BatchNorm, 1x1 Convolution, averagePooling, optional compression, dropout
|
||||
# Arguments
|
||||
x: input tensor
|
||||
stage: index for dense block
|
||||
nb_filter: number of filters
|
||||
compression: calculated as 1 - reduction. Reduces the number of feature maps in the transition block.
|
||||
dropout_rate: dropout rate
|
||||
weight_decay: weight decay factor
|
||||
'''
|
||||
|
||||
eps = 1.1e-5
|
||||
conv_name_base = 'conv' + str(stage) + '_blk'
|
||||
relu_name_base = 'relu' + str(stage) + '_blk'
|
||||
pool_name_base = 'pool' + str(stage)
|
||||
|
||||
x = BatchNormalization(epsilon=eps, axis=concat_axis, name=conv_name_base+'_bn')(x)
|
||||
x = Scale(axis=concat_axis, name=conv_name_base+'_scale')(x)
|
||||
x = Activation('relu', name=relu_name_base)(x)
|
||||
x = Convolution2D(int(nb_filter * compression), 1, 1, name=conv_name_base, bias=False)(x)
|
||||
|
||||
if dropout_rate:
|
||||
x = Dropout(dropout_rate)(x)
|
||||
|
||||
x = AveragePooling2D((2, 2), strides=(2, 2), name=pool_name_base)(x)
|
||||
|
||||
return x
|
||||
|
||||
|
||||
def dense_block(x, stage, nb_layers, nb_filter, growth_rate, dropout_rate=None, weight_decay=1e-4, grow_nb_filters=True):
|
||||
''' Build a dense_block where the output of each conv_block is fed to subsequent ones
|
||||
# Arguments
|
||||
x: input tensor
|
||||
stage: index for dense block
|
||||
nb_layers: the number of layers of conv_block to append to the model.
|
||||
nb_filter: number of filters
|
||||
growth_rate: growth rate
|
||||
dropout_rate: dropout rate
|
||||
weight_decay: weight decay factor
|
||||
grow_nb_filters: flag to decide to allow number of filters to grow
|
||||
'''
|
||||
|
||||
eps = 1.1e-5
|
||||
concat_feat = x
|
||||
|
||||
for i in range(nb_layers):
|
||||
branch = i+1
|
||||
x = conv_block(concat_feat, stage, branch, growth_rate, dropout_rate, weight_decay)
|
||||
concat_feat = merge([concat_feat, x], mode='concat', concat_axis=concat_axis, name='concat_'+str(stage)+'_'+str(branch))
|
||||
|
||||
if grow_nb_filters:
|
||||
nb_filter += growth_rate
|
||||
|
||||
return concat_feat, nb_filter
|
||||
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
from keras.models import Model
|
||||
from keras.layers import Input, merge, ZeroPadding2D
|
||||
from keras.layers.core import Dense, Dropout, Activation
|
||||
from keras.layers.convolutional import Convolution2D
|
||||
from keras.layers.pooling import AveragePooling2D, GlobalAveragePooling2D, MaxPooling2D
|
||||
from keras.layers.normalization import BatchNormalization
|
||||
import keras.backend as K
|
||||
|
||||
from custom_layers import Scale
|
||||
|
||||
def DenseNet(nb_dense_block=4, growth_rate=32, nb_filter=64, reduction=0.0, dropout_rate=0.0, weight_decay=1e-4, classes=1000, weights_path=None):
|
||||
'''Instantiate the DenseNet architecture,
|
||||
# Arguments
|
||||
nb_dense_block: number of dense blocks to add to end
|
||||
growth_rate: number of filters to add per dense block
|
||||
nb_filter: initial number of filters
|
||||
reduction: reduction factor of transition blocks.
|
||||
dropout_rate: dropout rate
|
||||
weight_decay: weight decay factor
|
||||
classes: optional number of classes to classify images
|
||||
weights_path: path to pre-trained weights
|
||||
# Returns
|
||||
A Keras model instance.
|
||||
'''
|
||||
eps = 1.1e-5
|
||||
|
||||
# compute compression factor
|
||||
compression = 1.0 - reduction
|
||||
|
||||
# Handle Dimension Ordering for different backends
|
||||
global concat_axis
|
||||
if K.image_dim_ordering() == 'tf':
|
||||
concat_axis = 3
|
||||
img_input = Input(shape=(224, 224, 3), name='data')
|
||||
else:
|
||||
concat_axis = 1
|
||||
img_input = Input(shape=(3, 224, 224), name='data')
|
||||
|
||||
# From architecture for ImageNet (Table 1 in the paper)
|
||||
nb_filter = 64
|
||||
nb_layers = [6,12,32,32] # For DenseNet-169
|
||||
|
||||
# Initial convolution
|
||||
x = ZeroPadding2D((3, 3), name='conv1_zeropadding')(img_input)
|
||||
x = Convolution2D(nb_filter, 7, 7, subsample=(2, 2), name='conv1', bias=False)(x)
|
||||
x = BatchNormalization(epsilon=eps, axis=concat_axis, name='conv1_bn')(x)
|
||||
x = Scale(axis=concat_axis, name='conv1_scale')(x)
|
||||
x = Activation('relu', name='relu1')(x)
|
||||
x = ZeroPadding2D((1, 1), name='pool1_zeropadding')(x)
|
||||
x = MaxPooling2D((3, 3), strides=(2, 2), name='pool1')(x)
|
||||
|
||||
# Add dense blocks
|
||||
for block_idx in range(nb_dense_block - 1):
|
||||
stage = block_idx+2
|
||||
x, nb_filter = dense_block(x, stage, nb_layers[block_idx], nb_filter, growth_rate, dropout_rate=dropout_rate, weight_decay=weight_decay)
|
||||
|
||||
# Add transition_block
|
||||
x = transition_block(x, stage, nb_filter, compression=compression, dropout_rate=dropout_rate, weight_decay=weight_decay)
|
||||
nb_filter = int(nb_filter * compression)
|
||||
|
||||
final_stage = stage + 1
|
||||
x, nb_filter = dense_block(x, final_stage, nb_layers[-1], nb_filter, growth_rate, dropout_rate=dropout_rate, weight_decay=weight_decay)
|
||||
|
||||
x = BatchNormalization(epsilon=eps, axis=concat_axis, name='conv'+str(final_stage)+'_blk_bn')(x)
|
||||
x = Scale(axis=concat_axis, name='conv'+str(final_stage)+'_blk_scale')(x)
|
||||
x = Activation('relu', name='relu'+str(final_stage)+'_blk')(x)
|
||||
x = GlobalAveragePooling2D(name='pool'+str(final_stage))(x)
|
||||
|
||||
x = Dense(classes, name='fc6')(x)
|
||||
x = Activation('softmax', name='prob')(x)
|
||||
|
||||
model = Model(img_input, x, name='densenet')
|
||||
|
||||
if weights_path is not None:
|
||||
model.load_weights(weights_path)
|
||||
|
||||
return model
|
||||
|
||||
|
||||
def conv_block(x, stage, branch, nb_filter, dropout_rate=None, weight_decay=1e-4):
|
||||
'''Apply BatchNorm, Relu, bottleneck 1x1 Conv2D, 3x3 Conv2D, and option dropout
|
||||
# Arguments
|
||||
x: input tensor
|
||||
stage: index for dense block
|
||||
branch: layer index within each dense block
|
||||
nb_filter: number of filters
|
||||
dropout_rate: dropout rate
|
||||
weight_decay: weight decay factor
|
||||
'''
|
||||
eps = 1.1e-5
|
||||
conv_name_base = 'conv' + str(stage) + '_' + str(branch)
|
||||
relu_name_base = 'relu' + str(stage) + '_' + str(branch)
|
||||
|
||||
# 1x1 Convolution (Bottleneck layer)
|
||||
inter_channel = nb_filter * 4
|
||||
x = BatchNormalization(epsilon=eps, axis=concat_axis, name=conv_name_base+'_x1_bn')(x)
|
||||
x = Scale(axis=concat_axis, name=conv_name_base+'_x1_scale')(x)
|
||||
x = Activation('relu', name=relu_name_base+'_x1')(x)
|
||||
x = Convolution2D(inter_channel, 1, 1, name=conv_name_base+'_x1', bias=False)(x)
|
||||
|
||||
if dropout_rate:
|
||||
x = Dropout(dropout_rate)(x)
|
||||
|
||||
# 3x3 Convolution
|
||||
x = BatchNormalization(epsilon=eps, axis=concat_axis, name=conv_name_base+'_x2_bn')(x)
|
||||
x = Scale(axis=concat_axis, name=conv_name_base+'_x2_scale')(x)
|
||||
x = Activation('relu', name=relu_name_base+'_x2')(x)
|
||||
x = ZeroPadding2D((1, 1), name=conv_name_base+'_x2_zeropadding')(x)
|
||||
x = Convolution2D(nb_filter, 3, 3, name=conv_name_base+'_x2', bias=False)(x)
|
||||
|
||||
if dropout_rate:
|
||||
x = Dropout(dropout_rate)(x)
|
||||
|
||||
return x
|
||||
|
||||
|
||||
def transition_block(x, stage, nb_filter, compression=1.0, dropout_rate=None, weight_decay=1E-4):
|
||||
''' Apply BatchNorm, 1x1 Convolution, averagePooling, optional compression, dropout
|
||||
# Arguments
|
||||
x: input tensor
|
||||
stage: index for dense block
|
||||
nb_filter: number of filters
|
||||
compression: calculated as 1 - reduction. Reduces the number of feature maps in the transition block.
|
||||
dropout_rate: dropout rate
|
||||
weight_decay: weight decay factor
|
||||
'''
|
||||
|
||||
eps = 1.1e-5
|
||||
conv_name_base = 'conv' + str(stage) + '_blk'
|
||||
relu_name_base = 'relu' + str(stage) + '_blk'
|
||||
pool_name_base = 'pool' + str(stage)
|
||||
|
||||
x = BatchNormalization(epsilon=eps, axis=concat_axis, name=conv_name_base+'_bn')(x)
|
||||
x = Scale(axis=concat_axis, name=conv_name_base+'_scale')(x)
|
||||
x = Activation('relu', name=relu_name_base)(x)
|
||||
x = Convolution2D(int(nb_filter * compression), 1, 1, name=conv_name_base, bias=False)(x)
|
||||
|
||||
if dropout_rate:
|
||||
x = Dropout(dropout_rate)(x)
|
||||
|
||||
x = AveragePooling2D((2, 2), strides=(2, 2), name=pool_name_base)(x)
|
||||
|
||||
return x
|
||||
|
||||
|
||||
def dense_block(x, stage, nb_layers, nb_filter, growth_rate, dropout_rate=None, weight_decay=1e-4, grow_nb_filters=True):
|
||||
''' Build a dense_block where the output of each conv_block is fed to subsequent ones
|
||||
# Arguments
|
||||
x: input tensor
|
||||
stage: index for dense block
|
||||
nb_layers: the number of layers of conv_block to append to the model.
|
||||
nb_filter: number of filters
|
||||
growth_rate: growth rate
|
||||
dropout_rate: dropout rate
|
||||
weight_decay: weight decay factor
|
||||
grow_nb_filters: flag to decide to allow number of filters to grow
|
||||
'''
|
||||
|
||||
eps = 1.1e-5
|
||||
concat_feat = x
|
||||
|
||||
for i in range(nb_layers):
|
||||
branch = i+1
|
||||
x = conv_block(concat_feat, stage, branch, growth_rate, dropout_rate, weight_decay)
|
||||
concat_feat = merge([concat_feat, x], mode='concat', concat_axis=concat_axis, name='concat_'+str(stage)+'_'+str(branch))
|
||||
|
||||
if grow_nb_filters:
|
||||
nb_filter += growth_rate
|
||||
|
||||
return concat_feat, nb_filter
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 137 KiB |
Executable
+1000
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 8.5 KiB |
@@ -0,0 +1,47 @@
|
||||
"""Test ImageNet pretrained DenseNet"""
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
from keras.optimizers import SGD
|
||||
import keras.backend as K
|
||||
|
||||
# We only test DenseNet-121 in this script for demo purpose
|
||||
from densenet121 import DenseNet
|
||||
|
||||
im = cv2.resize(cv2.imread('resources/cat.jpg'), (224, 224)).astype(np.float32)
|
||||
#im = cv2.resize(cv2.imread('shark.jpg'), (224, 224)).astype(np.float32)
|
||||
|
||||
# Subtract mean pixel and multiple by scaling constant
|
||||
# Reference: https://github.com/shicai/DenseNet-Caffe
|
||||
im[:,:,0] = (im[:,:,0] - 103.94) * 0.017
|
||||
im[:,:,1] = (im[:,:,1] - 116.78) * 0.017
|
||||
im[:,:,2] = (im[:,:,2] - 123.68) * 0.017
|
||||
|
||||
if K.image_dim_ordering() == 'th':
|
||||
# Transpose image dimensions (Theano uses the channels as the 1st dimension)
|
||||
im = im.transpose((2,0,1))
|
||||
|
||||
# Use pre-trained weights for Theano backend
|
||||
weights_path = 'imagenet_models/densenet121_weights_th.h5'
|
||||
else:
|
||||
# Use pre-trained weights for Tensorflow backend
|
||||
weights_path = 'imagenet_models/densenet121_weights_tf.h5'
|
||||
|
||||
# Insert a new dimension for the batch_size
|
||||
im = np.expand_dims(im, axis=0)
|
||||
|
||||
# Test pretrained model
|
||||
model = DenseNet(reduction=0.5, classes=1000, weights_path=weights_path)
|
||||
|
||||
sgd = SGD(lr=1e-2, decay=1e-6, momentum=0.9, nesterov=True)
|
||||
model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy'])
|
||||
|
||||
out = model.predict(im)
|
||||
|
||||
# Load ImageNet classes file
|
||||
classes = []
|
||||
with open('resources/classes.txt', 'r') as list_:
|
||||
for line in list_:
|
||||
classes.append(line.rstrip('\n'))
|
||||
|
||||
print 'Prediction: '+str(classes[np.argmax(out)])
|
||||
Reference in New Issue
Block a user