update conv layers

This commit is contained in:
farizrahman4u
2017-03-19 07:27:13 +05:30
parent aebac0335a
commit d25aaec04d
3 changed files with 236 additions and 245 deletions
+191 -194
View File
@@ -3,16 +3,16 @@ from __future__ import absolute_import
import functools
from .. import backend as K
from .. import activations
from .. import initializations
from .. import regularizers
from .. import constraints
from keras import activations
from keras import initializers
from keras import regularizers
from keras import constraints
from keras.engine import Layer
from keras.engine import InputSpec
from keras.layers.convolutional import Convolution3D
from keras.utils.generic_utils import get_custom_objects
from keras.utils.np_utils import conv_output_length
from keras.utils.np_utils import conv_input_length
from keras.utils.conv_utils import conv_output_length
from keras.utils.conv_utils import conv_input_length
import numpy as np
@@ -43,7 +43,7 @@ class Deconvolution3D(Convolution3D):
# with stride 1x1x1 and 3 output filters on a 12x12x12 image:
model = Sequential()
model.add(Deconvolution3D(3, 3, 3, 3, output_shape=(None, 3, 14, 14, 14),
border_mode='valid',
padding='valid',
input_shape=(3, 12, 12, 12)))
# we can predict with the model and print the shape of the array.
@@ -55,8 +55,8 @@ class Deconvolution3D(Convolution3D):
# with stride 2x2x2 and 3 output filters on a 12x12x12 image:
model = Sequential()
model.add(Deconvolution3D(3, 3, 3, 3, output_shape=(None, 3, 25, 25, 25),
subsample=(2, 2, 2),
border_mode='valid',
strides=(2, 2, 2),
padding='valid',
input_shape=(3, 12, 12, 12)))
model.summary()
@@ -72,7 +72,7 @@ class Deconvolution3D(Convolution3D):
# with stride 1x1x1 and 3 output filters on a 12x12x12 image:
model = Sequential()
model.add(Deconvolution3D(3, 3, 3, 3, output_shape=(None, 14, 14, 14, 3),
border_mode='valid',
padding='valid',
input_shape=(12, 12, 12, 3)))
# we can predict with the model and print the shape of the array.
@@ -84,8 +84,8 @@ class Deconvolution3D(Convolution3D):
# with stride 2x2x2 and 3 output filters on a 12x12x12 image:
model = Sequential()
model.add(Deconvolution3D(3, 3, 3, 3, output_shape=(None, 25, 25, 25, 3),
subsample=(2, 2, 2),
border_mode='valid',
strides=(2, 2, 2),
padding='valid',
input_shape=(12, 12, 12, 3)))
model.summary()
@@ -96,18 +96,18 @@ class Deconvolution3D(Convolution3D):
```
# Arguments
nb_filter: Number of transposed convolution filters to use.
filters: Number of transposed convolution filters to use.
kernel_dim1: Length of the first dimension in the transposed convolution kernel.
kernel_dim2: Length of the second dimension in the transposed convolution kernel.
kernel_dim3: Length of the third dimension in the transposed convolution kernel.
output_shape: Output shape of the transposed convolution operation.
tuple of integers
`(nb_samples, nb_filter, conv_dim1, conv_dim2, conv_dim3)`.
`(nb_samples, filters, conv_dim1, conv_dim2, conv_dim3)`.
It is better to use
a dummy input and observe the actual output shape of
a layer, as specified in the examples.
init: name of initialization function for the weights of the layer
(see [initializations](../initializations.md)), or alternatively,
(see [initializers](../initializers.md)), or alternatively,
Theano function to use for weights initialization.
This parameter is only relevant if you don't pass
a `weights` argument.
@@ -117,40 +117,40 @@ class Deconvolution3D(Convolution3D):
If you don't specify anything, no activation is applied
(ie. "linear" activation: a(x) = x).
weights: list of numpy arrays to set as initial weights.
border_mode: 'valid', 'same' or 'full'
padding: 'valid', 'same' or 'full'
('full' requires the Theano backend).
subsample: tuple of length 3. Factor by which to oversample output.
strides: tuple of length 3. Factor by which to oversample output.
Also called strides elsewhere.
W_regularizer: instance of [WeightRegularizer](../regularizers.md)
kernel_regularizer: instance of [WeightRegularizer](../regularizers.md)
(eg. L1 or L2 regularization), applied to the main weights matrix.
b_regularizer: instance of [WeightRegularizer](../regularizers.md),
applied to the bias.
bias_regularizer: instance of [WeightRegularizer](../regularizers.md),
applied to the use_bias.
activity_regularizer: instance of [ActivityRegularizer](../regularizers.md),
applied to the network output.
W_constraint: instance of the [constraints](../constraints.md) module
kernel_constraint: instance of the [constraints](../constraints.md) module
(eg. maxnorm, nonneg), applied to the main weights matrix.
b_constraint: instance of the [constraints](../constraints.md) module,
applied to the bias.
dim_ordering: 'th' or 'tf'. In 'th' mode, the channels dimension
(the depth) is at index 1, in 'tf' mode is it at index 4.
It defaults to the `image_dim_ordering` value found in your
bias_constraint: instance of the [constraints](../constraints.md) module,
applied to the use_bias.
data_format: 'channels_first' or 'channels_last'. In 'channels_first' mode, the channels dimension
(the depth) is at index 1, in 'channels_last' mode is it at index 4.
It defaults to the `image_data_format` value found in your
Keras config file at `~/.keras/keras.json`.
If you never set it, then it will be "tf".
bias: whether to include a bias
use_bias: whether to include a use_bias
(i.e. make the layer affine rather than linear).
# Input shape
5D tensor with shape:
`(samples, channels, conv_dim1, conv_dim2, conv_dim3)` if dim_ordering='th'
`(samples, channels, conv_dim1, conv_dim2, conv_dim3)` if data_format='channels_first'
or 5D tensor with shape:
`(samples, conv_dim1, conv_dim2, conv_dim3, channels)` if dim_ordering='tf'.
`(samples, conv_dim1, conv_dim2, conv_dim3, channels)` if data_format='channels_last'.
# Output shape
5D tensor with shape:
`(samples, nb_filter, new_conv_dim1, new_conv_dim2, new_conv_dim3)` if dim_ordering='th'
`(samples, filters, nekernel_conv_dim1, nekernel_conv_dim2, nekernel_conv_dim3)` if data_format='channels_first'
or 5D tensor with shape:
`(samples, new_conv_dim1, new_conv_dim2, new_conv_dim3, nb_filter)` if dim_ordering='tf'.
`new_conv_dim1`, `new_conv_dim2` and `new_conv_dim3` values might have changed due to padding.
`(samples, nekernel_conv_dim1, nekernel_conv_dim2, nekernel_conv_dim3, filters)` if data_format='channels_last'.
`nekernel_conv_dim1`, `nekernel_conv_dim2` and `nekernel_conv_dim3` values might have changed due to padding.
# References
- [A guide to convolution arithmetic for deep learning](https://arxiv.org/abs/1603.07285v1)
@@ -158,66 +158,65 @@ class Deconvolution3D(Convolution3D):
- [Deconvolutional Networks](http://www.matthewzeiler.com/pubs/cvpr2010/cvpr2010.pdf)
"""
def __init__(self, nb_filter, kernel_dim1, kernel_dim2, kernel_dim3,
output_shape, init='glorot_uniform', activation=None, weights=None,
border_mode='valid', subsample=(1, 1, 1),
dim_ordering='default',
W_regularizer=None, b_regularizer=None, activity_regularizer=None,
W_constraint=None, b_constraint=None,
bias=True, **kwargs):
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
if border_mode not in {'valid', 'same', 'full'}:
raise ValueError('Invalid border mode for Deconvolution3D:', border_mode)
def __init__(self, filters, kernel_size,
output_shape, activation=None, weights=None,
padding='valid', strides=(1, 1, 1), data_format=None,
kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None,
kernel_constraint=None, bias_constraint=None,
use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', **kwargs):
if padding not in {'valid', 'same', 'full'}:
raise ValueError('Invalid border mode for Deconvolution3D:', padding)
if len(output_shape) == 4:
# missing the batch size
output_shape = (None,) + tuple(output_shape)
self.output_shape_ = output_shape
super(Deconvolution3D, self).__init__(nb_filter,
kernel_dim1, kernel_dim2, kernel_dim3,
init=init,
super(Deconvolution3D, self).__init__(kernel_size=kernel_size,
filters=filters,
activation=activation,
weights=weights,
border_mode=border_mode,
subsample=subsample,
dim_ordering=dim_ordering,
W_regularizer=W_regularizer,
b_regularizer=b_regularizer,
padding=padding,
strides=strides,
data_format=data_format,
kernel_regularizer=kernel_regularizer,
bias_regularizer=bias_regularizer,
activity_regularizer=activity_regularizer,
W_constraint=W_constraint,
b_constraint=b_constraint,
bias=bias,
kernel_constraint=kernel_constraint,
bias_constraint=bias_constraint,
use_bias=use_bias,
kernel_initializer=kernel_initializer,
bias_initializer=bias_initializer,
**kwargs)
def get_output_shape_for(self, input_shape):
if self.dim_ordering == 'th':
def compute_output_shape(self, input_shape):
if self.data_format == 'channels_first':
conv_dim1 = self.output_shape_[2]
conv_dim2 = self.output_shape_[3]
conv_dim3 = self.output_shape_[4]
return (input_shape[0], self.nb_filter, conv_dim1, conv_dim2, conv_dim3)
elif self.dim_ordering == 'tf':
return (input_shape[0], self.filters, conv_dim1, conv_dim2, conv_dim3)
elif self.data_format == 'channels_last':
conv_dim1 = self.output_shape_[1]
conv_dim2 = self.output_shape_[2]
conv_dim3 = self.output_shape_[3]
return (input_shape[0], conv_dim1, conv_dim2, conv_dim3, self.nb_filter)
return (input_shape[0], conv_dim1, conv_dim2, conv_dim3, self.filters)
else:
raise ValueError('Invalid dim_ordering:', self.dim_ordering)
raise ValueError('Invalid data format: ', self.data_format)
def call(self, x, mask=None):
output = K.deconv3d(x, self.W, self.output_shape_,
strides=self.subsample,
border_mode=self.border_mode,
dim_ordering=self.dim_ordering,
filter_shape=self.W_shape)
if self.bias:
if self.dim_ordering == 'th':
output += K.reshape(self.b, (1, self.nb_filter, 1, 1, 1))
elif self.dim_ordering == 'tf':
output += K.reshape(self.b, (1, 1, 1, 1, self.nb_filter))
kernel_shape = self.kernel.get_value().shape
output = K.deconv3d(x, self.kernel, self.output_shape_,
strides=self.strides,
padding=self.padding,
data_format=self.data_format,
filter_shape=kernel_shape)
if self.use_bias:
if self.data_format == 'channels_first':
output += K.reshape(self.bias, (1, self.filters, 1, 1, 1))
elif self.data_format == 'channels_last':
output += K.reshape(self.use_bias, (1, 1, 1, 1, self.filters))
else:
raise ValueError('Invalid dim_ordering:', self.dim_ordering)
raise ValueError('Invalid data_format: ', self.data_format)
output = self.activation(output)
return output
@@ -248,21 +247,21 @@ class CosineConvolution2D(Layer):
# apply a 3x3 convolution with 64 output filters on a 256x256 image:
model = Sequential()
model.add(CosineConvolution2D(64, 3, 3,
border_mode='same',
padding='same',
input_shape=(3, 256, 256)))
# now model.output_shape == (None, 64, 256, 256)
# add a 3x3 convolution on top, with 32 output filters:
model.add(CosineConvolution2D(32, 3, 3, border_mode='same'))
model.add(CosineConvolution2D(32, 3, 3, padding='same'))
# now model.output_shape == (None, 32, 256, 256)
```
# Arguments
nb_filter: Number of convolution filters to use.
filters: Number of convolution filters to use.
nb_row: Number of rows in the convolution kernel.
nb_col: Number of columns in the convolution kernel.
init: name of initialization function for the weights of the layer
(see [initializations](../initializations.md)), or alternatively,
(see [initializers](../initializers.md)), or alternatively,
Theano function to use for weights initialization.
This parameter is only relevant if you don't pass
a `weights` argument.
@@ -272,102 +271,101 @@ class CosineConvolution2D(Layer):
If you don't specify anything, no activation is applied
(ie. "linear" activation: a(x) = x).
weights: list of numpy arrays to set as initial weights.
border_mode: 'valid', 'same' or 'full'
padding: 'valid', 'same' or 'full'
('full' requires the Theano backend).
subsample: tuple of length 2. Factor by which to subsample output.
strides: tuple of length 2. Factor by which to strides output.
Also called strides elsewhere.
W_regularizer: instance of [WeightRegularizer](../regularizers.md)
kernel_regularizer: instance of [WeightRegularizer](../regularizers.md)
(eg. L1 or L2 regularization), applied to the main weights matrix.
b_regularizer: instance of [WeightRegularizer](../regularizers.md),
applied to the bias.
bias_regularizer: instance of [WeightRegularizer](../regularizers.md),
applied to the use_bias.
activity_regularizer: instance of [ActivityRegularizer](../regularizers.md),
applied to the network output.
W_constraint: instance of the [constraints](../constraints.md) module
kernel_constraint: instance of the [constraints](../constraints.md) module
(eg. maxnorm, nonneg), applied to the main weights matrix.
b_constraint: instance of the [constraints](../constraints.md) module,
applied to the bias.
dim_ordering: 'th' or 'tf'. In 'th' mode, the channels dimension
(the depth) is at index 1, in 'tf' mode is it at index 3.
It defaults to the `image_dim_ordering` value found in your
bias_constraint: instance of the [constraints](../constraints.md) module,
applied to the use_bias.
data_format: 'channels_first' or 'channels_last'. In 'channels_first' mode, the channels dimension
(the depth) is at index 1, in 'channels_last' mode is it at index 3.
It defaults to the `image_data_format` value found in your
Keras config file at `~/.keras/keras.json`.
If you never set it, then it will be "tf".
bias: whether to include a bias
use_bias: whether to include a use_bias
(i.e. make the layer affine rather than linear).
# Input shape
4D tensor with shape:
`(samples, channels, rows, cols)` if dim_ordering='th'
`(samples, channels, rows, cols)` if data_format='channels_first'
or 4D tensor with shape:
`(samples, rows, cols, channels)` if dim_ordering='tf'.
`(samples, rows, cols, channels)` if data_format='channels_last'.
# Output shape
4D tensor with shape:
`(samples, nb_filter, new_rows, new_cols)` if dim_ordering='th'
`(samples, filters, nekernel_rows, nekernel_cols)` if data_format='channels_first'
or 4D tensor with shape:
`(samples, new_rows, new_cols, nb_filter)` if dim_ordering='tf'.
`(samples, nekernel_rows, nekernel_cols, filters)` if data_format='channels_last'.
`rows` and `cols` values might have changed due to padding.
"""
def __init__(self, nb_filter, nb_row, nb_col,
init='glorot_uniform', activation=None, weights=None,
border_mode='valid', subsample=(1, 1), dim_ordering='default',
W_regularizer=None, b_regularizer=None,
def __init__(self, filters, kernel_size,
kernel_initializer='glorot_uniform', activation=None, weights=None,
padding='valid', strides=(1, 1), data_format='default',
kernel_regularizer=None, bias_regularizer=None,
activity_regularizer=None,
W_constraint=None, b_constraint=None,
bias=True, **kwargs):
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
if border_mode not in {'valid', 'same', 'full'}:
raise ValueError('Invalid border mode for CosineConvolution2D:', border_mode)
self.nb_filter = nb_filter
self.nb_row = nb_row
self.nb_col = nb_col
self.init = initializations.get(init)
kernel_constraint=None, bias_constraint=None,
use_bias=True, **kwargs):
if data_format == 'default':
data_format = K.image_data_format()
if padding not in {'valid', 'same', 'full'}:
raise ValueError('Invalid border mode for CosineConvolution2D:', padding)
self.filters = filters
self.kernel_size = kernel_size
self.nb_row, self.nb_col = self.kernel_size
self.kernel_initializer = initializers.get(kernel_initializer)
self.activation = activations.get(activation)
self.border_mode = border_mode
self.subsample = tuple(subsample)
if dim_ordering not in {'tf', 'th'}:
raise ValueError('dim_ordering must be in {tf, th}.')
self.dim_ordering = dim_ordering
self.padding = padding
self.strides = tuple(strides)
if data_format not in {'channels_last', 'channels_first'}:
raise ValueError('data_format must be in {\'channels_last\', \'channels_first\'}.')
self.data_format = data_format
self.W_regularizer = regularizers.get(W_regularizer)
self.b_regularizer = regularizers.get(b_regularizer)
self.kernel_regularizer = regularizers.get(kernel_regularizer)
self.bias_regularizer = regularizers.get(bias_regularizer)
self.activity_regularizer = regularizers.get(activity_regularizer)
self.W_constraint = constraints.get(W_constraint)
self.b_constraint = constraints.get(b_constraint)
self.kernel_constraint = constraints.get(kernel_constraint)
self.bias_constraint = constraints.get(bias_constraint)
self.bias = bias
self.use_bias = use_bias
self.input_spec = [InputSpec(ndim=4)]
self.initial_weights = weights
super(CosineConvolution2D, self).__init__(**kwargs)
def build(self, input_shape):
if self.dim_ordering == 'th':
if self.data_format == 'channels_first':
stack_size = input_shape[1]
self.W_shape = (self.nb_filter, stack_size, self.nb_row, self.nb_col)
self.W_norm_shape = (1, stack_size, self.nb_row, self.nb_col)
elif self.dim_ordering == 'tf':
self.kernel_shape = (self.filters, stack_size, self.nb_row, self.nb_col)
self.kernel_norm_shape = (1, stack_size, self.nb_row, self.nb_col)
elif self.data_format == 'channels_last':
stack_size = input_shape[3]
self.W_shape = (self.nb_row, self.nb_col, stack_size, self.nb_filter)
self.W_norm_shape = (self.nb_row, self.nb_col, stack_size, 1)
self.kernel_shape = (self.nb_row, self.nb_col, stack_size, self.filters)
self.kernel_norm_shape = (self.nb_row, self.nb_col, stack_size, 1)
else:
raise ValueError('Invalid dim_ordering:', self.dim_ordering)
self.W = self.add_weight(self.W_shape,
initializer=functools.partial(self.init,
dim_ordering=self.dim_ordering),
raise ValueError('Invalid data_format:', self.data_format)
self.W = self.add_weight(self.kernel_shape,
initializer=functools.partial(self.kernel_initializer),
name='{}_W'.format(self.name),
regularizer=self.W_regularizer,
constraint=self.W_constraint)
regularizer=self.kernel_regularizer,
constraint=self.kernel_constraint)
self.W_norm = K.variable(np.ones(self.W_norm_shape), name='{}_W_norm'.format(self.name))
self.kernel_norm = K.variable(np.ones(self.kernel_norm_shape), name='{}_kernel_norm'.format(self.name))
if self.bias:
self.b = self.add_weight((self.nb_filter,),
if self.use_bias:
self.b = self.add_weight((self.filters,),
initializer='zero',
name='{}_b'.format(self.name),
regularizer=self.b_regularizer,
constraint=self.b_constraint)
regularizer=self.bias_regularizer,
constraint=self.bias_constraint)
else:
self.b = None
@@ -376,85 +374,84 @@ class CosineConvolution2D(Layer):
del self.initial_weights
self.built = True
def get_output_shape_for(self, input_shape):
if self.dim_ordering == 'th':
def compute_output_shape(self, input_shape):
if self.data_format == 'channels_first':
rows = input_shape[2]
cols = input_shape[3]
elif self.dim_ordering == 'tf':
elif self.data_format == 'channels_last':
rows = input_shape[1]
cols = input_shape[2]
else:
raise ValueError('Invalid dim_ordering:', self.dim_ordering)
raise ValueError('Invalid data_format:', self.data_format)
rows = conv_output_length(rows, self.nb_row,
self.border_mode, self.subsample[0])
self.padding, self.strides[0])
cols = conv_output_length(cols, self.nb_col,
self.border_mode, self.subsample[1])
self.padding, self.strides[1])
if self.dim_ordering == 'th':
return (input_shape[0], self.nb_filter, rows, cols)
elif self.dim_ordering == 'tf':
return (input_shape[0], rows, cols, self.nb_filter)
if self.data_format == 'channels_first':
return (input_shape[0], self.filters, rows, cols)
elif self.data_format == 'channels_last':
return (input_shape[0], rows, cols, self.filters)
def call(self, x, mask=None):
b, xb = 0., 0.
if self.dim_ordering == 'th':
W_sum_axes = [1, 2, 3]
if self.bias:
b = K.reshape(self.b, (self.nb_filter, 1, 1, 1))
if self.data_format == 'channels_first':
kernel_sum_axes = [1, 2, 3]
if self.use_bias:
b = K.reshape(self.b, (self.filters, 1, 1, 1))
xb = 1.
elif self.dim_ordering == 'tf':
W_sum_axes = [0, 1, 2]
if self.bias:
b = K.reshape(self.b, (1, 1, 1, self.nb_filter))
elif self.data_format == 'channels_last':
kernel_sum_axes = [0, 1, 2]
if self.use_bias:
b = K.reshape(self.b, (1, 1, 1, self.filters))
xb = 1.
Wnorm = K.sqrt(K.sum(K.square(self.W), axis=W_sum_axes, keepdims=True) + K.square(b) + K.epsilon())
xnorm = K.sqrt(K.conv2d(K.square(x), self.W_norm, strides=self.subsample,
border_mode=self.border_mode,
dim_ordering=self.dim_ordering,
filter_shape=self.W_norm_shape) + xb + K.epsilon())
Wnorm = K.sqrt(K.sum(K.square(self.W), axis=kernel_sum_axes, keepdims=True) + K.square(b) + K.epsilon())
xnorm = K.sqrt(K.conv2d(K.square(x), self.kernel_norm, strides=self.strides,
padding=self.padding,
data_format=self.data_format,
filter_shape=self.kernel_norm_shape) + xb + K.epsilon())
W = self.W / Wnorm
output = K.conv2d(x, W, strides=self.subsample,
border_mode=self.border_mode,
dim_ordering=self.dim_ordering,
filter_shape=self.W_shape)
output = K.conv2d(x, W, strides=self.strides,
padding=self.padding,
data_format=self.data_format,
filter_shape=self.kernel_shape)
if K.backend() == 'theano':
xnorm = K.pattern_broadcast(xnorm, [False, True, False, False])
output /= xnorm
if self.bias:
if self.use_bias:
b /= Wnorm
if self.dim_ordering == 'th':
b = K.reshape(b, (1, self.nb_filter, 1, 1))
elif self.dim_ordering == 'tf':
b = K.reshape(b, (1, 1, 1, self.nb_filter))
if self.data_format == 'channels_first':
b = K.reshape(b, (1, self.filters, 1, 1))
elif self.data_format == 'channels_last':
b = K.reshape(b, (1, 1, 1, self.filters))
else:
raise ValueError('Invalid dim_ordering:', self.dim_ordering)
raise ValueError('Invalid data_format:', self.data_format)
b /= xnorm
output += b
output = self.activation(output)
return output
def get_config(self):
config = {'nb_filter': self.nb_filter,
'nb_row': self.nb_row,
'nb_col': self.nb_col,
'init': self.init.__name__,
'activation': self.activation.__name__,
'border_mode': self.border_mode,
'subsample': self.subsample,
'dim_ordering': self.dim_ordering,
'W_regularizer': self.W_regularizer.get_config() if self.W_regularizer else None,
'b_regularizer': self.b_regularizer.get_config() if self.b_regularizer else None,
'activity_regularizer': self.activity_regularizer.get_config() if self.activity_regularizer else None,
'W_constraint': self.W_constraint.get_config() if self.W_constraint else None,
'b_constraint': self.b_constraint.get_config() if self.b_constraint else None,
'bias': self.bias}
config = {'filters': self.filters,
'kernel_size': self.kernel_size,
'kernel_initializer': initializers.serialize(self.kernel_initializer),
'activation': activations.serialize(self.activation),
'padding': self.padding,
'strides': self.strides,
'data_format': self.data_format,
'kernel_regularizer': regularizers.serialize(self.kernel_regularizer),
'bias_regularizer': regularizers.serialize(self.bias_regularizer),
'activity_regularizer': regularizers.serialize(self.activity_regularizer),
'kernel_constraint': constraints.serialize(self.kernel_constraint),
'bias_constraint': constraints.serialize(self.bias_constraint),
'use_bias': self.use_bias}
base_config = super(CosineConvolution2D, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
@@ -469,10 +466,10 @@ class SubPixelUpscaling(Layer):
and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network"
(https://arxiv.org/abs/1609.05158).
This layer requires a Convolution2D prior to it, having output nb_filter computed according to
This layer requires a Convolution2D prior to it, having output filters computed according to
the formula :
nb_filter = k * (scale_factor * scale_factor)
filters = k * (scale_factor * scale_factor)
where k = a user defined number of filters (generally larger than 32)
scale_factor = the upscaling factor (generally 2)
@@ -482,11 +479,11 @@ class SubPixelUpscaling(Layer):
# Example :
```python
# A standard subpixel upscaling block
x = Convolution2D(256, 3, 3, border_mode='same', activation='relu')(...)
x = Convolution2D(256, 3, 3, padding='same', activation='relu')(...)
u = SubPixelUpscaling(scale_factor=2)(x)
[Optional]
x = Convolution2D(256, 3, 3, border_mode='same', activation='relu')(u)
x = Convolution2D(256, 3, 3, padding='same', activation='relu')(u)
```
In practice, it is useful to have a second convolution layer after the
@@ -498,30 +495,30 @@ class SubPixelUpscaling(Layer):
# Arguments
scale_factor: Upscaling factor.
dim_ordering: Can be 'default', 'th' or 'tf'.
data_format: Can be 'default', 'channels_first' or 'channels_last'.
# Input shape
4D tensor with shape:
`(samples, k * (scale_factor * scale_factor) channels, rows, cols)` if dim_ordering='th'
`(samples, k * (scale_factor * scale_factor) channels, rows, cols)` if data_format='channels_first'
or 4D tensor with shape:
`(samples, rows, cols, k * (scale_factor * scale_factor) channels)` if dim_ordering='tf'.
`(samples, rows, cols, k * (scale_factor * scale_factor) channels)` if data_format='channels_last'.
# Output shape
4D tensor with shape:
`(samples, k channels, rows * scale_factor, cols * scale_factor))` if dim_ordering='th'
`(samples, k channels, rows * scale_factor, cols * scale_factor))` if data_format='channels_first'
or 4D tensor with shape:
`(samples, rows * scale_factor, cols * scale_factor, k channels)` if dim_ordering='tf'.
`(samples, rows * scale_factor, cols * scale_factor, k channels)` if data_format='channels_last'.
"""
def __init__(self, scale_factor=2, dim_ordering='default', **kwargs):
def __init__(self, scale_factor=2, data_format='default', **kwargs):
super(SubPixelUpscaling, self).__init__(**kwargs)
self.scale_factor = scale_factor
self.dim_ordering = dim_ordering
self.data_format = data_format
if self.dim_ordering == 'default':
self.dim_ordering = K.image_dim_ordering()
if self.data_format == 'default':
self.data_format = K.image_data_format()
def build(self, input_shape):
pass
@@ -531,7 +528,7 @@ class SubPixelUpscaling(Layer):
return y
def get_output_shape_for(self, input_shape):
if self.dim_ordering == 'th':
if self.data_format == 'channels_first':
b, k, r, c = input_shape
return (b, k // (self.scale_factor ** 2), r * self.scale_factor, c * self.scale_factor)
else:
@@ -540,7 +537,7 @@ class SubPixelUpscaling(Layer):
def get_config(self):
config = {'scale_factor': self.scale_factor,
'dim_ordering': self.dim_ordering}
'data_format': self.data_format}
base_config = super(SubPixelUpscaling, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
@@ -1,9 +1,9 @@
from .. import backend as K
from .. import activations
from .. import initializations
from .. import initializers
from .. import regularizers
import numpy as np
from keras.engine import Layer
from keras.engine import InputSpec
from keras.utils.np_utils import conv_output_length
from keras.utils.conv_utils import conv_output_length
@@ -4,7 +4,7 @@ import itertools
from numpy.testing import assert_allclose
from keras.utils.test_utils import layer_test, keras_test
from keras.utils.np_utils import conv_input_length
from keras.utils.conv_utils import conv_input_length
from keras import backend as K
from keras_contrib import backend as KC
from keras_contrib.layers import convolutional, pooling
@@ -12,7 +12,7 @@ from keras.models import Sequential
# TensorFlow does not support full convolution.
if K.backend() == 'theano':
_convolution_border_modes = ['valid', 'same', 'full']
_convolution_border_modes = ['valid', 'same']
else:
_convolution_border_modes = ['valid', 'same']
@@ -36,44 +36,38 @@ def test_deconvolution_3d():
dim2 = conv_input_length(kernel_dim2, 5, border_mode, subsample[1])
dim3 = conv_input_length(kernel_dim3, 3, border_mode, subsample[2])
layer_test(convolutional.Deconvolution3D,
kwargs={'nb_filter': nb_filter,
'kernel_dim1': 7,
'kernel_dim2': 5,
'kernel_dim3': 3,
kwargs={'filters': nb_filter,
'kernel_size': (7, 5, 3),
'output_shape': (batch_size, nb_filter, dim1, dim2, dim3),
'border_mode': border_mode,
'subsample': subsample,
'dim_ordering': 'th'},
'padding': border_mode,
'strides': subsample,
'data_format': 'channels_first'},
input_shape=(nb_samples, stack_size, kernel_dim1, kernel_dim2, kernel_dim3),
fixed_batch_size=True)
layer_test(convolutional.Deconvolution3D,
kwargs={'nb_filter': nb_filter,
'kernel_dim1': 7,
'kernel_dim2': 5,
'kernel_dim3': 3,
kwargs={'filters': nb_filter,
'kernel_size': (7, 5, 3),
'output_shape': (batch_size, nb_filter, dim1, dim2, dim3),
'border_mode': border_mode,
'dim_ordering': 'th',
'padding': border_mode,
'strides': subsample,
'data_format': 'channels_first',
'W_regularizer': 'l2',
'b_regularizer': 'l2',
'activity_regularizer': 'activity_l2',
'subsample': subsample},
'activity_regularizer': 'activity_l2'},
input_shape=(nb_samples, stack_size, kernel_dim1, kernel_dim2, kernel_dim3),
fixed_batch_size=True)
layer_test(convolutional.Deconvolution3D,
kwargs={'nb_filter': nb_filter,
'kernel_dim1': 7,
'kernel_dim2': 5,
'kernel_dim3': 3,
kwargs={'filters': nb_filter,
'kernel_size': (7, 5, 3),
'output_shape': (nb_filter, dim1, dim2, dim3),
'border_mode': border_mode,
'dim_ordering': 'th',
'padding': border_mode,
'strides': subsample,
'data_format': 'channels_first',
'W_regularizer': 'l2',
'b_regularizer': 'l2',
'activity_regularizer': 'activity_l2',
'subsample': subsample},
'activity_regularizer': 'activity_l2'},
input_shape=(nb_samples, stack_size, kernel_dim1, kernel_dim2, kernel_dim3))
@@ -86,50 +80,50 @@ def test_cosineconvolution_2d():
nb_col = 6
if K.backend() == 'theano':
dim_ordering = 'th'
data_format = 'channels_first'
elif K.backend() == 'tensorflow':
dim_ordering = 'tf'
data_format = 'channels_last'
for border_mode in _convolution_border_modes:
for subsample in [(1, 1), (2, 2)]:
for bias_mode in [True, False]:
for use_bias_mode in [True, False]:
if border_mode == 'same' and subsample != (1, 1):
continue
layer_test(convolutional.CosineConvolution2D,
kwargs={'nb_filter': nb_filter,
'nb_row': 3,
'nb_col': 3,
'border_mode': border_mode,
'subsample': subsample,
'bias': bias_mode,
'dim_ordering': dim_ordering},
kwargs={'filters': nb_filter,
'kernel_size': (3, 3),
'padding': border_mode,
'strides': subsample,
'use_bias': use_bias_mode,
'data_format': data_format},
input_shape=(nb_samples, nb_row, nb_col, stack_size))
layer_test(convolutional.CosineConvolution2D,
kwargs={'nb_filter': nb_filter,
'nb_row': 3,
'nb_col': 3,
'border_mode': border_mode,
'W_regularizer': 'l2',
'b_regularizer': 'l2',
'activity_regularizer': 'activity_l2',
'subsample': subsample,
'bias': bias_mode,
'dim_ordering': dim_ordering},
kwargs={'filters': nb_filter,
'kernel_size': (3, 3),
'padding': border_mode,
'strides': subsample,
'use_bias': use_bias_mode,
'data_format': data_format,
'kernel_regularizer': 'l2',
'bias_regularizer': 'l2',
'activity_regularizer': 'l2'},
input_shape=(nb_samples, nb_row, nb_col, stack_size))
if dim_ordering == 'th':
if data_format == 'channels_first':
X = np.random.randn(1, 3, 5, 5)
input_dim = (3, 5, 5)
W0 = X[:, :, ::-1, ::-1]
elif dim_ordering == 'tf':
elif data_format == 'channels_last':
X = np.random.randn(1, 5, 5, 3)
input_dim = (5, 5, 3)
W0 = X[0, :, :, :, None]
model = Sequential()
model.add(convolutional.CosineConvolution2D(1, 5, 5, bias=True, input_shape=input_dim, dim_ordering=dim_ordering))
model.add(convolutional.CosineConvolution2D(1, 5, 5, use_bias=True, input_shape=input_dim, dim_ordering=dim_ordering))
model.compile(loss='mse', optimizer='rmsprop')
W = model.get_weights()
W[0] = W0
@@ -139,7 +133,7 @@ def test_cosineconvolution_2d():
assert_allclose(out, np.ones((1, 1, 1, 1), dtype=K.floatx()), atol=1e-5)
model = Sequential()
model.add(convolutional.CosineConvolution2D(1, 5, 5, bias=False, input_shape=input_dim, dim_ordering=dim_ordering))
model.add(convolutional.CosineConvolution2D(1, 5, 5, use_bias=False, input_shape=input_dim, dim_ordering=dim_ordering))
model.compile(loss='mse', optimizer='rmsprop')
W = model.get_weights()
W[0] = -2 * W0