mirror of
https://github.com/wassname/keras-contrib.git
synced 2026-08-16 11:22:26 +08:00
update conv layers
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user