From d25aaec04d6aa8cea8dfb541c6fadea42916be0a Mon Sep 17 00:00:00 2001 From: farizrahman4u Date: Sun, 19 Mar 2017 07:27:13 +0530 Subject: [PATCH] update conv layers --- keras_contrib/layers/convolutional.py | 385 +++++++++--------- .../layers/convolutional_recurrent.py | 4 +- .../layers/test_convolutional.py | 92 ++--- 3 files changed, 236 insertions(+), 245 deletions(-) diff --git a/keras_contrib/layers/convolutional.py b/keras_contrib/layers/convolutional.py index 0d6d189..613fef7 100644 --- a/keras_contrib/layers/convolutional.py +++ b/keras_contrib/layers/convolutional.py @@ -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())) diff --git a/keras_contrib/layers/convolutional_recurrent.py b/keras_contrib/layers/convolutional_recurrent.py index 1bb7645..dcc07cd 100644 --- a/keras_contrib/layers/convolutional_recurrent.py +++ b/keras_contrib/layers/convolutional_recurrent.py @@ -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 diff --git a/tests/keras_contrib/layers/test_convolutional.py b/tests/keras_contrib/layers/test_convolutional.py index 868a1ea..a18b948 100644 --- a/tests/keras_contrib/layers/test_convolutional.py +++ b/tests/keras_contrib/layers/test_convolutional.py @@ -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