diff --git a/tests/keras-contrib/backend/test_backends.py b/tests/keras-contrib/backend/test_backends.py new file mode 100644 index 0000000..1997d2a --- /dev/null +++ b/tests/keras-contrib/backend/test_backends.py @@ -0,0 +1,76 @@ +import pytest +from numpy.testing import assert_allclose +import numpy as np +import scipy.sparse as sparse + +from kers import backend as K +from keras.backend import theano_backend as KTH, floatx, set_floatx, variable +from keras.backend import tensorflow_backend as KTF +from keras_contrib import backend as KC +from keras_contrib.backend import theano_backend as KCTH +from keras_contrib.backend import tensorflow_backend as KCTF +from keras.utils.np_utils import convert_kernel + + +def check_dtype(var, dtype): + if K._BACKEND == 'theano': + assert var.dtype == dtype + else: + assert var.dtype.name == '%s_ref' % dtype + + +def check_single_tensor_operation(function_name, input_shape, **kwargs): + val = np.random.random(input_shape) - 0.5 + xth = KTH.variable(val) + xtf = KTF.variable(val) + + zth = KTH.eval(getattr(KCTH, function_name)(xth, **kwargs)) + ztf = KTF.eval(getattr(KCTF, function_name)(xtf, **kwargs)) + + assert zth.shape == ztf.shape + assert_allclose(zth, ztf, atol=1e-05) + + +def check_two_tensor_operation(function_name, x_input_shape, + y_input_shape, **kwargs): + xval = np.random.random(x_input_shape) - 0.5 + + xth = KTH.variable(xval) + xtf = KTF.variable(xval) + + yval = np.random.random(y_input_shape) - 0.5 + + yth = KTH.variable(yval) + ytf = KTF.variable(yval) + + zth = KTH.eval(getattr(KCTH, function_name)(xth, yth, **kwargs)) + ztf = KTF.eval(getattr(KCTF, function_name)(xtf, ytf, **kwargs)) + + assert zth.shape == ztf.shape + assert_allclose(zth, ztf, atol=1e-05) + + +def check_composed_tensor_operations(first_function_name, first_function_args, + second_function_name, second_function_args, + input_shape): + ''' Creates a random tensor t0 with shape input_shape and compute + t1 = first_function_name(t0, **first_function_args) + t2 = second_function_name(t1, **second_function_args) + with both Theano and TensorFlow backends and ensures the answers match. + ''' + val = np.random.random(input_shape) - 0.5 + xth = KTH.variable(val) + xtf = KTF.variable(val) + + yth = getattr(KCTH, first_function_name)(xth, **first_function_args) + ytf = getattr(KCTF, first_function_name)(xtf, **first_function_args) + + zth = KTH.eval(getattr(KCTH, second_function_name)(yth, **second_function_args)) + ztf = KTF.eval(getattr(KCTF, second_function_name)(ytf, **second_function_args)) + + assert zth.shape == ztf.shape + assert_allclose(zth, ztf, atol=1e-05) + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/datasets/test_datasets.py b/tests/keras-contrib/datasets/test_datasets.py new file mode 100644 index 0000000..43088e9 --- /dev/null +++ b/tests/keras-contrib/datasets/test_datasets.py @@ -0,0 +1,9 @@ +from __future__ import print_function +import pytest +import time +import random +from keras_contrib import datasets + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/layers/test_advanced_activations.py b/tests/keras-contrib/layers/test_advanced_activations.py new file mode 100644 index 0000000..d510fc9 --- /dev/null +++ b/tests/keras-contrib/layers/test_advanced_activations.py @@ -0,0 +1,6 @@ +import pytest +from keras.utils.test_utils import layer_test, keras_test + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/layers/test_convolutional.py b/tests/keras-contrib/layers/test_convolutional.py new file mode 100644 index 0000000..d6540e8 --- /dev/null +++ b/tests/keras-contrib/layers/test_convolutional.py @@ -0,0 +1,20 @@ +import pytest +import numpy as np +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 import backend as K +from keras_contrib import backend as KC +from keras_contrib.layers import convolutional, pooling + + +# TensorFlow does not support full convolution. +if K.backend() == 'theano': + _convolution_border_modes = ['valid', 'same', 'full'] +else: + _convolution_border_modes = ['valid', 'same'] + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/layers/test_convolutional_recurrent.py b/tests/keras-contrib/layers/test_convolutional_recurrent.py new file mode 100644 index 0000000..99db297 --- /dev/null +++ b/tests/keras-contrib/layers/test_convolutional_recurrent.py @@ -0,0 +1,13 @@ +import pytest +import numpy as np +from numpy.testing import assert_allclose + +from keras import backend as K +from keras_contrib import backend as K +from keras.models import Sequential +from keras_contrib.layers import convolutional_recurrent +from keras.utils.test_utils import layer_test + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/layers/test_core.py b/tests/keras-contrib/layers/test_core.py new file mode 100644 index 0000000..fa517a4 --- /dev/null +++ b/tests/keras-contrib/layers/test_core.py @@ -0,0 +1,11 @@ +import pytest +import numpy as np + +from keras import backend as K +from keras_contrib import backend as KC +from keras_contrib.layers import core +from keras.utils.test_utils import layer_test, keras_test + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/layers/test_embeddings.py b/tests/keras-contrib/layers/test_embeddings.py new file mode 100644 index 0000000..5beab26 --- /dev/null +++ b/tests/keras-contrib/layers/test_embeddings.py @@ -0,0 +1,9 @@ +import pytest +from keras.utils.test_utils import layer_test, keras_test +from keras.layers.embeddings import Embedding +import keras.backend as K +import keras_contrib.backend as KC + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/layers/test_local.py b/tests/keras-contrib/layers/test_local.py new file mode 100644 index 0000000..9c5d6b6 --- /dev/null +++ b/tests/keras-contrib/layers/test_local.py @@ -0,0 +1,8 @@ +import pytest + +from keras.utils.test_utils import layer_test, keras_test +from keras_contrib.layers import local + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/layers/test_noise.py b/tests/keras-contrib/layers/test_noise.py new file mode 100644 index 0000000..be25cee --- /dev/null +++ b/tests/keras-contrib/layers/test_noise.py @@ -0,0 +1,7 @@ +import pytest +from keras.utils.test_utils import layer_test, keras_test +from keras_contrib.layers import noise + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/layers/test_normalization.py b/tests/keras-contrib/layers/test_normalization.py new file mode 100644 index 0000000..3bdd9ef --- /dev/null +++ b/tests/keras-contrib/layers/test_normalization.py @@ -0,0 +1,15 @@ +import pytest +import numpy as np +from numpy.testing import assert_allclose + +from keras.layers import Dense, Activation, Input +from keras.utils.test_utils import layer_test, keras_test +from keras_contrib.layers import normalization +from keras.models import Sequential, Model +from keras import backend as K +from keras_contrib import backend as KC + + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/layers/test_recurrent.py b/tests/keras-contrib/layers/test_recurrent.py new file mode 100644 index 0000000..6abbd15 --- /dev/null +++ b/tests/keras-contrib/layers/test_recurrent.py @@ -0,0 +1,151 @@ +import pytest +import numpy as np +from numpy.testing import assert_allclose + +from keras.utils.test_utils import layer_test +from keras_contrib.layers import recurrent +from keras.layers import embeddings +from keras.models import Sequential +from keras.layers.core import Masking +from keras import regularizers +from keras.utils.test_utils import keras_test + +from keras import backend as K +from keras_contrib import backend as KC + +nb_samples, timesteps, embedding_dim, output_dim = 2, 5, 4, 3 +embedding_num = 12 + + +def rnn_test(f): + """ + All the recurrent layers share the same interface, + so we can run through them with a single function. + """ + f = keras_test(f) + # Example : return pytest.mark.parametrize("layer_class", [recurrent.JZ1, recurrent.NTM])(f) + return pytest.mark.parametrize("layer_class", [])(f) + + +@rnn_test +def test_return_sequences(layer_class): + layer_test(layer_class, + kwargs={'output_dim': output_dim, + 'return_sequences': True}, + input_shape=(nb_samples, timesteps, embedding_dim)) + + +@rnn_test +def test_dynamic_behavior(layer_class): + layer = layer_class(output_dim, input_dim=embedding_dim) + model = Sequential() + model.add(layer) + model.compile('sgd', 'mse') + x = np.random.random((nb_samples, timesteps, embedding_dim)) + y = np.random.random((nb_samples, output_dim)) + model.train_on_batch(x, y) + + +@rnn_test +def test_dropout(layer_class): + layer_test(layer_class, + kwargs={'output_dim': output_dim, + 'dropout_U': 0.1, + 'dropout_W': 0.1}, + input_shape=(nb_samples, timesteps, embedding_dim)) + + +@rnn_test +def test_implementation_mode(layer_class): + for mode in ['cpu', 'mem', 'gpu']: + layer_test(layer_class, + kwargs={'output_dim': output_dim, + 'consume_less': mode}, + input_shape=(nb_samples, timesteps, embedding_dim)) + + +@rnn_test +def test_statefulness(layer_class): + model = Sequential() + model.add(embeddings.Embedding(embedding_num, embedding_dim, + mask_zero=True, + input_length=timesteps, + batch_input_shape=(nb_samples, timesteps))) + layer = layer_class(output_dim, return_sequences=False, + stateful=True, + weights=None) + model.add(layer) + model.compile(optimizer='sgd', loss='mse') + out1 = model.predict(np.ones((nb_samples, timesteps))) + assert(out1.shape == (nb_samples, output_dim)) + + # train once so that the states change + model.train_on_batch(np.ones((nb_samples, timesteps)), + np.ones((nb_samples, output_dim))) + out2 = model.predict(np.ones((nb_samples, timesteps))) + + # if the state is not reset, output should be different + assert(out1.max() != out2.max()) + + # check that output changes after states are reset + # (even though the model itself didn't change) + layer.reset_states() + out3 = model.predict(np.ones((nb_samples, timesteps))) + assert(out2.max() != out3.max()) + + # check that container-level reset_states() works + model.reset_states() + out4 = model.predict(np.ones((nb_samples, timesteps))) + assert_allclose(out3, out4, atol=1e-5) + + # check that the call to `predict` updated the states + out5 = model.predict(np.ones((nb_samples, timesteps))) + assert(out4.max() != out5.max()) + + # Check masking + layer.reset_states() + + left_padded_input = np.ones((nb_samples, timesteps)) + left_padded_input[0, :1] = 0 + left_padded_input[1, :2] = 0 + out6 = model.predict(left_padded_input) + + layer.reset_states() + + right_padded_input = np.ones((nb_samples, timesteps)) + right_padded_input[0, -1:] = 0 + right_padded_input[1, -2:] = 0 + out7 = model.predict(right_padded_input) + + assert_allclose(out7, out6, atol=1e-5) + + +@rnn_test +def test_regularizer(layer_class): + layer = layer_class(output_dim, return_sequences=False, weights=None, + batch_input_shape=(nb_samples, timesteps, embedding_dim), + W_regularizer=regularizers.WeightRegularizer(l1=0.01), + U_regularizer=regularizers.WeightRegularizer(l1=0.01), + b_regularizer='l2') + shape = (nb_samples, timesteps, embedding_dim) + layer.build(shape) + output = layer(K.variable(np.ones(shape))) + K.eval(output) + if layer_class == recurrent.SimpleRNN: + assert len(layer.losses) == 3 + if layer_class == recurrent.GRU: + assert len(layer.losses) == 9 + if layer_class == recurrent.LSTM: + assert len(layer.losses) == 12 + + +@rnn_test +def test_from_config(layer_class): + for stateful in (False, True): + l1 = layer_class(output_dim=1, stateful=stateful) + l2 = layer_class.from_config(l1.get_config()) + assert l1.get_config() == l2.get_config() + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/layers/test_wrappers.py b/tests/keras-contrib/layers/test_wrappers.py new file mode 100644 index 0000000..ff60299 --- /dev/null +++ b/tests/keras-contrib/layers/test_wrappers.py @@ -0,0 +1,9 @@ +import pytest +import numpy as np +from numpy.testing import assert_allclose +from keras.utils.test_utils import keras_test +from keras_contrib.layers import wrappers + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/preprocessing/.gitkeep b/tests/keras-contrib/preprocessing/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/keras-contrib/test_activations.py b/tests/keras-contrib/test_activations.py new file mode 100644 index 0000000..abb3560 --- /dev/null +++ b/tests/keras-contrib/test_activations.py @@ -0,0 +1,19 @@ +import pytest +import numpy as np +from numpy.testing import assert_allclose + +from keras import backend as K +from keras_contrib import backend as KC +from keras_contrib import activations + + +def get_standard_values(): + ''' + These are just a set of floats used for testing the activation + functions, and are useful in multiple tests. + ''' + return np.array([[0, 0.1, 0.5, 0.9, 1.0]], dtype=K.floatx()) + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/test_callbacks.py b/tests/keras-contrib/test_callbacks.py new file mode 100644 index 0000000..889b9a8 --- /dev/null +++ b/tests/keras-contrib/test_callbacks.py @@ -0,0 +1,29 @@ +import os +import sys +import multiprocessing + +import numpy as np +import pytest +from csv import Sniffer +from keras import optimizers + +np.random.seed(1337) + +from keras.models import Sequential +from keras.layers.core import Dense +from keras.utils.test_utils import get_test_data +from keras import backend as K +from keras_contrib import backend as KC +from keras.utils import np_utils +from keras_contrib import callbacks + +input_dim = 2 +nb_hidden = 4 +nb_class = 2 +batch_size = 5 +train_samples = 20 +test_samples = 20 + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/test_constraints.py b/tests/keras-contrib/test_constraints.py new file mode 100644 index 0000000..75f210a --- /dev/null +++ b/tests/keras-contrib/test_constraints.py @@ -0,0 +1,18 @@ +import pytest +import numpy as np +from numpy.testing import assert_allclose + +from keras import backend as K +from keras_contrib import backend as KC +from keras_contrib import constraints + + +test_values = [0.1, 0.5, 3, 8, 1e-7] +np.random.seed(3537) +example_array = np.random.random((100, 100)) * 100. - 50. +example_array[0, 0] = 0. # 0 could possibly cause trouble + + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/test_initializations.py b/tests/keras-contrib/test_initializations.py new file mode 100644 index 0000000..7896e18 --- /dev/null +++ b/tests/keras-contrib/test_initializations.py @@ -0,0 +1,46 @@ +import pytest +import numpy as np + +from keras import backend as K +from keras_contrib import backend as KC +from keras_contrib import initializations + + +# 2D tensor test fixture +FC_SHAPE = (100, 100) + +# 4D convolution in th order. This shape has the same effective shape as FC_SHAPE +CONV_SHAPE = (25, 25, 2, 2) + +# The equivalent shape of both test fixtures +SHAPE = (100, 100) + + +def _runner(init, shape, target_mean=None, target_std=None, + target_max=None, target_min=None): + variable = init(shape) + output = K.get_value(variable) + lim = 1e-2 + if target_std is not None: + assert abs(output.std() - target_std) < lim + if target_mean is not None: + assert abs(output.mean() - target_mean) < lim + if target_max is not None: + assert abs(output.max() - target_max) < lim + if target_min is not None: + assert abs(output.min() - target_min) < lim + + +''' +# Example : + +@pytest.mark.parametrize('tensor_shape', [FC_SHAPE, CONV_SHAPE], ids=['FC', 'CONV']) +def test_uniform(tensor_shape): + _runner(initializations.uniform, tensor_shape, target_mean=0., + target_max=0.05, target_min=-0.05) + +''' + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/test_metrics.py b/tests/keras-contrib/test_metrics.py new file mode 100644 index 0000000..c450680 --- /dev/null +++ b/tests/keras-contrib/test_metrics.py @@ -0,0 +1,22 @@ +import pytest +import numpy as np + +from keras import backend as K +from keras_contrib import backend as KC +from keras_contrib import metrics + + +all_metrics = [] +all_sparse_metrics = [] + + +def test_metrics(): + y_a = K.variable(np.random.random((6, 7))) + y_b = K.variable(np.random.random((6, 7))) + for metric in all_metrics: + output = metric(y_a, y_b) + assert K.eval(output).shape == () + + +if __name__ == "__main__": + pytest.main([__file__]) diff --git a/tests/keras-contrib/test_objectives.py b/tests/keras-contrib/test_objectives.py new file mode 100644 index 0000000..ee07515 --- /dev/null +++ b/tests/keras-contrib/test_objectives.py @@ -0,0 +1,29 @@ +import pytest +import numpy as np + +from keras import backend as K +from keras_contrib import backend as KC +from keras_contrib import objectives + + +allobj = [] + + +def test_objective_shapes_3d(): + y_a = K.variable(np.random.random((5, 6, 7))) + y_b = K.variable(np.random.random((5, 6, 7))) + for obj in allobj: + objective_output = obj(y_a, y_b) + assert K.eval(objective_output).shape == (5, 6) + + +def test_objective_shapes_2d(): + y_a = K.variable(np.random.random((6, 7))) + y_b = K.variable(np.random.random((6, 7))) + for obj in allobj: + objective_output = obj(y_a, y_b) + assert K.eval(objective_output).shape == (6,) + + +if __name__ == "__main__": + pytest.main([__file__]) diff --git a/tests/keras-contrib/test_optimizers.py b/tests/keras-contrib/test_optimizers.py new file mode 100644 index 0000000..e1b78e8 --- /dev/null +++ b/tests/keras-contrib/test_optimizers.py @@ -0,0 +1,44 @@ +from __future__ import print_function +import pytest +import numpy as np +np.random.seed(1337) + +from keras.utils.test_utils import get_test_data +from keras.models import Sequential +from keras.layers.core import Dense, Activation +from keras.utils.np_utils import to_categorical +from keras_contrib.optimizers import * + + +(X_train, y_train), (X_test, y_test) = get_test_data(nb_train=1000, + nb_test=200, + input_shape=(10,), + classification=True, + nb_class=2) +y_train = to_categorical(y_train) +y_test = to_categorical(y_test) + + +def get_model(input_dim, nb_hidden, output_dim): + model = Sequential() + model.add(Dense(nb_hidden, input_shape=(input_dim,))) + model.add(Activation('relu')) + model.add(Dense(output_dim)) + model.add(Activation('softmax')) + return model + + +def _test_optimizer(optimizer, target=0.89): + model = get_model(X_train.shape[1], 10, y_train.shape[1]) + model.compile(loss='categorical_crossentropy', + optimizer=optimizer, + metrics=['accuracy']) + history = model.fit(X_train, y_train, nb_epoch=12, batch_size=16, + validation_data=(X_test, y_test), verbose=2) + config = optimizer.get_config() + assert type(config) == dict + assert history.history['val_acc'][-1] >= target + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/test_regularizers.py b/tests/keras-contrib/test_regularizers.py new file mode 100644 index 0000000..b308b9a --- /dev/null +++ b/tests/keras-contrib/test_regularizers.py @@ -0,0 +1,55 @@ +import pytest +import numpy as np +np.random.seed(1337) + +from keras.models import Sequential +from keras.layers import Merge +from keras.layers import Dense +from keras.layers import Activation +from keras.layers import Flatten +from keras.layers import ActivityRegularization +from keras.layers import Embedding +from keras.datasets import mnist +from keras.utils import np_utils +from keras_contrib import regularizers + +nb_classes = 10 +batch_size = 128 +nb_epoch = 5 +weighted_class = 9 +standard_weight = 1 +high_weight = 5 +max_train_samples = 5000 +max_test_samples = 1000 + + +def get_data(): + # the data, shuffled and split between tran and test sets + (X_train, y_train), (X_test, y_test) = mnist.load_data() + X_train = X_train.reshape(60000, 784)[:max_train_samples] + X_test = X_test.reshape(10000, 784)[:max_test_samples] + X_train = X_train.astype("float32") / 255 + X_test = X_test.astype("float32") / 255 + + # convert class vectors to binary class matrices + y_train = y_train[:max_train_samples] + y_test = y_test[:max_test_samples] + Y_train = np_utils.to_categorical(y_train, nb_classes) + Y_test = np_utils.to_categorical(y_test, nb_classes) + test_ids = np.where(y_test == np.array(weighted_class))[0] + + return (X_train, Y_train), (X_test, Y_test), test_ids + + +def create_model(weight_reg=None, activity_reg=None): + model = Sequential() + model.add(Dense(50, input_shape=(784,))) + model.add(Activation('relu')) + model.add(Dense(10, W_regularizer=weight_reg, + activity_regularizer=activity_reg)) + model.add(Activation('softmax')) + return model + + +if __name__ == '__main__': + pytest.main([__file__]) diff --git a/tests/keras-contrib/utils/.gitkeep b/tests/keras-contrib/utils/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/keras-contrib/wrappers/.gitkeep b/tests/keras-contrib/wrappers/.gitkeep new file mode 100644 index 0000000..e69de29