diff --git a/keras/layers/convolutional.py b/keras/layers/convolutional.py index edbc5e3d..6f042c60 100644 --- a/keras/layers/convolutional.py +++ b/keras/layers/convolutional.py @@ -19,8 +19,6 @@ from .pooling import MaxPooling1D from .pooling import MaxPooling2D from .pooling import MaxPooling3D -from ..legacy import interfaces - class _Conv(Layer): """Abstract nD convolution layer (private, used as implementation base). diff --git a/keras/layers/convolutional_recurrent.py b/keras/layers/convolutional_recurrent.py index b06b9592..94ddbb69 100644 --- a/keras/layers/convolutional_recurrent.py +++ b/keras/layers/convolutional_recurrent.py @@ -11,6 +11,7 @@ from .recurrent import Recurrent import numpy as np from ..engine import InputSpec from ..utils import conv_utils +from ..legacy import interfaces class ConvRecurrent2D(Recurrent): @@ -270,6 +271,7 @@ class ConvLSTM2D(ConvRecurrent2D): cells output """ + @interfaces.legacy_convlstm2d_support def __init__(self, filters, kernel_size, strides=(1, 1), diff --git a/keras/layers/local.py b/keras/layers/local.py index f4f77ecf..30890ee9 100644 --- a/keras/layers/local.py +++ b/keras/layers/local.py @@ -9,6 +9,7 @@ from .. import constraints from ..engine import Layer from ..engine import InputSpec from ..utils import conv_utils +from ..legacy import interfaces class LocallyConnected1D(Layer): @@ -71,6 +72,7 @@ class LocallyConnected1D(Layer): `steps` value might have changed due to padding or strides. """ + @interfaces.legacy_conv1d_support def __init__(self, filters, kernel_size, strides=1, @@ -266,6 +268,7 @@ class LocallyConnected2D(Layer): `rows` and `cols` values might have changed due to padding. """ + @interfaces.legacy_conv2d_support def __init__(self, filters, kernel_size, strides=(1, 1), diff --git a/keras/layers/normalization.py b/keras/layers/normalization.py index 00f52a34..9e6c944e 100644 --- a/keras/layers/normalization.py +++ b/keras/layers/normalization.py @@ -6,6 +6,7 @@ from .. import initializers from .. import regularizers from .. import constraints from .. import backend as K +from ..legacy import interfaces class BatchNormalization(Layer): @@ -51,6 +52,7 @@ class BatchNormalization(Layer): - [Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift](https://arxiv.org/abs/1502.03167) """ + @interfaces.legacy_batchnorm_support def __init__(self, axis=-1, momentum=0.99, diff --git a/keras/legacy/interfaces.py b/keras/legacy/interfaces.py index 5c62fec1..1c35e75e 100644 --- a/keras/legacy/interfaces.py +++ b/keras/legacy/interfaces.py @@ -262,11 +262,14 @@ legacy_conv2d_support = generate_legacy_interface( def separable_conv2d_args_preprocessor(args, kwargs): + converted = [] if 'init' in kwargs: init = kwargs.pop('init') kwargs['depthwise_initializer'] = init kwargs['pointwise_initializer'] = init - return conv2d_args_preprocessor(args, kwargs) + converted.append(('init', 'depthwise_initializer/pointwise_initializer')) + args, kwargs, _converted = conv2d_args_preprocessor(args, kwargs) + return args, kwargs, converted + _converted legacy_separable_conv2d_support = generate_legacy_interface( allowed_positional_args=['filters', 'kernel_size'], @@ -284,12 +287,16 @@ legacy_separable_conv2d_support = generate_legacy_interface( def deconv2d_args_preprocessor(args, kwargs): + converted = [] if len(args) == 5: if isinstance(args[4], tuple): args = args[:-1] + converted.append(('output_shape', None)) if 'output_shape' in kwargs: kwargs.pop('output_shape') - return conv2d_args_preprocessor(args, kwargs) + converted.append(('output_shape', None)) + args, kwargs, _converted = conv2d_args_preprocessor(args, kwargs) + return args, kwargs, converted + _converted legacy_deconv2d_support = generate_legacy_interface( allowed_positional_args=['filters', 'kernel_size'], @@ -360,3 +367,62 @@ legacy_conv3d_support = generate_legacy_interface( 'th': 'channels_first', 'default': None}}, preprocessor=conv3d_args_preprocessor) + + +def batchnorm_args_preprocessor(args, kwargs): + converted = [] + if len(args) > 1: + raise TypeError('The `BatchNormalization` layer ' + 'does not accept positional arguments. ' + 'Use keyword arguments instead.') + if 'mode' in kwargs: + value = kwargs.pop('mode') + if value != 0: + raise TypeError('The `mode` argument of `BatchNormalization` ' + 'no longer exists. `mode=1` and `mode=2` ' + 'are no longer supported.') + converted.append(('mode', None)) + return args, kwargs, converted + + +def convlstm2d_args_preprocessor(args, kwargs): + converted = [] + if 'forget_bias_init' in kwargs: + value = kwargs.pop('forget_bias_init') + if value == 'one': + kwargs['unit_forget_bias'] = True + converted.append(('forget_bias_init', 'unit_forget_bias')) + else: + warnings.warn('The `forget_bias_init` argument ' + 'has been ignored. Use `unit_forget_bias=True` ' + 'instead to intialize with ones') + args, kwargs, _converted = conv2d_args_preprocessor(args, kwargs) + return args, kwargs, converted + _converted + + +legacy_convlstm2d_support = generate_legacy_interface( + allowed_positional_args=['filters', 'kernel_size'], + conversions=[('nb_filter', 'filters'), + ('subsample', 'strides'), + ('border_mode', 'padding'), + ('dim_ordering', 'data_format'), + ('init', 'kernel_initializer'), + ('inner_init', 'recurrent_initializer'), + ('W_regularizer', 'kernel_regularizer'), + ('U_regularizer', 'recurrent_regularizer'), + ('b_regularizer', 'bias_regularizer'), + ('inner_activation', 'recurrent_activation'), + ('dropout_W', 'dropout'), + ('dropout_U', 'recurrent_dropout'), + ('bias', 'use_bias')], + value_conversions={'dim_ordering': {'tf': 'channels_last', + 'th': 'channels_first', + 'default': None}}, + preprocessor=convlstm2d_args_preprocessor) + + +legacy_batchnorm_support = generate_legacy_interface( + allowed_positional_args=[], + conversions=[('beta_init', 'beta_initializer'), + ('gamma_init', 'gamma_initializer')], + preprocessor=batchnorm_args_preprocessor) diff --git a/pytest.ini b/pytest.ini index 079ed86d..cdfd1d5d 100644 --- a/pytest.ini +++ b/pytest.ini @@ -3,8 +3,6 @@ addopts=-v -n 2 --durations=10 - --cov-report term-missing - --cov=keras # Do not run tests in the build folder norecursedirs= build diff --git a/tests/keras/legacy/interface_test.py b/tests/keras/legacy/interface_test.py index 11adf368..952eebe0 100644 --- a/tests/keras/legacy/interface_test.py +++ b/tests/keras/legacy/interface_test.py @@ -592,5 +592,66 @@ def test_conv3d_legacy_interface(): assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config()) +@keras_test +def test_convlstm2d_legacy_interface(): + old_layer = keras.layers.ConvLSTM2D(5, 3, 3, name='conv') + new_layer = keras.layers.ConvLSTM2D(5, (3, 3), name='conv') + assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config()) + + old_layer = keras.layers.ConvLSTM2D(5, 3, nb_col=3, name='conv') + new_layer = keras.layers.ConvLSTM2D(5, (3, 3), name='conv') + assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config()) + + old_layer = keras.layers.ConvLSTM2D(5, nb_row=3, nb_col=3, name='conv') + new_layer = keras.layers.ConvLSTM2D(5, (3, 3), name='conv') + assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config()) + + old_layer = keras.layers.ConvLSTM2D(5, 3, 3, + init='normal', + inner_init='uniform', + forget_bias_init='one', + inner_activation='relu', + subsample=(2, 2), + border_mode='valid', + dim_ordering='th', + W_regularizer='l1', + U_regularizer='l2', + b_regularizer='l2', + dropout_W=0.2, + dropout_U=0.1, + name='conv') + new_layer = keras.layers.ConvLSTM2D(5, (3, 3), + kernel_initializer='normal', + recurrent_initializer='uniform', + unit_forget_bias=True, + recurrent_activation='relu', + strides=(2, 2), + padding='valid', + kernel_regularizer='l1', + recurrent_regularizer='l2', + bias_regularizer='l2', + data_format='channels_first', + dropout=0.2, + recurrent_dropout=0.1, + name='conv') + assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config()) + + +@keras_test +def test_batchnorm_legacy_interface(): + old_layer = keras.layers.BatchNormalization(mode=0, name='bn') + new_layer = keras.layers.BatchNormalization(name='bn') + assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config()) + + old_layer = keras.layers.BatchNormalization(mode=0, + beta_init='one', + gamma_init='uniform', + name='bn') + new_layer = keras.layers.BatchNormalization(beta_initializer='ones', + gamma_initializer='uniform', + name='bn') + assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config()) + + if __name__ == '__main__': pytest.main([__file__])