aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/contrib/keras
diff options
context:
space:
mode:
authorGravatar Francois Chollet <fchollet@google.com>2017-09-05 15:14:42 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2017-09-05 15:18:49 -0700
commiteaaa0b93852054dee086a3ed5373cf8bbe3d2fb3 (patch)
tree715404d30c98f037b6fa98bd668118ef4bc94f6e /tensorflow/contrib/keras
parenta8b7a320a47f326b97c00ac129d572b50a22fb51 (diff)
Move the Keras API to tf.keras.
PiperOrigin-RevId: 167638421
Diffstat (limited to 'tensorflow/contrib/keras')
-rw-r--r--tensorflow/contrib/keras/BUILD637
-rw-r--r--tensorflow/contrib/keras/README.md3
-rw-r--r--tensorflow/contrib/keras/api/keras/activations/__init__.py26
-rw-r--r--tensorflow/contrib/keras/api/keras/applications/inception_v3/__init__.py6
-rw-r--r--tensorflow/contrib/keras/api/keras/applications/mobilenet/__init__.py6
-rw-r--r--tensorflow/contrib/keras/api/keras/applications/resnet50/__init__.py6
-rw-r--r--tensorflow/contrib/keras/api/keras/applications/vgg16/__init__.py6
-rw-r--r--tensorflow/contrib/keras/api/keras/applications/vgg19/__init__.py6
-rw-r--r--tensorflow/contrib/keras/api/keras/applications/xception/__init__.py6
-rw-r--r--tensorflow/contrib/keras/api/keras/backend/__init__.py276
-rw-r--r--tensorflow/contrib/keras/api/keras/callbacks/__init__.py26
-rw-r--r--tensorflow/contrib/keras/api/keras/constraints/__init__.py24
-rw-r--r--tensorflow/contrib/keras/api/keras/datasets/boston_housing/__init__.py2
-rw-r--r--tensorflow/contrib/keras/api/keras/datasets/cifar10/__init__.py2
-rw-r--r--tensorflow/contrib/keras/api/keras/datasets/cifar100/__init__.py2
-rw-r--r--tensorflow/contrib/keras/api/keras/datasets/imdb/__init__.py4
-rw-r--r--tensorflow/contrib/keras/api/keras/datasets/mnist/__init__.py2
-rw-r--r--tensorflow/contrib/keras/api/keras/datasets/reuters/__init__.py4
-rw-r--r--tensorflow/contrib/keras/api/keras/initializers/__init__.py38
-rw-r--r--tensorflow/contrib/keras/api/keras/layers/__init__.py184
-rw-r--r--tensorflow/contrib/keras/api/keras/losses/__init__.py34
-rw-r--r--tensorflow/contrib/keras/api/keras/metrics/__init__.py38
-rw-r--r--tensorflow/contrib/keras/api/keras/models/__init__.py14
-rw-r--r--tensorflow/contrib/keras/api/keras/optimizers/__init__.py22
-rw-r--r--tensorflow/contrib/keras/api/keras/preprocessing/image/__init__.py28
-rw-r--r--tensorflow/contrib/keras/api/keras/preprocessing/sequence/__init__.py6
-rw-r--r--tensorflow/contrib/keras/api/keras/preprocessing/text/__init__.py6
-rw-r--r--tensorflow/contrib/keras/api/keras/regularizers/__init__.py16
-rw-r--r--tensorflow/contrib/keras/api/keras/utils/__init__.py30
-rw-r--r--tensorflow/contrib/keras/api/keras/wrappers/scikit_learn/__init__.py4
-rw-r--r--tensorflow/contrib/keras/python/keras/__init__.py40
-rw-r--r--tensorflow/contrib/keras/python/keras/activations.py130
-rw-r--r--tensorflow/contrib/keras/python/keras/activations_test.py184
-rw-r--r--tensorflow/contrib/keras/python/keras/applications/__init__.py26
-rw-r--r--tensorflow/contrib/keras/python/keras/applications/imagenet_utils.py193
-rw-r--r--tensorflow/contrib/keras/python/keras/applications/imagenet_utils_test.py159
-rw-r--r--tensorflow/contrib/keras/python/keras/applications/inception_v3.py392
-rw-r--r--tensorflow/contrib/keras/python/keras/applications/inception_v3_test.py58
-rw-r--r--tensorflow/contrib/keras/python/keras/applications/mobilenet.py669
-rw-r--r--tensorflow/contrib/keras/python/keras/applications/mobilenet_test.py101
-rw-r--r--tensorflow/contrib/keras/python/keras/applications/resnet50.py286
-rw-r--r--tensorflow/contrib/keras/python/keras/applications/resnet50_test.py51
-rw-r--r--tensorflow/contrib/keras/python/keras/applications/vgg16.py212
-rw-r--r--tensorflow/contrib/keras/python/keras/applications/vgg16_test.py50
-rw-r--r--tensorflow/contrib/keras/python/keras/applications/vgg19.py218
-rw-r--r--tensorflow/contrib/keras/python/keras/applications/vgg19_test.py50
-rw-r--r--tensorflow/contrib/keras/python/keras/applications/xception.py307
-rw-r--r--tensorflow/contrib/keras/python/keras/applications/xception_test.py57
-rw-r--r--tensorflow/contrib/keras/python/keras/backend.py4074
-rw-r--r--tensorflow/contrib/keras/python/keras/backend_test.py1041
-rw-r--r--tensorflow/contrib/keras/python/keras/callbacks.py1106
-rw-r--r--tensorflow/contrib/keras/python/keras/callbacks_test.py859
-rw-r--r--tensorflow/contrib/keras/python/keras/constraints.py199
-rw-r--r--tensorflow/contrib/keras/python/keras/constraints_test.py103
-rw-r--r--tensorflow/contrib/keras/python/keras/datasets/__init__.py27
-rw-r--r--tensorflow/contrib/keras/python/keras/datasets/boston_housing.py59
-rw-r--r--tensorflow/contrib/keras/python/keras/datasets/cifar.py53
-rw-r--r--tensorflow/contrib/keras/python/keras/datasets/cifar10.py61
-rw-r--r--tensorflow/contrib/keras/python/keras/datasets/cifar100.py62
-rw-r--r--tensorflow/contrib/keras/python/keras/datasets/imdb.py150
-rw-r--r--tensorflow/contrib/keras/python/keras/datasets/mnist.py44
-rw-r--r--tensorflow/contrib/keras/python/keras/datasets/reuters.py136
-rw-r--r--tensorflow/contrib/keras/python/keras/engine/__init__.py30
-rw-r--r--tensorflow/contrib/keras/python/keras/engine/topology.py1535
-rw-r--r--tensorflow/contrib/keras/python/keras/engine/topology_test.py689
-rw-r--r--tensorflow/contrib/keras/python/keras/engine/training.py2379
-rw-r--r--tensorflow/contrib/keras/python/keras/engine/training_test.py1423
-rw-r--r--tensorflow/contrib/keras/python/keras/initializers.py202
-rw-r--r--tensorflow/contrib/keras/python/keras/initializers_test.py161
-rw-r--r--tensorflow/contrib/keras/python/keras/integration_test.py292
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/__init__.py40
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/advanced_activations.py222
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/advanced_activations_test.py61
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/convolutional.py1656
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/convolutional_recurrent.py607
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/convolutional_recurrent_test.py184
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/convolutional_test.py842
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/core.py777
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/core_test.py210
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/embeddings.py181
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/embeddings_test.py72
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/gru_test.py203
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/local.py393
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/local_test.py171
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/lstm_test.py369
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/merge.py617
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/merge_test.py213
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/noise.py173
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/noise_test.py51
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/normalization.py134
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/normalization_test.py147
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/pooling.py595
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/pooling_test.py182
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/recurrent.py1270
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/serialization.py63
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/serialization_test.py41
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/simplernn_test.py203
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/wrappers.py408
-rw-r--r--tensorflow/contrib/keras/python/keras/layers/wrappers_test.py243
-rw-r--r--tensorflow/contrib/keras/python/keras/losses.py129
-rw-r--r--tensorflow/contrib/keras/python/keras/losses_test.py88
-rw-r--r--tensorflow/contrib/keras/python/keras/metrics.py96
-rw-r--r--tensorflow/contrib/keras/python/keras/metrics_test.py77
-rw-r--r--tensorflow/contrib/keras/python/keras/models.py1458
-rw-r--r--tensorflow/contrib/keras/python/keras/models_test.py419
-rw-r--r--tensorflow/contrib/keras/python/keras/optimizers.py771
-rw-r--r--tensorflow/contrib/keras/python/keras/optimizers_test.py146
-rw-r--r--tensorflow/contrib/keras/python/keras/preprocessing/__init__.py24
-rw-r--r--tensorflow/contrib/keras/python/keras/preprocessing/image.py1172
-rw-r--r--tensorflow/contrib/keras/python/keras/preprocessing/image_test.py254
-rw-r--r--tensorflow/contrib/keras/python/keras/preprocessing/sequence.py226
-rw-r--r--tensorflow/contrib/keras/python/keras/preprocessing/sequence_test.py99
-rw-r--r--tensorflow/contrib/keras/python/keras/preprocessing/text.py322
-rw-r--r--tensorflow/contrib/keras/python/keras/preprocessing/text_test.py81
-rw-r--r--tensorflow/contrib/keras/python/keras/regularizers.py102
-rw-r--r--tensorflow/contrib/keras/python/keras/regularizers_test.py76
-rw-r--r--tensorflow/contrib/keras/python/keras/testing_utils.py165
-rw-r--r--tensorflow/contrib/keras/python/keras/utils/__init__.py43
-rw-r--r--tensorflow/contrib/keras/python/keras/utils/conv_utils.py72
-rw-r--r--tensorflow/contrib/keras/python/keras/utils/data_utils.py664
-rw-r--r--tensorflow/contrib/keras/python/keras/utils/data_utils_test.py233
-rw-r--r--tensorflow/contrib/keras/python/keras/utils/generic_utils.py368
-rw-r--r--tensorflow/contrib/keras/python/keras/utils/generic_utils_test.py75
-rw-r--r--tensorflow/contrib/keras/python/keras/utils/io_utils.py170
-rw-r--r--tensorflow/contrib/keras/python/keras/utils/io_utils_test.py101
-rw-r--r--tensorflow/contrib/keras/python/keras/utils/layer_utils.py219
-rw-r--r--tensorflow/contrib/keras/python/keras/utils/np_utils.py58
-rw-r--r--tensorflow/contrib/keras/python/keras/utils/vis_utils.py154
-rw-r--r--tensorflow/contrib/keras/python/keras/wrappers/__init__.py22
-rw-r--r--tensorflow/contrib/keras/python/keras/wrappers/scikit_learn.py356
-rw-r--r--tensorflow/contrib/keras/python/keras/wrappers/scikit_learn_test.py190
131 files changed, 417 insertions, 37673 deletions
diff --git a/tensorflow/contrib/keras/BUILD b/tensorflow/contrib/keras/BUILD
index 26f0e41518..7e0019ce4a 100644
--- a/tensorflow/contrib/keras/BUILD
+++ b/tensorflow/contrib/keras/BUILD
@@ -1,5 +1,6 @@
# Description:
# Contains the Keras API (internal TensorFlow version).
+# Note that tf.contrib.keras has been deprecated in favor of tf.keras.
licenses(["notice"]) # Apache 2.0
@@ -7,9 +8,6 @@ exports_files(["LICENSE"])
package(default_visibility = ["//tensorflow:__subpackages__"])
-load("//tensorflow:tensorflow.bzl", "cuda_py_test")
-load("//tensorflow:tensorflow.bzl", "py_test")
-
py_library(
name = "keras",
srcs = [
@@ -48,641 +46,10 @@ py_library(
"api/keras/utils/__init__.py",
"api/keras/wrappers/__init__.py",
"api/keras/wrappers/scikit_learn/__init__.py",
- "python/keras/__init__.py",
- "python/keras/activations.py",
- "python/keras/applications/__init__.py",
- "python/keras/applications/imagenet_utils.py",
- "python/keras/applications/inception_v3.py",
- "python/keras/applications/mobilenet.py",
- "python/keras/applications/resnet50.py",
- "python/keras/applications/vgg16.py",
- "python/keras/applications/vgg19.py",
- "python/keras/applications/xception.py",
- "python/keras/backend.py",
- "python/keras/callbacks.py",
- "python/keras/constraints.py",
- "python/keras/datasets/__init__.py",
- "python/keras/datasets/boston_housing.py",
- "python/keras/datasets/cifar.py",
- "python/keras/datasets/cifar10.py",
- "python/keras/datasets/cifar100.py",
- "python/keras/datasets/imdb.py",
- "python/keras/datasets/mnist.py",
- "python/keras/datasets/reuters.py",
- "python/keras/engine/__init__.py",
- "python/keras/engine/topology.py",
- "python/keras/engine/training.py",
- "python/keras/initializers.py",
- "python/keras/layers/__init__.py",
- "python/keras/layers/advanced_activations.py",
- "python/keras/layers/convolutional.py",
- "python/keras/layers/convolutional_recurrent.py",
- "python/keras/layers/core.py",
- "python/keras/layers/embeddings.py",
- "python/keras/layers/local.py",
- "python/keras/layers/merge.py",
- "python/keras/layers/noise.py",
- "python/keras/layers/normalization.py",
- "python/keras/layers/pooling.py",
- "python/keras/layers/recurrent.py",
- "python/keras/layers/serialization.py",
- "python/keras/layers/wrappers.py",
- "python/keras/losses.py",
- "python/keras/metrics.py",
- "python/keras/models.py",
- "python/keras/optimizers.py",
- "python/keras/preprocessing/__init__.py",
- "python/keras/preprocessing/image.py",
- "python/keras/preprocessing/sequence.py",
- "python/keras/preprocessing/text.py",
- "python/keras/regularizers.py",
- "python/keras/testing_utils.py",
- "python/keras/utils/__init__.py",
- "python/keras/utils/conv_utils.py",
- "python/keras/utils/data_utils.py",
- "python/keras/utils/generic_utils.py",
- "python/keras/utils/io_utils.py",
- "python/keras/utils/layer_utils.py",
- "python/keras/utils/np_utils.py",
- "python/keras/utils/vis_utils.py",
- "python/keras/wrappers/__init__.py",
- "python/keras/wrappers/scikit_learn.py",
- ],
- srcs_version = "PY2AND3",
- deps = [
- "//tensorflow/contrib/tensorboard:projector",
- "//tensorflow/core:protos_all_py",
- "//tensorflow/python:array_ops",
- "//tensorflow/python:check_ops",
- "//tensorflow/python:client",
- "//tensorflow/python:clip_ops",
- "//tensorflow/python:constant_op",
- "//tensorflow/python:control_flow_ops",
- "//tensorflow/python:ctc_ops",
- "//tensorflow/python:dtypes",
- "//tensorflow/python:framework",
- "//tensorflow/python:framework_ops",
- "//tensorflow/python:functional_ops",
- "//tensorflow/python:gradients",
- "//tensorflow/python:image_ops",
- "//tensorflow/python:init_ops",
- "//tensorflow/python:layers",
- "//tensorflow/python:layers_base",
- "//tensorflow/python:logging_ops",
- "//tensorflow/python:math_ops",
- "//tensorflow/python:nn",
- "//tensorflow/python:platform",
- "//tensorflow/python:random_ops",
- "//tensorflow/python:sparse_ops",
- "//tensorflow/python:sparse_tensor",
- "//tensorflow/python:state_ops",
- "//tensorflow/python:summary",
- "//tensorflow/python:tensor_array_grad",
- "//tensorflow/python:tensor_array_ops",
- "//tensorflow/python:tensor_shape",
- "//tensorflow/python:training",
- "//tensorflow/python:util",
- "//tensorflow/python:variable_scope",
- "//tensorflow/python:variables",
- "@six_archive//:six",
- ],
-)
-
-py_test(
- name = "integration_test",
- size = "medium",
- srcs = ["python/keras/integration_test.py"],
- srcs_version = "PY2AND3",
- tags = ["notsan"],
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//tensorflow/python:layers",
- "//tensorflow/python:nn",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "activations_test",
- size = "small",
- srcs = ["python/keras/activations_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "constraints_test",
- size = "small",
- srcs = ["python/keras/constraints_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "initializers_test",
- size = "small",
- srcs = ["python/keras/initializers_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//tensorflow/python:init_ops",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "regularizers_test",
- size = "small",
- srcs = ["python/keras/regularizers_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- ],
-)
-
-py_test(
- name = "optimizers_test",
- size = "medium",
- srcs = ["python/keras/optimizers_test.py"],
- srcs_version = "PY2AND3",
- tags = ["notsan"],
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//tensorflow/python:training",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "losses_test",
- size = "small",
- srcs = ["python/keras/losses_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "metrics_test",
- size = "small",
- srcs = ["python/keras/metrics_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "inception_v3_test",
- size = "medium",
- srcs = ["python/keras/applications/inception_v3_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "mobilenet_test",
- size = "medium",
- srcs = ["python/keras/applications/mobilenet_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "resnet50_test",
- size = "small",
- srcs = ["python/keras/applications/resnet50_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- ],
-)
-
-py_test(
- name = "vgg16_test",
- size = "small",
- srcs = ["python/keras/applications/vgg16_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- ],
-)
-
-py_test(
- name = "vgg19_test",
- size = "small",
- srcs = ["python/keras/applications/vgg19_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- ],
-)
-
-py_test(
- name = "xception_test",
- size = "medium",
- srcs = ["python/keras/applications/xception_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "advanced_activations_test",
- size = "small",
- srcs = ["python/keras/layers/advanced_activations_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- ],
-)
-
-py_test(
- name = "convolutional_recurrent_test",
- size = "medium",
- srcs = ["python/keras/layers/convolutional_recurrent_test.py"],
- shard_count = 2,
- srcs_version = "PY2AND3",
- tags = ["noasan"], # times out b/63678675
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "convolutional_test",
- size = "medium",
- srcs = ["python/keras/layers/convolutional_test.py"],
- srcs_version = "PY2AND3",
- tags = [
- "manual",
- "noasan", # times out b/63678675
- "notsan",
- ],
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "pooling_test",
- size = "small",
- srcs = ["python/keras/layers/pooling_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- ],
-)
-
-py_test(
- name = "core_test",
- size = "small",
- srcs = ["python/keras/layers/core_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "embeddings_test",
- size = "small",
- srcs = ["python/keras/layers/embeddings_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- ],
-)
-
-py_test(
- name = "local_test",
- size = "medium",
- srcs = ["python/keras/layers/local_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "merge_test",
- size = "small",
- srcs = ["python/keras/layers/merge_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "noise_test",
- size = "small",
- srcs = ["python/keras/layers/noise_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- ],
-)
-
-py_test(
- name = "normalization_test",
- size = "small",
- srcs = ["python/keras/layers/normalization_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "simplernn_test",
- size = "medium",
- srcs = ["python/keras/layers/simplernn_test.py"],
- srcs_version = "PY2AND3",
- tags = ["notsan"],
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "gru_test",
- size = "medium",
- srcs = ["python/keras/layers/gru_test.py"],
- srcs_version = "PY2AND3",
- tags = ["notsan"], # http://b/62136390
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "lstm_test",
- size = "medium",
- srcs = ["python/keras/layers/lstm_test.py"],
- srcs_version = "PY2AND3",
- tags = [
- "noasan", # times out b/63678675
- "notsan", # http://b/62189182
- ],
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "serialization_test",
- size = "small",
- srcs = ["python/keras/layers/serialization_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- ],
-)
-
-py_test(
- name = "wrappers_test",
- size = "small",
- srcs = ["python/keras/layers/wrappers_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "scikit_learn_test",
- size = "small",
- srcs = ["python/keras/wrappers/scikit_learn_test.py"],
- srcs_version = "PY2AND3",
- tags = ["notsan"],
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "data_utils_test",
- size = "small",
- srcs = ["python/keras/utils/data_utils_test.py"],
- srcs_version = "PY2AND3",
- tags = [
- "noasan", # times out
- "notsan",
- ],
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "generic_utils_test",
- size = "small",
- srcs = ["python/keras/utils/generic_utils_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- ],
-)
-
-py_test(
- name = "io_utils_test",
- size = "small",
- srcs = ["python/keras/utils/io_utils_test.py"],
- srcs_version = "PY2AND3",
- tags = ["notsan"],
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "imagenet_utils_test",
- size = "small",
- srcs = ["python/keras/applications/imagenet_utils_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "image_test",
- size = "medium",
- srcs = ["python/keras/preprocessing/image_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "sequence_test",
- size = "small",
- srcs = ["python/keras/preprocessing/sequence_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "text_test",
- size = "small",
- srcs = ["python/keras/preprocessing/text_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "callbacks_test",
- size = "medium",
- srcs = ["python/keras/callbacks_test.py"],
- srcs_version = "PY2AND3",
- tags = ["notsan"],
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "training_test",
- size = "medium",
- srcs = ["python/keras/engine/training_test.py"],
- srcs_version = "PY2AND3",
- tags = ["notsan"],
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "topology_test",
- size = "small",
- srcs = ["python/keras/engine/topology_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:array_ops",
- "//tensorflow/python:client_testlib",
- "//tensorflow/python:dtypes",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "models_test",
- size = "small",
- srcs = ["python/keras/models_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//tensorflow/python:training",
- "//third_party/py/numpy",
- ],
-)
-
-py_test(
- name = "backend_test",
- size = "small",
- srcs = ["python/keras/backend_test.py"],
- srcs_version = "PY2AND3",
- deps = [
- ":keras",
- "//tensorflow/python:client_testlib",
- "//tensorflow/python:util",
- "//third_party/py/numpy",
- ],
-)
-
-py_library(
- name = "testing_utils",
- srcs = [
- "python/keras/testing_utils.py",
],
srcs_version = "PY2AND3",
deps = [
- ":keras",
- "//tensorflow/python:util",
- "//third_party/py/numpy",
+ "//tensorflow/python/keras",
],
)
diff --git a/tensorflow/contrib/keras/README.md b/tensorflow/contrib/keras/README.md
index db2556fe42..de4c81268d 100644
--- a/tensorflow/contrib/keras/README.md
+++ b/tensorflow/contrib/keras/README.md
@@ -1,3 +1,6 @@
+NOTE: THE `tensorflow.contrib.keras` MODULE HAS BEEN DEPRECATED.
+USE INSTEAD `tensorflow.keras`, PART OF CORE TENSORFLOW.
+
Keras is an object-oriented API for defining and training neural networks.
This module contains a pure-TensorFlow implementation of the Keras API,
diff --git a/tensorflow/contrib/keras/api/keras/activations/__init__.py b/tensorflow/contrib/keras/api/keras/activations/__init__.py
index af6f249e71..d04838c218 100644
--- a/tensorflow/contrib/keras/api/keras/activations/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/activations/__init__.py
@@ -19,22 +19,22 @@ from __future__ import division
from __future__ import print_function
# Activation functions.
-from tensorflow.contrib.keras.python.keras.activations import elu
-from tensorflow.contrib.keras.python.keras.activations import hard_sigmoid
-from tensorflow.contrib.keras.python.keras.activations import linear
-from tensorflow.contrib.keras.python.keras.activations import relu
-from tensorflow.contrib.keras.python.keras.activations import selu
-from tensorflow.contrib.keras.python.keras.activations import sigmoid
-from tensorflow.contrib.keras.python.keras.activations import softmax
-from tensorflow.contrib.keras.python.keras.activations import softplus
-from tensorflow.contrib.keras.python.keras.activations import softsign
-from tensorflow.contrib.keras.python.keras.activations import tanh
+from tensorflow.python.keras._impl.keras.activations import elu
+from tensorflow.python.keras._impl.keras.activations import hard_sigmoid
+from tensorflow.python.keras._impl.keras.activations import linear
+from tensorflow.python.keras._impl.keras.activations import relu
+from tensorflow.python.keras._impl.keras.activations import selu
+from tensorflow.python.keras._impl.keras.activations import sigmoid
+from tensorflow.python.keras._impl.keras.activations import softmax
+from tensorflow.python.keras._impl.keras.activations import softplus
+from tensorflow.python.keras._impl.keras.activations import softsign
+from tensorflow.python.keras._impl.keras.activations import tanh
# Auxiliary utils.
# pylint: disable=g-bad-import-order
-from tensorflow.contrib.keras.python.keras.activations import deserialize
-from tensorflow.contrib.keras.python.keras.activations import serialize
-from tensorflow.contrib.keras.python.keras.activations import get
+from tensorflow.python.keras._impl.keras.activations import deserialize
+from tensorflow.python.keras._impl.keras.activations import serialize
+from tensorflow.python.keras._impl.keras.activations import get
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/applications/inception_v3/__init__.py b/tensorflow/contrib/keras/api/keras/applications/inception_v3/__init__.py
index d8ca73fb97..abf8393ae4 100644
--- a/tensorflow/contrib/keras/api/keras/applications/inception_v3/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/applications/inception_v3/__init__.py
@@ -18,9 +18,9 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.applications.inception_v3 import decode_predictions
-from tensorflow.contrib.keras.python.keras.applications.inception_v3 import InceptionV3
-from tensorflow.contrib.keras.python.keras.applications.inception_v3 import preprocess_input
+from tensorflow.python.keras._impl.keras.applications.inception_v3 import decode_predictions
+from tensorflow.python.keras._impl.keras.applications.inception_v3 import InceptionV3
+from tensorflow.python.keras._impl.keras.applications.inception_v3 import preprocess_input
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/applications/mobilenet/__init__.py b/tensorflow/contrib/keras/api/keras/applications/mobilenet/__init__.py
index 594861fb51..b809e91193 100644
--- a/tensorflow/contrib/keras/api/keras/applications/mobilenet/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/applications/mobilenet/__init__.py
@@ -18,9 +18,9 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.applications.mobilenet import decode_predictions
-from tensorflow.contrib.keras.python.keras.applications.mobilenet import MobileNet
-from tensorflow.contrib.keras.python.keras.applications.mobilenet import preprocess_input
+from tensorflow.python.keras._impl.keras.applications.mobilenet import decode_predictions
+from tensorflow.python.keras._impl.keras.applications.mobilenet import MobileNet
+from tensorflow.python.keras._impl.keras.applications.mobilenet import preprocess_input
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/applications/resnet50/__init__.py b/tensorflow/contrib/keras/api/keras/applications/resnet50/__init__.py
index e9b25b66d5..530805d150 100644
--- a/tensorflow/contrib/keras/api/keras/applications/resnet50/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/applications/resnet50/__init__.py
@@ -18,9 +18,9 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.applications.resnet50 import decode_predictions
-from tensorflow.contrib.keras.python.keras.applications.resnet50 import preprocess_input
-from tensorflow.contrib.keras.python.keras.applications.resnet50 import ResNet50
+from tensorflow.python.keras._impl.keras.applications.resnet50 import decode_predictions
+from tensorflow.python.keras._impl.keras.applications.resnet50 import preprocess_input
+from tensorflow.python.keras._impl.keras.applications.resnet50 import ResNet50
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/applications/vgg16/__init__.py b/tensorflow/contrib/keras/api/keras/applications/vgg16/__init__.py
index 2a1f789cc5..118361604b 100644
--- a/tensorflow/contrib/keras/api/keras/applications/vgg16/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/applications/vgg16/__init__.py
@@ -18,9 +18,9 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.applications.vgg16 import decode_predictions
-from tensorflow.contrib.keras.python.keras.applications.vgg16 import preprocess_input
-from tensorflow.contrib.keras.python.keras.applications.vgg16 import VGG16
+from tensorflow.python.keras._impl.keras.applications.vgg16 import decode_predictions
+from tensorflow.python.keras._impl.keras.applications.vgg16 import preprocess_input
+from tensorflow.python.keras._impl.keras.applications.vgg16 import VGG16
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/applications/vgg19/__init__.py b/tensorflow/contrib/keras/api/keras/applications/vgg19/__init__.py
index 22b5e7c8e4..cda52628f3 100644
--- a/tensorflow/contrib/keras/api/keras/applications/vgg19/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/applications/vgg19/__init__.py
@@ -18,9 +18,9 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.applications.vgg19 import decode_predictions
-from tensorflow.contrib.keras.python.keras.applications.vgg19 import preprocess_input
-from tensorflow.contrib.keras.python.keras.applications.vgg19 import VGG19
+from tensorflow.python.keras._impl.keras.applications.vgg19 import decode_predictions
+from tensorflow.python.keras._impl.keras.applications.vgg19 import preprocess_input
+from tensorflow.python.keras._impl.keras.applications.vgg19 import VGG19
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/applications/xception/__init__.py b/tensorflow/contrib/keras/api/keras/applications/xception/__init__.py
index 23d1b6a0b3..ae9cd9cd18 100644
--- a/tensorflow/contrib/keras/api/keras/applications/xception/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/applications/xception/__init__.py
@@ -18,9 +18,9 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.applications.xception import decode_predictions
-from tensorflow.contrib.keras.python.keras.applications.xception import preprocess_input
-from tensorflow.contrib.keras.python.keras.applications.xception import Xception
+from tensorflow.python.keras._impl.keras.applications.xception import decode_predictions
+from tensorflow.python.keras._impl.keras.applications.xception import preprocess_input
+from tensorflow.python.keras._impl.keras.applications.xception import Xception
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/backend/__init__.py b/tensorflow/contrib/keras/api/keras/backend/__init__.py
index f3721a8dcb..10ef5a7585 100644
--- a/tensorflow/contrib/keras/api/keras/backend/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/backend/__init__.py
@@ -19,144 +19,144 @@ from __future__ import division
from __future__ import print_function
# pylint: disable=redefined-builtin
-from tensorflow.contrib.keras.python.keras.backend import abs
-from tensorflow.contrib.keras.python.keras.backend import all
-from tensorflow.contrib.keras.python.keras.backend import any
-from tensorflow.contrib.keras.python.keras.backend import arange
-from tensorflow.contrib.keras.python.keras.backend import argmax
-from tensorflow.contrib.keras.python.keras.backend import argmin
-from tensorflow.contrib.keras.python.keras.backend import backend
-from tensorflow.contrib.keras.python.keras.backend import batch_dot
-from tensorflow.contrib.keras.python.keras.backend import batch_flatten
-from tensorflow.contrib.keras.python.keras.backend import batch_get_value
-from tensorflow.contrib.keras.python.keras.backend import batch_normalization
-from tensorflow.contrib.keras.python.keras.backend import batch_set_value
-from tensorflow.contrib.keras.python.keras.backend import bias_add
-from tensorflow.contrib.keras.python.keras.backend import binary_crossentropy
-from tensorflow.contrib.keras.python.keras.backend import cast
-from tensorflow.contrib.keras.python.keras.backend import cast_to_floatx
-from tensorflow.contrib.keras.python.keras.backend import categorical_crossentropy
-from tensorflow.contrib.keras.python.keras.backend import clear_session
-from tensorflow.contrib.keras.python.keras.backend import clip
-from tensorflow.contrib.keras.python.keras.backend import concatenate
-from tensorflow.contrib.keras.python.keras.backend import constant
-from tensorflow.contrib.keras.python.keras.backend import conv1d
-from tensorflow.contrib.keras.python.keras.backend import conv2d
-from tensorflow.contrib.keras.python.keras.backend import conv2d_transpose
-from tensorflow.contrib.keras.python.keras.backend import conv3d
-from tensorflow.contrib.keras.python.keras.backend import cos
-from tensorflow.contrib.keras.python.keras.backend import count_params
-from tensorflow.contrib.keras.python.keras.backend import ctc_batch_cost
-from tensorflow.contrib.keras.python.keras.backend import ctc_decode
-from tensorflow.contrib.keras.python.keras.backend import ctc_label_dense_to_sparse
-from tensorflow.contrib.keras.python.keras.backend import dot
-from tensorflow.contrib.keras.python.keras.backend import dropout
-from tensorflow.contrib.keras.python.keras.backend import dtype
-from tensorflow.contrib.keras.python.keras.backend import elu
-from tensorflow.contrib.keras.python.keras.backend import epsilon
-from tensorflow.contrib.keras.python.keras.backend import equal
-from tensorflow.contrib.keras.python.keras.backend import eval
-from tensorflow.contrib.keras.python.keras.backend import exp
-from tensorflow.contrib.keras.python.keras.backend import expand_dims
-from tensorflow.contrib.keras.python.keras.backend import eye
-from tensorflow.contrib.keras.python.keras.backend import flatten
-from tensorflow.contrib.keras.python.keras.backend import floatx
-from tensorflow.contrib.keras.python.keras.backend import foldl
-from tensorflow.contrib.keras.python.keras.backend import foldr
-from tensorflow.contrib.keras.python.keras.backend import function
-from tensorflow.contrib.keras.python.keras.backend import gather
-from tensorflow.contrib.keras.python.keras.backend import get_session
-from tensorflow.contrib.keras.python.keras.backend import get_uid
-from tensorflow.contrib.keras.python.keras.backend import get_value
-from tensorflow.contrib.keras.python.keras.backend import gradients
-from tensorflow.contrib.keras.python.keras.backend import greater
-from tensorflow.contrib.keras.python.keras.backend import greater_equal
-from tensorflow.contrib.keras.python.keras.backend import hard_sigmoid
-from tensorflow.contrib.keras.python.keras.backend import image_data_format
-from tensorflow.contrib.keras.python.keras.backend import in_test_phase
-from tensorflow.contrib.keras.python.keras.backend import in_top_k
-from tensorflow.contrib.keras.python.keras.backend import in_train_phase
-from tensorflow.contrib.keras.python.keras.backend import int_shape
-from tensorflow.contrib.keras.python.keras.backend import is_sparse
-from tensorflow.contrib.keras.python.keras.backend import l2_normalize
-from tensorflow.contrib.keras.python.keras.backend import learning_phase
-from tensorflow.contrib.keras.python.keras.backend import less
-from tensorflow.contrib.keras.python.keras.backend import less_equal
-from tensorflow.contrib.keras.python.keras.backend import log
-from tensorflow.contrib.keras.python.keras.backend import manual_variable_initialization
-from tensorflow.contrib.keras.python.keras.backend import map_fn
-from tensorflow.contrib.keras.python.keras.backend import max
-from tensorflow.contrib.keras.python.keras.backend import maximum
-from tensorflow.contrib.keras.python.keras.backend import mean
-from tensorflow.contrib.keras.python.keras.backend import min
-from tensorflow.contrib.keras.python.keras.backend import minimum
-from tensorflow.contrib.keras.python.keras.backend import moving_average_update
-from tensorflow.contrib.keras.python.keras.backend import name_scope
-from tensorflow.contrib.keras.python.keras.backend import ndim
-from tensorflow.contrib.keras.python.keras.backend import normalize_batch_in_training
-from tensorflow.contrib.keras.python.keras.backend import not_equal
-from tensorflow.contrib.keras.python.keras.backend import one_hot
-from tensorflow.contrib.keras.python.keras.backend import ones
-from tensorflow.contrib.keras.python.keras.backend import ones_like
-from tensorflow.contrib.keras.python.keras.backend import permute_dimensions
-from tensorflow.contrib.keras.python.keras.backend import placeholder
-from tensorflow.contrib.keras.python.keras.backend import pool2d
-from tensorflow.contrib.keras.python.keras.backend import pool3d
-from tensorflow.contrib.keras.python.keras.backend import pow
-from tensorflow.contrib.keras.python.keras.backend import print_tensor
-from tensorflow.contrib.keras.python.keras.backend import prod
-from tensorflow.contrib.keras.python.keras.backend import random_binomial
-from tensorflow.contrib.keras.python.keras.backend import random_normal
-from tensorflow.contrib.keras.python.keras.backend import random_normal_variable
-from tensorflow.contrib.keras.python.keras.backend import random_uniform
-from tensorflow.contrib.keras.python.keras.backend import random_uniform_variable
-from tensorflow.contrib.keras.python.keras.backend import relu
-from tensorflow.contrib.keras.python.keras.backend import repeat
-from tensorflow.contrib.keras.python.keras.backend import repeat_elements
-from tensorflow.contrib.keras.python.keras.backend import reset_uids
-from tensorflow.contrib.keras.python.keras.backend import reshape
-from tensorflow.contrib.keras.python.keras.backend import resize_images
-from tensorflow.contrib.keras.python.keras.backend import resize_volumes
-from tensorflow.contrib.keras.python.keras.backend import reverse
-from tensorflow.contrib.keras.python.keras.backend import rnn
-from tensorflow.contrib.keras.python.keras.backend import round
-from tensorflow.contrib.keras.python.keras.backend import separable_conv2d
-from tensorflow.contrib.keras.python.keras.backend import set_epsilon
-from tensorflow.contrib.keras.python.keras.backend import set_floatx
-from tensorflow.contrib.keras.python.keras.backend import set_image_data_format
-from tensorflow.contrib.keras.python.keras.backend import set_learning_phase
-from tensorflow.contrib.keras.python.keras.backend import set_session
-from tensorflow.contrib.keras.python.keras.backend import set_value
-from tensorflow.contrib.keras.python.keras.backend import shape
-from tensorflow.contrib.keras.python.keras.backend import sigmoid
-from tensorflow.contrib.keras.python.keras.backend import sign
-from tensorflow.contrib.keras.python.keras.backend import sin
-from tensorflow.contrib.keras.python.keras.backend import softmax
-from tensorflow.contrib.keras.python.keras.backend import softplus
-from tensorflow.contrib.keras.python.keras.backend import softsign
-from tensorflow.contrib.keras.python.keras.backend import sparse_categorical_crossentropy
-from tensorflow.contrib.keras.python.keras.backend import spatial_2d_padding
-from tensorflow.contrib.keras.python.keras.backend import spatial_3d_padding
-from tensorflow.contrib.keras.python.keras.backend import sqrt
-from tensorflow.contrib.keras.python.keras.backend import square
-from tensorflow.contrib.keras.python.keras.backend import squeeze
-from tensorflow.contrib.keras.python.keras.backend import stack
-from tensorflow.contrib.keras.python.keras.backend import std
-from tensorflow.contrib.keras.python.keras.backend import stop_gradient
-from tensorflow.contrib.keras.python.keras.backend import sum
-from tensorflow.contrib.keras.python.keras.backend import switch
-from tensorflow.contrib.keras.python.keras.backend import tanh
-from tensorflow.contrib.keras.python.keras.backend import temporal_padding
-from tensorflow.contrib.keras.python.keras.backend import to_dense
-from tensorflow.contrib.keras.python.keras.backend import transpose
-from tensorflow.contrib.keras.python.keras.backend import truncated_normal
-from tensorflow.contrib.keras.python.keras.backend import update
-from tensorflow.contrib.keras.python.keras.backend import update_add
-from tensorflow.contrib.keras.python.keras.backend import update_sub
-from tensorflow.contrib.keras.python.keras.backend import var
-from tensorflow.contrib.keras.python.keras.backend import variable
-from tensorflow.contrib.keras.python.keras.backend import zeros
-from tensorflow.contrib.keras.python.keras.backend import zeros_like
+from tensorflow.python.keras._impl.keras.backend import abs
+from tensorflow.python.keras._impl.keras.backend import all
+from tensorflow.python.keras._impl.keras.backend import any
+from tensorflow.python.keras._impl.keras.backend import arange
+from tensorflow.python.keras._impl.keras.backend import argmax
+from tensorflow.python.keras._impl.keras.backend import argmin
+from tensorflow.python.keras._impl.keras.backend import backend
+from tensorflow.python.keras._impl.keras.backend import batch_dot
+from tensorflow.python.keras._impl.keras.backend import batch_flatten
+from tensorflow.python.keras._impl.keras.backend import batch_get_value
+from tensorflow.python.keras._impl.keras.backend import batch_normalization
+from tensorflow.python.keras._impl.keras.backend import batch_set_value
+from tensorflow.python.keras._impl.keras.backend import bias_add
+from tensorflow.python.keras._impl.keras.backend import binary_crossentropy
+from tensorflow.python.keras._impl.keras.backend import cast
+from tensorflow.python.keras._impl.keras.backend import cast_to_floatx
+from tensorflow.python.keras._impl.keras.backend import categorical_crossentropy
+from tensorflow.python.keras._impl.keras.backend import clear_session
+from tensorflow.python.keras._impl.keras.backend import clip
+from tensorflow.python.keras._impl.keras.backend import concatenate
+from tensorflow.python.keras._impl.keras.backend import constant
+from tensorflow.python.keras._impl.keras.backend import conv1d
+from tensorflow.python.keras._impl.keras.backend import conv2d
+from tensorflow.python.keras._impl.keras.backend import conv2d_transpose
+from tensorflow.python.keras._impl.keras.backend import conv3d
+from tensorflow.python.keras._impl.keras.backend import cos
+from tensorflow.python.keras._impl.keras.backend import count_params
+from tensorflow.python.keras._impl.keras.backend import ctc_batch_cost
+from tensorflow.python.keras._impl.keras.backend import ctc_decode
+from tensorflow.python.keras._impl.keras.backend import ctc_label_dense_to_sparse
+from tensorflow.python.keras._impl.keras.backend import dot
+from tensorflow.python.keras._impl.keras.backend import dropout
+from tensorflow.python.keras._impl.keras.backend import dtype
+from tensorflow.python.keras._impl.keras.backend import elu
+from tensorflow.python.keras._impl.keras.backend import epsilon
+from tensorflow.python.keras._impl.keras.backend import equal
+from tensorflow.python.keras._impl.keras.backend import eval
+from tensorflow.python.keras._impl.keras.backend import exp
+from tensorflow.python.keras._impl.keras.backend import expand_dims
+from tensorflow.python.keras._impl.keras.backend import eye
+from tensorflow.python.keras._impl.keras.backend import flatten
+from tensorflow.python.keras._impl.keras.backend import floatx
+from tensorflow.python.keras._impl.keras.backend import foldl
+from tensorflow.python.keras._impl.keras.backend import foldr
+from tensorflow.python.keras._impl.keras.backend import function
+from tensorflow.python.keras._impl.keras.backend import gather
+from tensorflow.python.keras._impl.keras.backend import get_session
+from tensorflow.python.keras._impl.keras.backend import get_uid
+from tensorflow.python.keras._impl.keras.backend import get_value
+from tensorflow.python.keras._impl.keras.backend import gradients
+from tensorflow.python.keras._impl.keras.backend import greater
+from tensorflow.python.keras._impl.keras.backend import greater_equal
+from tensorflow.python.keras._impl.keras.backend import hard_sigmoid
+from tensorflow.python.keras._impl.keras.backend import image_data_format
+from tensorflow.python.keras._impl.keras.backend import in_test_phase
+from tensorflow.python.keras._impl.keras.backend import in_top_k
+from tensorflow.python.keras._impl.keras.backend import in_train_phase
+from tensorflow.python.keras._impl.keras.backend import int_shape
+from tensorflow.python.keras._impl.keras.backend import is_sparse
+from tensorflow.python.keras._impl.keras.backend import l2_normalize
+from tensorflow.python.keras._impl.keras.backend import learning_phase
+from tensorflow.python.keras._impl.keras.backend import less
+from tensorflow.python.keras._impl.keras.backend import less_equal
+from tensorflow.python.keras._impl.keras.backend import log
+from tensorflow.python.keras._impl.keras.backend import manual_variable_initialization
+from tensorflow.python.keras._impl.keras.backend import map_fn
+from tensorflow.python.keras._impl.keras.backend import max
+from tensorflow.python.keras._impl.keras.backend import maximum
+from tensorflow.python.keras._impl.keras.backend import mean
+from tensorflow.python.keras._impl.keras.backend import min
+from tensorflow.python.keras._impl.keras.backend import minimum
+from tensorflow.python.keras._impl.keras.backend import moving_average_update
+from tensorflow.python.keras._impl.keras.backend import name_scope
+from tensorflow.python.keras._impl.keras.backend import ndim
+from tensorflow.python.keras._impl.keras.backend import normalize_batch_in_training
+from tensorflow.python.keras._impl.keras.backend import not_equal
+from tensorflow.python.keras._impl.keras.backend import one_hot
+from tensorflow.python.keras._impl.keras.backend import ones
+from tensorflow.python.keras._impl.keras.backend import ones_like
+from tensorflow.python.keras._impl.keras.backend import permute_dimensions
+from tensorflow.python.keras._impl.keras.backend import placeholder
+from tensorflow.python.keras._impl.keras.backend import pool2d
+from tensorflow.python.keras._impl.keras.backend import pool3d
+from tensorflow.python.keras._impl.keras.backend import pow
+from tensorflow.python.keras._impl.keras.backend import print_tensor
+from tensorflow.python.keras._impl.keras.backend import prod
+from tensorflow.python.keras._impl.keras.backend import random_binomial
+from tensorflow.python.keras._impl.keras.backend import random_normal
+from tensorflow.python.keras._impl.keras.backend import random_normal_variable
+from tensorflow.python.keras._impl.keras.backend import random_uniform
+from tensorflow.python.keras._impl.keras.backend import random_uniform_variable
+from tensorflow.python.keras._impl.keras.backend import relu
+from tensorflow.python.keras._impl.keras.backend import repeat
+from tensorflow.python.keras._impl.keras.backend import repeat_elements
+from tensorflow.python.keras._impl.keras.backend import reset_uids
+from tensorflow.python.keras._impl.keras.backend import reshape
+from tensorflow.python.keras._impl.keras.backend import resize_images
+from tensorflow.python.keras._impl.keras.backend import resize_volumes
+from tensorflow.python.keras._impl.keras.backend import reverse
+from tensorflow.python.keras._impl.keras.backend import rnn
+from tensorflow.python.keras._impl.keras.backend import round
+from tensorflow.python.keras._impl.keras.backend import separable_conv2d
+from tensorflow.python.keras._impl.keras.backend import set_epsilon
+from tensorflow.python.keras._impl.keras.backend import set_floatx
+from tensorflow.python.keras._impl.keras.backend import set_image_data_format
+from tensorflow.python.keras._impl.keras.backend import set_learning_phase
+from tensorflow.python.keras._impl.keras.backend import set_session
+from tensorflow.python.keras._impl.keras.backend import set_value
+from tensorflow.python.keras._impl.keras.backend import shape
+from tensorflow.python.keras._impl.keras.backend import sigmoid
+from tensorflow.python.keras._impl.keras.backend import sign
+from tensorflow.python.keras._impl.keras.backend import sin
+from tensorflow.python.keras._impl.keras.backend import softmax
+from tensorflow.python.keras._impl.keras.backend import softplus
+from tensorflow.python.keras._impl.keras.backend import softsign
+from tensorflow.python.keras._impl.keras.backend import sparse_categorical_crossentropy
+from tensorflow.python.keras._impl.keras.backend import spatial_2d_padding
+from tensorflow.python.keras._impl.keras.backend import spatial_3d_padding
+from tensorflow.python.keras._impl.keras.backend import sqrt
+from tensorflow.python.keras._impl.keras.backend import square
+from tensorflow.python.keras._impl.keras.backend import squeeze
+from tensorflow.python.keras._impl.keras.backend import stack
+from tensorflow.python.keras._impl.keras.backend import std
+from tensorflow.python.keras._impl.keras.backend import stop_gradient
+from tensorflow.python.keras._impl.keras.backend import sum
+from tensorflow.python.keras._impl.keras.backend import switch
+from tensorflow.python.keras._impl.keras.backend import tanh
+from tensorflow.python.keras._impl.keras.backend import temporal_padding
+from tensorflow.python.keras._impl.keras.backend import to_dense
+from tensorflow.python.keras._impl.keras.backend import transpose
+from tensorflow.python.keras._impl.keras.backend import truncated_normal
+from tensorflow.python.keras._impl.keras.backend import update
+from tensorflow.python.keras._impl.keras.backend import update_add
+from tensorflow.python.keras._impl.keras.backend import update_sub
+from tensorflow.python.keras._impl.keras.backend import var
+from tensorflow.python.keras._impl.keras.backend import variable
+from tensorflow.python.keras._impl.keras.backend import zeros
+from tensorflow.python.keras._impl.keras.backend import zeros_like
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/callbacks/__init__.py b/tensorflow/contrib/keras/api/keras/callbacks/__init__.py
index 3a97074857..2d884790dd 100644
--- a/tensorflow/contrib/keras/api/keras/callbacks/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/callbacks/__init__.py
@@ -18,19 +18,19 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.callbacks import BaseLogger
-from tensorflow.contrib.keras.python.keras.callbacks import Callback
-from tensorflow.contrib.keras.python.keras.callbacks import CSVLogger
-from tensorflow.contrib.keras.python.keras.callbacks import EarlyStopping
-from tensorflow.contrib.keras.python.keras.callbacks import History
-from tensorflow.contrib.keras.python.keras.callbacks import LambdaCallback
-from tensorflow.contrib.keras.python.keras.callbacks import LearningRateScheduler
-from tensorflow.contrib.keras.python.keras.callbacks import ModelCheckpoint
-from tensorflow.contrib.keras.python.keras.callbacks import ProgbarLogger
-from tensorflow.contrib.keras.python.keras.callbacks import ReduceLROnPlateau
-from tensorflow.contrib.keras.python.keras.callbacks import RemoteMonitor
-from tensorflow.contrib.keras.python.keras.callbacks import TensorBoard
-from tensorflow.contrib.keras.python.keras.callbacks import TerminateOnNaN
+from tensorflow.python.keras._impl.keras.callbacks import BaseLogger
+from tensorflow.python.keras._impl.keras.callbacks import Callback
+from tensorflow.python.keras._impl.keras.callbacks import CSVLogger
+from tensorflow.python.keras._impl.keras.callbacks import EarlyStopping
+from tensorflow.python.keras._impl.keras.callbacks import History
+from tensorflow.python.keras._impl.keras.callbacks import LambdaCallback
+from tensorflow.python.keras._impl.keras.callbacks import LearningRateScheduler
+from tensorflow.python.keras._impl.keras.callbacks import ModelCheckpoint
+from tensorflow.python.keras._impl.keras.callbacks import ProgbarLogger
+from tensorflow.python.keras._impl.keras.callbacks import ReduceLROnPlateau
+from tensorflow.python.keras._impl.keras.callbacks import RemoteMonitor
+from tensorflow.python.keras._impl.keras.callbacks import TensorBoard
+from tensorflow.python.keras._impl.keras.callbacks import TerminateOnNaN
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/constraints/__init__.py b/tensorflow/contrib/keras/api/keras/constraints/__init__.py
index 6b9e3bf46e..152606d8eb 100644
--- a/tensorflow/contrib/keras/api/keras/constraints/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/constraints/__init__.py
@@ -19,21 +19,21 @@ from __future__ import division
from __future__ import print_function
# Constraints functions / callable classes.
-from tensorflow.contrib.keras.python.keras.constraints import Constraint
-from tensorflow.contrib.keras.python.keras.constraints import max_norm
-from tensorflow.contrib.keras.python.keras.constraints import MaxNorm
-from tensorflow.contrib.keras.python.keras.constraints import min_max_norm
-from tensorflow.contrib.keras.python.keras.constraints import MinMaxNorm
-from tensorflow.contrib.keras.python.keras.constraints import non_neg
-from tensorflow.contrib.keras.python.keras.constraints import NonNeg
-from tensorflow.contrib.keras.python.keras.constraints import unit_norm
-from tensorflow.contrib.keras.python.keras.constraints import UnitNorm
+from tensorflow.python.keras._impl.keras.constraints import Constraint
+from tensorflow.python.keras._impl.keras.constraints import max_norm
+from tensorflow.python.keras._impl.keras.constraints import MaxNorm
+from tensorflow.python.keras._impl.keras.constraints import min_max_norm
+from tensorflow.python.keras._impl.keras.constraints import MinMaxNorm
+from tensorflow.python.keras._impl.keras.constraints import non_neg
+from tensorflow.python.keras._impl.keras.constraints import NonNeg
+from tensorflow.python.keras._impl.keras.constraints import unit_norm
+from tensorflow.python.keras._impl.keras.constraints import UnitNorm
# Auxiliary utils.
# pylint: disable=g-bad-import-order
-from tensorflow.contrib.keras.python.keras.constraints import deserialize
-from tensorflow.contrib.keras.python.keras.constraints import serialize
-from tensorflow.contrib.keras.python.keras.constraints import get
+from tensorflow.python.keras._impl.keras.constraints import deserialize
+from tensorflow.python.keras._impl.keras.constraints import serialize
+from tensorflow.python.keras._impl.keras.constraints import get
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/datasets/boston_housing/__init__.py b/tensorflow/contrib/keras/api/keras/datasets/boston_housing/__init__.py
index 0bfd3df540..b5371a03fd 100644
--- a/tensorflow/contrib/keras/api/keras/datasets/boston_housing/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/datasets/boston_housing/__init__.py
@@ -18,7 +18,7 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.datasets.boston_housing import load_data
+from tensorflow.python.keras._impl.keras.datasets.boston_housing import load_data
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/datasets/cifar10/__init__.py b/tensorflow/contrib/keras/api/keras/datasets/cifar10/__init__.py
index f5fac6982a..68d3eb789e 100644
--- a/tensorflow/contrib/keras/api/keras/datasets/cifar10/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/datasets/cifar10/__init__.py
@@ -18,7 +18,7 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.datasets.cifar10 import load_data
+from tensorflow.python.keras._impl.keras.datasets.cifar10 import load_data
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/datasets/cifar100/__init__.py b/tensorflow/contrib/keras/api/keras/datasets/cifar100/__init__.py
index a7e6996136..ca93742673 100644
--- a/tensorflow/contrib/keras/api/keras/datasets/cifar100/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/datasets/cifar100/__init__.py
@@ -18,7 +18,7 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.datasets.cifar100 import load_data
+from tensorflow.python.keras._impl.keras.datasets.cifar100 import load_data
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/datasets/imdb/__init__.py b/tensorflow/contrib/keras/api/keras/datasets/imdb/__init__.py
index f141c8a8e9..1c6396d2d3 100644
--- a/tensorflow/contrib/keras/api/keras/datasets/imdb/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/datasets/imdb/__init__.py
@@ -18,8 +18,8 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.datasets.imdb import get_word_index
-from tensorflow.contrib.keras.python.keras.datasets.imdb import load_data
+from tensorflow.python.keras._impl.keras.datasets.imdb import get_word_index
+from tensorflow.python.keras._impl.keras.datasets.imdb import load_data
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/datasets/mnist/__init__.py b/tensorflow/contrib/keras/api/keras/datasets/mnist/__init__.py
index 50b74f149c..364255f338 100644
--- a/tensorflow/contrib/keras/api/keras/datasets/mnist/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/datasets/mnist/__init__.py
@@ -18,7 +18,7 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.datasets.mnist import load_data
+from tensorflow.python.keras._impl.keras.datasets.mnist import load_data
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/datasets/reuters/__init__.py b/tensorflow/contrib/keras/api/keras/datasets/reuters/__init__.py
index fc7f1235a3..bb6791a344 100644
--- a/tensorflow/contrib/keras/api/keras/datasets/reuters/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/datasets/reuters/__init__.py
@@ -18,8 +18,8 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.datasets.reuters import get_word_index
-from tensorflow.contrib.keras.python.keras.datasets.reuters import load_data
+from tensorflow.python.keras._impl.keras.datasets.reuters import get_word_index
+from tensorflow.python.keras._impl.keras.datasets.reuters import load_data
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/initializers/__init__.py b/tensorflow/contrib/keras/api/keras/initializers/__init__.py
index 9b58723ed5..6b1fcfd2d9 100644
--- a/tensorflow/contrib/keras/api/keras/initializers/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/initializers/__init__.py
@@ -19,30 +19,30 @@ from __future__ import division
from __future__ import print_function
# Initializer functions / callable classes.
-from tensorflow.contrib.keras.python.keras.initializers import Constant
-from tensorflow.contrib.keras.python.keras.initializers import Identity
-from tensorflow.contrib.keras.python.keras.initializers import Initializer
-from tensorflow.contrib.keras.python.keras.initializers import Ones
-from tensorflow.contrib.keras.python.keras.initializers import Orthogonal
-from tensorflow.contrib.keras.python.keras.initializers import RandomNormal
-from tensorflow.contrib.keras.python.keras.initializers import RandomUniform
-from tensorflow.contrib.keras.python.keras.initializers import TruncatedNormal
-from tensorflow.contrib.keras.python.keras.initializers import VarianceScaling
-from tensorflow.contrib.keras.python.keras.initializers import Zeros
+from tensorflow.python.keras._impl.keras.initializers import Constant
+from tensorflow.python.keras._impl.keras.initializers import Identity
+from tensorflow.python.keras._impl.keras.initializers import Initializer
+from tensorflow.python.keras._impl.keras.initializers import Ones
+from tensorflow.python.keras._impl.keras.initializers import Orthogonal
+from tensorflow.python.keras._impl.keras.initializers import RandomNormal
+from tensorflow.python.keras._impl.keras.initializers import RandomUniform
+from tensorflow.python.keras._impl.keras.initializers import TruncatedNormal
+from tensorflow.python.keras._impl.keras.initializers import VarianceScaling
+from tensorflow.python.keras._impl.keras.initializers import Zeros
# Functional interface.
# pylint: disable=g-bad-import-order
-from tensorflow.contrib.keras.python.keras.initializers import glorot_normal
-from tensorflow.contrib.keras.python.keras.initializers import glorot_uniform
-from tensorflow.contrib.keras.python.keras.initializers import he_normal
-from tensorflow.contrib.keras.python.keras.initializers import he_uniform
-from tensorflow.contrib.keras.python.keras.initializers import lecun_normal
-from tensorflow.contrib.keras.python.keras.initializers import lecun_uniform
+from tensorflow.python.keras._impl.keras.initializers import glorot_normal
+from tensorflow.python.keras._impl.keras.initializers import glorot_uniform
+from tensorflow.python.keras._impl.keras.initializers import he_normal
+from tensorflow.python.keras._impl.keras.initializers import he_uniform
+from tensorflow.python.keras._impl.keras.initializers import lecun_normal
+from tensorflow.python.keras._impl.keras.initializers import lecun_uniform
# Auxiliary utils.
-from tensorflow.contrib.keras.python.keras.initializers import deserialize
-from tensorflow.contrib.keras.python.keras.initializers import serialize
-from tensorflow.contrib.keras.python.keras.initializers import get
+from tensorflow.python.keras._impl.keras.initializers import deserialize
+from tensorflow.python.keras._impl.keras.initializers import serialize
+from tensorflow.python.keras._impl.keras.initializers import get
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/layers/__init__.py b/tensorflow/contrib/keras/api/keras/layers/__init__.py
index aafd189217..acf0a5e179 100644
--- a/tensorflow/contrib/keras/api/keras/layers/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/layers/__init__.py
@@ -20,128 +20,128 @@ from __future__ import print_function
# Generic layers.
# pylint: disable=g-bad-import-order
-from tensorflow.contrib.keras.python.keras.engine import Input
-from tensorflow.contrib.keras.python.keras.engine import InputLayer
-from tensorflow.contrib.keras.python.keras.engine import InputSpec
-from tensorflow.contrib.keras.python.keras.engine import Layer
+from tensorflow.python.keras._impl.keras.engine import Input
+from tensorflow.python.keras._impl.keras.engine import InputLayer
+from tensorflow.python.keras._impl.keras.engine import InputSpec
+from tensorflow.python.keras._impl.keras.engine import Layer
# Advanced activations.
-from tensorflow.contrib.keras.python.keras.layers.advanced_activations import LeakyReLU
-from tensorflow.contrib.keras.python.keras.layers.advanced_activations import PReLU
-from tensorflow.contrib.keras.python.keras.layers.advanced_activations import ELU
-from tensorflow.contrib.keras.python.keras.layers.advanced_activations import ThresholdedReLU
+from tensorflow.python.keras._impl.keras.layers.advanced_activations import LeakyReLU
+from tensorflow.python.keras._impl.keras.layers.advanced_activations import PReLU
+from tensorflow.python.keras._impl.keras.layers.advanced_activations import ELU
+from tensorflow.python.keras._impl.keras.layers.advanced_activations import ThresholdedReLU
# Convolution layers.
-from tensorflow.contrib.keras.python.keras.layers.convolutional import Conv1D
-from tensorflow.contrib.keras.python.keras.layers.convolutional import Conv2D
-from tensorflow.contrib.keras.python.keras.layers.convolutional import Conv3D
-from tensorflow.contrib.keras.python.keras.layers.convolutional import Conv2DTranspose
-from tensorflow.contrib.keras.python.keras.layers.convolutional import Conv3DTranspose
-from tensorflow.contrib.keras.python.keras.layers.convolutional import SeparableConv2D
+from tensorflow.python.keras._impl.keras.layers.convolutional import Conv1D
+from tensorflow.python.keras._impl.keras.layers.convolutional import Conv2D
+from tensorflow.python.keras._impl.keras.layers.convolutional import Conv3D
+from tensorflow.python.keras._impl.keras.layers.convolutional import Conv2DTranspose
+from tensorflow.python.keras._impl.keras.layers.convolutional import Conv3DTranspose
+from tensorflow.python.keras._impl.keras.layers.convolutional import SeparableConv2D
# Convolution layer aliases.
-from tensorflow.contrib.keras.python.keras.layers.convolutional import Convolution1D
-from tensorflow.contrib.keras.python.keras.layers.convolutional import Convolution2D
-from tensorflow.contrib.keras.python.keras.layers.convolutional import Convolution3D
-from tensorflow.contrib.keras.python.keras.layers.convolutional import Convolution2DTranspose
-from tensorflow.contrib.keras.python.keras.layers.convolutional import Convolution3DTranspose
-from tensorflow.contrib.keras.python.keras.layers.convolutional import SeparableConvolution2D
+from tensorflow.python.keras._impl.keras.layers.convolutional import Convolution1D
+from tensorflow.python.keras._impl.keras.layers.convolutional import Convolution2D
+from tensorflow.python.keras._impl.keras.layers.convolutional import Convolution3D
+from tensorflow.python.keras._impl.keras.layers.convolutional import Convolution2DTranspose
+from tensorflow.python.keras._impl.keras.layers.convolutional import Convolution3DTranspose
+from tensorflow.python.keras._impl.keras.layers.convolutional import SeparableConvolution2D
# Image processing layers.
-from tensorflow.contrib.keras.python.keras.layers.convolutional import UpSampling1D
-from tensorflow.contrib.keras.python.keras.layers.convolutional import UpSampling2D
-from tensorflow.contrib.keras.python.keras.layers.convolutional import UpSampling3D
-from tensorflow.contrib.keras.python.keras.layers.convolutional import ZeroPadding1D
-from tensorflow.contrib.keras.python.keras.layers.convolutional import ZeroPadding2D
-from tensorflow.contrib.keras.python.keras.layers.convolutional import ZeroPadding3D
-from tensorflow.contrib.keras.python.keras.layers.convolutional import Cropping1D
-from tensorflow.contrib.keras.python.keras.layers.convolutional import Cropping2D
-from tensorflow.contrib.keras.python.keras.layers.convolutional import Cropping3D
+from tensorflow.python.keras._impl.keras.layers.convolutional import UpSampling1D
+from tensorflow.python.keras._impl.keras.layers.convolutional import UpSampling2D
+from tensorflow.python.keras._impl.keras.layers.convolutional import UpSampling3D
+from tensorflow.python.keras._impl.keras.layers.convolutional import ZeroPadding1D
+from tensorflow.python.keras._impl.keras.layers.convolutional import ZeroPadding2D
+from tensorflow.python.keras._impl.keras.layers.convolutional import ZeroPadding3D
+from tensorflow.python.keras._impl.keras.layers.convolutional import Cropping1D
+from tensorflow.python.keras._impl.keras.layers.convolutional import Cropping2D
+from tensorflow.python.keras._impl.keras.layers.convolutional import Cropping3D
# Convolutional-recurrent layers.
-from tensorflow.contrib.keras.python.keras.layers.convolutional_recurrent import ConvLSTM2D
+from tensorflow.python.keras._impl.keras.layers.convolutional_recurrent import ConvLSTM2D
# Core layers.
-from tensorflow.contrib.keras.python.keras.layers.core import Masking
-from tensorflow.contrib.keras.python.keras.layers.core import Dropout
-from tensorflow.contrib.keras.python.keras.layers.core import SpatialDropout1D
-from tensorflow.contrib.keras.python.keras.layers.core import SpatialDropout2D
-from tensorflow.contrib.keras.python.keras.layers.core import SpatialDropout3D
-from tensorflow.contrib.keras.python.keras.layers.core import Activation
-from tensorflow.contrib.keras.python.keras.layers.core import Reshape
-from tensorflow.contrib.keras.python.keras.layers.core import Permute
-from tensorflow.contrib.keras.python.keras.layers.core import Flatten
-from tensorflow.contrib.keras.python.keras.layers.core import RepeatVector
-from tensorflow.contrib.keras.python.keras.layers.core import Lambda
-from tensorflow.contrib.keras.python.keras.layers.core import Dense
-from tensorflow.contrib.keras.python.keras.layers.core import ActivityRegularization
+from tensorflow.python.keras._impl.keras.layers.core import Masking
+from tensorflow.python.keras._impl.keras.layers.core import Dropout
+from tensorflow.python.keras._impl.keras.layers.core import SpatialDropout1D
+from tensorflow.python.keras._impl.keras.layers.core import SpatialDropout2D
+from tensorflow.python.keras._impl.keras.layers.core import SpatialDropout3D
+from tensorflow.python.keras._impl.keras.layers.core import Activation
+from tensorflow.python.keras._impl.keras.layers.core import Reshape
+from tensorflow.python.keras._impl.keras.layers.core import Permute
+from tensorflow.python.keras._impl.keras.layers.core import Flatten
+from tensorflow.python.keras._impl.keras.layers.core import RepeatVector
+from tensorflow.python.keras._impl.keras.layers.core import Lambda
+from tensorflow.python.keras._impl.keras.layers.core import Dense
+from tensorflow.python.keras._impl.keras.layers.core import ActivityRegularization
# Embedding layers.
-from tensorflow.contrib.keras.python.keras.layers.embeddings import Embedding
+from tensorflow.python.keras._impl.keras.layers.embeddings import Embedding
# Locally-connected layers.
-from tensorflow.contrib.keras.python.keras.layers.local import LocallyConnected1D
-from tensorflow.contrib.keras.python.keras.layers.local import LocallyConnected2D
+from tensorflow.python.keras._impl.keras.layers.local import LocallyConnected1D
+from tensorflow.python.keras._impl.keras.layers.local import LocallyConnected2D
# Merge layers.
-from tensorflow.contrib.keras.python.keras.layers.merge import Add
-from tensorflow.contrib.keras.python.keras.layers.merge import Multiply
-from tensorflow.contrib.keras.python.keras.layers.merge import Average
-from tensorflow.contrib.keras.python.keras.layers.merge import Maximum
-from tensorflow.contrib.keras.python.keras.layers.merge import Concatenate
-from tensorflow.contrib.keras.python.keras.layers.merge import Dot
-from tensorflow.contrib.keras.python.keras.layers.merge import add
-from tensorflow.contrib.keras.python.keras.layers.merge import multiply
-from tensorflow.contrib.keras.python.keras.layers.merge import average
-from tensorflow.contrib.keras.python.keras.layers.merge import maximum
-from tensorflow.contrib.keras.python.keras.layers.merge import concatenate
-from tensorflow.contrib.keras.python.keras.layers.merge import dot
+from tensorflow.python.keras._impl.keras.layers.merge import Add
+from tensorflow.python.keras._impl.keras.layers.merge import Multiply
+from tensorflow.python.keras._impl.keras.layers.merge import Average
+from tensorflow.python.keras._impl.keras.layers.merge import Maximum
+from tensorflow.python.keras._impl.keras.layers.merge import Concatenate
+from tensorflow.python.keras._impl.keras.layers.merge import Dot
+from tensorflow.python.keras._impl.keras.layers.merge import add
+from tensorflow.python.keras._impl.keras.layers.merge import multiply
+from tensorflow.python.keras._impl.keras.layers.merge import average
+from tensorflow.python.keras._impl.keras.layers.merge import maximum
+from tensorflow.python.keras._impl.keras.layers.merge import concatenate
+from tensorflow.python.keras._impl.keras.layers.merge import dot
# Noise layers.
-from tensorflow.contrib.keras.python.keras.layers.noise import AlphaDropout
-from tensorflow.contrib.keras.python.keras.layers.noise import GaussianNoise
-from tensorflow.contrib.keras.python.keras.layers.noise import GaussianDropout
+from tensorflow.python.keras._impl.keras.layers.noise import AlphaDropout
+from tensorflow.python.keras._impl.keras.layers.noise import GaussianNoise
+from tensorflow.python.keras._impl.keras.layers.noise import GaussianDropout
# Normalization layers.
-from tensorflow.contrib.keras.python.keras.layers.normalization import BatchNormalization
+from tensorflow.python.keras._impl.keras.layers.normalization import BatchNormalization
# Pooling layers.
-from tensorflow.contrib.keras.python.keras.layers.pooling import MaxPooling1D
-from tensorflow.contrib.keras.python.keras.layers.pooling import MaxPooling2D
-from tensorflow.contrib.keras.python.keras.layers.pooling import MaxPooling3D
-from tensorflow.contrib.keras.python.keras.layers.pooling import AveragePooling1D
-from tensorflow.contrib.keras.python.keras.layers.pooling import AveragePooling2D
-from tensorflow.contrib.keras.python.keras.layers.pooling import AveragePooling3D
-from tensorflow.contrib.keras.python.keras.layers.pooling import GlobalAveragePooling1D
-from tensorflow.contrib.keras.python.keras.layers.pooling import GlobalAveragePooling2D
-from tensorflow.contrib.keras.python.keras.layers.pooling import GlobalAveragePooling3D
-from tensorflow.contrib.keras.python.keras.layers.pooling import GlobalMaxPooling1D
-from tensorflow.contrib.keras.python.keras.layers.pooling import GlobalMaxPooling2D
-from tensorflow.contrib.keras.python.keras.layers.pooling import GlobalMaxPooling3D
+from tensorflow.python.keras._impl.keras.layers.pooling import MaxPooling1D
+from tensorflow.python.keras._impl.keras.layers.pooling import MaxPooling2D
+from tensorflow.python.keras._impl.keras.layers.pooling import MaxPooling3D
+from tensorflow.python.keras._impl.keras.layers.pooling import AveragePooling1D
+from tensorflow.python.keras._impl.keras.layers.pooling import AveragePooling2D
+from tensorflow.python.keras._impl.keras.layers.pooling import AveragePooling3D
+from tensorflow.python.keras._impl.keras.layers.pooling import GlobalAveragePooling1D
+from tensorflow.python.keras._impl.keras.layers.pooling import GlobalAveragePooling2D
+from tensorflow.python.keras._impl.keras.layers.pooling import GlobalAveragePooling3D
+from tensorflow.python.keras._impl.keras.layers.pooling import GlobalMaxPooling1D
+from tensorflow.python.keras._impl.keras.layers.pooling import GlobalMaxPooling2D
+from tensorflow.python.keras._impl.keras.layers.pooling import GlobalMaxPooling3D
# Pooling layer aliases.
-from tensorflow.contrib.keras.python.keras.layers.pooling import MaxPool1D
-from tensorflow.contrib.keras.python.keras.layers.pooling import MaxPool2D
-from tensorflow.contrib.keras.python.keras.layers.pooling import MaxPool3D
-from tensorflow.contrib.keras.python.keras.layers.pooling import AvgPool1D
-from tensorflow.contrib.keras.python.keras.layers.pooling import AvgPool2D
-from tensorflow.contrib.keras.python.keras.layers.pooling import AvgPool3D
-from tensorflow.contrib.keras.python.keras.layers.pooling import GlobalAvgPool1D
-from tensorflow.contrib.keras.python.keras.layers.pooling import GlobalAvgPool2D
-from tensorflow.contrib.keras.python.keras.layers.pooling import GlobalAvgPool3D
-from tensorflow.contrib.keras.python.keras.layers.pooling import GlobalMaxPool1D
-from tensorflow.contrib.keras.python.keras.layers.pooling import GlobalMaxPool2D
-from tensorflow.contrib.keras.python.keras.layers.pooling import GlobalMaxPool3D
+from tensorflow.python.keras._impl.keras.layers.pooling import MaxPool1D
+from tensorflow.python.keras._impl.keras.layers.pooling import MaxPool2D
+from tensorflow.python.keras._impl.keras.layers.pooling import MaxPool3D
+from tensorflow.python.keras._impl.keras.layers.pooling import AvgPool1D
+from tensorflow.python.keras._impl.keras.layers.pooling import AvgPool2D
+from tensorflow.python.keras._impl.keras.layers.pooling import AvgPool3D
+from tensorflow.python.keras._impl.keras.layers.pooling import GlobalAvgPool1D
+from tensorflow.python.keras._impl.keras.layers.pooling import GlobalAvgPool2D
+from tensorflow.python.keras._impl.keras.layers.pooling import GlobalAvgPool3D
+from tensorflow.python.keras._impl.keras.layers.pooling import GlobalMaxPool1D
+from tensorflow.python.keras._impl.keras.layers.pooling import GlobalMaxPool2D
+from tensorflow.python.keras._impl.keras.layers.pooling import GlobalMaxPool3D
# Recurrent layers.
-from tensorflow.contrib.keras.python.keras.layers.recurrent import SimpleRNN
-from tensorflow.contrib.keras.python.keras.layers.recurrent import GRU
-from tensorflow.contrib.keras.python.keras.layers.recurrent import LSTM
+from tensorflow.python.keras._impl.keras.layers.recurrent import SimpleRNN
+from tensorflow.python.keras._impl.keras.layers.recurrent import GRU
+from tensorflow.python.keras._impl.keras.layers.recurrent import LSTM
# Wrapper functions
-from tensorflow.contrib.keras.python.keras.layers.wrappers import Wrapper
-from tensorflow.contrib.keras.python.keras.layers.wrappers import Bidirectional
-from tensorflow.contrib.keras.python.keras.layers.wrappers import TimeDistributed
+from tensorflow.python.keras._impl.keras.layers.wrappers import Wrapper
+from tensorflow.python.keras._impl.keras.layers.wrappers import Bidirectional
+from tensorflow.python.keras._impl.keras.layers.wrappers import TimeDistributed
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/losses/__init__.py b/tensorflow/contrib/keras/api/keras/losses/__init__.py
index 06dd679f9c..66721b694f 100644
--- a/tensorflow/contrib/keras/api/keras/losses/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/losses/__init__.py
@@ -19,26 +19,26 @@ from __future__ import division
from __future__ import print_function
# Loss functions.
-from tensorflow.contrib.keras.python.keras.losses import binary_crossentropy
-from tensorflow.contrib.keras.python.keras.losses import categorical_crossentropy
-from tensorflow.contrib.keras.python.keras.losses import categorical_hinge
-from tensorflow.contrib.keras.python.keras.losses import cosine_proximity
-from tensorflow.contrib.keras.python.keras.losses import hinge
-from tensorflow.contrib.keras.python.keras.losses import kullback_leibler_divergence
-from tensorflow.contrib.keras.python.keras.losses import logcosh
-from tensorflow.contrib.keras.python.keras.losses import mean_absolute_error
-from tensorflow.contrib.keras.python.keras.losses import mean_absolute_percentage_error
-from tensorflow.contrib.keras.python.keras.losses import mean_squared_error
-from tensorflow.contrib.keras.python.keras.losses import mean_squared_logarithmic_error
-from tensorflow.contrib.keras.python.keras.losses import poisson
-from tensorflow.contrib.keras.python.keras.losses import sparse_categorical_crossentropy
-from tensorflow.contrib.keras.python.keras.losses import squared_hinge
+from tensorflow.python.keras._impl.keras.losses import binary_crossentropy
+from tensorflow.python.keras._impl.keras.losses import categorical_crossentropy
+from tensorflow.python.keras._impl.keras.losses import categorical_hinge
+from tensorflow.python.keras._impl.keras.losses import cosine_proximity
+from tensorflow.python.keras._impl.keras.losses import hinge
+from tensorflow.python.keras._impl.keras.losses import kullback_leibler_divergence
+from tensorflow.python.keras._impl.keras.losses import logcosh
+from tensorflow.python.keras._impl.keras.losses import mean_absolute_error
+from tensorflow.python.keras._impl.keras.losses import mean_absolute_percentage_error
+from tensorflow.python.keras._impl.keras.losses import mean_squared_error
+from tensorflow.python.keras._impl.keras.losses import mean_squared_logarithmic_error
+from tensorflow.python.keras._impl.keras.losses import poisson
+from tensorflow.python.keras._impl.keras.losses import sparse_categorical_crossentropy
+from tensorflow.python.keras._impl.keras.losses import squared_hinge
# Auxiliary utils.
# pylint: disable=g-bad-import-order
-from tensorflow.contrib.keras.python.keras.losses import deserialize
-from tensorflow.contrib.keras.python.keras.losses import serialize
-from tensorflow.contrib.keras.python.keras.losses import get
+from tensorflow.python.keras._impl.keras.losses import deserialize
+from tensorflow.python.keras._impl.keras.losses import serialize
+from tensorflow.python.keras._impl.keras.losses import get
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/metrics/__init__.py b/tensorflow/contrib/keras/api/keras/metrics/__init__.py
index 99496edde2..59faf037bc 100644
--- a/tensorflow/contrib/keras/api/keras/metrics/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/metrics/__init__.py
@@ -19,28 +19,28 @@ from __future__ import division
from __future__ import print_function
# Metrics functions.
-from tensorflow.contrib.keras.python.keras.metrics import binary_accuracy
-from tensorflow.contrib.keras.python.keras.metrics import binary_crossentropy
-from tensorflow.contrib.keras.python.keras.metrics import categorical_accuracy
-from tensorflow.contrib.keras.python.keras.metrics import categorical_crossentropy
-from tensorflow.contrib.keras.python.keras.metrics import cosine_proximity
-from tensorflow.contrib.keras.python.keras.metrics import hinge
-from tensorflow.contrib.keras.python.keras.metrics import kullback_leibler_divergence
-from tensorflow.contrib.keras.python.keras.metrics import mean_absolute_error
-from tensorflow.contrib.keras.python.keras.metrics import mean_absolute_percentage_error
-from tensorflow.contrib.keras.python.keras.metrics import mean_squared_error
-from tensorflow.contrib.keras.python.keras.metrics import mean_squared_logarithmic_error
-from tensorflow.contrib.keras.python.keras.metrics import poisson
-from tensorflow.contrib.keras.python.keras.metrics import sparse_categorical_crossentropy
-from tensorflow.contrib.keras.python.keras.metrics import sparse_top_k_categorical_accuracy
-from tensorflow.contrib.keras.python.keras.metrics import squared_hinge
-from tensorflow.contrib.keras.python.keras.metrics import top_k_categorical_accuracy
+from tensorflow.python.keras._impl.keras.metrics import binary_accuracy
+from tensorflow.python.keras._impl.keras.metrics import binary_crossentropy
+from tensorflow.python.keras._impl.keras.metrics import categorical_accuracy
+from tensorflow.python.keras._impl.keras.metrics import categorical_crossentropy
+from tensorflow.python.keras._impl.keras.metrics import cosine_proximity
+from tensorflow.python.keras._impl.keras.metrics import hinge
+from tensorflow.python.keras._impl.keras.metrics import kullback_leibler_divergence
+from tensorflow.python.keras._impl.keras.metrics import mean_absolute_error
+from tensorflow.python.keras._impl.keras.metrics import mean_absolute_percentage_error
+from tensorflow.python.keras._impl.keras.metrics import mean_squared_error
+from tensorflow.python.keras._impl.keras.metrics import mean_squared_logarithmic_error
+from tensorflow.python.keras._impl.keras.metrics import poisson
+from tensorflow.python.keras._impl.keras.metrics import sparse_categorical_crossentropy
+from tensorflow.python.keras._impl.keras.metrics import sparse_top_k_categorical_accuracy
+from tensorflow.python.keras._impl.keras.metrics import squared_hinge
+from tensorflow.python.keras._impl.keras.metrics import top_k_categorical_accuracy
# Auxiliary utils.
# pylint: disable=g-bad-import-order
-from tensorflow.contrib.keras.python.keras.metrics import deserialize
-from tensorflow.contrib.keras.python.keras.metrics import serialize
-from tensorflow.contrib.keras.python.keras.metrics import get
+from tensorflow.python.keras._impl.keras.metrics import deserialize
+from tensorflow.python.keras._impl.keras.metrics import serialize
+from tensorflow.python.keras._impl.keras.metrics import get
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/models/__init__.py b/tensorflow/contrib/keras/api/keras/models/__init__.py
index 4e5b2a1ed0..2fb4ac0960 100644
--- a/tensorflow/contrib/keras/api/keras/models/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/models/__init__.py
@@ -18,13 +18,13 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.models import load_model
-from tensorflow.contrib.keras.python.keras.models import Model
-from tensorflow.contrib.keras.python.keras.models import model_from_config
-from tensorflow.contrib.keras.python.keras.models import model_from_json
-from tensorflow.contrib.keras.python.keras.models import model_from_yaml
-from tensorflow.contrib.keras.python.keras.models import save_model
-from tensorflow.contrib.keras.python.keras.models import Sequential
+from tensorflow.python.keras._impl.keras.models import load_model
+from tensorflow.python.keras._impl.keras.models import Model
+from tensorflow.python.keras._impl.keras.models import model_from_config
+from tensorflow.python.keras._impl.keras.models import model_from_json
+from tensorflow.python.keras._impl.keras.models import model_from_yaml
+from tensorflow.python.keras._impl.keras.models import save_model
+from tensorflow.python.keras._impl.keras.models import Sequential
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/optimizers/__init__.py b/tensorflow/contrib/keras/api/keras/optimizers/__init__.py
index b3531d7933..44f47bc47f 100644
--- a/tensorflow/contrib/keras/api/keras/optimizers/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/optimizers/__init__.py
@@ -19,20 +19,20 @@ from __future__ import division
from __future__ import print_function
# Optimizer classes.
-from tensorflow.contrib.keras.python.keras.optimizers import Adadelta
-from tensorflow.contrib.keras.python.keras.optimizers import Adagrad
-from tensorflow.contrib.keras.python.keras.optimizers import Adam
-from tensorflow.contrib.keras.python.keras.optimizers import Adamax
-from tensorflow.contrib.keras.python.keras.optimizers import Nadam
-from tensorflow.contrib.keras.python.keras.optimizers import Optimizer
-from tensorflow.contrib.keras.python.keras.optimizers import RMSprop
-from tensorflow.contrib.keras.python.keras.optimizers import SGD
+from tensorflow.python.keras._impl.keras.optimizers import Adadelta
+from tensorflow.python.keras._impl.keras.optimizers import Adagrad
+from tensorflow.python.keras._impl.keras.optimizers import Adam
+from tensorflow.python.keras._impl.keras.optimizers import Adamax
+from tensorflow.python.keras._impl.keras.optimizers import Nadam
+from tensorflow.python.keras._impl.keras.optimizers import Optimizer
+from tensorflow.python.keras._impl.keras.optimizers import RMSprop
+from tensorflow.python.keras._impl.keras.optimizers import SGD
# Auxiliary utils.
# pylint: disable=g-bad-import-order
-from tensorflow.contrib.keras.python.keras.optimizers import deserialize
-from tensorflow.contrib.keras.python.keras.optimizers import serialize
-from tensorflow.contrib.keras.python.keras.optimizers import get
+from tensorflow.python.keras._impl.keras.optimizers import deserialize
+from tensorflow.python.keras._impl.keras.optimizers import serialize
+from tensorflow.python.keras._impl.keras.optimizers import get
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/preprocessing/image/__init__.py b/tensorflow/contrib/keras/api/keras/preprocessing/image/__init__.py
index 18ce1becc2..b96e767552 100644
--- a/tensorflow/contrib/keras/api/keras/preprocessing/image/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/preprocessing/image/__init__.py
@@ -18,20 +18,20 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.preprocessing.image import apply_transform
-from tensorflow.contrib.keras.python.keras.preprocessing.image import array_to_img
-from tensorflow.contrib.keras.python.keras.preprocessing.image import DirectoryIterator
-from tensorflow.contrib.keras.python.keras.preprocessing.image import flip_axis
-from tensorflow.contrib.keras.python.keras.preprocessing.image import ImageDataGenerator
-from tensorflow.contrib.keras.python.keras.preprocessing.image import img_to_array
-from tensorflow.contrib.keras.python.keras.preprocessing.image import Iterator
-from tensorflow.contrib.keras.python.keras.preprocessing.image import load_img
-from tensorflow.contrib.keras.python.keras.preprocessing.image import NumpyArrayIterator
-from tensorflow.contrib.keras.python.keras.preprocessing.image import random_channel_shift
-from tensorflow.contrib.keras.python.keras.preprocessing.image import random_rotation
-from tensorflow.contrib.keras.python.keras.preprocessing.image import random_shear
-from tensorflow.contrib.keras.python.keras.preprocessing.image import random_shift
-from tensorflow.contrib.keras.python.keras.preprocessing.image import random_zoom
+from tensorflow.python.keras._impl.keras.preprocessing.image import apply_transform
+from tensorflow.python.keras._impl.keras.preprocessing.image import array_to_img
+from tensorflow.python.keras._impl.keras.preprocessing.image import DirectoryIterator
+from tensorflow.python.keras._impl.keras.preprocessing.image import flip_axis
+from tensorflow.python.keras._impl.keras.preprocessing.image import ImageDataGenerator
+from tensorflow.python.keras._impl.keras.preprocessing.image import img_to_array
+from tensorflow.python.keras._impl.keras.preprocessing.image import Iterator
+from tensorflow.python.keras._impl.keras.preprocessing.image import load_img
+from tensorflow.python.keras._impl.keras.preprocessing.image import NumpyArrayIterator
+from tensorflow.python.keras._impl.keras.preprocessing.image import random_channel_shift
+from tensorflow.python.keras._impl.keras.preprocessing.image import random_rotation
+from tensorflow.python.keras._impl.keras.preprocessing.image import random_shear
+from tensorflow.python.keras._impl.keras.preprocessing.image import random_shift
+from tensorflow.python.keras._impl.keras.preprocessing.image import random_zoom
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/preprocessing/sequence/__init__.py b/tensorflow/contrib/keras/api/keras/preprocessing/sequence/__init__.py
index 2621e9bf53..112f6af5e5 100644
--- a/tensorflow/contrib/keras/api/keras/preprocessing/sequence/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/preprocessing/sequence/__init__.py
@@ -18,9 +18,9 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.preprocessing.sequence import make_sampling_table
-from tensorflow.contrib.keras.python.keras.preprocessing.sequence import pad_sequences
-from tensorflow.contrib.keras.python.keras.preprocessing.sequence import skipgrams
+from tensorflow.python.keras._impl.keras.preprocessing.sequence import make_sampling_table
+from tensorflow.python.keras._impl.keras.preprocessing.sequence import pad_sequences
+from tensorflow.python.keras._impl.keras.preprocessing.sequence import skipgrams
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/preprocessing/text/__init__.py b/tensorflow/contrib/keras/api/keras/preprocessing/text/__init__.py
index a6b68c3ba6..5bf1a2fb21 100644
--- a/tensorflow/contrib/keras/api/keras/preprocessing/text/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/preprocessing/text/__init__.py
@@ -18,9 +18,9 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.preprocessing.text import one_hot
-from tensorflow.contrib.keras.python.keras.preprocessing.text import text_to_word_sequence
-from tensorflow.contrib.keras.python.keras.preprocessing.text import Tokenizer
+from tensorflow.python.keras._impl.keras.preprocessing.text import one_hot
+from tensorflow.python.keras._impl.keras.preprocessing.text import text_to_word_sequence
+from tensorflow.python.keras._impl.keras.preprocessing.text import Tokenizer
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/regularizers/__init__.py b/tensorflow/contrib/keras/api/keras/regularizers/__init__.py
index a3b0062d5c..3e707ccab5 100644
--- a/tensorflow/contrib/keras/api/keras/regularizers/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/regularizers/__init__.py
@@ -19,19 +19,19 @@ from __future__ import division
from __future__ import print_function
# Regularizer functions / callable classes.
-from tensorflow.contrib.keras.python.keras.regularizers import L1L2
-from tensorflow.contrib.keras.python.keras.regularizers import Regularizer
+from tensorflow.python.keras._impl.keras.regularizers import L1L2
+from tensorflow.python.keras._impl.keras.regularizers import Regularizer
# Functional interface.
# pylint: disable=g-bad-import-order
-from tensorflow.contrib.keras.python.keras.regularizers import l1
-from tensorflow.contrib.keras.python.keras.regularizers import l2
-from tensorflow.contrib.keras.python.keras.regularizers import l1_l2
+from tensorflow.python.keras._impl.keras.regularizers import l1
+from tensorflow.python.keras._impl.keras.regularizers import l2
+from tensorflow.python.keras._impl.keras.regularizers import l1_l2
# Auxiliary utils.
-from tensorflow.contrib.keras.python.keras.regularizers import deserialize
-from tensorflow.contrib.keras.python.keras.regularizers import serialize
-from tensorflow.contrib.keras.python.keras.regularizers import get
+from tensorflow.python.keras._impl.keras.regularizers import deserialize
+from tensorflow.python.keras._impl.keras.regularizers import serialize
+from tensorflow.python.keras._impl.keras.regularizers import get
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/utils/__init__.py b/tensorflow/contrib/keras/api/keras/utils/__init__.py
index d6d70f79d5..a7c2179fe7 100644
--- a/tensorflow/contrib/keras/api/keras/utils/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/utils/__init__.py
@@ -18,21 +18,21 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.utils.data_utils import GeneratorEnqueuer
-from tensorflow.contrib.keras.python.keras.utils.data_utils import get_file
-from tensorflow.contrib.keras.python.keras.utils.data_utils import Sequence
-from tensorflow.contrib.keras.python.keras.utils.data_utils import SequenceEnqueuer
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import custom_object_scope
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import CustomObjectScope
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import deserialize_keras_object
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import get_custom_objects
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import Progbar
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import serialize_keras_object
-from tensorflow.contrib.keras.python.keras.utils.io_utils import HDF5Matrix
-from tensorflow.contrib.keras.python.keras.utils.layer_utils import convert_all_kernels_in_model
-from tensorflow.contrib.keras.python.keras.utils.np_utils import normalize
-from tensorflow.contrib.keras.python.keras.utils.np_utils import to_categorical
-from tensorflow.contrib.keras.python.keras.utils.vis_utils import plot_model
+from tensorflow.python.keras._impl.keras.utils.data_utils import GeneratorEnqueuer
+from tensorflow.python.keras._impl.keras.utils.data_utils import get_file
+from tensorflow.python.keras._impl.keras.utils.data_utils import Sequence
+from tensorflow.python.keras._impl.keras.utils.data_utils import SequenceEnqueuer
+from tensorflow.python.keras._impl.keras.utils.generic_utils import custom_object_scope
+from tensorflow.python.keras._impl.keras.utils.generic_utils import CustomObjectScope
+from tensorflow.python.keras._impl.keras.utils.generic_utils import deserialize_keras_object
+from tensorflow.python.keras._impl.keras.utils.generic_utils import get_custom_objects
+from tensorflow.python.keras._impl.keras.utils.generic_utils import Progbar
+from tensorflow.python.keras._impl.keras.utils.generic_utils import serialize_keras_object
+from tensorflow.python.keras._impl.keras.utils.io_utils import HDF5Matrix
+from tensorflow.python.keras._impl.keras.utils.layer_utils import convert_all_kernels_in_model
+from tensorflow.python.keras._impl.keras.utils.np_utils import normalize
+from tensorflow.python.keras._impl.keras.utils.np_utils import to_categorical
+from tensorflow.python.keras._impl.keras.utils.vis_utils import plot_model
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/api/keras/wrappers/scikit_learn/__init__.py b/tensorflow/contrib/keras/api/keras/wrappers/scikit_learn/__init__.py
index ba1d28c5c6..a46f859273 100644
--- a/tensorflow/contrib/keras/api/keras/wrappers/scikit_learn/__init__.py
+++ b/tensorflow/contrib/keras/api/keras/wrappers/scikit_learn/__init__.py
@@ -18,8 +18,8 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-from tensorflow.contrib.keras.python.keras.wrappers.scikit_learn import KerasClassifier
-from tensorflow.contrib.keras.python.keras.wrappers.scikit_learn import KerasRegressor
+from tensorflow.python.keras._impl.keras.wrappers.scikit_learn import KerasClassifier
+from tensorflow.python.keras._impl.keras.wrappers.scikit_learn import KerasRegressor
del absolute_import
del division
diff --git a/tensorflow/contrib/keras/python/keras/__init__.py b/tensorflow/contrib/keras/python/keras/__init__.py
deleted file mode 100644
index a3edb29170..0000000000
--- a/tensorflow/contrib/keras/python/keras/__init__.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""The Keras API.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras import activations
-from tensorflow.contrib.keras.python.keras import applications
-from tensorflow.contrib.keras.python.keras import backend
-from tensorflow.contrib.keras.python.keras import callbacks
-from tensorflow.contrib.keras.python.keras import constraints
-from tensorflow.contrib.keras.python.keras import datasets
-from tensorflow.contrib.keras.python.keras import engine
-from tensorflow.contrib.keras.python.keras import initializers
-from tensorflow.contrib.keras.python.keras import layers
-from tensorflow.contrib.keras.python.keras import losses
-from tensorflow.contrib.keras.python.keras import metrics
-from tensorflow.contrib.keras.python.keras import models
-from tensorflow.contrib.keras.python.keras import optimizers
-from tensorflow.contrib.keras.python.keras import preprocessing
-from tensorflow.contrib.keras.python.keras import regularizers
-from tensorflow.contrib.keras.python.keras import utils
-from tensorflow.contrib.keras.python.keras import wrappers
-from tensorflow.contrib.keras.python.keras.layers import Input
-
-__version__ = '2.0.8-tf'
diff --git a/tensorflow/contrib/keras/python/keras/activations.py b/tensorflow/contrib/keras/python/keras/activations.py
deleted file mode 100644
index 7f04234e01..0000000000
--- a/tensorflow/contrib/keras/python/keras/activations.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Keras built-in activation functions.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import six
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.engine import Layer
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import deserialize_keras_object
-from tensorflow.python.platform import tf_logging as logging
-
-
-def softmax(x, axis=-1):
- """Softmax activation function.
-
- Arguments:
- x : Tensor.
- axis: Integer, axis along which the softmax normalization is applied.
-
- Returns:
- Tensor, output of softmax transformation.
-
- Raises:
- ValueError: In case `dim(x) == 1`.
- """
- ndim = K.ndim(x)
- if ndim == 2:
- return K.softmax(x)
- elif ndim > 2:
- e = K.exp(x - K.max(x, axis=axis, keepdims=True))
- s = K.sum(e, axis=axis, keepdims=True)
- return e / s
- else:
- raise ValueError('Cannot apply softmax to a tensor that is 1D')
-
-
-def elu(x, alpha=1.0):
- return K.elu(x, alpha)
-
-
-def selu(x):
- """Scaled Exponential Linear Unit. (Klambauer et al., 2017).
-
- Arguments:
- x: A tensor or variable to compute the activation function for.
-
- Returns:
- Tensor with the same shape and dtype as `x`.
-
- References:
- - [Self-Normalizing Neural Networks](https://arxiv.org/abs/1706.02515)
- """
- alpha = 1.6732632423543772848170429916717
- scale = 1.0507009873554804934193349852946
- return scale * K.elu(x, alpha)
-
-
-def softplus(x):
- return K.softplus(x)
-
-
-def softsign(x):
- return K.softsign(x)
-
-
-def relu(x, alpha=0., max_value=None):
- return K.relu(x, alpha=alpha, max_value=max_value)
-
-
-def tanh(x):
- return K.tanh(x)
-
-
-def sigmoid(x):
- return K.sigmoid(x)
-
-
-def hard_sigmoid(x):
- return K.hard_sigmoid(x)
-
-
-def linear(x):
- return x
-
-
-def serialize(activation):
- return activation.__name__
-
-
-def deserialize(name, custom_objects=None):
- return deserialize_keras_object(
- name,
- module_objects=globals(),
- custom_objects=custom_objects,
- printable_module_name='activation function')
-
-
-def get(identifier):
- if identifier is None:
- return linear
- if isinstance(identifier, six.string_types):
- identifier = str(identifier)
- return deserialize(identifier)
- elif callable(identifier):
- if isinstance(identifier, Layer):
- logging.warning(
- 'Do not pass a layer instance (such as {identifier}) as the '
- 'activation argument of another layer. Instead, advanced '
- 'activation layers should be used just like any other '
- 'layer in a model.'.format(identifier=identifier.__class__.__name__))
- return identifier
- else:
- raise ValueError('Could not interpret '
- 'activation function identifier:', identifier)
diff --git a/tensorflow/contrib/keras/python/keras/activations_test.py b/tensorflow/contrib/keras/python/keras/activations_test.py
deleted file mode 100644
index 8efa464b03..0000000000
--- a/tensorflow/contrib/keras/python/keras/activations_test.py
+++ /dev/null
@@ -1,184 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for Keras activation functions."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-def _ref_softmax(values):
- m = np.max(values)
- e = np.exp(values - m)
- return e / np.sum(e)
-
-
-class KerasActivationsTest(test.TestCase):
-
- def test_serialization(self):
- all_activations = ['softmax', 'relu', 'elu', 'tanh',
- 'sigmoid', 'hard_sigmoid', 'linear',
- 'softplus', 'softsign', 'selu']
- for name in all_activations:
- fn = keras.activations.get(name)
- ref_fn = getattr(keras.activations, name)
- assert fn == ref_fn
- config = keras.activations.serialize(fn)
- fn = keras.activations.deserialize(config)
- assert fn == ref_fn
-
- def test_softmax(self):
- with self.test_session():
- x = keras.backend.placeholder(ndim=2)
- f = keras.backend.function([x], [keras.activations.softmax(x)])
- test_values = np.random.random((2, 5))
-
- result = f([test_values])[0]
- expected = _ref_softmax(test_values[0])
- self.assertAllClose(result[0], expected, rtol=1e-05)
-
- with self.assertRaises(ValueError):
- x = keras.backend.placeholder(ndim=1)
- keras.activations.softmax(x)
-
- def test_temporal_softmax(self):
- with self.test_session():
- x = keras.backend.placeholder(shape=(2, 2, 3))
- f = keras.backend.function([x], [keras.activations.softmax(x)])
- test_values = np.random.random((2, 2, 3)) * 10
- result = f([test_values])[0]
- expected = _ref_softmax(test_values[0, 0])
- self.assertAllClose(result[0, 0], expected, rtol=1e-05)
-
- def test_selu(self):
- x = keras.backend.placeholder(ndim=2)
- f = keras.backend.function([x], [keras.activations.selu(x)])
- alpha = 1.6732632423543772848170429916717
- scale = 1.0507009873554804934193349852946
-
- with self.test_session():
- positive_values = np.array([[1, 2]], dtype=keras.backend.floatx())
- result = f([positive_values])[0]
- self.assertAllClose(result, positive_values * scale, rtol=1e-05)
-
- negative_values = np.array([[-1, -2]], dtype=keras.backend.floatx())
- result = f([negative_values])[0]
- true_result = (np.exp(negative_values) - 1) * scale * alpha
- self.assertAllClose(result, true_result)
-
- def test_softplus(self):
- def softplus(x):
- return np.log(np.ones_like(x) + np.exp(x))
-
- with self.test_session():
- x = keras.backend.placeholder(ndim=2)
- f = keras.backend.function([x], [keras.activations.softplus(x)])
- test_values = np.random.random((2, 5))
- result = f([test_values])[0]
- expected = softplus(test_values)
- self.assertAllClose(result, expected, rtol=1e-05)
-
- def test_softsign(self):
- def softsign(x):
- return np.divide(x, np.ones_like(x) + np.absolute(x))
-
- with self.test_session():
- x = keras.backend.placeholder(ndim=2)
- f = keras.backend.function([x], [keras.activations.softsign(x)])
- test_values = np.random.random((2, 5))
- result = f([test_values])[0]
- expected = softsign(test_values)
- self.assertAllClose(result, expected, rtol=1e-05)
-
- def test_sigmoid(self):
- def ref_sigmoid(x):
- if x >= 0:
- return 1 / (1 + np.exp(-x))
- else:
- z = np.exp(x)
- return z / (1 + z)
- sigmoid = np.vectorize(ref_sigmoid)
-
- with self.test_session():
- x = keras.backend.placeholder(ndim=2)
- f = keras.backend.function([x], [keras.activations.sigmoid(x)])
- test_values = np.random.random((2, 5))
- result = f([test_values])[0]
- expected = sigmoid(test_values)
- self.assertAllClose(result, expected, rtol=1e-05)
-
- def test_hard_sigmoid(self):
- def ref_hard_sigmoid(x):
- x = (x * 0.2) + 0.5
- z = 0.0 if x <= 0 else (1.0 if x >= 1 else x)
- return z
- hard_sigmoid = np.vectorize(ref_hard_sigmoid)
- with self.test_session():
- x = keras.backend.placeholder(ndim=2)
- f = keras.backend.function([x], [keras.activations.hard_sigmoid(x)])
- test_values = np.random.random((2, 5))
- result = f([test_values])[0]
- expected = hard_sigmoid(test_values)
- self.assertAllClose(result, expected, rtol=1e-05)
-
- def test_relu(self):
- with self.test_session():
- x = keras.backend.placeholder(ndim=2)
- f = keras.backend.function([x], [keras.activations.relu(x)])
- test_values = np.random.random((2, 5))
- result = f([test_values])[0]
- # No negative values in test values...
- self.assertAllClose(result, test_values, rtol=1e-05)
-
- def test_elu(self):
- with self.test_session():
- x = keras.backend.placeholder(ndim=2)
- f = keras.backend.function([x], [keras.activations.elu(x, 0.5)])
- test_values = np.random.random((2, 5))
- result = f([test_values])[0]
- self.assertAllClose(result, test_values, rtol=1e-05)
- negative_values = np.array([[-1, -2]], dtype=keras.backend.floatx())
- result = f([negative_values])[0]
- true_result = (np.exp(negative_values) - 1) / 2
- self.assertAllClose(result, true_result)
-
- def test_tanh(self):
- with self.test_session():
- test_values = np.random.random((2, 5))
- x = keras.backend.placeholder(ndim=2)
- exp = keras.activations.tanh(x)
- f = keras.backend.function([x], [exp])
- result = f([test_values])[0]
- expected = np.tanh(test_values)
- self.assertAllClose(result, expected, rtol=1e-05)
-
- def test_linear(self):
- x = np.random.random((10, 5))
- self.assertAllClose(x, keras.activations.linear(x))
-
- def test_invalid_usage(self):
- with self.assertRaises(ValueError):
- keras.activations.get('unknown')
-
- # The following should be possible but should raise a warning:
- keras.activations.get(keras.layers.LeakyReLU())
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/applications/__init__.py b/tensorflow/contrib/keras/python/keras/applications/__init__.py
deleted file mode 100644
index 9139df30a6..0000000000
--- a/tensorflow/contrib/keras/python/keras/applications/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Keras Applications: models with automatic loading of pre-trained weights.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras.applications.inception_v3 import InceptionV3
-from tensorflow.contrib.keras.python.keras.applications.mobilenet import MobileNet
-from tensorflow.contrib.keras.python.keras.applications.resnet50 import ResNet50
-from tensorflow.contrib.keras.python.keras.applications.vgg16 import VGG16
-from tensorflow.contrib.keras.python.keras.applications.vgg19 import VGG19
-from tensorflow.contrib.keras.python.keras.applications.xception import Xception
diff --git a/tensorflow/contrib/keras/python/keras/applications/imagenet_utils.py b/tensorflow/contrib/keras/python/keras/applications/imagenet_utils.py
deleted file mode 100644
index ce287dbd66..0000000000
--- a/tensorflow/contrib/keras/python/keras/applications/imagenet_utils.py
+++ /dev/null
@@ -1,193 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Utilities used by models pre-trained on ImageNet.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import json
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.utils.data_utils import get_file
-from tensorflow.python.platform import tf_logging as logging
-
-
-CLASS_INDEX = None
-CLASS_INDEX_PATH = 'https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.json'
-
-
-def preprocess_input(x, data_format=None):
- """Preprocesses a tensor encoding a batch of images.
-
- Arguments:
- x: input Numpy tensor, 4D.
- data_format: data format of the image tensor.
-
- Returns:
- Preprocessed tensor.
- """
- if data_format is None:
- data_format = K.image_data_format()
- assert data_format in {'channels_last', 'channels_first'}
-
- if data_format == 'channels_first':
- if x.ndim == 3:
- # 'RGB'->'BGR'
- x = x[::-1, ...]
- # Zero-center by mean pixel
- x[0, :, :] -= 103.939
- x[1, :, :] -= 116.779
- x[2, :, :] -= 123.68
- else:
- x = x[:, ::-1, ...]
- x[:, 0, :, :] -= 103.939
- x[:, 1, :, :] -= 116.779
- x[:, 2, :, :] -= 123.68
- else:
- # 'RGB'->'BGR'
- x = x[..., ::-1]
- # Zero-center by mean pixel
- x[..., 0] -= 103.939
- x[..., 1] -= 116.779
- x[..., 2] -= 123.68
- return x
-
-
-def decode_predictions(preds, top=5):
- """Decodes the prediction of an ImageNet model.
-
- Arguments:
- preds: Numpy tensor encoding a batch of predictions.
- top: integer, how many top-guesses to return.
-
- Returns:
- A list of lists of top class prediction tuples
- `(class_name, class_description, score)`.
- One list of tuples per sample in batch input.
-
- Raises:
- ValueError: in case of invalid shape of the `pred` array
- (must be 2D).
- """
- global CLASS_INDEX
- if len(preds.shape) != 2 or preds.shape[1] != 1000:
- raise ValueError('`decode_predictions` expects '
- 'a batch of predictions '
- '(i.e. a 2D array of shape (samples, 1000)). '
- 'Found array with shape: ' + str(preds.shape))
- if CLASS_INDEX is None:
- fpath = get_file(
- 'imagenet_class_index.json', CLASS_INDEX_PATH, cache_subdir='models')
- CLASS_INDEX = json.load(open(fpath))
- results = []
- for pred in preds:
- top_indices = pred.argsort()[-top:][::-1]
- result = [tuple(CLASS_INDEX[str(i)]) + (pred[i],) for i in top_indices]
- result.sort(key=lambda x: x[2], reverse=True)
- results.append(result)
- return results
-
-
-def _obtain_input_shape(input_shape,
- default_size,
- min_size,
- data_format,
- require_flatten,
- weights=None):
- """Internal utility to compute/validate an ImageNet model's input shape.
-
- Arguments:
- input_shape: either None (will return the default network input shape),
- or a user-provided shape to be validated.
- default_size: default input width/height for the model.
- min_size: minimum input width/height accepted by the model.
- data_format: image data format to use.
- require_flatten: whether the model is expected to
- be linked to a classifier via a Flatten layer.
- weights: one of `None` (random initialization)
- or 'imagenet' (pre-training on ImageNet).
- If weights='imagenet' input channels must be equal to 3.
-
- Returns:
- An integer shape tuple (may include None entries).
-
- Raises:
- ValueError: in case of invalid argument values.
- """
- if weights != 'imagenet' and input_shape and len(input_shape) == 3:
- if data_format == 'channels_first':
- if input_shape[0] not in {1, 3}:
- logging.warning('This model usually expects 1 or 3 input channels. '
- 'However, it was passed an input_shape with ' +
- str(input_shape[0]) + ' input channels.')
- default_shape = (input_shape[0], default_size, default_size)
- else:
- if input_shape[-1] not in {1, 3}:
- logging.warning('This model usually expects 1 or 3 input channels. '
- 'However, it was passed an input_shape with ' +
- str(input_shape[-1]) + ' input channels.')
- default_shape = (default_size, default_size, input_shape[-1])
- else:
- if data_format == 'channels_first':
- default_shape = (3, default_size, default_size)
- else:
- default_shape = (default_size, default_size, 3)
- if weights == 'imagenet' and require_flatten:
- if input_shape is not None:
- if input_shape != default_shape:
- raise ValueError('When setting`include_top=True` '
- 'and loading `imagenet` weights, '
- '`input_shape` should be ' + str(default_shape) + '.')
- return default_shape
- if input_shape:
- if data_format == 'channels_first':
- if input_shape is not None:
- if len(input_shape) != 3:
- raise ValueError('`input_shape` must be a tuple of three integers.')
- if input_shape[0] != 3 and weights == 'imagenet':
- raise ValueError('The input must have 3 channels; got '
- '`input_shape=' + str(input_shape) + '`')
- if ((input_shape[1] is not None and input_shape[1] < min_size) or
- (input_shape[2] is not None and input_shape[2] < min_size)):
- raise ValueError('Input size must be at least ' + str(min_size) + 'x'
- + str(min_size) + '; got '
- '`input_shape=' + str(input_shape) + '`')
- else:
- if input_shape is not None:
- if len(input_shape) != 3:
- raise ValueError('`input_shape` must be a tuple of three integers.')
- if input_shape[-1] != 3 and weights == 'imagenet':
- raise ValueError('The input must have 3 channels; got '
- '`input_shape=' + str(input_shape) + '`')
- if ((input_shape[0] is not None and input_shape[0] < min_size) or
- (input_shape[1] is not None and input_shape[1] < min_size)):
- raise ValueError('Input size must be at least ' + str(min_size) + 'x'
- + str(min_size) + '; got '
- '`input_shape=' + str(input_shape) + '`')
- else:
- if require_flatten:
- input_shape = default_shape
- else:
- if data_format == 'channels_first':
- input_shape = (3, None, None)
- else:
- input_shape = (None, None, 3)
- if require_flatten:
- if None in input_shape:
- raise ValueError('If `include_top` is True, '
- 'you should specify a static `input_shape`. '
- 'Got `input_shape=' + str(input_shape) + '`')
- return input_shape
diff --git a/tensorflow/contrib/keras/python/keras/applications/imagenet_utils_test.py b/tensorflow/contrib/keras/python/keras/applications/imagenet_utils_test.py
deleted file mode 100644
index fa0b9ec299..0000000000
--- a/tensorflow/contrib/keras/python/keras/applications/imagenet_utils_test.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for Inception V3 application."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-class ImageNetUtilsTest(test.TestCase):
-
- def test_preprocess_input(self):
- # Test batch of images
- x = np.random.uniform(0, 255, (2, 10, 10, 3))
- self.assertEqual(
- keras.applications.imagenet_utils.preprocess_input(x).shape, x.shape)
- out1 = keras.applications.imagenet_utils.preprocess_input(
- x, 'channels_last')
- out2 = keras.applications.imagenet_utils.preprocess_input(
- np.transpose(x, (0, 3, 1, 2)), 'channels_first')
- self.assertAllClose(out1, out2.transpose(0, 2, 3, 1))
-
- # Test single image
- x = np.random.uniform(0, 255, (10, 10, 3))
- self.assertEqual(
- keras.applications.imagenet_utils.preprocess_input(x).shape, x.shape)
- out1 = keras.applications.imagenet_utils.preprocess_input(
- x, 'channels_last')
- out2 = keras.applications.imagenet_utils.preprocess_input(
- np.transpose(x, (2, 0, 1)), 'channels_first')
- self.assertAllClose(out1, out2.transpose(1, 2, 0))
-
- def test_obtain_input_shape(self):
- # input_shape and default_size are not identical.
- with self.assertRaises(ValueError):
- keras.applications.imagenet_utils._obtain_input_shape(
- input_shape=(224, 224, 3),
- default_size=299,
- min_size=139,
- data_format='channels_last',
- require_flatten=True,
- weights='imagenet')
-
- # Test invalid use cases
- for data_format in ['channels_last', 'channels_first']:
- # input_shape is smaller than min_size.
- shape = (100, 100)
- if data_format == 'channels_last':
- input_shape = shape + (3,)
- else:
- input_shape = (3,) + shape
- with self.assertRaises(ValueError):
- keras.applications.imagenet_utils._obtain_input_shape(
- input_shape=input_shape,
- default_size=None,
- min_size=139,
- data_format=data_format,
- require_flatten=False)
-
- # shape is 1D.
- shape = (100,)
- if data_format == 'channels_last':
- input_shape = shape + (3,)
- else:
- input_shape = (3,) + shape
- with self.assertRaises(ValueError):
- keras.applications.imagenet_utils._obtain_input_shape(
- input_shape=input_shape,
- default_size=None,
- min_size=139,
- data_format=data_format,
- require_flatten=False)
-
- # the number of channels is 5 not 3.
- shape = (100, 100)
- if data_format == 'channels_last':
- input_shape = shape + (5,)
- else:
- input_shape = (5,) + shape
- with self.assertRaises(ValueError):
- keras.applications.imagenet_utils._obtain_input_shape(
- input_shape=input_shape,
- default_size=None,
- min_size=139,
- data_format=data_format,
- require_flatten=False)
-
- # require_flatten=True with dynamic input shape.
- with self.assertRaises(ValueError):
- keras.applications.imagenet_utils._obtain_input_shape(
- input_shape=None,
- default_size=None,
- min_size=139,
- data_format='channels_first',
- require_flatten=True)
-
- assert keras.applications.imagenet_utils._obtain_input_shape(
- input_shape=(3, 200, 200),
- default_size=None,
- min_size=139,
- data_format='channels_first',
- require_flatten=True) == (3, 200, 200)
-
- assert keras.applications.imagenet_utils._obtain_input_shape(
- input_shape=None,
- default_size=None,
- min_size=139,
- data_format='channels_last',
- require_flatten=False) == (None, None, 3)
-
- assert keras.applications.imagenet_utils._obtain_input_shape(
- input_shape=None,
- default_size=None,
- min_size=139,
- data_format='channels_first',
- require_flatten=False) == (3, None, None)
-
- assert keras.applications.imagenet_utils._obtain_input_shape(
- input_shape=None,
- default_size=None,
- min_size=139,
- data_format='channels_last',
- require_flatten=False) == (None, None, 3)
-
- assert keras.applications.imagenet_utils._obtain_input_shape(
- input_shape=(150, 150, 3),
- default_size=None,
- min_size=139,
- data_format='channels_last',
- require_flatten=False) == (150, 150, 3)
-
- assert keras.applications.imagenet_utils._obtain_input_shape(
- input_shape=(3, None, None),
- default_size=None,
- min_size=139,
- data_format='channels_first',
- require_flatten=False) == (3, None, None)
-
-
-if __name__ == '__main__':
- test.main()
-
diff --git a/tensorflow/contrib/keras/python/keras/applications/inception_v3.py b/tensorflow/contrib/keras/python/keras/applications/inception_v3.py
deleted file mode 100644
index 2fdc62f2f2..0000000000
--- a/tensorflow/contrib/keras/python/keras/applications/inception_v3.py
+++ /dev/null
@@ -1,392 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-# pylint: disable=invalid-name
-"""Inception V3 model for Keras.
-
-Note that the input image format for this model is different than for
-the VGG16 and ResNet models (299x299 instead of 224x224),
-and that the input preprocessing function is also different (same as Xception).
-
-# Reference
-
-- [Rethinking the Inception Architecture for Computer
-Vision](http://arxiv.org/abs/1512.00567)
-
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras import layers
-from tensorflow.contrib.keras.python.keras.applications.imagenet_utils import _obtain_input_shape
-from tensorflow.contrib.keras.python.keras.applications.imagenet_utils import decode_predictions # pylint: disable=unused-import
-from tensorflow.contrib.keras.python.keras.engine.topology import get_source_inputs
-from tensorflow.contrib.keras.python.keras.layers import Activation
-from tensorflow.contrib.keras.python.keras.layers import AveragePooling2D
-from tensorflow.contrib.keras.python.keras.layers import BatchNormalization
-from tensorflow.contrib.keras.python.keras.layers import Conv2D
-from tensorflow.contrib.keras.python.keras.layers import Dense
-from tensorflow.contrib.keras.python.keras.layers import GlobalAveragePooling2D
-from tensorflow.contrib.keras.python.keras.layers import GlobalMaxPooling2D
-from tensorflow.contrib.keras.python.keras.layers import Input
-from tensorflow.contrib.keras.python.keras.layers import MaxPooling2D
-from tensorflow.contrib.keras.python.keras.models import Model
-from tensorflow.contrib.keras.python.keras.utils.data_utils import get_file
-
-
-WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.5/inception_v3_weights_tf_dim_ordering_tf_kernels.h5'
-WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.5/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5'
-
-
-def conv2d_bn(x,
- filters,
- num_row,
- num_col,
- padding='same',
- strides=(1, 1),
- name=None):
- """Utility function to apply conv + BN.
-
- Arguments:
- x: input tensor.
- filters: filters in `Conv2D`.
- num_row: height of the convolution kernel.
- num_col: width of the convolution kernel.
- padding: padding mode in `Conv2D`.
- strides: strides in `Conv2D`.
- name: name of the ops; will become `name + '_conv'`
- for the convolution and `name + '_bn'` for the
- batch norm layer.
-
- Returns:
- Output tensor after applying `Conv2D` and `BatchNormalization`.
- """
- if name is not None:
- bn_name = name + '_bn'
- conv_name = name + '_conv'
- else:
- bn_name = None
- conv_name = None
- if K.image_data_format() == 'channels_first':
- bn_axis = 1
- else:
- bn_axis = 3
- x = Conv2D(
- filters, (num_row, num_col),
- strides=strides,
- padding=padding,
- use_bias=False,
- name=conv_name)(x)
- x = BatchNormalization(axis=bn_axis, scale=False, name=bn_name)(x)
- x = Activation('relu', name=name)(x)
- return x
-
-
-def InceptionV3(include_top=True,
- weights='imagenet',
- input_tensor=None,
- input_shape=None,
- pooling=None,
- classes=1000):
- """Instantiates the Inception v3 architecture.
-
- Optionally loads weights pre-trained
- on ImageNet. Note that when using TensorFlow,
- for best performance you should set
- `image_data_format="channels_last"` in your Keras config
- at ~/.keras/keras.json.
- The model and the weights are compatible with both
- TensorFlow and Theano. The data format
- convention used by the model is the one
- specified in your Keras config file.
- Note that the default input image size for this model is 299x299.
-
- Arguments:
- include_top: whether to include the fully-connected
- layer at the top of the network.
- weights: one of `None` (random initialization)
- or "imagenet" (pre-training on ImageNet).
- input_tensor: optional Keras tensor (i.e. output of `layers.Input()`)
- to use as image input for the model.
- input_shape: optional shape tuple, only to be specified
- if `include_top` is False (otherwise the input shape
- has to be `(299, 299, 3)` (with `channels_last` data format)
- or `(3, 299, 299)` (with `channels_first` data format).
- It should have exactly 3 input channels,
- and width and height should be no smaller than 139.
- E.g. `(150, 150, 3)` would be one valid value.
- pooling: Optional pooling mode for feature extraction
- when `include_top` is `False`.
- - `None` means that the output of the model will be
- the 4D tensor output of the
- last convolutional layer.
- - `avg` means that global average pooling
- will be applied to the output of the
- last convolutional layer, and thus
- the output of the model will be a 2D tensor.
- - `max` means that global max pooling will
- be applied.
- classes: optional number of classes to classify images
- into, only to be specified if `include_top` is True, and
- if no `weights` argument is specified.
-
- Returns:
- A Keras model instance.
-
- Raises:
- ValueError: in case of invalid argument for `weights`,
- or invalid input shape.
- """
- if weights not in {'imagenet', None}:
- raise ValueError('The `weights` argument should be either '
- '`None` (random initialization) or `imagenet` '
- '(pre-training on ImageNet).')
-
- if weights == 'imagenet' and include_top and classes != 1000:
- raise ValueError('If using `weights` as imagenet with `include_top`'
- ' as true, `classes` should be 1000')
-
- # Determine proper input shape
- input_shape = _obtain_input_shape(
- input_shape,
- default_size=299,
- min_size=139,
- data_format=K.image_data_format(),
- require_flatten=False,
- weights=weights)
-
- if input_tensor is None:
- img_input = Input(shape=input_shape)
- else:
- img_input = Input(tensor=input_tensor, shape=input_shape)
-
- if K.image_data_format() == 'channels_first':
- channel_axis = 1
- else:
- channel_axis = 3
-
- x = conv2d_bn(img_input, 32, 3, 3, strides=(2, 2), padding='valid')
- x = conv2d_bn(x, 32, 3, 3, padding='valid')
- x = conv2d_bn(x, 64, 3, 3)
- x = MaxPooling2D((3, 3), strides=(2, 2))(x)
-
- x = conv2d_bn(x, 80, 1, 1, padding='valid')
- x = conv2d_bn(x, 192, 3, 3, padding='valid')
- x = MaxPooling2D((3, 3), strides=(2, 2))(x)
-
- # mixed 0, 1, 2: 35 x 35 x 256
- branch1x1 = conv2d_bn(x, 64, 1, 1)
-
- branch5x5 = conv2d_bn(x, 48, 1, 1)
- branch5x5 = conv2d_bn(branch5x5, 64, 5, 5)
-
- branch3x3dbl = conv2d_bn(x, 64, 1, 1)
- branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3)
- branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3)
-
- branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x)
- branch_pool = conv2d_bn(branch_pool, 32, 1, 1)
- x = layers.concatenate(
- [branch1x1, branch5x5, branch3x3dbl, branch_pool],
- axis=channel_axis,
- name='mixed0')
-
- # mixed 1: 35 x 35 x 256
- branch1x1 = conv2d_bn(x, 64, 1, 1)
-
- branch5x5 = conv2d_bn(x, 48, 1, 1)
- branch5x5 = conv2d_bn(branch5x5, 64, 5, 5)
-
- branch3x3dbl = conv2d_bn(x, 64, 1, 1)
- branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3)
- branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3)
-
- branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x)
- branch_pool = conv2d_bn(branch_pool, 64, 1, 1)
- x = layers.concatenate(
- [branch1x1, branch5x5, branch3x3dbl, branch_pool],
- axis=channel_axis,
- name='mixed1')
-
- # mixed 2: 35 x 35 x 256
- branch1x1 = conv2d_bn(x, 64, 1, 1)
-
- branch5x5 = conv2d_bn(x, 48, 1, 1)
- branch5x5 = conv2d_bn(branch5x5, 64, 5, 5)
-
- branch3x3dbl = conv2d_bn(x, 64, 1, 1)
- branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3)
- branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3)
-
- branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x)
- branch_pool = conv2d_bn(branch_pool, 64, 1, 1)
- x = layers.concatenate(
- [branch1x1, branch5x5, branch3x3dbl, branch_pool],
- axis=channel_axis,
- name='mixed2')
-
- # mixed 3: 17 x 17 x 768
- branch3x3 = conv2d_bn(x, 384, 3, 3, strides=(2, 2), padding='valid')
-
- branch3x3dbl = conv2d_bn(x, 64, 1, 1)
- branch3x3dbl = conv2d_bn(branch3x3dbl, 96, 3, 3)
- branch3x3dbl = conv2d_bn(
- branch3x3dbl, 96, 3, 3, strides=(2, 2), padding='valid')
-
- branch_pool = MaxPooling2D((3, 3), strides=(2, 2))(x)
- x = layers.concatenate(
- [branch3x3, branch3x3dbl, branch_pool], axis=channel_axis, name='mixed3')
-
- # mixed 4: 17 x 17 x 768
- branch1x1 = conv2d_bn(x, 192, 1, 1)
-
- branch7x7 = conv2d_bn(x, 128, 1, 1)
- branch7x7 = conv2d_bn(branch7x7, 128, 1, 7)
- branch7x7 = conv2d_bn(branch7x7, 192, 7, 1)
-
- branch7x7dbl = conv2d_bn(x, 128, 1, 1)
- branch7x7dbl = conv2d_bn(branch7x7dbl, 128, 7, 1)
- branch7x7dbl = conv2d_bn(branch7x7dbl, 128, 1, 7)
- branch7x7dbl = conv2d_bn(branch7x7dbl, 128, 7, 1)
- branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7)
-
- branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x)
- branch_pool = conv2d_bn(branch_pool, 192, 1, 1)
- x = layers.concatenate(
- [branch1x1, branch7x7, branch7x7dbl, branch_pool],
- axis=channel_axis,
- name='mixed4')
-
- # mixed 5, 6: 17 x 17 x 768
- for i in range(2):
- branch1x1 = conv2d_bn(x, 192, 1, 1)
-
- branch7x7 = conv2d_bn(x, 160, 1, 1)
- branch7x7 = conv2d_bn(branch7x7, 160, 1, 7)
- branch7x7 = conv2d_bn(branch7x7, 192, 7, 1)
-
- branch7x7dbl = conv2d_bn(x, 160, 1, 1)
- branch7x7dbl = conv2d_bn(branch7x7dbl, 160, 7, 1)
- branch7x7dbl = conv2d_bn(branch7x7dbl, 160, 1, 7)
- branch7x7dbl = conv2d_bn(branch7x7dbl, 160, 7, 1)
- branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7)
-
- branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x)
- branch_pool = conv2d_bn(branch_pool, 192, 1, 1)
- x = layers.concatenate(
- [branch1x1, branch7x7, branch7x7dbl, branch_pool],
- axis=channel_axis,
- name='mixed' + str(5 + i))
-
- # mixed 7: 17 x 17 x 768
- branch1x1 = conv2d_bn(x, 192, 1, 1)
-
- branch7x7 = conv2d_bn(x, 192, 1, 1)
- branch7x7 = conv2d_bn(branch7x7, 192, 1, 7)
- branch7x7 = conv2d_bn(branch7x7, 192, 7, 1)
-
- branch7x7dbl = conv2d_bn(x, 192, 1, 1)
- branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 7, 1)
- branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7)
- branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 7, 1)
- branch7x7dbl = conv2d_bn(branch7x7dbl, 192, 1, 7)
-
- branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x)
- branch_pool = conv2d_bn(branch_pool, 192, 1, 1)
- x = layers.concatenate(
- [branch1x1, branch7x7, branch7x7dbl, branch_pool],
- axis=channel_axis,
- name='mixed7')
-
- # mixed 8: 8 x 8 x 1280
- branch3x3 = conv2d_bn(x, 192, 1, 1)
- branch3x3 = conv2d_bn(branch3x3, 320, 3, 3, strides=(2, 2), padding='valid')
-
- branch7x7x3 = conv2d_bn(x, 192, 1, 1)
- branch7x7x3 = conv2d_bn(branch7x7x3, 192, 1, 7)
- branch7x7x3 = conv2d_bn(branch7x7x3, 192, 7, 1)
- branch7x7x3 = conv2d_bn(
- branch7x7x3, 192, 3, 3, strides=(2, 2), padding='valid')
-
- branch_pool = MaxPooling2D((3, 3), strides=(2, 2))(x)
- x = layers.concatenate(
- [branch3x3, branch7x7x3, branch_pool], axis=channel_axis, name='mixed8')
-
- # mixed 9: 8 x 8 x 2048
- for i in range(2):
- branch1x1 = conv2d_bn(x, 320, 1, 1)
-
- branch3x3 = conv2d_bn(x, 384, 1, 1)
- branch3x3_1 = conv2d_bn(branch3x3, 384, 1, 3)
- branch3x3_2 = conv2d_bn(branch3x3, 384, 3, 1)
- branch3x3 = layers.concatenate(
- [branch3x3_1, branch3x3_2], axis=channel_axis, name='mixed9_' + str(i))
-
- branch3x3dbl = conv2d_bn(x, 448, 1, 1)
- branch3x3dbl = conv2d_bn(branch3x3dbl, 384, 3, 3)
- branch3x3dbl_1 = conv2d_bn(branch3x3dbl, 384, 1, 3)
- branch3x3dbl_2 = conv2d_bn(branch3x3dbl, 384, 3, 1)
- branch3x3dbl = layers.concatenate(
- [branch3x3dbl_1, branch3x3dbl_2], axis=channel_axis)
-
- branch_pool = AveragePooling2D((3, 3), strides=(1, 1), padding='same')(x)
- branch_pool = conv2d_bn(branch_pool, 192, 1, 1)
- x = layers.concatenate(
- [branch1x1, branch3x3, branch3x3dbl, branch_pool],
- axis=channel_axis,
- name='mixed' + str(9 + i))
- if include_top:
- # Classification block
- x = GlobalAveragePooling2D(name='avg_pool')(x)
- x = Dense(classes, activation='softmax', name='predictions')(x)
- else:
- if pooling == 'avg':
- x = GlobalAveragePooling2D()(x)
- elif pooling == 'max':
- x = GlobalMaxPooling2D()(x)
-
- # Ensure that the model takes into account
- # any potential predecessors of `input_tensor`.
- if input_tensor is not None:
- inputs = get_source_inputs(input_tensor)
- else:
- inputs = img_input
- # Create model.
- model = Model(inputs, x, name='inception_v3')
-
- # load weights
- if weights == 'imagenet':
- if include_top:
- weights_path = get_file(
- 'inception_v3_weights_tf_dim_ordering_tf_kernels.h5',
- WEIGHTS_PATH,
- cache_subdir='models',
- md5_hash='9a0d58056eeedaa3f26cb7ebd46da564')
- else:
- weights_path = get_file(
- 'inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5',
- WEIGHTS_PATH_NO_TOP,
- cache_subdir='models',
- md5_hash='bcbd6486424b2319ff4ef7d526e38f63')
- model.load_weights(weights_path)
- return model
-
-
-def preprocess_input(x):
- x /= 255.
- x -= 0.5
- x *= 2.
- return x
diff --git a/tensorflow/contrib/keras/python/keras/applications/inception_v3_test.py b/tensorflow/contrib/keras/python/keras/applications/inception_v3_test.py
deleted file mode 100644
index 890df612ff..0000000000
--- a/tensorflow/contrib/keras/python/keras/applications/inception_v3_test.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for Inception V3 application."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-class InceptionV3Test(test.TestCase):
-
- def test_with_top(self):
- model = keras.applications.InceptionV3(weights=None)
- self.assertEqual(model.output_shape, (None, 1000))
-
- def test_no_top(self):
- model = keras.applications.InceptionV3(weights=None, include_top=False)
- self.assertEqual(model.output_shape, (None, None, None, 2048))
-
- def test_with_pooling(self):
- model = keras.applications.InceptionV3(weights=None,
- include_top=False,
- pooling='avg')
- self.assertEqual(model.output_shape, (None, 2048))
-
- def test_weight_loading(self):
- with self.assertRaises(ValueError):
- keras.applications.InceptionV3(weights='unknown',
- include_top=False)
- with self.assertRaises(ValueError):
- keras.applications.InceptionV3(weights='imagenet',
- classes=2000)
-
- def test_preprocess_input(self):
- x = np.random.uniform(0, 255, (2, 300, 200, 3))
- out1 = keras.applications.inception_v3.preprocess_input(x)
- self.assertAllClose(np.mean(out1), 0., atol=0.1)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/applications/mobilenet.py b/tensorflow/contrib/keras/python/keras/applications/mobilenet.py
deleted file mode 100644
index 2a93486401..0000000000
--- a/tensorflow/contrib/keras/python/keras/applications/mobilenet.py
+++ /dev/null
@@ -1,669 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""MobileNet v1 models for Keras.
-
-MobileNet is a general architecture and can be used for multiple use cases.
-Depending on the use case, it can use different input layer size and
-different width factors. This allows different width models to reduce
-the number of multiply-adds and thereby
-reduce inference cost on mobile devices.
-
-MobileNets support any input size greater than 32 x 32, with larger image sizes
-offering better performance.
-The number of parameters and number of multiply-adds
-can be modified by using the `alpha` parameter,
-which increases/decreases the number of filters in each layer.
-By altering the image size and `alpha` parameter,
-all 16 models from the paper can be built, with ImageNet weights provided.
-
-The paper demonstrates the performance of MobileNets using `alpha` values of
-1.0 (also called 100 % MobileNet), 0.75, 0.5 and 0.25.
-For each of these `alpha` values, weights for 4 different input image sizes
-are provided (224, 192, 160, 128).
-
-The following table describes the size and accuracy of the 100% MobileNet
-on size 224 x 224:
-----------------------------------------------------------------------------
-Width Multiplier (alpha) | ImageNet Acc | Multiply-Adds (M) | Params (M)
-----------------------------------------------------------------------------
-| 1.0 MobileNet-224 | 70.6 % | 529 | 4.2 |
-| 0.75 MobileNet-224 | 68.4 % | 325 | 2.6 |
-| 0.50 MobileNet-224 | 63.7 % | 149 | 1.3 |
-| 0.25 MobileNet-224 | 50.6 % | 41 | 0.5 |
-----------------------------------------------------------------------------
-
-The following table describes the performance of
-the 100 % MobileNet on various input sizes:
-------------------------------------------------------------------------
- Resolution | ImageNet Acc | Multiply-Adds (M) | Params (M)
-------------------------------------------------------------------------
-| 1.0 MobileNet-224 | 70.6 % | 529 | 4.2 |
-| 1.0 MobileNet-192 | 69.1 % | 529 | 4.2 |
-| 1.0 MobileNet-160 | 67.2 % | 529 | 4.2 |
-| 1.0 MobileNet-128 | 64.4 % | 529 | 4.2 |
-------------------------------------------------------------------------
-
-The weights for all 16 models are obtained and translated
-from Tensorflow checkpoints found at
-https://github.com/tensorflow/models/blob/master/slim/nets/mobilenet_v1.md
-
-# Reference
-- [MobileNets: Efficient Convolutional Neural Networks for
- Mobile Vision Applications](https://arxiv.org/pdf/1704.04861.pdf))
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import warnings
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras import constraints
-from tensorflow.contrib.keras.python.keras import initializers
-from tensorflow.contrib.keras.python.keras import regularizers
-from tensorflow.contrib.keras.python.keras.applications.imagenet_utils import _obtain_input_shape
-from tensorflow.contrib.keras.python.keras.applications.imagenet_utils import decode_predictions # pylint: disable=unused-import
-from tensorflow.contrib.keras.python.keras.engine import InputSpec
-from tensorflow.contrib.keras.python.keras.engine.topology import get_source_inputs
-from tensorflow.contrib.keras.python.keras.layers import Activation
-from tensorflow.contrib.keras.python.keras.layers import BatchNormalization
-from tensorflow.contrib.keras.python.keras.layers import Conv2D
-from tensorflow.contrib.keras.python.keras.layers import Dropout
-from tensorflow.contrib.keras.python.keras.layers import GlobalAveragePooling2D
-from tensorflow.contrib.keras.python.keras.layers import GlobalMaxPooling2D
-from tensorflow.contrib.keras.python.keras.layers import Input
-from tensorflow.contrib.keras.python.keras.layers import Reshape
-from tensorflow.contrib.keras.python.keras.models import Model
-from tensorflow.contrib.keras.python.keras.utils import conv_utils
-from tensorflow.contrib.keras.python.keras.utils.data_utils import get_file
-
-BASE_WEIGHT_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.6/'
-
-
-def relu6(x):
- return K.relu(x, max_value=6)
-
-
-def preprocess_input(x):
- x /= 255.
- x -= 0.5
- x *= 2.
- return x
-
-
-class DepthwiseConv2D(Conv2D):
- """Depthwise separable 2D convolution.
-
- Depthwise Separable convolutions consists in performing
- just the first step in a depthwise spatial convolution
- (which acts on each input channel separately).
- The `depth_multiplier` argument controls how many
- output channels are generated per input channel in the depthwise step.
-
- Arguments:
- kernel_size: An integer or tuple/list of 2 integers, specifying the
- width and height of the 2D convolution window.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- strides: An integer or tuple/list of 2 integers,
- specifying the strides of the convolution along the width and height.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- Specifying any stride value != 1 is incompatible with specifying
- any `dilation_rate` value != 1.
- padding: one of `"valid"` or `"same"` (case-insensitive).
- depth_multiplier: The number of depthwise convolution output channels
- for each input channel.
- The total number of depthwise convolution output
- channels will be equal to `filters_in * depth_multiplier`.
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, height, width, channels)` while `channels_first`
- corresponds to inputs with shape
- `(batch, channels, height, width)`.
- 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 "channels_last".
- activation: Activation function to use
- (see [activations](../activations.md)).
- If you don't specify anything, no activation is applied
- (ie. "linear" activation: `a(x) = x`).
- use_bias: Boolean, whether the layer uses a bias vector.
- depthwise_initializer: Initializer for the depthwise kernel matrix
- (see [initializers](../initializers.md)).
- bias_initializer: Initializer for the bias vector
- (see [initializers](../initializers.md)).
- depthwise_regularizer: Regularizer function applied to
- the depthwise kernel matrix
- (see [regularizer](../regularizers.md)).
- bias_regularizer: Regularizer function applied to the bias vector
- (see [regularizer](../regularizers.md)).
- activity_regularizer: Regularizer function applied to
- the output of the layer (its "activation").
- (see [regularizer](../regularizers.md)).
- depthwise_constraint: Constraint function applied to
- the depthwise kernel matrix
- (see [constraints](../constraints.md)).
- bias_constraint: Constraint function applied to the bias vector
- (see [constraints](../constraints.md)).
-
- Input shape:
- 4D tensor with shape:
- `[batch, channels, rows, cols]` if data_format='channels_first'
- or 4D tensor with shape:
- `[batch, rows, cols, channels]` if data_format='channels_last'.
-
- Output shape:
- 4D tensor with shape:
- `[batch, filters, new_rows, new_cols]` if data_format='channels_first'
- or 4D tensor with shape:
- `[batch, new_rows, new_cols, filters]` if data_format='channels_last'.
- `rows` and `cols` values might have changed due to padding.
- """
-
- def __init__(self,
- kernel_size,
- strides=(1, 1),
- padding='valid',
- depth_multiplier=1,
- data_format=None,
- activation=None,
- use_bias=True,
- depthwise_initializer='glorot_uniform',
- bias_initializer='zeros',
- depthwise_regularizer=None,
- bias_regularizer=None,
- activity_regularizer=None,
- depthwise_constraint=None,
- bias_constraint=None,
- **kwargs):
- super(DepthwiseConv2D, self).__init__(
- filters=None,
- kernel_size=kernel_size,
- strides=strides,
- padding=padding,
- data_format=data_format,
- activation=activation,
- use_bias=use_bias,
- bias_regularizer=bias_regularizer,
- activity_regularizer=activity_regularizer,
- bias_constraint=bias_constraint,
- **kwargs)
- self.depth_multiplier = depth_multiplier
- self.depthwise_initializer = initializers.get(depthwise_initializer)
- self.depthwise_regularizer = regularizers.get(depthwise_regularizer)
- self.depthwise_constraint = constraints.get(depthwise_constraint)
- self.bias_initializer = initializers.get(bias_initializer)
-
- def build(self, input_shape):
- if len(input_shape) < 4:
- raise ValueError('Inputs to `DepthwiseConv2D` should have rank 4. '
- 'Received input shape:', str(input_shape))
- if self.data_format == 'channels_first':
- channel_axis = 1
- else:
- channel_axis = 3
- if input_shape[channel_axis] is None:
- raise ValueError('The channel dimension of the inputs to '
- '`DepthwiseConv2D` '
- 'should be defined. Found `None`.')
- input_dim = int(input_shape[channel_axis])
- depthwise_kernel_shape = (self.kernel_size[0], self.kernel_size[1],
- input_dim, self.depth_multiplier)
-
- self.depthwise_kernel = self.add_weight(
- shape=depthwise_kernel_shape,
- initializer=self.depthwise_initializer,
- name='depthwise_kernel',
- regularizer=self.depthwise_regularizer,
- constraint=self.depthwise_constraint)
-
- if self.use_bias:
- self.bias = self.add_weight(
- shape=(input_dim * self.depth_multiplier,),
- initializer=self.bias_initializer,
- name='bias',
- regularizer=self.bias_regularizer,
- constraint=self.bias_constraint)
- else:
- self.bias = None
- # Set input spec.
- self.input_spec = InputSpec(ndim=4, axes={channel_axis: input_dim})
- self.built = True
-
- def call(self, inputs, training=None):
- outputs = K.depthwise_conv2d(
- inputs,
- self.depthwise_kernel,
- strides=self.strides,
- padding=self.padding,
- dilation_rate=self.dilation_rate,
- data_format=self.data_format)
-
- if self.bias:
- outputs = K.bias_add(outputs, self.bias, data_format=self.data_format)
-
- if self.activation is not None:
- return self.activation(outputs)
-
- return outputs
-
- def compute_output_shape(self, input_shape):
- if self.data_format == 'channels_first':
- rows = input_shape[2]
- cols = input_shape[3]
- out_filters = input_shape[1] * self.depth_multiplier
- elif self.data_format == 'channels_last':
- rows = input_shape[1]
- cols = input_shape[2]
- out_filters = input_shape[3] * self.depth_multiplier
-
- rows = conv_utils.conv_output_length(rows, self.kernel_size[0],
- self.padding, self.strides[0])
- cols = conv_utils.conv_output_length(cols, self.kernel_size[1],
- self.padding, self.strides[1])
-
- if self.data_format == 'channels_first':
- return (input_shape[0], out_filters, rows, cols)
- elif self.data_format == 'channels_last':
- return (input_shape[0], rows, cols, out_filters)
-
- def get_config(self):
- config = super(DepthwiseConv2D, self).get_config()
- config.pop('filters')
- config.pop('kernel_initializer')
- config.pop('kernel_regularizer')
- config.pop('kernel_constraint')
- config['depth_multiplier'] = self.depth_multiplier
- config['depthwise_initializer'] = initializers.serialize(
- self.depthwise_initializer)
- config['depthwise_regularizer'] = regularizers.serialize(
- self.depthwise_regularizer)
- config['depthwise_constraint'] = constraints.serialize(
- self.depthwise_constraint)
- return config
-
-
-def MobileNet(input_shape=None, # pylint: disable=invalid-name
- alpha=1.0,
- depth_multiplier=1,
- dropout=1e-3,
- include_top=True,
- weights='imagenet',
- input_tensor=None,
- pooling=None,
- classes=1000):
- """Instantiates the MobileNet architecture.
-
- Note that only TensorFlow is supported for now,
- therefore it only works with the data format
- `image_data_format='channels_last'` in your Keras config
- at `~/.keras/keras.json`.
-
- To load a MobileNet model via `load_model`, import the custom
- objects `relu6` and `DepthwiseConv2D` and pass them to the
- `custom_objects` parameter.
- E.g.
- model = load_model('mobilenet.h5', custom_objects={
- 'relu6': mobilenet.relu6,
- 'DepthwiseConv2D': mobilenet.DepthwiseConv2D})
-
- Arguments:
- input_shape: optional shape tuple, only to be specified
- if `include_top` is False (otherwise the input shape
- has to be `(224, 224, 3)` (with `channels_last` data format)
- or (3, 224, 224) (with `channels_first` data format).
- It should have exactly 3 input channels,
- and width and height should be no smaller than 32.
- E.g. `(200, 200, 3)` would be one valid value.
- alpha: controls the width of the network.
- - If `alpha` < 1.0, proportionally decreases the number
- of filters in each layer.
- - If `alpha` > 1.0, proportionally increases the number
- of filters in each layer.
- - If `alpha` = 1, default number of filters from the paper
- are used at each layer.
- depth_multiplier: depth multiplier for depthwise convolution
- (also called the resolution multiplier)
- dropout: dropout rate
- include_top: whether to include the fully-connected
- layer at the top of the network.
- weights: `None` (random initialization) or
- `imagenet` (ImageNet weights)
- input_tensor: optional Keras tensor (i.e. output of
- `layers.Input()`)
- to use as image input for the model.
- pooling: Optional pooling mode for feature extraction
- when `include_top` is `False`.
- - `None` means that the output of the model
- will be the 4D tensor output of the
- last convolutional layer.
- - `avg` means that global average pooling
- will be applied to the output of the
- last convolutional layer, and thus
- the output of the model will be a
- 2D tensor.
- - `max` means that global max pooling will
- be applied.
- classes: optional number of classes to classify images
- into, only to be specified if `include_top` is True, and
- if no `weights` argument is specified.
-
- Returns:
- A Keras model instance.
-
- Raises:
- ValueError: in case of invalid argument for `weights`,
- or invalid input shape.
- RuntimeError: If attempting to run this model with a
- backend that does not support separable convolutions.
- """
-
- if K.backend() != 'tensorflow':
- raise RuntimeError('Only TensorFlow backend is currently supported, '
- 'as other backends do not support '
- 'depthwise convolution.')
-
- if weights not in {'imagenet', None}:
- raise ValueError('The `weights` argument should be either '
- '`None` (random initialization) or `imagenet` '
- '(pre-training on ImageNet).')
-
- if weights == 'imagenet' and include_top and classes != 1000:
- raise ValueError('If using `weights` as ImageNet with `include_top` '
- 'as true, `classes` should be 1000')
-
- # Determine proper input shape.
- if input_shape is None:
- default_size = 224
- else:
- if K.image_data_format() == 'channels_first':
- rows = input_shape[1]
- cols = input_shape[2]
- else:
- rows = input_shape[0]
- cols = input_shape[1]
- if rows == cols and rows in [128, 160, 192, 224]:
- default_size = rows
- else:
- default_size = 224
- input_shape = _obtain_input_shape(
- input_shape,
- default_size=default_size,
- min_size=32,
- data_format=K.image_data_format(),
- require_flatten=include_top,
- weights=weights)
- if K.image_data_format() == 'channels_last':
- row_axis, col_axis = (0, 1)
- else:
- row_axis, col_axis = (1, 2)
- rows = input_shape[row_axis]
- cols = input_shape[col_axis]
-
- if weights == 'imagenet':
- if depth_multiplier != 1:
- raise ValueError('If imagenet weights are being loaded, '
- 'depth multiplier must be 1')
-
- if alpha not in [0.25, 0.50, 0.75, 1.0]:
- raise ValueError('If imagenet weights are being loaded, '
- 'alpha can be one of'
- '`0.25`, `0.50`, `0.75` or `1.0` only.')
-
- if rows != cols or rows not in [128, 160, 192, 224]:
- raise ValueError('If imagenet weights are being loaded, '
- 'input must have a static square shape (one of '
- '(128,128), (160,160), (192,192), or (224, 224)).'
- ' Input shape provided = %s' % (input_shape,))
-
- if K.image_data_format() != 'channels_last':
- warnings.warn('The MobileNet family of models is only available '
- 'for the input data format "channels_last" '
- '(width, height, channels). '
- 'However your settings specify the default '
- 'data format "channels_first" (channels, width, height).'
- ' You should set `image_data_format="channels_last"` '
- 'in your Keras config located at ~/.keras/keras.json. '
- 'The model being returned right now will expect inputs '
- 'to follow the "channels_last" data format.')
- K.set_image_data_format('channels_last')
- old_data_format = 'channels_first'
- else:
- old_data_format = None
-
- if input_tensor is None:
- img_input = Input(shape=input_shape)
- else:
- if not K.is_keras_tensor(input_tensor):
- img_input = Input(tensor=input_tensor, shape=input_shape)
- else:
- img_input = input_tensor
-
- x = _conv_block(img_input, 32, alpha, strides=(2, 2))
- x = _depthwise_conv_block(x, 64, alpha, depth_multiplier, block_id=1)
-
- x = _depthwise_conv_block(
- x, 128, alpha, depth_multiplier, strides=(2, 2), block_id=2)
- x = _depthwise_conv_block(x, 128, alpha, depth_multiplier, block_id=3)
-
- x = _depthwise_conv_block(
- x, 256, alpha, depth_multiplier, strides=(2, 2), block_id=4)
- x = _depthwise_conv_block(x, 256, alpha, depth_multiplier, block_id=5)
-
- x = _depthwise_conv_block(
- x, 512, alpha, depth_multiplier, strides=(2, 2), block_id=6)
- x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=7)
- x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=8)
- x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=9)
- x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=10)
- x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=11)
-
- x = _depthwise_conv_block(
- x, 1024, alpha, depth_multiplier, strides=(2, 2), block_id=12)
- x = _depthwise_conv_block(x, 1024, alpha, depth_multiplier, block_id=13)
-
- if include_top:
- if K.image_data_format() == 'channels_first':
- shape = (int(1024 * alpha), 1, 1)
- else:
- shape = (1, 1, int(1024 * alpha))
-
- x = GlobalAveragePooling2D()(x)
- x = Reshape(shape, name='reshape_1')(x)
- x = Dropout(dropout, name='dropout')(x)
- x = Conv2D(classes, (1, 1), padding='same', name='conv_preds')(x)
- x = Activation('softmax', name='act_softmax')(x)
- x = Reshape((classes,), name='reshape_2')(x)
- else:
- if pooling == 'avg':
- x = GlobalAveragePooling2D()(x)
- elif pooling == 'max':
- x = GlobalMaxPooling2D()(x)
-
- # Ensure that the model takes into account
- # any potential predecessors of `input_tensor`.
- if input_tensor is not None:
- inputs = get_source_inputs(input_tensor)
- else:
- inputs = img_input
-
- # Create model.
- model = Model(inputs, x, name='mobilenet_%0.2f_%s' % (alpha, rows))
-
- # load weights
- if weights == 'imagenet':
- if K.image_data_format() == 'channels_first':
- raise ValueError('Weights for "channels_last" format '
- 'are not available.')
- if alpha == 1.0:
- alpha_text = '1_0'
- elif alpha == 0.75:
- alpha_text = '7_5'
- elif alpha == 0.50:
- alpha_text = '5_0'
- else:
- alpha_text = '2_5'
-
- if include_top:
- model_name = 'mobilenet_%s_%d_tf.h5' % (alpha_text, rows)
- weigh_path = BASE_WEIGHT_PATH + model_name
- weights_path = get_file(model_name, weigh_path, cache_subdir='models')
- else:
- model_name = 'mobilenet_%s_%d_tf_no_top.h5' % (alpha_text, rows)
- weigh_path = BASE_WEIGHT_PATH + model_name
- weights_path = get_file(model_name, weigh_path, cache_subdir='models')
- model.load_weights(weights_path)
-
- if old_data_format:
- K.set_image_data_format(old_data_format)
- return model
-
-
-def _conv_block(inputs, filters, alpha, kernel=(3, 3), strides=(1, 1)):
- """Adds an initial convolution layer (with batch normalization and relu6).
-
- Arguments:
- inputs: Input tensor of shape `(rows, cols, 3)`
- (with `channels_last` data format) or
- (3, rows, cols) (with `channels_first` data format).
- It should have exactly 3 inputs channels,
- and width and height should be no smaller than 32.
- E.g. `(224, 224, 3)` would be one valid value.
- filters: Integer, the dimensionality of the output space
- (i.e. the number output of filters in the convolution).
- alpha: controls the width of the network.
- - If `alpha` < 1.0, proportionally decreases the number
- of filters in each layer.
- - If `alpha` > 1.0, proportionally increases the number
- of filters in each layer.
- - If `alpha` = 1, default number of filters from the paper
- are used at each layer.
- kernel: An integer or tuple/list of 2 integers, specifying the
- width and height of the 2D convolution window.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- strides: An integer or tuple/list of 2 integers,
- specifying the strides of the convolution along the width and height.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- Specifying any stride value != 1 is incompatible with specifying
- any `dilation_rate` value != 1.
-
- Input shape:
- 4D tensor with shape:
- `(samples, channels, rows, cols)` if data_format='channels_first'
- or 4D tensor with shape:
- `(samples, rows, cols, channels)` if data_format='channels_last'.
-
- Output shape:
- 4D tensor with shape:
- `(samples, filters, new_rows, new_cols)` if data_format='channels_first'
- or 4D tensor with shape:
- `(samples, new_rows, new_cols, filters)` if data_format='channels_last'.
- `rows` and `cols` values might have changed due to stride.
-
- Returns:
- Output tensor of block.
- """
- channel_axis = 1 if K.image_data_format() == 'channels_first' else -1
- filters = int(filters * alpha)
- x = Conv2D(
- filters,
- kernel,
- padding='same',
- use_bias=False,
- strides=strides,
- name='conv1')(inputs)
- x = BatchNormalization(axis=channel_axis, name='conv1_bn')(x)
- return Activation(relu6, name='conv1_relu')(x)
-
-
-def _depthwise_conv_block(inputs,
- pointwise_conv_filters,
- alpha,
- depth_multiplier=1,
- strides=(1, 1),
- block_id=1):
- """Adds a depthwise convolution block.
-
- A depthwise convolution block consists of a depthwise conv,
- batch normalization, relu6, pointwise convolution,
- batch normalization and relu6 activation.
-
- Arguments:
- inputs: Input tensor of shape `(rows, cols, channels)`
- (with `channels_last` data format) or
- (channels, rows, cols) (with `channels_first` data format).
- pointwise_conv_filters: Integer, the dimensionality of the output space
- (i.e. the number output of filters in the pointwise convolution).
- alpha: controls the width of the network.
- - If `alpha` < 1.0, proportionally decreases the number
- of filters in each layer.
- - If `alpha` > 1.0, proportionally increases the number
- of filters in each layer.
- - If `alpha` = 1, default number of filters from the paper
- are used at each layer.
- depth_multiplier: The number of depthwise convolution output channels
- for each input channel.
- The total number of depthwise convolution output
- channels will be equal to `filters_in * depth_multiplier`.
- strides: An integer or tuple/list of 2 integers,
- specifying the strides of the convolution along the width and height.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- Specifying any stride value != 1 is incompatible with specifying
- any `dilation_rate` value != 1.
- block_id: Integer, a unique identification designating the block number.
-
- Input shape:
- 4D tensor with shape:
- `(batch, channels, rows, cols)` if data_format='channels_first'
- or 4D tensor with shape:
- `(batch, rows, cols, channels)` if data_format='channels_last'.
-
- Output shape:
- 4D tensor with shape:
- `(batch, filters, new_rows, new_cols)` if data_format='channels_first'
- or 4D tensor with shape:
- `(batch, new_rows, new_cols, filters)` if data_format='channels_last'.
- `rows` and `cols` values might have changed due to stride.
-
- Returns:
- Output tensor of block.
- """
- channel_axis = 1 if K.image_data_format() == 'channels_first' else -1
- pointwise_conv_filters = int(pointwise_conv_filters * alpha)
-
- x = DepthwiseConv2D( # pylint: disable=not-callable
- (3, 3),
- padding='same',
- depth_multiplier=depth_multiplier,
- strides=strides,
- use_bias=False,
- name='conv_dw_%d' % block_id)(inputs)
- x = BatchNormalization(axis=channel_axis, name='conv_dw_%d_bn' % block_id)(x)
- x = Activation(relu6, name='conv_dw_%d_relu' % block_id)(x)
-
- x = Conv2D(
- pointwise_conv_filters, (1, 1),
- padding='same',
- use_bias=False,
- strides=(1, 1),
- name='conv_pw_%d' % block_id)(x)
- x = BatchNormalization(axis=channel_axis, name='conv_pw_%d_bn' % block_id)(x)
- return Activation(relu6, name='conv_pw_%d_relu' % block_id)(x)
diff --git a/tensorflow/contrib/keras/python/keras/applications/mobilenet_test.py b/tensorflow/contrib/keras/python/keras/applications/mobilenet_test.py
deleted file mode 100644
index 19e69c764a..0000000000
--- a/tensorflow/contrib/keras/python/keras/applications/mobilenet_test.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for MobileNet application."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-class MobileNetTest(test.TestCase):
-
- def test_with_top(self):
- model = keras.applications.MobileNet(weights=None)
- self.assertEqual(model.output_shape, (None, 1000))
-
- def test_no_top(self):
- model = keras.applications.MobileNet(weights=None, include_top=False)
- self.assertEqual(model.output_shape, (None, None, None, 1024))
-
- def test_with_pooling(self):
- model = keras.applications.MobileNet(weights=None,
- include_top=False,
- pooling='avg')
- self.assertEqual(model.output_shape, (None, 1024))
-
- def test_weight_loading(self):
- with self.assertRaises(ValueError):
- keras.applications.MobileNet(weights='unknown',
- include_top=False)
- with self.assertRaises(ValueError):
- keras.applications.MobileNet(weights='imagenet',
- classes=2000)
-
- def test_preprocess_input(self):
- x = np.random.uniform(0, 255, (2, 300, 200, 3))
- out1 = keras.applications.mobilenet.preprocess_input(x)
- self.assertAllClose(np.mean(out1), 0., atol=0.1)
-
- def test_invalid_use_cases(self):
- keras.backend.set_image_data_format('channels_first')
- model = keras.applications.MobileNet(weights=None)
- self.assertEqual(model.output_shape, (None, 1000))
- keras.backend.set_image_data_format('channels_last')
-
- def test_mobilenet_variable_input_channels(self):
- input_shape = (None, None, 1)
- model = keras.applications.MobileNet(weights=None,
- include_top=False,
- input_shape=input_shape)
- self.assertEqual(model.output_shape, (None, None, None, 1024))
-
- input_shape = (None, None, 4)
- model = keras.applications.MobileNet(weights=None,
- include_top=False,
- input_shape=input_shape)
- self.assertEqual(model.output_shape, (None, None, None, 1024))
-
- def test_mobilenet_image_size(self):
- with self.test_session():
- valid_image_sizes = [128, 160, 192, 224]
- for size in valid_image_sizes:
- keras.backend.set_image_data_format('channels_last')
- input_shape = (size, size, 3)
- model = keras.applications.MobileNet(input_shape=input_shape,
- weights=None,
- include_top=True)
- self.assertEqual(model.input_shape, (None,) + input_shape)
-
- keras.backend.set_image_data_format('channels_first')
- input_shape = (3, size, size)
- model = keras.applications.MobileNet(input_shape=input_shape,
- weights=None,
- include_top=True)
- self.assertEqual(model.input_shape, (None,) + input_shape)
-
- keras.backend.set_image_data_format('channels_last')
- invalid_image_shape = (112, 112, 3)
- with self.assertRaises(ValueError):
- model = keras.applications.MobileNet(input_shape=invalid_image_shape,
- weights='imagenet',
- include_top=True)
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/applications/resnet50.py b/tensorflow/contrib/keras/python/keras/applications/resnet50.py
deleted file mode 100644
index 794e05e2dc..0000000000
--- a/tensorflow/contrib/keras/python/keras/applications/resnet50.py
+++ /dev/null
@@ -1,286 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-# pylint: disable=invalid-name
-"""ResNet50 model for Keras.
-
-# Reference:
-
-- [Deep Residual Learning for Image
-Recognition](https://arxiv.org/abs/1512.03385)
-
-Adapted from code contributed by BigMoyan.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras import layers
-from tensorflow.contrib.keras.python.keras.applications.imagenet_utils import _obtain_input_shape
-from tensorflow.contrib.keras.python.keras.applications.imagenet_utils import decode_predictions # pylint: disable=unused-import
-from tensorflow.contrib.keras.python.keras.applications.imagenet_utils import preprocess_input # pylint: disable=unused-import
-from tensorflow.contrib.keras.python.keras.engine.topology import get_source_inputs
-from tensorflow.contrib.keras.python.keras.layers import Activation
-from tensorflow.contrib.keras.python.keras.layers import AveragePooling2D
-from tensorflow.contrib.keras.python.keras.layers import BatchNormalization
-from tensorflow.contrib.keras.python.keras.layers import Conv2D
-from tensorflow.contrib.keras.python.keras.layers import Dense
-from tensorflow.contrib.keras.python.keras.layers import Flatten
-from tensorflow.contrib.keras.python.keras.layers import GlobalAveragePooling2D
-from tensorflow.contrib.keras.python.keras.layers import GlobalMaxPooling2D
-from tensorflow.contrib.keras.python.keras.layers import Input
-from tensorflow.contrib.keras.python.keras.layers import MaxPooling2D
-from tensorflow.contrib.keras.python.keras.models import Model
-from tensorflow.contrib.keras.python.keras.utils.data_utils import get_file
-
-
-WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.2/resnet50_weights_tf_dim_ordering_tf_kernels.h5'
-WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.2/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5'
-
-
-def identity_block(input_tensor, kernel_size, filters, stage, block):
- """The identity block is the block that has no conv layer at shortcut.
-
- Arguments:
- input_tensor: input tensor
- kernel_size: default 3, the kernel size of middle conv layer at main path
- filters: list of integers, the filterss of 3 conv layer at main path
- stage: integer, current stage label, used for generating layer names
- block: 'a','b'..., current block label, used for generating layer names
-
- Returns:
- Output tensor for the block.
- """
- filters1, filters2, filters3 = filters
- if K.image_data_format() == 'channels_last':
- bn_axis = 3
- else:
- bn_axis = 1
- conv_name_base = 'res' + str(stage) + block + '_branch'
- bn_name_base = 'bn' + str(stage) + block + '_branch'
-
- x = Conv2D(filters1, (1, 1), name=conv_name_base + '2a')(input_tensor)
- x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)
- x = Activation('relu')(x)
-
- x = Conv2D(
- filters2, kernel_size, padding='same', name=conv_name_base + '2b')(x)
- x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)
- x = Activation('relu')(x)
-
- x = Conv2D(filters3, (1, 1), name=conv_name_base + '2c')(x)
- x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)
-
- x = layers.add([x, input_tensor])
- x = Activation('relu')(x)
- return x
-
-
-def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2,
- 2)):
- """conv_block is the block that has a conv layer at shortcut.
-
- Arguments:
- input_tensor: input tensor
- kernel_size: default 3, the kernel size of middle conv layer at main path
- filters: list of integers, the filterss of 3 conv layer at main path
- stage: integer, current stage label, used for generating layer names
- block: 'a','b'..., current block label, used for generating layer names
- strides: Tuple of integers.
-
- Returns:
- Output tensor for the block.
-
- Note that from stage 3, the first conv layer at main path is with
- strides=(2,2)
- And the shortcut should have strides=(2,2) as well
- """
- filters1, filters2, filters3 = filters
- if K.image_data_format() == 'channels_last':
- bn_axis = 3
- else:
- bn_axis = 1
- conv_name_base = 'res' + str(stage) + block + '_branch'
- bn_name_base = 'bn' + str(stage) + block + '_branch'
-
- x = Conv2D(
- filters1, (1, 1), strides=strides,
- name=conv_name_base + '2a')(input_tensor)
- x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)
- x = Activation('relu')(x)
-
- x = Conv2D(
- filters2, kernel_size, padding='same', name=conv_name_base + '2b')(x)
- x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)
- x = Activation('relu')(x)
-
- x = Conv2D(filters3, (1, 1), name=conv_name_base + '2c')(x)
- x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)
-
- shortcut = Conv2D(
- filters3, (1, 1), strides=strides,
- name=conv_name_base + '1')(input_tensor)
- shortcut = BatchNormalization(axis=bn_axis, name=bn_name_base + '1')(shortcut)
-
- x = layers.add([x, shortcut])
- x = Activation('relu')(x)
- return x
-
-
-def ResNet50(include_top=True,
- weights='imagenet',
- input_tensor=None,
- input_shape=None,
- pooling=None,
- classes=1000):
- """Instantiates the ResNet50 architecture.
-
- Optionally loads weights pre-trained
- on ImageNet. Note that when using TensorFlow,
- for best performance you should set
- `image_data_format="channels_last"` in your Keras config
- at ~/.keras/keras.json.
-
- The model and the weights are compatible with both
- TensorFlow and Theano. The data format
- convention used by the model is the one
- specified in your Keras config file.
-
- Arguments:
- include_top: whether to include the fully-connected
- layer at the top of the network.
- weights: one of `None` (random initialization)
- or "imagenet" (pre-training on ImageNet).
- input_tensor: optional Keras tensor (i.e. output of `layers.Input()`)
- to use as image input for the model.
- input_shape: optional shape tuple, only to be specified
- if `include_top` is False (otherwise the input shape
- has to be `(224, 224, 3)` (with `channels_last` data format)
- or `(3, 224, 224)` (with `channels_first` data format).
- It should have exactly 3 input channels,
- and width and height should be no smaller than 197.
- E.g. `(200, 200, 3)` would be one valid value.
- pooling: Optional pooling mode for feature extraction
- when `include_top` is `False`.
- - `None` means that the output of the model will be
- the 4D tensor output of the
- last convolutional layer.
- - `avg` means that global average pooling
- will be applied to the output of the
- last convolutional layer, and thus
- the output of the model will be a 2D tensor.
- - `max` means that global max pooling will
- be applied.
- classes: optional number of classes to classify images
- into, only to be specified if `include_top` is True, and
- if no `weights` argument is specified.
-
- Returns:
- A Keras model instance.
-
- Raises:
- ValueError: in case of invalid argument for `weights`,
- or invalid input shape.
- """
- if weights not in {'imagenet', None}:
- raise ValueError('The `weights` argument should be either '
- '`None` (random initialization) or `imagenet` '
- '(pre-training on ImageNet).')
-
- if weights == 'imagenet' and include_top and classes != 1000:
- raise ValueError('If using `weights` as imagenet with `include_top`'
- ' as true, `classes` should be 1000')
-
- # Determine proper input shape
- input_shape = _obtain_input_shape(
- input_shape,
- default_size=224,
- min_size=197,
- data_format=K.image_data_format(),
- require_flatten=include_top,
- weights=weights)
-
- if input_tensor is None:
- img_input = Input(shape=input_shape)
- else:
- img_input = Input(tensor=input_tensor, shape=input_shape)
-
- if K.image_data_format() == 'channels_last':
- bn_axis = 3
- else:
- bn_axis = 1
-
- x = Conv2D(64, (7, 7),
- strides=(2, 2), padding='same', name='conv1')(img_input)
- x = BatchNormalization(axis=bn_axis, name='bn_conv1')(x)
- x = Activation('relu')(x)
- x = MaxPooling2D((3, 3), strides=(2, 2))(x)
-
- x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1))
- x = identity_block(x, 3, [64, 64, 256], stage=2, block='b')
- x = identity_block(x, 3, [64, 64, 256], stage=2, block='c')
-
- x = conv_block(x, 3, [128, 128, 512], stage=3, block='a')
- x = identity_block(x, 3, [128, 128, 512], stage=3, block='b')
- x = identity_block(x, 3, [128, 128, 512], stage=3, block='c')
- x = identity_block(x, 3, [128, 128, 512], stage=3, block='d')
-
- x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a')
- x = identity_block(x, 3, [256, 256, 1024], stage=4, block='b')
- x = identity_block(x, 3, [256, 256, 1024], stage=4, block='c')
- x = identity_block(x, 3, [256, 256, 1024], stage=4, block='d')
- x = identity_block(x, 3, [256, 256, 1024], stage=4, block='e')
- x = identity_block(x, 3, [256, 256, 1024], stage=4, block='f')
-
- x = conv_block(x, 3, [512, 512, 2048], stage=5, block='a')
- x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b')
- x = identity_block(x, 3, [512, 512, 2048], stage=5, block='c')
-
- x = AveragePooling2D((7, 7), name='avg_pool')(x)
-
- if include_top:
- x = Flatten()(x)
- x = Dense(classes, activation='softmax', name='fc1000')(x)
- else:
- if pooling == 'avg':
- x = GlobalAveragePooling2D()(x)
- elif pooling == 'max':
- x = GlobalMaxPooling2D()(x)
-
- # Ensure that the model takes into account
- # any potential predecessors of `input_tensor`.
- if input_tensor is not None:
- inputs = get_source_inputs(input_tensor)
- else:
- inputs = img_input
- # Create model.
- model = Model(inputs, x, name='resnet50')
-
- # load weights
- if weights == 'imagenet':
- if include_top:
- weights_path = get_file(
- 'resnet50_weights_tf_dim_ordering_tf_kernels.h5',
- WEIGHTS_PATH,
- cache_subdir='models',
- md5_hash='a7b3fe01876f51b976af0dea6bc144eb')
- else:
- weights_path = get_file(
- 'resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5',
- WEIGHTS_PATH_NO_TOP,
- cache_subdir='models',
- md5_hash='a268eb855778b3df3c7506639542a6af')
- model.load_weights(weights_path)
- return model
diff --git a/tensorflow/contrib/keras/python/keras/applications/resnet50_test.py b/tensorflow/contrib/keras/python/keras/applications/resnet50_test.py
deleted file mode 100644
index 2b00170652..0000000000
--- a/tensorflow/contrib/keras/python/keras/applications/resnet50_test.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for ResNet50 application."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-class ResNet50Test(test.TestCase):
-
- def test_with_top(self):
- model = keras.applications.ResNet50(weights=None)
- self.assertEqual(model.output_shape, (None, 1000))
-
- def test_no_top(self):
- model = keras.applications.ResNet50(weights=None, include_top=False)
- self.assertEqual(model.output_shape, (None, None, None, 2048))
-
- def test_with_pooling(self):
- model = keras.applications.ResNet50(weights=None,
- include_top=False,
- pooling='avg')
- self.assertEqual(model.output_shape, (None, 2048))
-
- def test_weight_loading(self):
- with self.assertRaises(ValueError):
- keras.applications.ResNet50(weights='unknown',
- include_top=False)
-
- with self.assertRaises(ValueError):
- keras.applications.ResNet50(weights='imagenet',
- classes=2000)
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/applications/vgg16.py b/tensorflow/contrib/keras/python/keras/applications/vgg16.py
deleted file mode 100644
index c38ae2a984..0000000000
--- a/tensorflow/contrib/keras/python/keras/applications/vgg16.py
+++ /dev/null
@@ -1,212 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-# pylint: disable=invalid-name
-"""VGG16 model for Keras.
-
-# Reference
-
-- [Very Deep Convolutional Networks for Large-Scale Image
-Recognition](https://arxiv.org/abs/1409.1556)
-
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.applications.imagenet_utils import _obtain_input_shape
-from tensorflow.contrib.keras.python.keras.applications.imagenet_utils import decode_predictions # pylint: disable=unused-import
-from tensorflow.contrib.keras.python.keras.applications.imagenet_utils import preprocess_input # pylint: disable=unused-import
-from tensorflow.contrib.keras.python.keras.engine.topology import get_source_inputs
-from tensorflow.contrib.keras.python.keras.layers import Conv2D
-from tensorflow.contrib.keras.python.keras.layers import Dense
-from tensorflow.contrib.keras.python.keras.layers import Flatten
-from tensorflow.contrib.keras.python.keras.layers import GlobalAveragePooling2D
-from tensorflow.contrib.keras.python.keras.layers import GlobalMaxPooling2D
-from tensorflow.contrib.keras.python.keras.layers import Input
-from tensorflow.contrib.keras.python.keras.layers import MaxPooling2D
-from tensorflow.contrib.keras.python.keras.models import Model
-from tensorflow.contrib.keras.python.keras.utils import layer_utils
-from tensorflow.contrib.keras.python.keras.utils.data_utils import get_file
-
-
-WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels.h5'
-WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5'
-
-
-def VGG16(include_top=True,
- weights='imagenet',
- input_tensor=None,
- input_shape=None,
- pooling=None,
- classes=1000):
- """Instantiates the VGG16 architecture.
-
- Optionally loads weights pre-trained
- on ImageNet. Note that when using TensorFlow,
- for best performance you should set
- `image_data_format="channels_last"` in your Keras config
- at ~/.keras/keras.json.
-
- The model and the weights are compatible with both
- TensorFlow and Theano. The data format
- convention used by the model is the one
- specified in your Keras config file.
-
- Arguments:
- include_top: whether to include the 3 fully-connected
- layers at the top of the network.
- weights: one of `None` (random initialization)
- or "imagenet" (pre-training on ImageNet).
- input_tensor: optional Keras tensor (i.e. output of `layers.Input()`)
- to use as image input for the model.
- input_shape: optional shape tuple, only to be specified
- if `include_top` is False (otherwise the input shape
- has to be `(224, 224, 3)` (with `channels_last` data format)
- or `(3, 224, 224)` (with `channels_first` data format).
- It should have exactly 3 input channels,
- and width and height should be no smaller than 48.
- E.g. `(200, 200, 3)` would be one valid value.
- pooling: Optional pooling mode for feature extraction
- when `include_top` is `False`.
- - `None` means that the output of the model will be
- the 4D tensor output of the
- last convolutional layer.
- - `avg` means that global average pooling
- will be applied to the output of the
- last convolutional layer, and thus
- the output of the model will be a 2D tensor.
- - `max` means that global max pooling will
- be applied.
- classes: optional number of classes to classify images
- into, only to be specified if `include_top` is True, and
- if no `weights` argument is specified.
-
- Returns:
- A Keras model instance.
-
- Raises:
- ValueError: in case of invalid argument for `weights`,
- or invalid input shape.
- """
- if weights not in {'imagenet', None}:
- raise ValueError('The `weights` argument should be either '
- '`None` (random initialization) or `imagenet` '
- '(pre-training on ImageNet).')
-
- if weights == 'imagenet' and include_top and classes != 1000:
- raise ValueError('If using `weights` as imagenet with `include_top`'
- ' as true, `classes` should be 1000')
- # Determine proper input shape
- input_shape = _obtain_input_shape(
- input_shape,
- default_size=224,
- min_size=48,
- data_format=K.image_data_format(),
- require_flatten=include_top,
- weights=weights)
-
- if input_tensor is None:
- img_input = Input(shape=input_shape)
- else:
- img_input = Input(tensor=input_tensor, shape=input_shape)
-
- # Block 1
- x = Conv2D(
- 64, (3, 3), activation='relu', padding='same',
- name='block1_conv1')(img_input)
- x = Conv2D(
- 64, (3, 3), activation='relu', padding='same', name='block1_conv2')(x)
- x = MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(x)
-
- # Block 2
- x = Conv2D(
- 128, (3, 3), activation='relu', padding='same', name='block2_conv1')(x)
- x = Conv2D(
- 128, (3, 3), activation='relu', padding='same', name='block2_conv2')(x)
- x = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x)
-
- # Block 3
- x = Conv2D(
- 256, (3, 3), activation='relu', padding='same', name='block3_conv1')(x)
- x = Conv2D(
- 256, (3, 3), activation='relu', padding='same', name='block3_conv2')(x)
- x = Conv2D(
- 256, (3, 3), activation='relu', padding='same', name='block3_conv3')(x)
- x = MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x)
-
- # Block 4
- x = Conv2D(
- 512, (3, 3), activation='relu', padding='same', name='block4_conv1')(x)
- x = Conv2D(
- 512, (3, 3), activation='relu', padding='same', name='block4_conv2')(x)
- x = Conv2D(
- 512, (3, 3), activation='relu', padding='same', name='block4_conv3')(x)
- x = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x)
-
- # Block 5
- x = Conv2D(
- 512, (3, 3), activation='relu', padding='same', name='block5_conv1')(x)
- x = Conv2D(
- 512, (3, 3), activation='relu', padding='same', name='block5_conv2')(x)
- x = Conv2D(
- 512, (3, 3), activation='relu', padding='same', name='block5_conv3')(x)
- x = MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x)
-
- if include_top:
- # Classification block
- x = Flatten(name='flatten')(x)
- x = Dense(4096, activation='relu', name='fc1')(x)
- x = Dense(4096, activation='relu', name='fc2')(x)
- x = Dense(classes, activation='softmax', name='predictions')(x)
- else:
- if pooling == 'avg':
- x = GlobalAveragePooling2D()(x)
- elif pooling == 'max':
- x = GlobalMaxPooling2D()(x)
-
- # Ensure that the model takes into account
- # any potential predecessors of `input_tensor`.
- if input_tensor is not None:
- inputs = get_source_inputs(input_tensor)
- else:
- inputs = img_input
- # Create model.
- model = Model(inputs, x, name='vgg16')
-
- # load weights
- if weights == 'imagenet':
- if include_top:
- weights_path = get_file(
- 'vgg16_weights_tf_dim_ordering_tf_kernels.h5',
- WEIGHTS_PATH,
- cache_subdir='models')
- else:
- weights_path = get_file(
- 'vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5',
- WEIGHTS_PATH_NO_TOP,
- cache_subdir='models')
- model.load_weights(weights_path)
- if K.backend() == 'theano':
- layer_utils.convert_all_kernels_in_model(model)
-
- if K.image_data_format() == 'channels_first':
- if include_top:
- maxpool = model.get_layer(name='block5_pool')
- shape = maxpool.output_shape[1:]
- dense = model.get_layer(name='fc1')
- layer_utils.convert_dense_weights_data_format(dense, shape,
- 'channels_first')
- return model
diff --git a/tensorflow/contrib/keras/python/keras/applications/vgg16_test.py b/tensorflow/contrib/keras/python/keras/applications/vgg16_test.py
deleted file mode 100644
index 4ba5dabd5a..0000000000
--- a/tensorflow/contrib/keras/python/keras/applications/vgg16_test.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for VGG16 application."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-class VGG16Test(test.TestCase):
-
- def test_with_top(self):
- model = keras.applications.VGG16(weights=None)
- self.assertEqual(model.output_shape, (None, 1000))
-
- def test_no_top(self):
- model = keras.applications.VGG16(weights=None, include_top=False)
- self.assertEqual(model.output_shape, (None, None, None, 512))
-
- def test_with_pooling(self):
- model = keras.applications.VGG16(weights=None,
- include_top=False,
- pooling='avg')
- self.assertEqual(model.output_shape, (None, 512))
-
- def test_weight_loading(self):
- with self.assertRaises(ValueError):
- keras.applications.VGG16(weights='unknown',
- include_top=False)
- with self.assertRaises(ValueError):
- keras.applications.VGG16(weights='imagenet',
- classes=2000)
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/applications/vgg19.py b/tensorflow/contrib/keras/python/keras/applications/vgg19.py
deleted file mode 100644
index ee67efaa92..0000000000
--- a/tensorflow/contrib/keras/python/keras/applications/vgg19.py
+++ /dev/null
@@ -1,218 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-# pylint: disable=invalid-name
-"""VGG19 model for Keras.
-
-# Reference
-
-- [Very Deep Convolutional Networks for Large-Scale Image
-Recognition](https://arxiv.org/abs/1409.1556)
-
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.applications.imagenet_utils import _obtain_input_shape
-from tensorflow.contrib.keras.python.keras.applications.imagenet_utils import decode_predictions # pylint: disable=unused-import
-from tensorflow.contrib.keras.python.keras.applications.imagenet_utils import preprocess_input # pylint: disable=unused-import
-from tensorflow.contrib.keras.python.keras.engine.topology import get_source_inputs
-from tensorflow.contrib.keras.python.keras.layers import Conv2D
-from tensorflow.contrib.keras.python.keras.layers import Dense
-from tensorflow.contrib.keras.python.keras.layers import Flatten
-from tensorflow.contrib.keras.python.keras.layers import GlobalAveragePooling2D
-from tensorflow.contrib.keras.python.keras.layers import GlobalMaxPooling2D
-from tensorflow.contrib.keras.python.keras.layers import Input
-from tensorflow.contrib.keras.python.keras.layers import MaxPooling2D
-from tensorflow.contrib.keras.python.keras.models import Model
-from tensorflow.contrib.keras.python.keras.utils import layer_utils
-from tensorflow.contrib.keras.python.keras.utils.data_utils import get_file
-
-
-WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg19_weights_tf_dim_ordering_tf_kernels.h5'
-WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg19_weights_tf_dim_ordering_tf_kernels_notop.h5'
-
-
-def VGG19(include_top=True,
- weights='imagenet',
- input_tensor=None,
- input_shape=None,
- pooling=None,
- classes=1000):
- """Instantiates the VGG19 architecture.
-
- Optionally loads weights pre-trained
- on ImageNet. Note that when using TensorFlow,
- for best performance you should set
- `image_data_format="channels_last"` in your Keras config
- at ~/.keras/keras.json.
-
- The model and the weights are compatible with both
- TensorFlow and Theano. The data format
- convention used by the model is the one
- specified in your Keras config file.
-
- Arguments:
- include_top: whether to include the 3 fully-connected
- layers at the top of the network.
- weights: one of `None` (random initialization)
- or "imagenet" (pre-training on ImageNet).
- input_tensor: optional Keras tensor (i.e. output of `layers.Input()`)
- to use as image input for the model.
- input_shape: optional shape tuple, only to be specified
- if `include_top` is False (otherwise the input shape
- has to be `(224, 224, 3)` (with `channels_last` data format)
- or `(3, 224, 224)` (with `channels_first` data format).
- It should have exactly 3 input channels,
- and width and height should be no smaller than 48.
- E.g. `(200, 200, 3)` would be one valid value.
- pooling: Optional pooling mode for feature extraction
- when `include_top` is `False`.
- - `None` means that the output of the model will be
- the 4D tensor output of the
- last convolutional layer.
- - `avg` means that global average pooling
- will be applied to the output of the
- last convolutional layer, and thus
- the output of the model will be a 2D tensor.
- - `max` means that global max pooling will
- be applied.
- classes: optional number of classes to classify images
- into, only to be specified if `include_top` is True, and
- if no `weights` argument is specified.
-
- Returns:
- A Keras model instance.
-
- Raises:
- ValueError: in case of invalid argument for `weights`,
- or invalid input shape.
- """
- if weights not in {'imagenet', None}:
- raise ValueError('The `weights` argument should be either '
- '`None` (random initialization) or `imagenet` '
- '(pre-training on ImageNet).')
-
- if weights == 'imagenet' and include_top and classes != 1000:
- raise ValueError('If using `weights` as imagenet with `include_top`'
- ' as true, `classes` should be 1000')
- # Determine proper input shape
- input_shape = _obtain_input_shape(
- input_shape,
- default_size=224,
- min_size=48,
- data_format=K.image_data_format(),
- require_flatten=include_top,
- weights=weights)
-
- if input_tensor is None:
- img_input = Input(shape=input_shape)
- else:
- img_input = Input(tensor=input_tensor, shape=input_shape)
-
- # Block 1
- x = Conv2D(
- 64, (3, 3), activation='relu', padding='same',
- name='block1_conv1')(img_input)
- x = Conv2D(
- 64, (3, 3), activation='relu', padding='same', name='block1_conv2')(x)
- x = MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(x)
-
- # Block 2
- x = Conv2D(
- 128, (3, 3), activation='relu', padding='same', name='block2_conv1')(x)
- x = Conv2D(
- 128, (3, 3), activation='relu', padding='same', name='block2_conv2')(x)
- x = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x)
-
- # Block 3
- x = Conv2D(
- 256, (3, 3), activation='relu', padding='same', name='block3_conv1')(x)
- x = Conv2D(
- 256, (3, 3), activation='relu', padding='same', name='block3_conv2')(x)
- x = Conv2D(
- 256, (3, 3), activation='relu', padding='same', name='block3_conv3')(x)
- x = Conv2D(
- 256, (3, 3), activation='relu', padding='same', name='block3_conv4')(x)
- x = MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x)
-
- # Block 4
- x = Conv2D(
- 512, (3, 3), activation='relu', padding='same', name='block4_conv1')(x)
- x = Conv2D(
- 512, (3, 3), activation='relu', padding='same', name='block4_conv2')(x)
- x = Conv2D(
- 512, (3, 3), activation='relu', padding='same', name='block4_conv3')(x)
- x = Conv2D(
- 512, (3, 3), activation='relu', padding='same', name='block4_conv4')(x)
- x = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x)
-
- # Block 5
- x = Conv2D(
- 512, (3, 3), activation='relu', padding='same', name='block5_conv1')(x)
- x = Conv2D(
- 512, (3, 3), activation='relu', padding='same', name='block5_conv2')(x)
- x = Conv2D(
- 512, (3, 3), activation='relu', padding='same', name='block5_conv3')(x)
- x = Conv2D(
- 512, (3, 3), activation='relu', padding='same', name='block5_conv4')(x)
- x = MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x)
-
- if include_top:
- # Classification block
- x = Flatten(name='flatten')(x)
- x = Dense(4096, activation='relu', name='fc1')(x)
- x = Dense(4096, activation='relu', name='fc2')(x)
- x = Dense(classes, activation='softmax', name='predictions')(x)
- else:
- if pooling == 'avg':
- x = GlobalAveragePooling2D()(x)
- elif pooling == 'max':
- x = GlobalMaxPooling2D()(x)
-
- # Ensure that the model takes into account
- # any potential predecessors of `input_tensor`.
- if input_tensor is not None:
- inputs = get_source_inputs(input_tensor)
- else:
- inputs = img_input
- # Create model.
- model = Model(inputs, x, name='vgg19')
-
- # load weights
- if weights == 'imagenet':
- if include_top:
- weights_path = get_file(
- 'vgg19_weights_tf_dim_ordering_tf_kernels.h5',
- WEIGHTS_PATH,
- cache_subdir='models')
- else:
- weights_path = get_file(
- 'vgg19_weights_tf_dim_ordering_tf_kernels_notop.h5',
- WEIGHTS_PATH_NO_TOP,
- cache_subdir='models')
- model.load_weights(weights_path)
- if K.backend() == 'theano':
- layer_utils.convert_all_kernels_in_model(model)
-
- if K.image_data_format() == 'channels_first':
- if include_top:
- maxpool = model.get_layer(name='block5_pool')
- shape = maxpool.output_shape[1:]
- dense = model.get_layer(name='fc1')
- layer_utils.convert_dense_weights_data_format(dense, shape,
- 'channels_first')
- return model
diff --git a/tensorflow/contrib/keras/python/keras/applications/vgg19_test.py b/tensorflow/contrib/keras/python/keras/applications/vgg19_test.py
deleted file mode 100644
index 604d4bb2d8..0000000000
--- a/tensorflow/contrib/keras/python/keras/applications/vgg19_test.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for VGG19 application."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-class VGG19Test(test.TestCase):
-
- def test_with_top(self):
- model = keras.applications.VGG19(weights=None)
- self.assertEqual(model.output_shape, (None, 1000))
-
- def test_no_top(self):
- model = keras.applications.VGG19(weights=None, include_top=False)
- self.assertEqual(model.output_shape, (None, None, None, 512))
-
- def test_with_pooling(self):
- model = keras.applications.VGG19(weights=None,
- include_top=False,
- pooling='avg')
- self.assertEqual(model.output_shape, (None, 512))
-
- def test_weight_loading(self):
- with self.assertRaises(ValueError):
- keras.applications.VGG19(weights='unknown',
- include_top=False)
- with self.assertRaises(ValueError):
- keras.applications.VGG19(weights='imagenet',
- classes=2000)
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/applications/xception.py b/tensorflow/contrib/keras/python/keras/applications/xception.py
deleted file mode 100644
index 7db7e9a9d6..0000000000
--- a/tensorflow/contrib/keras/python/keras/applications/xception.py
+++ /dev/null
@@ -1,307 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-# pylint: disable=invalid-name
-"""Xception V1 model for Keras.
-
-On ImageNet, this model gets to a top-1 validation accuracy of 0.790
-and a top-5 validation accuracy of 0.945.
-
-Do note that the input image format for this model is different than for
-the VGG16 and ResNet models (299x299 instead of 224x224),
-and that the input preprocessing function
-is also different (same as Inception V3).
-
-Also do note that this model is only available for the TensorFlow backend,
-due to its reliance on `SeparableConvolution` layers.
-
-# Reference
-
-- [Xception: Deep Learning with Depthwise Separable
-Convolutions](https://arxiv.org/abs/1610.02357)
-
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras import layers
-from tensorflow.contrib.keras.python.keras.applications.imagenet_utils import _obtain_input_shape
-from tensorflow.contrib.keras.python.keras.applications.imagenet_utils import decode_predictions # pylint: disable=unused-import
-from tensorflow.contrib.keras.python.keras.engine.topology import get_source_inputs
-from tensorflow.contrib.keras.python.keras.layers import Activation
-from tensorflow.contrib.keras.python.keras.layers import BatchNormalization
-from tensorflow.contrib.keras.python.keras.layers import Conv2D
-from tensorflow.contrib.keras.python.keras.layers import Dense
-from tensorflow.contrib.keras.python.keras.layers import GlobalAveragePooling2D
-from tensorflow.contrib.keras.python.keras.layers import GlobalMaxPooling2D
-from tensorflow.contrib.keras.python.keras.layers import Input
-from tensorflow.contrib.keras.python.keras.layers import MaxPooling2D
-from tensorflow.contrib.keras.python.keras.layers import SeparableConv2D
-from tensorflow.contrib.keras.python.keras.models import Model
-from tensorflow.contrib.keras.python.keras.utils.data_utils import get_file
-from tensorflow.python.platform import tf_logging as logging
-
-
-TF_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.4/xception_weights_tf_dim_ordering_tf_kernels.h5'
-TF_WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.4/xception_weights_tf_dim_ordering_tf_kernels_notop.h5'
-
-
-def Xception(include_top=True,
- weights='imagenet',
- input_tensor=None,
- input_shape=None,
- pooling=None,
- classes=1000):
- """Instantiates the Xception architecture.
-
- Optionally loads weights pre-trained
- on ImageNet. This model is available for TensorFlow only,
- and can only be used with inputs following the TensorFlow
- data format `(width, height, channels)`.
- You should set `image_data_format="channels_last"` in your Keras config
- located at ~/.keras/keras.json.
-
- Note that the default input image size for this model is 299x299.
-
- Arguments:
- include_top: whether to include the fully-connected
- layer at the top of the network.
- weights: one of `None` (random initialization)
- or "imagenet" (pre-training on ImageNet).
- input_tensor: optional Keras tensor (i.e. output of `layers.Input()`)
- to use as image input for the model.
- input_shape: optional shape tuple, only to be specified
- if `include_top` is False (otherwise the input shape
- has to be `(299, 299, 3)`.
- It should have exactly 3 input channels,
- and width and height should be no smaller than 71.
- E.g. `(150, 150, 3)` would be one valid value.
- pooling: Optional pooling mode for feature extraction
- when `include_top` is `False`.
- - `None` means that the output of the model will be
- the 4D tensor output of the
- last convolutional layer.
- - `avg` means that global average pooling
- will be applied to the output of the
- last convolutional layer, and thus
- the output of the model will be a 2D tensor.
- - `max` means that global max pooling will
- be applied.
- classes: optional number of classes to classify images
- into, only to be specified if `include_top` is True, and
- if no `weights` argument is specified.
-
- Returns:
- A Keras model instance.
-
- Raises:
- ValueError: in case of invalid argument for `weights`,
- or invalid input shape.
- RuntimeError: If attempting to run this model with a
- backend that does not support separable convolutions.
- """
- if weights not in {'imagenet', None}:
- raise ValueError('The `weights` argument should be either '
- '`None` (random initialization) or `imagenet` '
- '(pre-training on ImageNet).')
-
- if weights == 'imagenet' and include_top and classes != 1000:
- raise ValueError('If using `weights` as imagenet with `include_top`'
- ' as true, `classes` should be 1000')
-
- if K.backend() != 'tensorflow':
- raise RuntimeError('The Xception model is only available with '
- 'the TensorFlow backend.')
- if K.image_data_format() != 'channels_last':
- logging.warning(
- 'The Xception model is only available for the '
- 'input data format "channels_last" '
- '(width, height, channels). '
- 'However your settings specify the default '
- 'data format "channels_first" (channels, width, height). '
- 'You should set `image_data_format="channels_last"` in your Keras '
- 'config located at ~/.keras/keras.json. '
- 'The model being returned right now will expect inputs '
- 'to follow the "channels_last" data format.')
- K.set_image_data_format('channels_last')
- old_data_format = 'channels_first'
- else:
- old_data_format = None
-
- # Determine proper input shape
- input_shape = _obtain_input_shape(
- input_shape,
- default_size=299,
- min_size=71,
- data_format=K.image_data_format(),
- require_flatten=False,
- weights=weights)
-
- if input_tensor is None:
- img_input = Input(shape=input_shape)
- else:
- img_input = Input(tensor=input_tensor, shape=input_shape)
-
- x = Conv2D(
- 32, (3, 3), strides=(2, 2), use_bias=False,
- name='block1_conv1')(img_input)
- x = BatchNormalization(name='block1_conv1_bn')(x)
- x = Activation('relu', name='block1_conv1_act')(x)
- x = Conv2D(64, (3, 3), use_bias=False, name='block1_conv2')(x)
- x = BatchNormalization(name='block1_conv2_bn')(x)
- x = Activation('relu', name='block1_conv2_act')(x)
-
- residual = Conv2D(
- 128, (1, 1), strides=(2, 2), padding='same', use_bias=False)(x)
- residual = BatchNormalization()(residual)
-
- x = SeparableConv2D(
- 128, (3, 3), padding='same', use_bias=False, name='block2_sepconv1')(x)
- x = BatchNormalization(name='block2_sepconv1_bn')(x)
- x = Activation('relu', name='block2_sepconv2_act')(x)
- x = SeparableConv2D(
- 128, (3, 3), padding='same', use_bias=False, name='block2_sepconv2')(x)
- x = BatchNormalization(name='block2_sepconv2_bn')(x)
-
- x = MaxPooling2D(
- (3, 3), strides=(2, 2), padding='same', name='block2_pool')(x)
- x = layers.add([x, residual])
-
- residual = Conv2D(
- 256, (1, 1), strides=(2, 2), padding='same', use_bias=False)(x)
- residual = BatchNormalization()(residual)
-
- x = Activation('relu', name='block3_sepconv1_act')(x)
- x = SeparableConv2D(
- 256, (3, 3), padding='same', use_bias=False, name='block3_sepconv1')(x)
- x = BatchNormalization(name='block3_sepconv1_bn')(x)
- x = Activation('relu', name='block3_sepconv2_act')(x)
- x = SeparableConv2D(
- 256, (3, 3), padding='same', use_bias=False, name='block3_sepconv2')(x)
- x = BatchNormalization(name='block3_sepconv2_bn')(x)
-
- x = MaxPooling2D(
- (3, 3), strides=(2, 2), padding='same', name='block3_pool')(x)
- x = layers.add([x, residual])
-
- residual = Conv2D(
- 728, (1, 1), strides=(2, 2), padding='same', use_bias=False)(x)
- residual = BatchNormalization()(residual)
-
- x = Activation('relu', name='block4_sepconv1_act')(x)
- x = SeparableConv2D(
- 728, (3, 3), padding='same', use_bias=False, name='block4_sepconv1')(x)
- x = BatchNormalization(name='block4_sepconv1_bn')(x)
- x = Activation('relu', name='block4_sepconv2_act')(x)
- x = SeparableConv2D(
- 728, (3, 3), padding='same', use_bias=False, name='block4_sepconv2')(x)
- x = BatchNormalization(name='block4_sepconv2_bn')(x)
-
- x = MaxPooling2D(
- (3, 3), strides=(2, 2), padding='same', name='block4_pool')(x)
- x = layers.add([x, residual])
-
- for i in range(8):
- residual = x
- prefix = 'block' + str(i + 5)
-
- x = Activation('relu', name=prefix + '_sepconv1_act')(x)
- x = SeparableConv2D(
- 728, (3, 3), padding='same', use_bias=False,
- name=prefix + '_sepconv1')(x)
- x = BatchNormalization(name=prefix + '_sepconv1_bn')(x)
- x = Activation('relu', name=prefix + '_sepconv2_act')(x)
- x = SeparableConv2D(
- 728, (3, 3), padding='same', use_bias=False,
- name=prefix + '_sepconv2')(x)
- x = BatchNormalization(name=prefix + '_sepconv2_bn')(x)
- x = Activation('relu', name=prefix + '_sepconv3_act')(x)
- x = SeparableConv2D(
- 728, (3, 3), padding='same', use_bias=False,
- name=prefix + '_sepconv3')(x)
- x = BatchNormalization(name=prefix + '_sepconv3_bn')(x)
-
- x = layers.add([x, residual])
-
- residual = Conv2D(
- 1024, (1, 1), strides=(2, 2), padding='same', use_bias=False)(x)
- residual = BatchNormalization()(residual)
-
- x = Activation('relu', name='block13_sepconv1_act')(x)
- x = SeparableConv2D(
- 728, (3, 3), padding='same', use_bias=False, name='block13_sepconv1')(x)
- x = BatchNormalization(name='block13_sepconv1_bn')(x)
- x = Activation('relu', name='block13_sepconv2_act')(x)
- x = SeparableConv2D(
- 1024, (3, 3), padding='same', use_bias=False, name='block13_sepconv2')(x)
- x = BatchNormalization(name='block13_sepconv2_bn')(x)
-
- x = MaxPooling2D(
- (3, 3), strides=(2, 2), padding='same', name='block13_pool')(x)
- x = layers.add([x, residual])
-
- x = SeparableConv2D(
- 1536, (3, 3), padding='same', use_bias=False, name='block14_sepconv1')(x)
- x = BatchNormalization(name='block14_sepconv1_bn')(x)
- x = Activation('relu', name='block14_sepconv1_act')(x)
-
- x = SeparableConv2D(
- 2048, (3, 3), padding='same', use_bias=False, name='block14_sepconv2')(x)
- x = BatchNormalization(name='block14_sepconv2_bn')(x)
- x = Activation('relu', name='block14_sepconv2_act')(x)
-
- if include_top:
- x = GlobalAveragePooling2D(name='avg_pool')(x)
- x = Dense(classes, activation='softmax', name='predictions')(x)
- else:
- if pooling == 'avg':
- x = GlobalAveragePooling2D()(x)
- elif pooling == 'max':
- x = GlobalMaxPooling2D()(x)
-
- # Ensure that the model takes into account
- # any potential predecessors of `input_tensor`.
- if input_tensor is not None:
- inputs = get_source_inputs(input_tensor)
- else:
- inputs = img_input
- # Create model.
- model = Model(inputs, x, name='xception')
-
- # load weights
- if weights == 'imagenet':
- if include_top:
- weights_path = get_file(
- 'xception_weights_tf_dim_ordering_tf_kernels.h5',
- TF_WEIGHTS_PATH,
- cache_subdir='models')
- else:
- weights_path = get_file(
- 'xception_weights_tf_dim_ordering_tf_kernels_notop.h5',
- TF_WEIGHTS_PATH_NO_TOP,
- cache_subdir='models')
- model.load_weights(weights_path)
-
- if old_data_format:
- K.set_image_data_format(old_data_format)
- return model
-
-
-def preprocess_input(x):
- x /= 255.
- x -= 0.5
- x *= 2.
- return x
diff --git a/tensorflow/contrib/keras/python/keras/applications/xception_test.py b/tensorflow/contrib/keras/python/keras/applications/xception_test.py
deleted file mode 100644
index a941514c3e..0000000000
--- a/tensorflow/contrib/keras/python/keras/applications/xception_test.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for Xception application."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-class XceptionTest(test.TestCase):
-
- def test_with_top(self):
- model = keras.applications.Xception(weights=None)
- self.assertEqual(model.output_shape, (None, 1000))
-
- def test_no_top(self):
- model = keras.applications.Xception(weights=None, include_top=False)
- self.assertEqual(model.output_shape, (None, None, None, 2048))
-
- def test_with_pooling(self):
- model = keras.applications.Xception(weights=None,
- include_top=False,
- pooling='avg')
- self.assertEqual(model.output_shape, (None, 2048))
-
- def test_weight_loading(self):
- with self.assertRaises(ValueError):
- keras.applications.Xception(weights='unknown',
- include_top=False)
- with self.assertRaises(ValueError):
- keras.applications.Xception(weights='imagenet',
- classes=2000)
-
- def test_preprocess_input(self):
- x = np.random.uniform(0, 255, (2, 300, 200, 3))
- out1 = keras.applications.xception.preprocess_input(x)
- self.assertAllClose(np.mean(out1), 0., atol=0.1)
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/backend.py b/tensorflow/contrib/keras/python/keras/backend.py
deleted file mode 100644
index 76704d5d3d..0000000000
--- a/tensorflow/contrib/keras/python/keras/backend.py
+++ /dev/null
@@ -1,4074 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-# pylint: disable=protected-access
-# pylint: disable=redefined-outer-name
-# pylint: disable=redefined-builtin
-"""Keras backend API.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import collections
-import json
-import os
-
-import numpy as np
-
-from tensorflow.core.protobuf import config_pb2
-from tensorflow.python.client import session as session_module
-from tensorflow.python.framework import constant_op
-from tensorflow.python.framework import dtypes as dtypes_module
-from tensorflow.python.framework import ops
-from tensorflow.python.framework import sparse_tensor
-from tensorflow.python.layers import base as tf_base_layers
-from tensorflow.python.ops import array_ops
-from tensorflow.python.ops import clip_ops
-from tensorflow.python.ops import control_flow_ops
-from tensorflow.python.ops import ctc_ops as ctc
-from tensorflow.python.ops import functional_ops
-from tensorflow.python.ops import gradients as gradients_module
-from tensorflow.python.ops import image_ops
-from tensorflow.python.ops import init_ops
-from tensorflow.python.ops import logging_ops
-from tensorflow.python.ops import math_ops
-from tensorflow.python.ops import nn
-from tensorflow.python.ops import random_ops
-from tensorflow.python.ops import sparse_ops
-from tensorflow.python.ops import state_ops
-from tensorflow.python.ops import tensor_array_grad # pylint: disable=unused-import
-from tensorflow.python.ops import tensor_array_ops
-from tensorflow.python.ops import variables as variables_module
-from tensorflow.python.training import moving_averages
-from tensorflow.python.util import tf_inspect
-
-
-py_all = all
-py_sum = sum
-
-# INTERNAL UTILS
-
-# This is the default internal TF session used by Keras.
-# It can be set manually via `set_session(sess)`.
-_SESSION = None
-
-# This dictionary holds a mapping {graph: learning_phase}.
-# A learning phase is a bool tensor used to run Keras models in
-# either train mode (learning_phase == 1) or test mode (learning_phase == 0).
-_GRAPH_LEARNING_PHASES = {}
-
-# This dictionary holds a mapping {graph: UID_DICT}.
-# each UID_DICT is a dictionary mapping name prefixes to a current index,
-# used for generatic graph-specific string UIDs
-# for various names (e.g. layer names).
-_GRAPH_UID_DICTS = {}
-
-# This boolean flag can be set to True to leave variable initialization
-# up to the user.
-# Change its value via `manual_variable_initialization(value)`.
-_MANUAL_VAR_INIT = False
-
-# The type of float to use throughout a session.
-_FLOATX = 'float32'
-
-# Epsilon fuzz factor used throughout the codebase.
-_EPSILON = 10e-8
-
-# Default image data format, one of "channels_last", "channels_first".
-_IMAGE_DATA_FORMAT = 'channels_last'
-
-
-def backend():
- """Publicly accessible method for determining the current backend.
-
- Only exists for API compatibility with multi-backend Keras.
-
- Returns:
- The string "tensorflow".
- """
- return 'tensorflow'
-
-
-def epsilon():
- """Returns the value of the fuzz factor used in numeric expressions.
-
- Returns:
- A float.
-
- Example:
- ```python
- >>> keras.backend.epsilon()
- 1e-08
- ```
- """
- return _EPSILON
-
-
-def set_epsilon(value):
- """Sets the value of the fuzz factor used in numeric expressions.
-
- Arguments:
- value: float. New value of epsilon.
-
- Example:
- ```python
- >>> from keras import backend as K
- >>> K.epsilon()
- 1e-08
- >>> K.set_epsilon(1e-05)
- >>> K.epsilon()
- 1e-05
- ```
- """
- global _EPSILON
- _EPSILON = value
-
-
-def floatx():
- """Returns the default float type, as a string.
-
- E.g. 'float16', 'float32', 'float64'.
-
- Returns:
- String, the current default float type.
-
- Example:
- ```python
- >>> keras.backend.floatx()
- 'float32'
- ```
- """
- return _FLOATX
-
-
-def set_floatx(value):
- """Sets the default float type.
-
- Arguments:
- value: String; 'float16', 'float32', or 'float64'.
-
- Example:
- ```python
- >>> from keras import backend as K
- >>> K.floatx()
- 'float32'
- >>> K.set_floatx('float16')
- >>> K.floatx()
- 'float16'
- ```
-
- Raises:
- ValueError: In case of invalid value.
- """
- global _FLOATX
- if value not in {'float16', 'float32', 'float64'}:
- raise ValueError('Unknown floatx type: ' + str(value))
- _FLOATX = str(value)
-
-
-def cast_to_floatx(x):
- """Cast a Numpy array to the default Keras float type.
-
- Arguments:
- x: Numpy array.
-
- Returns:
- The same Numpy array, cast to its new type.
-
- Example:
- ```python
- >>> from keras import backend as K
- >>> K.floatx()
- 'float32'
- >>> arr = numpy.array([1.0, 2.0], dtype='float64')
- >>> arr.dtype
- dtype('float64')
- >>> new_arr = K.cast_to_floatx(arr)
- >>> new_arr
- array([ 1., 2.], dtype=float32)
- >>> new_arr.dtype
- dtype('float32')
- ```
- """
- return np.asarray(x, dtype=_FLOATX)
-
-
-def image_data_format():
- """Returns the default image data format convention.
-
- Returns:
- A string, either `'channels_first'` or `'channels_last'`
-
- Example:
- ```python
- >>> keras.backend.image_data_format()
- 'channels_first'
- ```
- """
- return _IMAGE_DATA_FORMAT
-
-
-def set_image_data_format(data_format):
- """Sets the value of the image data format convention.
-
- Arguments:
- data_format: string. `'channels_first'` or `'channels_last'`.
-
- Example:
- ```python
- >>> from keras import backend as K
- >>> K.image_data_format()
- 'channels_first'
- >>> K.set_image_data_format('channels_last')
- >>> K.image_data_format()
- 'channels_last'
- ```
-
- Raises:
- ValueError: In case of invalid `data_format` value.
- """
- global _IMAGE_DATA_FORMAT
- if data_format not in {'channels_last', 'channels_first'}:
- raise ValueError('Unknown data_format:', data_format)
- _IMAGE_DATA_FORMAT = str(data_format)
-
-
-def get_uid(prefix=''):
- """Associates a string prefix with an integer counter in a TensorFlow graph.
-
- Arguments:
- prefix: String prefix to index.
-
- Returns:
- Unique integer ID.
-
- Example:
-
- ```
- >>> get_uid('dense')
- 1
- >>> get_uid('dense')
- 2
- ```
- """
- graph = ops.get_default_graph()
- if graph not in tf_base_layers.PER_GRAPH_LAYER_NAME_UIDS:
- tf_base_layers.PER_GRAPH_LAYER_NAME_UIDS[graph] = collections.defaultdict(
- int)
- layer_name_uids = tf_base_layers.PER_GRAPH_LAYER_NAME_UIDS[graph]
- layer_name_uids[prefix] += 1
- return layer_name_uids[prefix]
-
-
-def reset_uids():
- per_graph_layer_name_uids = tf_base_layers.PER_GRAPH_LAYER_NAME_UIDS
- keys = list(per_graph_layer_name_uids.keys())
- for key in keys:
- del per_graph_layer_name_uids[key]
-
-
-def clear_session():
- """Destroys the current TF graph and creates a new one.
-
- Useful to avoid clutter from old models / layers.
- """
- global _SESSION
- global _GRAPH_LEARNING_PHASES # pylint: disable=global-variable-not-assigned
- ops.reset_default_graph()
- reset_uids()
- _SESSION = None
- phase = array_ops.placeholder(dtype='bool', name='keras_learning_phase')
- _GRAPH_LEARNING_PHASES = {}
- _GRAPH_LEARNING_PHASES[ops.get_default_graph()] = phase
-
-
-def manual_variable_initialization(value):
- """Sets the manual variable initialization flag.
-
- This boolean flag determines whether
- variables should be initialized
- as they are instantiated (default), or if
- the user should handle the initialization
- (e.g. via `tf.initialize_all_variables()`).
-
- Arguments:
- value: Python boolean.
- """
- global _MANUAL_VAR_INIT
- _MANUAL_VAR_INIT = value
-
-
-def learning_phase():
- """Returns the learning phase flag.
-
- The learning phase flag is a bool tensor (0 = test, 1 = train)
- to be passed as input to any Keras function
- that uses a different behavior at train time and test time.
-
- Returns:
- Learning phase (scalar integer tensor or Python integer).
- """
- graph = ops.get_default_graph()
- if graph not in _GRAPH_LEARNING_PHASES:
- phase = array_ops.placeholder(dtype='bool', name='keras_learning_phase')
- _GRAPH_LEARNING_PHASES[graph] = phase
- return _GRAPH_LEARNING_PHASES[graph]
-
-
-def set_learning_phase(value):
- """Sets the learning phase to a fixed value.
-
- Arguments:
- value: Learning phase value, either 0 or 1 (integers).
-
- Raises:
- ValueError: if `value` is neither `0` nor `1`.
- """
- global _GRAPH_LEARNING_PHASES # pylint: disable=global-variable-not-assigned
- if value not in {0, 1}:
- raise ValueError('Expected learning phase to be ' '0 or 1.')
- _GRAPH_LEARNING_PHASES[ops.get_default_graph()] = value
-
-
-def get_session():
- """Returns the TF session to be used by the backend.
-
- If a default TensorFlow session is available, we will return it.
-
- Else, we will return the global Keras session.
-
- If no global Keras session exists at this point:
- we will create a new global session.
-
- Note that you can manually set the global session
- via `K.set_session(sess)`.
-
- Returns:
- A TensorFlow session.
- """
- global _SESSION
- if ops.get_default_session() is not None:
- session = ops.get_default_session()
- else:
- if _SESSION is None:
- if not os.environ.get('OMP_NUM_THREADS'):
- config = config_pb2.ConfigProto(allow_soft_placement=True)
- else:
- num_thread = int(os.environ.get('OMP_NUM_THREADS'))
- config = config_pb2.ConfigProto(
- intra_op_parallelism_threads=num_thread, allow_soft_placement=True)
- _SESSION = session_module.Session(config=config)
- session = _SESSION
- if not _MANUAL_VAR_INIT:
- with session.graph.as_default():
- _initialize_variables()
- return session
-
-
-def set_session(session):
- """Sets the global TensorFlow session.
-
- Arguments:
- session: A TF Session.
- """
- global _SESSION
- _SESSION = session
-
-
-# VARIABLE MANIPULATION
-
-
-def _convert_string_dtype(dtype):
- """Get the type from a string.
-
- Arguments:
- dtype: A string representation of a type.
-
- Returns:
- The type requested.
-
- Raises:
- ValueError: if `dtype` is not supported.
- """
- if dtype == 'float16':
- return dtypes_module.float16
- if dtype == 'float32':
- return dtypes_module.float32
- elif dtype == 'float64':
- return dtypes_module.float64
- elif dtype == 'int16':
- return dtypes_module.int16
- elif dtype == 'int32':
- return dtypes_module.int32
- elif dtype == 'int64':
- return dtypes_module.int64
- elif dtype == 'uint8':
- return dtypes_module.int8
- elif dtype == 'uint16':
- return dtypes_module.uint16
- else:
- raise ValueError('Unsupported dtype:', dtype)
-
-
-def _to_tensor(x, dtype):
- """Convert the input `x` to a tensor of type `dtype`.
-
- Arguments:
- x: An object to be converted (numpy array, list, tensors).
- dtype: The destination type.
-
- Returns:
- A tensor.
- """
- x = ops.convert_to_tensor(x)
- if x.dtype != dtype:
- x = math_ops.cast(x, dtype)
- return x
-
-
-def is_sparse(tensor):
- """Returns whether a tensor is a sparse tensor.
-
- Arguments:
- tensor: A tensor instance.
-
- Returns:
- A boolean.
-
- Example:
- ```python
- >>> from keras import backend as K
- >>> a = K.placeholder((2, 2), sparse=False)
- >>> print(K.is_sparse(a))
- False
- >>> b = K.placeholder((2, 2), sparse=True)
- >>> print(K.is_sparse(b))
- True
- ```
- """
- return isinstance(tensor, sparse_tensor.SparseTensor)
-
-
-def to_dense(tensor):
- """Converts a sparse tensor into a dense tensor and returns it.
-
- Arguments:
- tensor: A tensor instance (potentially sparse).
-
- Returns:
- A dense tensor.
-
- Examples:
- ```python
- >>> from keras import backend as K
- >>> b = K.placeholder((2, 2), sparse=True)
- >>> print(K.is_sparse(b))
- True
- >>> c = K.to_dense(b)
- >>> print(K.is_sparse(c))
- False
- ```
- """
- if is_sparse(tensor):
- return sparse_ops.sparse_tensor_to_dense(tensor)
- else:
- return tensor
-
-
-name_scope = ops.name_scope
-
-
-def variable(value, dtype=None, name=None, constraint=None):
- """Instantiates a variable and returns it.
-
- Arguments:
- value: Numpy array, initial value of the tensor.
- dtype: Tensor type.
- name: Optional name string for the tensor.
- constraint: Optional projection function to be
- applied to the variable after an optimizer update.
-
- Returns:
- A variable instance (with Keras metadata included).
-
- Examples:
- ```python
- >>> from keras import backend as K
- >>> val = np.array([[1, 2], [3, 4]])
- >>> kvar = K.variable(value=val, dtype='float64', name='example_var')
- >>> K.dtype(kvar)
- 'float64'
- >>> print(kvar)
- example_var
- >>> kvar.eval()
- array([[ 1., 2.],
- [ 3., 4.]])
- ```
- """
- if dtype is None:
- dtype = floatx()
- if hasattr(value, 'tocoo'):
- sparse_coo = value.tocoo()
- indices = np.concatenate((np.expand_dims(sparse_coo.row, 1), np.expand_dims(
- sparse_coo.col, 1)), 1)
- v = sparse_tensor.SparseTensor(
- indices=indices, values=sparse_coo.data, dense_shape=sparse_coo.shape)
- v._keras_shape = sparse_coo.shape
- v._uses_learning_phase = False
- return v
- v = variables_module.Variable(
- value,
- dtype=_convert_string_dtype(dtype),
- name=name,
- constraint=constraint)
- if isinstance(value, np.ndarray):
- v._keras_shape = value.shape
- elif hasattr(value, 'get_shape'):
- v._keras_shape = int_shape(value)
- v._uses_learning_phase = False
- return v
-
-
-def _initialize_variables():
- """Utility to initialize uninitialized variables on the fly.
- """
- variables = variables_module.global_variables()
- uninitialized_variables = []
- for v in variables:
- if not hasattr(v, '_keras_initialized') or not v._keras_initialized:
- uninitialized_variables.append(v)
- v._keras_initialized = True
- if uninitialized_variables:
- sess = get_session()
- sess.run(variables_module.variables_initializer(uninitialized_variables))
-
-
-def constant(value, dtype=None, shape=None, name=None):
- """Creates a constant tensor.
-
- Arguments:
- value: A constant value (or list)
- dtype: The type of the elements of the resulting tensor.
- shape: Optional dimensions of resulting tensor.
- name: Optional name for the tensor.
-
- Returns:
- A Constant Tensor.
- """
- if dtype is None:
- dtype = floatx()
- return constant_op.constant(value, dtype=dtype, shape=shape, name=name)
-
-
-def is_keras_tensor(x):
- """Returns whether `x` is a Keras tensor.
-
- A "Keras tensor" is a tensor that was returned by a Keras layer,
- (`Layer` class) or by `Input`.
-
- Arguments:
- x: A candidate tensor.
-
- Returns:
- A boolean: Whether the argument is a Keras tensor.
-
- Raises:
- ValueError: In case `x` is not a symbolic tensor.
-
- Examples:
- ```python
- >>> from keras import backend as K
- >>> from keras.layers import Input, Dense
- >>> np_var = numpy.array([1, 2])
- >>> K.is_keras_tensor(np_var) # A numpy array is not a symbolic tensor.
- ValueError
- >>> k_var = tf.placeholder('float32', shape=(1,1))
- >>> K.is_keras_tensor(k_var) # A variable indirectly created outside of
- keras is not a Keras tensor.
- False
- >>> keras_var = K.variable(np_var)
- >>> K.is_keras_tensor(keras_var) # A variable created with the keras
- backend is not a Keras tensor.
- False
- >>> keras_placeholder = K.placeholder(shape=(2, 4, 5))
- >>> K.is_keras_tensor(keras_placeholder) # A placeholder is not a Keras
- tensor.
- False
- >>> keras_input = Input([10])
- >>> K.is_keras_tensor(keras_input) # An Input is a Keras tensor.
- True
- >>> keras_layer_output = Dense(10)(keras_input)
- >>> K.is_keras_tensor(keras_layer_output) # Any Keras layer output is a
- Keras tensor.
- True
- ```
- """
- if not isinstance(x, (ops.Tensor,
- variables_module.Variable,
- sparse_tensor.SparseTensor)):
- raise ValueError('Unexpectedly found an instance of type `' + str(type(x)) +
- '`. Expected a symbolic tensor instance.')
- return hasattr(x, '_keras_history')
-
-
-def placeholder(shape=None, ndim=None, dtype=None, sparse=False, name=None):
- """Instantiates a placeholder tensor and returns it.
-
- Arguments:
- shape: Shape of the placeholder
- (integer tuple, may include `None` entries).
- ndim: Number of axes of the tensor.
- At least one of {`shape`, `ndim`} must be specified.
- If both are specified, `shape` is used.
- dtype: Placeholder type.
- sparse: Boolean, whether the placeholder should have a sparse type.
- name: Optional name string for the placeholder.
-
- Returns:
- Tensor instance (with Keras metadata included).
-
- Examples:
- ```python
- >>> from keras import backend as K
- >>> input_ph = K.placeholder(shape=(2, 4, 5))
- >>> input_ph
- <tf.Tensor 'Placeholder_4:0' shape=(2, 4, 5) dtype=float32>
- ```
- """
- if dtype is None:
- dtype = floatx()
- if not shape:
- if ndim:
- shape = tuple([None for _ in range(ndim)])
- if sparse:
- x = array_ops.sparse_placeholder(dtype, shape=shape, name=name)
- else:
- x = array_ops.placeholder(dtype, shape=shape, name=name)
- x._uses_learning_phase = False
- return x
-
-
-def is_placeholder(x):
- """Returns whether `x` is a placeholder.
-
- Arguments:
- x: A candidate placeholder.
-
- Returns:
- Boolean.
- """
- try:
- return x.op.type == 'Placeholder'
- except AttributeError:
- return False
-
-
-def shape(x):
- """Returns the symbolic shape of a tensor or variable.
-
- Arguments:
- x: A tensor or variable.
-
- Returns:
- A symbolic shape (which is itself a tensor).
-
- Examples:
-
- ```python
- # TensorFlow example
- >>> from keras import backend as K
- >>> tf_session = K.get_session()
- >>> val = np.array([[1, 2], [3, 4]])
- >>> kvar = K.variable(value=val)
- >>> input = keras.backend.placeholder(shape=(2, 4, 5))
- >>> K.shape(kvar)
- <tf.Tensor 'Shape_8:0' shape=(2,) dtype=int32>
- >>> K.shape(input)
- <tf.Tensor 'Shape_9:0' shape=(3,) dtype=int32>
- # To get integer shape (Instead, you can use K.int_shape(x))
- >>> K.shape(kvar).eval(session=tf_session)
- array([2, 2], dtype=int32)
- >>> K.shape(input).eval(session=tf_session)
- array([2, 4, 5], dtype=int32)
- ```
- """
- return array_ops.shape(x)
-
-
-def int_shape(x):
- """Returns the shape tensor or variable as a tuple of int or None entries.
-
- Arguments:
- x: Tensor or variable.
-
- Returns:
- A tuple of integers (or None entries).
-
- Examples:
- ```python
- >>> from keras import backend as K
- >>> input = K.placeholder(shape=(2, 4, 5))
- >>> K.int_shape(input)
- (2, 4, 5)
- >>> val = np.array([[1, 2], [3, 4]])
- >>> kvar = K.variable(value=val)
- >>> K.int_shape(kvar)
- (2, 2)
- ```
- """
- try:
- return tuple(x.get_shape().as_list())
- except ValueError:
- return None
-
-
-def ndim(x):
- """Returns the number of axes in a tensor, as an integer.
-
- Arguments:
- x: Tensor or variable.
-
- Returns:
- Integer (scalar), number of axes.
-
- Examples:
- ```python
- >>> from keras import backend as K
- >>> input = K.placeholder(shape=(2, 4, 5))
- >>> val = np.array([[1, 2], [3, 4]])
- >>> kvar = K.variable(value=val)
- >>> K.ndim(input)
- 3
- >>> K.ndim(kvar)
- 2
- ```
- """
- dims = x.get_shape()._dims
- if dims is not None:
- return len(dims)
- return None
-
-
-def dtype(x):
- """Returns the dtype of a Keras tensor or variable, as a string.
-
- Arguments:
- x: Tensor or variable.
-
- Returns:
- String, dtype of `x`.
-
- Examples:
- ```python
- >>> from keras import backend as K
- >>> K.dtype(K.placeholder(shape=(2,4,5)))
- 'float32'
- >>> K.dtype(K.placeholder(shape=(2,4,5), dtype='float32'))
- 'float32'
- >>> K.dtype(K.placeholder(shape=(2,4,5), dtype='float64'))
- 'float64'
- # Keras variable
- >>> kvar = K.variable(np.array([[1, 2], [3, 4]]))
- >>> K.dtype(kvar)
- 'float32_ref'
- >>> kvar = K.variable(np.array([[1, 2], [3, 4]]), dtype='float32')
- >>> K.dtype(kvar)
- 'float32_ref'
- ```
- """
- return x.dtype.base_dtype.name
-
-
-def eval(x):
- """Evaluates the value of a variable.
-
- Arguments:
- x: A variable.
-
- Returns:
- A Numpy array.
-
- Examples:
- ```python
- >>> from keras import backend as K
- >>> kvar = K.variable(np.array([[1, 2], [3, 4]]), dtype='float32')
- >>> K.eval(kvar)
- array([[ 1., 2.],
- [ 3., 4.]], dtype=float32)
- ```
- """
- return to_dense(x).eval(session=get_session())
-
-
-def zeros(shape, dtype=None, name=None):
- """Instantiates an all-zeros variable and returns it.
-
- Arguments:
- shape: Tuple of integers, shape of returned Keras variable
- dtype: String, data type of returned Keras variable
- name: String, name of returned Keras variable
-
- Returns:
- A variable (including Keras metadata), filled with `0.0`.
-
- Example:
- ```python
- >>> from keras import backend as K
- >>> kvar = K.zeros((3,4))
- >>> K.eval(kvar)
- array([[ 0., 0., 0., 0.],
- [ 0., 0., 0., 0.],
- [ 0., 0., 0., 0.]], dtype=float32)
- ```
- """
- if dtype is None:
- dtype = floatx()
- tf_dtype = _convert_string_dtype(dtype)
- return variable(
- init_ops.constant_initializer(0., dtype=tf_dtype)(shape), dtype, name)
-
-
-def ones(shape, dtype=None, name=None):
- """Instantiates an all-ones tensor variable and returns it.
-
- Arguments:
- shape: Tuple of integers, shape of returned Keras variable.
- dtype: String, data type of returned Keras variable.
- name: String, name of returned Keras variable.
-
- Returns:
- A Keras variable, filled with `1.0`.
-
- Example:
- ```python
- >>> from keras import backend as K
- >>> kvar = K.ones((3,4))
- >>> K.eval(kvar)
- array([[ 1., 1., 1., 1.],
- [ 1., 1., 1., 1.],
- [ 1., 1., 1., 1.]], dtype=float32)
- ```
- """
- if dtype is None:
- dtype = floatx()
- tf_dtype = _convert_string_dtype(dtype)
- return variable(
- init_ops.constant_initializer(1., dtype=tf_dtype)(shape), dtype, name)
-
-
-def eye(size, dtype=None, name=None):
- """Instantiate an identity matrix and returns it.
-
- Arguments:
- size: Integer, number of rows/columns.
- dtype: String, data type of returned Keras variable.
- name: String, name of returned Keras variable.
-
- Returns:
- A Keras variable, an identity matrix.
-
- Example:
- ```python
- >>> from keras import backend as K
- >>> kvar = K.eye(3)
- >>> K.eval(kvar)
- array([[ 1., 0., 0.],
- [ 0., 1., 0.],
- [ 0., 0., 1.]], dtype=float32)
- ```
-
- """
- return variable(np.eye(size), dtype, name)
-
-
-def zeros_like(x, dtype=None, name=None):
- """Instantiates an all-zeros variable of the same shape as another tensor.
-
- Arguments:
- x: Keras variable or Keras tensor.
- dtype: String, dtype of returned Keras variable.
- None uses the dtype of x.
- name: String, name for the variable to create.
-
- Returns:
- A Keras variable with the shape of x filled with zeros.
-
- Example:
- ```python
- >>> from keras import backend as K
- >>> kvar = K.variable(np.random.random((2,3)))
- >>> kvar_zeros = K.zeros_like(kvar)
- >>> K.eval(kvar_zeros)
- array([[ 0., 0., 0.],
- [ 0., 0., 0.]], dtype=float32)
- ```
- """
- return array_ops.zeros_like(x, dtype=dtype, name=name)
-
-
-def ones_like(x, dtype=None, name=None):
- """Instantiates an all-ones variable of the same shape as another tensor.
-
- Arguments:
- x: Keras variable or tensor.
- dtype: String, dtype of returned Keras variable.
- None uses the dtype of x.
- name: String, name for the variable to create.
-
- Returns:
- A Keras variable with the shape of x filled with ones.
-
- Example:
- ```python
- >>> from keras import backend as K
- >>> kvar = K.variable(np.random.random((2,3)))
- >>> kvar_ones = K.ones_like(kvar)
- >>> K.eval(kvar_ones)
- array([[ 1., 1., 1.],
- [ 1., 1., 1.]], dtype=float32)
- ```
- """
- return array_ops.ones_like(x, dtype=dtype, name=name)
-
-
-def identity(x):
- """Returns a tensor with the same content as the input tensor.
-
- Arguments:
- x: The input tensor.
-
- Returns:
- A tensor of the same shape, type and content.
- """
- return array_ops.identity(x)
-
-
-def random_uniform_variable(shape, low, high, dtype=None, name=None, seed=None):
- """Instantiates a variable with values drawn from a uniform distribution.
-
- Arguments:
- shape: Tuple of integers, shape of returned Keras variable.
- low: Float, lower boundary of the output interval.
- high: Float, upper boundary of the output interval.
- dtype: String, dtype of returned Keras variable.
- name: String, name of returned Keras variable.
- seed: Integer, random seed.
-
- Returns:
- A Keras variable, filled with drawn samples.
-
- Example:
- ```python
- # TensorFlow example
- >>> kvar = K.random_uniform_variable((2,3), 0, 1)
- >>> kvar
- <tensorflow.python.ops.variables.Variable object at 0x10ab40b10>
- >>> K.eval(kvar)
- array([[ 0.10940075, 0.10047495, 0.476143 ],
- [ 0.66137183, 0.00869417, 0.89220798]], dtype=float32)
- ```
- """
- if dtype is None:
- dtype = floatx()
- tf_dtype = _convert_string_dtype(dtype)
- if seed is None:
- # ensure that randomness is conditioned by the Numpy RNG
- seed = np.random.randint(10e8)
- value = init_ops.random_uniform_initializer(
- low, high, dtype=tf_dtype, seed=seed)(shape)
- return variable(value, dtype=dtype, name=name)
-
-
-def random_normal_variable(shape, mean, scale, dtype=None, name=None,
- seed=None):
- """Instantiates a variable with values drawn from a normal distribution.
-
- Arguments:
- shape: Tuple of integers, shape of returned Keras variable.
- mean: Float, mean of the normal distribution.
- scale: Float, standard deviation of the normal distribution.
- dtype: String, dtype of returned Keras variable.
- name: String, name of returned Keras variable.
- seed: Integer, random seed.
-
- Returns:
- A Keras variable, filled with drawn samples.
-
- Example:
- ```python
- # TensorFlow example
- >>> kvar = K.random_normal_variable((2,3), 0, 1)
- >>> kvar
- <tensorflow.python.ops.variables.Variable object at 0x10ab12dd0>
- >>> K.eval(kvar)
- array([[ 1.19591331, 0.68685907, -0.63814116],
- [ 0.92629528, 0.28055015, 1.70484698]], dtype=float32)
- ```
- """
- if dtype is None:
- dtype = floatx()
- tf_dtype = _convert_string_dtype(dtype)
- if seed is None:
- # ensure that randomness is conditioned by the Numpy RNG
- seed = np.random.randint(10e8)
- value = init_ops.random_normal_initializer(
- mean, scale, dtype=tf_dtype, seed=seed)(shape)
- return variable(value, dtype=dtype, name=name)
-
-
-def count_params(x):
- """Returns the number of scalars in a Keras variable.
-
- Arguments:
- x: Keras variable.
-
- Returns:
- Integer, the number of scalars in `x`.
-
- Example:
- ```python
- >>> kvar = K.zeros((2,3))
- >>> K.count_params(kvar)
- 6
- >>> K.eval(kvar)
- array([[ 0., 0., 0.],
- [ 0., 0., 0.]], dtype=float32)
- ```
- """
- shape = x.get_shape()
- return np.prod([shape[i]._value for i in range(len(shape))])
-
-
-def cast(x, dtype):
- """Casts a tensor to a different dtype and returns it.
-
- You can cast a Keras variable but it still returns a Keras tensor.
-
- Arguments:
- x: Keras tensor (or variable).
- dtype: String, either (`'float16'`, `'float32'`, or `'float64'`).
-
- Returns:
- Keras tensor with dtype `dtype`.
-
- Example:
- ```python
- >>> from keras import backend as K
- >>> input = K.placeholder((2, 3), dtype='float32')
- >>> input
- <tf.Tensor 'Placeholder_2:0' shape=(2, 3) dtype=float32>
- # It doesn't work in-place as below.
- >>> K.cast(input, dtype='float16')
- <tf.Tensor 'Cast_1:0' shape=(2, 3) dtype=float16>
- >>> input
- <tf.Tensor 'Placeholder_2:0' shape=(2, 3) dtype=float32>
- # you need to assign it.
- >>> input = K.cast(input, dtype='float16')
- >>> input
- <tf.Tensor 'Cast_2:0' shape=(2, 3) dtype=float16>
- ```
- """
- return math_ops.cast(x, dtype)
-
-
-# UPDATES OPS
-
-
-def update(x, new_x):
- return state_ops.assign(x, new_x)
-
-
-def update_add(x, increment):
- """Update the value of `x` by adding `increment`.
-
- Arguments:
- x: A Variable.
- increment: A tensor of same shape as `x`.
-
- Returns:
- The variable `x` updated.
- """
- return state_ops.assign_add(x, increment)
-
-
-def update_sub(x, decrement):
- """Update the value of `x` by subtracting `decrement`.
-
- Arguments:
- x: A Variable.
- decrement: A tensor of same shape as `x`.
-
- Returns:
- The variable `x` updated.
- """
- return state_ops.assign_sub(x, decrement)
-
-
-def moving_average_update(x, value, momentum):
- """Compute the moving average of a variable.
-
- Arguments:
- x: A Variable.
- value: A tensor with the same shape as `variable`.
- momentum: The moving average momentum.
-
- Returns:
- An Operation to update the variable.
- """
- return moving_averages.assign_moving_average(
- x, value, momentum, zero_debias=False)
-
-
-# LINEAR ALGEBRA
-
-
-def dot(x, y):
- """Multiplies 2 tensors (and/or variables) and returns a *tensor*.
-
- When attempting to multiply a nD tensor
- with a nD tensor, it reproduces the Theano behavior.
- (e.g. `(2, 3) * (4, 3, 5) -> (2, 4, 5)`)
-
- Arguments:
- x: Tensor or variable.
- y: Tensor or variable.
-
- Returns:
- A tensor, dot product of `x` and `y`.
-
- Examples:
- ```python
- # dot product between tensors
- >>> x = K.placeholder(shape=(2, 3))
- >>> y = K.placeholder(shape=(3, 4))
- >>> xy = K.dot(x, y)
- >>> xy
- <tf.Tensor 'MatMul_9:0' shape=(2, 4) dtype=float32>
- ```
-
- ```python
- # dot product between tensors
- >>> x = K.placeholder(shape=(32, 28, 3))
- >>> y = K.placeholder(shape=(3, 4))
- >>> xy = K.dot(x, y)
- >>> xy
- <tf.Tensor 'MatMul_9:0' shape=(32, 28, 4) dtype=float32>
- ```
-
- ```python
- # Theano-like behavior example
- >>> x = K.random_uniform_variable(shape=(2, 3), low=0, high=1)
- >>> y = K.ones((4, 3, 5))
- >>> xy = K.dot(x, y)
- >>> K.int_shape(xy)
- (2, 4, 5)
- ```
- """
- if ndim(x) is not None and (ndim(x) > 2 or ndim(y) > 2):
- x_shape = []
- for i, s in zip(int_shape(x), array_ops.unstack(array_ops.shape(x))):
- if i is not None:
- x_shape.append(i)
- else:
- x_shape.append(s)
- x_shape = tuple(x_shape)
- y_shape = []
- for i, s in zip(int_shape(y), array_ops.unstack(array_ops.shape(y))):
- if i is not None:
- y_shape.append(i)
- else:
- y_shape.append(s)
- y_shape = tuple(y_shape)
- y_permute_dim = list(range(ndim(y)))
- y_permute_dim = [y_permute_dim.pop(-2)] + y_permute_dim
- xt = array_ops.reshape(x, [-1, x_shape[-1]])
- yt = array_ops.reshape(
- array_ops.transpose(y, perm=y_permute_dim), [y_shape[-2], -1])
- return array_ops.reshape(
- math_ops.matmul(xt, yt), x_shape[:-1] + y_shape[:-2] + y_shape[-1:])
- if is_sparse(x):
- out = sparse_ops.sparse_tensor_dense_matmul(x, y)
- else:
- out = math_ops.matmul(x, y)
- return out
-
-
-def batch_dot(x, y, axes=None):
- """Batchwise dot product.
-
- `batch_dot` is used to compute dot product of `x` and `y` when
- `x` and `y` are data in batch, i.e. in a shape of
- `(batch_size, :)`.
- `batch_dot` results in a tensor or variable with less dimensions
- than the input. If the number of dimensions is reduced to 1,
- we use `expand_dims` to make sure that ndim is at least 2.
-
- Arguments:
- x: Keras tensor or variable with `ndim >= 2`.
- y: Keras tensor or variable with `ndim >= 2`.
- axes: list of (or single) int with target dimensions.
- The lengths of `axes[0]` and `axes[1]` should be the same.
-
- Returns:
- A tensor with shape equal to the concatenation of `x`'s shape
- (less the dimension that was summed over) and `y`'s shape
- (less the batch dimension and the dimension that was summed over).
- If the final rank is 1, we reshape it to `(batch_size, 1)`.
-
- Examples:
- Assume `x = [[1, 2], [3, 4]]` and `y = [[5, 6], [7, 8]]`
- `batch_dot(x, y, axes=1) = [[17, 53]]` which is the main diagonal
- of `x.dot(y.T)`, although we never have to calculate the off-diagonal
- elements.
-
- Shape inference:
- Let `x`'s shape be `(100, 20)` and `y`'s shape be `(100, 30, 20)`.
- If `axes` is (1, 2), to find the output shape of resultant tensor,
- loop through each dimension in `x`'s shape and `y`'s shape:
-
- * `x.shape[0]` : 100 : append to output shape
- * `x.shape[1]` : 20 : do not append to output shape,
- dimension 1 of `x` has been summed over. (`dot_axes[0]` = 1)
- * `y.shape[0]` : 100 : do not append to output shape,
- always ignore first dimension of `y`
- * `y.shape[1]` : 30 : append to output shape
- * `y.shape[2]` : 20 : do not append to output shape,
- dimension 2 of `y` has been summed over. (`dot_axes[1]` = 2)
- `output_shape` = `(100, 30)`
-
- ```python
- >>> x_batch = K.ones(shape=(32, 20, 1))
- >>> y_batch = K.ones(shape=(32, 30, 20))
- >>> xy_batch_dot = K.batch_dot(x_batch, y_batch, axes=[1, 2])
- >>> K.int_shape(xy_batch_dot)
- (32, 1, 30)
- ```
- """
- if isinstance(axes, int):
- axes = (axes, axes)
- x_ndim = ndim(x)
- y_ndim = ndim(y)
- if x_ndim > y_ndim:
- diff = x_ndim - y_ndim
- y = array_ops.reshape(y,
- array_ops.concat(
- [array_ops.shape(y), [1] * (diff)], axis=0))
- elif y_ndim > x_ndim:
- diff = y_ndim - x_ndim
- x = array_ops.reshape(x,
- array_ops.concat(
- [array_ops.shape(x), [1] * (diff)], axis=0))
- else:
- diff = 0
- if ndim(x) == 2 and ndim(y) == 2:
- if axes[0] == axes[1]:
- out = math_ops.reduce_sum(math_ops.multiply(x, y), axes[0])
- else:
- out = math_ops.reduce_sum(
- math_ops.multiply(array_ops.transpose(x, [1, 0]), y), axes[1])
- else:
- if axes is not None:
- adj_x = None if axes[0] == ndim(x) - 1 else True
- adj_y = True if axes[1] == ndim(y) - 1 else None
- else:
- adj_x = None
- adj_y = None
- out = math_ops.matmul(x, y, adjoint_a=adj_x, adjoint_b=adj_y)
- if diff:
- if x_ndim > y_ndim:
- idx = x_ndim + y_ndim - 3
- else:
- idx = x_ndim - 1
- out = array_ops.squeeze(out, list(range(idx, idx + diff)))
- if ndim(out) == 1:
- out = expand_dims(out, 1)
- return out
-
-
-def transpose(x):
- """Transposes a tensor and returns it.
-
- Arguments:
- x: Tensor or variable.
-
- Returns:
- A tensor.
-
- Examples:
- ```python
- >>> var = K.variable([[1, 2, 3], [4, 5, 6]])
- >>> K.eval(var)
- array([[ 1., 2., 3.],
- [ 4., 5., 6.]], dtype=float32)
- >>> var_transposed = K.transpose(var)
- >>> K.eval(var_transposed)
- array([[ 1., 4.],
- [ 2., 5.],
- [ 3., 6.]], dtype=float32)
- ```
-
- ```python
- >>> input = K.placeholder((2, 3))
- >>> input
- <tf.Tensor 'Placeholder_11:0' shape=(2, 3) dtype=float32>
- >>> input_transposed = K.transpose(input)
- >>> input_transposed
- <tf.Tensor 'transpose_4:0' shape=(3, 2) dtype=float32>
-
- ```
- """
- return array_ops.transpose(x)
-
-
-def gather(reference, indices):
- """Retrieves the elements of indices `indices` in the tensor `reference`.
-
- Arguments:
- reference: A tensor.
- indices: An integer tensor of indices.
-
- Returns:
- A tensor of same type as `reference`.
- """
- return array_ops.gather(reference, indices)
-
-
-# ELEMENT-WISE OPERATIONS
-
-
-def max(x, axis=None, keepdims=False):
- """Maximum value in a tensor.
-
- Arguments:
- x: A tensor or variable.
- axis: An integer, the axis to find maximum values.
- keepdims: A boolean, whether to keep the dimensions or not.
- If `keepdims` is `False`, the rank of the tensor is reduced
- by 1. If `keepdims` is `True`,
- the reduced dimension is retained with length 1.
-
- Returns:
- A tensor with maximum values of `x`.
- """
- return math_ops.reduce_max(x, axis=axis, keep_dims=keepdims)
-
-
-def min(x, axis=None, keepdims=False):
- """Minimum value in a tensor.
-
- Arguments:
- x: A tensor or variable.
- axis: An integer, the axis to find minimum values.
- keepdims: A boolean, whether to keep the dimensions or not.
- If `keepdims` is `False`, the rank of the tensor is reduced
- by 1. If `keepdims` is `True`,
- the reduced dimension is retained with length 1.
-
- Returns:
- A tensor with miminum values of `x`.
- """
- return math_ops.reduce_min(x, axis=axis, keep_dims=keepdims)
-
-
-def sum(x, axis=None, keepdims=False):
- """Sum of the values in a tensor, alongside the specified axis.
-
- Arguments:
- x: A tensor or variable.
- axis: An integer, the axis to sum over.
- keepdims: A boolean, whether to keep the dimensions or not.
- If `keepdims` is `False`, the rank of the tensor is reduced
- by 1. If `keepdims` is `True`,
- the reduced dimension is retained with length 1.
-
- Returns:
- A tensor with sum of `x`.
- """
- return math_ops.reduce_sum(x, axis=axis, keep_dims=keepdims)
-
-
-def prod(x, axis=None, keepdims=False):
- """Multiplies the values in a tensor, alongside the specified axis.
-
- Arguments:
- x: A tensor or variable.
- axis: An integer, the axis to compute the product.
- keepdims: A boolean, whether to keep the dimensions or not.
- If `keepdims` is `False`, the rank of the tensor is reduced
- by 1. If `keepdims` is `True`,
- the reduced dimension is retained with length 1.
-
- Returns:
- A tensor with the product of elements of `x`.
- """
- return math_ops.reduce_prod(x, axis=axis, keep_dims=keepdims)
-
-
-def cumsum(x, axis=0):
- """Cumulative sum of the values in a tensor, alongside the specified axis.
-
- Arguments:
- x: A tensor or variable.
- axis: An integer, the axis to compute the sum.
-
- Returns:
- A tensor of the cumulative sum of values of `x` along `axis`.
- """
- return math_ops.cumsum(x, axis=axis)
-
-
-def cumprod(x, axis=0):
- """Cumulative product of the values in a tensor, alongside the specified axis.
-
- Arguments:
- x: A tensor or variable.
- axis: An integer, the axis to compute the product.
-
- Returns:
- A tensor of the cumulative product of values of `x` along `axis`.
- """
- return math_ops.cumprod(x, axis=axis)
-
-
-def var(x, axis=None, keepdims=False):
- """Variance of a tensor, alongside the specified axis.
-
- Arguments:
- x: A tensor or variable.
- axis: An integer, the axis to compute the variance.
- keepdims: A boolean, whether to keep the dimensions or not.
- If `keepdims` is `False`, the rank of the tensor is reduced
- by 1. If `keepdims` is `True`,
- the reduced dimension is retained with length 1.
-
- Returns:
- A tensor with the variance of elements of `x`.
- """
- if x.dtype.base_dtype == dtypes_module.bool:
- x = math_ops.cast(x, floatx())
- m = math_ops.reduce_mean(x, axis=axis, keep_dims=True)
- devs_squared = math_ops.square(x - m)
- return math_ops.reduce_mean(
- devs_squared, axis=axis, keep_dims=keepdims)
-
-
-def std(x, axis=None, keepdims=False):
- """Standard deviation of a tensor, alongside the specified axis.
-
- Arguments:
- x: A tensor or variable.
- axis: An integer, the axis to compute the standard deviation.
- keepdims: A boolean, whether to keep the dimensions or not.
- If `keepdims` is `False`, the rank of the tensor is reduced
- by 1. If `keepdims` is `True`,
- the reduced dimension is retained with length 1.
-
- Returns:
- A tensor with the standard deviation of elements of `x`.
- """
- return math_ops.sqrt(var(x, axis=axis, keepdims=keepdims))
-
-
-def mean(x, axis=None, keepdims=False):
- """Mean of a tensor, alongside the specified axis.
-
- Arguments:
- x: A tensor or variable.
- axis: A list of integer. Axes to compute the mean.
- keepdims: A boolean, whether to keep the dimensions or not.
- If `keepdims` is `False`, the rank of the tensor is reduced
- by 1 for each entry in `axis`. If `keep_dims` is `True`,
- the reduced dimensions are retained with length 1.
-
- Returns:
- A tensor with the mean of elements of `x`.
- """
- if x.dtype.base_dtype == dtypes_module.bool:
- x = math_ops.cast(x, floatx())
- return math_ops.reduce_mean(x, axis=axis, keep_dims=keepdims)
-
-
-def any(x, axis=None, keepdims=False):
- """Bitwise reduction (logical OR).
-
- Arguments:
- x: Tensor or variable.
- axis: axis along which to perform the reduction.
- keepdims: whether the drop or broadcast the reduction axes.
-
- Returns:
- A uint8 tensor (0s and 1s).
- """
- x = math_ops.cast(x, dtypes_module.bool)
- return math_ops.reduce_any(x, axis=axis, keep_dims=keepdims)
-
-
-def all(x, axis=None, keepdims=False):
- """Bitwise reduction (logical AND).
-
- Arguments:
- x: Tensor or variable.
- axis: axis along which to perform the reduction.
- keepdims: whether the drop or broadcast the reduction axes.
-
- Returns:
- A uint8 tensor (0s and 1s).
- """
- x = math_ops.cast(x, dtypes_module.bool)
- return math_ops.reduce_all(x, axis=axis, keep_dims=keepdims)
-
-
-def argmax(x, axis=-1):
- """Returns the index of the maximum value along an axis.
-
- Arguments:
- x: Tensor or variable.
- axis: axis along which to perform the reduction.
-
- Returns:
- A tensor.
- """
- return math_ops.argmax(x, axis)
-
-
-def argmin(x, axis=-1):
- """Returns the index of the minimum value along an axis.
-
- Arguments:
- x: Tensor or variable.
- axis: axis along which to perform the reduction.
-
- Returns:
- A tensor.
- """
- return math_ops.argmin(x, axis)
-
-
-def square(x):
- """Element-wise square.
-
- Arguments:
- x: Tensor or variable.
-
- Returns:
- A tensor.
- """
- return math_ops.square(x)
-
-
-def abs(x):
- """Element-wise absolute value.
-
- Arguments:
- x: Tensor or variable.
-
- Returns:
- A tensor.
- """
- return math_ops.abs(x)
-
-
-def sqrt(x):
- """Element-wise square root.
-
- Arguments:
- x: Tensor or variable.
-
- Returns:
- A tensor.
- """
- zero = _to_tensor(0., x.dtype.base_dtype)
- inf = _to_tensor(np.inf, x.dtype.base_dtype)
- x = clip_ops.clip_by_value(x, zero, inf)
- return math_ops.sqrt(x)
-
-
-def exp(x):
- """Element-wise exponential.
-
- Arguments:
- x: Tensor or variable.
-
- Returns:
- A tensor.
- """
- return math_ops.exp(x)
-
-
-def log(x):
- """Element-wise log.
-
- Arguments:
- x: Tensor or variable.
-
- Returns:
- A tensor.
- """
- return math_ops.log(x)
-
-
-def logsumexp(x, axis=None, keepdims=False):
- """Computes log(sum(exp(elements across dimensions of a tensor))).
-
- This function is more numerically stable than log(sum(exp(x))).
- It avoids overflows caused by taking the exp of large inputs and
- underflows caused by taking the log of small inputs.
-
- Arguments:
- x: A tensor or variable.
- axis: An integer, the axis to reduce over.
- keepdims: A boolean, whether to keep the dimensions or not.
- If `keepdims` is `False`, the rank of the tensor is reduced
- by 1. If `keepdims` is `True`, the reduced dimension is
- retained with length 1.
-
- Returns:
- The reduced tensor.
- """
- return math_ops.reduce_logsumexp(x, axis=axis, keep_dims=keepdims)
-
-
-def round(x):
- """Element-wise rounding to the closest integer.
-
- In case of tie, the rounding mode used is "half to even".
-
- Arguments:
- x: Tensor or variable.
-
- Returns:
- A tensor.
- """
- return math_ops.round(x)
-
-
-def sign(x):
- """Element-wise sign.
-
- Arguments:
- x: Tensor or variable.
-
- Returns:
- A tensor.
- """
- return math_ops.sign(x)
-
-
-def pow(x, a):
- """Element-wise exponentiation.
-
- Arguments:
- x: Tensor or variable.
- a: Python integer.
-
- Returns:
- A tensor.
- """
- return math_ops.pow(x, a)
-
-
-def clip(x, min_value, max_value):
- """Element-wise value clipping.
-
- Arguments:
- x: Tensor or variable.
- min_value: Python float or integer.
- max_value: Python float or integer.
-
- Returns:
- A tensor.
- """
- if max_value is not None and max_value < min_value:
- max_value = min_value
- if max_value is None:
- max_value = np.inf
- min_value = _to_tensor(min_value, x.dtype.base_dtype)
- max_value = _to_tensor(max_value, x.dtype.base_dtype)
- return clip_ops.clip_by_value(x, min_value, max_value)
-
-
-def equal(x, y):
- """Element-wise equality between two tensors.
-
- Arguments:
- x: Tensor or variable.
- y: Tensor or variable.
-
- Returns:
- A bool tensor.
- """
- return math_ops.equal(x, y)
-
-
-def not_equal(x, y):
- """Element-wise inequality between two tensors.
-
- Arguments:
- x: Tensor or variable.
- y: Tensor or variable.
-
- Returns:
- A bool tensor.
- """
- return math_ops.not_equal(x, y)
-
-
-def greater(x, y):
- """Element-wise truth value of (x > y).
-
- Arguments:
- x: Tensor or variable.
- y: Tensor or variable.
-
- Returns:
- A bool tensor.
- """
- return math_ops.greater(x, y)
-
-
-def greater_equal(x, y):
- """Element-wise truth value of (x >= y).
-
- Arguments:
- x: Tensor or variable.
- y: Tensor or variable.
-
- Returns:
- A bool tensor.
- """
- return math_ops.greater_equal(x, y)
-
-
-def less(x, y):
- """Element-wise truth value of (x < y).
-
- Arguments:
- x: Tensor or variable.
- y: Tensor or variable.
-
- Returns:
- A bool tensor.
- """
- return math_ops.less(x, y)
-
-
-def less_equal(x, y):
- """Element-wise truth value of (x <= y).
-
- Arguments:
- x: Tensor or variable.
- y: Tensor or variable.
-
- Returns:
- A bool tensor.
- """
- return math_ops.less_equal(x, y)
-
-
-def maximum(x, y):
- """Element-wise maximum of two tensors.
-
- Arguments:
- x: Tensor or variable.
- y: Tensor or variable.
-
- Returns:
- A tensor.
- """
- return math_ops.maximum(x, y)
-
-
-def minimum(x, y):
- """Element-wise minimum of two tensors.
-
- Arguments:
- x: Tensor or variable.
- y: Tensor or variable.
-
- Returns:
- A tensor.
- """
- return math_ops.minimum(x, y)
-
-
-def sin(x):
- """Computes sin of x element-wise.
-
- Arguments:
- x: Tensor or variable.
-
- Returns:
- A tensor.
- """
- return math_ops.sin(x)
-
-
-def cos(x):
- """Computes cos of x element-wise.
-
- Arguments:
- x: Tensor or variable.
-
- Returns:
- A tensor.
- """
- return math_ops.cos(x)
-
-
-def normalize_batch_in_training(x, gamma, beta, reduction_axes, epsilon=1e-3):
- """Computes mean and std for batch then apply batch_normalization on batch.
-
- Arguments:
- x: Input tensor or variable.
- gamma: Tensor by which to scale the input.
- beta: Tensor with which to center the input.
- reduction_axes: iterable of integers,
- axes over which to normalize.
- epsilon: Fuzz factor.
-
- Returns:
- A tuple length of 3, `(normalized_tensor, mean, variance)`.
- """
- mean, var = nn.moments(
- x, reduction_axes, shift=None, name=None, keep_dims=False)
- if sorted(reduction_axes) == list(range(ndim(x)))[:-1]:
- normed = nn.batch_normalization(x, mean, var, beta, gamma, epsilon)
- else:
- # need broadcasting
- target_shape = []
- for axis in range(ndim(x)):
- if axis in reduction_axes:
- target_shape.append(1)
- else:
- target_shape.append(array_ops.shape(x)[axis])
- target_shape = array_ops.stack(target_shape)
-
- broadcast_mean = array_ops.reshape(mean, target_shape)
- broadcast_var = array_ops.reshape(var, target_shape)
- if gamma is None:
- broadcast_gamma = None
- else:
- broadcast_gamma = array_ops.reshape(gamma, target_shape)
- if beta is None:
- broadcast_beta = None
- else:
- broadcast_beta = array_ops.reshape(beta, target_shape)
- normed = nn.batch_normalization(x, broadcast_mean, broadcast_var,
- broadcast_beta, broadcast_gamma, epsilon)
- return normed, mean, var
-
-
-def batch_normalization(x, mean, var, beta, gamma, epsilon=1e-3):
- """Applies batch normalization on x given mean, var, beta and gamma.
-
- I.e. returns:
- `output = (x - mean) / (sqrt(var) + epsilon) * gamma + beta`
-
- Arguments:
- x: Input tensor or variable.
- mean: Mean of batch.
- var: Variance of batch.
- beta: Tensor with which to center the input.
- gamma: Tensor by which to scale the input.
- epsilon: Fuzz factor.
-
- Returns:
- A tensor.
- """
- return nn.batch_normalization(x, mean, var, beta, gamma, epsilon)
-
-
-# SHAPE OPERATIONS
-
-
-def concatenate(tensors, axis=-1):
- """Concatenates a list of tensors alongside the specified axis.
-
- Arguments:
- tensors: list of tensors to concatenate.
- axis: concatenation axis.
-
- Returns:
- A tensor.
- """
- if axis < 0:
- rank = ndim(tensors[0])
- if rank:
- axis %= rank
- else:
- axis = 0
-
- if py_all([is_sparse(x) for x in tensors]):
- return sparse_ops.sparse_concat(axis, tensors)
- else:
- return array_ops.concat([to_dense(x) for x in tensors], axis)
-
-
-def reshape(x, shape):
- """Reshapes a tensor to the specified shape.
-
- Arguments:
- x: Tensor or variable.
- shape: Target shape tuple.
-
- Returns:
- A tensor.
- """
- return array_ops.reshape(x, shape)
-
-
-def permute_dimensions(x, pattern):
- """Permutes axes in a tensor.
-
- Arguments:
- x: Tensor or variable.
- pattern: A tuple of
- dimension indices, e.g. `(0, 2, 1)`.
-
- Returns:
- A tensor.
- """
- return array_ops.transpose(x, perm=pattern)
-
-
-def resize_images(x, height_factor, width_factor, data_format):
- """Resizes the images contained in a 4D tensor.
-
- Arguments:
- x: Tensor or variable to resize.
- height_factor: Positive integer.
- width_factor: Positive integer.
- data_format: One of `"channels_first"`, `"channels_last"`.
-
- Returns:
- A tensor.
-
- Raises:
- ValueError: if `data_format` is neither
- `channels_last` or `channels_first`.
- """
- if data_format == 'channels_first':
- original_shape = int_shape(x)
- new_shape = array_ops.shape(x)[2:]
- new_shape *= constant_op.constant(
- np.array([height_factor, width_factor]).astype('int32'))
- x = permute_dimensions(x, [0, 2, 3, 1])
- x = image_ops.resize_nearest_neighbor(x, new_shape)
- x = permute_dimensions(x, [0, 3, 1, 2])
- x.set_shape((None, None, original_shape[2] * height_factor
- if original_shape[2] is not None else None,
- original_shape[3] * width_factor
- if original_shape[3] is not None else None))
- return x
- elif data_format == 'channels_last':
- original_shape = int_shape(x)
- new_shape = array_ops.shape(x)[1:3]
- new_shape *= constant_op.constant(
- np.array([height_factor, width_factor]).astype('int32'))
- x = image_ops.resize_nearest_neighbor(x, new_shape)
- x.set_shape((None, original_shape[1] * height_factor
- if original_shape[1] is not None else None,
- original_shape[2] * width_factor
- if original_shape[2] is not None else None, None))
- return x
- else:
- raise ValueError('Invalid data_format:', data_format)
-
-
-def resize_volumes(x, depth_factor, height_factor, width_factor, data_format):
- """Resizes the volume contained in a 5D tensor.
-
- Arguments:
- x: Tensor or variable to resize.
- depth_factor: Positive integer.
- height_factor: Positive integer.
- width_factor: Positive integer.
- data_format: One of `"channels_first"`, `"channels_last"`.
-
- Returns:
- A tensor.
-
- Raises:
- ValueError: if `data_format` is neither
- `channels_last` or `channels_first`.
- """
- if data_format == 'channels_first':
- output = repeat_elements(x, depth_factor, axis=2)
- output = repeat_elements(output, height_factor, axis=3)
- output = repeat_elements(output, width_factor, axis=4)
- return output
- elif data_format == 'channels_last':
- output = repeat_elements(x, depth_factor, axis=1)
- output = repeat_elements(output, height_factor, axis=2)
- output = repeat_elements(output, width_factor, axis=3)
- return output
- else:
- raise ValueError('Invalid data_format:', data_format)
-
-
-def repeat_elements(x, rep, axis):
- """Repeats the elements of a tensor along an axis, like `np.repeat`.
-
- If `x` has shape `(s1, s2, s3)` and `axis` is `1`, the output
- will have shape `(s1, s2 * rep, s3)`.
-
- Arguments:
- x: Tensor or variable.
- rep: Python integer, number of times to repeat.
- axis: Axis along which to repeat.
-
- Returns:
- A tensor.
- """
- x_shape = x.get_shape().as_list()
- # For static axis
- if x_shape[axis] is not None:
- # slices along the repeat axis
- splits = array_ops.split(value=x,
- num_or_size_splits=x_shape[axis],
- axis=axis)
- # repeat each slice the given number of reps
- x_rep = [s for s in splits for _ in range(rep)]
- return concatenate(x_rep, axis)
-
- # Here we use tf.tile to mimic behavior of np.repeat so that
- # we can handle dynamic shapes (that include None).
- # To do that, we need an auxiliary axis to repeat elements along
- # it and then merge them along the desired axis.
-
- # Repeating
- auxiliary_axis = axis + 1
- x_shape = array_ops.shape(x)
- x_rep = array_ops.expand_dims(x, axis=auxiliary_axis)
- reps = np.ones(len(x.get_shape()) + 1)
- reps[auxiliary_axis] = rep
- x_rep = array_ops.tile(x_rep, reps)
-
- # Merging
- reps = np.delete(reps, auxiliary_axis)
- reps[axis] = rep
- reps = array_ops.constant(reps, dtype='int32')
- x_shape *= reps
- x_rep = array_ops.reshape(x_rep, x_shape)
-
- # Fix shape representation
- x_shape = x.get_shape().as_list()
- x_rep.set_shape(x_shape)
- x_rep._keras_shape = tuple(x_shape)
- return x_rep
-
-
-def repeat(x, n):
- """Repeats a 2D tensor.
-
- if `x` has shape (samples, dim) and `n` is `2`,
- the output will have shape `(samples, 2, dim)`.
-
- Arguments:
- x: Tensor or variable.
- n: Python integer, number of times to repeat.
-
- Returns:
- A tensor.
- """
- assert ndim(x) == 2
- x = array_ops.expand_dims(x, 1)
- pattern = array_ops.stack([1, n, 1])
- return array_ops.tile(x, pattern)
-
-
-def arange(start, stop=None, step=1, dtype='int32'):
- """Creates a 1D tensor containing a sequence of integers.
-
- The function arguments use the same convention as
- Theano's arange: if only one argument is provided,
- it is in fact the "stop" argument.
-
- The default type of the returned tensor is `'int32'` to
- match TensorFlow's default.
-
- Arguments:
- start: Start value.
- stop: Stop value.
- step: Difference between two successive values.
- dtype: Integer dtype to use.
-
- Returns:
- An integer tensor.
-
- """
- # Match the behavior of numpy and Theano by returning an empty seqence.
- if stop is None and start < 0:
- start = 0
- result = math_ops.range(start, limit=stop, delta=step, name='arange')
- if dtype != 'int32':
- result = cast(result, dtype)
- return result
-
-
-def tile(x, n):
- """Creates a tensor by tiling `x` by `n`.
-
- Arguments:
- x: A tensor or variable
- n: A list of integer. The length must be the same as the number of
- dimensions in `x`.
-
- Returns:
- A tiled tensor.
- """
- if isinstance(n, int):
- n = [n]
- return array_ops.tile(x, n)
-
-
-def flatten(x):
- """Flatten a tensor.
-
- Arguments:
- x: A tensor or variable.
-
- Returns:
- A tensor, reshaped into 1-D
- """
- return array_ops.reshape(x, [-1])
-
-
-def batch_flatten(x):
- """Turn a nD tensor into a 2D tensor with same 0th dimension.
-
- In other words, it flattens each data samples of a batch.
-
- Arguments:
- x: A tensor or variable.
-
- Returns:
- A tensor.
- """
- x = array_ops.reshape(x, array_ops.stack([-1, prod(shape(x)[1:])]))
- return x
-
-
-def expand_dims(x, axis=-1):
- """Adds a 1-sized dimension at index "axis".
-
- Arguments:
- x: A tensor or variable.
- axis: Position where to add a new axis.
-
- Returns:
- A tensor with expanded dimensions.
- """
- return array_ops.expand_dims(x, axis)
-
-
-def squeeze(x, axis):
- """Removes a 1-dimension from the tensor at index "axis".
-
- Arguments:
- x: A tensor or variable.
- axis: Axis to drop.
-
- Returns:
- A tensor with the same data as `x` but reduced dimensions.
- """
- return array_ops.squeeze(x, [axis])
-
-
-def temporal_padding(x, padding=(1, 1)):
- """Pads the middle dimension of a 3D tensor.
-
- Arguments:
- x: Tensor or variable.
- padding: Tuple of 2 integers, how many zeros to
- add at the start and end of dim 1.
-
- Returns:
- A padded 3D tensor.
- """
- assert len(padding) == 2
- pattern = [[0, 0], [padding[0], padding[1]], [0, 0]]
- return array_ops.pad(x, pattern)
-
-
-def spatial_2d_padding(x, padding=((1, 1), (1, 1)), data_format=None):
- """Pads the 2nd and 3rd dimensions of a 4D tensor.
-
- Arguments:
- x: Tensor or variable.
- padding: Tuple of 2 tuples, padding pattern.
- data_format: One of `channels_last` or `channels_first`.
-
- Returns:
- A padded 4D tensor.
-
- Raises:
- ValueError: if `data_format` is neither
- `channels_last` or `channels_first`.
- """
- assert len(padding) == 2
- assert len(padding[0]) == 2
- assert len(padding[1]) == 2
- if data_format is None:
- data_format = image_data_format()
- if data_format not in {'channels_first', 'channels_last'}:
- raise ValueError('Unknown data_format ' + str(data_format))
-
- if data_format == 'channels_first':
- pattern = [[0, 0], [0, 0], list(padding[0]), list(padding[1])]
- else:
- pattern = [[0, 0], list(padding[0]), list(padding[1]), [0, 0]]
- return array_ops.pad(x, pattern)
-
-
-def spatial_3d_padding(x, padding=((1, 1), (1, 1), (1, 1)), data_format=None):
- """Pads 5D tensor with zeros along the depth, height, width dimensions.
-
- Pads these dimensions with respectively
- "padding[0]", "padding[1]" and "padding[2]" zeros left and right.
-
- For 'channels_last' data_format,
- the 2nd, 3rd and 4th dimension will be padded.
- For 'channels_first' data_format,
- the 3rd, 4th and 5th dimension will be padded.
-
- Arguments:
- x: Tensor or variable.
- padding: Tuple of 3 tuples, padding pattern.
- data_format: One of `channels_last` or `channels_first`.
-
- Returns:
- A padded 5D tensor.
-
- Raises:
- ValueError: if `data_format` is neither
- `channels_last` or `channels_first`.
-
- """
- assert len(padding) == 3
- assert len(padding[0]) == 2
- assert len(padding[1]) == 2
- assert len(padding[2]) == 2
- if data_format is None:
- data_format = image_data_format()
- if data_format not in {'channels_first', 'channels_last'}:
- raise ValueError('Unknown data_format ' + str(data_format))
-
- if data_format == 'channels_first':
- pattern = [[0, 0], [0, 0], [padding[0][0], padding[0][1]],
- [padding[1][0], padding[1][1]], [padding[2][0], padding[2][1]]]
- else:
- pattern = [[0, 0], [padding[0][0], padding[0][1]],
- [padding[1][0], padding[1][1]], [padding[2][0],
- padding[2][1]], [0, 0]]
- return array_ops.pad(x, pattern)
-
-
-def stack(x, axis=0):
- """Stacks a list of rank `R` tensors into a rank `R+1` tensor.
-
- Arguments:
- x: List of tensors.
- axis: Axis along which to perform stacking.
-
- Returns:
- A tensor.
- """
- return array_ops.stack(x, axis=axis)
-
-
-def one_hot(indices, num_classes):
- """Computes the one-hot representation of an integer tensor.
-
- Arguments:
- indices: nD integer tensor of shape
- `(batch_size, dim1, dim2, ... dim(n-1))`
- num_classes: Integer, number of classes to consider.
-
- Returns:
- (n + 1)D one hot representation of the input
- with shape `(batch_size, dim1, dim2, ... dim(n-1), num_classes)`
-
- Returns:
- The one-hot tensor.
- """
- return array_ops.one_hot(indices, depth=num_classes, axis=-1)
-
-
-def reverse(x, axes):
- """Reverse a tensor along the specified axes.
-
- Arguments:
- x: Tensor to reverse.
- axes: Integer or iterable of integers.
- Axes to reverse.
-
- Returns:
- A tensor.
- """
- if isinstance(axes, int):
- axes = [axes]
- return array_ops.reverse(x, axes)
-
-
-# VALUE MANIPULATION
-
-
-def get_value(x):
- """Returns the value of a variable.
-
- Arguments:
- x: input variable.
-
- Returns:
- A Numpy array.
- """
- return x.eval(session=get_session())
-
-
-def batch_get_value(tensors):
- """Returns the value of more than one tensor variable.
-
- Arguments:
- tensors: list of ops to run.
-
- Returns:
- A list of Numpy arrays.
- """
- if tensors:
- return get_session().run(tensors)
- else:
- return []
-
-
-def set_value(x, value):
- """Sets the value of a variable, from a Numpy array.
-
- Arguments:
- x: Tensor to set to a new value.
- value: Value to set the tensor to, as a Numpy array
- (of the same shape).
- """
- value = np.asarray(value, dtype=dtype(x))
- tf_dtype = _convert_string_dtype(x.dtype.name.split('_')[0])
- if hasattr(x, '_assign_placeholder'):
- assign_placeholder = x._assign_placeholder
- assign_op = x._assign_op
- else:
- assign_placeholder = array_ops.placeholder(tf_dtype, shape=value.shape)
- assign_op = x.assign(assign_placeholder)
- x._assign_placeholder = assign_placeholder
- x._assign_op = assign_op
- get_session().run(assign_op, feed_dict={assign_placeholder: value})
-
-
-def batch_set_value(tuples):
- """Sets the values of many tensor variables at once.
-
- Arguments:
- tuples: a list of tuples `(tensor, value)`.
- `value` should be a Numpy array.
- """
- if tuples:
- assign_ops = []
- feed_dict = {}
- for x, value in tuples:
- value = np.asarray(value, dtype=dtype(x))
- tf_dtype = _convert_string_dtype(x.dtype.name.split('_')[0])
- if hasattr(x, '_assign_placeholder'):
- assign_placeholder = x._assign_placeholder
- assign_op = x._assign_op
- else:
- assign_placeholder = array_ops.placeholder(tf_dtype, shape=value.shape)
- assign_op = x.assign(assign_placeholder)
- x._assign_placeholder = assign_placeholder
- x._assign_op = assign_op
- assign_ops.append(assign_op)
- feed_dict[assign_placeholder] = value
- get_session().run(assign_ops, feed_dict=feed_dict)
-
-
-def print_tensor(x, message=''):
- """Prints `message` and the tensor value when evaluated.
-
- Arguments:
- x: Tensor to print.
- message: Message to print jointly with the tensor.
-
- Returns:
- The same tensor `x`, unchanged.
- """
- return logging_ops.Print(x, [x], message)
-
-
-# GRAPH MANIPULATION
-
-
-class Function(object):
- """Runs a computation graph.
-
- Arguments:
- inputs: Feed placeholders to the computation graph.
- outputs: Output tensors to fetch.
- updates: Additional update ops to be run at function call.
- name: a name to help users identify what this function does.
- """
-
- def __init__(self, inputs, outputs, updates=None, name=None,
- **session_kwargs):
- updates = updates or []
- if not isinstance(inputs, (list, tuple)):
- raise TypeError('`inputs` to a TensorFlow backend function '
- 'should be a list or tuple.')
- if not isinstance(outputs, (list, tuple)):
- raise TypeError('`outputs` of a TensorFlow backend function '
- 'should be a list or tuple.')
- if not isinstance(updates, (list, tuple)):
- raise TypeError('`updates` in a TensorFlow backend function '
- 'should be a list or tuple.')
- self.inputs = list(inputs)
- self.outputs = list(outputs)
- with ops.control_dependencies(self.outputs):
- updates_ops = []
- for update in updates:
- if isinstance(update, tuple):
- p, new_p = update
- updates_ops.append(state_ops.assign(p, new_p))
- else:
- # assumed already an op
- updates_ops.append(update)
- self.updates_op = control_flow_ops.group(*updates_ops)
- self.name = name
- self.session_kwargs = session_kwargs
-
- def __call__(self, inputs):
- if not isinstance(inputs, (list, tuple)):
- raise TypeError('`inputs` should be a list or tuple.')
- feed_dict = {}
- for tensor, value in zip(self.inputs, inputs):
- if is_sparse(tensor):
- sparse_coo = value.tocoo()
- indices = np.concatenate((np.expand_dims(sparse_coo.row, 1),
- np.expand_dims(sparse_coo.col, 1)), 1)
- value = (indices, sparse_coo.data, sparse_coo.shape)
- feed_dict[tensor] = value
- session = get_session()
- updated = session.run(
- self.outputs + [self.updates_op],
- feed_dict=feed_dict,
- **self.session_kwargs)
- return updated[:len(self.outputs)]
-
-
-def function(inputs, outputs, updates=None, **kwargs):
- """Instantiates a Keras function.
-
- Arguments:
- inputs: List of placeholder tensors.
- outputs: List of output tensors.
- updates: List of update ops.
- **kwargs: Passed to `tf.Session.run`.
-
- Returns:
- Output values as Numpy arrays.
-
- Raises:
- ValueError: if invalid kwargs are passed in.
- """
- if kwargs:
- for key in kwargs:
- if (key not in tf_inspect.getargspec(session_module.Session.run)[0] and
- key not in tf_inspect.getargspec(Function.__init__)[0]):
- msg = ('Invalid argument "%s" passed to K.function with Tensorflow '
- 'backend') % key
- raise ValueError(msg)
- return Function(inputs, outputs, updates=updates, **kwargs)
-
-
-def gradients(loss, variables):
- """Returns the gradients of `variables` w.r.t. `loss`.
-
- Arguments:
- loss: Scalar tensor to minimize.
- variables: List of variables.
-
- Returns:
- A gradients tensor.
- """
- return gradients_module.gradients(
- loss, variables, colocate_gradients_with_ops=True)
-
-
-def stop_gradient(variables):
- """Returns `variables` but with zero gradient w.r.t. every other variable.
-
- Arguments:
- variables: Tensor or list of tensors to consider constant with respect
- to any other variable.
-
-
- Returns:
- A single tensor or a list of tensors (depending on the passed argument)
- that has no gradient with respect to any other variable.
- """
- if isinstance(variables, (list, tuple)):
- return map(array_ops.stop_gradient, variables)
- return array_ops.stop_gradient(variables)
-
-
-# CONTROL FLOW
-
-
-def rnn(step_function,
- inputs,
- initial_states,
- go_backwards=False,
- mask=None,
- constants=None,
- unroll=False):
- """Iterates over the time dimension of a tensor.
-
- Arguments:
- step_function: RNN step function.
- Parameters;
- input; tensor with shape `(samples, ...)` (no time dimension),
- representing input for the batch of samples at a certain
- time step.
- states; list of tensors.
- Returns;
- output; tensor with shape `(samples, output_dim)`
- (no time dimension).
- new_states; list of tensors, same length and shapes
- as 'states'. The first state in the list must be the
- output tensor at the previous timestep.
- inputs: tensor of temporal data of shape `(samples, time, ...)`
- (at least 3D).
- initial_states: tensor with shape (samples, output_dim)
- (no time dimension),
- containing the initial values for the states used in
- the step function.
- go_backwards: boolean. If True, do the iteration over the time
- dimension in reverse order and return the reversed sequence.
- mask: binary tensor with shape `(samples, time, 1)`,
- with a zero for every element that is masked.
- constants: a list of constant values passed at each step.
- unroll: whether to unroll the RNN or to use a symbolic loop
- (`while_loop` or `scan` depending on backend).
-
- Returns:
- A tuple, `(last_output, outputs, new_states)`.
- last_output: the latest output of the rnn, of shape `(samples, ...)`
- outputs: tensor with shape `(samples, time, ...)` where each
- entry `outputs[s, t]` is the output of the step function
- at time `t` for sample `s`.
- new_states: list of tensors, latest states returned by
- the step function, of shape `(samples, ...)`.
-
- Raises:
- ValueError: if input dimension is less than 3.
- ValueError: if `unroll` is `True` but input timestep is not a fixed
- number.
- ValueError: if `mask` is provided (not `None`) but states is not provided
- (`len(states)` == 0).
- """
- ndim = len(inputs.get_shape())
- if ndim < 3:
- raise ValueError('Input should be at least 3D.')
- axes = [1, 0] + list(range(2, ndim))
- inputs = array_ops.transpose(inputs, (axes))
-
- if mask is not None:
- if mask.dtype != dtypes_module.bool:
- mask = math_ops.cast(mask, dtypes_module.bool)
- if len(mask.get_shape()) == ndim - 1:
- mask = expand_dims(mask)
- mask = array_ops.transpose(mask, axes)
-
- if constants is None:
- constants = []
-
- if unroll:
- if not inputs.get_shape()[0]:
- raise ValueError('Unrolling requires a ' 'fixed number of timesteps.')
- states = initial_states
- successive_states = []
- successive_outputs = []
-
- input_list = array_ops.unstack(inputs)
- if go_backwards:
- input_list.reverse()
-
- if mask is not None:
- mask_list = array_ops.unstack(mask)
- if go_backwards:
- mask_list.reverse()
-
- for inp, mask_t in zip(input_list, mask_list):
- output, new_states = step_function(inp, states + constants)
-
- # tf.where needs its condition tensor
- # to be the same shape as its two
- # result tensors, but in our case
- # the condition (mask) tensor is
- # (nsamples, 1), and A and B are (nsamples, ndimensions).
- # So we need to
- # broadcast the mask to match the shape of A and B.
- # That's what the tile call does,
- # it just repeats the mask along its second dimension
- # n times.
- tiled_mask_t = array_ops.tile(mask_t,
- array_ops.stack(
- [1, array_ops.shape(output)[1]]))
-
- if not successive_outputs:
- prev_output = zeros_like(output)
- else:
- prev_output = successive_outputs[-1]
-
- output = array_ops.where(tiled_mask_t, output, prev_output)
-
- return_states = []
- for state, new_state in zip(states, new_states):
- # (see earlier comment for tile explanation)
- tiled_mask_t = array_ops.tile(mask_t,
- array_ops.stack(
- [1,
- array_ops.shape(new_state)[1]]))
- return_states.append(array_ops.where(tiled_mask_t, new_state, state))
- states = return_states
- successive_outputs.append(output)
- successive_states.append(states)
- last_output = successive_outputs[-1]
- new_states = successive_states[-1]
- outputs = array_ops.stack(successive_outputs)
- else:
- for inp in input_list:
- output, states = step_function(inp, states + constants)
- successive_outputs.append(output)
- successive_states.append(states)
- last_output = successive_outputs[-1]
- new_states = successive_states[-1]
- outputs = array_ops.stack(successive_outputs)
-
- else:
- if go_backwards:
- inputs = reverse(inputs, 0)
-
- states = tuple(initial_states)
-
- time_steps = array_ops.shape(inputs)[0]
- outputs, _ = step_function(inputs[0], initial_states + constants)
- output_ta = tensor_array_ops.TensorArray(
- dtype=outputs.dtype, size=time_steps, tensor_array_name='output_ta')
- input_ta = tensor_array_ops.TensorArray(
- dtype=inputs.dtype, size=time_steps, tensor_array_name='input_ta')
- input_ta = input_ta.unstack(inputs)
- time = constant_op.constant(0, dtype='int32', name='time')
-
- if mask is not None:
- if not states:
- raise ValueError('No initial states provided! '
- 'When using masking in an RNN, you should '
- 'provide initial states '
- '(and your step function should return '
- 'as its first state at time `t` '
- 'the output at time `t-1`).')
- if go_backwards:
- mask = reverse(mask, 0)
-
- mask_ta = tensor_array_ops.TensorArray(
- dtype=dtypes_module.bool,
- size=time_steps,
- tensor_array_name='mask_ta')
- mask_ta = mask_ta.unstack(mask)
-
- def _step(time, output_ta_t, *states):
- """RNN step function.
-
- Arguments:
- time: Current timestep value.
- output_ta_t: TensorArray.
- *states: List of states.
-
- Returns:
- Tuple: `(time + 1,output_ta_t) + tuple(new_states)`
- """
- current_input = input_ta.read(time)
- mask_t = mask_ta.read(time)
- output, new_states = step_function(current_input,
- tuple(states) + tuple(constants))
- for state, new_state in zip(states, new_states):
- new_state.set_shape(state.get_shape())
- tiled_mask_t = array_ops.tile(mask_t,
- array_ops.stack(
- [1, array_ops.shape(output)[1]]))
- output = array_ops.where(tiled_mask_t, output, states[0])
- new_states = [
- array_ops.where(tiled_mask_t, new_states[i], states[i])
- for i in range(len(states))
- ]
- output_ta_t = output_ta_t.write(time, output)
- return (time + 1, output_ta_t) + tuple(new_states)
- else:
-
- def _step(time, output_ta_t, *states):
- """RNN step function.
-
- Arguments:
- time: Current timestep value.
- output_ta_t: TensorArray.
- *states: List of states.
-
- Returns:
- Tuple: `(time + 1,output_ta_t) + tuple(new_states)`
- """
- current_input = input_ta.read(time)
- output, new_states = step_function(current_input,
- tuple(states) + tuple(constants))
- for state, new_state in zip(states, new_states):
- new_state.set_shape(state.get_shape())
- output_ta_t = output_ta_t.write(time, output)
- return (time + 1, output_ta_t) + tuple(new_states)
-
- final_outputs = control_flow_ops.while_loop(
- cond=lambda time, *_: time < time_steps,
- body=_step,
- loop_vars=(time, output_ta) + states,
- parallel_iterations=32,
- swap_memory=True)
- last_time = final_outputs[0]
- output_ta = final_outputs[1]
- new_states = final_outputs[2:]
-
- outputs = output_ta.stack()
- last_output = output_ta.read(last_time - 1)
-
- axes = [1, 0] + list(range(2, len(outputs.get_shape())))
- outputs = array_ops.transpose(outputs, axes)
- return last_output, outputs, new_states
-
-
-def switch(condition, then_expression, else_expression):
- """Switches between two operations depending on a scalar value.
-
- Note that both `then_expression` and `else_expression`
- should be symbolic tensors of the *same shape*.
-
- Arguments:
- condition: scalar tensor (`int` or `bool`).
- then_expression: either a tensor, or a callable that returns a tensor.
- else_expression: either a tensor, or a callable that returns a tensor.
-
- Returns:
- The selected tensor.
- """
- if condition.dtype != dtypes_module.bool:
- condition = math_ops.cast(condition, 'bool')
- if not callable(then_expression):
-
- def then_expression_fn():
- return then_expression
- else:
- then_expression_fn = then_expression
- if not callable(else_expression):
-
- def else_expression_fn():
- return else_expression
- else:
- else_expression_fn = else_expression
- x = control_flow_ops.cond(condition, then_expression_fn, else_expression_fn)
- return x
-
-
-def in_train_phase(x, alt, training=None):
- """Selects `x` in train phase, and `alt` otherwise.
-
- Note that `alt` should have the *same shape* as `x`.
-
- Arguments:
- x: What to return in train phase
- (tensor or callable that returns a tensor).
- alt: What to return otherwise
- (tensor or callable that returns a tensor).
- training: Optional scalar tensor
- (or Python boolean, or Python integer)
- specifying the learning phase.
-
- Returns:
- Either `x` or `alt` based on the `training` flag.
- the `training` flag defaults to `K.learning_phase()`.
- """
- if training is None:
- training = learning_phase()
- uses_learning_phase = True
- else:
- uses_learning_phase = False
-
- if training is 1 or training is True:
- if callable(x):
- return x()
- else:
- return x
-
- elif training is 0 or training is False:
- if callable(alt):
- return alt()
- else:
- return alt
-
- # else: assume learning phase is a placeholder tensor.
- x = switch(training, x, alt)
- if uses_learning_phase:
- x._uses_learning_phase = True
- return x
-
-
-def in_test_phase(x, alt, training=None):
- """Selects `x` in test phase, and `alt` otherwise.
-
- Note that `alt` should have the *same shape* as `x`.
-
- Arguments:
- x: What to return in test phase
- (tensor or callable that returns a tensor).
- alt: What to return otherwise
- (tensor or callable that returns a tensor).
- training: Optional scalar tensor
- (or Python boolean, or Python integer)
- specifying the learning phase.
-
- Returns:
- Either `x` or `alt` based on `K.learning_phase`.
- """
- return in_train_phase(alt, x, training=training)
-
-
-# NN OPERATIONS
-
-
-def relu(x, alpha=0., max_value=None):
- """Rectified linear unit.
-
- With default values, it returns element-wise `max(x, 0)`.
-
- Arguments:
- x: A tensor or variable.
- alpha: A scalar, slope of negative section (default=`0.`).
- max_value: Saturation threshold.
-
- Returns:
- A tensor.
- """
- if alpha != 0.:
- negative_part = nn.relu(-x)
- x = nn.relu(x)
- if max_value is not None:
- max_value = _to_tensor(max_value, x.dtype.base_dtype)
- zero = _to_tensor(0., x.dtype.base_dtype)
- x = clip_ops.clip_by_value(x, zero, max_value)
- if alpha != 0.:
- alpha = _to_tensor(alpha, x.dtype.base_dtype)
- x -= alpha * negative_part
- return x
-
-
-def elu(x, alpha=1.):
- """Exponential linear unit.
-
- Arguments:
- x: A tenor or variable to compute the activation function for.
- alpha: A scalar, slope of positive section.
-
- Returns:
- A tensor.
- """
- res = nn.elu(x)
- if alpha == 1:
- return res
- else:
- return array_ops.where(x > 0, res, alpha * res)
-
-
-def softmax(x):
- """Softmax of a tensor.
-
- Arguments:
- x: A tensor or variable.
-
- Returns:
- A tensor.
- """
- return nn.softmax(x)
-
-
-def softplus(x):
- """Softplus of a tensor.
-
- Arguments:
- x: A tensor or variable.
-
- Returns:
- A tensor.
- """
- return nn.softplus(x)
-
-
-def softsign(x):
- """Softsign of a tensor.
-
- Arguments:
- x: A tensor or variable.
-
- Returns:
- A tensor.
- """
- return nn.softsign(x)
-
-
-def categorical_crossentropy(target, output, from_logits=False):
- """Categorical crossentropy between an output tensor and a target tensor.
-
- Arguments:
- target: A tensor of the same shape as `output`.
- output: A tensor resulting from a softmax
- (unless `from_logits` is True, in which
- case `output` is expected to be the logits).
- from_logits: Boolean, whether `output` is the
- result of a softmax, or is a tensor of logits.
-
- Returns:
- Output tensor.
- """
- # Note: nn.softmax_cross_entropy_with_logits
- # expects logits, Keras expects probabilities.
- if not from_logits:
- # scale preds so that the class probas of each sample sum to 1
- output /= math_ops.reduce_sum(
- output, axis=len(output.get_shape()) - 1, keep_dims=True)
- # manual computation of crossentropy
- epsilon_ = _to_tensor(epsilon(), output.dtype.base_dtype)
- output = clip_ops.clip_by_value(output, epsilon_, 1. - epsilon_)
- return -math_ops.reduce_sum(
- target * math_ops.log(output),
- axis=len(output.get_shape()) - 1)
- else:
- return nn.softmax_cross_entropy_with_logits(labels=target, logits=output)
-
-
-def sparse_categorical_crossentropy(target, output, from_logits=False):
- """Categorical crossentropy with integer targets.
-
- Arguments:
- target: An integer tensor.
- output: A tensor resulting from a softmax
- (unless `from_logits` is True, in which
- case `output` is expected to be the logits).
- from_logits: Boolean, whether `output` is the
- result of a softmax, or is a tensor of logits.
-
- Returns:
- Output tensor.
- """
- # Note: nn.sparse_softmax_cross_entropy_with_logits
- # expects logits, Keras expects probabilities.
- if not from_logits:
- epsilon_ = _to_tensor(epsilon(), output.dtype.base_dtype)
- output = clip_ops.clip_by_value(output, epsilon_, 1 - epsilon_)
- output = math_ops.log(output)
-
- output_shape = output.get_shape()
- targets = cast(flatten(target), 'int64')
- logits = array_ops.reshape(output, [-1, int(output_shape[-1])])
- res = nn.sparse_softmax_cross_entropy_with_logits(
- labels=targets, logits=logits)
- if len(output_shape) == 3:
- # if our output includes timesteps we need to reshape
- return array_ops.reshape(res, array_ops.shape(output)[:-1])
- else:
- return res
-
-
-def binary_crossentropy(target, output, from_logits=False):
- """Binary crossentropy between an output tensor and a target tensor.
-
- Arguments:
- target: A tensor with the same shape as `output`.
- output: A tensor.
- from_logits: Whether `output` is expected to be a logits tensor.
- By default, we consider that `output`
- encodes a probability distribution.
-
- Returns:
- A tensor.
- """
- # Note: nn.softmax_cross_entropy_with_logits
- # expects logits, Keras expects probabilities.
- if not from_logits:
- # transform back to logits
- epsilon_ = _to_tensor(epsilon(), output.dtype.base_dtype)
- output = clip_ops.clip_by_value(output, epsilon_, 1 - epsilon_)
- output = math_ops.log(output / (1 - output))
- return nn.sigmoid_cross_entropy_with_logits(labels=target, logits=output)
-
-
-def sigmoid(x):
- """Element-wise sigmoid.
-
- Arguments:
- x: A tensor or variable.
-
- Returns:
- A tensor.
- """
- return nn.sigmoid(x)
-
-
-def hard_sigmoid(x):
- """Segment-wise linear approximation of sigmoid.
-
- Faster than sigmoid.
- Returns `0.` if `x < -2.5`, `1.` if `x > 2.5`.
- In `-2.5 <= x <= 2.5`, returns `0.2 * x + 0.5`.
-
- Arguments:
- x: A tensor or variable.
-
- Returns:
- A tensor.
- """
- x = (0.2 * x) + 0.5
- zero = _to_tensor(0., x.dtype.base_dtype)
- one = _to_tensor(1., x.dtype.base_dtype)
- x = clip_ops.clip_by_value(x, zero, one)
- return x
-
-
-def tanh(x):
- """Element-wise tanh.
-
- Arguments:
- x: A tensor or variable.
-
- Returns:
- A tensor.
- """
- return nn.tanh(x)
-
-
-def dropout(x, level, noise_shape=None, seed=None):
- """Sets entries in `x` to zero at random, while scaling the entire tensor.
-
- Arguments:
- x: tensor
- level: fraction of the entries in the tensor
- that will be set to 0.
- noise_shape: shape for randomly generated keep/drop flags,
- must be broadcastable to the shape of `x`
- seed: random seed to ensure determinism.
-
- Returns:
- A tensor.
- """
- retain_prob = 1. - level
- if seed is None:
- seed = np.random.randint(10e6)
- # the dummy 1. works around a TF bug
- # (float32_ref vs. float32 incompatibility)
- return nn.dropout(x * 1., retain_prob, noise_shape, seed=seed)
-
-
-def l2_normalize(x, axis=None):
- """Normalizes a tensor wrt the L2 norm alongside the specified axis.
-
- Arguments:
- x: Tensor or variable.
- axis: axis along which to perform normalization.
-
- Returns:
- A tensor.
- """
- return nn.l2_normalize(x, dim=axis)
-
-
-def in_top_k(predictions, targets, k):
- """Returns whether the `targets` are in the top `k` `predictions`.
-
- Arguments:
- predictions: A tensor of shape `(batch_size, classes)` and type `float32`.
- targets: A 1D tensor of length `batch_size` and type `int32` or `int64`.
- k: An `int`, number of top elements to consider.
-
- Returns:
- A 1D tensor of length `batch_size` and type `bool`.
- `output[i]` is `True` if `predictions[i, targets[i]]` is within top-`k`
- values of `predictions[i]`.
- """
- return nn.in_top_k(predictions, targets, k)
-
-
-# CONVOLUTIONS
-
-
-def _preprocess_deconv_output_shape(x, shape, data_format):
- """Get the output_shape for the deconvolution.
-
- Arguments:
- x: input tensor.
- shape: output shape.
- data_format: string, one of 'channels_last', 'channels_first'.
-
- Returns:
- The output shape.
- """
- if data_format == 'channels_first':
- shape = (shape[0], shape[2], shape[3], shape[1])
-
- if shape[0] is None:
- shape = (array_ops.shape(x)[0],) + tuple(shape[1:])
- shape = array_ops.stack(list(shape))
- return shape
-
-
-def _preprocess_conv2d_input(x, data_format):
- """Transpose and cast the input before the conv2d.
-
- Arguments:
- x: input tensor.
- data_format: string, one of 'channels_last', 'channels_first'.
-
- Returns:
- A tensor.
- """
- if dtype(x) == 'float64':
- x = math_ops.cast(x, 'float32')
- if data_format == 'channels_first':
- # TF uses the last dimension as channel dimension,
- # instead of the 2nd one.
- # TH input shape: (samples, input_depth, rows, cols)
- # TF input shape: (samples, rows, cols, input_depth)
- x = array_ops.transpose(x, (0, 2, 3, 1))
- return x
-
-
-def _preprocess_conv3d_input(x, data_format):
- """Transpose and cast the input before the conv3d.
-
- Arguments:
- x: input tensor.
- data_format: string, one of 'channels_last', 'channels_first'.
-
- Returns:
- A tensor.
- """
- if dtype(x) == 'float64':
- x = math_ops.cast(x, 'float32')
- if data_format == 'channels_first':
- x = array_ops.transpose(x, (0, 2, 3, 4, 1))
- return x
-
-
-def _preprocess_padding(padding):
- """Convert keras' padding to tensorflow's padding.
-
- Arguments:
- padding: string, one of 'same' , 'valid'
-
- Returns:
- a string, one of 'SAME', 'VALID'.
-
- Raises:
- ValueError: if invalid `padding'`
- """
- if padding == 'same':
- padding = 'SAME'
- elif padding == 'valid':
- padding = 'VALID'
- else:
- raise ValueError('Invalid padding:', padding)
- return padding
-
-
-def _postprocess_conv2d_output(x, data_format):
- """Transpose and cast the output from conv2d if needed.
-
- Arguments:
- x: A tensor.
- data_format: string, one of "channels_last", "channels_first".
-
- Returns:
- A tensor.
- """
-
- if data_format == 'channels_first':
- x = array_ops.transpose(x, (0, 3, 1, 2))
-
- if floatx() == 'float64':
- x = math_ops.cast(x, 'float64')
- return x
-
-
-def _postprocess_conv3d_output(x, data_format):
- """Transpose and cast the output from conv3d if needed.
-
- Arguments:
- x: A tensor.
- data_format: string, one of "channels_last", "channels_first".
-
- Returns:
- A tensor.
- """
- if data_format == 'channels_first':
- x = array_ops.transpose(x, (0, 4, 1, 2, 3))
-
- if floatx() == 'float64':
- x = math_ops.cast(x, 'float64')
- return x
-
-
-def conv1d(x,
- kernel,
- strides=1,
- padding='valid',
- data_format=None,
- dilation_rate=1):
- """1D convolution.
-
- Arguments:
- x: Tensor or variable.
- kernel: kernel tensor.
- strides: stride integer.
- padding: string, `"same"`, `"causal"` or `"valid"`.
- data_format: string, one of "channels_last", "channels_first".
- dilation_rate: integer dilate rate.
-
- Returns:
- A tensor, result of 1D convolution.
- """
- kernel_shape = kernel.get_shape().as_list()
- if padding == 'causal':
- # causal (dilated) convolution:
- left_pad = dilation_rate * (kernel_shape[0] - 1)
- x = temporal_padding(x, (left_pad, 0))
- padding = 'valid'
- padding = _preprocess_padding(padding)
- if data_format == 'channels_last':
- tf_data_format = 'NWC'
- else:
- tf_data_format = 'NCW'
- x = nn.convolution(
- input=x,
- filter=kernel,
- dilation_rate=(dilation_rate,),
- strides=(strides,),
- padding=padding,
- data_format=tf_data_format)
- return x
-
-
-def conv2d(x,
- kernel,
- strides=(1, 1),
- padding='valid',
- data_format=None,
- dilation_rate=(1, 1)):
- """2D convolution.
-
- Arguments:
- x: Tensor or variable.
- kernel: kernel tensor.
- strides: strides tuple.
- padding: string, `"same"` or `"valid"`.
- data_format: `"channels_last"` or `"channels_first"`.
- Whether to use Theano or TensorFlow data format
- for inputs/kernels/outputs.
- dilation_rate: tuple of 2 integers.
-
- Returns:
- A tensor, result of 2D convolution.
-
- Raises:
- ValueError: if `data_format` is neither `channels_last` or
- `channels_first`.
- """
- if data_format is None:
- data_format = image_data_format()
- if data_format not in {'channels_first', 'channels_last'}:
- raise ValueError('Unknown data_format ' + str(data_format))
-
- # With 4d inputs, nn.convolution only supports
- # data_format NHWC, so we transpose the inputs
- # in case we are in data_format channels_first.
- x = _preprocess_conv2d_input(x, data_format)
- padding = _preprocess_padding(padding)
- x = nn.convolution(
- input=x,
- filter=kernel,
- dilation_rate=dilation_rate,
- strides=strides,
- padding=padding,
- data_format='NHWC')
- return _postprocess_conv2d_output(x, data_format)
-
-
-def conv2d_transpose(x,
- kernel,
- output_shape,
- strides=(1, 1),
- padding='valid',
- data_format=None):
- """2D deconvolution (i.e.
-
- transposed convolution).
-
- Arguments:
- x: Tensor or variable.
- kernel: kernel tensor.
- output_shape: 1D int tensor for the output shape.
- strides: strides tuple.
- padding: string, `"same"` or `"valid"`.
- data_format: `"channels_last"` or `"channels_first"`.
- Whether to use Theano or TensorFlow data format
- for inputs/kernels/outputs.
-
- Returns:
- A tensor, result of transposed 2D convolution.
-
- Raises:
- ValueError: if `data_format` is neither `channels_last` or
- `channels_first`.
- """
- if data_format is None:
- data_format = image_data_format()
- if data_format not in {'channels_first', 'channels_last'}:
- raise ValueError('Unknown data_format ' + str(data_format))
- if isinstance(output_shape, (tuple, list)):
- output_shape = array_ops.stack(output_shape)
-
- x = _preprocess_conv2d_input(x, data_format)
- output_shape = _preprocess_deconv_output_shape(x, output_shape, data_format)
- padding = _preprocess_padding(padding)
- strides = (1,) + strides + (1,)
-
- x = nn.conv2d_transpose(x, kernel, output_shape, strides, padding=padding)
- x = _postprocess_conv2d_output(x, data_format)
- return x
-
-
-def separable_conv2d(x,
- depthwise_kernel,
- pointwise_kernel,
- strides=(1, 1),
- padding='valid',
- data_format=None,
- dilation_rate=(1, 1)):
- """2D convolution with separable filters.
-
- Arguments:
- x: input tensor
- depthwise_kernel: convolution kernel for the depthwise convolution.
- pointwise_kernel: kernel for the 1x1 convolution.
- strides: strides tuple (length 2).
- padding: padding mode, "valid" or "same".
- data_format: data format, "channels_first" or "channels_last".
- dilation_rate: tuple of integers,
- dilation rates for the separable convolution.
-
- Returns:
- Output tensor.
-
- Raises:
- ValueError: if `data_format` is neither `channels_last` or
- `channels_first`.
- """
- if data_format is None:
- data_format = image_data_format()
- if data_format not in {'channels_first', 'channels_last'}:
- raise ValueError('Unknown data_format ' + str(data_format))
-
- x = _preprocess_conv2d_input(x, data_format)
- padding = _preprocess_padding(padding)
- strides = (1,) + strides + (1,)
-
- x = nn.separable_conv2d(
- x,
- depthwise_kernel,
- pointwise_kernel,
- strides=strides,
- padding=padding,
- rate=dilation_rate)
- return _postprocess_conv2d_output(x, data_format)
-
-
-def depthwise_conv2d(x, depthwise_kernel, strides=(1, 1), padding='valid',
- data_format=None, dilation_rate=(1, 1)):
- """2D convolution with separable filters.
-
- Arguments:
- x: input tensor
- depthwise_kernel: convolution kernel for the depthwise convolution.
- strides: strides tuple (length 2).
- padding: string, `"same"` or `"valid"`.
- data_format: string, `"channels_last"` or `"channels_first"`.
- dilation_rate: tuple of integers,
- dilation rates for the separable convolution.
-
- Returns:
- Output tensor.
-
- Raises:
- ValueError: if `data_format` is neither `channels_last`
- or `channels_first`.
- """
- if data_format is None:
- data_format = image_data_format()
- if data_format not in {'channels_first', 'channels_last'}:
- raise ValueError('Unknown data_format ' + str(data_format))
-
- x = _preprocess_conv2d_input(x, data_format)
- padding = _preprocess_padding(padding)
- strides = (1,) + strides + (1,)
-
- x = nn.depthwise_conv2d(x, depthwise_kernel,
- strides=strides,
- padding=padding,
- rate=dilation_rate)
- return _postprocess_conv2d_output(x, data_format)
-
-
-def conv3d(x,
- kernel,
- strides=(1, 1, 1),
- padding='valid',
- data_format=None,
- dilation_rate=(1, 1, 1)):
- """3D convolution.
-
- Arguments:
- x: Tensor or variable.
- kernel: kernel tensor.
- strides: strides tuple.
- padding: string, `"same"` or `"valid"`.
- data_format: `"channels_last"` or `"channels_first"`.
- Whether to use Theano or TensorFlow data format
- for inputs/kernels/outputs.
- dilation_rate: tuple of 3 integers.
-
- Returns:
- A tensor, result of 3D convolution.
-
- Raises:
- ValueError: if `data_format` is neither `channels_last` or
- `channels_first`.
- """
- if data_format is None:
- data_format = image_data_format()
- if data_format not in {'channels_first', 'channels_last'}:
- raise ValueError('Unknown data_format ' + str(data_format))
-
- # With 5d inputs, nn.convolution only supports
- # data_format NDHWC, so we transpose the inputs
- # in case we are in data_format channels_first.
- x = _preprocess_conv3d_input(x, data_format)
- padding = _preprocess_padding(padding)
- x = nn.convolution(
- input=x,
- filter=kernel,
- dilation_rate=dilation_rate,
- strides=strides,
- padding=padding,
- data_format='NDHWC')
- return _postprocess_conv3d_output(x, data_format)
-
-
-def pool2d(x,
- pool_size,
- strides=(1, 1),
- padding='valid',
- data_format=None,
- pool_mode='max'):
- """2D Pooling.
-
- Arguments:
- x: Tensor or variable.
- pool_size: tuple of 2 integers.
- strides: tuple of 2 integers.
- padding: one of `"valid"`, `"same"`.
- data_format: one of `"channels_first"`, `"channels_last"`.
- pool_mode: one of `"max"`, `"avg"`.
-
- Returns:
- A tensor, result of 2D pooling.
-
- Raises:
- ValueError: if `data_format` is neither `channels_last` or
- `channels_first`.
- ValueError: if `pool_mode` is neither `max` or `avg`.
- """
- if data_format is None:
- data_format = image_data_format()
- if data_format not in {'channels_first', 'channels_last'}:
- raise ValueError('Unknown data_format ' + str(data_format))
-
- padding = _preprocess_padding(padding)
- strides = (1,) + strides + (1,)
- pool_size = (1,) + pool_size + (1,)
-
- x = _preprocess_conv2d_input(x, data_format)
-
- if pool_mode == 'max':
- x = nn.max_pool(x, pool_size, strides, padding=padding)
- elif pool_mode == 'avg':
- x = nn.avg_pool(x, pool_size, strides, padding=padding)
- else:
- raise ValueError('Invalid pooling mode:', pool_mode)
-
- return _postprocess_conv2d_output(x, data_format)
-
-
-def pool3d(x,
- pool_size,
- strides=(1, 1, 1),
- padding='valid',
- data_format=None,
- pool_mode='max'):
- """3D Pooling.
-
- Arguments:
- x: Tensor or variable.
- pool_size: tuple of 3 integers.
- strides: tuple of 3 integers.
- padding: one of `"valid"`, `"same"`.
- data_format: one of `"channels_first"`, `"channels_last"`.
- pool_mode: one of `"max"`, `"avg"`.
-
- Returns:
- A tensor, result of 3D pooling.
-
- Raises:
- ValueError: if `data_format` is neither
- `channels_last` or `channels_first`.
- ValueError: if `pool_mode` is neither `max` or `avg`.
- """
- if data_format is None:
- data_format = image_data_format()
- if data_format not in {'channels_first', 'channels_last'}:
- raise ValueError('Unknown data_format ' + str(data_format))
-
- padding = _preprocess_padding(padding)
- strides = (1,) + strides + (1,)
- pool_size = (1,) + pool_size + (1,)
-
- x = _preprocess_conv3d_input(x, data_format)
-
- if pool_mode == 'max':
- x = nn.max_pool3d(x, pool_size, strides, padding=padding)
- elif pool_mode == 'avg':
- x = nn.avg_pool3d(x, pool_size, strides, padding=padding)
- else:
- raise ValueError('Invalid pooling mode:', pool_mode)
-
- return _postprocess_conv3d_output(x, data_format)
-
-
-def local_conv1d(inputs, kernel, kernel_size, strides, data_format=None):
- """Apply 1D conv with un-shared weights.
-
- Arguments:
- inputs: 3D tensor with shape: (batch_size, steps, input_dim)
- kernel: the unshared weight for convolution,
- with shape (output_length, feature_dim, filters)
- kernel_size: a tuple of a single integer,
- specifying the length of the 1D convolution window
- strides: a tuple of a single integer,
- specifying the stride length of the convolution
- data_format: the data format, channels_first or channels_last
-
- Returns:
- the tensor after 1d conv with un-shared weights, with shape (batch_size,
- output_length, filters)
-
- Raises:
- ValueError: if `data_format` is neither `channels_last` or
- `channels_first`.
- """
- if data_format is None:
- data_format = image_data_format()
- if data_format not in {'channels_first', 'channels_last'}:
- raise ValueError('Unknown data_format ' + str(data_format))
-
- stride = strides[0]
- kernel_shape = int_shape(kernel)
- output_length = kernel_shape[0]
- feature_dim = kernel_shape[1]
-
- xs = []
- for i in range(output_length):
- slice_length = slice(i * stride, i * stride + kernel_size[0])
- xs.append(reshape(inputs[:, slice_length, :], (1, -1, feature_dim)))
- x_aggregate = concatenate(xs, axis=0)
- # Shape: `(output_length, batch_size, filters)`.
- output = batch_dot(x_aggregate, kernel)
- return permute_dimensions(output, (1, 0, 2))
-
-
-def local_conv2d(inputs,
- kernel,
- kernel_size,
- strides,
- output_shape,
- data_format=None):
- """Apply 2D conv with un-shared weights.
-
- Arguments:
- inputs: 4D tensor with shape:
- (batch_size, filters, new_rows, new_cols)
- if data_format='channels_first'
- or 4D tensor with shape:
- (batch_size, new_rows, new_cols, filters)
- if data_format='channels_last'.
- kernel: the unshared weight for convolution,
- with shape (output_items, feature_dim, filters)
- kernel_size: a tuple of 2 integers, specifying the
- width and height of the 2D convolution window.
- strides: a tuple of 2 integers, specifying the strides
- of the convolution along the width and height.
- output_shape: a tuple with (output_row, output_col)
- data_format: the data format, channels_first or channels_last
-
- Returns:
- A 4d tensor with shape:
- (batch_size, filters, new_rows, new_cols)
- if data_format='channels_first'
- or 4D tensor with shape:
- (batch_size, new_rows, new_cols, filters)
- if data_format='channels_last'.
-
- Raises:
- ValueError: if `data_format` is neither
- `channels_last` or `channels_first`.
- """
- if data_format is None:
- data_format = image_data_format()
- if data_format not in {'channels_first', 'channels_last'}:
- raise ValueError('Unknown data_format ' + str(data_format))
-
- stride_row, stride_col = strides
- output_row, output_col = output_shape
- kernel_shape = int_shape(kernel)
- feature_dim = kernel_shape[1]
- filters = kernel_shape[2]
-
- xs = []
- for i in range(output_row):
- for j in range(output_col):
- slice_row = slice(i * stride_row, i * stride_row + kernel_size[0])
- slice_col = slice(j * stride_col, j * stride_col + kernel_size[1])
- if data_format == 'channels_first':
- xs.append(
- reshape(inputs[:, :, slice_row, slice_col], (1, -1, feature_dim)))
- else:
- xs.append(
- reshape(inputs[:, slice_row, slice_col, :], (1, -1, feature_dim)))
-
- x_aggregate = concatenate(xs, axis=0)
- output = batch_dot(x_aggregate, kernel)
- output = reshape(output, (output_row, output_col, -1, filters))
-
- if data_format == 'channels_first':
- output = permute_dimensions(output, (2, 3, 0, 1))
- else:
- output = permute_dimensions(output, (2, 0, 1, 3))
- return output
-
-
-def bias_add(x, bias, data_format=None):
- """Adds a bias vector to a tensor.
-
- Arguments:
- x: Tensor or variable.
- bias: Bias tensor to add.
- data_format: string, `"channels_last"` or `"channels_first"`.
-
- Returns:
- Output tensor.
-
- Raises:
- ValueError: In one of the two cases below:
- 1. invalid `data_format` argument.
- 2. invalid bias shape.
- the bias should be either a vector or
- a tensor with ndim(x) - 1 dimension
- """
- if data_format is None:
- data_format = image_data_format()
- if data_format not in {'channels_first', 'channels_last'}:
- raise ValueError('Unknown data_format ' + str(data_format))
- bias_shape = int_shape(bias)
- if len(bias_shape) != 1 and len(bias_shape) != ndim(x) - 1:
- raise ValueError(
- 'Unexpected bias dimensions %d, expect to be 1 or %d dimensions' %
- (len(bias_shape), ndim(x)))
- if ndim(x) == 5:
- if data_format == 'channels_first':
- if len(bias_shape) == 1:
- x += reshape(bias, (1, bias_shape[0], 1, 1, 1))
- else:
- x += reshape(bias, (1, bias_shape[3]) + bias_shape[:3])
- elif data_format == 'channels_last':
- if len(bias_shape) == 1:
- x += reshape(bias, (1, 1, 1, bias_shape[0]))
- else:
- x += reshape(bias, (1,) + bias_shape)
- elif ndim(x) == 4:
- if data_format == 'channels_first':
- if len(bias_shape) == 1:
- x += reshape(bias, (1, bias_shape[0], 1, 1))
- else:
- x += reshape(bias, (1, bias_shape[2]) + bias_shape[:2])
- elif data_format == 'channels_last':
- if len(bias_shape) == 1:
- x = nn.bias_add(x, bias, data_format='NHWC')
- else:
- x += reshape(bias, (1,) + bias_shape)
- elif ndim(x) == 3:
- if data_format == 'channels_first':
- if len(bias_shape) == 1:
- x += reshape(bias, (1, bias_shape[0], 1))
- else:
- x += reshape(bias, (1, bias_shape[1], bias_shape[0]))
- elif data_format == 'channels_last':
- if len(bias_shape) == 1:
- x += reshape(bias, (1, 1, bias_shape[0]))
- else:
- x += reshape(bias, (1,) + bias_shape)
- else:
- x = nn.bias_add(x, bias)
- return x
-
-
-# RANDOMNESS
-
-
-def random_normal(shape, mean=0.0, stddev=1.0, dtype=None, seed=None):
- """Returns a tensor with normal distribution of values.
-
- Arguments:
- shape: A tuple of integers, the shape of tensor to create.
- mean: A float, mean of the normal distribution to draw samples.
- stddev: A float, standard deviation of the normal distribution
- to draw samples.
- dtype: String, dtype of returned tensor.
- seed: Integer, random seed.
-
- Returns:
- A tensor.
- """
- if dtype is None:
- dtype = floatx()
- if seed is None:
- seed = np.random.randint(10e6)
- return random_ops.random_normal(
- shape, mean=mean, stddev=stddev, dtype=dtype, seed=seed)
-
-
-def random_uniform(shape, minval=0.0, maxval=1.0, dtype=None, seed=None):
- """Returns a tensor with uniform distribution of values.
-
- Arguments:
- shape: A tuple of integers, the shape of tensor to create.
- minval: A float, lower boundary of the uniform distribution
- to draw samples.
- maxval: A float, upper boundary of the uniform distribution
- to draw samples.
- dtype: String, dtype of returned tensor.
- seed: Integer, random seed.
-
- Returns:
- A tensor.
- """
- if dtype is None:
- dtype = floatx()
- if seed is None:
- seed = np.random.randint(10e6)
- return random_ops.random_uniform(
- shape, minval=minval, maxval=maxval, dtype=dtype, seed=seed)
-
-
-def random_binomial(shape, p=0.0, dtype=None, seed=None):
- """Returns a tensor with random binomial distribution of values.
-
- Arguments:
- shape: A tuple of integers, the shape of tensor to create.
- p: A float, `0. <= p <= 1`, probability of binomial distribution.
- dtype: String, dtype of returned tensor.
- seed: Integer, random seed.
-
- Returns:
- A tensor.
- """
- if dtype is None:
- dtype = floatx()
- if seed is None:
- seed = np.random.randint(10e6)
- return array_ops.where(
- random_ops.random_uniform(shape, dtype=dtype, seed=seed) <= p,
- array_ops.ones(shape, dtype=dtype), array_ops.zeros(shape, dtype=dtype))
-
-
-def truncated_normal(shape, mean=0.0, stddev=1.0, dtype=None, seed=None):
- """Returns a tensor with truncated random normal distribution of values.
-
- The generated values follow a normal distribution
- with specified mean and standard deviation,
- except that values whose magnitude is more than
- two standard deviations from the mean are dropped and re-picked.
-
- Arguments:
- shape: A tuple of integers, the shape of tensor to create.
- mean: Mean of the values.
- stddev: Standard deviation of the values.
- dtype: String, dtype of returned tensor.
- seed: Integer, random seed.
-
- Returns:
- A tensor.
- """
- if dtype is None:
- dtype = floatx()
- if seed is None:
- seed = np.random.randint(10e6)
- return random_ops.truncated_normal(
- shape, mean, stddev, dtype=dtype, seed=seed)
-
-
-# CTC
-# tensorflow has a native implemenation, but it uses sparse tensors
-# and therefore requires a wrapper for Keras. The functions below convert
-# dense to sparse tensors and also wraps up the beam search code that is
-# in tensorflow's CTC implementation
-
-
-def ctc_label_dense_to_sparse(labels, label_lengths):
- """Converts CTC labels from dense to sparse.
-
- Arguments:
- labels: dense CTC labels.
- label_lengths: length of the labels.
-
- Returns:
- A sparse tensor representation of the labels.
- """
- label_shape = array_ops.shape(labels)
- num_batches_tns = array_ops.stack([label_shape[0]])
- max_num_labels_tns = array_ops.stack([label_shape[1]])
-
- def range_less_than(_, current_input):
- return array_ops.expand_dims(
- math_ops.range(label_shape[1]), 0) < array_ops.fill(
- max_num_labels_tns, current_input)
-
- init = math_ops.cast(
- array_ops.fill([1, label_shape[1]], 0), dtypes_module.bool)
- dense_mask = functional_ops.scan(
- range_less_than, label_lengths, initializer=init, parallel_iterations=1)
- dense_mask = dense_mask[:, 0, :]
-
- label_array = array_ops.reshape(
- array_ops.tile(math_ops.range(0, label_shape[1]), num_batches_tns),
- label_shape)
- label_ind = array_ops.boolean_mask(label_array, dense_mask)
-
- batch_array = array_ops.transpose(
- array_ops.reshape(
- array_ops.tile(math_ops.range(0, label_shape[0]), max_num_labels_tns),
- reverse(label_shape, 0)))
- batch_ind = array_ops.boolean_mask(batch_array, dense_mask)
- indices = array_ops.transpose(
- array_ops.reshape(concatenate([batch_ind, label_ind], axis=0), [2, -1]))
-
- vals_sparse = array_ops.gather_nd(labels, indices)
-
- return sparse_tensor.SparseTensor(
- math_ops.to_int64(indices), vals_sparse, math_ops.to_int64(label_shape))
-
-
-def ctc_batch_cost(y_true, y_pred, input_length, label_length):
- """Runs CTC loss algorithm on each batch element.
-
- Arguments:
- y_true: tensor `(samples, max_string_length)`
- containing the truth labels.
- y_pred: tensor `(samples, time_steps, num_categories)`
- containing the prediction, or output of the softmax.
- input_length: tensor `(samples, 1)` containing the sequence length for
- each batch item in `y_pred`.
- label_length: tensor `(samples, 1)` containing the sequence length for
- each batch item in `y_true`.
-
- Returns:
- Tensor with shape (samples,1) containing the
- CTC loss of each element.
- """
- label_length = math_ops.to_int32(array_ops.squeeze(label_length))
- input_length = math_ops.to_int32(array_ops.squeeze(input_length))
- sparse_labels = math_ops.to_int32(
- ctc_label_dense_to_sparse(y_true, label_length))
-
- y_pred = math_ops.log(array_ops.transpose(y_pred, perm=[1, 0, 2]) + 1e-8)
-
- return array_ops.expand_dims(
- ctc.ctc_loss(
- inputs=y_pred, labels=sparse_labels, sequence_length=input_length), 1)
-
-
-def ctc_decode(y_pred, input_length, greedy=True, beam_width=100, top_paths=1):
- """Decodes the output of a softmax.
-
- Can use either greedy search (also known as best path)
- or a constrained dictionary search.
-
- Arguments:
- y_pred: tensor `(samples, time_steps, num_categories)`
- containing the prediction, or output of the softmax.
- input_length: tensor `(samples, )` containing the sequence length for
- each batch item in `y_pred`.
- greedy: perform much faster best-path search if `true`.
- This does not use a dictionary.
- beam_width: if `greedy` is `false`: a beam search decoder will be used
- with a beam of this width.
- top_paths: if `greedy` is `false`,
- how many of the most probable paths will be returned.
-
- Returns:
- Tuple:
- List: if `greedy` is `true`, returns a list of one element that
- contains the decoded sequence.
- If `false`, returns the `top_paths` most probable
- decoded sequences.
- Important: blank labels are returned as `-1`.
- Tensor `(top_paths, )` that contains
- the log probability of each decoded sequence.
- """
- y_pred = math_ops.log(array_ops.transpose(y_pred, perm=[1, 0, 2]) + 1e-8)
- input_length = math_ops.to_int32(input_length)
-
- if greedy:
- (decoded, log_prob) = ctc.ctc_greedy_decoder(
- inputs=y_pred, sequence_length=input_length)
- else:
- (decoded, log_prob) = ctc.ctc_beam_search_decoder(
- inputs=y_pred,
- sequence_length=input_length,
- beam_width=beam_width,
- top_paths=top_paths)
- decoded_dense = [
- sparse_ops.sparse_to_dense(
- st.indices, st.dense_shape, st.values, default_value=-1)
- for st in decoded
- ]
- return (decoded_dense, log_prob)
-
-
-# HIGH ORDER FUNCTIONS
-
-
-def map_fn(fn, elems, name=None, dtype=None):
- """Map the function fn over the elements elems and return the outputs.
-
- Arguments:
- fn: Callable that will be called upon each element in elems
- elems: tensor
- name: A string name for the map node in the graph
- dtype: Output data type.
-
- Returns:
- Tensor with dtype `dtype`.
- """
- return functional_ops.map_fn(fn, elems, name=name, dtype=dtype)
-
-
-def foldl(fn, elems, initializer=None, name=None):
- """Reduce elems using fn to combine them from left to right.
-
- Arguments:
- fn: Callable that will be called upon each element in elems and an
- accumulator, for instance `lambda acc, x: acc + x`
- elems: tensor
- initializer: The first value used (`elems[0]` in case of None)
- name: A string name for the foldl node in the graph
-
- Returns:
- Tensor with same type and shape as `initializer`.
- """
- return functional_ops.foldl(fn, elems, initializer=initializer, name=name)
-
-
-def foldr(fn, elems, initializer=None, name=None):
- """Reduce elems using fn to combine them from right to left.
-
- Arguments:
- fn: Callable that will be called upon each element in elems and an
- accumulator, for instance `lambda acc, x: acc + x`
- elems: tensor
- initializer: The first value used (`elems[-1]` in case of None)
- name: A string name for the foldr node in the graph
-
- Returns:
- Same type and shape as initializer
- """
- return functional_ops.foldr(fn, elems, initializer=initializer, name=name)
-
-
-# Load Keras default configuration from config file if present.
-_keras_base_dir = os.path.expanduser('~')
-_keras_dir = os.path.join(_keras_base_dir, '.keras')
-_config_path = os.path.expanduser(os.path.join(_keras_dir, 'keras.json'))
-if os.path.exists(_config_path):
- try:
- _config = json.load(open(_config_path))
- except ValueError:
- _config = {}
- _floatx = _config.get('floatx', floatx())
- assert _floatx in {'float16', 'float32', 'float64'}
- _epsilon = _config.get('epsilon', epsilon())
- assert isinstance(_epsilon, float)
- _image_data_format = _config.get('image_data_format', image_data_format())
- assert _image_data_format in {'channels_last', 'channels_first'}
- set_floatx(_floatx)
- set_epsilon(_epsilon)
- set_image_data_format(_image_data_format)
-
-# Save config file.
-if not os.path.exists(_keras_dir):
- try:
- os.makedirs(_keras_dir)
- except OSError:
- # Except permission denied and potential race conditions
- # in multi-threaded environments.
- pass
-
-if not os.path.exists(_config_path):
- _config = {
- 'floatx': floatx(),
- 'epsilon': epsilon(),
- 'backend': 'tensorflow',
- 'image_data_format': image_data_format()
- }
- try:
- with open(_config_path, 'w') as f:
- f.write(json.dumps(_config, indent=4))
- except IOError:
- # Except permission denied.
- pass
diff --git a/tensorflow/contrib/keras/python/keras/backend_test.py b/tensorflow/contrib/keras/python/keras/backend_test.py
deleted file mode 100644
index 0717c91c6c..0000000000
--- a/tensorflow/contrib/keras/python/keras/backend_test.py
+++ /dev/null
@@ -1,1041 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for Keras backend."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-import scipy.sparse
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.framework import sparse_tensor
-from tensorflow.python.platform import test
-from tensorflow.python.util import tf_inspect
-
-
-def compare_single_input_op_to_numpy(keras_op,
- np_op,
- input_shape,
- dtype='float32',
- negative_values=True,
- keras_args=None,
- keras_kwargs=None,
- np_args=None,
- np_kwargs=None):
- keras_args = keras_args or []
- keras_kwargs = keras_kwargs or {}
- np_args = np_args or []
- np_kwargs = np_kwargs or {}
- inputs = 2. * np.random.random(input_shape)
- if negative_values:
- inputs -= 1.
- keras_output = keras_op(keras.backend.variable(inputs, dtype=dtype),
- *keras_args, **keras_kwargs)
- keras_output = keras.backend.eval(keras_output)
- np_output = np_op(inputs.astype(dtype), *np_args, **np_kwargs)
- try:
- np.testing.assert_allclose(keras_output, np_output, atol=1e-4)
- except AssertionError:
- raise AssertionError('Test for op `' + str(keras_op.__name__) + '` failed; '
- 'Expected ' + str(np_output) + ' but got ' +
- str(keras_output))
-
-
-def compare_two_inputs_op_to_numpy(keras_op,
- np_op,
- input_shape_a,
- input_shape_b,
- dtype='float32',
- keras_args=None,
- keras_kwargs=None,
- np_args=None,
- np_kwargs=None):
- keras_args = keras_args or []
- keras_kwargs = keras_kwargs or {}
- np_args = np_args or []
- np_kwargs = np_kwargs or {}
- input_a = np.random.random(input_shape_a)
- input_b = np.random.random(input_shape_b)
- keras_output = keras_op(keras.backend.variable(input_a, dtype=dtype),
- keras.backend.variable(input_b, dtype=dtype),
- *keras_args, **keras_kwargs)
- keras_output = keras.backend.eval(keras_output)
- np_output = np_op(input_a.astype(dtype), input_b.astype(dtype),
- *np_args, **np_kwargs)
- try:
- np.testing.assert_allclose(keras_output, np_output, atol=1e-4)
- except AssertionError:
- raise AssertionError('Test for op `' + str(keras_op.__name__) + '` failed; '
- 'Expected ' + str(np_output) + ' but got ' +
- str(keras_output))
-
-
-class BackendUtilsTest(test.TestCase):
-
- def test_backend(self):
- self.assertEqual(keras.backend.backend(), 'tensorflow')
-
- def test_espilon(self):
- epsilon = 1e-2
- keras.backend.set_epsilon(epsilon)
- self.assertEqual(keras.backend.epsilon(), epsilon)
- keras.backend.set_epsilon(1e-7)
-
- def test_floatx(self):
- floatx = 'float64'
- keras.backend.set_floatx(floatx)
- self.assertEqual(keras.backend.floatx(), floatx)
- keras.backend.set_floatx('float32')
-
- def test_image_data_format(self):
- image_data_format = 'channels_first'
- keras.backend.set_image_data_format(image_data_format)
- self.assertEqual(keras.backend.image_data_format(), image_data_format)
- keras.backend.set_image_data_format('channels_last')
-
- def test_get_reset_uids(self):
- self.assertEqual(keras.backend.get_uid('foo'), 1)
- self.assertEqual(keras.backend.get_uid('foo'), 2)
-
- keras.backend.reset_uids()
- self.assertEqual(keras.backend.get_uid('foo'), 1)
-
- def test_learning_phase(self):
- with self.test_session():
- keras.backend.set_learning_phase(1)
- self.assertEqual(keras.backend.learning_phase(), 1)
- with self.assertRaises(ValueError):
- keras.backend.set_learning_phase(2)
-
- def test_int_shape(self):
- x = keras.backend.placeholder(shape=(3, 4))
- self.assertEqual(keras.backend.int_shape(x), (3, 4))
-
- x = keras.backend.placeholder(shape=(None, 4))
- self.assertEqual(keras.backend.int_shape(x), (None, 4))
-
- def test_in_train_phase(self):
- with self.test_session():
- y1 = keras.backend.variable(1)
- y2 = keras.backend.variable(2)
- y = keras.backend.in_train_phase(y1, y2)
- f = keras.backend.function([keras.backend.learning_phase()], [y])
- y_val = f([0])[0]
- self.assertAllClose(y_val, 2)
- y_val = f([1])[0]
- self.assertAllClose(y_val, 1)
-
- def test_is_keras_tensor(self):
- x = keras.backend.variable(1)
- self.assertEqual(keras.backend.is_keras_tensor(x), False)
- x = keras.Input(shape=(1,))
- self.assertEqual(keras.backend.is_keras_tensor(x), True)
- with self.assertRaises(ValueError):
- keras.backend.is_keras_tensor(0)
-
- def test_is_placeholder(self):
- x = keras.backend.placeholder(shape=(1,))
- self.assertEqual(keras.backend.is_placeholder(x), True)
- # Test with TF placeholder
- x = keras.backend.array_ops.placeholder(dtype='float32', shape=(1,))
- self.assertEqual(keras.backend.is_placeholder(x), True)
- x = keras.backend.variable(1)
- self.assertEqual(keras.backend.is_placeholder(x), False)
-
- def test_stop_gradient(self):
- x = keras.backend.variable(1)
- y = keras.backend.stop_gradient(x)
- self.assertEqual(y.op.name[:12], 'StopGradient')
-
- xs = [keras.backend.variable(1) for _ in range(3)]
- ys = keras.backend.stop_gradient(xs)
- for y in ys:
- self.assertEqual(y.op.name[:12], 'StopGradient')
-
-
-class BackendVariableTest(test.TestCase):
-
- def test_zeros(self):
- with self.test_session():
- x = keras.backend.zeros((3, 4))
- val = keras.backend.eval(x)
- self.assertAllClose(val, np.zeros((3, 4)))
-
- def test_ones(self):
- with self.test_session():
- x = keras.backend.ones((3, 4))
- val = keras.backend.eval(x)
- self.assertAllClose(val, np.ones((3, 4)))
-
- def test_eye(self):
- with self.test_session():
- x = keras.backend.eye(4)
- val = keras.backend.eval(x)
- self.assertAllClose(val, np.eye(4))
-
- def test_zeros_like(self):
- with self.test_session():
- x = keras.backend.zeros((3, 4))
- y = keras.backend.zeros_like(x)
- val = keras.backend.eval(y)
- self.assertAllClose(val, np.zeros((3, 4)))
-
- def test_ones_like(self):
- with self.test_session():
- x = keras.backend.zeros((3, 4))
- y = keras.backend.ones_like(x)
- val = keras.backend.eval(y)
- self.assertAllClose(val, np.ones((3, 4)))
-
- def test_random_uniform_variable(self):
- with self.test_session():
- x = keras.backend.random_uniform_variable((30, 20), low=1, high=2, seed=0)
- val = keras.backend.eval(x)
- self.assertAllClose(val.mean(), 1.5, atol=1e-1)
- self.assertAllClose(val.max(), 2., atol=1e-1)
- self.assertAllClose(val.min(), 1., atol=1e-1)
-
- def test_random_normal_variable(self):
- with self.test_session():
- x = keras.backend.random_normal_variable((30, 20), 1., 0.5,
- seed=0)
- val = keras.backend.eval(x)
- self.assertAllClose(val.mean(), 1., atol=1e-1)
- self.assertAllClose(val.std(), 0.5, atol=1e-1)
-
- def test_count_params(self):
- with self.test_session():
- x = keras.backend.zeros((4, 5))
- val = keras.backend.count_params(x)
- self.assertAllClose(val, 20)
-
- def test_constant(self):
- with self.test_session():
- ref_val = np.random.random((3, 4)).astype('float32')
- x = keras.backend.constant(ref_val)
- val = keras.backend.eval(x)
- self.assertAllClose(val, ref_val)
-
- def test_sparse_variable(self):
- with self.test_session():
- val = scipy.sparse.eye(10)
- x = keras.backend.variable(val)
- self.assertTrue(isinstance(x, sparse_tensor.SparseTensor))
-
- y = keras.backend.to_dense(x)
- self.assertFalse(keras.backend.is_sparse(y))
-
- def test_placeholder(self):
- x = keras.backend.placeholder(shape=(3, 4))
- self.assertEqual(x.get_shape().as_list(), [3, 4])
- x = keras.backend.placeholder(shape=(3, 4), sparse=True)
- self.assertEqual(x.get_shape().as_list(), [3, 4])
-
-
-class BackendLinearAlgebraTest(test.TestCase):
-
- def test_dot(self):
- x = keras.backend.placeholder(shape=(2, 3))
- y = keras.backend.placeholder(shape=(3, 4))
- xy = keras.backend.dot(x, y)
- self.assertEqual(xy.get_shape().as_list(), [2, 4])
-
- x = keras.backend.placeholder(shape=(32, 28, 3))
- y = keras.backend.placeholder(shape=(3, 4))
- xy = keras.backend.dot(x, y)
- self.assertEqual(xy.get_shape().as_list(), [32, 28, 4])
-
- def test_batch_dot(self):
- x = keras.backend.ones(shape=(32, 20, 1))
- y = keras.backend.ones(shape=(32, 30, 20))
- xy = keras.backend.batch_dot(x, y, axes=[1, 2])
- self.assertEqual(xy.get_shape().as_list(), [32, 1, 30])
-
- # TODO(fchollet): insufficiently tested.
-
- def test_reduction_ops(self):
- ops_to_test = [
- (keras.backend.max, np.max),
- (keras.backend.min, np.min),
- (keras.backend.sum, np.sum),
- (keras.backend.prod, np.prod),
- (keras.backend.var, np.var),
- (keras.backend.std, np.std),
- (keras.backend.mean, np.mean),
- (keras.backend.argmin, np.argmin),
- (keras.backend.argmax, np.argmax),
- ]
- for keras_op, np_op in ops_to_test:
- with self.test_session():
- compare_single_input_op_to_numpy(keras_op, np_op, input_shape=(4, 7, 5),
- keras_kwargs={'axis': 1},
- np_kwargs={'axis': 1})
- compare_single_input_op_to_numpy(keras_op, np_op, input_shape=(4, 7, 5),
- keras_kwargs={'axis': -1},
- np_kwargs={'axis': -1})
- if 'keepdims' in tf_inspect.getargspec(keras_op).args:
- compare_single_input_op_to_numpy(keras_op, np_op,
- input_shape=(4, 7, 5),
- keras_kwargs={'axis': 1,
- 'keepdims': True},
- np_kwargs={'axis': 1,
- 'keepdims': True})
-
- def test_elementwise_ops(self):
- ops_to_test = [
- (keras.backend.square, np.square),
- (keras.backend.abs, np.abs),
- (keras.backend.round, np.round),
- (keras.backend.sign, np.sign),
- (keras.backend.sin, np.sin),
- (keras.backend.cos, np.cos),
- (keras.backend.exp, np.exp),
- ]
- for keras_op, np_op in ops_to_test:
- with self.test_session():
- compare_single_input_op_to_numpy(keras_op, np_op, input_shape=(4, 7))
-
- ops_to_test = [
- (keras.backend.sqrt, np.sqrt),
- (keras.backend.log, np.log),
- ]
- for keras_op, np_op in ops_to_test:
- with self.test_session():
- compare_single_input_op_to_numpy(keras_op, np_op,
- input_shape=(4, 7),
- negative_values=False)
-
- with self.test_session():
- compare_single_input_op_to_numpy(
- keras.backend.clip, np.clip,
- input_shape=(6, 4),
- keras_kwargs={'min_value': 0.1, 'max_value': 2.4},
- np_kwargs={'a_min': 0.1, 'a_max': 1.4})
-
- with self.test_session():
- compare_single_input_op_to_numpy(
- keras.backend.pow, np.power,
- input_shape=(6, 4),
- keras_args=[3],
- np_args=[3])
-
- def test_two_tensor_ops(self):
- ops_to_test = [
- (keras.backend.equal, np.equal),
- (keras.backend.not_equal, np.not_equal),
- (keras.backend.greater, np.greater),
- (keras.backend.greater_equal, np.greater_equal),
- (keras.backend.less, np.less),
- (keras.backend.less_equal, np.less_equal),
- (keras.backend.maximum, np.maximum),
- (keras.backend.minimum, np.minimum),
- ]
- for keras_op, np_op in ops_to_test:
- with self.test_session():
- compare_two_inputs_op_to_numpy(keras_op, np_op,
- input_shape_a=(4, 7),
- input_shape_b=(4, 7))
-
-
-class BackendShapeOpsTest(test.TestCase):
-
- def test_reshape(self):
- with self.test_session():
- compare_single_input_op_to_numpy(keras.backend.reshape, np.reshape,
- input_shape=(4, 7),
- keras_args=[(2, 14)],
- np_args=[(2, 14)])
-
- def test_concatenate(self):
- a = keras.backend.variable(np.ones((1, 2, 3)))
- b = keras.backend.variable(np.ones((1, 2, 2)))
- y = keras.backend.concatenate([a, b], axis=-1)
- self.assertEqual(y.get_shape().as_list(), [1, 2, 5])
-
- def test_permute_dimensions(self):
- with self.test_session():
- compare_single_input_op_to_numpy(keras.backend.permute_dimensions,
- np.transpose,
- input_shape=(4, 7),
- keras_args=[(1, 0)],
- np_args=[(1, 0)])
-
- def test_resize_images(self):
- height_factor = 2
- width_factor = 2
- data_format = 'channels_last'
- x = keras.backend.variable(np.ones((1, 2, 2, 3)))
- y = keras.backend.resize_images(x,
- height_factor,
- width_factor,
- data_format)
- self.assertEqual(y.get_shape().as_list(), [1, 4, 4, 3])
-
- data_format = 'channels_first'
- x = keras.backend.variable(np.ones((1, 3, 2, 2)))
- y = keras.backend.resize_images(x,
- height_factor,
- width_factor,
- data_format)
- self.assertEqual(y.get_shape().as_list(), [1, 3, 4, 4])
-
- # Invalid use:
- with self.assertRaises(ValueError):
- keras.backend.resize_images(x,
- height_factor,
- width_factor,
- data_format='unknown')
-
- def test_resize_volumes(self):
- height_factor = 2
- width_factor = 2
- depth_factor = 2
- data_format = 'channels_last'
- x = keras.backend.variable(np.ones((1, 2, 2, 2, 3)))
- y = keras.backend.resize_volumes(x,
- depth_factor,
- height_factor,
- width_factor,
- data_format)
- self.assertEqual(y.get_shape().as_list(), [1, 4, 4, 4, 3])
-
- data_format = 'channels_first'
- x = keras.backend.variable(np.ones((1, 3, 2, 2, 2)))
- y = keras.backend.resize_volumes(x,
- depth_factor,
- height_factor,
- width_factor,
- data_format)
- self.assertEqual(y.get_shape().as_list(), [1, 3, 4, 4, 4])
-
- # Invalid use:
- with self.assertRaises(ValueError):
- keras.backend.resize_volumes(x,
- depth_factor,
- height_factor,
- width_factor,
- data_format='unknown')
-
- def test_repeat_elements(self):
- x = keras.backend.variable(np.ones((1, 3, 2)))
- y = keras.backend.repeat_elements(x, 3, axis=1)
- self.assertEqual(y.get_shape().as_list(), [1, 9, 2])
-
- # Use with a dynamic axis:
- x = keras.backend.placeholder(shape=(2, None, 2))
- y = keras.backend.repeat_elements(x, 3, axis=1)
- self.assertEqual(y.get_shape().as_list(), [2, None, 2])
-
- def test_repeat(self):
- x = keras.backend.variable(np.ones((1, 3)))
- y = keras.backend.repeat(x, 2)
- self.assertEqual(y.get_shape().as_list(), [1, 2, 3])
-
- def test_flatten(self):
- with self.test_session():
- compare_single_input_op_to_numpy(keras.backend.flatten,
- np.reshape,
- input_shape=(4, 7, 6),
- np_args=[(4 * 7 * 6,)])
-
- def test_batch_flatten(self):
- with self.test_session():
- compare_single_input_op_to_numpy(keras.backend.batch_flatten,
- np.reshape,
- input_shape=(4, 7, 6),
- np_args=[(4, 7 * 6)])
-
- def test_temporal_padding(self):
-
- def ref_op(x, padding):
- shape = list(x.shape)
- shape[1] += padding[0] + padding[1]
- y = np.zeros(tuple(shape))
- y[:, padding[0]:-padding[1], :] = x
- return y
-
- with self.test_session():
- compare_single_input_op_to_numpy(keras.backend.temporal_padding,
- ref_op,
- input_shape=(4, 7, 6),
- keras_args=[(2, 3)],
- np_args=[(2, 3)])
-
- def test_spatial_2d_padding(self):
-
- def ref_op(x, padding, data_format='channels_last'):
- shape = list(x.shape)
- if data_format == 'channels_last':
- shape[1] += padding[0][0] + padding[0][1]
- shape[2] += padding[1][0] + padding[1][1]
- y = np.zeros(tuple(shape))
- y[:, padding[0][0]:-padding[0][1], padding[1][0]:-padding[1][1], :] = x
- else:
- shape[2] += padding[0][0] + padding[0][1]
- shape[3] += padding[1][0] + padding[1][1]
- y = np.zeros(tuple(shape))
- y[:, :, padding[0][0]:-padding[0][1], padding[1][0]:-padding[1][1]] = x
- return y
-
- with self.test_session():
- compare_single_input_op_to_numpy(
- keras.backend.spatial_2d_padding,
- ref_op,
- input_shape=(2, 3, 2, 3),
- keras_args=[((2, 3), (1, 2))],
- keras_kwargs={'data_format': 'channels_last'},
- np_args=[((2, 3), (1, 2))],
- np_kwargs={'data_format': 'channels_last'})
- compare_single_input_op_to_numpy(
- keras.backend.spatial_2d_padding,
- ref_op,
- input_shape=(2, 3, 2, 3),
- keras_args=[((2, 3), (1, 2))],
- keras_kwargs={'data_format': 'channels_first'},
- np_args=[((2, 3), (1, 2))],
- np_kwargs={'data_format': 'channels_first'})
-
- def test_spatial_3d_padding(self):
-
- def ref_op(x, padding, data_format='channels_last'):
- shape = list(x.shape)
- if data_format == 'channels_last':
- shape[1] += padding[0][0] + padding[0][1]
- shape[2] += padding[1][0] + padding[1][1]
- shape[3] += padding[2][0] + padding[2][1]
- y = np.zeros(tuple(shape))
- y[:,
- padding[0][0]:-padding[0][1],
- padding[1][0]:-padding[1][1],
- padding[2][0]:-padding[2][1],
- :] = x
- else:
- shape[2] += padding[0][0] + padding[0][1]
- shape[3] += padding[1][0] + padding[1][1]
- shape[4] += padding[2][0] + padding[2][1]
- y = np.zeros(tuple(shape))
- y[:, :,
- padding[0][0]:-padding[0][1],
- padding[1][0]:-padding[1][1],
- padding[2][0]:-padding[2][1]] = x
- return y
-
- with self.test_session():
- compare_single_input_op_to_numpy(
- keras.backend.spatial_3d_padding,
- ref_op,
- input_shape=(2, 3, 2, 3, 2),
- keras_args=[((2, 3), (1, 2), (2, 3))],
- keras_kwargs={'data_format': 'channels_last'},
- np_args=[((2, 3), (1, 2), (2, 3))],
- np_kwargs={'data_format': 'channels_last'})
- compare_single_input_op_to_numpy(
- keras.backend.spatial_3d_padding,
- ref_op,
- input_shape=(2, 3, 2, 3, 2),
- keras_args=[((2, 3), (1, 2), (2, 3))],
- keras_kwargs={'data_format': 'channels_first'},
- np_args=[((2, 3), (1, 2), (2, 3))],
- np_kwargs={'data_format': 'channels_first'})
-
-
-class BackendNNOpsTest(test.TestCase):
-
- def test_bias_add(self):
- with self.test_session():
- keras_op = keras.backend.bias_add
- np_op = np.add
- compare_two_inputs_op_to_numpy(keras_op, np_op,
- input_shape_a=(4, 7),
- input_shape_b=(7,))
- compare_two_inputs_op_to_numpy(keras_op, np_op,
- input_shape_a=(4, 3, 7),
- input_shape_b=(7,))
- compare_two_inputs_op_to_numpy(keras_op, np_op,
- input_shape_a=(4, 3, 5, 7),
- input_shape_b=(7,))
- compare_two_inputs_op_to_numpy(keras_op, np_op,
- input_shape_a=(4, 3, 5, 2, 7),
- input_shape_b=(7,))
-
- with self.assertRaises(ValueError):
- x = keras.backend.variable((3, 4))
- b = keras.backend.variable((3, 4))
- keras.backend.bias_add(x, b)
- with self.assertRaises(ValueError):
- x = keras.backend.variable((3, 4))
- b = keras.backend.variable((4,))
- keras.backend.bias_add(x, b, data_format='unknown')
-
- def test_bias_add_channels_first(self):
- with self.test_session():
- def keras_op(x, b):
- return keras.backend.bias_add(x, b, data_format='channels_first')
-
- def np_op(x, b):
- if x.ndim == 3:
- b = b.reshape((1, b.shape[0], 1))
- if x.ndim == 4:
- b = b.reshape((1, b.shape[0], 1, 1))
- return x + b
-
- compare_two_inputs_op_to_numpy(keras_op, np_op,
- input_shape_a=(4, 3, 7),
- input_shape_b=(3,))
- compare_two_inputs_op_to_numpy(keras_op, np_op,
- input_shape_a=(4, 3, 5, 7),
- input_shape_b=(3,))
-
- def test_pool2d(self):
- val = np.random.random((10, 3, 10, 10))
- x = keras.backend.variable(val)
- y = keras.backend.pool2d(x, (2, 2), strides=(1, 1),
- padding='valid', data_format='channels_first',
- pool_mode='max')
- self.assertEqual(y.get_shape().as_list(), [10, 3, 9, 9])
-
- y = keras.backend.pool2d(x, (2, 2), strides=(1, 1),
- padding='valid', data_format='channels_first',
- pool_mode='avg')
- self.assertEqual(y.get_shape().as_list(), [10, 3, 9, 9])
-
- val = np.random.random((10, 10, 10, 3))
- x = keras.backend.variable(val)
- y = keras.backend.pool2d(x, (2, 2), strides=(1, 1),
- padding='valid', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 9, 9, 3])
-
- val = np.random.random((10, 10, 10, 3))
- x = keras.backend.variable(val)
- y = keras.backend.pool2d(x, (2, 2), strides=(1, 1),
- padding='same', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 10, 10, 3])
-
- val = np.random.random((10, 10, 10, 3))
- x = keras.backend.variable(val)
- y = keras.backend.pool2d(x, (2, 2), strides=(2, 2),
- padding='same', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 5, 5, 3])
-
- with self.assertRaises(ValueError):
- y = keras.backend.pool2d(x, (2, 2), strides=(2, 2),
- padding='other', data_format='channels_last')
- with self.assertRaises(ValueError):
- y = keras.backend.pool2d(x, (2, 2), strides=(2, 2),
- data_format='other')
- with self.assertRaises(ValueError):
- y = keras.backend.pool2d(x, (2, 2, 2), strides=(2, 2))
- with self.assertRaises(ValueError):
- y = keras.backend.pool2d(x, (2, 2), strides=(2, 2, 2))
- with self.assertRaises(ValueError):
- y = keras.backend.pool2d(x, (2, 2), strides=(2, 2), pool_mode='other')
-
- def test_pool3d(self):
- val = np.random.random((10, 3, 10, 10, 10))
- x = keras.backend.variable(val)
- y = keras.backend.pool3d(x, (2, 2, 2), strides=(1, 1, 1),
- padding='valid', data_format='channels_first',
- pool_mode='max')
- self.assertEqual(y.get_shape().as_list(), [10, 3, 9, 9, 9])
-
- y = keras.backend.pool3d(x, (2, 2, 2), strides=(1, 1, 1),
- padding='valid', data_format='channels_first',
- pool_mode='avg')
- self.assertEqual(y.get_shape().as_list(), [10, 3, 9, 9, 9])
-
- val = np.random.random((10, 10, 10, 10, 3))
- x = keras.backend.variable(val)
- y = keras.backend.pool3d(x, (2, 2, 2), strides=(1, 1, 1),
- padding='valid', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 9, 9, 9, 3])
-
- val = np.random.random((10, 10, 10, 10, 3))
- x = keras.backend.variable(val)
- y = keras.backend.pool3d(x, (2, 2, 2), strides=(1, 1, 1),
- padding='same', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 10, 10, 10, 3])
-
- val = np.random.random((10, 10, 10, 10, 3))
- x = keras.backend.variable(val)
- y = keras.backend.pool3d(x, (2, 2, 2), strides=(2, 2, 2),
- padding='same', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 5, 5, 5, 3])
-
- def test_conv1d(self):
- val = np.random.random((10, 4, 10))
- x = keras.backend.variable(val)
- kernel_val = np.random.random((3, 4, 5))
- k = keras.backend.variable(kernel_val)
- y = keras.backend.conv1d(x, k, strides=(1,),
- padding='valid', data_format='channels_first')
- self.assertEqual(y.get_shape().as_list(), [10, 5, 8])
-
- val = np.random.random((10, 10, 4))
- x = keras.backend.variable(val)
- y = keras.backend.conv1d(x, k, strides=(1,),
- padding='valid', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 8, 5])
-
- val = np.random.random((10, 10, 4))
- x = keras.backend.variable(val)
- y = keras.backend.conv1d(x, k, strides=(1,),
- padding='same', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 10, 5])
-
- val = np.random.random((10, 10, 4))
- x = keras.backend.variable(val)
- y = keras.backend.conv1d(x, k, strides=(2,),
- padding='same', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 5, 5])
-
- def test_conv2d(self):
- val = np.random.random((10, 4, 10, 10))
- x = keras.backend.variable(val)
- kernel_val = np.random.random((3, 3, 4, 5))
- k = keras.backend.variable(kernel_val)
- y = keras.backend.conv2d(x, k,
- padding='valid', data_format='channels_first')
- self.assertEqual(y.get_shape().as_list(), [10, 5, 8, 8])
-
- val = np.random.random((10, 10, 10, 4))
- x = keras.backend.variable(val)
- y = keras.backend.conv2d(x, k, strides=(1, 1),
- padding='valid', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 8, 8, 5])
-
- val = np.random.random((10, 10, 10, 4))
- x = keras.backend.variable(val)
- y = keras.backend.conv2d(x, k, strides=(1, 1),
- padding='same', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 10, 10, 5])
-
- val = np.random.random((10, 10, 10, 4))
- x = keras.backend.variable(val)
- y = keras.backend.conv2d(x, k, strides=(2, 2),
- padding='same', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 5, 5, 5])
- with self.assertRaises(ValueError):
- y = keras.backend.conv2d(x, k, (2, 2),
- padding='other', data_format='channels_last')
- with self.assertRaises(ValueError):
- y = keras.backend.conv2d(x, k, (2, 2),
- data_format='other')
- with self.assertRaises(ValueError):
- y = keras.backend.conv2d(x, k, (2, 2, 2))
-
- def test_separable_conv2d(self):
- val = np.random.random((10, 4, 10, 10))
- x = keras.backend.variable(val)
- depthwise_kernel_val = np.random.random((3, 3, 4, 1))
- pointwise_kernel_val = np.random.random((1, 1, 4, 5))
- dk = keras.backend.variable(depthwise_kernel_val)
- pk = keras.backend.variable(pointwise_kernel_val)
- y = keras.backend.separable_conv2d(
- x, dk, pk, padding='valid', data_format='channels_first')
- self.assertEqual(y.get_shape().as_list(), [10, 5, 8, 8])
-
- val = np.random.random((10, 10, 10, 4))
- x = keras.backend.variable(val)
- y = keras.backend.separable_conv2d(
- x, dk, pk, strides=(1, 1), padding='valid', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 8, 8, 5])
-
- val = np.random.random((10, 10, 10, 4))
- x = keras.backend.variable(val)
- y = keras.backend.separable_conv2d(
- x, dk, pk, strides=(1, 1), padding='same', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 10, 10, 5])
-
- val = np.random.random((10, 10, 10, 4))
- x = keras.backend.variable(val)
- y = keras.backend.separable_conv2d(
- x, dk, pk, strides=(2, 2), padding='same', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 5, 5, 5])
- with self.assertRaises(ValueError):
- y = keras.backend.separable_conv2d(
- x, dk, pk, (2, 2), padding='other', data_format='channels_last')
- with self.assertRaises(ValueError):
- y = keras.backend.separable_conv2d(
- x, dk, pk, (2, 2), data_format='other')
- with self.assertRaises(ValueError):
- y = keras.backend.separable_conv2d(x, dk, pk, (2, 2, 2))
-
- def test_conv3d(self):
- val = np.random.random((10, 4, 10, 10, 10))
- x = keras.backend.variable(val)
- kernel_val = np.random.random((3, 3, 3, 4, 5))
- k = keras.backend.variable(kernel_val)
- y = keras.backend.conv3d(x, k,
- padding='valid', data_format='channels_first')
- self.assertEqual(y.get_shape().as_list(), [10, 5, 8, 8, 8])
-
- val = np.random.random((10, 10, 10, 10, 4))
- x = keras.backend.variable(val)
- y = keras.backend.conv3d(x, k, strides=(1, 1, 1),
- padding='valid', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 8, 8, 8, 5])
-
- val = np.random.random((10, 10, 10, 10, 4))
- x = keras.backend.variable(val)
- y = keras.backend.conv3d(x, k, strides=(1, 1, 1),
- padding='same', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 10, 10, 10, 5])
-
- val = np.random.random((10, 10, 10, 10, 4))
- x = keras.backend.variable(val)
- y = keras.backend.conv3d(x, k, strides=(2, 2, 2),
- padding='same', data_format='channels_last')
- self.assertEqual(y.get_shape().as_list(), [10, 5, 5, 5, 5])
- with self.assertRaises(ValueError):
- y = keras.backend.conv3d(x, k, (2, 2, 2),
- padding='other', data_format='channels_last')
- with self.assertRaises(ValueError):
- y = keras.backend.conv3d(x, k, (2, 2, 2),
- data_format='other')
- with self.assertRaises(ValueError):
- y = keras.backend.conv3d(x, k, (2, 2))
-
- def test_rnn(self):
- # implement a simple RNN
- num_samples = 4
- input_dim = 5
- output_dim = 3
- timesteps = 6
-
- input_val = np.random.random(
- (num_samples, timesteps, input_dim)).astype(np.float32)
- init_state_val = np.random.random(
- (num_samples, output_dim)).astype(np.float32)
- w_i_val = np.random.random((input_dim, output_dim)).astype(np.float32)
- w_o_val = np.random.random((output_dim, output_dim)).astype(np.float32)
- np_mask = np.random.randint(2, size=(num_samples, timesteps))
-
- def rnn_step_fn():
- w_i = keras.backend.variable(w_i_val)
- w_o = keras.backend.variable(w_o_val)
-
- def step_function(x, states):
- assert len(states) == 1
- prev_output = states[0]
- output = keras.backend.dot(x, w_i) + keras.backend.dot(prev_output, w_o)
- return output, [output]
-
- return step_function
-
- # test default setup
- last_output_list = [[], [], [], [], [], []]
- outputs_list = [[], [], [], [], [], []]
- state_list = [[], [], [], [], [], []]
-
- rnn_fn = rnn_step_fn()
- inputs = keras.backend.variable(input_val)
- initial_states = [keras.backend.variable(init_state_val)]
- mask = keras.backend.variable(np_mask)
-
- kwargs_list = [
- {'go_backwards': False, 'mask': None},
- {'go_backwards': False, 'mask': None, 'unroll': True},
- {'go_backwards': True, 'mask': None},
- {'go_backwards': True, 'mask': None, 'unroll': True},
- {'go_backwards': False, 'mask': mask},
- {'go_backwards': False, 'mask': mask, 'unroll': True},
- ]
-
- for (i, kwargs) in enumerate(kwargs_list):
- last_output, outputs, new_states = keras.backend.rnn(rnn_fn, inputs,
- initial_states,
- **kwargs)
- last_output_list[i].append(keras.backend.eval(last_output))
- outputs_list[i].append(keras.backend.eval(outputs))
- self.assertEqual(len(new_states), 1)
- state_list[i].append(keras.backend.eval(new_states[0]))
-
- def assert_list_pairwise(z_list, atol=1e-05):
- for (z1, z2) in zip(z_list[1:], z_list[:-1]):
- self.assertAllClose(z1, z2, atol=atol)
-
- assert_list_pairwise(last_output_list[0], atol=1e-04)
- assert_list_pairwise(outputs_list[0], atol=1e-04)
- assert_list_pairwise(state_list[0], atol=1e-04)
- assert_list_pairwise(last_output_list[2], atol=1e-04)
- assert_list_pairwise(outputs_list[2], atol=1e-04)
- assert_list_pairwise(state_list[2], atol=1e-04)
-
- for l, u_l in zip(last_output_list[0], last_output_list[1]):
- self.assertAllClose(l, u_l, atol=1e-04)
-
- for o, u_o in zip(outputs_list[0], outputs_list[1]):
- self.assertAllClose(o, u_o, atol=1e-04)
-
- for s, u_s in zip(state_list[0], state_list[1]):
- self.assertAllClose(s, u_s, atol=1e-04)
-
- for b_l, b_u_l in zip(last_output_list[2], last_output_list[3]):
- self.assertAllClose(b_l, b_u_l, atol=1e-04)
-
- for b_o, b_u_o in zip(outputs_list[2], outputs_list[3]):
- self.assertAllClose(b_o, b_u_o, atol=1e-04)
-
- for b_s, b_u_s in zip(state_list[2], state_list[3]):
- self.assertAllClose(b_s, b_u_s, atol=1e-04)
-
- def test_normalize_batch_in_training(self):
- val = np.random.random((10, 3, 10, 10))
- x = keras.backend.variable(val)
- reduction_axes = (0, 2, 3)
-
- # case: need broadcasting
- g_val = np.random.random((3,))
- b_val = np.random.random((3,))
- gamma = keras.backend.variable(g_val)
- beta = keras.backend.variable(b_val)
- normed, mean, var = keras.backend.normalize_batch_in_training(
- x, gamma, beta, reduction_axes, epsilon=1e-3)
- self.assertEqual(normed.get_shape().as_list(), [10, 3, 10, 10])
- self.assertEqual(mean.get_shape().as_list(), [3,])
- self.assertEqual(var.get_shape().as_list(), [3,])
-
- # case: doesn't need broadcasting
- g_val = np.random.random((1, 3, 1, 1))
- b_val = np.random.random((1, 3, 1, 1))
- gamma = keras.backend.variable(g_val)
- beta = keras.backend.variable(b_val)
- normed, mean, var = keras.backend.normalize_batch_in_training(
- x, gamma, beta, reduction_axes, epsilon=1e-3)
- self.assertEqual(normed.get_shape().as_list(), [10, 3, 10, 10])
- self.assertEqual(mean.get_shape().as_list(), [3,])
- self.assertEqual(var.get_shape().as_list(), [3,])
-
- # case: gamma=None
- gamma = None
- normed, mean, var = keras.backend.normalize_batch_in_training(
- x, gamma, beta, reduction_axes, epsilon=1e-3)
- self.assertEqual(normed.get_shape().as_list(), [10, 3, 10, 10])
- self.assertEqual(mean.get_shape().as_list(), [3,])
- self.assertEqual(var.get_shape().as_list(), [3,])
-
- # case: beta=None
- beta = None
- normed, mean, var = keras.backend.normalize_batch_in_training(
- x, gamma, beta, reduction_axes, epsilon=1e-3)
- self.assertEqual(normed.get_shape().as_list(), [10, 3, 10, 10])
- self.assertEqual(mean.get_shape().as_list(), [3,])
- self.assertEqual(var.get_shape().as_list(), [3,])
-
-
-class TestCTC(test.TestCase):
-
- def test_ctc_decode(self):
- with self.test_session():
- depth = 6
- seq_len_0 = 5
- input_prob_matrix_0 = np.asarray(
- [[0.30999, 0.309938, 0.0679938, 0.0673362, 0.0708352, 0.173908],
- [0.215136, 0.439699, 0.0370931, 0.0393967, 0.0381581, 0.230517],
- [0.199959, 0.489485, 0.0233221, 0.0251417, 0.0233289, 0.238763],
- [0.279611, 0.452966, 0.0204795, 0.0209126, 0.0194803, 0.20655],
- [0.51286, 0.288951, 0.0243026, 0.0220788, 0.0219297, 0.129878],
- # Random entry added in at time=5
- [0.155251, 0.164444, 0.173517, 0.176138, 0.169979, 0.160671]],
- dtype=np.float32)
-
- # len max_time_steps array of batch_size x depth matrices
- inputs = ([input_prob_matrix_0[t, :][np.newaxis, :]
- for t in range(seq_len_0)] + # Pad to max_time_steps = 8
- 2 * [np.zeros((1, depth), dtype=np.float32)])
-
- inputs = keras.backend.variable(np.asarray(inputs).transpose((1, 0, 2)))
-
- # batch_size length vector of sequence_lengths
- input_length = keras.backend.variable(
- np.array([seq_len_0], dtype=np.int32))
- # batch_size length vector of negative log probabilities
- log_prob_truth = np.array([
- 0.584855, # output beam 0
- 0.389139 # output beam 1
- ], np.float32)[np.newaxis, :]
-
- decode_truth = [np.array([1, 0]), np.array([0, 1, 0])]
- beam_width = 2
- top_paths = 2
-
- decode_pred_tf, log_prob_pred_tf = keras.backend.ctc_decode(
- inputs,
- input_length,
- greedy=False,
- beam_width=beam_width,
- top_paths=top_paths)
-
- self.assertEqual(len(decode_pred_tf), top_paths)
- log_prob_pred = keras.backend.eval(log_prob_pred_tf)
- for i in range(top_paths):
- self.assertTrue(
- np.alltrue(
- decode_truth[i] == keras.backend.eval(decode_pred_tf[i])))
- self.assertAllClose(log_prob_truth, log_prob_pred)
-
- def test_ctc_batch_cost(self):
- with self.test_session():
- label_lens = np.expand_dims(np.asarray([5, 4]), 1)
- input_lens = np.expand_dims(np.asarray([5, 5]), 1) # number of timesteps
- loss_log_probs = [3.34211, 5.42262]
-
- # dimensions are batch x time x categories
- labels = np.asarray([[0, 1, 2, 1, 0], [0, 1, 1, 0, -1]])
- inputs = np.asarray(
- [[[0.633766, 0.221185, 0.0917319, 0.0129757, 0.0142857, 0.0260553],
- [0.111121, 0.588392, 0.278779, 0.0055756, 0.00569609, 0.010436],
- [0.0357786, 0.633813, 0.321418, 0.00249248, 0.00272882, 0.0037688],
- [0.0663296, 0.643849, 0.280111, 0.00283995, 0.0035545, 0.00331533],
- [0.458235, 0.396634, 0.123377, 0.00648837, 0.00903441, 0.00623107]],
- [[0.30176, 0.28562, 0.0831517, 0.0862751, 0.0816851, 0.161508],
- [0.24082, 0.397533, 0.0557226, 0.0546814, 0.0557528, 0.19549],
- [0.230246, 0.450868, 0.0389607, 0.038309, 0.0391602, 0.202456],
- [0.280884, 0.429522, 0.0326593, 0.0339046, 0.0326856, 0.190345],
- [0.423286, 0.315517, 0.0338439, 0.0393744, 0.0339315, 0.154046]]],
- dtype=np.float32)
-
- labels = keras.backend.variable(labels, dtype='int32')
- inputs = keras.backend.variable(inputs, dtype='float32')
- input_lens = keras.backend.variable(input_lens, dtype='int32')
- label_lens = keras.backend.variable(label_lens, dtype='int32')
- res = keras.backend.eval(
- keras.backend.ctc_batch_cost(labels, inputs, input_lens, label_lens))
- self.assertAllClose(res[:, 0], loss_log_probs, atol=1e-05)
-
-
-class TestRandomOps(test.TestCase):
-
- def test_random_binomial(self):
- with self.test_session():
- np.random.seed(123)
- x = keras.backend.random_binomial((1000, 1000), p=0.5)
- self.assertAllClose(np.mean(keras.backend.eval(x)), 0.5, atol=0.1)
-
- def test_truncated_normal(self):
- with self.test_session():
- np.random.seed(123)
- x = keras.backend.truncated_normal((1000, 1000), mean=0.0, stddev=1.0)
- y = keras.backend.eval(x)
- self.assertAllClose(np.mean(y), 0., atol=0.1)
- self.assertAllClose(np.std(y), 0.88, atol=0.1)
- self.assertAllClose(np.max(y), 2., atol=0.1)
- self.assertAllClose(np.min(y), -2., atol=0.1)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/callbacks.py b/tensorflow/contrib/keras/python/keras/callbacks.py
deleted file mode 100644
index 323fdddb1f..0000000000
--- a/tensorflow/contrib/keras/python/keras/callbacks.py
+++ /dev/null
@@ -1,1106 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Keras callbacks: utilities called at certain points during model training.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from collections import deque
-from collections import Iterable
-from collections import OrderedDict
-import csv
-import json
-import os
-import time
-
-import numpy as np
-import six
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import Progbar
-from tensorflow.contrib.tensorboard.plugins import projector
-from tensorflow.python.ops import array_ops
-from tensorflow.python.platform import tf_logging as logging
-from tensorflow.python.summary import summary as tf_summary
-from tensorflow.python.training import saver as saver_lib
-
-
-# pylint: disable=g-import-not-at-top
-try:
- import requests
-except ImportError:
- requests = None
-# pylint: enable=g-import-not-at-top
-
-
-class CallbackList(object):
- """Container abstracting a list of callbacks.
-
- Arguments:
- callbacks: List of `Callback` instances.
- queue_length: Queue length for keeping
- running statistics over callback execution time.
- """
-
- def __init__(self, callbacks=None, queue_length=10):
- callbacks = callbacks or []
- self.callbacks = [c for c in callbacks]
- self.queue_length = queue_length
-
- def append(self, callback):
- self.callbacks.append(callback)
-
- def set_params(self, params):
- for callback in self.callbacks:
- callback.set_params(params)
-
- def set_model(self, model):
- for callback in self.callbacks:
- callback.set_model(model)
-
- def on_epoch_begin(self, epoch, logs=None):
- """Called at the start of an epoch.
-
- Arguments:
- epoch: integer, index of epoch.
- logs: dictionary of logs.
- """
- logs = logs or {}
- for callback in self.callbacks:
- callback.on_epoch_begin(epoch, logs)
- self._delta_t_batch = 0.
- self._delta_ts_batch_begin = deque([], maxlen=self.queue_length)
- self._delta_ts_batch_end = deque([], maxlen=self.queue_length)
-
- def on_epoch_end(self, epoch, logs=None):
- """Called at the end of an epoch.
-
- Arguments:
- epoch: integer, index of epoch.
- logs: dictionary of logs.
- """
- logs = logs or {}
- for callback in self.callbacks:
- callback.on_epoch_end(epoch, logs)
-
- def on_batch_begin(self, batch, logs=None):
- """Called right before processing a batch.
-
- Arguments:
- batch: integer, index of batch within the current epoch.
- logs: dictionary of logs.
- """
- logs = logs or {}
- t_before_callbacks = time.time()
- for callback in self.callbacks:
- callback.on_batch_begin(batch, logs)
- self._delta_ts_batch_begin.append(time.time() - t_before_callbacks)
- delta_t_median = np.median(self._delta_ts_batch_begin)
- if (self._delta_t_batch > 0. and
- delta_t_median > 0.95 * self._delta_t_batch and delta_t_median > 0.1):
- logging.warning(
- 'Method on_batch_begin() is slow compared '
- 'to the batch update (%f). Check your callbacks.' % delta_t_median)
- self._t_enter_batch = time.time()
-
- def on_batch_end(self, batch, logs=None):
- """Called at the end of a batch.
-
- Arguments:
- batch: integer, index of batch within the current epoch.
- logs: dictionary of logs.
- """
- logs = logs or {}
- if not hasattr(self, '_t_enter_batch'):
- self._t_enter_batch = time.time()
- self._delta_t_batch = time.time() - self._t_enter_batch
- t_before_callbacks = time.time()
- for callback in self.callbacks:
- callback.on_batch_end(batch, logs)
- self._delta_ts_batch_end.append(time.time() - t_before_callbacks)
- delta_t_median = np.median(self._delta_ts_batch_end)
- if (self._delta_t_batch > 0. and
- (delta_t_median > 0.95 * self._delta_t_batch and delta_t_median > 0.1)):
- logging.warning(
- 'Method on_batch_end() is slow compared '
- 'to the batch update (%f). Check your callbacks.' % delta_t_median)
-
- def on_train_begin(self, logs=None):
- """Called at the beginning of training.
-
- Arguments:
- logs: dictionary of logs.
- """
- logs = logs or {}
- for callback in self.callbacks:
- callback.on_train_begin(logs)
-
- def on_train_end(self, logs=None):
- """Called at the end of training.
-
- Arguments:
- logs: dictionary of logs.
- """
- logs = logs or {}
- for callback in self.callbacks:
- callback.on_train_end(logs)
-
- def __iter__(self):
- return iter(self.callbacks)
-
-
-class Callback(object):
- """Abstract base class used to build new callbacks.
-
- # Properties
- params: dict. Training parameters
- (eg. verbosity, batch size, number of epochs...).
- model: instance of `keras.models.Model`.
- Reference of the model being trained.
-
- The `logs` dictionary that callback methods
- take as argument will contain keys for quantities relevant to
- the current batch or epoch.
-
- Currently, the `.fit()` method of the `Sequential` model class
- will include the following quantities in the `logs` that
- it passes to its callbacks:
-
- on_epoch_end: logs include `acc` and `loss`, and
- optionally include `val_loss`
- (if validation is enabled in `fit`), and `val_acc`
- (if validation and accuracy monitoring are enabled).
- on_batch_begin: logs include `size`,
- the number of samples in the current batch.
- on_batch_end: logs include `loss`, and optionally `acc`
- (if accuracy monitoring is enabled).
- """
-
- def __init__(self):
- self.validation_data = None
-
- def set_params(self, params):
- self.params = params
-
- def set_model(self, model):
- self.model = model
-
- def on_epoch_begin(self, epoch, logs=None):
- pass
-
- def on_epoch_end(self, epoch, logs=None):
- pass
-
- def on_batch_begin(self, batch, logs=None):
- pass
-
- def on_batch_end(self, batch, logs=None):
- pass
-
- def on_train_begin(self, logs=None):
- pass
-
- def on_train_end(self, logs=None):
- pass
-
-
-class BaseLogger(Callback):
- """Callback that accumulates epoch averages of metrics.
-
- This callback is automatically applied to every Keras model.
- """
-
- def on_epoch_begin(self, epoch, logs=None):
- self.seen = 0
- self.totals = {}
-
- def on_batch_end(self, batch, logs=None):
- logs = logs or {}
- batch_size = logs.get('size', 0)
- self.seen += batch_size
-
- for k, v in logs.items():
- if k in self.totals:
- self.totals[k] += v * batch_size
- else:
- self.totals[k] = v * batch_size
-
- def on_epoch_end(self, epoch, logs=None):
- if logs is not None:
- for k in self.params['metrics']:
- if k in self.totals:
- # Make value available to next callbacks.
- logs[k] = self.totals[k] / self.seen
-
-
-class TerminateOnNaN(Callback):
- """Callback that terminates training when a NaN loss is encountered."""
-
- def __init__(self):
- super(TerminateOnNaN, self).__init__()
-
- def on_batch_end(self, batch, logs=None):
- logs = logs or {}
- loss = logs.get('loss')
- if loss is not None:
- if np.isnan(loss) or np.isinf(loss):
- print('Batch %d: Invalid loss, terminating training' % (batch))
- self.model.stop_training = True
-
-
-class ProgbarLogger(Callback):
- """Callback that prints metrics to stdout.
-
- Arguments:
- count_mode: One of "steps" or "samples".
- Whether the progress bar should
- count samples seens or steps (batches) seen.
-
- Raises:
- ValueError: In case of invalid `count_mode`.
- """
-
- def __init__(self, count_mode='samples'):
- super(ProgbarLogger, self).__init__()
- if count_mode == 'samples':
- self.use_steps = False
- elif count_mode == 'steps':
- self.use_steps = True
- else:
- raise ValueError('Unknown `count_mode`: ' + str(count_mode))
-
- def on_train_begin(self, logs=None):
- self.verbose = self.params['verbose']
- self.epochs = self.params['epochs']
-
- def on_epoch_begin(self, epoch, logs=None):
- if self.verbose:
- print('Epoch %d/%d' % (epoch + 1, self.epochs))
- if self.use_steps:
- target = self.params['steps']
- else:
- target = self.params['samples']
- self.target = target
- self.progbar = Progbar(target=self.target, verbose=self.verbose)
- self.seen = 0
-
- def on_batch_begin(self, batch, logs=None):
- if self.seen < self.target:
- self.log_values = []
-
- def on_batch_end(self, batch, logs=None):
- logs = logs or {}
- batch_size = logs.get('size', 0)
- if self.use_steps:
- self.seen += 1
- else:
- self.seen += batch_size
-
- for k in self.params['metrics']:
- if k in logs:
- self.log_values.append((k, logs[k]))
-
- # Skip progbar update for the last batch;
- # will be handled by on_epoch_end.
- if self.verbose and self.seen < self.target:
- self.progbar.update(self.seen, self.log_values)
-
- def on_epoch_end(self, epoch, logs=None):
- logs = logs or {}
- for k in self.params['metrics']:
- if k in logs:
- self.log_values.append((k, logs[k]))
- if self.verbose:
- self.progbar.update(self.seen, self.log_values, force=True)
-
-
-class History(Callback):
- """Callback that records events into a `History` object.
-
- This callback is automatically applied to
- every Keras model. The `History` object
- gets returned by the `fit` method of models.
- """
-
- def on_train_begin(self, logs=None):
- self.epoch = []
- self.history = {}
-
- def on_epoch_end(self, epoch, logs=None):
- logs = logs or {}
- self.epoch.append(epoch)
- for k, v in logs.items():
- self.history.setdefault(k, []).append(v)
-
-
-class ModelCheckpoint(Callback):
- """Save the model after every epoch.
-
- `filepath` can contain named formatting options,
- which will be filled the value of `epoch` and
- keys in `logs` (passed in `on_epoch_end`).
-
- For example: if `filepath` is `weights.{epoch:02d}-{val_loss:.2f}.hdf5`,
- then the model checkpoints will be saved with the epoch number and
- the validation loss in the filename.
-
- Arguments:
- filepath: string, path to save the model file.
- monitor: quantity to monitor.
- verbose: verbosity mode, 0 or 1.
- save_best_only: if `save_best_only=True`,
- the latest best model according to
- the quantity monitored will not be overwritten.
- mode: one of {auto, min, max}.
- If `save_best_only=True`, the decision
- to overwrite the current save file is made
- based on either the maximization or the
- minimization of the monitored quantity. For `val_acc`,
- this should be `max`, for `val_loss` this should
- be `min`, etc. In `auto` mode, the direction is
- automatically inferred from the name of the monitored quantity.
- save_weights_only: if True, then only the model's weights will be
- saved (`model.save_weights(filepath)`), else the full model
- is saved (`model.save(filepath)`).
- period: Interval (number of epochs) between checkpoints.
- """
-
- def __init__(self,
- filepath,
- monitor='val_loss',
- verbose=0,
- save_best_only=False,
- save_weights_only=False,
- mode='auto',
- period=1):
- super(ModelCheckpoint, self).__init__()
- self.monitor = monitor
- self.verbose = verbose
- self.filepath = filepath
- self.save_best_only = save_best_only
- self.save_weights_only = save_weights_only
- self.period = period
- self.epochs_since_last_save = 0
-
- if mode not in ['auto', 'min', 'max']:
- logging.warning('ModelCheckpoint mode %s is unknown, '
- 'fallback to auto mode.' % mode)
- mode = 'auto'
-
- if mode == 'min':
- self.monitor_op = np.less
- self.best = np.Inf
- elif mode == 'max':
- self.monitor_op = np.greater
- self.best = -np.Inf
- else:
- if 'acc' in self.monitor or self.monitor.startswith('fmeasure'):
- self.monitor_op = np.greater
- self.best = -np.Inf
- else:
- self.monitor_op = np.less
- self.best = np.Inf
-
- def on_epoch_end(self, epoch, logs=None):
- logs = logs or {}
- self.epochs_since_last_save += 1
- if self.epochs_since_last_save >= self.period:
- self.epochs_since_last_save = 0
- filepath = self.filepath.format(epoch=epoch, **logs)
- if self.save_best_only:
- current = logs.get(self.monitor)
- if current is None:
- logging.warning('Can save best model only with %s available, '
- 'skipping.' % (self.monitor))
- else:
- if self.monitor_op(current, self.best):
- if self.verbose > 0:
- print('Epoch %05d: %s improved from %0.5f to %0.5f,'
- ' saving model to %s' % (epoch, self.monitor, self.best,
- current, filepath))
- self.best = current
- if self.save_weights_only:
- self.model.save_weights(filepath, overwrite=True)
- else:
- self.model.save(filepath, overwrite=True)
- else:
- if self.verbose > 0:
- print('Epoch %05d: %s did not improve' % (epoch, self.monitor))
- else:
- if self.verbose > 0:
- print('Epoch %05d: saving model to %s' % (epoch, filepath))
- if self.save_weights_only:
- self.model.save_weights(filepath, overwrite=True)
- else:
- self.model.save(filepath, overwrite=True)
-
-
-class EarlyStopping(Callback):
- """Stop training when a monitored quantity has stopped improving.
-
- Arguments:
- monitor: quantity to be monitored.
- min_delta: minimum change in the monitored quantity
- to qualify as an improvement, i.e. an absolute
- change of less than min_delta, will count as no
- improvement.
- patience: number of epochs with no improvement
- after which training will be stopped.
- verbose: verbosity mode.
- mode: one of {auto, min, max}. In `min` mode,
- training will stop when the quantity
- monitored has stopped decreasing; in `max`
- mode it will stop when the quantity
- monitored has stopped increasing; in `auto`
- mode, the direction is automatically inferred
- from the name of the monitored quantity.
- """
-
- def __init__(self,
- monitor='val_loss',
- min_delta=0,
- patience=0,
- verbose=0,
- mode='auto'):
- super(EarlyStopping, self).__init__()
-
- self.monitor = monitor
- self.patience = patience
- self.verbose = verbose
- self.min_delta = min_delta
- self.wait = 0
- self.stopped_epoch = 0
-
- if mode not in ['auto', 'min', 'max']:
- logging.warning('EarlyStopping mode %s is unknown, '
- 'fallback to auto mode.' % mode)
- mode = 'auto'
-
- if mode == 'min':
- self.monitor_op = np.less
- elif mode == 'max':
- self.monitor_op = np.greater
- else:
- if 'acc' in self.monitor:
- self.monitor_op = np.greater
- else:
- self.monitor_op = np.less
-
- if self.monitor_op == np.greater:
- self.min_delta *= 1
- else:
- self.min_delta *= -1
-
- def on_train_begin(self, logs=None):
- # Allow instances to be re-used
- self.wait = 0
- self.stopped_epoch = 0
- self.best = np.Inf if self.monitor_op == np.less else -np.Inf
-
- def on_epoch_end(self, epoch, logs=None):
- current = logs.get(self.monitor)
- if current is None:
- logging.warning('Early stopping conditioned on metric `%s` '
- 'which is not available. Available metrics are: %s' %
- (self.monitor, ','.join(list(logs.keys()))))
- return
- if self.monitor_op(current - self.min_delta, self.best):
- self.best = current
- self.wait = 0
- else:
- if self.wait >= self.patience:
- self.stopped_epoch = epoch
- self.model.stop_training = True
- self.wait += 1
-
- def on_train_end(self, logs=None):
- if self.stopped_epoch > 0 and self.verbose > 0:
- print('Epoch %05d: early stopping' % (self.stopped_epoch))
-
-
-class RemoteMonitor(Callback):
- """Callback used to stream events to a server.
-
- Requires the `requests` library.
- Events are sent to `root + '/publish/epoch/end/'` by default. Calls are
- HTTP POST, with a `data` argument which is a
- JSON-encoded dictionary of event data.
-
- Arguments:
- root: String; root url of the target server.
- path: String; path relative to `root` to which the events will be sent.
- field: String; JSON field under which the data will be stored.
- headers: Dictionary; optional custom HTTP headers.
- Defaults to:
- `{'Accept': 'application/json', 'Content-Type': 'application/json'}`
- """
-
- def __init__(self,
- root='http://localhost:9000',
- path='/publish/epoch/end/',
- field='data',
- headers=None):
- super(RemoteMonitor, self).__init__()
- if headers is None:
- headers = {
- 'Accept': 'application/json',
- 'Content-Type': 'application/json'
- }
- self.root = root
- self.path = path
- self.field = field
- self.headers = headers
-
- def on_epoch_end(self, epoch, logs=None):
- if requests is None:
- raise ImportError('RemoteMonitor requires ' 'the `requests` library.')
- logs = logs or {}
- send = {}
- send['epoch'] = epoch
- for k, v in logs.items():
- send[k] = v
- try:
- requests.post(
- self.root + self.path, {self.field: json.dumps(send)},
- headers=self.headers)
- except requests.exceptions.RequestException:
- logging.warning('Warning: could not reach RemoteMonitor '
- 'root server at ' + str(self.root))
-
-
-class LearningRateScheduler(Callback):
- """Learning rate scheduler.
-
- Arguments:
- schedule: a function that takes an epoch index as input
- (integer, indexed from 0) and returns a new
- learning rate as output (float).
- """
-
- def __init__(self, schedule):
- super(LearningRateScheduler, self).__init__()
- self.schedule = schedule
-
- def on_epoch_begin(self, epoch, logs=None):
- if not hasattr(self.model.optimizer, 'lr'):
- raise ValueError('Optimizer must have a "lr" attribute.')
- lr = self.schedule(epoch)
- if not isinstance(lr, (float, np.float32, np.float64)):
- raise ValueError('The output of the "schedule" function '
- 'should be float.')
- K.set_value(self.model.optimizer.lr, lr)
-
-
-class TensorBoard(Callback):
- # pylint: disable=line-too-long
- """Tensorboard basic visualizations.
-
- This callback writes a log for TensorBoard, which allows
- you to visualize dynamic graphs of your training and test
- metrics, as well as activation histograms for the different
- layers in your model.
-
- TensorBoard is a visualization tool provided with TensorFlow.
-
- If you have installed TensorFlow with pip, you should be able
- to launch TensorBoard from the command line:
-
- ```sh
- tensorboard --logdir=/full_path_to_your_logs
- ```
-
- You can find more information about TensorBoard
- [here](https://www.tensorflow.org/get_started/summaries_and_tensorboard).
-
- Arguments:
- log_dir: the path of the directory where to save the log
- files to be parsed by TensorBoard.
- histogram_freq: frequency (in epochs) at which to compute activation
- and weight histograms for the layers of the model. If set to 0,
- histograms won't be computed. Validation data (or split) must be
- specified for histogram visualizations.
- write_graph: whether to visualize the graph in TensorBoard.
- The log file can become quite large when
- write_graph is set to True.
- write_grads: whether to visualize gradient histograms in TensorBoard.
- `histogram_freq` must be greater than 0.
- batch_size: size of batch of inputs to feed to the network
- for histograms computation.
- write_images: whether to write model weights to visualize as
- image in TensorBoard.
- embeddings_freq: frequency (in epochs) at which selected embedding
- layers will be saved.
- embeddings_layer_names: a list of names of layers to keep eye on. If
- None or empty list all the embedding layer will be watched.
- embeddings_metadata: a dictionary which maps layer name to a file name
- in which metadata for this embedding layer is saved. See the
- [details](https://www.tensorflow.org/how_tos/embedding_viz/#metadata_optional)
- about metadata files format. In case if the same metadata file is
- used for all embedding layers, string can be passed.
- """
-
- # pylint: enable=line-too-long
-
- def __init__(self,
- log_dir='./logs',
- histogram_freq=0,
- batch_size=32,
- write_graph=True,
- write_grads=False,
- write_images=False,
- embeddings_freq=0,
- embeddings_layer_names=None,
- embeddings_metadata=None):
- super(TensorBoard, self).__init__()
- self.log_dir = log_dir
- self.histogram_freq = histogram_freq
- self.merged = None
- self.write_graph = write_graph
- self.write_grads = write_grads
- self.write_images = write_images
- self.embeddings_freq = embeddings_freq
- self.embeddings_layer_names = embeddings_layer_names
- self.embeddings_metadata = embeddings_metadata or {}
- self.batch_size = batch_size
-
- def set_model(self, model):
- self.model = model
- self.sess = K.get_session()
- if self.histogram_freq and self.merged is None:
- for layer in self.model.layers:
- for weight in layer.weights:
- mapped_weight_name = weight.name.replace(':', '_')
- tf_summary.histogram(mapped_weight_name, weight)
- if self.write_grads:
- grads = model.optimizer.get_gradients(model.total_loss, weight)
-
- def is_indexed_slices(grad):
- return type(grad).__name__ == 'IndexedSlices'
-
- grads = [grad.values if is_indexed_slices(grad) else grad
- for grad in grads]
- tf_summary.histogram('{}_grad'.format(mapped_weight_name), grads)
- if self.write_images:
- w_img = array_ops.squeeze(weight)
- shape = K.int_shape(w_img)
- if len(shape) == 2: # dense layer kernel case
- if shape[0] > shape[1]:
- w_img = array_ops.transpose(w_img)
- shape = K.int_shape(w_img)
- w_img = array_ops.reshape(w_img, [1, shape[0], shape[1], 1])
- elif len(shape) == 3: # convnet case
- if K.image_data_format() == 'channels_last':
- # switch to channels_first to display
- # every kernel as a separate image
- w_img = array_ops.transpose(w_img, perm=[2, 0, 1])
- shape = K.int_shape(w_img)
- w_img = array_ops.reshape(w_img,
- [shape[0], shape[1], shape[2], 1])
- elif len(shape) == 1: # bias case
- w_img = array_ops.reshape(w_img, [1, shape[0], 1, 1])
- else:
- # not possible to handle 3D convnets etc.
- continue
-
- shape = K.int_shape(w_img)
- assert len(shape) == 4 and shape[-1] in [1, 3, 4]
- tf_summary.image(mapped_weight_name, w_img)
-
- if hasattr(layer, 'output'):
- tf_summary.histogram('{}_out'.format(layer.name), layer.output)
- self.merged = tf_summary.merge_all()
-
- if self.write_graph:
- self.writer = tf_summary.FileWriter(self.log_dir, self.sess.graph)
- else:
- self.writer = tf_summary.FileWriter(self.log_dir)
-
- if self.embeddings_freq:
- embeddings_layer_names = self.embeddings_layer_names
-
- if not embeddings_layer_names:
- embeddings_layer_names = [
- layer.name for layer in self.model.layers
- if type(layer).__name__ == 'Embedding'
- ]
-
- embeddings = {
- layer.name: layer.weights[0]
- for layer in self.model.layers if layer.name in embeddings_layer_names
- }
-
- self.saver = saver_lib.Saver(list(embeddings.values()))
-
- embeddings_metadata = {}
-
- if not isinstance(self.embeddings_metadata, str):
- embeddings_metadata = self.embeddings_metadata
- else:
- embeddings_metadata = {
- layer_name: self.embeddings_metadata
- for layer_name in embeddings.keys()
- }
-
- config = projector.ProjectorConfig()
- self.embeddings_ckpt_path = os.path.join(self.log_dir,
- 'keras_embedding.ckpt')
-
- for layer_name, tensor in embeddings.items():
- embedding = config.embeddings.add()
- embedding.tensor_name = tensor.name
-
- if layer_name in embeddings_metadata:
- embedding.metadata_path = embeddings_metadata[layer_name]
-
- projector.visualize_embeddings(self.writer, config)
-
- def on_epoch_end(self, epoch, logs=None):
- logs = logs or {}
-
- if not self.validation_data and self.histogram_freq:
- raise ValueError('If printing histograms, validation_data must be '
- 'provided, and cannot be a generator.')
- if self.validation_data and self.histogram_freq:
- if epoch % self.histogram_freq == 0:
-
- val_data = self.validation_data
- tensors = (
- self.model.inputs + self.model.targets + self.model.sample_weights)
-
- if self.model.uses_learning_phase:
- tensors += [K.learning_phase()]
-
- assert len(val_data) == len(tensors)
- val_size = val_data[0].shape[0]
- i = 0
- while i < val_size:
- step = min(self.batch_size, val_size - i)
- batch_val = []
- batch_val.append(val_data[0][i:i + step])
- batch_val.append(val_data[1][i:i + step])
- batch_val.append(val_data[2][i:i + step])
- if self.model.uses_learning_phase:
- # do not slice the learning phase
- batch_val = [x[i:i + step] for x in val_data[:-1]]
- batch_val.append(val_data[-1])
- else:
- batch_val = [x[i:i + step] for x in val_data]
- feed_dict = dict(zip(tensors, batch_val))
- result = self.sess.run([self.merged], feed_dict=feed_dict)
- summary_str = result[0]
- self.writer.add_summary(summary_str, epoch)
- i += self.batch_size
-
- if self.embeddings_freq and self.embeddings_ckpt_path:
- if epoch % self.embeddings_freq == 0:
- self.saver.save(self.sess, self.embeddings_ckpt_path, epoch)
-
- for name, value in logs.items():
- if name in ['batch', 'size']:
- continue
- summary = tf_summary.Summary()
- summary_value = summary.value.add()
- summary_value.simple_value = value.item()
- summary_value.tag = name
- self.writer.add_summary(summary, epoch)
- self.writer.flush()
-
- def on_train_end(self, _):
- self.writer.close()
-
-
-class ReduceLROnPlateau(Callback):
- """Reduce learning rate when a metric has stopped improving.
-
- Models often benefit from reducing the learning rate by a factor
- of 2-10 once learning stagnates. This callback monitors a
- quantity and if no improvement is seen for a 'patience' number
- of epochs, the learning rate is reduced.
-
- Example:
-
- ```python
- reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2,
- patience=5, min_lr=0.001)
- model.fit(X_train, Y_train, callbacks=[reduce_lr])
- ```
-
- Arguments:
- monitor: quantity to be monitored.
- factor: factor by which the learning rate will
- be reduced. new_lr = lr * factor
- patience: number of epochs with no improvement
- after which learning rate will be reduced.
- verbose: int. 0: quiet, 1: update messages.
- mode: one of {auto, min, max}. In `min` mode,
- lr will be reduced when the quantity
- monitored has stopped decreasing; in `max`
- mode it will be reduced when the quantity
- monitored has stopped increasing; in `auto`
- mode, the direction is automatically inferred
- from the name of the monitored quantity.
- epsilon: threshold for measuring the new optimum,
- to only focus on significant changes.
- cooldown: number of epochs to wait before resuming
- normal operation after lr has been reduced.
- min_lr: lower bound on the learning rate.
- """
-
- def __init__(self,
- monitor='val_loss',
- factor=0.1,
- patience=10,
- verbose=0,
- mode='auto',
- epsilon=1e-4,
- cooldown=0,
- min_lr=0):
- super(ReduceLROnPlateau, self).__init__()
-
- self.monitor = monitor
- if factor >= 1.0:
- raise ValueError('ReduceLROnPlateau ' 'does not support a factor >= 1.0.')
- self.factor = factor
- self.min_lr = min_lr
- self.epsilon = epsilon
- self.patience = patience
- self.verbose = verbose
- self.cooldown = cooldown
- self.cooldown_counter = 0 # Cooldown counter.
- self.wait = 0
- self.best = 0
- self.mode = mode
- self.monitor_op = None
- self._reset()
-
- def _reset(self):
- """Resets wait counter and cooldown counter.
- """
- if self.mode not in ['auto', 'min', 'max']:
- logging.warning('Learning Rate Plateau Reducing mode %s is unknown, '
- 'fallback to auto mode.' % (self.mode))
- self.mode = 'auto'
- if (self.mode == 'min' or
- (self.mode == 'auto' and 'acc' not in self.monitor)):
- self.monitor_op = lambda a, b: np.less(a, b - self.epsilon)
- self.best = np.Inf
- else:
- self.monitor_op = lambda a, b: np.greater(a, b + self.epsilon)
- self.best = -np.Inf
- self.cooldown_counter = 0
- self.wait = 0
- self.lr_epsilon = self.min_lr * 1e-4
-
- def on_train_begin(self, logs=None):
- self._reset()
-
- def on_epoch_end(self, epoch, logs=None):
- logs = logs or {}
- logs['lr'] = K.get_value(self.model.optimizer.lr)
- current = logs.get(self.monitor)
- if current is None:
- logging.warning('Reduce LR on plateau conditioned on metric `%s` '
- 'which is not available. Available metrics are: %s' %
- (self.monitor, ','.join(list(logs.keys()))))
- else:
- if self.in_cooldown():
- self.cooldown_counter -= 1
- self.wait = 0
-
- if self.monitor_op(current, self.best):
- self.best = current
- self.wait = 0
- elif not self.in_cooldown():
- if self.wait >= self.patience:
- old_lr = float(K.get_value(self.model.optimizer.lr))
- if old_lr > self.min_lr + self.lr_epsilon:
- new_lr = old_lr * self.factor
- new_lr = max(new_lr, self.min_lr)
- K.set_value(self.model.optimizer.lr, new_lr)
- if self.verbose > 0:
- print('\nEpoch %05d: reducing learning rate to %s.' % (epoch,
- new_lr))
- self.cooldown_counter = self.cooldown
- self.wait = 0
- self.wait += 1
-
- def in_cooldown(self):
- return self.cooldown_counter > 0
-
-
-class CSVLogger(Callback):
- """Callback that streams epoch results to a csv file.
-
- Supports all values that can be represented as a string,
- including 1D iterables such as np.ndarray.
-
- Example:
- ```python
- csv_logger = CSVLogger('training.log')
- model.fit(X_train, Y_train, callbacks=[csv_logger])
- ```
-
- Arguments:
- filename: filename of the csv file, e.g. 'run/log.csv'.
- separator: string used to separate elements in the csv file.
- append: True: append if file exists (useful for continuing
- training). False: overwrite existing file,
- """
-
- def __init__(self, filename, separator=',', append=False):
- self.sep = separator
- self.filename = filename
- self.append = append
- self.writer = None
- self.keys = None
- self.append_header = True
- self.file_flags = 'b' if six.PY2 and os.name == 'nt' else ''
- super(CSVLogger, self).__init__()
-
- def on_train_begin(self, logs=None):
- if self.append:
- if os.path.exists(self.filename):
- with open(self.filename, 'r' + self.file_flags) as f:
- self.append_header = not bool(len(f.readline()))
- self.csv_file = open(self.filename, 'a' + self.file_flags)
- else:
- self.csv_file = open(self.filename, 'w' + self.file_flags)
-
- def on_epoch_end(self, epoch, logs=None):
- logs = logs or {}
-
- def handle_value(k):
- is_zero_dim_ndarray = isinstance(k, np.ndarray) and k.ndim == 0
- if isinstance(k, six.string_types):
- return k
- elif isinstance(k, Iterable) and not is_zero_dim_ndarray:
- return '"[%s]"' % (', '.join(map(str, k)))
- else:
- return k
-
- if self.model.stop_training:
- # We set NA so that csv parsers do not fail for this last epoch.
- logs = dict([(k, logs[k]) if k in logs else (k, 'NA') for k in self.keys])
-
- if not self.writer:
- self.keys = sorted(logs.keys())
-
- class CustomDialect(csv.excel):
- delimiter = self.sep
-
- self.writer = csv.DictWriter(
- self.csv_file,
- fieldnames=['epoch'] + self.keys,
- dialect=CustomDialect)
- if self.append_header:
- self.writer.writeheader()
-
- row_dict = OrderedDict({'epoch': epoch})
- row_dict.update((key, handle_value(logs[key])) for key in self.keys)
- self.writer.writerow(row_dict)
- self.csv_file.flush()
-
- def on_train_end(self, logs=None):
- self.csv_file.close()
- self.writer = None
-
-
-class LambdaCallback(Callback):
- r"""Callback for creating simple, custom callbacks on-the-fly.
-
- This callback is constructed with anonymous functions that will be called
- at the appropriate time. Note that the callbacks expects positional
- arguments, as:
-
- - `on_epoch_begin` and `on_epoch_end` expect two positional arguments:
- `epoch`, `logs`
- - `on_batch_begin` and `on_batch_end` expect two positional arguments:
- `batch`, `logs`
- - `on_train_begin` and `on_train_end` expect one positional argument:
- `logs`
-
- Arguments:
- on_epoch_begin: called at the beginning of every epoch.
- on_epoch_end: called at the end of every epoch.
- on_batch_begin: called at the beginning of every batch.
- on_batch_end: called at the end of every batch.
- on_train_begin: called at the beginning of model training.
- on_train_end: called at the end of model training.
-
- Example:
-
- ```python
- # Print the batch number at the beginning of every batch.
- batch_print_callback = LambdaCallback(
- on_batch_begin=lambda batch,logs: print(batch))
-
- # Stream the epoch loss to a file in JSON format. The file content
- # is not well-formed JSON but rather has a JSON object per line.
- import json
- json_log = open('loss_log.json', mode='wt', buffering=1)
- json_logging_callback = LambdaCallback(
- on_epoch_end=lambda epoch, logs: json_log.write(
- json.dumps({'epoch': epoch, 'loss': logs['loss']}) + '\n'),
- on_train_end=lambda logs: json_log.close()
- )
-
- # Terminate some processes after having finished model training.
- processes = ...
- cleanup_callback = LambdaCallback(
- on_train_end=lambda logs: [
- p.terminate() for p in processes if p.is_alive()])
-
- model.fit(...,
- callbacks=[batch_print_callback,
- json_logging_callback,
- cleanup_callback])
- ```
- """
-
- def __init__(self,
- on_epoch_begin=None,
- on_epoch_end=None,
- on_batch_begin=None,
- on_batch_end=None,
- on_train_begin=None,
- on_train_end=None,
- **kwargs):
- super(LambdaCallback, self).__init__()
- self.__dict__.update(kwargs)
- if on_epoch_begin is not None:
- self.on_epoch_begin = on_epoch_begin
- else:
- self.on_epoch_begin = lambda epoch, logs: None
- if on_epoch_end is not None:
- self.on_epoch_end = on_epoch_end
- else:
- self.on_epoch_end = lambda epoch, logs: None
- if on_batch_begin is not None:
- self.on_batch_begin = on_batch_begin
- else:
- self.on_batch_begin = lambda batch, logs: None
- if on_batch_end is not None:
- self.on_batch_end = on_batch_end
- else:
- self.on_batch_end = lambda batch, logs: None
- if on_train_begin is not None:
- self.on_train_begin = on_train_begin
- else:
- self.on_train_begin = lambda logs: None
- if on_train_end is not None:
- self.on_train_end = on_train_end
- else:
- self.on_train_end = lambda logs: None
diff --git a/tensorflow/contrib/keras/python/keras/callbacks_test.py b/tensorflow/contrib/keras/python/keras/callbacks_test.py
deleted file mode 100644
index f255feff41..0000000000
--- a/tensorflow/contrib/keras/python/keras/callbacks_test.py
+++ /dev/null
@@ -1,859 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for Keras callbacks."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import csv
-import multiprocessing
-import os
-import re
-import shutil
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-
-try:
- import h5py # pylint:disable=g-import-not-at-top
-except ImportError:
- h5py = None
-
-try:
- import requests # pylint:disable=g-import-not-at-top
-except ImportError:
- requests = None
-
-
-TRAIN_SAMPLES = 10
-TEST_SAMPLES = 10
-NUM_CLASSES = 2
-INPUT_DIM = 3
-NUM_HIDDEN = 5
-BATCH_SIZE = 5
-
-
-class KerasCallbacksTest(test.TestCase):
-
- def test_ModelCheckpoint(self):
- if h5py is None:
- return # Skip test if models cannot be saved.
-
- with self.test_session():
- np.random.seed(1337)
-
- temp_dir = self.get_temp_dir()
- self.addCleanup(shutil.rmtree, temp_dir)
-
- filepath = os.path.join(temp_dir, 'checkpoint.h5')
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=TRAIN_SAMPLES,
- test_samples=TEST_SAMPLES,
- input_shape=(INPUT_DIM,),
- num_classes=NUM_CLASSES)
- y_test = keras.utils.to_categorical(y_test)
- y_train = keras.utils.to_categorical(y_train)
- # case 1
- monitor = 'val_loss'
- save_best_only = False
- mode = 'auto'
-
- model = keras.models.Sequential()
- model.add(
- keras.layers.Dense(
- NUM_HIDDEN, input_dim=INPUT_DIM, activation='relu'))
- model.add(keras.layers.Dense(NUM_CLASSES, activation='softmax'))
- model.compile(
- loss='categorical_crossentropy',
- optimizer='rmsprop',
- metrics=['accuracy'])
-
- cbks = [
- keras.callbacks.ModelCheckpoint(
- filepath,
- monitor=monitor,
- save_best_only=save_best_only,
- mode=mode)
- ]
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=1,
- verbose=0)
- assert os.path.exists(filepath)
- os.remove(filepath)
-
- # case 2
- mode = 'min'
- cbks = [
- keras.callbacks.ModelCheckpoint(
- filepath,
- monitor=monitor,
- save_best_only=save_best_only,
- mode=mode)
- ]
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=1,
- verbose=0)
- assert os.path.exists(filepath)
- os.remove(filepath)
-
- # case 3
- mode = 'max'
- monitor = 'val_acc'
- cbks = [
- keras.callbacks.ModelCheckpoint(
- filepath,
- monitor=monitor,
- save_best_only=save_best_only,
- mode=mode)
- ]
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=1,
- verbose=0)
- assert os.path.exists(filepath)
- os.remove(filepath)
-
- # case 4
- save_best_only = True
- cbks = [
- keras.callbacks.ModelCheckpoint(
- filepath,
- monitor=monitor,
- save_best_only=save_best_only,
- mode=mode)
- ]
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=1,
- verbose=0)
- assert os.path.exists(filepath)
- os.remove(filepath)
-
- # Case: metric not available.
- cbks = [
- keras.callbacks.ModelCheckpoint(
- filepath,
- monitor='unknown',
- save_best_only=True)
- ]
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=1,
- verbose=0)
- # File won't be written.
- assert not os.path.exists(filepath)
-
- # case 5
- save_best_only = False
- period = 2
- mode = 'auto'
-
- filepath = os.path.join(temp_dir, 'checkpoint.{epoch:02d}.h5')
- cbks = [
- keras.callbacks.ModelCheckpoint(
- filepath,
- monitor=monitor,
- save_best_only=save_best_only,
- mode=mode,
- period=period)
- ]
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=4,
- verbose=1)
- assert os.path.exists(filepath.format(epoch=1))
- assert os.path.exists(filepath.format(epoch=3))
- os.remove(filepath.format(epoch=1))
- os.remove(filepath.format(epoch=3))
- assert not os.path.exists(filepath.format(epoch=0))
- assert not os.path.exists(filepath.format(epoch=2))
-
- # Invalid use: this will raise a warning but not an Exception.
- keras.callbacks.ModelCheckpoint(
- filepath,
- monitor=monitor,
- save_best_only=save_best_only,
- mode='unknown')
-
- def test_EarlyStopping(self):
- with self.test_session():
- np.random.seed(123)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=TRAIN_SAMPLES,
- test_samples=TEST_SAMPLES,
- input_shape=(INPUT_DIM,),
- num_classes=NUM_CLASSES)
- y_test = keras.utils.to_categorical(y_test)
- y_train = keras.utils.to_categorical(y_train)
- model = keras.models.Sequential()
- model.add(
- keras.layers.Dense(
- NUM_HIDDEN, input_dim=INPUT_DIM, activation='relu'))
- model.add(keras.layers.Dense(NUM_CLASSES, activation='softmax'))
- model.compile(
- loss='categorical_crossentropy',
- optimizer='rmsprop',
- metrics=['accuracy'])
-
- cases = [
- ('max', 'val_acc'),
- ('min', 'val_loss'),
- ('auto', 'val_acc'),
- ('auto', 'loss'),
- ('unknown', 'unknown')
- ]
- for mode, monitor in cases:
- patience = 0
- cbks = [
- keras.callbacks.EarlyStopping(
- patience=patience, monitor=monitor, mode=mode)
- ]
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=5,
- verbose=0)
-
- def test_EarlyStopping_reuse(self):
- with self.test_session():
- np.random.seed(1337)
- patience = 3
- data = np.random.random((100, 1))
- labels = np.where(data > 0.5, 1, 0)
- model = keras.models.Sequential((keras.layers.Dense(
- 1, input_dim=1, activation='relu'), keras.layers.Dense(
- 1, activation='sigmoid'),))
- model.compile(
- optimizer='sgd', loss='binary_crossentropy', metrics=['accuracy'])
- stopper = keras.callbacks.EarlyStopping(monitor='acc', patience=patience)
- weights = model.get_weights()
-
- hist = model.fit(data, labels, callbacks=[stopper], verbose=0)
- assert len(hist.epoch) >= patience
-
- # This should allow training to go for at least `patience` epochs
- model.set_weights(weights)
- hist = model.fit(data, labels, callbacks=[stopper], verbose=0)
- assert len(hist.epoch) >= patience
-
- def test_RemoteMonitor(self):
- if requests is None:
- return
-
- monitor = keras.callbacks.RemoteMonitor()
- # This will raise a warning since the default address in unreachable:
- monitor.on_epoch_end(0, logs={'loss': 0.})
-
- def test_LearningRateScheduler(self):
- with self.test_session():
- np.random.seed(1337)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=TRAIN_SAMPLES,
- test_samples=TEST_SAMPLES,
- input_shape=(INPUT_DIM,),
- num_classes=NUM_CLASSES)
- y_test = keras.utils.to_categorical(y_test)
- y_train = keras.utils.to_categorical(y_train)
- model = keras.models.Sequential()
- model.add(
- keras.layers.Dense(
- NUM_HIDDEN, input_dim=INPUT_DIM, activation='relu'))
- model.add(keras.layers.Dense(NUM_CLASSES, activation='softmax'))
- model.compile(
- loss='categorical_crossentropy',
- optimizer='sgd',
- metrics=['accuracy'])
-
- cbks = [keras.callbacks.LearningRateScheduler(lambda x: 1. / (1. + x))]
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=5,
- verbose=0)
- assert (float(keras.backend.get_value(model.optimizer.lr)) - 0.2
- ) < keras.backend.epsilon()
-
- def test_ReduceLROnPlateau(self):
- with self.test_session():
- np.random.seed(1337)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=TRAIN_SAMPLES,
- test_samples=TEST_SAMPLES,
- input_shape=(INPUT_DIM,),
- num_classes=NUM_CLASSES)
- y_test = keras.utils.to_categorical(y_test)
- y_train = keras.utils.to_categorical(y_train)
-
- def make_model():
- np.random.seed(1337)
- model = keras.models.Sequential()
- model.add(
- keras.layers.Dense(
- NUM_HIDDEN, input_dim=INPUT_DIM, activation='relu'))
- model.add(keras.layers.Dense(NUM_CLASSES, activation='softmax'))
-
- model.compile(
- loss='categorical_crossentropy',
- optimizer=keras.optimizers.SGD(lr=0.1),
- metrics=['accuracy'])
- return model
-
- model = make_model()
- # This should reduce the LR after the first epoch (due to high epsilon).
- cbks = [
- keras.callbacks.ReduceLROnPlateau(
- monitor='val_loss',
- factor=0.1,
- epsilon=10,
- patience=1,
- cooldown=5)
- ]
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=5,
- verbose=0)
- self.assertAllClose(
- float(keras.backend.get_value(model.optimizer.lr)),
- 0.01,
- atol=1e-4)
-
- def test_CSVLogger(self):
- with self.test_session():
- np.random.seed(1337)
- temp_dir = self.get_temp_dir()
- self.addCleanup(shutil.rmtree, temp_dir)
- filepath = os.path.join(temp_dir, 'log.tsv')
-
- sep = '\t'
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=TRAIN_SAMPLES,
- test_samples=TEST_SAMPLES,
- input_shape=(INPUT_DIM,),
- num_classes=NUM_CLASSES)
- y_test = keras.utils.to_categorical(y_test)
- y_train = keras.utils.to_categorical(y_train)
-
- def make_model():
- np.random.seed(1337)
- model = keras.models.Sequential()
- model.add(
- keras.layers.Dense(
- NUM_HIDDEN, input_dim=INPUT_DIM, activation='relu'))
- model.add(keras.layers.Dense(NUM_CLASSES, activation='softmax'))
-
- model.compile(
- loss='categorical_crossentropy',
- optimizer=keras.optimizers.SGD(lr=0.1),
- metrics=['accuracy'])
- return model
-
- # case 1, create new file with defined separator
- model = make_model()
- cbks = [keras.callbacks.CSVLogger(filepath, separator=sep)]
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=1,
- verbose=0)
-
- assert os.path.exists(filepath)
- with open(filepath) as csvfile:
- dialect = csv.Sniffer().sniff(csvfile.read())
- assert dialect.delimiter == sep
- del model
- del cbks
-
- # case 2, append data to existing file, skip header
- model = make_model()
- cbks = [keras.callbacks.CSVLogger(filepath, separator=sep, append=True)]
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=1,
- verbose=0)
-
- # case 3, reuse of CSVLogger object
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=1,
- verbose=0)
-
- with open(filepath) as csvfile:
- output = ' '.join(csvfile.readlines())
- assert len(re.findall('epoch', output)) == 1
-
- os.remove(filepath)
-
- def test_stop_training_csv(self):
- # Test that using the CSVLogger callback with the TerminateOnNaN callback
- # does not result in invalid CSVs.
- np.random.seed(1337)
- tmpdir = self.get_temp_dir()
- self.addCleanup(shutil.rmtree, tmpdir)
-
- with self.test_session():
- fp = os.path.join(tmpdir, 'test.csv')
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=TRAIN_SAMPLES,
- test_samples=TEST_SAMPLES,
- input_shape=(INPUT_DIM,),
- num_classes=NUM_CLASSES)
-
- y_test = keras.utils.to_categorical(y_test)
- y_train = keras.utils.to_categorical(y_train)
- cbks = [keras.callbacks.TerminateOnNaN(), keras.callbacks.CSVLogger(fp)]
- model = keras.models.Sequential()
- for _ in range(5):
- model.add(keras.layers.Dense(2, input_dim=INPUT_DIM, activation='relu'))
- model.add(keras.layers.Dense(NUM_CLASSES, activation='linear'))
- model.compile(loss='mean_squared_error',
- optimizer='rmsprop')
-
- def data_generator():
- i = 0
- max_batch_index = len(x_train) // BATCH_SIZE
- tot = 0
- while 1:
- if tot > 3 * len(x_train):
- yield (np.ones([BATCH_SIZE, INPUT_DIM]) * np.nan,
- np.ones([BATCH_SIZE, NUM_CLASSES]) * np.nan)
- else:
- yield (x_train[i * BATCH_SIZE: (i + 1) * BATCH_SIZE],
- y_train[i * BATCH_SIZE: (i + 1) * BATCH_SIZE])
- i += 1
- tot += 1
- i %= max_batch_index
-
- history = model.fit_generator(data_generator(),
- len(x_train) // BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=20)
- loss = history.history['loss']
- assert len(loss) > 1
- assert loss[-1] == np.inf or np.isnan(loss[-1])
-
- values = []
- with open(fp) as f:
- for x in csv.reader(f):
- values.append(x)
- assert 'nan' in values[-1], 'The last epoch was not logged.'
-
- def test_TerminateOnNaN(self):
- np.random.seed(1337)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=TRAIN_SAMPLES,
- test_samples=TEST_SAMPLES,
- input_shape=(INPUT_DIM,),
- num_classes=NUM_CLASSES)
-
- y_test = keras.utils.to_categorical(y_test)
- y_train = keras.utils.to_categorical(y_train)
- cbks = [keras.callbacks.TerminateOnNaN()]
- model = keras.models.Sequential()
- initializer = keras.initializers.Constant(value=1e5)
- for _ in range(5):
- model.add(keras.layers.Dense(2,
- input_dim=INPUT_DIM,
- activation='relu',
- kernel_initializer=initializer))
- model.add(keras.layers.Dense(NUM_CLASSES))
- model.compile(loss='mean_squared_error',
- optimizer='rmsprop')
-
- history = model.fit(x_train, y_train, batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks, epochs=20)
- loss = history.history['loss']
- assert len(loss) == 1
- assert loss[0] == np.inf
-
- def test_TensorBoard(self):
- np.random.seed(1337)
-
- temp_dir = self.get_temp_dir()
- self.addCleanup(shutil.rmtree, temp_dir)
-
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=TRAIN_SAMPLES,
- test_samples=TEST_SAMPLES,
- input_shape=(INPUT_DIM,),
- num_classes=NUM_CLASSES)
- y_test = keras.utils.to_categorical(y_test)
- y_train = keras.utils.to_categorical(y_train)
-
- def data_generator(train):
- if train:
- max_batch_index = len(x_train) // BATCH_SIZE
- else:
- max_batch_index = len(x_test) // BATCH_SIZE
- i = 0
- while 1:
- if train:
- yield (x_train[i * BATCH_SIZE:(i + 1) * BATCH_SIZE],
- y_train[i * BATCH_SIZE:(i + 1) * BATCH_SIZE])
- else:
- yield (x_test[i * BATCH_SIZE:(i + 1) * BATCH_SIZE],
- y_test[i * BATCH_SIZE:(i + 1) * BATCH_SIZE])
- i += 1
- i %= max_batch_index
-
- # case: Sequential
- with self.test_session():
- model = keras.models.Sequential()
- model.add(
- keras.layers.Dense(
- NUM_HIDDEN, input_dim=INPUT_DIM, activation='relu'))
- model.add(keras.layers.Dense(NUM_CLASSES, activation='softmax'))
- model.compile(
- loss='categorical_crossentropy',
- optimizer='sgd',
- metrics=['accuracy'])
-
- tsb = keras.callbacks.TensorBoard(
- log_dir=temp_dir, histogram_freq=1, write_images=True,
- write_grads=True, embeddings_freq=1,
- embeddings_layer_names=['dense_1'], batch_size=5)
- cbks = [tsb]
-
- # fit with validation data
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=3,
- verbose=0)
-
- # fit with validation data and accuracy
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=2,
- verbose=0)
-
- # fit generator with validation data
- model.fit_generator(
- data_generator(True),
- len(x_train),
- epochs=2,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- verbose=0)
-
- # fit generator without validation data
- model.fit_generator(
- data_generator(True),
- len(x_train),
- epochs=2,
- callbacks=cbks,
- verbose=0)
-
- # fit generator with validation data and accuracy
- model.fit_generator(
- data_generator(True),
- len(x_train),
- epochs=2,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- verbose=0)
-
- # fit generator without validation data and accuracy
- model.fit_generator(
- data_generator(True), len(x_train), epochs=2, callbacks=cbks)
- assert os.path.exists(temp_dir)
-
- def test_TensorBoard_histogram_freq_must_have_validation_data(self):
- np.random.seed(1337)
- tmpdir = self.get_temp_dir()
- self.addCleanup(shutil.rmtree, tmpdir)
-
- with self.test_session():
- filepath = os.path.join(tmpdir, 'logs')
-
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=TRAIN_SAMPLES,
- test_samples=TEST_SAMPLES,
- input_shape=(INPUT_DIM,),
- num_classes=NUM_CLASSES)
- y_test = keras.utils.to_categorical(y_test)
- y_train = keras.utils.to_categorical(y_train)
-
- def data_generator(train):
- if train:
- max_batch_index = len(x_train) // BATCH_SIZE
- else:
- max_batch_index = len(x_test) // BATCH_SIZE
- i = 0
- while 1:
- if train:
- # simulate multi-input/output models
- yield (x_train[i * BATCH_SIZE: (i + 1) * BATCH_SIZE],
- y_train[i * BATCH_SIZE: (i + 1) * BATCH_SIZE])
- else:
- yield (x_test[i * BATCH_SIZE: (i + 1) * BATCH_SIZE],
- y_test[i * BATCH_SIZE: (i + 1) * BATCH_SIZE])
- i += 1
- i %= max_batch_index
-
- inp = keras.Input((INPUT_DIM,))
- hidden = keras.layers.Dense(2, activation='relu')(inp)
- hidden = keras.layers.Dropout(0.1)(hidden)
- output = keras.layers.Dense(NUM_CLASSES, activation='softmax')(hidden)
- model = keras.models.Model(inputs=inp, outputs=output)
- model.compile(loss='categorical_crossentropy',
- optimizer='sgd',
- metrics=['accuracy'])
-
- # we must generate new callbacks for each test, as they aren't stateless
- def callbacks_factory(histogram_freq):
- return [keras.callbacks.TensorBoard(
- log_dir=filepath,
- histogram_freq=histogram_freq,
- write_images=True, write_grads=True,
- embeddings_freq=1,
- embeddings_layer_names=['dense_1'],
- batch_size=5)]
-
- # fit w/o validation data should raise ValueError if histogram_freq > 0
- with self.assertRaises(ValueError):
- model.fit(x_train, y_train, batch_size=BATCH_SIZE,
- callbacks=callbacks_factory(histogram_freq=1), epochs=3)
-
- # fit generator without validation data should raise ValueError if
- # histogram_freq > 0
- with self.assertRaises(ValueError):
- model.fit_generator(data_generator(True), len(x_train), epochs=2,
- callbacks=callbacks_factory(histogram_freq=1))
-
- # fit generator with validation data generator should raise ValueError if
- # histogram_freq > 0
- with self.assertRaises(ValueError):
- model.fit_generator(data_generator(True), len(x_train), epochs=2,
- validation_data=data_generator(False),
- validation_steps=1,
- callbacks=callbacks_factory(histogram_freq=1))
-
- def test_TensorBoard_multi_input_output(self):
- np.random.seed(1337)
- tmpdir = self.get_temp_dir()
- self.addCleanup(shutil.rmtree, tmpdir)
-
- with self.test_session():
- filepath = os.path.join(tmpdir, 'logs')
-
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=TRAIN_SAMPLES,
- test_samples=TEST_SAMPLES,
- input_shape=(INPUT_DIM,),
- num_classes=NUM_CLASSES)
- y_test = keras.utils.to_categorical(y_test)
- y_train = keras.utils.to_categorical(y_train)
-
- def data_generator(train):
- if train:
- max_batch_index = len(x_train) // BATCH_SIZE
- else:
- max_batch_index = len(x_test) // BATCH_SIZE
- i = 0
- while 1:
- if train:
- # simulate multi-input/output models
- yield ([x_train[i * BATCH_SIZE: (i + 1) * BATCH_SIZE]] * 2,
- [y_train[i * BATCH_SIZE: (i + 1) * BATCH_SIZE]] * 2)
- else:
- yield ([x_test[i * BATCH_SIZE: (i + 1) * BATCH_SIZE]] * 2,
- [y_test[i * BATCH_SIZE: (i + 1) * BATCH_SIZE]] * 2)
- i += 1
- i %= max_batch_index
-
- inp1 = keras.Input((INPUT_DIM,))
- inp2 = keras.Input((INPUT_DIM,))
- inp = keras.layers.add([inp1, inp2])
- hidden = keras.layers.Dense(2, activation='relu')(inp)
- hidden = keras.layers.Dropout(0.1)(hidden)
- output1 = keras.layers.Dense(NUM_CLASSES, activation='softmax')(hidden)
- output2 = keras.layers.Dense(NUM_CLASSES, activation='softmax')(hidden)
- model = keras.models.Model([inp1, inp2], [output1, output2])
- model.compile(loss='categorical_crossentropy',
- optimizer='sgd',
- metrics=['accuracy'])
-
- # we must generate new callbacks for each test, as they aren't stateless
- def callbacks_factory(histogram_freq):
- return [keras.callbacks.TensorBoard(log_dir=filepath,
- histogram_freq=histogram_freq,
- write_images=True, write_grads=True,
- embeddings_freq=1,
- embeddings_layer_names=['dense_1'],
- batch_size=5)]
-
- # fit without validation data
- model.fit([x_train] * 2, [y_train] * 2, batch_size=BATCH_SIZE,
- callbacks=callbacks_factory(histogram_freq=0), epochs=3)
-
- # fit with validation data and accuracy
- model.fit([x_train] * 2, [y_train] * 2, batch_size=BATCH_SIZE,
- validation_data=([x_test] * 2, [y_test] * 2),
- callbacks=callbacks_factory(histogram_freq=1), epochs=2)
-
- # fit generator without validation data
- model.fit_generator(data_generator(True), len(x_train), epochs=2,
- callbacks=callbacks_factory(histogram_freq=0))
-
- # fit generator with validation data and accuracy
- model.fit_generator(data_generator(True), len(x_train), epochs=2,
- validation_data=([x_test] * 2, [y_test] * 2),
- callbacks=callbacks_factory(histogram_freq=1))
- assert os.path.isdir(filepath)
-
- def test_LambdaCallback(self):
- with self.test_session():
- np.random.seed(1337)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=TRAIN_SAMPLES,
- test_samples=TEST_SAMPLES,
- input_shape=(INPUT_DIM,),
- num_classes=NUM_CLASSES)
- y_test = keras.utils.to_categorical(y_test)
- y_train = keras.utils.to_categorical(y_train)
- model = keras.models.Sequential()
- model.add(
- keras.layers.Dense(
- NUM_HIDDEN, input_dim=INPUT_DIM, activation='relu'))
- model.add(keras.layers.Dense(NUM_CLASSES, activation='softmax'))
- model.compile(
- loss='categorical_crossentropy',
- optimizer='sgd',
- metrics=['accuracy'])
-
- # Start an arbitrary process that should run during model
- # training and be terminated after training has completed.
- def target():
- while True:
- pass
-
- p = multiprocessing.Process(target=target)
- p.start()
- cleanup_callback = keras.callbacks.LambdaCallback(
- on_train_end=lambda logs: p.terminate())
-
- cbks = [cleanup_callback]
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=5,
- verbose=0)
- p.join()
- assert not p.is_alive()
-
- def test_TensorBoard_with_ReduceLROnPlateau(self):
- with self.test_session():
- temp_dir = self.get_temp_dir()
- self.addCleanup(shutil.rmtree, temp_dir)
-
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=TRAIN_SAMPLES,
- test_samples=TEST_SAMPLES,
- input_shape=(INPUT_DIM,),
- num_classes=NUM_CLASSES)
- y_test = keras.utils.to_categorical(y_test)
- y_train = keras.utils.to_categorical(y_train)
-
- model = keras.models.Sequential()
- model.add(
- keras.layers.Dense(
- NUM_HIDDEN, input_dim=INPUT_DIM, activation='relu'))
- model.add(keras.layers.Dense(NUM_CLASSES, activation='softmax'))
- model.compile(
- loss='binary_crossentropy', optimizer='sgd', metrics=['accuracy'])
-
- cbks = [
- keras.callbacks.ReduceLROnPlateau(
- monitor='val_loss', factor=0.5, patience=4, verbose=1),
- keras.callbacks.TensorBoard(log_dir=temp_dir)
- ]
-
- model.fit(
- x_train,
- y_train,
- batch_size=BATCH_SIZE,
- validation_data=(x_test, y_test),
- callbacks=cbks,
- epochs=2,
- verbose=0)
-
- assert os.path.exists(temp_dir)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/constraints.py b/tensorflow/contrib/keras/python/keras/constraints.py
deleted file mode 100644
index 0a59dd92c1..0000000000
--- a/tensorflow/contrib/keras/python/keras/constraints.py
+++ /dev/null
@@ -1,199 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Constraints: functions that impose constraints on weights values.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import six
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import deserialize_keras_object
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import serialize_keras_object
-
-
-class Constraint(object):
-
- def __call__(self, w):
- return w
-
- def get_config(self):
- return {}
-
-
-class MaxNorm(Constraint):
- """MaxNorm weight constraint.
-
- Constrains the weights incident to each hidden unit
- to have a norm less than or equal to a desired value.
-
- Arguments:
- m: the maximum norm for the incoming weights.
- axis: integer, axis along which to calculate weight norms.
- For instance, in a `Dense` layer the weight matrix
- has shape `(input_dim, output_dim)`,
- set `axis` to `0` to constrain each weight vector
- of length `(input_dim,)`.
- In a `Conv2D` layer with `data_format="channels_last"`,
- the weight tensor has shape
- `(rows, cols, input_depth, output_depth)`,
- set `axis` to `[0, 1, 2]`
- to constrain the weights of each filter tensor of size
- `(rows, cols, input_depth)`.
-
- References:
- - [Dropout: A Simple Way to Prevent Neural Networks from Overfitting
- Srivastava, Hinton, et al.
- 2014](http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf)
- """
-
- def __init__(self, max_value=2, axis=0):
- self.max_value = max_value
- self.axis = axis
-
- def __call__(self, w):
- norms = K.sqrt(K.sum(K.square(w), axis=self.axis, keepdims=True))
- desired = K.clip(norms, 0, self.max_value)
- w *= (desired / (K.epsilon() + norms))
- return w
-
- def get_config(self):
- return {'max_value': self.max_value, 'axis': self.axis}
-
-
-class NonNeg(Constraint):
- """Constrains the weights to be non-negative.
- """
-
- def __call__(self, w):
- w *= K.cast(w >= 0., K.floatx())
- return w
-
-
-class UnitNorm(Constraint):
- """Constrains the weights incident to each hidden unit to have unit norm.
-
- Arguments:
- axis: integer, axis along which to calculate weight norms.
- For instance, in a `Dense` layer the weight matrix
- has shape `(input_dim, output_dim)`,
- set `axis` to `0` to constrain each weight vector
- of length `(input_dim,)`.
- In a `Conv2D` layer with `data_format="channels_last"`,
- the weight tensor has shape
- `(rows, cols, input_depth, output_depth)`,
- set `axis` to `[0, 1, 2]`
- to constrain the weights of each filter tensor of size
- `(rows, cols, input_depth)`.
- """
-
- def __init__(self, axis=0):
- self.axis = axis
-
- def __call__(self, w):
- return w / (
- K.epsilon() + K.sqrt(K.sum(K.square(w), axis=self.axis, keepdims=True)))
-
- def get_config(self):
- return {'axis': self.axis}
-
-
-class MinMaxNorm(Constraint):
- """MinMaxNorm weight constraint.
-
- Constrains the weights incident to each hidden unit
- to have the norm between a lower bound and an upper bound.
-
- Arguments:
- min_value: the minimum norm for the incoming weights.
- max_value: the maximum norm for the incoming weights.
- rate: rate for enforcing the constraint: weights will be
- rescaled to yield
- `(1 - rate) * norm + rate * norm.clip(min_value, max_value)`.
- Effectively, this means that rate=1.0 stands for strict
- enforcement of the constraint, while rate<1.0 means that
- weights will be rescaled at each step to slowly move
- towards a value inside the desired interval.
- axis: integer, axis along which to calculate weight norms.
- For instance, in a `Dense` layer the weight matrix
- has shape `(input_dim, output_dim)`,
- set `axis` to `0` to constrain each weight vector
- of length `(input_dim,)`.
- In a `Conv2D` layer with `dim_ordering="channels_last"`,
- the weight tensor has shape
- `(rows, cols, input_depth, output_depth)`,
- set `axis` to `[0, 1, 2]`
- to constrain the weights of each filter tensor of size
- `(rows, cols, input_depth)`.
- """
-
- def __init__(self, min_value=0.0, max_value=1.0, rate=1.0, axis=0):
- self.min_value = min_value
- self.max_value = max_value
- self.rate = rate
- self.axis = axis
-
- def __call__(self, w):
- norms = K.sqrt(K.sum(K.square(w), axis=self.axis, keepdims=True))
- desired = (self.rate * K.clip(norms, self.min_value, self.max_value) +
- (1 - self.rate) * norms)
- w *= (desired / (K.epsilon() + norms))
- return w
-
- def get_config(self):
- return {
- 'min_value': self.min_value,
- 'max_value': self.max_value,
- 'rate': self.rate,
- 'axis': self.axis
- }
-
-
-# Aliases.
-
-# pylint: disable=invalid-name
-max_norm = MaxNorm
-non_neg = NonNeg
-unit_norm = UnitNorm
-min_max_norm = MinMaxNorm
-
-# pylint: enable=invalid-name
-
-
-def serialize(constraint):
- return serialize_keras_object(constraint)
-
-
-def deserialize(config, custom_objects=None):
- return deserialize_keras_object(
- config,
- module_objects=globals(),
- custom_objects=custom_objects,
- printable_module_name='constraint')
-
-
-def get(identifier):
- if identifier is None:
- return None
- if isinstance(identifier, dict):
- return deserialize(identifier)
- elif isinstance(identifier, six.string_types):
- config = {'class_name': str(identifier), 'config': {}}
- return deserialize(config)
- elif callable(identifier):
- return identifier
- else:
- raise ValueError('Could not interpret constraint identifier:', identifier)
diff --git a/tensorflow/contrib/keras/python/keras/constraints_test.py b/tensorflow/contrib/keras/python/keras/constraints_test.py
deleted file mode 100644
index 36fbee7fd5..0000000000
--- a/tensorflow/contrib/keras/python/keras/constraints_test.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for Keras weights constraints."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-def get_test_values():
- return [0.1, 0.5, 3, 8, 1e-7]
-
-
-def get_example_array():
- np.random.seed(3537)
- example_array = np.random.random((100, 100)) * 100. - 50.
- example_array[0, 0] = 0. # 0 could possibly cause trouble
- return example_array
-
-
-class KerasConstraintsTest(test.TestCase):
-
- def test_serialization(self):
- all_activations = ['max_norm', 'non_neg',
- 'unit_norm', 'min_max_norm']
- for name in all_activations:
- fn = keras.constraints.get(name)
- ref_fn = getattr(keras.constraints, name)()
- assert fn.__class__ == ref_fn.__class__
- config = keras.constraints.serialize(fn)
- fn = keras.constraints.deserialize(config)
- assert fn.__class__ == ref_fn.__class__
-
- def test_max_norm(self):
- with self.test_session():
- array = get_example_array()
- for m in get_test_values():
- norm_instance = keras.constraints.max_norm(m)
- normed = norm_instance(keras.backend.variable(array))
- assert np.all(keras.backend.eval(normed) < m)
-
- # a more explicit example
- norm_instance = keras.constraints.max_norm(2.0)
- x = np.array([[0, 0, 0], [1.0, 0, 0], [3, 0, 0], [3, 3, 3]]).T
- x_normed_target = np.array([[0, 0, 0], [1.0, 0, 0],
- [2.0, 0, 0],
- [2. / np.sqrt(3),
- 2. / np.sqrt(3),
- 2. / np.sqrt(3)]]).T
- x_normed_actual = keras.backend.eval(
- norm_instance(keras.backend.variable(x)))
- self.assertAllClose(x_normed_actual, x_normed_target, rtol=1e-05)
-
- def test_non_neg(self):
- with self.test_session():
- non_neg_instance = keras.constraints.non_neg()
- normed = non_neg_instance(keras.backend.variable(get_example_array()))
- assert np.all(np.min(keras.backend.eval(normed), axis=1) == 0.)
-
- def test_unit_norm(self):
- with self.test_session():
- unit_norm_instance = keras.constraints.unit_norm()
- normalized = unit_norm_instance(
- keras.backend.variable(get_example_array()))
- norm_of_normalized = np.sqrt(
- np.sum(keras.backend.eval(normalized) ** 2, axis=0))
- # In the unit norm constraint, it should be equal to 1.
- difference = norm_of_normalized - 1.
- largest_difference = np.max(np.abs(difference))
- assert np.abs(largest_difference) < 10e-5
-
- def test_min_max_norm(self):
- with self.test_session():
- array = get_example_array()
- for m in get_test_values():
- norm_instance = keras.constraints.min_max_norm(min_value=m,
- max_value=m * 2)
- normed = norm_instance(keras.backend.variable(array))
- value = keras.backend.eval(normed)
- l2 = np.sqrt(np.sum(np.square(value), axis=0))
- assert not l2[l2 < m]
- assert not l2[l2 > m * 2 + 1e-5]
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/datasets/__init__.py b/tensorflow/contrib/keras/python/keras/datasets/__init__.py
deleted file mode 100644
index fe8dee54db..0000000000
--- a/tensorflow/contrib/keras/python/keras/datasets/__init__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Keras datasets: utilities for downloading and pre-processing common datasets.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras.datasets import boston_housing
-from tensorflow.contrib.keras.python.keras.datasets import cifar10
-from tensorflow.contrib.keras.python.keras.datasets import cifar100
-from tensorflow.contrib.keras.python.keras.datasets import imdb
-from tensorflow.contrib.keras.python.keras.datasets import mnist
-from tensorflow.contrib.keras.python.keras.datasets import reuters
-
diff --git a/tensorflow/contrib/keras/python/keras/datasets/boston_housing.py b/tensorflow/contrib/keras/python/keras/datasets/boston_housing.py
deleted file mode 100644
index 36b20451ff..0000000000
--- a/tensorflow/contrib/keras/python/keras/datasets/boston_housing.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Boston housing price regression dataset.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python.keras.utils.data_utils import get_file
-
-
-def load_data(path='boston_housing.npz', seed=113, test_split=0.2):
- """Loads the Boston Housing dataset.
-
- Arguments:
- path: path where to cache the dataset locally
- (relative to ~/.keras/datasets).
- seed: Random seed for shuffling the data
- before computing the test split.
- test_split: fraction of the data to reserve as test set.
-
- Returns:
- Tuple of Numpy arrays: `(x_train, y_train), (x_test, y_test)`.
- """
- assert 0 <= test_split < 1
- fh = 'f553886a1f8d56431e820c5b82552d9d95cfcb96d1e678153f8839538947dff5'
- path = get_file(
- path,
- origin='https://s3.amazonaws.com/keras-datasets/boston_housing.npz',
- file_hash=fh)
- f = np.load(path)
- x = f['x']
- y = f['y']
- f.close()
-
- np.random.seed(seed)
- np.random.shuffle(x)
- np.random.seed(seed)
- np.random.shuffle(y)
-
- x_train = np.array(x[:int(len(x) * (1 - test_split))])
- y_train = np.array(y[:int(len(x) * (1 - test_split))])
- x_test = np.array(x[int(len(x) * (1 - test_split)):])
- y_test = np.array(y[int(len(x) * (1 - test_split)):])
- return (x_train, y_train), (x_test, y_test)
diff --git a/tensorflow/contrib/keras/python/keras/datasets/cifar.py b/tensorflow/contrib/keras/python/keras/datasets/cifar.py
deleted file mode 100644
index 564709c0ee..0000000000
--- a/tensorflow/contrib/keras/python/keras/datasets/cifar.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Utilities used by the CIFAR10 and CIFAR100 datasets.
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import sys
-
-from six.moves import cPickle
-
-
-def load_batch(fpath, label_key='labels'):
- """Internal utility for parsing CIFAR data.
-
- Arguments:
- fpath: path the file to parse.
- label_key: key for label data in the retrieve
- dictionary.
-
- Returns:
- A tuple `(data, labels)`.
- """
- f = open(fpath, 'rb')
- if sys.version_info < (3,):
- d = cPickle.load(f)
- else:
- d = cPickle.load(f, encoding='bytes')
- # decode utf8
- d_decoded = {}
- for k, v in d.items():
- d_decoded[k.decode('utf8')] = v
- d = d_decoded
- f.close()
- data = d['data']
- labels = d[label_key]
-
- data = data.reshape(data.shape[0], 3, 32, 32)
- return data, labels
diff --git a/tensorflow/contrib/keras/python/keras/datasets/cifar10.py b/tensorflow/contrib/keras/python/keras/datasets/cifar10.py
deleted file mode 100644
index 11618b8552..0000000000
--- a/tensorflow/contrib/keras/python/keras/datasets/cifar10.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""CIFAR10 small image classification dataset.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import os
-
-import numpy as np
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.datasets.cifar import load_batch
-from tensorflow.contrib.keras.python.keras.utils.data_utils import get_file
-
-
-def load_data():
- """Loads CIFAR10 dataset.
-
- Returns:
- Tuple of Numpy arrays: `(x_train, y_train), (x_test, y_test)`.
- """
- dirname = 'cifar-10-batches-py'
- origin = 'http://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz'
- path = get_file(dirname, origin=origin, untar=True)
-
- num_train_samples = 50000
-
- x_train = np.zeros((num_train_samples, 3, 32, 32), dtype='uint8')
- y_train = np.zeros((num_train_samples,), dtype='uint8')
-
- for i in range(1, 6):
- fpath = os.path.join(path, 'data_batch_' + str(i))
- data, labels = load_batch(fpath)
- x_train[(i - 1) * 10000:i * 10000, :, :, :] = data
- y_train[(i - 1) * 10000:i * 10000] = labels
-
- fpath = os.path.join(path, 'test_batch')
- x_test, y_test = load_batch(fpath)
-
- y_train = np.reshape(y_train, (len(y_train), 1))
- y_test = np.reshape(y_test, (len(y_test), 1))
-
- if K.image_data_format() == 'channels_last':
- x_train = x_train.transpose(0, 2, 3, 1)
- x_test = x_test.transpose(0, 2, 3, 1)
-
- return (x_train, y_train), (x_test, y_test)
diff --git a/tensorflow/contrib/keras/python/keras/datasets/cifar100.py b/tensorflow/contrib/keras/python/keras/datasets/cifar100.py
deleted file mode 100644
index eba3ee6415..0000000000
--- a/tensorflow/contrib/keras/python/keras/datasets/cifar100.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""CIFAR100 small image classification dataset.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import os
-
-import numpy as np
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.datasets.cifar import load_batch
-from tensorflow.contrib.keras.python.keras.utils.data_utils import get_file
-
-
-def load_data(label_mode='fine'):
- """Loads CIFAR100 dataset.
-
- Arguments:
- label_mode: one of "fine", "coarse".
-
- Returns:
- Tuple of Numpy arrays: `(x_train, y_train), (x_test, y_test)`.
-
- Raises:
- ValueError: in case of invalid `label_mode`.
- """
- if label_mode not in ['fine', 'coarse']:
- raise ValueError('label_mode must be one of "fine" "coarse".')
-
- dirname = 'cifar-100-python'
- origin = 'http://www.cs.toronto.edu/~kriz/cifar-100-python.tar.gz'
- path = get_file(dirname, origin=origin, untar=True)
-
- fpath = os.path.join(path, 'train')
- x_train, y_train = load_batch(fpath, label_key=label_mode + '_labels')
-
- fpath = os.path.join(path, 'test')
- x_test, y_test = load_batch(fpath, label_key=label_mode + '_labels')
-
- y_train = np.reshape(y_train, (len(y_train), 1))
- y_test = np.reshape(y_test, (len(y_test), 1))
-
- if K.image_data_format() == 'channels_last':
- x_train = x_train.transpose(0, 2, 3, 1)
- x_test = x_test.transpose(0, 2, 3, 1)
-
- return (x_train, y_train), (x_test, y_test)
diff --git a/tensorflow/contrib/keras/python/keras/datasets/imdb.py b/tensorflow/contrib/keras/python/keras/datasets/imdb.py
deleted file mode 100644
index 04ab154f9f..0000000000
--- a/tensorflow/contrib/keras/python/keras/datasets/imdb.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""IMDB movie review sentiment classification dataset.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import json
-
-import numpy as np
-from six.moves import zip # pylint: disable=redefined-builtin
-
-from tensorflow.contrib.keras.python.keras.utils.data_utils import get_file
-
-
-def load_data(path='imdb.npz',
- num_words=None,
- skip_top=0,
- maxlen=None,
- seed=113,
- start_char=1,
- oov_char=2,
- index_from=3):
- """Loads the IMDB dataset.
-
- Arguments:
- path: where to cache the data (relative to `~/.keras/dataset`).
- num_words: max number of words to include. Words are ranked
- by how often they occur (in the training set) and only
- the most frequent words are kept
- skip_top: skip the top N most frequently occurring words
- (which may not be informative).
- maxlen: truncate sequences after this length.
- seed: random seed for sample shuffling.
- start_char: The start of a sequence will be marked with this character.
- Set to 1 because 0 is usually the padding character.
- oov_char: words that were cut out because of the `num_words`
- or `skip_top` limit will be replaced with this character.
- index_from: index actual words with this index and higher.
-
- Returns:
- Tuple of Numpy arrays: `(x_train, y_train), (x_test, y_test)`.
-
- Raises:
- ValueError: in case `maxlen` is so low
- that no input sequence could be kept.
-
- Note that the 'out of vocabulary' character is only used for
- words that were present in the training set but are not included
- because they're not making the `num_words` cut here.
- Words that were not seen in the training set but are in the test set
- have simply been skipped.
- """
- path = get_file(
- path, origin='https://s3.amazonaws.com/text-datasets/imdb.npz')
- f = np.load(path)
- x_train = f['x_train']
- labels_train = f['y_train']
- x_test = f['x_test']
- labels_test = f['y_test']
- f.close()
-
- np.random.seed(seed)
- np.random.shuffle(x_train)
- np.random.seed(seed)
- np.random.shuffle(labels_train)
-
- np.random.seed(seed * 2)
- np.random.shuffle(x_test)
- np.random.seed(seed * 2)
- np.random.shuffle(labels_test)
-
- xs = np.concatenate([x_train, x_test])
- labels = np.concatenate([labels_train, labels_test])
-
- if start_char is not None:
- xs = [[start_char] + [w + index_from for w in x] for x in xs]
- elif index_from:
- xs = [[w + index_from for w in x] for x in xs]
-
- if maxlen:
- new_xs = []
- new_labels = []
- for x, y in zip(xs, labels):
- if len(x) < maxlen:
- new_xs.append(x)
- new_labels.append(y)
- xs = new_xs
- labels = new_labels
- if not xs:
- raise ValueError('After filtering for sequences shorter than maxlen=' +
- str(maxlen) + ', no sequence was kept. '
- 'Increase maxlen.')
- if not num_words:
- num_words = max([max(x) for x in xs])
-
- # by convention, use 2 as OOV word
- # reserve 'index_from' (=3 by default) characters:
- # 0 (padding), 1 (start), 2 (OOV)
- if oov_char is not None:
- xs = [[oov_char if (w >= num_words or w < skip_top) else w for w in x]
- for x in xs]
- else:
- new_xs = []
- for x in xs:
- nx = []
- for w in x:
- if skip_top <= w < num_words:
- nx.append(w)
- new_xs.append(nx)
- xs = new_xs
-
- x_train = np.array(xs[:len(x_train)])
- y_train = np.array(labels[:len(x_train)])
-
- x_test = np.array(xs[len(x_train):])
- y_test = np.array(labels[len(x_train):])
-
- return (x_train, y_train), (x_test, y_test)
-
-
-def get_word_index(path='imdb_word_index.json'):
- """Retrieves the dictionary mapping word indices back to words.
-
- Arguments:
- path: where to cache the data (relative to `~/.keras/dataset`).
-
- Returns:
- The word index dictionary.
- """
- path = get_file(
- path,
- origin='https://s3.amazonaws.com/text-datasets/imdb_word_index.json')
- f = open(path)
- data = json.load(f)
- f.close()
- return data
diff --git a/tensorflow/contrib/keras/python/keras/datasets/mnist.py b/tensorflow/contrib/keras/python/keras/datasets/mnist.py
deleted file mode 100644
index aaced003d0..0000000000
--- a/tensorflow/contrib/keras/python/keras/datasets/mnist.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""MNIST handwritten digits classification dataset.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python.keras.utils.data_utils import get_file
-
-
-def load_data(path='mnist.npz'):
- """Loads the MNIST dataset.
-
- Arguments:
- path: path where to cache the dataset locally
- (relative to ~/.keras/datasets).
-
- Returns:
- Tuple of Numpy arrays: `(x_train, y_train), (x_test, y_test)`.
- """
- path = get_file(
- path, origin='https://s3.amazonaws.com/img-datasets/mnist.npz')
- f = np.load(path)
- x_train = f['x_train']
- y_train = f['y_train']
- x_test = f['x_test']
- y_test = f['y_test']
- f.close()
- return (x_train, y_train), (x_test, y_test)
diff --git a/tensorflow/contrib/keras/python/keras/datasets/reuters.py b/tensorflow/contrib/keras/python/keras/datasets/reuters.py
deleted file mode 100644
index 2904eb5bf6..0000000000
--- a/tensorflow/contrib/keras/python/keras/datasets/reuters.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Reuters newswire topic classification dataset.
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import json
-
-import numpy as np
-from six.moves import zip # pylint: disable=redefined-builtin
-
-from tensorflow.contrib.keras.python.keras.utils.data_utils import get_file
-
-
-def load_data(path='reuters.npz',
- num_words=None,
- skip_top=0,
- maxlen=None,
- test_split=0.2,
- seed=113,
- start_char=1,
- oov_char=2,
- index_from=3):
- """Loads the Reuters newswire classification dataset.
-
- Arguments:
- path: where to cache the data (relative to `~/.keras/dataset`).
- num_words: max number of words to include. Words are ranked
- by how often they occur (in the training set) and only
- the most frequent words are kept
- skip_top: skip the top N most frequently occurring words
- (which may not be informative).
- maxlen: truncate sequences after this length.
- test_split: Fraction of the dataset to be used as test data.
- seed: random seed for sample shuffling.
- start_char: The start of a sequence will be marked with this character.
- Set to 1 because 0 is usually the padding character.
- oov_char: words that were cut out because of the `num_words`
- or `skip_top` limit will be replaced with this character.
- index_from: index actual words with this index and higher.
-
- Returns:
- Tuple of Numpy arrays: `(x_train, y_train), (x_test, y_test)`.
-
- Note that the 'out of vocabulary' character is only used for
- words that were present in the training set but are not included
- because they're not making the `num_words` cut here.
- Words that were not seen in the training set but are in the test set
- have simply been skipped.
- """
- path = get_file(
- path, origin='https://s3.amazonaws.com/text-datasets/reuters.npz')
- npzfile = np.load(path)
- xs = npzfile['x']
- labels = npzfile['y']
- npzfile.close()
-
- np.random.seed(seed)
- np.random.shuffle(xs)
- np.random.seed(seed)
- np.random.shuffle(labels)
-
- if start_char is not None:
- xs = [[start_char] + [w + index_from for w in x] for x in xs]
- elif index_from:
- xs = [[w + index_from for w in x] for x in xs]
-
- if maxlen:
- new_xs = []
- new_labels = []
- for x, y in zip(xs, labels):
- if len(x) < maxlen:
- new_xs.append(x)
- new_labels.append(y)
- xs = new_xs
- labels = new_labels
-
- if not num_words:
- num_words = max([max(x) for x in xs])
-
- # by convention, use 2 as OOV word
- # reserve 'index_from' (=3 by default) characters:
- # 0 (padding), 1 (start), 2 (OOV)
- if oov_char is not None:
- xs = [[oov_char if (w >= num_words or w < skip_top) else w for w in x]
- for x in xs]
- else:
- new_xs = []
- for x in xs:
- nx = []
- for w in x:
- if skip_top <= w < num_words:
- nx.append(w)
- new_xs.append(nx)
- xs = new_xs
-
- x_train = np.array(xs[:int(len(xs) * (1 - test_split))])
- y_train = np.array(labels[:int(len(xs) * (1 - test_split))])
-
- x_test = np.array(xs[int(len(xs) * (1 - test_split)):])
- y_test = np.array(labels[int(len(xs) * (1 - test_split)):])
-
- return (x_train, y_train), (x_test, y_test)
-
-
-def get_word_index(path='reuters_word_index.json'):
- """Retrieves the dictionary mapping word indices back to words.
-
- Arguments:
- path: where to cache the data (relative to `~/.keras/dataset`).
-
- Returns:
- The word index dictionary.
- """
- path = get_file(
- path,
- origin='https://s3.amazonaws.com/text-datasets/reuters_word_index.json')
- f = open(path)
- data = json.load(f)
- f.close()
- return data
diff --git a/tensorflow/contrib/keras/python/keras/engine/__init__.py b/tensorflow/contrib/keras/python/keras/engine/__init__.py
deleted file mode 100644
index 0a1dc3dd2d..0000000000
--- a/tensorflow/contrib/keras/python/keras/engine/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""The Keras Engine: graph topology and training loop functionality.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras.engine.topology import get_source_inputs
-from tensorflow.contrib.keras.python.keras.engine.topology import Input
-from tensorflow.contrib.keras.python.keras.engine.topology import InputLayer
-from tensorflow.contrib.keras.python.keras.engine.topology import InputSpec
-from tensorflow.contrib.keras.python.keras.engine.topology import Layer
-from tensorflow.contrib.keras.python.keras.engine.training import Model
-
-
-# Note: topology.Node is an internal class,
-# it isn't meant to be used by Keras users.
diff --git a/tensorflow/contrib/keras/python/keras/engine/topology.py b/tensorflow/contrib/keras/python/keras/engine/topology.py
deleted file mode 100644
index 6502ba0f72..0000000000
--- a/tensorflow/contrib/keras/python/keras/engine/topology.py
+++ /dev/null
@@ -1,1535 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-# pylint: disable=protected-access
-"""Base layer code and base model (Container) code.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import copy
-import json
-import os
-
-import numpy as np
-from six.moves import zip # pylint: disable=redefined-builtin
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.utils import conv_utils
-from tensorflow.contrib.keras.python.keras.utils.io_utils import ask_to_proceed_with_overwrite
-from tensorflow.contrib.keras.python.keras.utils.layer_utils import print_summary as print_layer_summary
-from tensorflow.python.framework import tensor_shape
-from tensorflow.python.layers import base as tf_base_layers
-from tensorflow.python.platform import tf_logging as logging
-
-
-# pylint: disable=g-import-not-at-top
-try:
- import h5py
-except ImportError:
- h5py = None
-
-try:
- import yaml
-except ImportError:
- yaml = None
-# pylint: enable=g-import-not-at-top
-
-# pylint: disable=invalid-name
-InputSpec = tf_base_layers.InputSpec
-Node = tf_base_layers.Node
-TFBaseLayer = tf_base_layers.Layer
-# pylint: enable=invalid-name
-
-
-class Layer(tf_base_layers.Layer):
- """Abstract base layer class.
-
- # Properties
- name: String, must be unique within a model.
- input_spec: List of InputSpec class instances
- each entry describes one required input:
- - ndim
- - dtype
- A layer with `n` input tensors must have
- an `input_spec` of length `n`.
- trainable: Boolean, whether the layer weights
- will be updated during training.
- uses_learning_phase: Whether any operation
- of the layer uses `K.in_training_phase()`
- or `K.in_test_phase()`.
- input_shape: Shape tuple. Provided for convenience,
- but note that there may be cases in which this
- attribute is ill-defined (e.g. a shared layer
- with multiple input shapes), in which case
- requesting `input_shape` will raise an Exception.
- Prefer using `layer.get_input_shape_for(input_shape)`,
- or `layer.get_input_shape_at(node_index)`.
- output_shape: Shape tuple. See above.
- inbound_nodes: List of nodes.
- outbound_nodes: List of nodes.
- input, output: Input/output tensor(s). Note that if the layer is used
- more than once (shared layer), this is ill-defined
- and will raise an exception. In such cases, use
- `layer.get_input_at(node_index)`.
- input_mask, output_mask: Same as above, for masks.
- trainable_weights: List of variables.
- non_trainable_weights: List of variables.
- weights: The concatenation of the lists trainable_weights and
- non_trainable_weights (in this order).
-
- # Methods
- call(x, mask=None): Where the layer's logic lives.
- __call__(x, mask=None): Wrapper around the layer logic (`call`).
- If x is a Keras tensor:
- - Connect current layer with last layer from tensor:
- `self._add_inbound_node(last_layer)`
- - Add layer to tensor history
- If layer is not built:
- - Build from inputs shape
- get_weights()
- set_weights(weights)
- get_config()
- count_params()
- _compute_output_shape(input_shape)
- compute_mask(x, mask)
- get_input_at(node_index)
- get_output_at(node_index)
- get_input_shape_at(node_index)
- get_output_shape_at(node_index)
- get_input_mask_at(node_index)
- get_output_mask_at(node_index)
-
- # Class Methods
- from_config(config)
-
- # Internal methods:
- build(input_shape)
- _add_inbound_node(layer, index=0)
- """
-
- def __init__(self, **kwargs):
- # These properties should be set by the user via keyword arguments.
- # note that 'dtype', 'input_shape' and 'batch_input_shape'
- # are only applicable to input layers: do not pass these keywords
- # to non-input layers.
- allowed_kwargs = {
- 'input_shape',
- 'batch_input_shape',
- 'batch_size',
- 'dtype',
- 'name',
- 'trainable',
- 'weights',
- }
- # Validate optional keyword arguments.
- for kwarg in kwargs:
- if kwarg not in allowed_kwargs:
- raise TypeError('Keyword argument not understood:', kwarg)
-
- # Get layer name.
- name = kwargs.get('name')
-
- # Get `trainable` status.
- trainable = kwargs.get('trainable', True)
-
- # Get `dtype`.
- dtype = kwargs.get('dtype')
- if dtype is None:
- dtype = K.floatx()
-
- # Call super, which will set all properties common to Keras layers
- # and core TF layers.
- super(Layer, self).__init__(name=name, dtype=dtype, trainable=trainable)
-
- # Add properties that are Keras-only for now.
- self.supports_masking = False
-
- # Manage input shape information if passed.
- if 'input_shape' in kwargs or 'batch_input_shape' in kwargs:
- # In this case we will later create an input layer
- # to insert before the current layer
- if 'batch_input_shape' in kwargs:
- batch_input_shape = tuple(kwargs['batch_input_shape'])
- elif 'input_shape' in kwargs:
- if 'batch_size' in kwargs:
- batch_size = kwargs['batch_size']
- else:
- batch_size = None
- batch_input_shape = (batch_size,) + tuple(kwargs['input_shape'])
- self.batch_input_shape = batch_input_shape
-
- # Manage initial weight values if passed.
- if 'weights' in kwargs:
- self._initial_weights = kwargs['weights']
- else:
- self._initial_weights = None
-
- def add_weight(self,
- name,
- shape,
- dtype=None,
- initializer=None,
- regularizer=None,
- trainable=True,
- constraint=None):
- """Adds a weight variable to the layer.
-
- Arguments:
- name: String, the name for the weight variable.
- shape: The shape tuple of the weight.
- dtype: The dtype of the weight.
- initializer: An Initializer instance (callable).
- regularizer: An optional Regularizer instance.
- trainable: A boolean, whether the weight should
- be trained via backprop or not (assuming
- that the layer itself is also trainable).
- constraint: An optional Constraint instance.
-
- Returns:
- The created weight variable.
- """
- if dtype is None:
- dtype = K.floatx()
- weight = self.add_variable(name, shape,
- dtype=dtype,
- initializer=initializer,
- regularizer=regularizer,
- constraint=constraint,
- trainable=trainable)
- return weight
-
- def call(self, inputs, **kwargs): # pylint: disable=unused-argument
- """This is where the layer's logic lives.
-
- Arguments:
- inputs: Input tensor, or list/tuple of input tensors.
- **kwargs: Additional keyword arguments.
-
- Returns:
- A tensor or list/tuple of tensors.
- """
- return inputs
-
- def __call__(self, inputs, **kwargs):
- """Wrapper around self.call(), for handling internal references.
-
- If a Keras tensor is passed:
- - We call self._add_inbound_node().
- - If necessary, we `build` the layer to match
- the shape of the input(s).
- - We update the _keras_history of the output tensor(s)
- with the current layer.
- This is done as part of _add_inbound_node().
-
- Arguments:
- inputs: Can be a tensor or list/tuple of tensors.
- **kwargs: Additional keyword arguments to be passed to `call()`.
-
- Returns:
- Output of the layer's `call` method.
-
- Raises:
- ValueError: in case the layer is missing shape information
- for its `build` call.
- """
- # Actually call the layer (optionally building it).
- output = super(Layer, self).__call__(inputs, **kwargs)
-
- # Update learning phase info.
- output_tensors = _to_list(output)
- uses_lp = any(
- [getattr(x, '_uses_learning_phase', False) for x in _to_list(inputs)])
- uses_lp = getattr(self, 'uses_learning_phase', False) or uses_lp
- for i in range(len(output_tensors)):
- output_tensors[i]._uses_learning_phase = getattr(
- output_tensors[i], '_uses_learning_phase', False) or uses_lp
-
- # Optionally load weight values that were specified at layer instantiation.
- if hasattr(self, '_initial_weights') and self._initial_weights is not None:
- self.set_weights(self._initial_weights)
- del self._initial_weights
- return output
-
- def _compute_output_shape(self, input_shape):
- """Computes the output shape of the layer.
-
- Assumes that the layer will be built
- to match that input shape provided.
-
- Arguments:
- input_shape: Shape tuple (tuple of integers)
- or list of shape tuples (one per output tensor of the layer).
- Shape tuples can include None for free dimensions,
- instead of an integer.
-
- Returns:
- An input shape tuple.
- """
- if isinstance(input_shape, list):
- return [tensor_shape.TensorShape(shape) for shape in input_shape]
- else:
- return tensor_shape.TensorShape(input_shape)
-
- def compute_mask(self, inputs, mask=None): # pylint: disable=unused-argument
- """Computes an output mask tensor.
-
- Arguments:
- inputs: Tensor or list of tensors.
- mask: Tensor or list of tensors.
-
- Returns:
- None or a tensor (or list of tensors,
- one per output tensor of the layer).
- """
- if not self.supports_masking:
- if mask is not None:
- if isinstance(mask, list):
- if any(m is not None for m in mask):
- raise TypeError('Layer ' + self.name + ' does not support masking, '
- 'but was passed an input_mask: ' + str(mask))
- else:
- raise TypeError('Layer ' + self.name + ' does not support masking, '
- 'but was passed an input_mask: ' + str(mask))
- # masking not explicitly supported: return None as mask
- return None
- # if masking is explicitly supported, by default
- # carry over the input mask
- return mask
-
- def get_input_mask_at(self, node_index):
- """Retrieves the input mask tensor(s) of a layer at a given node.
-
- Arguments:
- node_index: Integer, index of the node
- from which to retrieve the attribute.
- E.g. `node_index=0` will correspond to the
- first time the layer was called.
-
- Returns:
- A mask tensor
- (or list of tensors if the layer has multiple inputs).
- """
- inputs = self.get_input_at(node_index)
- if isinstance(inputs, list):
- return [getattr(x, '_keras_mask', None) for x in inputs]
- else:
- return getattr(inputs, '_keras_mask', None)
-
- def get_output_mask_at(self, node_index):
- """Retrieves the output mask tensor(s) of a layer at a given node.
-
- Arguments:
- node_index: Integer, index of the node
- from which to retrieve the attribute.
- E.g. `node_index=0` will correspond to the
- first time the layer was called.
-
- Returns:
- A mask tensor
- (or list of tensors if the layer has multiple outputs).
- """
- output = self.get_output_at(node_index)
- if isinstance(output, list):
- return [getattr(x, '_keras_mask', None) for x in output]
- else:
- return getattr(output, '_keras_mask', None)
-
- @property
- def input_mask(self):
- """Retrieves the input mask tensor(s) of a layer.
-
- Only applicable if the layer has exactly one inbound node,
- i.e. if it is connected to one incoming layer.
-
- Returns:
- Input mask tensor (potentially None) or list of input
- mask tensors.
-
- Raises:
- AttributeError: if the layer is connected to
- more than one incoming layers.
- """
- inputs = self.input
- if isinstance(inputs, list):
- return [getattr(x, '_keras_mask', None) for x in inputs]
- else:
- return getattr(inputs, '_keras_mask', None)
-
- @property
- def output_mask(self):
- """Retrieves the output mask tensor(s) of a layer.
-
- Only applicable if the layer has exactly one inbound node,
- i.e. if it is connected to one incoming layer.
-
- Returns:
- Output mask tensor (potentially None) or list of output
- mask tensors.
-
- Raises:
- AttributeError: if the layer is connected to
- more than one incoming layers.
- """
- output = self.output
- if isinstance(output, list):
- return [getattr(x, '_keras_mask', None) for x in output]
- else:
- return getattr(output, '_keras_mask', None)
-
- def set_weights(self, weights):
- """Sets the weights of the layer, from Numpy arrays.
-
- Arguments:
- weights: a list of Numpy arrays. The number
- of arrays and their shape must match
- number of the dimensions of the weights
- of the layer (i.e. it should match the
- output of `get_weights`).
-
- Raises:
- ValueError: If the provided weights list does not match the
- layer's specifications.
- """
- params = self.weights
- if len(params) != len(weights):
- raise ValueError('You called `set_weights(weights)` on layer "' +
- self.name + '" with a weight list of length ' +
- str(len(weights)) + ', but the layer was expecting ' +
- str(len(params)) + ' weights. Provided weights: ' +
- str(weights)[:50] + '...')
- if not params:
- return
- weight_value_tuples = []
- param_values = K.batch_get_value(params)
- for pv, p, w in zip(param_values, params, weights):
- if pv.shape != w.shape:
- raise ValueError('Layer weight shape ' + str(pv.shape) +
- ' not compatible with '
- 'provided weight shape ' + str(w.shape))
- weight_value_tuples.append((p, w))
- K.batch_set_value(weight_value_tuples)
-
- def get_weights(self):
- """Returns the current weights of the layer.
-
- Returns:
- Weights values as a list of numpy arrays.
- """
- params = self.weights
- return K.batch_get_value(params)
-
- def get_config(self):
- """Returns the config of the layer.
-
- A layer config is a Python dictionary (serializable)
- containing the configuration of a layer.
- The same layer can be reinstantiated later
- (without its trained weights) from this configuration.
-
- The config of a layer does not include connectivity
- information, nor the layer class name. These are handled
- by `Container` (one layer of abstraction above).
-
- Returns:
- Python dictionary.
- """
- config = {'name': self.name, 'trainable': self.trainable}
- if hasattr(self, 'batch_input_shape'):
- config['batch_input_shape'] = self.batch_input_shape
- if hasattr(self, 'dtype'):
- config['dtype'] = self.dtype
- return config
-
- @classmethod
- def from_config(cls, config):
- """Creates a layer from its config.
-
- This method is the reverse of `get_config`,
- capable of instantiating the same layer from the config
- dictionary. It does not handle layer connectivity
- (handled by Container), nor weights (handled by `set_weights`).
-
- Arguments:
- config: A Python dictionary, typically the
- output of get_config.
-
- Returns:
- A layer instance.
- """
- return cls(**config)
-
-
-class InputLayer(tf_base_layers.InputLayer, Layer):
- """Layer to be used as an entry point into a graph.
-
- It can either wrap an existing tensor (pass an `input_tensor` argument)
- or create its a placeholder tensor (pass argument `input_shape`.
-
- Arguments:
- input_shape: Shape tuple, not including the batch axis.
- batch_size: Optional input batch size (integer or None).
- dtype: Datatype of the input.
- input_tensor: Optional tensor to use as layer input
- instead of creating a placeholder.
- sparse: Boolean, whether the placeholder created
- is meant to be sparse.
- name: Name of the layer (string).
- """
-
- def __init__(self,
- input_shape=None,
- batch_size=None,
- dtype=None,
- input_tensor=None,
- sparse=False,
- name=None,
- **kwargs):
- if 'batch_input_shape' in kwargs:
- batch_input_shape = kwargs.pop('batch_input_shape')
- if input_shape and batch_input_shape:
- raise ValueError('Only provide the input_shape OR '
- 'batch_input_shape argument to '
- 'InputLayer, not both at the same time.')
- batch_size = batch_input_shape[0]
- input_shape = batch_input_shape[1:]
- if kwargs:
- raise ValueError('Unrecognized keyword arguments:', kwargs.keys())
-
- if not name:
- prefix = 'input'
- name = prefix + '_' + str(K.get_uid(prefix))
-
- if not dtype:
- if input_tensor is None:
- dtype = K.floatx()
- else:
- dtype = K.dtype(input_tensor)
- super(InputLayer, self).__init__(input_shape=input_shape,
- batch_size=batch_size,
- dtype=dtype,
- input_tensor=input_tensor,
- sparse=sparse,
- name=name)
-
- def get_config(self):
- config = {
- 'batch_input_shape': self.batch_input_shape,
- 'dtype': self.dtype,
- 'sparse': self.sparse,
- 'name': self.name
- }
- return config
-
-
-def Input( # pylint: disable=invalid-name
- shape=None,
- batch_size=None,
- name=None,
- dtype=None,
- sparse=False,
- tensor=None,
- **kwargs):
- """`Input()` is used to instantiate a Keras tensor.
-
- A Keras tensor is a tensor object from the underlying backend
- (Theano or TensorFlow), which we augment with certain
- attributes that allow us to build a Keras model
- just by knowing the inputs and outputs of the model.
-
- For instance, if a, b and c are Keras tensors,
- it becomes possible to do:
- `model = Model(input=[a, b], output=c)`
-
- The added Keras attribute is:
- `_keras_history`: Last layer applied to the tensor.
- the entire layer graph is retrievable from that layer,
- recursively.
-
- Arguments:
- shape: A shape tuple (integers), not including the batch size.
- For instance, `shape=(32,)` indicates that the expected input
- will be batches of 32-dimensional vectors.
- batch_size: optional static batch size (integer).
- name: An optional name string for the layer.
- Should be unique in a model (do not reuse the same name twice).
- It will be autogenerated if it isn't provided.
- dtype: The data type expected by the input, as a string
- (`float32`, `float64`, `int32`...)
- sparse: A boolean specifying whether the placeholder
- to be created is sparse.
- tensor: Optional existing tensor to wrap into the `Input` layer.
- If set, the layer will not create a placeholder tensor.
- **kwargs: deprecated arguments support.
-
- Returns:
- A tensor.
-
- Example:
-
- ```python
- # this is a logistic regression in Keras
- x = Input(shape=(32,))
- y = Dense(16, activation='softmax')(x)
- model = Model(x, y)
- ```
-
- Raises:
- ValueError: in case of invalid arguments.
- """
- if 'batch_shape' in kwargs:
- batch_shape = kwargs.pop('batch_shape')
- if shape and batch_shape:
- raise ValueError('Only provide the shape OR '
- 'batch_shape argument to '
- 'Input, not both at the same time.')
- batch_size = batch_shape[0]
- shape = batch_shape[1:]
- if kwargs:
- raise ValueError('Unrecognized keyword arguments:', kwargs.keys())
-
- if dtype is None:
- dtype = K.floatx()
- if not shape and tensor is None:
- raise ValueError('Please provide to Input either a `shape`'
- ' or a `tensor` argument. Note that '
- '`shape` does not include the batch '
- 'dimension.')
- input_layer = InputLayer(
- input_shape=shape,
- batch_size=batch_size,
- name=name,
- dtype=dtype,
- sparse=sparse,
- input_tensor=tensor)
- # Return tensor including `_keras_history`.
- # Note that in this case train_output and test_output are the same pointer.
- outputs = input_layer.inbound_nodes[0].output_tensors
- if len(outputs) == 1:
- return outputs[0]
- else:
- return outputs
-
-
-class Network(tf_base_layers.Network, Layer):
- """A Container is a directed acyclic graph of layers.
-
- It is the topological form of a "model". A Model
- is simply a Container with added training routines.
-
- # Properties
- name
- inputs
- outputs
- input_layers
- output_layers
- input_spec (list of class instances)
- each entry describes one required input:
- - ndim
- - dtype
- trainable (boolean)
- input_shape
- output_shape
- inbound_nodes: list of nodes
- outbound_nodes: list of nodes
- trainable_weights (list of variables)
- non_trainable_weights (list of variables)
-
- # Methods
- summary
- get_layer
- get_weights
- set_weights
- get_config
- compute_output_shape
-
- # Class Methods
- from_config
- """
-
- def __init__(self, inputs, outputs, name=None):
- super(Network, self).__init__(inputs, outputs, name=name)
-
- self.supports_masking = False
- # Fill in the output mask cache.
- masks = []
- for x in self.inputs:
- mask = x._keras_mask if hasattr(x, '_keras_mask') else None
- masks.append(mask)
- mask_cache_key = (tf_base_layers._object_list_uid(self.inputs) + '_' +
- tf_base_layers._object_list_uid(masks))
- masks = []
- for x in self.outputs:
- mask = x._keras_mask if hasattr(x, '_keras_mask') else None
- masks.append(mask)
- if len(masks) == 1:
- mask = masks[0]
- else:
- mask = masks
- self._output_mask_cache[mask_cache_key] = mask
-
- # Build self.input_names and self.output_names.
- self.input_names = []
- self.output_names = []
- self._feed_input_names = []
- self._feed_inputs = []
- self._feed_input_shapes = []
- for i, layer in enumerate(self._input_layers):
- self.input_names.append(layer.name)
- if layer.is_placeholder:
- self._feed_input_names.append(layer.name)
- self._feed_inputs.append(layer.input)
- self._feed_input_shapes.append(K.int_shape(self.inputs[i]))
- for layer in self._output_layers:
- self.output_names.append(layer.name)
-
- self.internal_input_shapes = [K.int_shape(x) for x in self.inputs]
- self.internal_output_shapes = [K.int_shape(x) for x in self.outputs]
-
- @property
- def uses_learning_phase(self):
- return any(
- [getattr(x, '_uses_learning_phase', False) for x in self.outputs])
-
- @property
- def stateful(self):
- return any([(hasattr(layer, 'stateful') and layer.stateful)
- for layer in self.layers])
-
- def reset_states(self):
- for layer in self.layers:
- if hasattr(layer, 'reset_states') and getattr(layer, 'stateful', False):
- layer.reset_states()
-
- @property
- def state_updates(self):
- """Returns the `updates` from all layers that are stateful.
-
- This is useful for separating training updates and
- state updates, e.g. when we need to update a layer's internal state
- during prediction.
-
- Returns:
- A list of update ops.
- """
- state_updates = []
- for layer in self.layers:
- if getattr(layer, 'stateful', False):
- if hasattr(layer, 'updates'):
- state_updates += layer.updates
- return state_updates
-
- def get_weights(self):
- """Retrieves the weights of the model.
-
- Returns:
- A flat list of Numpy arrays.
- """
- weights = []
- for layer in self.layers:
- weights += layer.weights
- return K.batch_get_value(weights)
-
- def set_weights(self, weights):
- """Sets the weights of the model.
-
- Arguments:
- weights: A list of Numpy arrays with shapes and types matching
- the output of `model.get_weights()`.
- """
- tuples = []
- for layer in self.layers:
- num_param = len(layer.weights)
- layer_weights = weights[:num_param]
- for sw, w in zip(layer.weights, layer_weights):
- tuples.append((sw, w))
- weights = weights[num_param:]
- K.batch_set_value(tuples)
-
- def compute_mask(self, inputs, mask):
- inputs = _to_list(inputs)
- if mask is None:
- masks = [None for _ in range(len(inputs))]
- else:
- masks = _to_list(mask)
- cache_key = ','.join([str(id(x)) for x in inputs])
- cache_key += '_' + ','.join([str(id(x)) for x in masks])
- if cache_key in self._output_mask_cache:
- return self._output_mask_cache[cache_key]
- else:
- _, output_masks, _ = self._run_internal_graph(inputs, masks)
- return output_masks
-
- def get_config(self):
- config = {
- 'name': self.name,
- }
- node_conversion_map = {}
- for layer in self.layers:
- if issubclass(layer.__class__, Network):
- # Containers start with a pre-existing node
- # linking their input to output.
- kept_nodes = 1
- else:
- kept_nodes = 0
- for original_node_index, node in enumerate(layer.inbound_nodes):
- node_key = tf_base_layers._make_node_key(layer.name,
- original_node_index)
- if node_key in self._network_nodes:
- node_conversion_map[node_key] = kept_nodes
- kept_nodes += 1
- layer_configs = []
- for layer in self.layers: # From the earliest layers on.
- layer_class_name = layer.__class__.__name__
- layer_config = layer.get_config()
- filtered_inbound_nodes = []
- for original_node_index, node in enumerate(layer.inbound_nodes):
- node_key = tf_base_layers._make_node_key(layer.name,
- original_node_index)
- if node_key in self._network_nodes:
- # The node is relevant to the model:
- # add to filtered_inbound_nodes.
- if node.arguments:
- try:
- json.dumps(node.arguments)
- kwargs = node.arguments
- except TypeError:
- logging.warning(
- 'Layer ' + layer.name +
- ' was passed non-serializable keyword arguments: ' +
- str(node.arguments) + '. They will not be included '
- 'in the serialized model (and thus will be missing '
- 'at deserialization time).')
- kwargs = {}
- else:
- kwargs = {}
- if node.inbound_layers:
- node_data = []
- for i in range(len(node.inbound_layers)):
- inbound_layer = node.inbound_layers[i]
- node_index = node.node_indices[i]
- tensor_index = node.tensor_indices[i]
- node_key = tf_base_layers._make_node_key(inbound_layer.name,
- node_index)
- new_node_index = node_conversion_map.get(node_key, 0)
- node_data.append(
- [inbound_layer.name, new_node_index, tensor_index, kwargs])
- filtered_inbound_nodes.append(node_data)
- layer_configs.append({
- 'name': layer.name,
- 'class_name': layer_class_name,
- 'config': layer_config,
- 'inbound_nodes': filtered_inbound_nodes,
- })
- config['layers'] = layer_configs
-
- # Gather info about inputs and outputs.
- model_inputs = []
- for i in range(len(self._input_layers)):
- layer, node_index, tensor_index = self._input_coordinates[i]
- node_key = tf_base_layers._make_node_key(layer.name,
- node_index)
- if node_key not in self._network_nodes:
- continue
- new_node_index = node_conversion_map[node_key]
- model_inputs.append([layer.name, new_node_index, tensor_index])
- config['input_layers'] = model_inputs
- model_outputs = []
- for i in range(len(self._output_layers)):
- layer, node_index, tensor_index = self._output_coordinates[i]
- node_key = tf_base_layers._make_node_key(layer.name,
- node_index)
- if node_key not in self._network_nodes:
- continue
- new_node_index = node_conversion_map[node_key]
- model_outputs.append([layer.name, new_node_index, tensor_index])
- config['output_layers'] = model_outputs
- return copy.deepcopy(config)
-
- @classmethod
- def from_config(cls, config, custom_objects=None):
- """Instantiates a Model from its config (output of `get_config()`).
-
- Arguments:
- config: Model config dictionary.
- custom_objects: Optional dictionary mapping names
- (strings) to custom classes or functions to be
- considered during deserialization.
-
- Returns:
- A model instance.
-
- Raises:
- ValueError: In case of improperly formatted config dict.
- """
- # Layer instances created during
- # the graph reconstruction process
- created_layers = {}
-
- # Dictionary mapping layer instances to
- # node data that specifies a layer call.
- # It acts as a queue that maintains any unprocessed
- # layer call until it becomes possible to process it
- # (i.e. until the input tensors to the call all exist).
- unprocessed_nodes = {}
-
- def add_unprocessed_node(layer, node_data):
- if layer not in unprocessed_nodes:
- unprocessed_nodes[layer] = [node_data]
- else:
- unprocessed_nodes[layer].append(node_data)
-
- def process_node(layer, node_data):
- """Deserialize a node.
-
- Arguments:
- layer: layer instance.
- node_data: node config dict.
-
- Raises:
- ValueError: In case of improperly formatted `node_data` dict.
- """
- input_tensors = []
- for input_data in node_data:
- inbound_layer_name = input_data[0]
- inbound_node_index = input_data[1]
- inbound_tensor_index = input_data[2]
- if len(input_data) == 3:
- kwargs = {}
- elif len(input_data) == 4:
- kwargs = input_data[3]
- else:
- raise ValueError('Improperly formatted model config.')
- if inbound_layer_name not in created_layers:
- add_unprocessed_node(layer, node_data)
- return
- inbound_layer = created_layers[inbound_layer_name]
- if len(inbound_layer.inbound_nodes) <= inbound_node_index:
- add_unprocessed_node(layer, node_data)
- return
- inbound_node = inbound_layer.inbound_nodes[inbound_node_index]
- input_tensors.append(inbound_node.output_tensors[inbound_tensor_index])
- # Call layer on its inputs, thus creating the node
- # and building the layer if needed.
- if input_tensors:
- if len(input_tensors) == 1:
- layer(input_tensors[0], **kwargs)
- else:
- layer(input_tensors, **kwargs)
-
- def process_layer(layer_data):
- """Deserialize a layer, then call it on appropriate inputs.
-
- Arguments:
- layer_data: layer config dict.
-
- Raises:
- ValueError: In case of improperly formatted `layer_data` dict.
- """
- layer_name = layer_data['name']
-
- # Instantiate layer.
- from tensorflow.contrib.keras.python.keras.layers import deserialize as deserialize_layer # pylint: disable=g-import-not-at-top
-
- layer = deserialize_layer(layer_data, custom_objects=custom_objects)
- created_layers[layer_name] = layer
-
- # Gather layer inputs.
- inbound_nodes_data = layer_data['inbound_nodes']
- for node_data in inbound_nodes_data:
- # We don't process nodes (i.e. make layer calls)
- # on the fly because the inbound node may not yet exist,
- # in case of layer shared at different topological depths
- # (e.g. a model such as A(B(A(B(x)))))
- add_unprocessed_node(layer, node_data)
-
- # First, we create all layers and enqueue nodes to be processed
- for layer_data in config['layers']:
- process_layer(layer_data)
- # Then we process nodes in order of layer depth.
- # Nodes that cannot yet be processed (if the inbound node
- # does not yet exist) are re-enqueued, and the process
- # is repeated until all nodes are processed.
- while unprocessed_nodes:
- for layer_data in config['layers']:
- layer = created_layers[layer_data['name']]
- if layer in unprocessed_nodes:
- for node_data in unprocessed_nodes.pop(layer):
- process_node(layer, node_data)
-
- name = config.get('name')
- input_tensors = []
- output_tensors = []
- for layer_data in config['input_layers']:
- layer_name, node_index, tensor_index = layer_data
- assert layer_name in created_layers
- layer = created_layers[layer_name]
- layer_output_tensors = layer.inbound_nodes[node_index].output_tensors
- input_tensors.append(layer_output_tensors[tensor_index])
- for layer_data in config['output_layers']:
- layer_name, node_index, tensor_index = layer_data
- assert layer_name in created_layers
- layer = created_layers[layer_name]
- layer_output_tensors = layer.inbound_nodes[node_index].output_tensors
- output_tensors.append(layer_output_tensors[tensor_index])
- return cls(inputs=input_tensors, outputs=output_tensors, name=name)
-
- def save(self, filepath, overwrite=True, include_optimizer=True):
- """Save the model to a single HDF5 file.
-
- The savefile includes:
- - The model architecture, allowing to re-instantiate the model.
- - The model weights.
- - The state of the optimizer, allowing to resume training
- exactly where you left off.
-
- This allows you to save the entirety of the state of a model
- in a single file.
-
- Saved models can be reinstantiated via `keras.models.load_model`.
- The model returned by `load_model`
- is a compiled model ready to be used (unless the saved model
- was never compiled in the first place).
-
- Arguments:
- filepath: String, path to the file to save the weights to.
- overwrite: Whether to silently overwrite any existing file at the
- target location, or provide the user with a manual prompt.
- include_optimizer: If True, save optimizer's state together.
-
- Example:
-
- ```python
- from keras.models import load_model
-
- model.save('my_model.h5') # creates a HDF5 file 'my_model.h5'
- del model # deletes the existing model
-
- # returns a compiled model
- # identical to the previous one
- model = load_model('my_model.h5')
- ```
- """
- from tensorflow.contrib.keras.python.keras.models import save_model # pylint: disable=g-import-not-at-top
- save_model(self, filepath, overwrite, include_optimizer)
-
- def save_weights(self, filepath, overwrite=True):
- """Dumps all layer weights to a HDF5 file.
-
- The weight file has:
- - `layer_names` (attribute), a list of strings
- (ordered names of model layers).
- - For every layer, a `group` named `layer.name`
- - For every such layer group, a group attribute `weight_names`,
- a list of strings
- (ordered names of weights tensor of the layer).
- - For every weight in the layer, a dataset
- storing the weight value, named after the weight tensor.
-
- Arguments:
- filepath: String, path to the file to save the weights to.
- overwrite: Whether to silently overwrite any existing file at the
- target location, or provide the user with a manual prompt.
-
- Raises:
- ImportError: If h5py is not available.
- """
- if h5py is None:
- raise ImportError('`save_weights` requires h5py.')
- # If file exists and should not be overwritten:
- if not overwrite and os.path.isfile(filepath):
- proceed = ask_to_proceed_with_overwrite(filepath)
- if not proceed:
- return
- f = h5py.File(filepath, 'w')
- save_weights_to_hdf5_group(f, self.layers)
- f.flush()
- f.close()
-
- def load_weights(self, filepath, by_name=False):
- """Loads all layer weights from a HDF5 save file.
-
- If `by_name` is False (default) weights are loaded
- based on the network's topology, meaning the architecture
- should be the same as when the weights were saved.
- Note that layers that don't have weights are not taken
- into account in the topological ordering, so adding or
- removing layers is fine as long as they don't have weights.
-
- If `by_name` is True, weights are loaded into layers
- only if they share the same name. This is useful
- for fine-tuning or transfer-learning models where
- some of the layers have changed.
-
- Arguments:
- filepath: String, path to the weights file to load.
- by_name: Boolean, whether to load weights by name
- or by topological order.
-
- Raises:
- ImportError: If h5py is not available.
- """
- if h5py is None:
- raise ImportError('`load_weights` requires h5py.')
- f = h5py.File(filepath, mode='r')
- if 'layer_names' not in f.attrs and 'model_weights' in f:
- f = f['model_weights']
- if by_name:
- load_weights_from_hdf5_group_by_name(f, self.layers)
- else:
- load_weights_from_hdf5_group(f, self.layers)
-
- if hasattr(f, 'close'):
- f.close()
-
- def _updated_config(self):
- """Util hared between different serialization methods.
-
- Returns:
- Model config with Keras version information added.
- """
- from tensorflow.contrib.keras.python.keras import __version__ as keras_version # pylint: disable=g-import-not-at-top
-
- config = self.get_config()
- model_config = {
- 'class_name': self.__class__.__name__,
- 'config': config,
- 'keras_version': keras_version,
- 'backend': K.backend()
- }
- return model_config
-
- def to_json(self, **kwargs):
- """Returns a JSON string containing the network configuration.
-
- To load a network from a JSON save file, use
- `keras.models.model_from_json(json_string, custom_objects={})`.
-
- Arguments:
- **kwargs: Additional keyword arguments
- to be passed to `json.dumps()`.
-
- Returns:
- A JSON string.
- """
-
- def get_json_type(obj):
- # If obj is any numpy type
- if type(obj).__module__ == np.__name__:
- return obj.item()
-
- # If obj is a python 'type'
- if type(obj).__name__ == type.__name__:
- return obj.__name__
-
- raise TypeError('Not JSON Serializable:', obj)
-
- model_config = self._updated_config()
- return json.dumps(model_config, default=get_json_type, **kwargs)
-
- def to_yaml(self, **kwargs):
- """Returns a yaml string containing the network configuration.
-
- To load a network from a yaml save file, use
- `keras.models.model_from_yaml(yaml_string, custom_objects={})`.
-
- `custom_objects` should be a dictionary mapping
- the names of custom losses / layers / etc to the corresponding
- functions / classes.
-
- Arguments:
- **kwargs: Additional keyword arguments
- to be passed to `yaml.dump()`.
-
- Returns:
- A YAML string.
-
- Raises:
- ImportError: if yaml module is not found.
- """
- if yaml is None:
- raise ImportError('Requires yaml module installed.')
- return yaml.dump(self._updated_config(), **kwargs)
-
- def summary(self, line_length=None, positions=None, print_fn=None):
- """Prints a string summary of the network.
-
- Arguments:
- line_length: Total length of printed lines
- (e.g. set this to adapt the display to different
- terminal window sizes).
- positions: Relative or absolute positions of log elements
- in each line. If not provided,
- defaults to `[.33, .55, .67, 1.]`.
- print_fn: Print function to use. Defaults to `print`.
- It will be called on each line of the summary.
- You can set it to a custom function
- in order to capture the string summary.
- """
- print_layer_summary(self,
- line_length=line_length,
- positions=positions,
- print_fn=print_fn)
-
-
-# Alias for legacy support.
-Container = Network
-
-
-def get_source_inputs(tensor, layer=None, node_index=None):
- """Returns the list of input tensors necessary to compute `tensor`.
-
- Output will always be a list of tensors
- (potentially with 1 element).
-
- Arguments:
- tensor: The tensor to start from.
- layer: Origin layer of the tensor. Will be
- determined via tensor._keras_history if not provided.
- node_index: Origin node index of the tensor.
-
- Returns:
- List of input tensors.
- """
- if not hasattr(tensor, '_keras_history'):
- return tensor
-
- if layer is None or node_index:
- layer, node_index, _ = tensor._keras_history
- if not layer.inbound_nodes:
- return [tensor]
- else:
- node = layer.inbound_nodes[node_index]
- if not node.inbound_layers:
- # Reached an Input layer, stop recursion.
- return node.input_tensors
- else:
- source_tensors = []
- for i in range(len(node.inbound_layers)):
- x = node.input_tensors[i]
- layer = node.inbound_layers[i]
- node_index = node.node_indices[i]
- previous_sources = get_source_inputs(x, layer, node_index)
- # Avoid input redundancy.
- for x in previous_sources:
- if x not in source_tensors:
- source_tensors.append(x)
- return source_tensors
-
-
-def _to_list(x):
- """Normalizes a list/tensor into a list.
-
- If a tensor is passed, we return
- a list of size 1 containing the tensor.
-
- Arguments:
- x: target object to be normalized.
-
- Returns:
- A list.
- """
- if isinstance(x, list):
- return x
- return [x]
-
-
-def save_weights_to_hdf5_group(f, layers):
- from tensorflow.contrib.keras.python.keras import __version__ as keras_version # pylint: disable=g-import-not-at-top
-
- f.attrs['layer_names'] = [layer.name.encode('utf8') for layer in layers]
- f.attrs['backend'] = K.backend().encode('utf8')
- f.attrs['keras_version'] = str(keras_version).encode('utf8')
-
- for layer in layers:
- g = f.create_group(layer.name)
- symbolic_weights = layer.weights
- weight_values = K.batch_get_value(symbolic_weights)
- weight_names = []
- for i, (w, val) in enumerate(zip(symbolic_weights, weight_values)):
- if hasattr(w, 'name') and w.name:
- name = str(w.name)
- else:
- name = 'param_' + str(i)
- weight_names.append(name.encode('utf8'))
- g.attrs['weight_names'] = weight_names
- for name, val in zip(weight_names, weight_values):
- param_dset = g.create_dataset(name, val.shape, dtype=val.dtype)
- if not val.shape:
- # scalar
- param_dset[()] = val
- else:
- param_dset[:] = val
-
-
-def preprocess_weights_for_loading(layer,
- weights,
- original_keras_version=None,
- original_backend=None):
- """Converts layers weights from Keras 1 format to Keras 2.
-
- Arguments:
- layer: Layer instance.
- weights: List of weights values (Numpy arrays).
- original_keras_version: Keras version for the weights, as a string.
- original_backend: Keras backend the weights were trained with,
- as a string.
-
- Returns:
- A list of weights values (Numpy arrays).
- """
- if original_keras_version == '1':
- if layer.__class__.__name__ == 'Bidirectional':
- num_weights_per_layer = len(weights) // 2
-
- forward_weights = preprocess_weights_for_loading(
- layer.forward_layer, weights[:num_weights_per_layer],
- original_keras_version, original_backend)
- backward_weights = preprocess_weights_for_loading(
- layer.backward_layer, weights[num_weights_per_layer:],
- original_keras_version, original_backend)
- weights = forward_weights + backward_weights
-
- if layer.__class__.__name__ == 'TimeDistributed':
- weights = preprocess_weights_for_loading(
- layer.layer, weights, original_keras_version, original_backend)
-
- if layer.__class__.__name__ == 'Conv1D':
- shape = weights[0].shape
- # Handle Keras 1.1 format
- if shape[:2] != (layer.kernel_size[0], 1) or shape[3] != layer.filters:
- # Legacy shape:
- # (filters, input_dim, filter_length, 1)
- assert shape[0] == layer.filters and shape[2:] == (layer.kernel_size[0],
- 1)
- weights[0] = np.transpose(weights[0], (2, 3, 1, 0))
- weights[0] = weights[0][:, 0, :, :]
-
- if layer.__class__.__name__ == 'Conv2D':
- if layer.data_format == 'channels_first':
- # old: (filters, stack_size, kernel_rows, kernel_cols)
- # new: (kernel_rows, kernel_cols, stack_size, filters)
- weights[0] = np.transpose(weights[0], (2, 3, 1, 0))
-
- if layer.__class__.__name__ == 'Conv2DTranspose':
- if layer.data_format == 'channels_last':
- # old: (kernel_rows, kernel_cols, stack_size, filters)
- # new: (kernel_rows, kernel_cols, filters, stack_size)
- weights[0] = np.transpose(weights[0], (0, 1, 3, 2))
- if layer.data_format == 'channels_first':
- # old: (filters, stack_size, kernel_rows, kernel_cols)
- # new: (kernel_rows, kernel_cols, filters, stack_size)
- weights[0] = np.transpose(weights[0], (2, 3, 0, 1))
-
- if layer.__class__.__name__ == 'Conv3D':
- if layer.data_format == 'channels_first':
- # old: (filters, stack_size, ...)
- # new: (..., stack_size, filters)
- weights[0] = np.transpose(weights[0], (2, 3, 4, 1, 0))
-
- if layer.__class__.__name__ == 'GRU':
- if len(weights) == 9:
- kernel = np.concatenate([weights[0], weights[3], weights[6]], axis=-1)
- recurrent_kernel = np.concatenate(
- [weights[1], weights[4], weights[7]], axis=-1)
- bias = np.concatenate([weights[2], weights[5], weights[8]], axis=-1)
- weights = [kernel, recurrent_kernel, bias]
-
- if layer.__class__.__name__ == 'LSTM':
- if len(weights) == 12:
- # old: i, c, f, o
- # new: i, f, c, o
- kernel = np.concatenate(
- [weights[0], weights[6], weights[3], weights[9]], axis=-1)
- recurrent_kernel = np.concatenate(
- [weights[1], weights[7], weights[4], weights[10]], axis=-1)
- bias = np.concatenate(
- [weights[2], weights[8], weights[5], weights[11]], axis=-1)
- weights = [kernel, recurrent_kernel, bias]
-
- if layer.__class__.__name__ == 'ConvLSTM2D':
- if len(weights) == 12:
- kernel = np.concatenate(
- [weights[0], weights[6], weights[3], weights[9]], axis=-1)
- recurrent_kernel = np.concatenate(
- [weights[1], weights[7], weights[4], weights[10]], axis=-1)
- bias = np.concatenate(
- [weights[2], weights[8], weights[5], weights[11]], axis=-1)
- if layer.data_format == 'channels_first':
- # old: (filters, stack_size, kernel_rows, kernel_cols)
- # new: (kernel_rows, kernel_cols, stack_size, filters)
- kernel = np.transpose(kernel, (2, 3, 1, 0))
- recurrent_kernel = np.transpose(recurrent_kernel, (2, 3, 1, 0))
- weights = [kernel, recurrent_kernel, bias]
-
- if layer.__class__.__name__ in ['Model', 'Sequential']:
- new_weights = []
- # trainable weights
- for sublayer in layer.layers:
- num_weights = len(sublayer.trainable_weights)
- if num_weights > 0:
- new_weights.extend(
- preprocess_weights_for_loading(
- layer=sublayer,
- weights=weights[:num_weights],
- original_keras_version=original_keras_version,
- original_backend=original_backend))
- weights = weights[num_weights:]
-
- # non-trainable weights
- for sublayer in layer.layers:
- num_weights = len([
- l for l in sublayer.weights if l not in sublayer.trainable_weights
- ])
- if num_weights > 0:
- new_weights.extend(
- preprocess_weights_for_loading(
- layer=sublayer,
- weights=weights[:num_weights],
- original_keras_version=original_keras_version,
- original_backend=original_backend))
- weights = weights[num_weights:]
- weights = new_weights
-
- conv_layers = ['Conv1D', 'Conv2D', 'Conv3D', 'Conv2DTranspose', 'ConvLSTM2D']
- if layer.__class__.__name__ in conv_layers:
- if original_backend and K.backend() != original_backend:
- weights[0] = conv_utils.convert_kernel(weights[0])
- if layer.__class__.__name__ == 'ConvLSTM2D':
- weights[1] = conv_utils.convert_kernel(weights[1])
- if K.int_shape(layer.weights[0]) != weights[0].shape:
- weights[0] = np.transpose(weights[0], (3, 2, 0, 1))
- if layer.__class__.__name__ == 'ConvLSTM2D':
- weights[1] = np.transpose(weights[1], (3, 2, 0, 1))
- return weights
-
-
-def load_weights_from_hdf5_group(f, layers):
- """Implements topological (order-based) weight loading.
-
- Arguments:
- f: A pointer to a HDF5 group.
- layers: a list of target layers.
-
- Raises:
- ValueError: in case of mismatch between provided layers
- and weights file.
- """
- if 'keras_version' in f.attrs:
- original_keras_version = f.attrs['keras_version'].decode('utf8')
- else:
- original_keras_version = '1'
- if 'backend' in f.attrs:
- original_backend = f.attrs['backend'].decode('utf8')
- else:
- original_backend = None
-
- filtered_layers = []
- for layer in layers:
- weights = layer.weights
- if weights:
- filtered_layers.append(layer)
-
- layer_names = [n.decode('utf8') for n in f.attrs['layer_names']]
- filtered_layer_names = []
- for name in layer_names:
- g = f[name]
- weight_names = [n.decode('utf8') for n in g.attrs['weight_names']]
- if weight_names:
- filtered_layer_names.append(name)
- layer_names = filtered_layer_names
- if len(layer_names) != len(filtered_layers):
- raise ValueError('You are trying to load a weight file '
- 'containing ' + str(len(layer_names)) +
- ' layers into a model with ' + str(len(filtered_layers)) +
- ' layers.')
-
- # We batch weight value assignments in a single backend call
- # which provides a speedup in TensorFlow.
- weight_value_tuples = []
- for k, name in enumerate(layer_names):
- g = f[name]
- weight_names = [n.decode('utf8') for n in g.attrs['weight_names']]
- weight_values = [g[weight_name] for weight_name in weight_names]
- layer = filtered_layers[k]
- symbolic_weights = layer.weights
- weight_values = preprocess_weights_for_loading(
- layer, weight_values, original_keras_version, original_backend)
- if len(weight_values) != len(symbolic_weights):
- raise ValueError('Layer #' + str(k) + ' (named "' + layer.name +
- '" in the current model) was found to '
- 'correspond to layer ' + name + ' in the save file. '
- 'However the new layer ' + layer.name + ' expects ' +
- str(len(symbolic_weights)) +
- ' weights, but the saved weights have ' +
- str(len(weight_values)) + ' elements.')
- weight_value_tuples += zip(symbolic_weights, weight_values)
- K.batch_set_value(weight_value_tuples)
-
-
-def load_weights_from_hdf5_group_by_name(f, layers):
- """Implements name-based weight loading.
-
- (instead of topological weight loading).
-
- Layers that have no matching name are skipped.
-
- Arguments:
- f: A pointer to a HDF5 group.
- layers: a list of target layers.
-
- Raises:
- ValueError: in case of mismatch between provided layers
- and weights file.
- """
- if 'keras_version' in f.attrs:
- original_keras_version = f.attrs['keras_version'].decode('utf8')
- else:
- original_keras_version = '1'
- if 'backend' in f.attrs:
- original_backend = f.attrs['backend'].decode('utf8')
- else:
- original_backend = None
-
- # New file format.
- layer_names = [n.decode('utf8') for n in f.attrs['layer_names']]
-
- # Reverse index of layer name to list of layers with name.
- index = {}
- for layer in layers:
- if layer.name:
- index.setdefault(layer.name, []).append(layer)
-
- # We batch weight value assignments in a single backend call
- # which provides a speedup in TensorFlow.
- weight_value_tuples = []
- for k, name in enumerate(layer_names):
- g = f[name]
- weight_names = [n.decode('utf8') for n in g.attrs['weight_names']]
- weight_values = [g[weight_name] for weight_name in weight_names]
-
- for layer in index.get(name, []):
- symbolic_weights = layer.weights
- weight_values = preprocess_weights_for_loading(
- layer, weight_values, original_keras_version, original_backend)
- if len(weight_values) != len(symbolic_weights):
- raise ValueError('Layer #' + str(k) + ' (named "' + layer.name +
- '") expects ' + str(len(symbolic_weights)) +
- ' weight(s), but the saved weights' + ' have ' +
- str(len(weight_values)) + ' element(s).')
- # Set values.
- for i in range(len(weight_values)):
- weight_value_tuples.append((symbolic_weights[i], weight_values[i]))
- K.batch_set_value(weight_value_tuples)
diff --git a/tensorflow/contrib/keras/python/keras/engine/topology_test.py b/tensorflow/contrib/keras/python/keras/engine/topology_test.py
deleted file mode 100644
index 0fe775cf66..0000000000
--- a/tensorflow/contrib/keras/python/keras/engine/topology_test.py
+++ /dev/null
@@ -1,689 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#,============================================================================
-"""Tests for layer graphs construction & handling."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import os
-import shutil
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.framework import dtypes
-from tensorflow.python.ops import array_ops
-from tensorflow.python.platform import test
-
-try:
- import yaml # pylint:disable=g-import-not-at-top
-except ImportError:
- yaml = None
-
-try:
- import h5py # pylint:disable=g-import-not-at-top
-except ImportError:
- h5py = None
-
-
-class TopologyConstructionTest(test.TestCase):
-
- def test_get_updates_for(self):
- a = keras.layers.Input(shape=(2,))
- dense_layer = keras.layers.Dense(1)
- dense_layer.add_update(0, inputs=a)
- dense_layer.add_update(1, inputs=None)
-
- self.assertListEqual(dense_layer.get_updates_for(a), [0])
- self.assertListEqual(dense_layer.get_updates_for(None), [1])
-
- def test_get_losses_for(self):
- a = keras.layers.Input(shape=(2,))
- dense_layer = keras.layers.Dense(1)
- dense_layer.add_loss(0, inputs=a)
- dense_layer.add_loss(1, inputs=None)
-
- self.assertListEqual(dense_layer.get_losses_for(a), [0])
- self.assertListEqual(dense_layer.get_losses_for(None), [1])
-
- def test_trainable_weights(self):
- a = keras.layers.Input(shape=(2,))
- b = keras.layers.Dense(1)(a)
- model = keras.models.Model(a, b)
-
- weights = model.weights
- self.assertListEqual(model.trainable_weights, weights)
- self.assertListEqual(model.non_trainable_weights, [])
-
- model.trainable = False
- self.assertListEqual(model.trainable_weights, [])
- self.assertListEqual(model.non_trainable_weights, weights)
-
- model.trainable = True
- self.assertListEqual(model.trainable_weights, weights)
- self.assertListEqual(model.non_trainable_weights, [])
-
- model.layers[1].trainable = False
- self.assertListEqual(model.trainable_weights, [])
- self.assertListEqual(model.non_trainable_weights, weights)
-
- # sequential model
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(1, input_dim=2))
- weights = model.weights
-
- self.assertListEqual(model.trainable_weights, weights)
- self.assertListEqual(model.non_trainable_weights, [])
-
- model.trainable = False
- self.assertListEqual(model.trainable_weights, [])
- self.assertListEqual(model.non_trainable_weights, weights)
-
- model.trainable = True
- self.assertListEqual(model.trainable_weights, weights)
- self.assertListEqual(model.non_trainable_weights, [])
-
- model.layers[0].trainable = False
- self.assertListEqual(model.trainable_weights, [])
- self.assertListEqual(model.non_trainable_weights, weights)
-
- def test_weight_loading(self):
- with self.test_session():
- a = keras.layers.Input(shape=(2,))
- x = keras.layers.Dense(3)(a)
- b = keras.layers.Dense(1)(x)
- model = keras.models.Model(a, b)
-
- x = np.random.random((3, 2))
- ref_y = model.predict(x)
- weights = model.get_weights()
- model.set_weights(weights)
- y = model.predict(x)
- self.assertAllClose(ref_y, y)
-
- with self.assertRaises(ValueError):
- model.set_weights(weights[1:])
- with self.assertRaises(ValueError):
- model.set_weights(weights[::-1])
-
- if h5py is None:
- return # Skip rest of test if H5py isn't available.
-
- temp_dir = self.get_temp_dir()
- self.addCleanup(shutil.rmtree, temp_dir)
-
- h5_path = os.path.join(temp_dir, 'test.h5')
- model.save_weights(h5_path)
- model.load_weights(h5_path)
- y = model.predict(x)
- self.assertAllClose(ref_y, y)
-
- model.load_weights(h5_path, by_name=True)
- y = model.predict(x)
- self.assertAllClose(ref_y, y)
-
- def test_learning_phase(self):
- with self.test_session():
- a = keras.layers.Input(shape=(32,), name='input_a')
- b = keras.layers.Input(shape=(32,), name='input_b')
-
- a_2 = keras.layers.Dense(16, name='dense_1')(a)
- dp = keras.layers.Dropout(0.5, name='dropout')
- b_2 = dp(b)
-
- self.assertFalse(a_2._uses_learning_phase)
- self.assertTrue(b_2._uses_learning_phase)
-
- # test merge
- m = keras.layers.concatenate([a_2, b_2])
- self.assertTrue(m._uses_learning_phase)
-
- # Test recursion
- model = keras.models.Model([a, b], [a_2, b_2])
- self.assertTrue(model.uses_learning_phase)
-
- c = keras.layers.Input(shape=(32,), name='input_c')
- d = keras.layers.Input(shape=(32,), name='input_d')
-
- c_2, b_2 = model([c, d])
- self.assertTrue(c_2._uses_learning_phase)
- self.assertTrue(b_2._uses_learning_phase)
-
- # try actually running graph
- fn = keras.backend.function(
- model.inputs + [keras.backend.learning_phase()], model.outputs)
- input_a_np = np.random.random((10, 32))
- input_b_np = np.random.random((10, 32))
- fn_outputs_no_dp = fn([input_a_np, input_b_np, 0])
- fn_outputs_dp = fn([input_a_np, input_b_np, 1])
- # output a: nothing changes
- self.assertEqual(fn_outputs_no_dp[0].sum(), fn_outputs_dp[0].sum())
- # output b: dropout applied
- self.assertNotEqual(fn_outputs_no_dp[1].sum(), fn_outputs_dp[1].sum())
-
- def test_layer_call_arguments(self):
- # Test the ability to pass and serialize arguments to `call`.
- inp = keras.layers.Input(shape=(2,))
- x = keras.layers.Dense(3)(inp)
- x = keras.layers.Dropout(0.5)(x, training=True)
- model = keras.models.Model(inp, x)
- self.assertFalse(model.uses_learning_phase)
-
- # Test that argument is kept when applying the model
- inp2 = keras.layers.Input(shape=(2,))
- out2 = model(inp2)
- self.assertFalse(out2._uses_learning_phase)
-
- # Test that argument is kept after loading a model
- config = model.get_config()
- model = keras.models.Model.from_config(config)
- self.assertFalse(model.uses_learning_phase)
-
- def test_node_construction(self):
- # test basics
- a = keras.layers.Input(shape=(32,), name='input_a')
- b = keras.layers.Input(shape=(32,), name='input_b')
-
- with self.assertRaises(ValueError):
- _ = keras.layers.Input(shape=(32,), batch_shape=(10, 32))
- with self.assertRaises(ValueError):
- _ = keras.layers.Input(shape=(32,), unknwon_kwarg=None)
-
- self.assertListEqual(a.get_shape().as_list(), [None, 32])
- a_layer, a_node_index, a_tensor_index = a._keras_history
- b_layer, _, _ = b._keras_history
- self.assertEqual(len(a_layer.inbound_nodes), 1)
- self.assertEqual(a_tensor_index, 0)
- node = a_layer.inbound_nodes[a_node_index]
- self.assertEqual(node.outbound_layer, a_layer)
-
- self.assertListEqual(node.inbound_layers, [])
- self.assertListEqual(node.input_tensors, [a])
- self.assertListEqual(node.input_shapes, [(None, 32)])
- self.assertListEqual(node.output_tensors, [a])
- self.assertListEqual(node.output_shapes, [(None, 32)])
-
- dense = keras.layers.Dense(16, name='dense_1')
- a_2 = dense(a)
- b_2 = dense(b)
-
- self.assertEqual(len(dense.inbound_nodes), 2)
- self.assertEqual(len(dense.outbound_nodes), 0)
- self.assertListEqual(dense.inbound_nodes[0].inbound_layers, [a_layer])
- self.assertEqual(dense.inbound_nodes[0].outbound_layer, dense)
- self.assertListEqual(dense.inbound_nodes[1].inbound_layers, [b_layer])
- self.assertEqual(dense.inbound_nodes[1].outbound_layer, dense)
- self.assertListEqual(dense.inbound_nodes[0].input_tensors, [a])
- self.assertListEqual(dense.inbound_nodes[1].input_tensors, [b])
-
- # test layer properties
- test_layer = keras.layers.Dense(16, name='test_layer')
- a_test = test_layer(a)
- self.assertListEqual(test_layer.kernel.get_shape().as_list(), [32, 16])
- self.assertEqual(test_layer.input, a)
- self.assertEqual(test_layer.output, a_test)
- self.assertEqual(test_layer.input_shape, (None, 32))
- self.assertEqual(test_layer.output_shape, (None, 16))
-
- self.assertEqual(dense.get_input_at(0), a)
- self.assertEqual(dense.get_input_at(1), b)
- self.assertEqual(dense.get_output_at(0), a_2)
- self.assertEqual(dense.get_output_at(1), b_2)
- self.assertEqual(dense.get_input_shape_at(0), (None, 32))
- self.assertEqual(dense.get_input_shape_at(1), (None, 32))
- self.assertEqual(dense.get_output_shape_at(0), (None, 16))
- self.assertEqual(dense.get_output_shape_at(1), (None, 16))
- self.assertEqual(dense.get_input_mask_at(0), None)
- self.assertEqual(dense.get_input_mask_at(1), None)
- self.assertEqual(dense.get_output_mask_at(0), None)
- self.assertEqual(dense.get_output_mask_at(1), None)
-
- def test_multi_input_layer(self):
- with self.test_session():
- # test multi-input layer
- a = keras.layers.Input(shape=(32,), name='input_a')
- b = keras.layers.Input(shape=(32,), name='input_b')
-
- dense = keras.layers.Dense(16, name='dense_1')
- a_2 = dense(a)
- b_2 = dense(b)
-
- merged = keras.layers.concatenate([a_2, b_2], name='merge')
- self.assertListEqual(merged.get_shape().as_list(), [None, 16 * 2])
- merge_layer, merge_node_index, merge_tensor_index = merged._keras_history
-
- self.assertEqual(merge_node_index, 0)
- self.assertEqual(merge_tensor_index, 0)
-
- self.assertEqual(len(merge_layer.inbound_nodes), 1)
- self.assertEqual(len(merge_layer.outbound_nodes), 0)
-
- self.assertEqual(len(merge_layer.inbound_nodes[0].input_tensors), 2)
- self.assertEqual(len(merge_layer.inbound_nodes[0].inbound_layers), 2)
-
- c = keras.layers.Dense(64, name='dense_2')(merged)
- d = keras.layers.Dense(5, name='dense_3')(c)
-
- model = keras.models.Model(inputs=[a, b], outputs=[c, d], name='model')
- self.assertEqual(len(model.layers), 6)
- output_shapes = model._compute_output_shape([(None, 32), (None, 32)])
- self.assertListEqual(output_shapes[0].as_list(), [None, 64])
- self.assertListEqual(output_shapes[1].as_list(), [None, 5])
- self.assertListEqual(
- model.compute_mask([a, b], [None, None]), [None, None])
-
- # we don't check names of first 2 layers (inputs) because
- # ordering of same-level layers is not fixed
- self.assertListEqual([l.name for l in model.layers][2:],
- ['dense_1', 'merge', 'dense_2', 'dense_3'])
- self.assertListEqual([l.name for l in model._input_layers],
- ['input_a', 'input_b'])
- self.assertListEqual([l.name for l in model._output_layers],
- ['dense_2', 'dense_3'])
-
- # actually run model
- fn = keras.backend.function(model.inputs, model.outputs)
- input_a_np = np.random.random((10, 32))
- input_b_np = np.random.random((10, 32))
- fn_outputs = fn([input_a_np, input_b_np])
- self.assertListEqual([x.shape for x in fn_outputs], [(10, 64), (10, 5)])
-
- # test get_source_inputs
- self.assertListEqual(keras.engine.topology.get_source_inputs(c), [a, b])
-
- # serialization / deserialization
- json_config = model.to_json()
- recreated_model = keras.models.model_from_json(json_config)
- recreated_model.compile('rmsprop', 'mse')
-
- self.assertListEqual([l.name for l in recreated_model.layers][2:],
- ['dense_1', 'merge', 'dense_2', 'dense_3'])
- self.assertListEqual([l.name for l in recreated_model._input_layers],
- ['input_a', 'input_b'])
- self.assertListEqual([l.name for l in recreated_model._output_layers],
- ['dense_2', 'dense_3'])
-
- fn = keras.backend.function(recreated_model.inputs,
- recreated_model.outputs)
- input_a_np = np.random.random((10, 32))
- input_b_np = np.random.random((10, 32))
- fn_outputs = fn([input_a_np, input_b_np])
- self.assertListEqual([x.shape for x in fn_outputs], [(10, 64), (10, 5)])
-
- def test_recursion(self):
- with self.test_session():
- a = keras.layers.Input(shape=(32,), name='input_a')
- b = keras.layers.Input(shape=(32,), name='input_b')
-
- dense = keras.layers.Dense(16, name='dense_1')
- a_2 = dense(a)
- b_2 = dense(b)
- merged = keras.layers.concatenate([a_2, b_2], name='merge')
- c = keras.layers.Dense(64, name='dense_2')(merged)
- d = keras.layers.Dense(5, name='dense_3')(c)
-
- model = keras.models.Model(inputs=[a, b], outputs=[c, d], name='model')
-
- e = keras.layers.Input(shape=(32,), name='input_e')
- f = keras.layers.Input(shape=(32,), name='input_f')
- g, h = model([e, f])
-
- self.assertListEqual(g.get_shape().as_list(), c.get_shape().as_list())
- self.assertListEqual(h.get_shape().as_list(), d.get_shape().as_list())
-
- # test separate manipulation of different layer outputs
- i = keras.layers.Dense(7, name='dense_4')(h)
-
- final_model = keras.models.Model(
- inputs=[e, f], outputs=[i, g], name='final')
- self.assertEqual(len(final_model.inputs), 2)
- self.assertEqual(len(final_model.outputs), 2)
- self.assertEqual(len(final_model.layers), 4)
-
- # we don't check names of first 2 layers (inputs) because
- # ordering of same-level layers is not fixed
- self.assertListEqual([layer.name for layer in final_model.layers][2:],
- ['model', 'dense_4'])
- self.assertListEqual(
- model.compute_mask([e, f], [None, None]), [None, None])
- self.assertListEqual(
- final_model._compute_output_shape([(10, 32), (10, 32)]), [(10, 7),
- (10, 64)])
-
- # run recursive model
- fn = keras.backend.function(final_model.inputs, final_model.outputs)
- input_a_np = np.random.random((10, 32))
- input_b_np = np.random.random((10, 32))
- fn_outputs = fn([input_a_np, input_b_np])
- self.assertListEqual([x.shape for x in fn_outputs], [(10, 7), (10, 64)])
-
- # test serialization
- model_config = final_model.get_config()
- recreated_model = keras.models.Model.from_config(model_config)
-
- fn = keras.backend.function(recreated_model.inputs,
- recreated_model.outputs)
- input_a_np = np.random.random((10, 32))
- input_b_np = np.random.random((10, 32))
- fn_outputs = fn([input_a_np, input_b_np])
- self.assertListEqual([x.shape for x in fn_outputs], [(10, 7), (10, 64)])
-
- def test_multi_input_multi_output_recursion(self):
- with self.test_session():
- # test multi-input multi-output
- a = keras.layers.Input(shape=(32,), name='input_a')
- b = keras.layers.Input(shape=(32,), name='input_b')
-
- dense = keras.layers.Dense(16, name='dense_1')
- a_2 = dense(a)
- b_2 = dense(b)
- merged = keras.layers.concatenate([a_2, b_2], name='merge')
- c = keras.layers.Dense(64, name='dense_2')(merged)
- d = keras.layers.Dense(5, name='dense_3')(c)
-
- model = keras.models.Model(inputs=[a, b], outputs=[c, d], name='model')
-
- j = keras.layers.Input(shape=(32,), name='input_j')
- k = keras.layers.Input(shape=(32,), name='input_k')
- _, n = model([j, k])
-
- o = keras.layers.Input(shape=(32,), name='input_o')
- p = keras.layers.Input(shape=(32,), name='input_p')
- q, _ = model([o, p])
-
- self.assertListEqual(n.get_shape().as_list(), [None, 5])
- self.assertListEqual(q.get_shape().as_list(), [None, 64])
- s = keras.layers.concatenate([n, q], name='merge_nq')
- self.assertListEqual(s.get_shape().as_list(), [None, 64 + 5])
-
- # test with single output as 1-elem list
- multi_io_model = keras.models.Model([j, k, o, p], [s])
-
- fn = keras.backend.function(multi_io_model.inputs, multi_io_model.outputs)
- fn_outputs = fn([
- np.random.random((10, 32)), np.random.random((10, 32)),
- np.random.random((10, 32)), np.random.random((10, 32))
- ])
- self.assertListEqual([x.shape for x in fn_outputs], [(10, 69)])
-
- # test with single output as tensor
- multi_io_model = keras.models.Model([j, k, o, p], s)
-
- fn = keras.backend.function(multi_io_model.inputs, multi_io_model.outputs)
- fn_outputs = fn([
- np.random.random((10, 32)), np.random.random((10, 32)),
- np.random.random((10, 32)), np.random.random((10, 32))
- ])
- # note that the output of the function will still be a 1-elem list
- self.assertListEqual([x.shape for x in fn_outputs], [(10, 69)])
-
- # test serialization
- model_config = multi_io_model.get_config()
- recreated_model = keras.models.Model.from_config(model_config)
-
- fn = keras.backend.function(recreated_model.inputs,
- recreated_model.outputs)
- fn_outputs = fn([
- np.random.random((10, 32)), np.random.random((10, 32)),
- np.random.random((10, 32)), np.random.random((10, 32))
- ])
- # note that the output of the function will still be a 1-elem list
- self.assertListEqual([x.shape for x in fn_outputs], [(10, 69)])
-
- config = model.get_config()
- keras.models.Model.from_config(config)
-
- model.summary()
- json_str = model.to_json()
- keras.models.model_from_json(json_str)
-
- if yaml is not None:
- yaml_str = model.to_yaml()
- keras.models.model_from_yaml(yaml_str)
-
- def test_invalid_graphs(self):
- a = keras.layers.Input(shape=(32,), name='input_a')
- b = keras.layers.Input(shape=(32,), name='input_b')
-
- dense = keras.layers.Dense(16, name='dense_1')
- a_2 = dense(a)
- b_2 = dense(b)
- merged = keras.layers.concatenate([a_2, b_2], name='merge')
- c = keras.layers.Dense(64, name='dense_2')(merged)
- d = keras.layers.Dense(5, name='dense_3')(c)
-
- model = keras.models.Model(inputs=[a, b], outputs=[c, d], name='model')
-
- # input is not an Input tensor
- j = keras.layers.Input(shape=(32,), name='input_j')
- j = keras.layers.Dense(32)(j)
- k = keras.layers.Input(shape=(32,), name='input_k')
- m, n = model([j, k])
-
- with self.assertRaises(Exception):
- keras.models.Model([j, k], [m, n])
-
- # disconnected graph
- j = keras.layers.Input(shape=(32,), name='input_j')
- k = keras.layers.Input(shape=(32,), name='input_k')
- m, n = model([j, k])
- with self.assertRaises(Exception):
- keras.models.Model([j], [m, n])
-
- # redundant outputs
- j = keras.layers.Input(shape=(32,), name='input_j')
- k = keras.layers.Input(shape=(32,), name='input_k')
- m, n = model([j, k])
-
- keras.models.Model([j, k], [m, n, n])
-
- # redundant inputs
- j = keras.layers.Input(shape=(32,), name='input_j')
- k = keras.layers.Input(shape=(32,), name='input_k')
- m, n = model([j, k])
- with self.assertRaises(Exception):
- keras.models.Model([j, k, j], [m, n])
-
- # i have not idea what I'm doing: garbage as inputs/outputs
- j = keras.layers.Input(shape=(32,), name='input_j')
- k = keras.layers.Input(shape=(32,), name='input_k')
- m, n = model([j, k])
- with self.assertRaises(Exception):
- keras.models.Model([j, k], [m, n, 0])
-
- def test_raw_tf_compatibility(self):
- # test calling layers/models on TF tensors
- a = keras.layers.Input(shape=(32,), name='input_a')
- b = keras.layers.Input(shape=(32,), name='input_b')
-
- dense = keras.layers.Dense(16, name='dense_1')
- a_2 = dense(a)
- b_2 = dense(b)
- merged = keras.layers.concatenate([a_2, b_2], name='merge')
- c = keras.layers.Dense(64, name='dense_2')(merged)
- d = keras.layers.Dense(5, name='dense_3')(c)
-
- model = keras.models.Model(inputs=[a, b], outputs=[c, d], name='model')
-
- j = keras.layers.Input(shape=(32,), name='input_j')
- k = keras.layers.Input(shape=(32,), name='input_k')
- m, n = model([j, k])
- tf_model = keras.models.Model([j, k], [m, n])
-
- j_tf = array_ops.placeholder(dtype=dtypes.float32, shape=(None, 32))
- k_tf = array_ops.placeholder(dtype=dtypes.float32, shape=(None, 32))
- m_tf, n_tf = tf_model([j_tf, k_tf])
- self.assertListEqual(m_tf.get_shape().as_list(), [None, 64])
- self.assertListEqual(n_tf.get_shape().as_list(), [None, 5])
-
- # test merge
- keras.layers.concatenate([j_tf, k_tf], axis=1)
- keras.layers.add([j_tf, k_tf])
-
- # test tensor input
- x = array_ops.placeholder(shape=(None, 2), dtype=dtypes.float32)
- keras.layers.InputLayer(input_tensor=x)
-
- x = keras.layers.Input(tensor=x)
- keras.layers.Dense(2)(x)
-
- def test_basic_masking(self):
- a = keras.layers.Input(shape=(10, 32), name='input_a')
- b = keras.layers.Masking()(a)
- model = keras.models.Model(a, b)
- self.assertEqual(model.output_mask.get_shape().as_list(), [None, 10])
-
- def test_weight_preprocessing(self):
- input_dim = 3
- output_dim = 3
- size = 2
- cases = [
- [
- (keras.layers.Bidirectional(keras.layers.SimpleRNN(2))),
- [np.random.random((2, 1)), np.random.random((2, 1))],
- (None, 3, 2),
- ],
- [
- (keras.layers.TimeDistributed(keras.layers.Dense(1))),
- [np.random.random((2, 1)), np.random.random((1,))],
- (None, 3, 2),
- ],
- [
- (keras.layers.Conv1D(output_dim, size, use_bias=False)),
- [np.random.random((output_dim, input_dim, size, 1))],
- (None, 4, input_dim),
- ],
- [
- (keras.layers.Conv2D(output_dim, size,
- use_bias=False, data_format='channels_first')),
- [np.random.random((output_dim, input_dim, size, size))],
- (None, input_dim, 4, 4),
- ],
- [
- (keras.layers.Conv2DTranspose(output_dim, size,
- use_bias=False,
- data_format='channels_first')),
- [np.random.random((output_dim, input_dim, size, size))],
- (None, input_dim, 4, 4),
- ],
- [
- (keras.layers.Conv2DTranspose(output_dim, size,
- use_bias=False,
- data_format='channels_last')),
- [np.random.random((size, size, input_dim, output_dim))],
- (None, 4, 4, input_dim),
- ],
- [
- (keras.layers.Conv3D(output_dim, size,
- use_bias=False, data_format='channels_first')),
- [np.random.random((output_dim, input_dim, size, size, size))],
- (None, input_dim, 4, 4, 4),
- ],
- [
- (keras.layers.GRU(output_dim)),
- [np.random.random((input_dim, output_dim)),
- np.random.random((output_dim, output_dim)),
- np.random.random((output_dim,)),
- np.random.random((input_dim, output_dim)),
- np.random.random((output_dim, output_dim)),
- np.random.random((output_dim,)),
- np.random.random((input_dim, output_dim)),
- np.random.random((output_dim, output_dim)),
- np.random.random((output_dim,))],
- (None, 4, input_dim),
- ],
- [
- (keras.layers.LSTM(output_dim)),
- [np.random.random((input_dim, output_dim)),
- np.random.random((output_dim, output_dim)),
- np.random.random((output_dim,)),
- np.random.random((input_dim, output_dim)),
- np.random.random((output_dim, output_dim)),
- np.random.random((output_dim,)),
- np.random.random((input_dim, output_dim)),
- np.random.random((output_dim, output_dim)),
- np.random.random((output_dim,)),
- np.random.random((input_dim, output_dim)),
- np.random.random((output_dim, output_dim)),
- np.random.random((output_dim,))],
- (None, 4, input_dim),
- ],
- ]
- for layer, weights, input_shape in cases:
- layer.build(input_shape)
- _ = keras.engine.topology.preprocess_weights_for_loading(
- layer, weights, original_keras_version='1')
-
- model = keras.models.Sequential([keras.layers.Dense(2, input_dim=2)])
- _ = keras.engine.topology.preprocess_weights_for_loading(
- model, model.weights, original_keras_version='1')
-
- x = keras.Input((2,))
- y = keras.layers.Dense(2)(x)
- model = keras.models.Model(x, y)
- _ = keras.engine.topology.preprocess_weights_for_loading(
- model, model.weights, original_keras_version='1')
-
- def test_layer_sharing_at_heterogenous_depth(self):
- with self.test_session():
- x_val = np.random.random((10, 5))
-
- x = keras.Input(shape=(5,))
- a = keras.layers.Dense(5, name='A')
- b = keras.layers.Dense(5, name='B')
- output = a(b(a(b(x))))
- m = keras.models.Model(x, output)
-
- output_val = m.predict(x_val)
-
- config = m.get_config()
- weights = m.get_weights()
-
- m2 = keras.models.Model.from_config(config)
- m2.set_weights(weights)
-
- output_val_2 = m2.predict(x_val)
- self.assertAllClose(output_val, output_val_2, atol=1e-6)
-
- def test_layer_sharing_at_heterogenous_depth_with_concat(self):
- with self.test_session():
- input_shape = (16, 9, 3)
- input_layer = keras.Input(shape=input_shape)
-
- a = keras.layers.Dense(3, name='dense_A')
- b = keras.layers.Dense(3, name='dense_B')
- c = keras.layers.Dense(3, name='dense_C')
-
- x1 = b(a(input_layer))
- x2 = a(c(input_layer))
- output = keras.layers.concatenate([x1, x2])
-
- m = keras.models.Model(inputs=input_layer, outputs=output)
-
- x_val = np.random.random((10, 16, 9, 3))
- output_val = m.predict(x_val)
-
- config = m.get_config()
- weights = m.get_weights()
-
- m2 = keras.models.Model.from_config(config)
- m2.set_weights(weights)
-
- output_val_2 = m2.predict(x_val)
- self.assertAllClose(output_val, output_val_2, atol=1e-6)
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/engine/training.py b/tensorflow/contrib/keras/python/keras/engine/training.py
deleted file mode 100644
index 619ae74b66..0000000000
--- a/tensorflow/contrib/keras/python/keras/engine/training.py
+++ /dev/null
@@ -1,2379 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Keras training and evaluation routines.
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import copy
-
-import numpy as np
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras import callbacks as cbks
-from tensorflow.contrib.keras.python.keras import losses
-from tensorflow.contrib.keras.python.keras import metrics as metrics_module
-from tensorflow.contrib.keras.python.keras import optimizers
-from tensorflow.contrib.keras.python.keras.engine.topology import Container
-from tensorflow.contrib.keras.python.keras.utils.data_utils import GeneratorEnqueuer
-from tensorflow.contrib.keras.python.keras.utils.data_utils import OrderedEnqueuer
-from tensorflow.contrib.keras.python.keras.utils.data_utils import Sequence
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import Progbar
-from tensorflow.python.platform import tf_logging as logging
-
-
-def _standardize_input_data(data,
- names,
- shapes=None,
- check_batch_axis=True,
- exception_prefix=''):
- """Normalizes inputs and targets provided by users.
-
- Users may pass data as a list of arrays, dictionary of arrays,
- or as a single array. We normalize this to an ordered list of
- arrays (same order as `names`), while checking that the provided
- arrays have shapes that match the network's expectations.
-
- Arguments:
- data: User-provided input data (polymorphic).
- names: List of expected array names.
- shapes: Optional list of expected array shapes.
- check_batch_axis: Boolean; whether to check that
- the batch axis of the arrays matches the expected
- value found in `shapes`.
- exception_prefix: String prefix used for exception formatting.
-
- Returns:
- List of standardized input arrays (one array per model input).
-
- Raises:
- ValueError: in case of improperly formatted user-provided data.
- """
- if not names:
- if data is not None and hasattr(data, '__len__') and len(data):
- raise ValueError('Error when checking model ' + exception_prefix + ': '
- 'expected no data, but got:', data)
- return []
- if data is None:
- return [None for _ in range(len(names))]
- if isinstance(data, dict):
- arrays = []
- for name in names:
- if name not in data:
- raise ValueError('No data provided for "' + name +
- '". Need data for each key in: ' + str(names))
- arrays.append(data[name])
- elif isinstance(data, list):
- if len(data) != len(names):
- if data and hasattr(data[0], 'shape'):
- raise ValueError(
- 'Error when checking model ' + exception_prefix +
- ': the list of Numpy arrays '
- 'that you are passing to your model '
- 'is not the size the model expected. '
- 'Expected to see ' + str(len(names)) + ' array(s), but instead got '
- 'the following list of ' + str(len(data)) + ' arrays: ' +
- str(data)[:200] + '...')
- else:
- if len(names) == 1:
- data = [np.asarray(data)]
- else:
- raise ValueError('Error when checking model ' + exception_prefix +
- ': you are passing a list as '
- 'input to your model, '
- 'but the model expects '
- 'a list of ' + str(len(names)) +
- ' Numpy arrays instead. '
- 'The list you passed was: ' + str(data)[:200])
- arrays = data
- else:
- if not hasattr(data, 'shape'):
- raise TypeError('Error when checking model ' + exception_prefix +
- ': data should be a Numpy array, '
- 'or list/dict of Numpy arrays. '
- 'Found: ' + str(data)[:200] + '...')
- if len(names) > 1:
- # Case: model expects multiple inputs but only received
- # a single Numpy array.
- raise ValueError('The model expects ' + str(len(names)) + ' ' +
- exception_prefix +
- ' arrays, but only received one array. '
- 'Found: array with shape ' + str(data.shape))
- arrays = [data]
-
- # Make arrays at least 2D.
- for i in range(len(names)):
- array = arrays[i]
- if len(array.shape) == 1:
- array = np.expand_dims(array, 1)
- arrays[i] = array
-
- # Check shapes compatibility.
- if shapes:
- for i in range(len(names)):
- if shapes[i] is None:
- continue
- array = arrays[i]
- if len(array.shape) != len(shapes[i]):
- raise ValueError(
- 'Error when checking ' + exception_prefix + ': expected ' + names[i]
- + ' to have ' + str(len(shapes[i])) +
- ' dimensions, but got array with shape ' + str(array.shape))
- for j, (dim, ref_dim) in enumerate(zip(array.shape, shapes[i])):
- if not j and not check_batch_axis:
- # skip the first axis
- continue
- if ref_dim:
- if ref_dim != dim:
- raise ValueError('Error when checking ' + exception_prefix +
- ': expected ' + names[i] + ' to have shape ' +
- str(shapes[i]) + ' but got array with shape ' +
- str(array.shape))
- return arrays
-
-
-def _standardize_sample_or_class_weights(x_weight, output_names, weight_type):
- """Maps `sample_weight` or `class_weight` to model outputs.
-
- Arguments:
- x_weight: User-provided `sample_weight` or `class_weight` argument.
- output_names: List of output names (strings) in the model.
- weight_type: A string used purely for exception printing.
-
- Returns:
- A list of `sample_weight` or `class_weight` where there are exactly
- one element per model output.
-
- Raises:
- ValueError: In case of invalid user-provided argument.
- """
- if x_weight is None or len(x_weight) == 0: # pylint: disable=g-explicit-length-test
- return [None for _ in output_names]
- if len(output_names) == 1:
- if isinstance(x_weight, list) and len(x_weight) == 1:
- return x_weight
- if isinstance(x_weight, dict) and output_names[0] in x_weight:
- return [x_weight[output_names[0]]]
- else:
- return [x_weight]
- if isinstance(x_weight, list):
- if len(x_weight) != len(output_names):
- raise ValueError('Provided `' + weight_type + '` was a list of ' +
- str(len(x_weight)) + ' elements, but the model has ' +
- str(len(output_names)) + ' outputs. '
- 'You should provide one `' + weight_type + '`'
- 'array per model output.')
- return x_weight
- if isinstance(x_weight, dict):
- x_weights = []
- for name in output_names:
- x_weights.append(x_weight.get(name))
- return x_weights
- else:
- raise TypeError('The model has multiple outputs, so `' + weight_type + '` '
- 'should be either a list of a dict. '
- 'Provided `' + weight_type + '` type not understood: ' +
- str(x_weight))
-
-
-def _standardize_class_weights(class_weight, output_names):
- return _standardize_sample_or_class_weights(class_weight, output_names,
- 'class_weight')
-
-
-def _standardize_sample_weights(sample_weight, output_names):
- return _standardize_sample_or_class_weights(sample_weight, output_names,
- 'sample_weight')
-
-
-def _check_array_lengths(inputs, targets, weights=None):
- """Does user input validation for numpy arrays.
-
- Arguments:
- inputs: list of Numpy arrays of inputs.
- targets: list of Numpy arrays of targets.
- weights: list of Numpy arrays of sample weights.
-
- Raises:
- ValueError: in case of incorrectly formatted data.
- """
-
- def set_of_lengths(x):
- # return a set with the variation between
- # different shapes, with None => 0
- if x is None:
- return {0}
- else:
- return set([0 if y is None else y.shape[0] for y in x])
-
- set_x = set_of_lengths(inputs)
- set_y = set_of_lengths(targets)
- set_w = set_of_lengths(weights)
- if len(set_x) > 1:
- raise ValueError('All input arrays (x) should have '
- 'the same number of samples. Got array shapes: ' + str(
- [x.shape for x in inputs]))
- if len(set_y) > 1:
- raise ValueError('All target arrays (y) should have '
- 'the same number of samples. Got array shapes: ' + str(
- [y.shape for y in targets]))
- if set_x and set_y and list(set_x)[0] != list(set_y)[0]:
- raise ValueError('Input arrays should have '
- 'the same number of samples as target arrays. '
- 'Found ' + str(list(set_x)[0]) + ' input samples '
- 'and ' + str(list(set_y)[0]) + ' target samples.')
- if len(set_w) > 1:
- raise ValueError('All sample_weight arrays should have '
- 'the same number of samples. Got array shapes: ' + str(
- [w.shape for w in weights]))
- if set_y and set_w and list(set_y)[0] != list(set_w)[0]:
- raise ValueError('Sample_weight arrays should have '
- 'the same number of samples as target arrays. Got ' +
- str(list(set_y)[0]) + ' input samples and ' +
- str(list(set_w)[0]) + ' target samples.')
-
-
-def _check_loss_and_target_compatibility(targets, loss_fns, output_shapes):
- """Does validation on the compatibility of targets and loss functions.
-
- This helps prevent users from using loss functions incorrectly.
-
- Arguments:
- targets: list of Numpy arrays of targets.
- loss_fns: list of loss functions.
- output_shapes: list of shapes of model outputs.
-
- Raises:
- ValueError: if a loss function or target array
- is incompatible with an output.
- """
- key_losses = {
- 'mean_squared_error', 'binary_crossentropy', 'categorical_crossentropy'
- }
- for y, loss, shape in zip(targets, loss_fns, output_shapes):
- if loss is None:
- continue
- if loss.__name__ == 'categorical_crossentropy':
- if y.shape[-1] == 1:
- raise ValueError('You are passing a target array of shape ' + str(
- y.shape) + ' while using as loss `categorical_crossentropy`. '
- '`categorical_crossentropy` expects '
- 'targets to be binary matrices (1s and 0s) '
- 'of shape (samples, classes). '
- 'If your targets are integer classes, '
- 'you can convert them to the expected format via:\n'
- '```\n'
- 'from keras.utils.np_utils import to_categorical\n'
- 'y_binary = to_categorical(y_int)\n'
- '```\n'
- '\n'
- 'Alternatively, you can use the loss function '
- '`sparse_categorical_crossentropy` instead, '
- 'which does expect integer targets.')
- if loss.__name__ in key_losses:
- for target_dim, out_dim in zip(y.shape[1:], shape[1:]):
- if out_dim is not None and target_dim != out_dim:
- raise ValueError('A target array with shape ' + str(y.shape) +
- ' was passed for an output of shape ' + str(shape) +
- ' while using as loss `' + loss.__name__ + '`. '
- 'This loss expects '
- 'targets to have the same shape '
- 'as the output.')
-
-
-def _collect_metrics(metrics, output_names):
- """Maps metric functions to model outputs.
-
- Arguments:
- metrics: a list or dict of metric functions.
- output_names: a list of the names (strings) of model outputs.
-
- Returns:
- A list (one entry per model output) of lists of metric functions.
- For instance, if the model has 2 outputs, and for the first output
- we want to compute "binary_accuracy" and "binary_crossentropy",
- and just "binary_accuracy" for the second output,
- the list would look like:
- `[[binary_accuracy, binary_crossentropy], [binary_accuracy]]`
-
- Raises:
- TypeError: if an incorrect type is passed for the `metrics` argument.
- """
- if not metrics:
- return [[] for _ in output_names]
- if isinstance(metrics, list):
- # we then apply all metrics to all outputs.
- return [copy.copy(metrics) for _ in output_names]
- elif isinstance(metrics, dict):
- nested_metrics = []
- for name in output_names:
- output_metrics = metrics.get(name, [])
- if not isinstance(output_metrics, list):
- output_metrics = [output_metrics]
- nested_metrics.append(output_metrics)
- return nested_metrics
- else:
- raise TypeError('Type of `metrics` argument not understood. '
- 'Expected a list or dictionary, found: ' + str(metrics))
-
-
-def _batch_shuffle(index_array, batch_size):
- """Shuffles an array in a batch-wise fashion.
-
- Useful for shuffling HDF5 arrays
- (where one cannot access arbitrary indices).
-
- Arguments:
- index_array: array of indices to be shuffled.
- batch_size: integer.
-
- Returns:
- The `index_array` array, shuffled in a batch-wise fashion.
- """
- batch_count = int(len(index_array) / batch_size)
- # to reshape we need to be cleanly divisible by batch size
- # we stash extra items and reappend them after shuffling
- last_batch = index_array[batch_count * batch_size:]
- index_array = index_array[:batch_count * batch_size]
- index_array = index_array.reshape((batch_count, batch_size))
- np.random.shuffle(index_array)
- index_array = index_array.flatten()
- return np.append(index_array, last_batch)
-
-
-def _make_batches(size, batch_size):
- """Returns a list of batch indices (tuples of indices).
-
- Arguments:
- size: Integer, total size of the data to slice into batches.
- batch_size: Integer, batch size.
-
- Returns:
- A list of tuples of array indices.
- """
- num_batches = int(np.ceil(size / float(batch_size)))
- return [(i * batch_size, min(size, (i + 1) * batch_size))
- for i in range(0, num_batches)]
-
-
-def _slice_arrays(arrays, start=None, stop=None):
- """Slice an array or list of arrays.
-
- This takes an array-like, or a list of
- array-likes, and outputs:
- - arrays[start:stop] if `arrays` is an array-like
- - [x[start:stop] for x in arrays] if `arrays` is a list
-
- Can also work on list/array of indices: `_slice_arrays(x, indices)`
-
- Arguments:
- arrays: Single array or list of arrays.
- start: can be an integer index (start index)
- or a list/array of indices
- stop: integer (stop index); should be None if
- `start` was a list.
-
- Returns:
- A slice of the array(s).
- """
- if arrays is None:
- return [None]
- elif isinstance(arrays, list):
- if hasattr(start, '__len__'):
- # hdf5 datasets only support list objects as indices
- if hasattr(start, 'shape'):
- start = start.tolist()
- return [None if x is None else x[start] for x in arrays]
- else:
- return [None if x is None else x[start:stop] for x in arrays]
- else:
- if hasattr(start, '__len__'):
- if hasattr(start, 'shape'):
- start = start.tolist()
- return arrays[start]
- elif hasattr(start, '__getitem__'):
- return arrays[start:stop]
- else:
- return [None]
-
-
-def _weighted_masked_objective(fn):
- """Adds support for masking and sample-weighting to an objective function.
-
- It transforms an objective function `fn(y_true, y_pred)`
- into a sample-weighted, cost-masked objective function
- `fn(y_true, y_pred, weights, mask)`.
-
- Arguments:
- fn: The objective function to wrap,
- with signature `fn(y_true, y_pred)`.
-
- Returns:
- A function with signature `fn(y_true, y_pred, weights, mask)`.
- """
- if fn is None:
- return None
-
- def weighted(y_true, y_pred, weights, mask=None):
- """Wrapper function.
-
- Arguments:
- y_true: `y_true` argument of `fn`.
- y_pred: `y_pred` argument of `fn`.
- weights: Weights tensor.
- mask: Mask tensor.
-
- Returns:
- Scalar tensor.
- """
- # score_array has ndim >= 2
- score_array = fn(y_true, y_pred)
- if mask is not None:
- # Cast the mask to floatX to avoid float64 upcasting in theano
- mask = K.cast(mask, K.floatx())
- # mask should have the same shape as score_array
- score_array *= mask
- # the loss per batch should be proportional
- # to the number of unmasked samples.
- score_array /= K.mean(mask)
-
- # apply sample weighting
- if weights is not None:
- # reduce score_array to same ndim as weight array
- ndim = K.ndim(score_array)
- weight_ndim = K.ndim(weights)
- score_array = K.mean(score_array, axis=list(range(weight_ndim, ndim)))
- score_array *= weights
- score_array /= K.mean(K.cast(K.not_equal(weights, 0), K.floatx()))
- return K.mean(score_array)
-
- return weighted
-
-
-def _standardize_weights(y,
- sample_weight=None,
- class_weight=None,
- sample_weight_mode=None):
- """Performs sample weight validation and standardization.
-
- Everything gets normalized to a single sample-wise (or timestep-wise)
- weight array.
-
- Arguments:
- y: Numpy array of model targets to be weighted.
- sample_weight: User-provided `sample_weight` argument.
- class_weight: User-provided `class_weight` argument.
- sample_weight_mode: One of `None` or `"temporal"`.
- `"temporal"` indicated that we expect 2D weight data
- that will be applied to the last 2 dimensions of
- the targets (i.e. we are weighting timesteps, not samples).
-
- Returns:
- A numpy array of target weights, one entry per sample to weight.
-
- Raises:
- ValueError: In case of invalid user-provided arguments.
- """
- if sample_weight_mode is not None:
- if sample_weight_mode != 'temporal':
- raise ValueError('"sample_weight_mode '
- 'should be None or "temporal". '
- 'Found: ' + str(sample_weight_mode))
- if len(y.shape) < 3:
- raise ValueError('Found a sample_weight array for '
- 'an input with shape ' + str(y.shape) + '. '
- 'Timestep-wise sample weighting (use of '
- 'sample_weight_mode="temporal") is restricted to '
- 'outputs that are at least 3D, i.e. that have '
- 'a time dimension.')
- if sample_weight is not None and len(sample_weight.shape) != 2:
- raise ValueError('Found a sample_weight array with shape ' +
- str(sample_weight.shape) + '. '
- 'In order to use timestep-wise sample weighting, '
- 'you should pass a 2D sample_weight array.')
- else:
- if sample_weight is not None and len(sample_weight.shape) != 1:
- raise ValueError('Found a sample_weight array with shape ' +
- str(sample_weight.shape) + '. '
- 'In order to use timestep-wise sample weights, '
- 'you should specify '
- 'sample_weight_mode="temporal" '
- 'in compile(). If you just mean to use '
- 'sample-wise weights, make sure your '
- 'sample_weight array is 1D.')
-
- if sample_weight is not None:
- if len(sample_weight.shape) > len(y.shape):
- raise ValueError('Found a sample_weight with shape' +
- str(sample_weight.shape) + '.'
- 'Expected sample_weight with rank '
- 'less than or equal to ' + str(len(y.shape)))
-
- if y.shape[:sample_weight.ndim] != sample_weight.shape:
- raise ValueError('Found a sample_weight array with shape ' +
- str(sample_weight.shape) + ' for an input with shape ' +
- str(y.shape) + '. '
- 'sample_weight cannot be broadcast.')
- return sample_weight
- elif isinstance(class_weight, dict):
- if len(y.shape) > 2:
- raise ValueError('`class_weight` not supported for '
- '3+ dimensional targets.')
- if y.shape[1] > 1:
- y_classes = y.argmax(axis=1)
- elif y.shape[1] == 1:
- y_classes = np.reshape(y, y.shape[0])
- else:
- y_classes = y
-
- weights = np.asarray(
- [class_weight[cls] for cls in y_classes if cls in class_weight])
-
- if len(weights) != len(y_classes):
- # subtract the sets to pick all missing classes
- existing_classes = set(y_classes)
- existing_class_weight = set(class_weight.keys())
- raise ValueError('`class_weight` must contain all classes in the data.'
- ' The classes %s exist in the data but not in '
- '`class_weight`.' %
- (existing_classes - existing_class_weight))
- return weights
- else:
- if sample_weight_mode is None:
- return np.ones((y.shape[0],), dtype=K.floatx())
- else:
- return np.ones((y.shape[0], y.shape[1]), dtype=K.floatx())
-
-
-class Model(Container):
- """The `Model` class adds training & evaluation routines to a `Container`.
- """
-
- def compile(self,
- optimizer,
- loss,
- metrics=None,
- loss_weights=None,
- sample_weight_mode=None,
- weighted_metrics=None,
- target_tensors=None,
- **kwargs):
- """Configures the model for training.
-
- Arguments:
- optimizer: String (name of optimizer) or optimizer object.
- See [optimizers](/optimizers).
- loss: String (name of objective function) or objective function.
- See [losses](/losses).
- If the model has multiple outputs, you can use a different loss
- on each output by passing a dictionary or a list of losses.
- The loss value that will be minimized by the model
- will then be the sum of all individual losses.
- metrics: List of metrics to be evaluated by the model
- during training and testing.
- Typically you will use `metrics=['accuracy']`.
- To specify different metrics for different outputs of a
- multi-output model, you could also pass a dictionary,
- such as `metrics={'output_a': 'accuracy'}`.
- loss_weights: Optional list or dictionary specifying scalar
- coefficients (Python floats) to weight the loss contributions
- of different model outputs.
- The loss value that will be minimized by the model
- will then be the *weighted sum* of all individual losses,
- weighted by the `loss_weights` coefficients.
- If a list, it is expected to have a 1:1 mapping
- to the model's outputs. If a tensor, it is expected to map
- output names (strings) to scalar coefficients.
- sample_weight_mode: If you need to do timestep-wise
- sample weighting (2D weights), set this to `"temporal"`.
- `None` defaults to sample-wise weights (1D).
- If the model has multiple outputs, you can use a different
- `sample_weight_mode` on each output by passing a
- dictionary or a list of modes.
- weighted_metrics: List of metrics to be evaluated and weighted
- by sample_weight or class_weight during training and testing.
- target_tensors: By default, Keras will create placeholders for the
- model's target, which will be fed with the target data during
- training. If instead you would like to use your own
- target tensors (in turn, Keras will not expect external
- Numpy data for these targets at training time), you
- can specify them via the `target_tensors` argument. It can be
- a single tensor (for a single-output model), a list of tensors,
- or a dict mapping output names to target tensors.
- **kwargs: When using the Theano/CNTK backends, these arguments
- are passed into K.function. When using the TensorFlow backend,
- these arguments are passed into `tf.Session.run`.
-
- Raises:
- ValueError: In case of invalid arguments for
- `optimizer`, `loss`, `metrics` or `sample_weight_mode`.
- """
- loss = loss or {}
- self.optimizer = optimizers.get(optimizer)
- self.sample_weight_mode = sample_weight_mode
- self.loss = loss
- self.loss_weights = loss_weights
-
- # Prepare loss functions.
- if isinstance(loss, dict):
- for name in loss:
- if name not in self.output_names:
- raise ValueError('Unknown entry in loss '
- 'dictionary: "' + name + '". '
- 'Only expected the following keys: ' +
- str(self.output_names))
- loss_functions = []
- for name in self.output_names:
- if name not in loss:
- logging.warning(
- 'Output "' + name + '" missing from loss dictionary. '
- 'We assume this was done on purpose, '
- 'and we will not be expecting '
- 'any data to be passed to "' + name + '" during training.')
- loss_functions.append(losses.get(loss.get(name)))
- elif isinstance(loss, list):
- if len(loss) != len(self.outputs):
- raise ValueError('When passing a list as loss, '
- 'it should have one entry per model outputs. '
- 'The model has ' + str(len(self.outputs)) +
- ' outputs, but you passed loss=' + str(loss))
- loss_functions = [losses.get(l) for l in loss]
- else:
- loss_function = losses.get(loss)
- loss_functions = [loss_function for _ in range(len(self.outputs))]
- self.loss_functions = loss_functions
- weighted_losses = [_weighted_masked_objective(fn) for fn in loss_functions]
- skip_target_indices = []
- skip_target_weighing_indices = []
- self._feed_outputs = []
- self._feed_output_names = []
- self._feed_output_shapes = []
- self._feed_loss_fns = []
- for i in range(len(weighted_losses)):
- if weighted_losses[i] is None:
- skip_target_indices.append(i)
- skip_target_weighing_indices.append(i)
-
- # Prepare output masks.
- masks = self.compute_mask(self.inputs, mask=None)
- if masks is None:
- masks = [None for _ in self.outputs]
- if not isinstance(masks, list):
- masks = [masks]
-
- # Prepare loss weights.
- if loss_weights is None:
- loss_weights_list = [1. for _ in range(len(self.outputs))]
- elif isinstance(loss_weights, dict):
- for name in loss_weights:
- if name not in self.output_names:
- raise ValueError('Unknown entry in loss_weights '
- 'dictionary: "' + name + '". '
- 'Only expected the following keys: ' +
- str(self.output_names))
- loss_weights_list = []
- for name in self.output_names:
- loss_weights_list.append(loss_weights.get(name, 1.))
- elif isinstance(loss_weights, list):
- if len(loss_weights) != len(self.outputs):
- raise ValueError('When passing a list as loss_weights, '
- 'it should have one entry per model outputs. '
- 'The model has ' + str(len(self.outputs)) +
- ' outputs, but you passed loss_weights=' +
- str(loss_weights))
- loss_weights_list = loss_weights
- else:
- raise TypeError('Could not interpret loss_weights argument: ' +
- str(loss_weights) + ' - expected a list of dicts.')
-
- # Prepare targets of model.
- self.targets = []
- self._feed_targets = []
- if target_tensors is not None:
- if isinstance(target_tensors, list):
- if len(target_tensors) != len(self.outputs):
- raise ValueError('When passing a list as `target_tensors`, '
- 'it should have one entry per model outputs. '
- 'The model has ' + str(len(self.outputs)) +
- ' outputs, but you passed target_tensors=' +
- str(target_tensors))
- elif isinstance(target_tensors, dict):
- for name in target_tensors:
- if name not in self.output_names:
- raise ValueError('Unknown entry in `target_tensors` '
- 'dictionary: "' + name + '". '
- 'Only expected the following keys: ' +
- str(self.output_names))
- target_tensors_ = []
- for name in self.output_names:
- target_tensors_.append(target_tensors.get(name, None))
- target_tensors = target_tensors_
- else:
- raise TypeError('Expected `target_tensors` to be '
- 'a list or dict, but got:', target_tensors)
- for i in range(len(self.outputs)):
- if i in skip_target_indices:
- self.targets.append(None)
- else:
- shape = self.internal_output_shapes[i]
- name = self.output_names[i]
- if target_tensors is not None:
- target = target_tensors[i]
- else:
- target = None
- if target is None or K.is_placeholder(target):
- if target is None:
- target = K.placeholder(
- ndim=len(shape),
- name=name + '_target',
- sparse=K.is_sparse(self.outputs[i]),
- dtype=K.dtype(self.outputs[i]))
- self._feed_targets.append(target)
- self._feed_outputs.append(self.outputs[i])
- self._feed_output_names.append(name)
- self._feed_output_shapes.append(shape)
- self._feed_loss_fns.append(self.loss_functions[i])
- else:
- skip_target_weighing_indices.append(i)
- self.targets.append(target)
-
- # Prepare sample weights.
- sample_weights = []
- sample_weight_modes = []
- if isinstance(sample_weight_mode, dict):
- for name in sample_weight_mode:
- if name not in self.output_names:
- raise ValueError('Unknown entry in '
- 'sample_weight_mode dictionary: "' + name + '". '
- 'Only expected the following keys: ' +
- str(self.output_names))
- for i, name in enumerate(self.output_names):
- if i in skip_target_weighing_indices:
- weight = None
- sample_weight_modes.append(None)
- else:
- if name not in sample_weight_mode:
- raise ValueError('Output "' + name +
- '" missing from sample_weight_modes '
- 'dictionary')
- if sample_weight_mode.get(name) == 'temporal':
- weight = K.placeholder(ndim=2, name=name + '_sample_weights')
- sample_weight_modes.append('temporal')
- else:
- weight = K.placeholder(ndim=1, name=name + '_sample_weights')
- sample_weight_modes.append(None)
- sample_weights.append(weight)
- elif isinstance(sample_weight_mode, list):
- if len(sample_weight_mode) != len(self.outputs):
- raise ValueError('When passing a list as sample_weight_mode, '
- 'it should have one entry per model outputs. '
- 'The model has ' + str(len(self.outputs)) +
- ' outputs, but you passed '
- 'sample_weight_mode=' + str(sample_weight_mode))
- for i in range(len(self.output_names)):
- if i in skip_target_weighing_indices:
- weight = None
- sample_weight_modes.append(None)
- else:
- mode = sample_weight_mode[i]
- name = self.output_names[i]
- if mode == 'temporal':
- weight = K.placeholder(ndim=2, name=name + '_sample_weights')
- sample_weight_modes.append('temporal')
- else:
- weight = K.placeholder(ndim=1, name=name + '_sample_weights')
- sample_weight_modes.append(None)
- sample_weights.append(weight)
- else:
- for i, name in enumerate(self.output_names):
- if i in skip_target_weighing_indices:
- sample_weight_modes.append(None)
- sample_weights.append(None)
- else:
- if sample_weight_mode == 'temporal':
- sample_weights.append(
- K.placeholder(ndim=2, name=name + '_sample_weights'))
- sample_weight_modes.append('temporal')
- else:
- sample_weights.append(
- K.placeholder(ndim=1, name=name + '_sample_weights'))
- sample_weight_modes.append(None)
- self.sample_weight_modes = sample_weight_modes
- self._feed_sample_weight_modes = []
- for i in range(len(self.outputs)):
- if i not in skip_target_weighing_indices:
- self._feed_sample_weight_modes.append(self.sample_weight_modes[i])
-
- # Prepare metrics.
- self.metrics = metrics
- self.weighted_metrics = weighted_metrics
- self.metrics_names = ['loss']
- self.metrics_tensors = []
-
- # Compute total loss.
- total_loss = None
- with K.name_scope('loss'):
- for i in range(len(self.outputs)):
- if i in skip_target_indices:
- continue
- y_true = self.targets[i]
- y_pred = self.outputs[i]
- weighted_loss = weighted_losses[i]
- sample_weight = sample_weights[i]
- mask = masks[i]
- loss_weight = loss_weights_list[i]
- with K.name_scope(self.output_names[i] + '_loss'):
- output_loss = weighted_loss(y_true, y_pred, sample_weight, mask)
- if len(self.outputs) > 1:
- self.metrics_tensors.append(output_loss)
- self.metrics_names.append(self.output_names[i] + '_loss')
- if total_loss is None:
- total_loss = loss_weight * output_loss
- else:
- total_loss += loss_weight * output_loss
- if total_loss is None:
- if not self.losses:
- raise ValueError('The model cannot be compiled '
- 'because it has no loss to optimize.')
- else:
- total_loss = 0.
-
- # Add regularization penalties
- # and other layer-specific losses.
- for loss_tensor in self.losses:
- total_loss += loss_tensor
-
- # List of same size as output_names.
- # contains tuples (metrics for output, names of metrics).
- nested_metrics = _collect_metrics(metrics, self.output_names)
- nested_weighted_metrics = _collect_metrics(weighted_metrics,
- self.output_names)
-
- def append_metric(layer_index, metric_name, metric_tensor):
- """Helper function used in loop below."""
- if len(self.output_names) > 1:
- metric_name = self.output_names[layer_index] + '_' + metric_name
- self.metrics_names.append(metric_name)
- self.metrics_tensors.append(metric_tensor)
-
- with K.name_scope('metrics'):
- for i in range(len(self.outputs)):
- if i in skip_target_indices:
- continue
-
- y_true = self.targets[i]
- y_pred = self.outputs[i]
- weights = sample_weights[i]
- output_metrics = nested_metrics[i]
- output_weighted_metrics = nested_weighted_metrics[i]
-
- def handle_metrics(metrics, weights=None):
- metric_name_prefix = 'weighted_' if weights is not None else ''
-
- for metric in metrics:
- if metric == 'accuracy' or metric == 'acc':
- # custom handling of accuracy
- # (because of class mode duality)
- output_shape = self.internal_output_shapes[i]
- if (output_shape[-1] == 1 or
- self.loss_functions[i] == losses.binary_crossentropy):
- # case: binary accuracy
- acc_fn = metrics_module.binary_accuracy
- elif self.loss_functions[
- i] == losses.sparse_categorical_crossentropy:
- # case: categorical accuracy with sparse targets
- acc_fn = metrics_module.sparse_categorical_accuracy
- else:
- acc_fn = metrics_module.categorical_accuracy
-
- weighted_metric_fn = _weighted_masked_objective(acc_fn)
- metric_name = metric_name_prefix + 'acc'
- else:
- metric_fn = metrics_module.get(metric)
- weighted_metric_fn = _weighted_masked_objective(metric_fn)
- metric_name = metric_name_prefix + metric_fn.__name__
-
- with K.name_scope(metric_name):
- metric_result = weighted_metric_fn(
- y_true, y_pred, weights=weights, mask=masks[i])
- append_metric(i, metric_name, metric_result)
-
- handle_metrics(output_metrics)
- handle_metrics(output_weighted_metrics, weights=weights)
-
- # Prepare gradient updates and state updates.
- self.total_loss = total_loss
- self.sample_weights = sample_weights
- self._feed_sample_weights = []
- for i in range(len(self.sample_weights)):
- if i not in skip_target_weighing_indices:
- self._feed_sample_weights.append(sample_weights[i])
-
- # Functions for train, test and predict will
- # be compiled lazily when required.
- # This saves time when the user is not using all functions.
- self._function_kwargs = kwargs
-
- self.train_function = None
- self.test_function = None
- self.predict_function = None
-
- # Collected trainable weights, sorted in topological order.
- trainable_weights = self.trainable_weights
- self._collected_trainable_weights = trainable_weights
-
- def _make_train_function(self):
- if not hasattr(self, 'train_function'):
- raise RuntimeError('You must compile your model before using it.')
- if self.train_function is None:
- inputs = (self._feed_inputs +
- self._feed_targets +
- self._feed_sample_weights)
- if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
- inputs += [K.learning_phase()]
-
- with K.name_scope('training'):
- with K.name_scope(self.optimizer.__class__.__name__):
- training_updates = self.optimizer.get_updates(
- params=self._collected_trainable_weights, loss=self.total_loss)
- updates = self.updates + training_updates
- # Gets loss and metrics. Updates weights at each call.
- self.train_function = K.function(
- inputs, [self.total_loss] + self.metrics_tensors,
- updates=updates,
- name='train_function',
- **self._function_kwargs)
-
- def _make_test_function(self):
- if not hasattr(self, 'test_function'):
- raise RuntimeError('You must compile your model before using it.')
- if self.test_function is None:
- inputs = (self._feed_inputs +
- self._feed_targets +
- self._feed_sample_weights)
- if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
- inputs += [K.learning_phase()]
- # Return loss and metrics, no gradient updates.
- # Does update the network states.
- self.test_function = K.function(
- inputs, [self.total_loss] + self.metrics_tensors,
- updates=self.state_updates,
- name='test_function',
- **self._function_kwargs)
-
- def _make_predict_function(self):
- if not hasattr(self, 'predict_function'):
- self.predict_function = None
- if self.predict_function is None:
- if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
- inputs = self._feed_inputs + [K.learning_phase()]
- else:
- inputs = self._feed_inputs
- # Gets network outputs. Does not update weights.
- # Does update the network states.
- kwargs = getattr(self, '_function_kwargs', {})
- self.predict_function = K.function(
- inputs,
- self.outputs,
- updates=self.state_updates,
- name='predict_function',
- **kwargs)
-
- def _check_num_samples(self,
- ins,
- batch_size=None,
- steps=None,
- steps_name='steps'):
- """Determine the number of samples provided for training and evaluation.
-
- The number of samples is not defined when running with `steps`,
- in which case the number of samples is set to `None`.
-
- Arguments:
- ins: List of tensors to be fed to the Keras function.
- batch_size: Integer batch size or `None` if not defined.
- steps: Total number of steps (batches of samples)
- before declaring `_predict_loop` finished.
- Ignored with the default value of `None`.
- steps_name: The public API's parameter name for `steps`.
-
- Raises:
- ValueError: when `steps` is `None` and the attribute `ins.shape`
- does not exist. Also raises ValueError when `steps` is not `None`
- and `batch_size` is not `None` because they are mutually
- exclusive.
-
- Returns:
- When steps is `None`, returns the number of samples to be
- processed based on the size of the first dimension of the
- first input numpy array. When steps is not `None` and
- `batch_size` is `None`, returns `None`.
- """
- if steps is not None:
- num_samples = None
- if batch_size is not None:
- raise ValueError('If ' + steps_name +
- ' is set, the `batch_size` must be None.')
- elif ins and hasattr(ins[0], 'shape'):
- num_samples = ins[0].shape[0]
- else:
- raise ValueError('Either the input data should have '
- 'a defined shape, or ' + steps_name +
- ' should be specified.')
- return num_samples
-
- def _fit_loop(self,
- f,
- ins,
- out_labels=None,
- batch_size=None,
- epochs=100,
- verbose=1,
- callbacks=None,
- val_f=None,
- val_ins=None,
- shuffle=True,
- callback_metrics=None,
- initial_epoch=0,
- steps_per_epoch=None,
- validation_steps=None):
- """Abstract fit function for `f(ins)`.
-
- Assume that f returns a list, labeled by out_labels.
-
- Arguments:
- f: Keras function returning a list of tensors
- ins: List of tensors to be fed to `f`
- out_labels: List of strings, display names of
- the outputs of `f`
- batch_size: Integer batch size or None if unknown.
- epochs: Number of times to iterate over the data
- verbose: Verbosity mode, 0, 1 or 2
- callbacks: List of callbacks to be called during training
- val_f: Keras function to call for validation
- val_ins: List of tensors to be fed to `val_f`
- shuffle: Whether to shuffle the data at the beginning of each epoch
- callback_metrics: List of strings, the display names of the metrics
- passed to the callbacks. They should be the
- concatenation of list the display names of the outputs of
- `f` and the list of display names of the outputs of `f_val`.
- initial_epoch: Epoch at which to start training
- (useful for resuming a previous training run)
- steps_per_epoch: Total number of steps (batches of samples)
- before declaring one epoch finished and starting the
- next epoch. Ignored with the default value of `None`.
- validation_steps: Number of steps to run validation for (only if doing
- validation from data tensors). Ignored with default value of `None`.
-
- Returns:
- `History` object.
-
- Raises:
- ValueError: In case of invalid argument values.
- """
- do_validation = False
- if val_f and val_ins:
- do_validation = True
- if (verbose and ins and
- hasattr(ins[0], 'shape') and hasattr(val_ins[0], 'shape')):
- print('Train on %d samples, validate on %d samples' %
- (ins[0].shape[0], val_ins[0].shape[0]))
- if validation_steps:
- if steps_per_epoch is None:
- raise ValueError('Can only use `validation_steps` when doing step-wise '
- 'training, i.e. `steps_per_epoch` must be set.')
- do_validation = True
-
- num_train_samples = self._check_num_samples(
- ins, batch_size, steps_per_epoch, 'steps_per_epoch')
-
- if num_train_samples is not None:
- index_array = np.arange(num_train_samples)
-
- self.history = cbks.History()
- callbacks = [cbks.BaseLogger()] + (callbacks or []) + [self.history]
- if verbose:
- if steps_per_epoch is not None:
- count_mode = 'steps'
- else:
- count_mode = 'samples'
- callbacks += [cbks.ProgbarLogger(count_mode)]
- callbacks = cbks.CallbackList(callbacks)
- out_labels = out_labels or []
-
- # it's possible to callback a different model than self
- # (used by Sequential models)
- if hasattr(self, 'callback_model') and self.callback_model:
- callback_model = self.callback_model
- else:
- callback_model = self
-
- callbacks.set_model(callback_model)
- callbacks.set_params({
- 'batch_size': batch_size,
- 'epochs': epochs,
- 'steps': steps_per_epoch,
- 'samples': num_train_samples,
- 'verbose': verbose,
- 'do_validation': do_validation,
- 'metrics': callback_metrics or [],
- })
- callbacks.on_train_begin()
- callback_model.stop_training = False
- for cbk in callbacks:
- cbk.validation_data = val_ins
-
- for epoch in range(initial_epoch, epochs):
- callbacks.on_epoch_begin(epoch)
- epoch_logs = {}
- if steps_per_epoch is not None:
- for step_index in range(steps_per_epoch):
- batch_logs = {}
- batch_logs['batch'] = step_index
- batch_logs['size'] = 1
- callbacks.on_batch_begin(step_index, batch_logs)
- outs = f(ins)
-
- if not isinstance(outs, list):
- outs = [outs]
- for l, o in zip(out_labels, outs):
- batch_logs[l] = o
-
- callbacks.on_batch_end(step_index, batch_logs)
- if callback_model.stop_training:
- break
-
- if do_validation:
- val_outs = self._test_loop(
- val_f,
- val_ins,
- batch_size=batch_size,
- steps=validation_steps,
- verbose=0)
- if not isinstance(val_outs, list):
- val_outs = [val_outs]
- # Same labels assumed.
- for l, o in zip(out_labels, val_outs):
- epoch_logs['val_' + l] = o
- else:
- if shuffle == 'batch':
- index_array = _batch_shuffle(index_array, batch_size)
- elif shuffle:
- np.random.shuffle(index_array)
-
- batches = _make_batches(num_train_samples, batch_size)
- for batch_index, (batch_start, batch_end) in enumerate(batches):
- batch_ids = index_array[batch_start:batch_end]
- try:
- if isinstance(ins[-1], float):
- # Do not slice the training phase flag.
- ins_batch = _slice_arrays(ins[:-1], batch_ids) + [ins[-1]]
- else:
- ins_batch = _slice_arrays(ins, batch_ids)
- except TypeError:
- raise TypeError('TypeError while preparing batch. '
- 'If using HDF5 input data, '
- 'pass shuffle="batch".')
- batch_logs = {}
- batch_logs['batch'] = batch_index
- batch_logs['size'] = len(batch_ids)
- callbacks.on_batch_begin(batch_index, batch_logs)
- outs = f(ins_batch)
- if not isinstance(outs, list):
- outs = [outs]
- for l, o in zip(out_labels, outs):
- batch_logs[l] = o
-
- callbacks.on_batch_end(batch_index, batch_logs)
- if callback_model.stop_training:
- break
-
- if batch_index == len(batches) - 1: # Last batch.
- if do_validation:
- val_outs = self._test_loop(
- val_f, val_ins, batch_size=batch_size, verbose=0)
- if not isinstance(val_outs, list):
- val_outs = [val_outs]
- # Same labels assumed.
- for l, o in zip(out_labels, val_outs):
- epoch_logs['val_' + l] = o
- callbacks.on_epoch_end(epoch, epoch_logs)
- if callback_model.stop_training:
- break
- callbacks.on_train_end()
- return self.history
-
- def _predict_loop(self, f, ins, batch_size=32, verbose=0, steps=None):
- """Abstract method to loop over some data in batches.
-
- Arguments:
- f: Keras function returning a list of tensors.
- ins: list of tensors to be fed to `f`.
- batch_size: integer batch size.
- verbose: verbosity mode.
- steps: Total number of steps (batches of samples)
- before declaring `_predict_loop` finished.
- Ignored with the default value of `None`.
-
- Returns:
- Array of predictions (if the model has a single output)
- or list of arrays of predictions
- (if the model has multiple outputs).
- """
- num_samples = self._check_num_samples(ins, batch_size, steps, 'steps')
- if verbose == 1:
- if steps is not None:
- progbar = Progbar(target=steps)
- else:
- progbar = Progbar(target=num_samples)
- if steps is not None:
- # Step-based predictions.
- # Since we do not know how many samples
- # we will see, we cannot pre-allocate
- # the returned Numpy arrays.
- # Instead, we store one array per batch seen
- # and concatenate them upon returning.
- unconcatenated_outs = []
- for step in range(steps):
- batch_outs = f(ins)
- if not isinstance(batch_outs, list):
- batch_outs = [batch_outs]
- if step == 0:
- for batch_out in batch_outs:
- unconcatenated_outs.append([])
- for i, batch_out in enumerate(batch_outs):
- unconcatenated_outs[i].append(batch_out)
- if verbose == 1:
- progbar.update(step)
- if len(unconcatenated_outs) == 1:
- return np.concatenate(unconcatenated_outs[0], axis=0)
- return [
- np.concatenate(unconcatenated_outs[i], axis=0)
- for i in range(len(unconcatenated_outs))
- ]
- else:
- # Sample-based predictions.
- outs = []
- batches = _make_batches(num_samples, batch_size)
- index_array = np.arange(num_samples)
- for batch_index, (batch_start, batch_end) in enumerate(batches):
- batch_ids = index_array[batch_start:batch_end]
- if ins and isinstance(ins[-1], float):
- # Do not slice the training phase flag.
- ins_batch = _slice_arrays(ins[:-1], batch_ids) + [ins[-1]]
- else:
- ins_batch = _slice_arrays(ins, batch_ids)
- batch_outs = f(ins_batch)
- if not isinstance(batch_outs, list):
- batch_outs = [batch_outs]
- if batch_index == 0:
- # Pre-allocate the results arrays.
- for batch_out in batch_outs:
- shape = (num_samples,) + batch_out.shape[1:]
- outs.append(np.zeros(shape, dtype=batch_out.dtype))
- for i, batch_out in enumerate(batch_outs):
- outs[i][batch_start:batch_end] = batch_out
- if verbose == 1:
- progbar.update(batch_end)
- if len(outs) == 1:
- return outs[0]
- return outs
-
- def _test_loop(self, f, ins, batch_size=None, verbose=0, steps=None):
- """Abstract method to loop over some data in batches.
-
- Arguments:
- f: Keras function returning a list of tensors.
- ins: list of tensors to be fed to `f`.
- batch_size: integer batch size or `None`.
- verbose: verbosity mode.
- steps: Total number of steps (batches of samples)
- before declaring predictions finished.
- Ignored with the default value of `None`.
-
- Returns:
- Scalar loss (if the model has a single output and no metrics)
- or list of scalars (if the model has multiple outputs
- and/or metrics). The attribute `model.metrics_names` will give you
- the display labels for the scalar outputs.
- """
- num_samples = self._check_num_samples(ins, batch_size, steps, 'steps')
- outs = []
- if steps is not None:
- if verbose == 1:
- progbar = Progbar(target=steps)
- for step in range(steps):
- batch_outs = f(ins)
- if isinstance(batch_outs, list):
- if step == 0:
- for _ in enumerate(batch_outs):
- outs.append(0.)
- for i, batch_out in enumerate(batch_outs):
- outs[i] += batch_out
- else:
- if step == 0:
- outs.append(0.)
- outs[0] += batch_outs
- if verbose == 1:
- progbar.update(step)
- for i in range(len(outs)):
- outs[i] /= steps
- else:
- if verbose == 1:
- progbar = Progbar(target=num_samples)
- batches = _make_batches(num_samples, batch_size)
- index_array = np.arange(num_samples)
- for batch_index, (batch_start, batch_end) in enumerate(batches):
- batch_ids = index_array[batch_start:batch_end]
- if isinstance(ins[-1], float):
- # Do not slice the training phase flag.
- ins_batch = _slice_arrays(ins[:-1], batch_ids) + [ins[-1]]
- else:
- ins_batch = _slice_arrays(ins, batch_ids)
-
- batch_outs = f(ins_batch)
- if isinstance(batch_outs, list):
- if batch_index == 0:
- for batch_out in enumerate(batch_outs):
- outs.append(0.)
- for i, batch_out in enumerate(batch_outs):
- outs[i] += batch_out * len(batch_ids)
- else:
- if batch_index == 0:
- outs.append(0.)
- outs[0] += batch_outs * len(batch_ids)
-
- if verbose == 1:
- progbar.update(batch_end)
- for i in range(len(outs)):
- outs[i] /= num_samples
- if len(outs) == 1:
- return outs[0]
- return outs
-
- def _standardize_user_data(self,
- x,
- y,
- sample_weight=None,
- class_weight=None,
- check_batch_axis=True,
- batch_size=None):
- if not hasattr(self, 'optimizer'):
- raise RuntimeError('You must compile a model before '
- 'training/testing. '
- 'Use `model.compile(optimizer, loss)`.')
-
- output_shapes = []
- for output_shape, loss_fn in zip(self._feed_output_shapes,
- self._feed_loss_fns):
- if loss_fn.__name__ == 'sparse_categorical_crossentropy':
- output_shapes.append(output_shape[:-1] + (1,))
- elif getattr(losses, loss_fn.__name__, None) is None:
- output_shapes.append(None)
- else:
- output_shapes.append(output_shape)
- x = _standardize_input_data(
- x,
- self._feed_input_names,
- self._feed_input_shapes,
- check_batch_axis=False,
- exception_prefix='input')
- y = _standardize_input_data(
- y,
- self._feed_output_names,
- output_shapes,
- check_batch_axis=False,
- exception_prefix='target')
- sample_weights = _standardize_sample_weights(sample_weight,
- self._feed_output_names)
- class_weights = _standardize_class_weights(class_weight,
- self._feed_output_names)
- sample_weights = [
- _standardize_weights(ref, sw, cw, mode)
- for (ref, sw, cw, mode) in zip(y, sample_weights, class_weights,
- self._feed_sample_weight_modes)
- ]
- _check_array_lengths(x, y, sample_weights)
- _check_loss_and_target_compatibility(y, self._feed_loss_fns,
- self._feed_output_shapes)
- if self.stateful and batch_size:
- if x[0].shape[0] % batch_size != 0:
- raise ValueError('In a stateful network, '
- 'you should only pass inputs with '
- 'a number of samples that can be '
- 'divided by the batch size. Found: ' +
- str(x[0].shape[0]) + ' samples')
- return x, y, sample_weights
-
- def _get_deduped_metrics_names(self):
- out_labels = self.metrics_names
-
- # Rename duplicated metrics name
- # (can happen with an output layer shared among multiple dataflows).
- deduped_out_labels = []
- for i, label in enumerate(out_labels):
- new_label = label
- if out_labels.count(label) > 1:
- dup_idx = out_labels[:i].count(label)
- new_label += '_' + str(dup_idx + 1)
- deduped_out_labels.append(new_label)
- return deduped_out_labels
-
- def fit(self,
- x=None,
- y=None,
- batch_size=None,
- epochs=1,
- verbose=1,
- callbacks=None,
- validation_split=0.,
- validation_data=None,
- shuffle=True,
- class_weight=None,
- sample_weight=None,
- initial_epoch=0,
- steps_per_epoch=None,
- validation_steps=None):
- """Trains the model for a fixed number of epochs (iterations on a dataset).
-
- Arguments:
- x: Numpy array of training data,
- or list of Numpy arrays if the model has multiple inputs.
- If all inputs in the model are named,
- you can also pass a dictionary
- mapping input names to Numpy arrays.
- y: Numpy array of target data,
- or list of Numpy arrays if the model has multiple outputs.
- If all outputs in the model are named,
- you can also pass a dictionary
- mapping output names to Numpy arrays.
- batch_size: Integer or `None`.
- Number of samples per gradient update.
- If unspecified, it will default to 32.
- epochs: Integer, the number of times to iterate
- over the training data arrays.
- verbose: 0, 1, or 2. Verbosity mode.
- 0 = silent, 1 = verbose, 2 = one log line per epoch.
- callbacks: List of callbacks to be called during training.
- See [callbacks](/callbacks).
- validation_split: Float between 0 and 1:
- fraction of the training data to be used as validation data.
- The model will set apart this fraction of the training data,
- will not train on it, and will evaluate
- the loss and any model metrics
- on this data at the end of each epoch.
- validation_data: Data on which to evaluate
- the loss and any model metrics
- at the end of each epoch. The model will not
- be trained on this data.
- This could be a tuple (x_val, y_val)
- or a tuple (x_val, y_val, val_sample_weights).
- shuffle: Boolean, whether to shuffle the training data
- before each epoch. Has no effect when `steps_per_epoch`
- is not `None`.
- class_weight: Optional dictionary mapping
- class indices (integers) to
- a weight (float) to apply to the model's loss for the samples
- from this class during training.
- This can be useful to tell the model to "pay more attention" to
- samples from an under-represented class.
- sample_weight: Optional array of the same length as x, containing
- weights to apply to the model's loss for each sample.
- In the case of temporal data, you can pass a 2D array
- with shape (samples, sequence_length),
- to apply a different weight to every timestep of every sample.
- In this case you should make sure to specify
- sample_weight_mode="temporal" in compile().
- initial_epoch: Epoch at which to start training
- (useful for resuming a previous training run)
- steps_per_epoch: Total number of steps (batches of samples)
- before declaring one epoch finished and starting the
- next epoch. When training with Input Tensors such as
- TensorFlow data tensors, the default `None` is equal to
- the number of unique samples in your dataset divided by
- the batch size, or 1 if that cannot be determined.
- validation_steps: Only relevant if `steps_per_epoch`
- is specified. Total number of steps (batches of samples)
- to validate before stopping.
-
- Returns:
- A `History` instance. Its `history` attribute contains
- all information collected during training.
-
- Raises:
- ValueError: In case of mismatch between the provided input data
- and what the model expects.
- """
- # Backwards compatibility
- if batch_size is None and steps_per_epoch is None:
- batch_size = 32
- if x is None and y is None and steps_per_epoch is None:
- raise ValueError('If fitting from data tensors, '
- 'you should specify the `steps_per_epoch` '
- 'argument.')
- # Validate user data.
- x, y, sample_weights = self._standardize_user_data(
- x,
- y,
- sample_weight=sample_weight,
- class_weight=class_weight,
- check_batch_axis=False,
- batch_size=batch_size)
-
- # Prepare validation data.
- do_validation = False
- val_ins = []
- if validation_data:
- do_validation = True
- if len(validation_data) == 2:
- val_x, val_y = validation_data # pylint: disable=unpacking-non-sequence
- val_sample_weight = None
- elif len(validation_data) == 3:
- val_x, val_y, val_sample_weight = validation_data # pylint: disable=unpacking-non-sequence
- else:
- raise ValueError(
- 'When passing validation_data, '
- 'it must contain 2 (x_val, y_val) '
- 'or 3 (x_val, y_val, val_sample_weights) '
- 'items, however it contains %d items' % len(validation_data))
-
- val_x, val_y, val_sample_weights = self._standardize_user_data(
- val_x,
- val_y,
- sample_weight=val_sample_weight,
- check_batch_axis=False,
- batch_size=batch_size)
- if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
- val_ins = val_x + val_y + val_sample_weights + [0.]
- else:
- val_ins = val_x + val_y + val_sample_weights
-
- elif validation_split and 0. < validation_split < 1.:
- do_validation = True
- if hasattr(x[0], 'shape'):
- split_at = int(x[0].shape[0] * (1. - validation_split))
- else:
- split_at = int(len(x[0]) * (1. - validation_split))
- x, val_x = (_slice_arrays(x, 0, split_at), _slice_arrays(x, split_at))
- y, val_y = (_slice_arrays(y, 0, split_at), _slice_arrays(y, split_at))
- sample_weights, val_sample_weights = (_slice_arrays(
- sample_weights, 0, split_at), _slice_arrays(sample_weights, split_at))
- if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
- val_ins = val_x + val_y + val_sample_weights + [0.]
- else:
- val_ins = val_x + val_y + val_sample_weights
-
- elif validation_steps:
- do_validation = True
- if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
- val_ins = [0.]
-
- # Prepare input arrays and training function.
- if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
- ins = x + y + sample_weights + [1.]
- else:
- ins = x + y + sample_weights
- self._make_train_function()
- f = self.train_function
-
- # Prepare display labels.
- out_labels = self._get_deduped_metrics_names()
-
- if do_validation:
- self._make_test_function()
- val_f = self.test_function
- callback_metrics = copy.copy(out_labels) + [
- 'val_' + n for n in out_labels
- ]
- else:
- val_f = None
- callback_metrics = copy.copy(out_labels)
-
- # Delegate logic to `_fit_loop`.
- return self._fit_loop(
- f,
- ins,
- out_labels=out_labels,
- batch_size=batch_size,
- epochs=epochs,
- verbose=verbose,
- callbacks=callbacks,
- val_f=val_f,
- val_ins=val_ins,
- shuffle=shuffle,
- callback_metrics=callback_metrics,
- initial_epoch=initial_epoch,
- steps_per_epoch=steps_per_epoch,
- validation_steps=validation_steps)
-
- def evaluate(self,
- x,
- y,
- batch_size=None,
- verbose=1,
- sample_weight=None,
- steps=None):
- """Returns the loss value & metrics values for the model in test mode.
-
- Computation is done in batches.
-
- Arguments:
- x: Numpy array of test data,
- or list of Numpy arrays if the model has multiple inputs.
- If all inputs in the model are named,
- you can also pass a dictionary
- mapping input names to Numpy arrays.
- y: Numpy array of target data,
- or list of Numpy arrays if the model has multiple outputs.
- If all outputs in the model are named,
- you can also pass a dictionary
- mapping output names to Numpy arrays.
- batch_size: Integer. If unspecified, it will default to 32.
- verbose: Verbosity mode, 0 or 1.
- sample_weight: Array of weights to weight the contribution
- of different samples to the loss and metrics.
- steps: Total number of steps (batches of samples)
- before declaring the evaluation round finished.
- Ignored with the default value of `None`.
-
- Returns:
- Scalar test loss (if the model has a single output and no metrics)
- or list of scalars (if the model has multiple outputs
- and/or metrics). The attribute `model.metrics_names` will give you
- the display labels for the scalar outputs.
-
- Raises:
- ValueError: In case of invalid argument values.
- """
- # Backwards compatibility.
- if batch_size is None and steps is None:
- batch_size = 32
- if x is None and y is None and steps is None:
- raise ValueError('If evaluating from data tensors, '
- 'you should specify the `steps` '
- 'argument.')
- # Validate user data.
- x, y, sample_weights = self._standardize_user_data(
- x,
- y,
- sample_weight=sample_weight,
- check_batch_axis=False,
- batch_size=batch_size)
- # Prepare inputs, delegate logic to `_test_loop`.
- if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
- ins = x + y + sample_weights + [0.]
- else:
- ins = x + y + sample_weights
- self._make_test_function()
- f = self.test_function
- return self._test_loop(
- f, ins, batch_size=batch_size, verbose=verbose, steps=steps)
-
- def predict(self, x, batch_size=None, verbose=0, steps=None):
- """Generates output predictions for the input samples.
-
- Computation is done in batches.
-
- Arguments:
- x: The input data, as a Numpy array
- (or list of Numpy arrays if the model has multiple outputs).
- batch_size: Integer. If unspecified, it will default to 32.
- verbose: Verbosity mode, 0 or 1.
- steps: Total number of steps (batches of samples)
- before declaring the prediction round finished.
- Ignored with the default value of `None`.
-
- Returns:
- Numpy array(s) of predictions.
-
- Raises:
- ValueError: In case of mismatch between the provided
- input data and the model's expectations,
- or in case a stateful model receives a number of samples
- that is not a multiple of the batch size.
- """
- # Backwards compatibility.
- if batch_size is None and steps is None:
- batch_size = 32
- if x is None and steps is None:
- raise ValueError('If predicting from data tensors, '
- 'you should specify the `steps` '
- 'argument.')
- # Validate user data.
- x = _standardize_input_data(
- x,
- self._feed_input_names,
- self._feed_input_shapes,
- check_batch_axis=False)
- if self.stateful:
- if x[0].shape[0] > batch_size and x[0].shape[0] % batch_size != 0:
- raise ValueError('In a stateful network, '
- 'you should only pass inputs with '
- 'a number of samples that can be '
- 'divided by the batch size. Found: ' +
- str(x[0].shape[0]) + ' samples. '
- 'Batch size: ' + str(batch_size) + '.')
-
- # Prepare inputs, delegate logic to `_predict_loop`.
- if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
- ins = x + [0.]
- else:
- ins = x
- self._make_predict_function()
- f = self.predict_function
- return self._predict_loop(
- f, ins, batch_size=batch_size, verbose=verbose, steps=steps)
-
- def train_on_batch(self, x, y, sample_weight=None, class_weight=None):
- """Runs a single gradient update on a single batch of data.
-
- Arguments:
- x: Numpy array of training data,
- or list of Numpy arrays if the model has multiple inputs.
- If all inputs in the model are named,
- you can also pass a dictionary
- mapping input names to Numpy arrays.
- y: Numpy array of target data,
- or list of Numpy arrays if the model has multiple outputs.
- If all outputs in the model are named,
- you can also pass a dictionary
- mapping output names to Numpy arrays.
- sample_weight: Optional array of the same length as x, containing
- weights to apply to the model's loss for each sample.
- In the case of temporal data, you can pass a 2D array
- with shape (samples, sequence_length),
- to apply a different weight to every timestep of every sample.
- In this case you should make sure to specify
- sample_weight_mode="temporal" in compile().
- class_weight: Optional dictionary mapping
- class indices (integers) to
- a weight (float) to apply to the model's loss for the samples
- from this class during training.
- This can be useful to tell the model to "pay more attention" to
- samples from an under-represented class.
-
- Returns:
- Scalar training loss
- (if the model has a single output and no metrics)
- or list of scalars (if the model has multiple outputs
- and/or metrics). The attribute `model.metrics_names` will give you
- the display labels for the scalar outputs.
- """
- x, y, sample_weights = self._standardize_user_data(
- x,
- y,
- sample_weight=sample_weight,
- class_weight=class_weight,
- check_batch_axis=True)
- if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
- ins = x + y + sample_weights + [1.]
- else:
- ins = x + y + sample_weights
- self._make_train_function()
- outputs = self.train_function(ins)
- if len(outputs) == 1:
- return outputs[0]
- return outputs
-
- def test_on_batch(self, x, y, sample_weight=None):
- """Test the model on a single batch of samples.
-
- Arguments:
- x: Numpy array of test data,
- or list of Numpy arrays if the model has multiple inputs.
- If all inputs in the model are named,
- you can also pass a dictionary
- mapping input names to Numpy arrays.
- y: Numpy array of target data,
- or list of Numpy arrays if the model has multiple outputs.
- If all outputs in the model are named,
- you can also pass a dictionary
- mapping output names to Numpy arrays.
- sample_weight: Optional array of the same length as x, containing
- weights to apply to the model's loss for each sample.
- In the case of temporal data, you can pass a 2D array
- with shape (samples, sequence_length),
- to apply a different weight to every timestep of every sample.
- In this case you should make sure to specify
- sample_weight_mode="temporal" in compile().
-
- Returns:
- Scalar test loss (if the model has a single output and no metrics)
- or list of scalars (if the model has multiple outputs
- and/or metrics). The attribute `model.metrics_names` will give you
- the display labels for the scalar outputs.
- """
- x, y, sample_weights = self._standardize_user_data(
- x, y, sample_weight=sample_weight, check_batch_axis=True)
- if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
- ins = x + y + sample_weights + [0.]
- else:
- ins = x + y + sample_weights
- self._make_test_function()
- outputs = self.test_function(ins)
- if len(outputs) == 1:
- return outputs[0]
- return outputs
-
- def predict_on_batch(self, x):
- """Returns predictions for a single batch of samples.
-
- Arguments:
- x: Input samples, as a Numpy array.
-
- Returns:
- Numpy array(s) of predictions.
- """
- x = _standardize_input_data(x, self._feed_input_names,
- self._feed_input_shapes)
- if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
- ins = x + [0.]
- else:
- ins = x
- self._make_predict_function()
- outputs = self.predict_function(ins)
- if len(outputs) == 1:
- return outputs[0]
- return outputs
-
- def fit_generator(self,
- generator,
- steps_per_epoch,
- epochs=1,
- verbose=1,
- callbacks=None,
- validation_data=None,
- validation_steps=None,
- class_weight=None,
- max_queue_size=10,
- workers=1,
- use_multiprocessing=False,
- shuffle=True,
- initial_epoch=0,
- **kwargs):
- """Fits the model on data yielded batch-by-batch by a Python generator.
-
- The generator is run in parallel to the model, for efficiency.
- For instance, this allows you to do real-time data augmentation
- on images on CPU in parallel to training your model on GPU.
-
- The use of `keras.utils.Sequence` guarantees the ordering
- and guarantees the single use of every input per epoch when
- using `use_multiprocessing=True`.
-
- Arguments:
- generator: A generator or an instance of Sequence (keras.utils.Sequence)
- object in order to avoid duplicate data
- when using multiprocessing.
- The output of the generator must be either
- - a tuple (inputs, targets)
- - a tuple (inputs, targets, sample_weights).
- All arrays should contain the same number of samples.
- The generator is expected to loop over its data
- indefinitely. An epoch finishes when `steps_per_epoch`
- batches have been seen by the model.
- steps_per_epoch: Total number of steps (batches of samples)
- to yield from `generator` before declaring one epoch
- finished and starting the next epoch. It should typically
- be equal to the number of unique samples if your dataset
- divided by the batch size.
- epochs: Integer, total number of iterations on the data.
- verbose: Verbosity mode, 0, 1, or 2.
- callbacks: List of callbacks to be called during training.
- validation_data: This can be either
- - a generator for the validation data
- - a tuple (inputs, targets)
- - a tuple (inputs, targets, sample_weights).
- validation_steps: Only relevant if `validation_data`
- is a generator. Total number of steps (batches of samples)
- to yield from `generator` before stopping.
- class_weight: Dictionary mapping class indices to a weight
- for the class.
- max_queue_size: Maximum size for the generator queue
- workers: Maximum number of processes to spin up
- when using process based threading
- use_multiprocessing: If True, use process based threading.
- Note that because
- this implementation relies on multiprocessing,
- you should not pass
- non picklable arguments to the generator
- as they can't be passed
- easily to children processes.
- shuffle: Whether to shuffle the data at the beginning of each
- epoch. Only used with instances of `Sequence` (
- keras.utils.Sequence).
- initial_epoch: Epoch at which to start training
- (useful for resuming a previous training run)
- **kwargs: support for legacy arguments.
-
- Returns:
- A `History` object.
-
- Example:
-
- ```python
- def generate_arrays_from_file(path):
- while 1:
- f = open(path)
- for line in f:
- # create numpy arrays of input data
- # and labels, from each line in the file
- x1, x2, y = process_line(line)
- yield ({'input_1': x1, 'input_2': x2}, {'output': y})
- f.close()
-
- model.fit_generator(generate_arrays_from_file('/my_file.txt'),
- steps_per_epoch=10000, epochs=10)
- ```
-
- Raises:
- ValueError: In case the generator yields
- data in an invalid format.
- """
- # Legacy support
- if 'max_q_size' in kwargs:
- max_queue_size = kwargs.pop('max_q_size')
- logging.warning('The argument `max_q_size` has been renamed '
- '`max_queue_size`. Update your method calls accordingly.')
- if 'pickle_safe' in kwargs:
- use_multiprocessing = kwargs.pop('pickle_safe')
- logging.warning('The argument `pickle_safe` has been renamed '
- '`use_multiprocessing`. '
- 'Update your method calls accordingly.')
- if kwargs:
- raise ValueError('Unrecognized keyword arguments: ' + str(kwargs))
-
- wait_time = 0.01 # in seconds
- epoch = initial_epoch
-
- do_validation = bool(validation_data)
- self._make_train_function()
- if do_validation:
- self._make_test_function()
-
- # python 2 has 'next', 3 has '__next__'
- # avoid any explicit version checks
- val_gen = (hasattr(validation_data, 'next') or
- hasattr(validation_data, '__next__') or
- isinstance(validation_data, Sequence))
- if val_gen and not validation_steps:
- raise ValueError('When using a generator for validation data, '
- 'you must specify a value for '
- '`validation_steps`.')
-
- # Prepare display labels.
- out_labels = self._get_deduped_metrics_names()
- callback_metrics = out_labels + ['val_' + n for n in out_labels]
-
- # prepare callbacks
- self.history = cbks.History()
- callbacks = [cbks.BaseLogger()] + (callbacks or []) + [self.history]
- if verbose:
- callbacks += [cbks.ProgbarLogger(count_mode='steps')]
- callbacks = cbks.CallbackList(callbacks)
-
- # it's possible to callback a different model than self:
- if hasattr(self, 'callback_model') and self.callback_model:
- callback_model = self.callback_model
- else:
- callback_model = self
- callbacks.set_model(callback_model)
- callbacks.set_params({
- 'epochs': epochs,
- 'steps': steps_per_epoch,
- 'verbose': verbose,
- 'do_validation': do_validation,
- 'metrics': callback_metrics,
- })
- callbacks.on_train_begin()
-
- if do_validation and not val_gen:
- if len(validation_data) == 2:
- val_x, val_y = validation_data # pylint: disable=unpacking-non-sequence
- val_sample_weight = None
- elif len(validation_data) == 3:
- val_x, val_y, val_sample_weight = validation_data # pylint: disable=unpacking-non-sequence
- else:
- raise ValueError('`validation_data` should be a tuple '
- '`(val_x, val_y, val_sample_weight)` '
- 'or `(val_x, val_y)`. Found: ' + str(validation_data))
- val_x, val_y, val_sample_weights = self._standardize_user_data(
- val_x, val_y, val_sample_weight)
- val_data = val_x + val_y + val_sample_weights
- if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
- val_data += [0.]
- for cbk in callbacks:
- cbk.validation_data = val_data
- is_sequence = isinstance(generator, Sequence)
- if not is_sequence and use_multiprocessing and workers > 1:
- logging.warning(
- logging.warning('Using a generator with `use_multiprocessing=True`'
- ' and multiple workers may duplicate your data.'
- ' Please consider using the`keras.utils.Sequence'
- ' class.'))
- enqueuer = None
-
- try:
- if is_sequence:
- enqueuer = OrderedEnqueuer(
- generator, use_multiprocessing=use_multiprocessing, shuffle=shuffle)
- else:
- enqueuer = GeneratorEnqueuer(
- generator,
- use_multiprocessing=use_multiprocessing,
- wait_time=wait_time)
- enqueuer.start(workers=workers, max_queue_size=max_queue_size)
- output_generator = enqueuer.get()
-
- callback_model.stop_training = False
- while epoch < epochs:
- callbacks.on_epoch_begin(epoch)
- steps_done = 0
- batch_index = 0
- while steps_done < steps_per_epoch:
- generator_output = next(output_generator)
-
- if not hasattr(generator_output, '__len__'):
- raise ValueError('Output of generator should be '
- 'a tuple `(x, y, sample_weight)` '
- 'or `(x, y)`. Found: ' + str(generator_output))
- if len(generator_output) == 2:
- x, y = generator_output
- sample_weight = None
- elif len(generator_output) == 3:
- x, y, sample_weight = generator_output
- else:
- raise ValueError('Output of generator should be '
- 'a tuple `(x, y, sample_weight)` '
- 'or `(x, y)`. Found: ' + str(generator_output))
- # build batch logs
- batch_logs = {}
- if isinstance(x, list):
- batch_size = x[0].shape[0]
- elif isinstance(x, dict):
- batch_size = list(x.values())[0].shape[0]
- else:
- batch_size = x.shape[0]
- batch_logs['batch'] = batch_index
- batch_logs['size'] = batch_size
- callbacks.on_batch_begin(batch_index, batch_logs)
-
- outs = self.train_on_batch(
- x, y, sample_weight=sample_weight, class_weight=class_weight)
-
- if not isinstance(outs, list):
- outs = [outs]
- for l, o in zip(out_labels, outs):
- batch_logs[l] = o
-
- callbacks.on_batch_end(batch_index, batch_logs)
-
- # Construct epoch logs.
- epoch_logs = {}
- batch_index += 1
- steps_done += 1
-
- # Epoch finished.
- if steps_done >= steps_per_epoch and do_validation:
- if val_gen:
- val_outs = self.evaluate_generator(
- validation_data,
- validation_steps,
- max_queue_size=max_queue_size,
- workers=workers,
- use_multiprocessing=use_multiprocessing)
- else:
- # No need for try/except because
- # data has already been validated.
- val_outs = self.evaluate(
- val_x,
- val_y,
- batch_size=batch_size,
- sample_weight=val_sample_weights,
- verbose=0)
- if not isinstance(val_outs, list):
- val_outs = [val_outs]
- # Same labels assumed.
- for l, o in zip(out_labels, val_outs):
- epoch_logs['val_' + l] = o
-
- if callback_model.stop_training:
- break
-
- callbacks.on_epoch_end(epoch, epoch_logs)
- epoch += 1
- if callback_model.stop_training:
- break
-
- finally:
- if enqueuer is not None:
- enqueuer.stop()
-
- callbacks.on_train_end()
- return self.history
-
- def evaluate_generator(self,
- generator,
- steps,
- max_queue_size=10,
- workers=1,
- use_multiprocessing=False,
- **kwargs):
- """Evaluates the model on a data generator.
-
- The generator should return the same kind of data
- as accepted by `test_on_batch`.
-
- Arguments:
- generator: Generator yielding tuples (inputs, targets)
- or (inputs, targets, sample_weights)
- or an instance of Sequence (keras.utils.Sequence)
- object in order to avoid duplicate data
- when using multiprocessing.
- steps: Total number of steps (batches of samples)
- to yield from `generator` before stopping.
- max_queue_size: maximum size for the generator queue
- workers: maximum number of processes to spin up
- when using process based threading
- use_multiprocessing: if True, use process based threading.
- Note that because
- this implementation relies on multiprocessing,
- you should not pass
- non picklable arguments to the generator
- as they can't be passed
- easily to children processes.
- **kwargs: support for legacy arguments.
-
- Returns:
- Scalar test loss (if the model has a single output and no metrics)
- or list of scalars (if the model has multiple outputs
- and/or metrics). The attribute `model.metrics_names` will give you
- the display labels for the scalar outputs.
-
- Raises:
- ValueError: In case the generator yields
- data in an invalid format.
- """
- # Legacy support
- if 'max_q_size' in kwargs:
- max_queue_size = kwargs.pop('max_q_size')
- logging.warning('The argument `max_q_size` has been renamed '
- '`max_queue_size`. Update your method calls accordingly.')
- if 'pickle_safe' in kwargs:
- use_multiprocessing = kwargs.pop('pickle_safe')
- logging.warning('The argument `pickle_safe` has been renamed '
- '`use_multiprocessing`. '
- 'Update your method calls accordingly.')
- if kwargs:
- raise ValueError('Unrecognized keyword arguments: ' + str(kwargs))
-
- self._make_test_function()
-
- steps_done = 0
- wait_time = 0.01
- all_outs = []
- batch_sizes = []
- is_sequence = isinstance(generator, Sequence)
- if not is_sequence and use_multiprocessing and workers > 1:
- logging.warning(
- logging.warning('Using a generator with `use_multiprocessing=True`'
- ' and multiple workers may duplicate your data.'
- ' Please consider using the`keras.utils.Sequence'
- ' class.'))
- enqueuer = None
-
- try:
- if is_sequence:
- enqueuer = OrderedEnqueuer(
- generator, use_multiprocessing=use_multiprocessing)
- else:
- enqueuer = GeneratorEnqueuer(
- generator,
- use_multiprocessing=use_multiprocessing,
- wait_time=wait_time)
- enqueuer.start(workers=workers, max_queue_size=max_queue_size)
- output_generator = enqueuer.get()
-
- while steps_done < steps:
- generator_output = next(output_generator)
- if not hasattr(generator_output, '__len__'):
- raise ValueError('Output of generator should be a tuple '
- '(x, y, sample_weight) '
- 'or (x, y). Found: ' + str(generator_output))
- if len(generator_output) == 2:
- x, y = generator_output
- sample_weight = None
- elif len(generator_output) == 3:
- x, y, sample_weight = generator_output
- else:
- raise ValueError('Output of generator should be a tuple '
- '(x, y, sample_weight) '
- 'or (x, y). Found: ' + str(generator_output))
- outs = self.test_on_batch(x, y, sample_weight=sample_weight)
-
- if isinstance(x, list):
- batch_size = len(x[0])
- elif isinstance(x, dict):
- batch_size = len(list(x.values())[0])
- else:
- batch_size = len(x)
- if batch_size == 0:
- raise ValueError('Received an empty batch. '
- 'Batches should at least contain one item.')
- all_outs.append(outs)
-
- steps_done += 1
- batch_sizes.append(batch_size)
-
- finally:
- if enqueuer is not None:
- enqueuer.stop()
-
- if not isinstance(outs, list):
- return np.average(np.asarray(all_outs), weights=batch_sizes)
- else:
- averages = []
- for i in range(len(outs)):
- averages.append(
- np.average([out[i] for out in all_outs], weights=batch_sizes))
- return averages
-
- def predict_generator(self,
- generator,
- steps,
- max_queue_size=10,
- workers=1,
- use_multiprocessing=False,
- verbose=0,
- **kwargs):
- """Generates predictions for the input samples from a data generator.
-
- The generator should return the same kind of data as accepted by
- `predict_on_batch`.
-
- Arguments:
- generator: Generator yielding batches of input samples
- or an instance of Sequence (keras.utils.Sequence)
- object in order to avoid duplicate data
- when using multiprocessing.
- steps: Total number of steps (batches of samples)
- to yield from `generator` before stopping.
- max_queue_size: Maximum size for the generator queue.
- workers: Maximum number of processes to spin up
- when using process based threading
- use_multiprocessing: If `True`, use process based threading.
- Note that because
- this implementation relies on multiprocessing,
- you should not pass
- non picklable arguments to the generator
- as they can't be passed
- easily to children processes.
- verbose: verbosity mode, 0 or 1.
- **kwargs: support for legacy arguments.
-
- Returns:
- Numpy array(s) of predictions.
-
- Raises:
- ValueError: In case the generator yields
- data in an invalid format.
- """
- # Legacy support
- if 'max_q_size' in kwargs:
- max_queue_size = kwargs.pop('max_q_size')
- logging.warning('The argument `max_q_size` has been renamed '
- '`max_queue_size`. Update your method calls accordingly.')
- if 'pickle_safe' in kwargs:
- use_multiprocessing = kwargs.pop('pickle_safe')
- logging.warning('The argument `pickle_safe` has been renamed '
- '`use_multiprocessing`. '
- 'Update your method calls accordingly.')
-
- self._make_predict_function()
-
- steps_done = 0
- wait_time = 0.01
- all_outs = []
- is_sequence = isinstance(generator, Sequence)
- if not is_sequence and use_multiprocessing and workers > 1:
- logging.warning(
- logging.warning('Using a generator with `use_multiprocessing=True`'
- ' and multiple workers may duplicate your data.'
- ' Please consider using the`keras.utils.Sequence'
- ' class.'))
- enqueuer = None
-
- try:
- if is_sequence:
- enqueuer = OrderedEnqueuer(
- generator, use_multiprocessing=use_multiprocessing)
- else:
- enqueuer = GeneratorEnqueuer(
- generator,
- use_multiprocessing=use_multiprocessing,
- wait_time=wait_time)
- enqueuer.start(workers=workers, max_queue_size=max_queue_size)
- output_generator = enqueuer.get()
-
- if verbose == 1:
- progbar = Progbar(target=steps)
-
- while steps_done < steps:
- generator_output = next(output_generator)
- if isinstance(generator_output, tuple):
- # Compatibility with the generators
- # used for training.
- if len(generator_output) == 2:
- x, _ = generator_output
- elif len(generator_output) == 3:
- x, _, _ = generator_output
- else:
- raise ValueError('Output of generator should be '
- 'a tuple `(x, y, sample_weight)` '
- 'or `(x, y)`. Found: ' + str(generator_output))
- else:
- # Assumes a generator that only
- # yields inputs (not targets and sample weights).
- x = generator_output
-
- outs = self.predict_on_batch(x)
- if not isinstance(outs, list):
- outs = [outs]
-
- if not all_outs:
- for out in outs:
- all_outs.append([])
-
- for i, out in enumerate(outs):
- all_outs[i].append(out)
- steps_done += 1
- if verbose == 1:
- progbar.update(steps_done)
-
- finally:
- if enqueuer is not None:
- enqueuer.stop()
-
- if len(all_outs) == 1:
- if steps_done == 1:
- return all_outs[0][0]
- else:
- return np.concatenate(all_outs[0])
- if steps_done == 1:
- return [out for out in all_outs]
- else:
- return [np.concatenate(out) for out in all_outs]
diff --git a/tensorflow/contrib/keras/python/keras/engine/training_test.py b/tensorflow/contrib/keras/python/keras/engine/training_test.py
deleted file mode 100644
index 30cdba96e4..0000000000
--- a/tensorflow/contrib/keras/python/keras/engine/training_test.py
+++ /dev/null
@@ -1,1423 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for training routines."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.contrib.keras.python.keras.engine.training import _weighted_masked_objective
-from tensorflow.python.platform import test
-
-
-class TrainingTest(test.TestCase):
-
- def test_fit_on_arrays(self):
- with self.test_session():
- a = keras.layers.Input(shape=(3,), name='input_a')
- b = keras.layers.Input(shape=(3,), name='input_b')
-
- dense = keras.layers.Dense(4, name='dense')
- c = dense(a)
- d = dense(b)
- e = keras.layers.Dropout(0.5, name='dropout')(c)
-
- model = keras.models.Model([a, b], [d, e])
-
- optimizer = 'rmsprop'
- loss = 'mse'
- loss_weights = [1., 0.5]
- metrics = ['mae']
- model.compile(optimizer, loss, metrics=metrics, loss_weights=loss_weights)
-
- input_a_np = np.random.random((10, 3))
- input_b_np = np.random.random((10, 3))
-
- output_d_np = np.random.random((10, 4))
- output_e_np = np.random.random((10, 4))
-
- # Test fit at different verbosity
- model.fit(
- [input_a_np, input_b_np], [output_d_np, output_e_np],
- epochs=1,
- batch_size=5,
- verbose=0)
- model.fit(
- [input_a_np, input_b_np], [output_d_np, output_e_np],
- epochs=1,
- batch_size=5,
- verbose=1)
- model.fit(
- [input_a_np, input_b_np], [output_d_np, output_e_np],
- epochs=2,
- batch_size=5,
- verbose=2)
- model.train_on_batch([input_a_np, input_b_np], [output_d_np, output_e_np])
-
- # Test with validation data
- model.fit(
- [input_a_np, input_b_np], [output_d_np, output_e_np],
- validation_data=([input_a_np, input_b_np], [output_d_np,
- output_e_np]),
- epochs=1,
- batch_size=5,
- verbose=0)
- model.fit(
- [input_a_np, input_b_np], [output_d_np, output_e_np],
- validation_data=([input_a_np, input_b_np], [output_d_np,
- output_e_np]),
- epochs=2,
- batch_size=5,
- verbose=1)
- model.fit(
- [input_a_np, input_b_np], [output_d_np, output_e_np],
- validation_data=([input_a_np, input_b_np], [output_d_np,
- output_e_np]),
- epochs=2,
- batch_size=5,
- verbose=2)
- # Test with validation split
- model.fit(
- [input_a_np, input_b_np], [output_d_np, output_e_np],
- epochs=2,
- batch_size=5,
- verbose=0,
- validation_split=0.2)
-
- # Test with dictionary inputs
- model.fit(
- {
- 'input_a': input_a_np,
- 'input_b': input_b_np
- }, {'dense': output_d_np,
- 'dropout': output_e_np},
- epochs=1,
- batch_size=5,
- verbose=0)
- model.fit(
- {
- 'input_a': input_a_np,
- 'input_b': input_b_np
- }, {'dense': output_d_np,
- 'dropout': output_e_np},
- epochs=1,
- batch_size=5,
- verbose=1)
- model.fit(
- {
- 'input_a': input_a_np,
- 'input_b': input_b_np
- }, {'dense': output_d_np,
- 'dropout': output_e_np},
- validation_data=({
- 'input_a': input_a_np,
- 'input_b': input_b_np
- }, {
- 'dense': output_d_np,
- 'dropout': output_e_np
- }),
- epochs=1,
- batch_size=5,
- verbose=0)
- model.train_on_batch({
- 'input_a': input_a_np,
- 'input_b': input_b_np
- }, {'dense': output_d_np,
- 'dropout': output_e_np})
-
- # Test with lists for loss, metrics
- loss = ['mae', 'mse']
- metrics = ['acc', 'mae']
- model.compile(optimizer, loss, metrics=metrics)
- model.fit(
- [input_a_np, input_b_np], [output_d_np, output_e_np],
- epochs=1,
- batch_size=5,
- verbose=0)
-
- # Test with dictionaries for loss, metrics, loss weights
- loss = {'dense': 'mse', 'dropout': 'mae'}
- loss_weights = {'dense': 1., 'dropout': 0.5}
- metrics = {'dense': 'mse', 'dropout': 'mae'}
- model.compile(optimizer, loss, metrics=metrics, loss_weights=loss_weights)
- model.fit(
- [input_a_np, input_b_np], [output_d_np, output_e_np],
- epochs=1,
- batch_size=5,
- verbose=0)
-
- # Invalid use cases
- with self.assertRaises(ValueError):
- model.train_on_batch({'input_a': input_a_np},
- [output_d_np, output_e_np])
- with self.assertRaises(TypeError):
- model.fit(
- [input_a_np, input_b_np], [output_d_np, output_e_np],
- epochs=1,
- validation_data=([input_a_np, input_b_np], 0, 0),
- verbose=0)
- with self.assertRaises(ValueError):
- model.train_on_batch([input_a_np], [output_d_np, output_e_np])
- with self.assertRaises(TypeError):
- model.train_on_batch(1, [output_d_np, output_e_np])
- with self.assertRaises(ValueError):
- model.train_on_batch(input_a_np, [output_d_np, output_e_np])
- with self.assertRaises(ValueError):
- bad_input = np.random.random((11, 3))
- model.train_on_batch([bad_input, input_b_np],
- [output_d_np, output_e_np])
- with self.assertRaises(ValueError):
- bad_target = np.random.random((11, 4))
- model.train_on_batch([input_a_np, input_b_np],
- [bad_target, output_e_np])
-
- # Build single-input model
- x = keras.layers.Input(shape=(3,), name='input_a')
- y = keras.layers.Dense(4)(x)
- model = keras.models.Model(x, y)
- model.compile(optimizer='rmsprop', loss='mse')
- # This will work
- model.fit([input_a_np], output_d_np, epochs=1)
- with self.assertRaises(ValueError):
- model.fit([input_a_np, input_a_np], output_d_np, epochs=1)
-
- def test_evaluate_predict_on_arrays(self):
- with self.test_session():
- a = keras.layers.Input(shape=(3,), name='input_a')
- b = keras.layers.Input(shape=(3,), name='input_b')
-
- dense = keras.layers.Dense(4, name='dense')
- c = dense(a)
- d = dense(b)
- e = keras.layers.Dropout(0.5, name='dropout')(c)
-
- model = keras.models.Model([a, b], [d, e])
-
- optimizer = 'rmsprop'
- loss = 'mse'
- loss_weights = [1., 0.5]
- metrics = ['mae']
- model.compile(
- optimizer,
- loss,
- metrics=metrics,
- loss_weights=loss_weights,
- sample_weight_mode=None)
-
- input_a_np = np.random.random((10, 3))
- input_b_np = np.random.random((10, 3))
-
- output_d_np = np.random.random((10, 4))
- output_e_np = np.random.random((10, 4))
-
- # Test evaluate at different verbosity
- out = model.evaluate(
- [input_a_np, input_b_np], [output_d_np, output_e_np],
- batch_size=5,
- verbose=0)
- self.assertEqual(len(out), 5)
- out = model.evaluate(
- [input_a_np, input_b_np], [output_d_np, output_e_np],
- batch_size=5,
- verbose=1)
- self.assertEqual(len(out), 5)
- out = model.evaluate(
- [input_a_np, input_b_np], [output_d_np, output_e_np],
- batch_size=5,
- verbose=2)
- self.assertEqual(len(out), 5)
- out = model.test_on_batch([input_a_np, input_b_np],
- [output_d_np, output_e_np])
- self.assertEqual(len(out), 5)
-
- # Test evaluate with dictionary inputs
- model.evaluate(
- {
- 'input_a': input_a_np,
- 'input_b': input_b_np
- }, {'dense': output_d_np,
- 'dropout': output_e_np},
- batch_size=5,
- verbose=0)
- model.evaluate(
- {
- 'input_a': input_a_np,
- 'input_b': input_b_np
- }, {'dense': output_d_np,
- 'dropout': output_e_np},
- batch_size=5,
- verbose=1)
-
- # Test predict
- out = model.predict([input_a_np, input_b_np], batch_size=5)
- self.assertEqual(len(out), 2)
- out = model.predict({'input_a': input_a_np, 'input_b': input_b_np})
- self.assertEqual(len(out), 2)
- out = model.predict_on_batch({
- 'input_a': input_a_np,
- 'input_b': input_b_np
- })
- self.assertEqual(len(out), 2)
-
- def test_invalid_loss_or_metrics(self):
- num_classes = 5
- train_samples = 1000
- test_samples = 1000
- input_dim = 5
-
- with self.test_session():
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(10, input_shape=(input_dim,)))
- model.add(keras.layers.Activation('relu'))
- model.add(keras.layers.Dense(num_classes))
- model.add(keras.layers.Activation('softmax'))
- model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
- np.random.seed(1337)
- (x_train, y_train), (_, _) = testing_utils.get_test_data(
- train_samples=train_samples,
- test_samples=test_samples,
- input_shape=(input_dim,),
- num_classes=num_classes)
- with self.assertRaises(ValueError):
- model.fit(x_train, y_train)
-
- with self.assertRaises(ValueError):
- model.fit(x_train, np.concatenate([y_train, y_train], axis=-1))
-
- with self.assertRaises(TypeError):
- model.compile(loss='categorical_crossentropy',
- optimizer='rmsprop',
- metrics=set(0))
-
- with self.assertRaises(ValueError):
- model.compile(loss=None,
- optimizer='rmsprop')
-
-
-class LossWeightingTest(test.TestCase):
-
- def test_class_weights(self):
- num_classes = 5
- batch_size = 5
- epochs = 5
- weighted_class = 3
- train_samples = 1000
- test_samples = 1000
- input_dim = 5
-
- with self.test_session():
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(10, input_shape=(input_dim,)))
- model.add(keras.layers.Activation('relu'))
- model.add(keras.layers.Dense(num_classes))
- model.add(keras.layers.Activation('softmax'))
- model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
-
- np.random.seed(1337)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=train_samples,
- test_samples=test_samples,
- input_shape=(input_dim,),
- num_classes=num_classes)
- int_y_test = y_test.copy()
- int_y_train = y_train.copy()
- # convert class vectors to binary class matrices
- y_train = keras.utils.to_categorical(y_train, num_classes)
- y_test = keras.utils.to_categorical(y_test, num_classes)
- test_ids = np.where(int_y_test == np.array(weighted_class))[0]
-
- class_weight = dict([(i, 1.) for i in range(num_classes)])
- class_weight[weighted_class] = 2.
-
- sample_weight = np.ones((y_train.shape[0]))
- sample_weight[int_y_train == weighted_class] = 2.
-
- model.fit(
- x_train,
- y_train,
- batch_size=batch_size,
- epochs=epochs // 3,
- verbose=0,
- class_weight=class_weight,
- validation_data=(x_train, y_train, sample_weight))
- model.fit(
- x_train,
- y_train,
- batch_size=batch_size,
- epochs=epochs // 2,
- verbose=0,
- class_weight=class_weight)
- model.fit(
- x_train,
- y_train,
- batch_size=batch_size,
- epochs=epochs // 2,
- verbose=0,
- class_weight=class_weight,
- validation_split=0.1)
-
- model.train_on_batch(
- x_train[:batch_size], y_train[:batch_size], class_weight=class_weight)
- ref_score = model.evaluate(x_test, y_test, verbose=0)
- score = model.evaluate(
- x_test[test_ids, :], y_test[test_ids, :], verbose=0)
- self.assertLess(score, ref_score)
-
- def test_sample_weights(self):
- num_classes = 5
- batch_size = 5
- epochs = 5
- weighted_class = 3
- train_samples = 1000
- test_samples = 1000
- input_dim = 5
-
- with self.test_session():
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(10, input_shape=(input_dim,)))
- model.add(keras.layers.Activation('relu'))
- model.add(keras.layers.Dense(num_classes))
- model.add(keras.layers.Activation('softmax'))
- model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
-
- np.random.seed(1337)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=train_samples,
- test_samples=test_samples,
- input_shape=(input_dim,),
- num_classes=num_classes)
- int_y_test = y_test.copy()
- int_y_train = y_train.copy()
- # convert class vectors to binary class matrices
- y_train = keras.utils.to_categorical(y_train, num_classes)
- y_test = keras.utils.to_categorical(y_test, num_classes)
- test_ids = np.where(int_y_test == np.array(weighted_class))[0]
-
- class_weight = dict([(i, 1.) for i in range(num_classes)])
- class_weight[weighted_class] = 2.
-
- sample_weight = np.ones((y_train.shape[0]))
- sample_weight[int_y_train == weighted_class] = 2.
-
- model.fit(
- x_train,
- y_train,
- batch_size=batch_size,
- epochs=epochs // 3,
- verbose=0,
- sample_weight=sample_weight)
- model.fit(
- x_train,
- y_train,
- batch_size=batch_size,
- epochs=epochs // 3,
- verbose=0,
- sample_weight=sample_weight,
- validation_split=0.1)
-
- model.train_on_batch(
- x_train[:batch_size],
- y_train[:batch_size],
- sample_weight=sample_weight[:batch_size])
- model.test_on_batch(
- x_train[:batch_size],
- y_train[:batch_size],
- sample_weight=sample_weight[:batch_size])
- ref_score = model.evaluate(x_test, y_test, verbose=0)
- score = model.evaluate(
- x_test[test_ids, :], y_test[test_ids, :], verbose=0)
- self.assertLess(score, ref_score)
-
- def test_temporal_sample_weights(self):
- num_classes = 5
- batch_size = 5
- epochs = 5
- weighted_class = 3
- train_samples = 1000
- test_samples = 1000
- input_dim = 5
- timesteps = 3
-
- with self.test_session():
- model = keras.models.Sequential()
- model.add(
- keras.layers.TimeDistributed(
- keras.layers.Dense(num_classes),
- input_shape=(timesteps, input_dim)))
- model.add(keras.layers.Activation('softmax'))
-
- np.random.seed(1337)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=train_samples,
- test_samples=test_samples,
- input_shape=(input_dim,),
- num_classes=num_classes)
- int_y_test = y_test.copy()
- int_y_train = y_train.copy()
- # convert class vectors to binary class matrices
- y_train = keras.utils.to_categorical(y_train, num_classes)
- y_test = keras.utils.to_categorical(y_test, num_classes)
- test_ids = np.where(int_y_test == np.array(weighted_class))[0]
-
- class_weight = dict([(i, 1.) for i in range(num_classes)])
- class_weight[weighted_class] = 2.
-
- sample_weight = np.ones((y_train.shape[0]))
- sample_weight[int_y_train == weighted_class] = 2.
-
- temporal_x_train = np.reshape(x_train, (len(x_train), 1,
- x_train.shape[1]))
- temporal_x_train = np.repeat(temporal_x_train, timesteps, axis=1)
- temporal_x_test = np.reshape(x_test, (len(x_test), 1, x_test.shape[1]))
- temporal_x_test = np.repeat(temporal_x_test, timesteps, axis=1)
-
- temporal_y_train = np.reshape(y_train, (len(y_train), 1,
- y_train.shape[1]))
- temporal_y_train = np.repeat(temporal_y_train, timesteps, axis=1)
- temporal_y_test = np.reshape(y_test, (len(y_test), 1, y_test.shape[1]))
- temporal_y_test = np.repeat(temporal_y_test, timesteps, axis=1)
-
- temporal_sample_weight = np.reshape(sample_weight, (len(sample_weight),
- 1))
- temporal_sample_weight = np.repeat(
- temporal_sample_weight, timesteps, axis=1)
-
- model.compile(
- loss='binary_crossentropy',
- optimizer='rmsprop',
- sample_weight_mode='temporal')
-
- model.fit(
- temporal_x_train,
- temporal_y_train,
- batch_size=batch_size,
- epochs=epochs // 3,
- verbose=0,
- sample_weight=temporal_sample_weight)
- model.fit(
- temporal_x_train,
- temporal_y_train,
- batch_size=batch_size,
- epochs=epochs // 3,
- verbose=0,
- sample_weight=temporal_sample_weight,
- validation_split=0.1)
-
- model.train_on_batch(
- temporal_x_train[:batch_size],
- temporal_y_train[:batch_size],
- sample_weight=temporal_sample_weight[:batch_size])
- model.test_on_batch(
- temporal_x_train[:batch_size],
- temporal_y_train[:batch_size],
- sample_weight=temporal_sample_weight[:batch_size])
- ref_score = model.evaluate(temporal_x_test, temporal_y_test, verbose=0)
- score = model.evaluate(
- temporal_x_test[test_ids], temporal_y_test[test_ids], verbose=0)
- self.assertLess(score, ref_score)
-
- def test_class_weight_invalid_use_case(self):
- num_classes = 5
- train_samples = 1000
- test_samples = 1000
- input_dim = 5
- timesteps = 3
-
- with self.test_session():
- model = keras.models.Sequential()
- model.add(
- keras.layers.TimeDistributed(
- keras.layers.Dense(num_classes),
- input_shape=(timesteps, input_dim)))
- model.add(keras.layers.Activation('softmax'))
- model.compile(
- loss='binary_crossentropy',
- optimizer='rmsprop')
-
- (x_train, y_train), _ = testing_utils.get_test_data(
- train_samples=train_samples,
- test_samples=test_samples,
- input_shape=(input_dim,),
- num_classes=num_classes)
- # convert class vectors to binary class matrices
- y_train = keras.utils.to_categorical(y_train, num_classes)
- class_weight = dict([(i, 1.) for i in range(num_classes)])
-
- del class_weight[1]
- with self.assertRaises(ValueError):
- model.fit(x_train, y_train,
- epochs=0, verbose=0, class_weight=class_weight)
-
- with self.assertRaises(ValueError):
- model.compile(
- loss='binary_crossentropy',
- optimizer='rmsprop',
- sample_weight_mode=[])
-
- # Build multi-output model
- x = keras.Input((3,))
- y1 = keras.layers.Dense(4, name='1')(x)
- y2 = keras.layers.Dense(4, name='2')(x)
- model = keras.models.Model(x, [y1, y2])
- model.compile(optimizer='rmsprop', loss='mse')
- x_np = np.random.random((10, 3))
- y_np = np.random.random((10, 4))
- w_np = np.random.random((10,))
- # This will work
- model.fit(x_np, [y_np, y_np], epochs=1,
- sample_weight={'1': w_np})
- # These will not
- with self.assertRaises(ValueError):
- model.fit(x_np, [y_np, y_np], epochs=1,
- sample_weight=[w_np])
- with self.assertRaises(TypeError):
- model.fit(x_np, [y_np, y_np], epochs=1,
- sample_weight=w_np)
- with self.assertRaises(ValueError):
- bad_w_np = np.random.random((11,))
- model.fit(x_np, [y_np, y_np], epochs=1,
- sample_weight={'1': bad_w_np})
- with self.assertRaises(ValueError):
- bad_w_np = np.random.random((10, 2))
- model.fit(x_np, [y_np, y_np], epochs=1,
- sample_weight={'1': bad_w_np})
- with self.assertRaises(ValueError):
- bad_w_np = np.random.random((10, 2, 2))
- model.fit(x_np, [y_np, y_np], epochs=1,
- sample_weight={'1': bad_w_np})
-
-
-class LossMaskingTest(test.TestCase):
-
- def test_masking(self):
- with self.test_session():
- np.random.seed(1337)
- x = np.array([[[1], [1]], [[0], [0]]])
- model = keras.models.Sequential()
- model.add(keras.layers.Masking(mask_value=0, input_shape=(2, 1)))
- model.add(
- keras.layers.TimeDistributed(
- keras.layers.Dense(1, kernel_initializer='one')))
- model.compile(loss='mse', optimizer='sgd')
- y = np.array([[[1], [1]], [[1], [1]]])
- loss = model.train_on_batch(x, y)
- self.assertEqual(loss, 0)
-
- def test_loss_masking(self):
- with self.test_session():
- weighted_loss = _weighted_masked_objective(keras.losses.get('mae'))
- shape = (3, 4, 2)
- x = np.arange(24).reshape(shape)
- y = 2 * x
-
- # Normally the trailing 1 is added by standardize_weights
- weights = np.ones((3,))
- mask = np.ones((3, 4))
- mask[1, 0] = 0
-
- keras.backend.eval(
- weighted_loss(
- keras.backend.variable(x),
- keras.backend.variable(y),
- keras.backend.variable(weights), keras.backend.variable(mask)))
-
-
-class TestDynamicTrainability(test.TestCase):
-
- def test_trainable_argument(self):
- with self.test_session():
- x = np.random.random((5, 3))
- y = np.random.random((5, 2))
-
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(2, input_dim=3, trainable=False))
- model.compile('rmsprop', 'mse')
- out = model.predict(x)
- model.train_on_batch(x, y)
- out_2 = model.predict(x)
- self.assertAllClose(out, out_2)
-
- # test with nesting
- inputs = keras.layers.Input(shape=(3,))
- output = model(inputs)
- model = keras.models.Model(inputs, output)
- model.compile('rmsprop', 'mse')
- out = model.predict(x)
- model.train_on_batch(x, y)
- out_2 = model.predict(x)
- self.assertAllClose(out, out_2)
-
- def test_layer_trainability_switch(self):
- with self.test_session():
- # with constructor argument, in Sequential
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(2, trainable=False, input_dim=1))
- self.assertListEqual(model.trainable_weights, [])
-
- # by setting the `trainable` argument, in Sequential
- model = keras.models.Sequential()
- layer = keras.layers.Dense(2, input_dim=1)
- model.add(layer)
- self.assertListEqual(model.trainable_weights, layer.trainable_weights)
- layer.trainable = False
- self.assertListEqual(model.trainable_weights, [])
-
- # with constructor argument, in Model
- x = keras.layers.Input(shape=(1,))
- y = keras.layers.Dense(2, trainable=False)(x)
- model = keras.models.Model(x, y)
- self.assertListEqual(model.trainable_weights, [])
-
- # by setting the `trainable` argument, in Model
- x = keras.layers.Input(shape=(1,))
- layer = keras.layers.Dense(2)
- y = layer(x)
- model = keras.models.Model(x, y)
- self.assertListEqual(model.trainable_weights, layer.trainable_weights)
- layer.trainable = False
- self.assertListEqual(model.trainable_weights, [])
-
- def test_model_trainability_switch(self):
- with self.test_session():
- # a non-trainable model has no trainable weights
- x = keras.layers.Input(shape=(1,))
- y = keras.layers.Dense(2)(x)
- model = keras.models.Model(x, y)
- model.trainable = False
- self.assertListEqual(model.trainable_weights, [])
-
- # same for Sequential
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(2, input_dim=1))
- model.trainable = False
- self.assertListEqual(model.trainable_weights, [])
-
- def test_nested_model_trainability(self):
- with self.test_session():
- # a Sequential inside a Model
- inner_model = keras.models.Sequential()
- inner_model.add(keras.layers.Dense(2, input_dim=1))
-
- x = keras.layers.Input(shape=(1,))
- y = inner_model(x)
- outer_model = keras.models.Model(x, y)
- self.assertListEqual(outer_model.trainable_weights,
- inner_model.trainable_weights)
- inner_model.trainable = False
- self.assertListEqual(outer_model.trainable_weights, [])
- inner_model.trainable = True
- inner_model.layers[-1].trainable = False
- self.assertListEqual(outer_model.trainable_weights, [])
-
- # a Sequential inside a Sequential
- inner_model = keras.models.Sequential()
- inner_model.add(keras.layers.Dense(2, input_dim=1))
- outer_model = keras.models.Sequential()
- outer_model.add(inner_model)
- self.assertListEqual(outer_model.trainable_weights,
- inner_model.trainable_weights)
- inner_model.trainable = False
- self.assertListEqual(outer_model.trainable_weights, [])
- inner_model.trainable = True
- inner_model.layers[-1].trainable = False
- self.assertListEqual(outer_model.trainable_weights, [])
-
- # a Model inside a Model
- x = keras.layers.Input(shape=(1,))
- y = keras.layers.Dense(2)(x)
- inner_model = keras.models.Model(x, y)
- x = keras.layers.Input(shape=(1,))
- y = inner_model(x)
- outer_model = keras.models.Model(x, y)
- self.assertListEqual(outer_model.trainable_weights,
- inner_model.trainable_weights)
- inner_model.trainable = False
- self.assertListEqual(outer_model.trainable_weights, [])
- inner_model.trainable = True
- inner_model.layers[-1].trainable = False
- self.assertListEqual(outer_model.trainable_weights, [])
-
- # a Model inside a Sequential
- x = keras.layers.Input(shape=(1,))
- y = keras.layers.Dense(2)(x)
- inner_model = keras.models.Model(x, y)
- outer_model = keras.models.Sequential()
- outer_model.add(inner_model)
- self.assertListEqual(outer_model.trainable_weights,
- inner_model.trainable_weights)
- inner_model.trainable = False
- self.assertListEqual(outer_model.trainable_weights, [])
- inner_model.trainable = True
- inner_model.layers[-1].trainable = False
- self.assertListEqual(outer_model.trainable_weights, [])
-
-
-class TestGeneratorMethods(test.TestCase):
-
- def test_generator_methods(self):
- arr_data = np.random.random((50, 2))
- arr_labels = np.random.random((50,))
-
- def custom_generator():
- batch_size = 10
- n_samples = 50
- while True:
- batch_index = np.random.randint(0, n_samples - batch_size)
- start = batch_index
- end = start + batch_size
- x = arr_data[start: end]
- y = arr_labels[start: end]
- yield x, y
-
- with self.test_session():
- x = keras.Input((2,))
- y = keras.layers.Dense(1)(x)
- fn_model = keras.models.Model(x, y)
- fn_model.compile(loss='mse', optimizer='sgd')
-
- seq_model = keras.models.Sequential()
- seq_model.add(keras.layers.Dense(1, input_shape=(2,)))
- seq_model.compile(loss='mse', optimizer='sgd')
-
- for model in [fn_model, seq_model]:
- model.fit_generator(custom_generator(),
- steps_per_epoch=5,
- epochs=1,
- verbose=1,
- max_queue_size=10,
- workers=4,
- use_multiprocessing=True)
- model.fit_generator(custom_generator(),
- steps_per_epoch=5,
- epochs=1,
- verbose=1,
- max_queue_size=10,
- use_multiprocessing=False)
- model.fit_generator(custom_generator(),
- steps_per_epoch=5,
- epochs=1,
- verbose=1,
- max_queue_size=10,
- use_multiprocessing=False,
- validation_data=custom_generator(),
- validation_steps=10)
- model.predict_generator(custom_generator(),
- steps=5,
- max_queue_size=10,
- workers=2,
- use_multiprocessing=True)
- model.predict_generator(custom_generator(),
- steps=5,
- max_queue_size=10,
- use_multiprocessing=False)
- model.evaluate_generator(custom_generator(),
- steps=5,
- max_queue_size=10,
- workers=2,
- use_multiprocessing=True)
- model.evaluate_generator(custom_generator(),
- steps=5,
- max_queue_size=10,
- use_multiprocessing=False)
-
- # Test legacy API
- model.fit_generator(custom_generator(),
- steps_per_epoch=5,
- epochs=1,
- verbose=1,
- max_q_size=10,
- workers=4,
- pickle_safe=True)
- model.predict_generator(custom_generator(),
- steps=5,
- max_q_size=10,
- workers=2,
- pickle_safe=True)
- model.evaluate_generator(custom_generator(),
- steps=5,
- max_q_size=10,
- workers=2,
- pickle_safe=True)
-
- def test_generator_methods_with_sample_weights(self):
- arr_data = np.random.random((50, 2))
- arr_labels = np.random.random((50,))
- arr_sample_weights = np.random.random((50,))
-
- def custom_generator():
- batch_size = 10
- n_samples = 50
- while True:
- batch_index = np.random.randint(0, n_samples - batch_size)
- start = batch_index
- end = start + batch_size
- x = arr_data[start: end]
- y = arr_labels[start: end]
- w = arr_sample_weights[start: end]
- yield x, y, w
-
- with self.test_session():
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(1, input_shape=(2,)))
- model.compile(loss='mse', optimizer='sgd')
-
- model.fit_generator(custom_generator(),
- steps_per_epoch=5,
- epochs=1,
- verbose=1,
- max_queue_size=10,
- use_multiprocessing=False)
- model.fit_generator(custom_generator(),
- steps_per_epoch=5,
- epochs=1,
- verbose=1,
- max_queue_size=10,
- use_multiprocessing=False,
- validation_data=custom_generator(),
- validation_steps=10)
- model.predict_generator(custom_generator(),
- steps=5,
- max_queue_size=10,
- use_multiprocessing=False)
- model.evaluate_generator(custom_generator(),
- steps=5,
- max_queue_size=10,
- use_multiprocessing=False)
-
- def test_generator_methods_invalid_use_case(self):
-
- def custom_generator():
- while 1:
- yield 0
-
- with self.test_session():
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(1, input_shape=(2,)))
- model.compile(loss='mse', optimizer='sgd')
-
- with self.assertRaises(ValueError):
- model.fit_generator(custom_generator(),
- steps_per_epoch=5,
- epochs=1,
- verbose=1,
- max_queue_size=10,
- use_multiprocessing=False)
- with self.assertRaises(ValueError):
- model.fit_generator(custom_generator(),
- steps_per_epoch=5,
- epochs=1,
- verbose=1,
- max_queue_size=10,
- use_multiprocessing=False,
- validation_data=custom_generator(),
- validation_steps=10)
- with self.assertRaises(TypeError):
- model.predict_generator(custom_generator(),
- steps=5,
- max_queue_size=10,
- use_multiprocessing=False)
- with self.assertRaises(ValueError):
- model.evaluate_generator(custom_generator(),
- steps=5,
- max_queue_size=10,
- use_multiprocessing=False)
-
-
-class TestTrainingUtils(test.TestCase):
-
- def test_check_array_lengths(self):
- keras.engine.training._check_array_lengths(None, None, None)
- a_np = np.random.random((4, 3, 3))
- keras.engine.training._check_array_lengths(a_np, a_np, a_np)
- keras.engine.training._check_array_lengths(
- [a_np, a_np], [a_np, a_np], [a_np, a_np])
- keras.engine.training._check_array_lengths([None], [None], [None])
-
- b_np = np.random.random((3, 4))
- with self.assertRaises(ValueError):
- keras.engine.training._check_array_lengths(a_np, None, None)
- with self.assertRaises(ValueError):
- keras.engine.training._check_array_lengths(a_np, a_np, None)
- with self.assertRaises(ValueError):
- keras.engine.training._check_array_lengths([a_np], [None], None)
- with self.assertRaises(ValueError):
- keras.engine.training._check_array_lengths([a_np], [b_np], None)
- with self.assertRaises(ValueError):
- keras.engine.training._check_array_lengths([a_np], None, [b_np])
-
- def test_slice_arrays(self):
- input_a = np.random.random((10, 3))
- keras.engine.training._slice_arrays(None)
- keras.engine.training._slice_arrays(input_a, 0)
- keras.engine.training._slice_arrays(input_a, 0, 1)
- keras.engine.training._slice_arrays(input_a, stop=2)
- input_a = [None, [1, 1], None, [1, 1]]
- keras.engine.training._slice_arrays(input_a, 0)
- keras.engine.training._slice_arrays(input_a, 0, 1)
- keras.engine.training._slice_arrays(input_a, stop=2)
- input_a = [None]
- keras.engine.training._slice_arrays(input_a, 0)
- keras.engine.training._slice_arrays(input_a, 0, 1)
- keras.engine.training._slice_arrays(input_a, stop=2)
- input_a = None
- keras.engine.training._slice_arrays(input_a, 0)
- keras.engine.training._slice_arrays(input_a, 0, 1)
- keras.engine.training._slice_arrays(input_a, stop=2)
-
-
-class TestTrainingWithDataTensors(test.TestCase):
-
- def test_model_with_input_feed_tensor(self):
- """We test building a model with a TF variable as input.
-
- We should be able to call fit, evaluate, predict,
- by only passing them data for the placeholder inputs
- in the model.
- """
- with self.test_session():
- input_a_np = np.random.random((10, 3))
- input_b_np = np.random.random((10, 3))
-
- output_a_np = np.random.random((10, 4))
- output_b_np = np.random.random((10, 3))
-
- a = keras.Input(
- tensor=keras.backend.variables_module.Variable(input_a_np,
- dtype='float32'))
- b = keras.Input(shape=(3,), name='input_b')
-
- a_2 = keras.layers.Dense(4, name='dense_1')(a)
- dp = keras.layers.Dropout(0.5, name='dropout')
- b_2 = dp(b)
-
- model = keras.models.Model([a, b], [a_2, b_2])
- model.summary()
-
- optimizer = 'rmsprop'
- loss = 'mse'
- loss_weights = [1., 0.5]
- model.compile(optimizer, loss, metrics=['mean_squared_error'],
- loss_weights=loss_weights,
- sample_weight_mode=None)
-
- # test train_on_batch
- out = model.train_on_batch(input_b_np,
- [output_a_np, output_b_np])
- out = model.train_on_batch({'input_b': input_b_np},
- [output_a_np, output_b_np])
- out = model.test_on_batch({'input_b': input_b_np},
- [output_a_np, output_b_np])
- out = model.predict_on_batch({'input_b': input_b_np})
-
- # test fit
- out = model.fit({'input_b': input_b_np},
- [output_a_np, output_b_np], epochs=1, batch_size=10)
- out = model.fit(input_b_np,
- [output_a_np, output_b_np], epochs=1, batch_size=10)
-
- # test evaluate
- out = model.evaluate({'input_b': input_b_np},
- [output_a_np, output_b_np], batch_size=10)
- out = model.evaluate(input_b_np,
- [output_a_np, output_b_np], batch_size=10)
-
- # test predict
- out = model.predict({'input_b': input_b_np}, batch_size=10)
- out = model.predict(input_b_np, batch_size=10)
- self.assertEqual(len(out), 2)
-
- # Now test a model with a single input
- # i.e. we don't pass any data to fit the model.
- a = keras.Input(
- tensor=keras.backend.variables_module.Variable(input_a_np,
- dtype='float32'))
- a_2 = keras.layers.Dense(4, name='dense_1')(a)
- a_2 = keras.layers.Dropout(0.5, name='dropout')(a_2)
- model = keras.models.Model(a, a_2)
- model.summary()
-
- optimizer = 'rmsprop'
- loss = 'mse'
- model.compile(optimizer, loss, metrics=['mean_squared_error'])
-
- # test train_on_batch
- out = model.train_on_batch(None,
- output_a_np)
- out = model.train_on_batch(None,
- output_a_np)
- out = model.test_on_batch(None,
- output_a_np)
- out = model.predict_on_batch(None)
- out = model.train_on_batch([],
- output_a_np)
- out = model.train_on_batch({},
- output_a_np)
-
- # test fit
- out = model.fit(None,
- output_a_np, epochs=1, batch_size=10)
- out = model.fit(None,
- output_a_np, epochs=1, batch_size=10)
-
- # test evaluate
- out = model.evaluate(None,
- output_a_np, batch_size=10)
- out = model.evaluate(None,
- output_a_np, batch_size=10)
-
- # test predict
- out = model.predict(None, steps=3)
- out = model.predict(None, steps=3)
- self.assertEqual(out.shape, (10 * 3, 4))
-
- # Same, without learning phase
- # i.e. we don't pass any data to fit the model.
- a = keras.Input(
- tensor=keras.backend.variables_module.Variable(input_a_np,
- dtype='float32'))
- a_2 = keras.layers.Dense(4, name='dense_1')(a)
- model = keras.models.Model(a, a_2)
- model.summary()
-
- optimizer = 'rmsprop'
- loss = 'mse'
- model.compile(optimizer, loss, metrics=['mean_squared_error'])
-
- # test train_on_batch
- out = model.train_on_batch(None,
- output_a_np)
- out = model.train_on_batch(None,
- output_a_np)
- out = model.test_on_batch(None,
- output_a_np)
- out = model.predict_on_batch(None)
- out = model.train_on_batch([],
- output_a_np)
- out = model.train_on_batch({},
- output_a_np)
-
- # test fit
- out = model.fit(None,
- output_a_np, epochs=1, batch_size=10)
- out = model.fit(None,
- output_a_np, epochs=1, batch_size=10)
-
- # test evaluate
- out = model.evaluate(None,
- output_a_np, batch_size=10)
- out = model.evaluate(None,
- output_a_np, batch_size=10)
-
- # test predict
- out = model.predict(None, steps=3)
- out = model.predict(None, steps=3)
- self.assertEqual(out.shape, (10 * 3, 4))
-
- def test_model_with_partial_loss(self):
- with self.test_session():
- a = keras.Input(shape=(3,), name='input_a')
- a_2 = keras.layers.Dense(4, name='dense_1')(a)
- dp = keras.layers.Dropout(0.5, name='dropout')
- a_3 = dp(a_2)
- model = keras.models.Model(a, [a_2, a_3])
-
- optimizer = 'rmsprop'
- loss = {'dropout': 'mse'}
- model.compile(optimizer, loss, metrics=['mae'])
-
- input_a_np = np.random.random((10, 3))
- output_a_np = np.random.random((10, 4))
-
- # test train_on_batch
- _ = model.train_on_batch(input_a_np, output_a_np)
- _ = model.test_on_batch(input_a_np, output_a_np)
- # fit
- _ = model.fit(input_a_np, [output_a_np])
- # evaluate
- _ = model.evaluate(input_a_np, [output_a_np])
-
- # Same without dropout.
- a = keras.Input(shape=(3,), name='input_a')
- a_2 = keras.layers.Dense(4, name='dense_1')(a)
- a_3 = keras.layers.Dense(4, name='dense_2')(a_2)
- model = keras.models.Model(a, [a_2, a_3])
-
- optimizer = 'rmsprop'
- loss = {'dense_2': 'mse'}
- model.compile(optimizer, loss, metrics={'dense_1': 'mae'})
-
- # test train_on_batch
- _ = model.train_on_batch(input_a_np, output_a_np)
- _ = model.test_on_batch(input_a_np, output_a_np)
- # fit
- _ = model.fit(input_a_np, [output_a_np])
- # evaluate
- _ = model.evaluate(input_a_np, [output_a_np])
-
- def test_model_with_external_loss(self):
- with self.test_session():
- # None loss, only regularization loss.
- a = keras.Input(shape=(3,), name='input_a')
- a_2 = keras.layers.Dense(4, name='dense_1',
- kernel_regularizer='l1',
- bias_regularizer='l2')(a)
- dp = keras.layers.Dropout(0.5, name='dropout')
- a_3 = dp(a_2)
-
- model = keras.models.Model(a, [a_2, a_3])
-
- optimizer = 'rmsprop'
- loss = None
- model.compile(optimizer, loss, metrics=['mae'])
-
- input_a_np = np.random.random((10, 3))
-
- # test train_on_batch
- out = model.train_on_batch(input_a_np, None)
- out = model.test_on_batch(input_a_np, None)
- # fit
- out = model.fit(input_a_np, None)
- # evaluate
- out = model.evaluate(input_a_np, None)
-
- # No dropout, external loss.
- a = keras.Input(shape=(3,), name='input_a')
- a_2 = keras.layers.Dense(4, name='dense_1')(a)
- a_3 = keras.layers.Dense(4, name='dense_2')(a)
-
- model = keras.models.Model(a, [a_2, a_3])
- model.add_loss(keras.backend.mean(a_3 + a_2))
-
- optimizer = 'rmsprop'
- loss = None
- model.compile(optimizer, loss, metrics=['mae'])
-
- # test train_on_batch
- out = model.train_on_batch(input_a_np, None)
- out = model.test_on_batch(input_a_np, None)
- # fit
- out = model.fit(input_a_np, None)
- # evaluate
- out = model.evaluate(input_a_np, None)
-
- # Test model with no external data at all.
- a = keras.Input(
- tensor=keras.backend.variables_module.Variable(input_a_np,
- dtype='float32'))
- a_2 = keras.layers.Dense(4, name='dense_1')(a)
- a_2 = keras.layers.Dropout(0.5, name='dropout')(a_2)
- model = keras.models.Model(a, a_2)
- model.add_loss(keras.backend.mean(a_2))
-
- model.compile(optimizer='rmsprop',
- loss=None,
- metrics=['mean_squared_error'])
-
- # test train_on_batch
- out = model.train_on_batch(None, None)
- out = model.test_on_batch(None, None)
- out = model.predict_on_batch(None)
-
- # test fit
- with self.assertRaises(ValueError):
- out = model.fit(None, None, epochs=1, batch_size=10)
- out = model.fit(None, None, epochs=1, steps_per_epoch=1)
-
- # test fit with validation data
- with self.assertRaises(ValueError):
- out = model.fit(None, None, epochs=1,
- steps_per_epoch=None,
- validation_steps=2)
- out = model.fit(None, None, epochs=1,
- steps_per_epoch=2,
- validation_steps=2)
-
- # test evaluate
- with self.assertRaises(ValueError):
- out = model.evaluate(None, None, batch_size=10)
- out = model.evaluate(None, None, steps=3)
-
- # test predict
- with self.assertRaises(ValueError):
- out = model.predict(None, batch_size=10)
- out = model.predict(None, steps=3)
- self.assertEqual(out.shape, (10 * 3, 4))
-
- # Test multi-output model with no external data at all.
- a = keras.Input(
- tensor=keras.backend.variables_module.Variable(input_a_np,
- dtype='float32'))
- a_1 = keras.layers.Dense(4, name='dense_1')(a)
- a_2 = keras.layers.Dropout(0.5, name='dropout')(a_1)
- model = keras.models.Model(a, [a_1, a_2])
- model.add_loss(keras.backend.mean(a_2))
-
- model.compile(optimizer='rmsprop',
- loss=None,
- metrics=['mean_squared_error'])
-
- # test train_on_batch
- out = model.train_on_batch(None, None)
- out = model.test_on_batch(None, None)
- out = model.predict_on_batch(None)
-
- # test fit
- with self.assertRaises(ValueError):
- out = model.fit(None, None, epochs=1, batch_size=10)
- out = model.fit(None, None, epochs=1, steps_per_epoch=1)
-
- # test fit with validation data
- out = model.fit(None, None, epochs=1,
- steps_per_epoch=2,
- validation_steps=2)
-
- # test evaluate
- with self.assertRaises(ValueError):
- out = model.evaluate(None, None, batch_size=10)
- out = model.evaluate(None, None, steps=3)
-
- # test predict
- with self.assertRaises(ValueError):
- out = model.predict(None, batch_size=10, verbose=1)
- out = model.predict(None, steps=3)
- self.assertEqual(len(out), 2)
- self.assertEqual(out[0].shape, (10 * 3, 4))
- self.assertEqual(out[1].shape, (10 * 3, 4))
-
- def test_target_tensors(self):
- with self.test_session():
- # single-output, as list
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(4, input_shape=(4,), name='dense'))
- input_val = np.random.random((10, 4))
- target_val = np.random.random((10, 4))
- target = keras.backend.variable(target_val)
- model.compile(optimizer='rmsprop', loss='mse', target_tensors=[target])
- model.train_on_batch(input_val, None)
-
- # single-output, as dict
- model.compile(optimizer='rmsprop', loss='mse',
- target_tensors={'dense': target})
- model.train_on_batch(input_val, None)
-
- # test invalid arguments
- with self.assertRaises(TypeError):
- model.compile(optimizer='rmsprop', loss='mse',
- target_tensors=set())
- with self.assertRaises(ValueError):
- model.compile(optimizer='rmsprop', loss='mse',
- target_tensors=[target, target])
- with self.assertRaises(ValueError):
- model.compile(optimizer='rmsprop', loss='mse',
- target_tensors={'dense2': None})
- with self.assertRaises(ValueError):
- model.compile(optimizer='rmsprop', loss='mse',
- target_tensors=[target])
- model.train_on_batch(input_val, target_val)
-
- # multi-output, as list
- input_val = np.random.random((10, 4))
- target_val_a = np.random.random((10, 4))
- target_val_b = np.random.random((10, 4))
- target_a = keras.backend.variable(target_val_a)
- target_b = keras.backend.variable(target_val_b)
-
- inputs = keras.layers.Input(shape=(4,))
- output_a = keras.layers.Dense(4, name='dense_a')(inputs)
- output_b = keras.layers.Dense(4, name='dense_b')(inputs)
- model = keras.models.Model(inputs, [output_a, output_b])
- model.compile(optimizer='rmsprop', loss='mse',
- target_tensors=[target_a, target_b])
- model.train_on_batch(input_val, None)
-
- # multi-output, as dict
- model.compile(optimizer='rmsprop', loss='mse',
- target_tensors={'dense_a': target_a,
- 'dense_b': target_b})
- model.train_on_batch(input_val, None)
-
- # test with sample weights
- model.compile(optimizer='rmsprop', loss='mse',
- target_tensors=[target_a, target_b])
- model.train_on_batch(input_val, None,
- sample_weight={'dense_a': np.random.random((10,))})
-
- def test_model_custom_target_tensors(self):
- with self.test_session():
- a = keras.Input(shape=(3,), name='input_a')
- b = keras.Input(shape=(3,), name='input_b')
-
- a_2 = keras.layers.Dense(4, name='dense_1')(a)
- dp = keras.layers.Dropout(0.5, name='dropout')
- b_2 = dp(b)
-
- y = keras.backend.placeholder([10, 4], name='y')
- y1 = keras.backend.placeholder([10, 3], name='y1')
- y2 = keras.backend.placeholder([7, 5], name='y2')
- model = keras.models.Model([a, b], [a_2, b_2])
-
- optimizer = 'rmsprop'
- loss = 'mse'
- loss_weights = [1., 0.5]
-
- # test list of target tensors
- with self.assertRaises(ValueError):
- model.compile(optimizer, loss, metrics=[], loss_weights=loss_weights,
- sample_weight_mode=None, target_tensors=[y, y1, y2])
- model.compile(optimizer, loss, metrics=[], loss_weights=loss_weights,
- sample_weight_mode=None, target_tensors=[y, y1])
- input_a_np = np.random.random((10, 3))
- input_b_np = np.random.random((10, 3))
-
- output_a_np = np.random.random((10, 4))
- output_b_np = np.random.random((10, 3))
-
- _ = model.train_on_batch([input_a_np, input_b_np],
- [output_a_np, output_b_np],
- {y: np.random.random((10, 4)),
- y1: np.random.random((10, 3))})
- # test dictionary of target_tensors
- with self.assertRaises(ValueError):
- model.compile(optimizer, loss,
- metrics=[],
- loss_weights=loss_weights,
- sample_weight_mode=None,
- target_tensors={'does_not_exist': y2})
- # test dictionary of target_tensors
- model.compile(optimizer, loss,
- metrics=[],
- loss_weights=loss_weights,
- sample_weight_mode=None,
- target_tensors={'dense_1': y, 'dropout': y1})
- _ = model.train_on_batch([input_a_np, input_b_np],
- [output_a_np, output_b_np],
- {y: np.random.random((10, 4)),
- y1: np.random.random((10, 3))})
-
- # test with custom TF placeholder as target
- pl_target_a = keras.backend.array_ops.placeholder('float32',
- shape=(None, 4))
- model.compile(optimizer='rmsprop', loss='mse',
- target_tensors={'dense_1': pl_target_a})
- model.train_on_batch([input_a_np, input_b_np],
- [output_a_np, output_b_np])
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/initializers.py b/tensorflow/contrib/keras/python/keras/initializers.py
deleted file mode 100644
index ae76c079f3..0000000000
--- a/tensorflow/contrib/keras/python/keras/initializers.py
+++ /dev/null
@@ -1,202 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Keras initializer classes (soon to be replaced with core TF initializers).
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import six
-
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import deserialize_keras_object
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import serialize_keras_object
-from tensorflow.python.ops.init_ops import Constant
-from tensorflow.python.ops.init_ops import Identity
-from tensorflow.python.ops.init_ops import Initializer # pylint: disable=unused-import
-from tensorflow.python.ops.init_ops import Ones
-from tensorflow.python.ops.init_ops import Orthogonal
-from tensorflow.python.ops.init_ops import RandomNormal
-from tensorflow.python.ops.init_ops import RandomUniform
-from tensorflow.python.ops.init_ops import TruncatedNormal
-from tensorflow.python.ops.init_ops import VarianceScaling
-from tensorflow.python.ops.init_ops import Zeros
-
-
-def lecun_normal(seed=None):
- """LeCun normal initializer.
-
- It draws samples from a truncated normal distribution centered on 0
- with `stddev = sqrt(1 / fan_in)`
- where `fan_in` is the number of input units in the weight tensor.
-
- Arguments:
- seed: A Python integer. Used to seed the random generator.
-
- Returns:
- An initializer.
-
- References:
- - [Self-Normalizing Neural Networks](https://arxiv.org/abs/1706.02515)
- - [Efficient
- Backprop](http://yann.lecun.com/exdb/publis/pdf/lecun-98b.pdf)
- """
- return VarianceScaling(
- scale=1., mode='fan_in', distribution='normal', seed=seed)
-
-
-def lecun_uniform(seed=None):
- """LeCun uniform initializer.
-
- It draws samples from a uniform distribution within [-limit, limit]
- where `limit` is `sqrt(3 / fan_in)`
- where `fan_in` is the number of input units in the weight tensor.
-
- Arguments:
- seed: A Python integer. Used to seed the random generator.
-
- Returns:
- An initializer.
-
- References:
- LeCun 98, Efficient Backprop,
- http://yann.lecun.com/exdb/publis/pdf/lecun-98b.pdf
- """
- return VarianceScaling(
- scale=1., mode='fan_in', distribution='uniform', seed=seed)
-
-
-def glorot_normal(seed=None):
- """Glorot normal initializer, also called Xavier normal initializer.
-
- It draws samples from a truncated normal distribution centered on 0
- with `stddev = sqrt(2 / (fan_in + fan_out))`
- where `fan_in` is the number of input units in the weight tensor
- and `fan_out` is the number of output units in the weight tensor.
-
- Arguments:
- seed: A Python integer. Used to seed the random generator.
-
- Returns:
- An initializer.
-
- References:
- Glorot & Bengio, AISTATS 2010
- http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf
- """
- return VarianceScaling(
- scale=1., mode='fan_avg', distribution='normal', seed=seed)
-
-
-def glorot_uniform(seed=None):
- """Glorot uniform initializer, also called Xavier uniform initializer.
-
- It draws samples from a uniform distribution within [-limit, limit]
- where `limit` is `sqrt(6 / (fan_in + fan_out))`
- where `fan_in` is the number of input units in the weight tensor
- and `fan_out` is the number of output units in the weight tensor.
-
- Arguments:
- seed: A Python integer. Used to seed the random generator.
-
- Returns:
- An initializer.
-
- References:
- Glorot & Bengio, AISTATS 2010
- http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf
- """
- return VarianceScaling(
- scale=1., mode='fan_avg', distribution='uniform', seed=seed)
-
-
-def he_normal(seed=None):
- """He normal initializer.
-
- It draws samples from a truncated normal distribution centered on 0
- with `stddev = sqrt(2 / fan_in)`
- where `fan_in` is the number of input units in the weight tensor.
-
- Arguments:
- seed: A Python integer. Used to seed the random generator.
-
- Returns:
- An initializer.
-
- References:
- He et al., http://arxiv.org/abs/1502.01852
- """
- return VarianceScaling(
- scale=2., mode='fan_in', distribution='normal', seed=seed)
-
-
-def he_uniform(seed=None):
- """He uniform variance scaling initializer.
-
- It draws samples from a uniform distribution within [-limit, limit]
- where `limit` is `sqrt(6 / fan_in)`
- where `fan_in` is the number of input units in the weight tensor.
-
- Arguments:
- seed: A Python integer. Used to seed the random generator.
-
- Returns:
- An initializer.
-
- References:
- He et al., http://arxiv.org/abs/1502.01852
- """
- return VarianceScaling(
- scale=2., mode='fan_in', distribution='uniform', seed=seed)
-
-
-# Compatibility aliases
-
-# pylint: disable=invalid-name
-zero = zeros = Zeros
-one = ones = Ones
-constant = Constant
-uniform = random_uniform = RandomUniform
-normal = random_normal = RandomNormal
-truncated_normal = TruncatedNormal
-identity = Identity
-orthogonal = Orthogonal
-
-# pylint: enable=invalid-name
-
-# Utility functions
-
-
-def serialize(initializer):
- return serialize_keras_object(initializer)
-
-
-def deserialize(config, custom_objects=None):
- return deserialize_keras_object(
- config,
- module_objects=globals(),
- custom_objects=custom_objects,
- printable_module_name='initializer')
-
-
-def get(identifier):
- if isinstance(identifier, dict):
- return deserialize(identifier)
- elif isinstance(identifier, six.string_types):
- config = {'class_name': str(identifier), 'config': {}}
- return deserialize(config)
- elif callable(identifier):
- return identifier
- else:
- raise ValueError('Could not interpret initializer identifier:', identifier)
diff --git a/tensorflow/contrib/keras/python/keras/initializers_test.py b/tensorflow/contrib/keras/python/keras/initializers_test.py
deleted file mode 100644
index f39d2bfd52..0000000000
--- a/tensorflow/contrib/keras/python/keras/initializers_test.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for Keras initializers."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.ops import init_ops
-from tensorflow.python.platform import test
-
-
-class KerasInitializersTest(test.TestCase):
-
- def _runner(self, init, shape, target_mean=None, target_std=None,
- target_max=None, target_min=None):
- variable = keras.backend.variable(init(shape))
- output = keras.backend.get_value(variable)
- lim = 3e-2
- if target_std is not None:
- self.assertGreater(lim, abs(output.std() - target_std))
- if target_mean is not None:
- self.assertGreater(lim, abs(output.mean() - target_mean))
- if target_max is not None:
- self.assertGreater(lim, abs(output.max() - target_max))
- if target_min is not None:
- self.assertGreater(lim, abs(output.min() - target_min))
-
- # Test serialization (assumes deterministic behavior).
- config = init.get_config()
- reconstructed_init = init.__class__.from_config(config)
- variable = keras.backend.variable(reconstructed_init(shape))
- output_2 = keras.backend.get_value(variable)
- self.assertAllClose(output, output_2, atol=1e-4)
-
- def test_uniform(self):
- tensor_shape = (9, 6, 7)
- with self.test_session():
- self._runner(keras.initializers.RandomUniform(minval=-1,
- maxval=1,
- seed=124),
- tensor_shape,
- target_mean=0., target_max=1, target_min=-1)
-
- def test_normal(self):
- tensor_shape = (8, 12, 99)
- with self.test_session():
- self._runner(keras.initializers.RandomNormal(mean=0, stddev=1, seed=153),
- tensor_shape,
- target_mean=0., target_std=1)
-
- def test_truncated_normal(self):
- tensor_shape = (12, 99, 7)
- with self.test_session():
- self._runner(keras.initializers.TruncatedNormal(mean=0,
- stddev=1,
- seed=126),
- tensor_shape,
- target_mean=0., target_std=None, target_max=2)
-
- def test_constant(self):
- tensor_shape = (5, 6, 4)
- with self.test_session():
- self._runner(keras.initializers.Constant(2), tensor_shape,
- target_mean=2, target_max=2, target_min=2)
-
- def test_lecun_uniform(self):
- tensor_shape = (5, 6, 4, 2)
- with self.test_session():
- fan_in, _ = init_ops._compute_fans(tensor_shape)
- scale = np.sqrt(3. / fan_in)
- self._runner(keras.initializers.lecun_uniform(seed=123), tensor_shape,
- target_mean=0., target_max=scale, target_min=-scale)
-
- def test_glorot_uniform(self):
- tensor_shape = (5, 6, 4, 2)
- with self.test_session():
- fan_in, fan_out = init_ops._compute_fans(tensor_shape)
- scale = np.sqrt(6. / (fan_in + fan_out))
- self._runner(keras.initializers.glorot_uniform(seed=123), tensor_shape,
- target_mean=0., target_max=scale, target_min=-scale)
-
- def test_he_uniform(self):
- tensor_shape = (5, 6, 4, 2)
- with self.test_session():
- fan_in, _ = init_ops._compute_fans(tensor_shape)
- scale = np.sqrt(6. / fan_in)
- self._runner(keras.initializers.he_uniform(seed=123), tensor_shape,
- target_mean=0., target_max=scale, target_min=-scale)
-
- def test_lecun_normal(self):
- tensor_shape = (5, 6, 4, 2)
- with self.test_session():
- fan_in, _ = init_ops._compute_fans(tensor_shape)
- scale = np.sqrt(1. / fan_in)
- self._runner(keras.initializers.lecun_normal(seed=123), tensor_shape,
- target_mean=0., target_std=None, target_max=2 * scale)
-
- def test_glorot_normal(self):
- tensor_shape = (5, 6, 4, 2)
- with self.test_session():
- fan_in, fan_out = init_ops._compute_fans(tensor_shape)
- scale = np.sqrt(2. / (fan_in + fan_out))
- self._runner(keras.initializers.glorot_normal(seed=123), tensor_shape,
- target_mean=0., target_std=None, target_max=2 * scale)
-
- def test_he_normal(self):
- tensor_shape = (5, 6, 4, 2)
- with self.test_session():
- fan_in, _ = init_ops._compute_fans(tensor_shape)
- scale = np.sqrt(2. / fan_in)
- self._runner(keras.initializers.he_normal(seed=123), tensor_shape,
- target_mean=0., target_std=None, target_max=2 * scale)
-
- def test_orthogonal(self):
- tensor_shape = (20, 20)
- with self.test_session():
- self._runner(keras.initializers.orthogonal(seed=123), tensor_shape,
- target_mean=0.)
-
- def test_identity(self):
- with self.test_session():
- tensor_shape = (3, 4, 5)
- with self.assertRaises(ValueError):
- self._runner(keras.initializers.identity(), tensor_shape,
- target_mean=1. / tensor_shape[0], target_max=1.)
-
- tensor_shape = (3, 3)
- self._runner(keras.initializers.identity(), tensor_shape,
- target_mean=1. / tensor_shape[0], target_max=1.)
-
- def test_zero(self):
- tensor_shape = (4, 5)
- with self.test_session():
- self._runner(keras.initializers.zeros(), tensor_shape,
- target_mean=0., target_max=0.)
-
- def test_one(self):
- tensor_shape = (4, 5)
- with self.test_session():
- self._runner(keras.initializers.ones(), tensor_shape,
- target_mean=1., target_max=1.)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/integration_test.py b/tensorflow/contrib/keras/python/keras/integration_test.py
deleted file mode 100644
index 5c42ffcfbd..0000000000
--- a/tensorflow/contrib/keras/python/keras/integration_test.py
+++ /dev/null
@@ -1,292 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Integration tests for Keras."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.layers import base as tf_base_layers
-from tensorflow.python.layers import core as tf_core_layers
-from tensorflow.python.ops import nn
-from tensorflow.python.platform import test
-
-
-class KerasIntegrationTest(test.TestCase):
-
- def test_vector_classification_declarative(self):
- with self.test_session():
- np.random.seed(1337)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=200,
- test_samples=100,
- input_shape=(10,),
- num_classes=2)
- y_train = keras.utils.to_categorical(y_train)
- y_test = keras.utils.to_categorical(y_test)
-
- model = keras.models.Sequential([
- keras.layers.Dense(16,
- activation='relu',
- input_shape=x_train.shape[1:]),
- keras.layers.Dropout(0.1),
- keras.layers.Dense(y_train.shape[-1], activation='softmax')
- ])
- model.compile(loss='categorical_crossentropy',
- optimizer='rmsprop',
- metrics=['accuracy'])
- history = model.fit(x_train, y_train, epochs=10, batch_size=16,
- validation_data=(x_test, y_test),
- verbose=2)
- self.assertGreater(history.history['val_acc'][-1], 0.85)
-
- def test_vector_classification_functional(self):
- with self.test_session():
- np.random.seed(1337)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=200,
- test_samples=100,
- input_shape=(10,),
- num_classes=2)
- y_train = keras.utils.to_categorical(y_train)
- y_test = keras.utils.to_categorical(y_test)
-
- inputs = keras.layers.Input(shape=x_train.shape[1:])
- x = keras.layers.Dense(16, activation='relu')(inputs)
- x = keras.layers.Dropout(0.1)(x)
- outputs = keras.layers.Dense(y_train.shape[-1], activation='softmax')(x)
-
- model = keras.models.Model(inputs, outputs)
- model.compile(loss='categorical_crossentropy',
- optimizer='rmsprop',
- metrics=['accuracy'])
- history = model.fit(x_train, y_train, epochs=10, batch_size=16,
- validation_data=(x_test, y_test),
- verbose=2)
- self.assertGreater(history.history['val_acc'][-1], 0.85)
-
- def test_temporal_classification_declarative(self):
- with self.test_session():
- np.random.seed(1336)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=200,
- test_samples=100,
- input_shape=(4, 8),
- num_classes=2)
- y_train = keras.utils.to_categorical(y_train)
- y_test = keras.utils.to_categorical(y_test)
-
- model = keras.models.Sequential()
- model.add(keras.layers.LSTM(3, return_sequences=True,
- input_shape=x_train.shape[1:]))
- model.add(keras.layers.GRU(y_train.shape[-1], activation='softmax'))
- model.compile(loss='categorical_crossentropy',
- optimizer='adam',
- metrics=['accuracy'])
- history = model.fit(x_train, y_train, epochs=10, batch_size=16,
- validation_data=(x_test, y_test),
- verbose=2)
- self.assertGreater(history.history['val_acc'][-1], 0.85)
-
- def test_image_classification_declarative(self):
- with self.test_session():
- np.random.seed(1337)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=200,
- test_samples=100,
- input_shape=(8, 8, 3),
- num_classes=2)
- y_train = keras.utils.to_categorical(y_train)
- y_test = keras.utils.to_categorical(y_test)
-
- model = keras.models.Sequential()
- model.add(keras.layers.Conv2D(
- 8, 3,
- activation='relu',
- input_shape=x_train.shape[1:]))
- model.add(keras.layers.BatchNormalization())
- model.add(keras.layers.Conv2D(
- 8, 3,
- padding='same',
- activation='relu'))
- model.add(keras.layers.GlobalMaxPooling2D())
- model.add(keras.layers.Dense(y_train.shape[-1], activation='softmax'))
- model.compile(loss='categorical_crossentropy',
- optimizer='adam',
- metrics=['accuracy'])
- history = model.fit(x_train, y_train, epochs=10, batch_size=16,
- validation_data=(x_test, y_test),
- verbose=2)
- self.assertGreater(history.history['val_acc'][-1], 0.85)
-
- def test_video_classification_functional(self):
- with self.test_session():
- np.random.seed(1337)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=200,
- test_samples=100,
- input_shape=(4, 8, 8, 3),
- num_classes=3)
- y_train = keras.utils.to_categorical(y_train)
- y_test = keras.utils.to_categorical(y_test)
-
- inputs = keras.layers.Input(shape=x_train.shape[1:])
- x = keras.layers.TimeDistributed(
- keras.layers.Conv2D(4, 3, activation='relu'))(inputs)
- x = keras.layers.BatchNormalization()(x)
- x = keras.layers.TimeDistributed(keras.layers.GlobalMaxPooling2D())(x)
- x = keras.layers.Conv1D(8, 3, activation='relu')(x)
- x = keras.layers.Flatten()(x)
- outputs = keras.layers.Dense(y_train.shape[-1], activation='softmax')(x)
-
- model = keras.models.Model(inputs, outputs)
- model.compile(loss='categorical_crossentropy',
- optimizer=keras.optimizers.SGD(lr=0.01, momentum=0.8),
- metrics=['accuracy'])
- history = model.fit(x_train, y_train, epochs=10, batch_size=16,
- validation_data=(x_test, y_test),
- verbose=2)
- self.assertGreater(history.history['val_acc'][-1], 0.70)
-
- def test_vector_classification_shared_sequential(self):
- # Test that Sequential models that feature internal updates
- # and internal losses can be shared.
- with self.test_session():
- np.random.seed(1337)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=200,
- test_samples=100,
- input_shape=(10,),
- num_classes=2)
- y_train = keras.utils.to_categorical(y_train)
- y_test = keras.utils.to_categorical(y_test)
-
- base_model = keras.models.Sequential([
- keras.layers.Dense(16,
- activation='relu',
- kernel_regularizer=keras.regularizers.l2(1e-5),
- bias_regularizer=keras.regularizers.l2(1e-5),
- input_shape=x_train.shape[1:]),
- keras.layers.BatchNormalization(),
- ])
- x = keras.layers.Input(x_train.shape[1:])
- y = base_model(x)
- y = keras.layers.Dense(y_train.shape[-1], activation='softmax')(y)
- model = keras.models.Model(x, y)
- model.compile(loss='categorical_crossentropy',
- optimizer='rmsprop',
- metrics=['accuracy'])
- history = model.fit(x_train, y_train, epochs=10, batch_size=16,
- validation_data=(x_test, y_test),
- verbose=2)
- self.assertGreater(history.history['val_acc'][-1], 0.85)
-
- def test_vector_classification_shared_model(self):
- # Test that functional models that feature internal updates
- # and internal losses can be shared.
- with self.test_session():
- np.random.seed(1337)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=200,
- test_samples=100,
- input_shape=(10,),
- num_classes=2)
- y_train = keras.utils.to_categorical(y_train)
- y_test = keras.utils.to_categorical(y_test)
-
- inputs = keras.layers.Input(x_train.shape[1:])
- x = keras.layers.Dense(16,
- activation='relu',
- kernel_regularizer=keras.regularizers.l2(1e-5),
- bias_regularizer=keras.regularizers.l2(1e-5),
- input_shape=x_train.shape[1:])(inputs)
- x = keras.layers.BatchNormalization()(x)
- base_model = keras.models.Model(inputs, x)
-
- x = keras.layers.Input(x_train.shape[1:])
- y = base_model(x)
- y = keras.layers.Dense(y_train.shape[-1], activation='softmax')(y)
- model = keras.models.Model(x, y)
- model.compile(loss='categorical_crossentropy',
- optimizer='rmsprop',
- metrics=['accuracy'])
- history = model.fit(x_train, y_train, epochs=10, batch_size=16,
- validation_data=(x_test, y_test),
- verbose=2)
- self.assertGreater(history.history['val_acc'][-1], 0.85)
-
- def test_embedding_with_clipnorm(self):
- with self.test_session():
- model = keras.models.Sequential()
- model.add(keras.layers.Embedding(input_dim=1, output_dim=1))
- model.compile(optimizer=keras.optimizers.SGD(clipnorm=0.1), loss='mse')
- model.fit(np.array([[0]]), np.array([[[0.5]]]), epochs=1)
-
- def test_using_tf_layers_in_keras_sequential_model(self):
- with self.test_session():
- np.random.seed(1337)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=200,
- test_samples=100,
- input_shape=(10,),
- num_classes=2)
-
- model = keras.models.Sequential()
- model.add(tf_core_layers.Dense(32, activation=nn.relu, input_shape=(10,)))
- model.add(tf_core_layers.Dense(2, activation=nn.softmax))
- model.summary()
-
- y_train = keras.utils.to_categorical(y_train)
- y_test = keras.utils.to_categorical(y_test)
- model.compile(loss='categorical_crossentropy',
- optimizer='adam',
- metrics=['accuracy'])
- history = model.fit(x_train, y_train, epochs=10, batch_size=16,
- validation_data=(x_test, y_test),
- verbose=0)
- self.assertGreater(history.history['val_acc'][-1], 0.85)
-
- def test_using_tf_layers_in_keras_functional_model(self):
- with self.test_session():
- np.random.seed(1337)
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=200,
- test_samples=100,
- input_shape=(10,),
- num_classes=2)
- y_train = keras.utils.to_categorical(y_train)
- y_test = keras.utils.to_categorical(y_test)
-
- inputs = tf_base_layers.Input(shape=(10,))
- x = tf_core_layers.Dense(32, activation=nn.relu)(inputs)
- outputs = tf_core_layers.Dense(2, activation=nn.softmax)(x)
- model = keras.models.Model(inputs, outputs)
- model.summary()
-
- model.compile(loss='categorical_crossentropy',
- optimizer='adam',
- metrics=['accuracy'])
- history = model.fit(x_train, y_train, epochs=10, batch_size=16,
- validation_data=(x_test, y_test),
- verbose=0)
- self.assertGreater(history.history['val_acc'][-1], 0.85)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/layers/__init__.py b/tensorflow/contrib/keras/python/keras/layers/__init__.py
deleted file mode 100644
index 9a428f3114..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/__init__.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Keras layers module.
-"""
-# pylint: disable=wildcard-import
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras.engine import Input
-from tensorflow.contrib.keras.python.keras.engine import InputLayer
-from tensorflow.contrib.keras.python.keras.engine import InputSpec
-from tensorflow.contrib.keras.python.keras.engine import Layer
-from tensorflow.contrib.keras.python.keras.layers.advanced_activations import *
-from tensorflow.contrib.keras.python.keras.layers.convolutional import *
-from tensorflow.contrib.keras.python.keras.layers.convolutional_recurrent import *
-from tensorflow.contrib.keras.python.keras.layers.core import *
-from tensorflow.contrib.keras.python.keras.layers.embeddings import *
-from tensorflow.contrib.keras.python.keras.layers.local import *
-from tensorflow.contrib.keras.python.keras.layers.merge import *
-from tensorflow.contrib.keras.python.keras.layers.noise import *
-from tensorflow.contrib.keras.python.keras.layers.normalization import *
-from tensorflow.contrib.keras.python.keras.layers.pooling import *
-from tensorflow.contrib.keras.python.keras.layers.recurrent import *
-from tensorflow.contrib.keras.python.keras.layers.serialization import deserialize
-from tensorflow.contrib.keras.python.keras.layers.serialization import serialize
-from tensorflow.contrib.keras.python.keras.layers.wrappers import *
-
diff --git a/tensorflow/contrib/keras/python/keras/layers/advanced_activations.py b/tensorflow/contrib/keras/python/keras/layers/advanced_activations.py
deleted file mode 100644
index 55f17ac4e2..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/advanced_activations.py
+++ /dev/null
@@ -1,222 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Layers that act as activation functions.
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras import constraints
-from tensorflow.contrib.keras.python.keras import initializers
-from tensorflow.contrib.keras.python.keras import regularizers
-from tensorflow.contrib.keras.python.keras.engine import InputSpec
-from tensorflow.contrib.keras.python.keras.engine import Layer
-from tensorflow.python.framework import tensor_shape
-
-
-class LeakyReLU(Layer):
- """Leaky version of a Rectified Linear Unit.
-
- It allows a small gradient when the unit is not active:
- `f(x) = alpha * x for x < 0`,
- `f(x) = x for x >= 0`.
-
- Input shape:
- Arbitrary. Use the keyword argument `input_shape`
- (tuple of integers, does not include the samples axis)
- when using this layer as the first layer in a model.
-
- Output shape:
- Same shape as the input.
-
- Arguments:
- alpha: float >= 0. Negative slope coefficient.
-
- """
-
- def __init__(self, alpha=0.3, **kwargs):
- super(LeakyReLU, self).__init__(**kwargs)
- self.supports_masking = True
- self.alpha = K.cast_to_floatx(alpha)
-
- def call(self, inputs):
- return K.relu(inputs, alpha=self.alpha)
-
- def get_config(self):
- config = {'alpha': float(self.alpha)}
- base_config = super(LeakyReLU, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class PReLU(Layer):
- """Parametric Rectified Linear Unit.
-
- It follows:
- `f(x) = alpha * x for x < 0`,
- `f(x) = x for x >= 0`,
- where `alpha` is a learned array with the same shape as x.
-
- Input shape:
- Arbitrary. Use the keyword argument `input_shape`
- (tuple of integers, does not include the samples axis)
- when using this layer as the first layer in a model.
-
- Output shape:
- Same shape as the input.
-
- Arguments:
- alpha_initializer: initializer function for the weights.
- alpha_regularizer: regularizer for the weights.
- alpha_constraint: constraint for the weights.
- shared_axes: the axes along which to share learnable
- parameters for the activation function.
- For example, if the incoming feature maps
- are from a 2D convolution
- with output shape `(batch, height, width, channels)`,
- and you wish to share parameters across space
- so that each filter only has one set of parameters,
- set `shared_axes=[1, 2]`.
-
- """
-
- def __init__(self,
- alpha_initializer='zeros',
- alpha_regularizer=None,
- alpha_constraint=None,
- shared_axes=None,
- **kwargs):
- super(PReLU, self).__init__(**kwargs)
- self.supports_masking = True
- self.alpha_initializer = initializers.get(alpha_initializer)
- self.alpha_regularizer = regularizers.get(alpha_regularizer)
- self.alpha_constraint = constraints.get(alpha_constraint)
- if shared_axes is None:
- self.shared_axes = None
- elif not isinstance(shared_axes, (list, tuple)):
- self.shared_axes = [shared_axes]
- else:
- self.shared_axes = list(shared_axes)
-
- def build(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- param_shape = input_shape[1:]
- self.param_broadcast = [False] * len(param_shape)
- if self.shared_axes is not None:
- for i in self.shared_axes:
- param_shape[i - 1] = 1
- self.param_broadcast[i - 1] = True
- self.alpha = self.add_weight(
- shape=param_shape,
- name='alpha',
- initializer=self.alpha_initializer,
- regularizer=self.alpha_regularizer,
- constraint=self.alpha_constraint)
- # Set input spec
- axes = {}
- if self.shared_axes:
- for i in range(1, len(input_shape)):
- if i not in self.shared_axes:
- axes[i] = input_shape[i]
- self.input_spec = InputSpec(ndim=len(input_shape), axes=axes)
- self.built = True
-
- def call(self, inputs, mask=None):
- pos = K.relu(inputs)
- if K.backend() == 'theano':
- neg = (K.pattern_broadcast(self.alpha, self.param_broadcast) *
- (inputs - K.abs(inputs)) * 0.5)
- else:
- neg = -self.alpha * K.relu(-inputs)
- return pos + neg
-
- def get_config(self):
- config = {
- 'alpha_initializer': initializers.serialize(self.alpha_initializer),
- 'alpha_regularizer': regularizers.serialize(self.alpha_regularizer),
- 'alpha_constraint': constraints.serialize(self.alpha_constraint),
- 'shared_axes': self.shared_axes
- }
- base_config = super(PReLU, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class ELU(Layer):
- """Exponential Linear Unit.
-
- It follows:
- `f(x) = alpha * (exp(x) - 1.) for x < 0`,
- `f(x) = x for x >= 0`.
-
- Input shape:
- Arbitrary. Use the keyword argument `input_shape`
- (tuple of integers, does not include the samples axis)
- when using this layer as the first layer in a model.
-
- Output shape:
- Same shape as the input.
-
- Arguments:
- alpha: scale for the negative factor.
-
- """
-
- def __init__(self, alpha=1.0, **kwargs):
- super(ELU, self).__init__(**kwargs)
- self.supports_masking = True
- self.alpha = K.cast_to_floatx(alpha)
-
- def call(self, inputs):
- return K.elu(inputs, self.alpha)
-
- def get_config(self):
- config = {'alpha': float(self.alpha)}
- base_config = super(ELU, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class ThresholdedReLU(Layer):
- """Thresholded Rectified Linear Unit.
-
- It follows:
- `f(x) = x for x > theta`,
- `f(x) = 0 otherwise`.
-
- Input shape:
- Arbitrary. Use the keyword argument `input_shape`
- (tuple of integers, does not include the samples axis)
- when using this layer as the first layer in a model.
-
- Output shape:
- Same shape as the input.
-
- Arguments:
- theta: float >= 0. Threshold location of activation.
-
- """
-
- def __init__(self, theta=1.0, **kwargs):
- super(ThresholdedReLU, self).__init__(**kwargs)
- self.supports_masking = True
- self.theta = K.cast_to_floatx(theta)
-
- def call(self, inputs, mask=None):
- return inputs * K.cast(inputs > self.theta, K.floatx())
-
- def get_config(self):
- config = {'theta': float(self.theta)}
- base_config = super(ThresholdedReLU, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
diff --git a/tensorflow/contrib/keras/python/keras/layers/advanced_activations_test.py b/tensorflow/contrib/keras/python/keras/layers/advanced_activations_test.py
deleted file mode 100644
index 1be56123d8..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/advanced_activations_test.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for advanced activation layers."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-
-
-class AdvancedActivationsTest(test.TestCase):
-
- def test_leaky_relu(self):
- with self.test_session():
- for alpha in [0., .5, -1.]:
- testing_utils.layer_test(keras.layers.LeakyReLU,
- kwargs={'alpha': alpha},
- input_shape=(2, 3, 4))
-
- def test_prelu(self):
- with self.test_session():
- testing_utils.layer_test(keras.layers.PReLU, kwargs={},
- input_shape=(2, 3, 4))
-
- def test_prelu_share(self):
- with self.test_session():
- testing_utils.layer_test(keras.layers.PReLU,
- kwargs={'shared_axes': 1},
- input_shape=(2, 3, 4))
-
- def test_elu(self):
- with self.test_session():
- for alpha in [0., .5, -1.]:
- testing_utils.layer_test(keras.layers.ELU,
- kwargs={'alpha': alpha},
- input_shape=(2, 3, 4))
-
- def test_thresholded_relu(self):
- with self.test_session():
- testing_utils.layer_test(keras.layers.ThresholdedReLU,
- kwargs={'theta': 0.5},
- input_shape=(2, 3, 4))
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/layers/convolutional.py b/tensorflow/contrib/keras/python/keras/layers/convolutional.py
deleted file mode 100644
index 9eda94c1df..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/convolutional.py
+++ /dev/null
@@ -1,1656 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Keras convolution layers and image transformation layers.
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras import activations
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras import constraints
-from tensorflow.contrib.keras.python.keras import initializers
-from tensorflow.contrib.keras.python.keras import regularizers
-from tensorflow.contrib.keras.python.keras.engine import InputSpec
-from tensorflow.contrib.keras.python.keras.engine import Layer
-# imports for backwards namespace compatibility
-# pylint: disable=unused-import
-from tensorflow.contrib.keras.python.keras.layers.pooling import AveragePooling1D
-from tensorflow.contrib.keras.python.keras.layers.pooling import AveragePooling2D
-from tensorflow.contrib.keras.python.keras.layers.pooling import AveragePooling3D
-from tensorflow.contrib.keras.python.keras.layers.pooling import MaxPooling1D
-from tensorflow.contrib.keras.python.keras.layers.pooling import MaxPooling2D
-from tensorflow.contrib.keras.python.keras.layers.pooling import MaxPooling3D
-# pylint: enable=unused-import
-from tensorflow.contrib.keras.python.keras.utils import conv_utils
-from tensorflow.python.framework import tensor_shape
-from tensorflow.python.layers import convolutional as tf_convolutional_layers
-
-
-class Conv1D(tf_convolutional_layers.Conv1D, Layer):
- """1D convolution layer (e.g. temporal convolution).
-
- This layer creates a convolution kernel that is convolved
- with the layer input over a single spatial (or temporal) dimension
- to produce a tensor of outputs.
- If `use_bias` is True, a bias vector is created and added to the outputs.
- Finally, if `activation` is not `None`,
- it is applied to the outputs as well.
-
- When using this layer as the first layer in a model,
- provide an `input_shape` argument
- (tuple of integers or `None`, e.g.
- `(10, 128)` for sequences of 10 vectors of 128-dimensional vectors,
- or `(None, 128)` for variable-length sequences of 128-dimensional vectors.
-
- Arguments:
- filters: Integer, the dimensionality of the output space
- (i.e. the number output of filters in the convolution).
- kernel_size: An integer or tuple/list of a single integer,
- specifying the length of the 1D convolution window.
- strides: An integer or tuple/list of a single integer,
- specifying the stride length of the convolution.
- Specifying any stride value != 1 is incompatible with specifying
- any `dilation_rate` value != 1.
- padding: One of `"valid"`, `"causal"` or `"same"` (case-insensitive).
- `"causal"` results in causal (dilated) convolutions, e.g. output[t]
- does not depend on input[t+1:]. Useful when modeling temporal data
- where the model should not violate the temporal order.
- See [WaveNet: A Generative Model for Raw Audio, section
- 2.1](https://arxiv.org/abs/1609.03499).
- dilation_rate: an integer or tuple/list of a single integer, specifying
- the dilation rate to use for dilated convolution.
- Currently, specifying any `dilation_rate` value != 1 is
- incompatible with specifying any `strides` value != 1.
- activation: Activation function to use.
- If you don't specify anything, no activation is applied
- (ie. "linear" activation: `a(x) = x`).
- use_bias: Boolean, whether the layer uses a bias vector.
- kernel_initializer: Initializer for the `kernel` weights matrix.
- bias_initializer: Initializer for the bias vector.
- kernel_regularizer: Regularizer function applied to
- the `kernel` weights matrix.
- bias_regularizer: Regularizer function applied to the bias vector.
- activity_regularizer: Regularizer function applied to
- the output of the layer (its "activation")..
- kernel_constraint: Constraint function applied to the kernel matrix.
- bias_constraint: Constraint function applied to the bias vector.
-
- Input shape:
- 3D tensor with shape: `(batch_size, steps, input_dim)`
-
- Output shape:
- 3D tensor with shape: `(batch_size, new_steps, filters)`
- `steps` value might have changed due to padding or strides.
- """
-
- def __init__(self,
- filters,
- kernel_size,
- strides=1,
- padding='valid',
- dilation_rate=1,
- activation=None,
- use_bias=True,
- kernel_initializer='glorot_uniform',
- bias_initializer='zeros',
- kernel_regularizer=None,
- bias_regularizer=None,
- activity_regularizer=None,
- kernel_constraint=None,
- bias_constraint=None,
- **kwargs):
- super(Conv1D, self).__init__(
- filters=filters,
- kernel_size=kernel_size,
- strides=strides,
- padding=padding,
- data_format='channels_last',
- dilation_rate=dilation_rate,
- activation=activations.get(activation),
- use_bias=use_bias,
- kernel_initializer=initializers.get(kernel_initializer),
- bias_initializer=initializers.get(bias_initializer),
- kernel_regularizer=regularizers.get(kernel_regularizer),
- bias_regularizer=regularizers.get(bias_regularizer),
- activity_regularizer=regularizers.get(activity_regularizer),
- kernel_constraint=constraints.get(kernel_constraint),
- bias_constraint=constraints.get(bias_constraint),
- **kwargs)
-
- def get_config(self):
- config = {
- 'filters': self.filters,
- 'kernel_size': self.kernel_size,
- 'strides': self.strides,
- 'padding': self.padding,
- 'dilation_rate': self.dilation_rate,
- 'activation': activations.serialize(self.activation),
- 'use_bias': self.use_bias,
- 'kernel_initializer': initializers.serialize(self.kernel_initializer),
- 'bias_initializer': initializers.serialize(self.bias_initializer),
- '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)
- }
- base_config = super(Conv1D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Conv2D(tf_convolutional_layers.Conv2D, Layer):
- """2D convolution layer (e.g. spatial convolution over images).
-
- This layer creates a convolution kernel that is convolved
- with the layer input to produce a tensor of
- outputs. If `use_bias` is True,
- a bias vector is created and added to the outputs. Finally, if
- `activation` is not `None`, it is applied to the outputs as well.
-
- When using this layer as the first layer in a model,
- provide the keyword argument `input_shape`
- (tuple of integers, does not include the sample axis),
- e.g. `input_shape=(128, 128, 3)` for 128x128 RGB pictures
- in `data_format="channels_last"`.
-
- Arguments:
- filters: Integer, the dimensionality of the output space
- (i.e. the number output of filters in the convolution).
- kernel_size: An integer or tuple/list of 2 integers, specifying the
- width and height of the 2D convolution window.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- strides: An integer or tuple/list of 2 integers,
- specifying the strides of the convolution along the width and height.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- Specifying any stride value != 1 is incompatible with specifying
- any `dilation_rate` value != 1.
- padding: one of `"valid"` or `"same"` (case-insensitive).
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, height, width, channels)` while `channels_first`
- corresponds to inputs with shape
- `(batch, channels, height, width)`.
- 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 "channels_last".
- dilation_rate: an integer or tuple/list of 2 integers, specifying
- the dilation rate to use for dilated convolution.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- Currently, specifying any `dilation_rate` value != 1 is
- incompatible with specifying any stride value != 1.
- activation: Activation function to use.
- If you don't specify anything, no activation is applied
- (ie. "linear" activation: `a(x) = x`).
- use_bias: Boolean, whether the layer uses a bias vector.
- kernel_initializer: Initializer for the `kernel` weights matrix.
- bias_initializer: Initializer for the bias vector.
- kernel_regularizer: Regularizer function applied to
- the `kernel` weights matrix.
- bias_regularizer: Regularizer function applied to the bias vector.
- activity_regularizer: Regularizer function applied to
- the output of the layer (its "activation")..
- kernel_constraint: Constraint function applied to the kernel matrix.
- bias_constraint: Constraint function applied to the bias vector.
-
- Input shape:
- 4D tensor with shape:
- `(samples, channels, rows, cols)` if data_format='channels_first'
- or 4D tensor with shape:
- `(samples, rows, cols, channels)` if data_format='channels_last'.
-
- Output shape:
- 4D tensor with shape:
- `(samples, filters, new_rows, new_cols)` if data_format='channels_first'
- or 4D tensor with shape:
- `(samples, new_rows, new_cols, filters)` if data_format='channels_last'.
- `rows` and `cols` values might have changed due to padding.
- """
-
- def __init__(self,
- filters,
- kernel_size,
- strides=(1, 1),
- padding='valid',
- data_format=None,
- dilation_rate=(1, 1),
- activation=None,
- use_bias=True,
- kernel_initializer='glorot_uniform',
- bias_initializer='zeros',
- kernel_regularizer=None,
- bias_regularizer=None,
- activity_regularizer=None,
- kernel_constraint=None,
- bias_constraint=None,
- **kwargs):
- if data_format is None:
- data_format = K.image_data_format()
- super(Conv2D, self).__init__(
- filters=filters,
- kernel_size=kernel_size,
- strides=strides,
- padding=padding,
- data_format=data_format,
- dilation_rate=dilation_rate,
- activation=activations.get(activation),
- use_bias=use_bias,
- kernel_initializer=initializers.get(kernel_initializer),
- bias_initializer=initializers.get(bias_initializer),
- kernel_regularizer=regularizers.get(kernel_regularizer),
- bias_regularizer=regularizers.get(bias_regularizer),
- activity_regularizer=regularizers.get(activity_regularizer),
- kernel_constraint=constraints.get(kernel_constraint),
- bias_constraint=constraints.get(bias_constraint),
- **kwargs)
-
- def get_config(self):
- config = {
- 'filters': self.filters,
- 'kernel_size': self.kernel_size,
- 'strides': self.strides,
- 'padding': self.padding,
- 'data_format': self.data_format,
- 'dilation_rate': self.dilation_rate,
- 'activation': activations.serialize(self.activation),
- 'use_bias': self.use_bias,
- 'kernel_initializer': initializers.serialize(self.kernel_initializer),
- 'bias_initializer': initializers.serialize(self.bias_initializer),
- '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)
- }
- base_config = super(Conv2D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Conv3D(tf_convolutional_layers.Conv3D, Layer):
- """3D convolution layer (e.g. spatial convolution over volumes).
-
- This layer creates a convolution kernel that is convolved
- with the layer input to produce a tensor of
- outputs. If `use_bias` is True,
- a bias vector is created and added to the outputs. Finally, if
- `activation` is not `None`, it is applied to the outputs as well.
-
- When using this layer as the first layer in a model,
- provide the keyword argument `input_shape`
- (tuple of integers, does not include the sample axis),
- e.g. `input_shape=(128, 128, 128, 1)` for 128x128x128 volumes
- with a single channel,
- in `data_format="channels_last"`.
-
- Arguments:
- filters: Integer, the dimensionality of the output space
- (i.e. the number output of filters in the convolution).
- kernel_size: An integer or tuple/list of 3 integers, specifying the
- depth, height and width of the 3D convolution window.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- strides: An integer or tuple/list of 3 integers,
- specifying the strides of the convolution along each spatial
- dimension.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- Specifying any stride value != 1 is incompatible with specifying
- any `dilation_rate` value != 1.
- padding: one of `"valid"` or `"same"` (case-insensitive).
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
- while `channels_first` corresponds to inputs with shape
- `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
- 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 "channels_last".
- dilation_rate: an integer or tuple/list of 3 integers, specifying
- the dilation rate to use for dilated convolution.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- Currently, specifying any `dilation_rate` value != 1 is
- incompatible with specifying any stride value != 1.
- activation: Activation function to use.
- If you don't specify anything, no activation is applied
- (ie. "linear" activation: `a(x) = x`).
- use_bias: Boolean, whether the layer uses a bias vector.
- kernel_initializer: Initializer for the `kernel` weights matrix.
- bias_initializer: Initializer for the bias vector.
- kernel_regularizer: Regularizer function applied to
- the `kernel` weights matrix.
- bias_regularizer: Regularizer function applied to the bias vector.
- activity_regularizer: Regularizer function applied to
- the output of the layer (its "activation")..
- kernel_constraint: Constraint function applied to the kernel matrix.
- bias_constraint: Constraint function applied to the bias vector.
-
- Input shape:
- 5D tensor with shape:
- `(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
- data_format='channels_last'.
-
- Output shape:
- 5D tensor with shape:
- `(samples, filters, new_conv_dim1, new_conv_dim2, new_conv_dim3)` if
- data_format='channels_first'
- or 5D tensor with shape:
- `(samples, new_conv_dim1, new_conv_dim2, new_conv_dim3, filters)` if
- data_format='channels_last'.
- `new_conv_dim1`, `new_conv_dim2` and `new_conv_dim3` values might have
- changed due to padding.
- """
-
- def __init__(self,
- filters,
- kernel_size,
- strides=(1, 1, 1),
- padding='valid',
- data_format=None,
- dilation_rate=(1, 1, 1),
- activation=None,
- use_bias=True,
- kernel_initializer='glorot_uniform',
- bias_initializer='zeros',
- kernel_regularizer=None,
- bias_regularizer=None,
- activity_regularizer=None,
- kernel_constraint=None,
- bias_constraint=None,
- **kwargs):
- if data_format is None:
- data_format = K.image_data_format()
- super(Conv3D, self).__init__(
- filters=filters,
- kernel_size=kernel_size,
- strides=strides,
- padding=padding,
- data_format=data_format,
- dilation_rate=dilation_rate,
- activation=activations.get(activation),
- use_bias=use_bias,
- kernel_initializer=initializers.get(kernel_initializer),
- bias_initializer=initializers.get(bias_initializer),
- kernel_regularizer=regularizers.get(kernel_regularizer),
- bias_regularizer=regularizers.get(bias_regularizer),
- activity_regularizer=regularizers.get(activity_regularizer),
- kernel_constraint=constraints.get(kernel_constraint),
- bias_constraint=constraints.get(bias_constraint),
- **kwargs)
-
- def get_config(self):
- config = {
- 'filters': self.filters,
- 'kernel_size': self.kernel_size,
- 'strides': self.strides,
- 'padding': self.padding,
- 'data_format': self.data_format,
- 'dilation_rate': self.dilation_rate,
- 'activation': activations.serialize(self.activation),
- 'use_bias': self.use_bias,
- 'kernel_initializer': initializers.serialize(self.kernel_initializer),
- 'bias_initializer': initializers.serialize(self.bias_initializer),
- '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)
- }
- base_config = super(Conv3D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Conv2DTranspose(tf_convolutional_layers.Conv2DTranspose, Layer):
- """Transposed convolution layer (sometimes called Deconvolution).
-
- The need for transposed convolutions generally arises
- from the desire to use a transformation going in the opposite direction
- of a normal convolution, i.e., from something that has the shape of the
- output of some convolution to something that has the shape of its input
- while maintaining a connectivity pattern that is compatible with
- said convolution.
-
- When using this layer as the first layer in a model,
- provide the keyword argument `input_shape`
- (tuple of integers, does not include the sample axis),
- e.g. `input_shape=(128, 128, 3)` for 128x128 RGB pictures
- in `data_format="channels_last"`.
-
- Arguments:
- filters: Integer, the dimensionality of the output space
- (i.e. the number of output filters in the convolution).
- kernel_size: An integer or tuple/list of 2 integers, specifying the
- width and height of the 2D convolution window.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- strides: An integer or tuple/list of 2 integers,
- specifying the strides of the convolution along the width and height.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- Specifying any stride value != 1 is incompatible with specifying
- any `dilation_rate` value != 1.
- padding: one of `"valid"` or `"same"` (case-insensitive).
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, height, width, channels)` while `channels_first`
- corresponds to inputs with shape
- `(batch, channels, height, width)`.
- 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 "channels_last".
- dilation_rate: an integer or tuple/list of 2 integers, specifying
- the dilation rate to use for dilated convolution.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- Currently, specifying any `dilation_rate` value != 1 is
- incompatible with specifying any stride value != 1.
- activation: Activation function to use.
- If you don't specify anything, no activation is applied
- (ie. "linear" activation: `a(x) = x`).
- use_bias: Boolean, whether the layer uses a bias vector.
- kernel_initializer: Initializer for the `kernel` weights matrix.
- bias_initializer: Initializer for the bias vector.
- kernel_regularizer: Regularizer function applied to
- the `kernel` weights matrix.
- bias_regularizer: Regularizer function applied to the bias vector.
- activity_regularizer: Regularizer function applied to
- the output of the layer (its "activation")..
- kernel_constraint: Constraint function applied to the kernel matrix.
- bias_constraint: Constraint function applied to the bias vector.
-
- Input shape:
- 4D tensor with shape:
- `(batch, channels, rows, cols)` if data_format='channels_first'
- or 4D tensor with shape:
- `(batch, rows, cols, channels)` if data_format='channels_last'.
-
- Output shape:
- 4D tensor with shape:
- `(batch, filters, new_rows, new_cols)` if data_format='channels_first'
- or 4D tensor with shape:
- `(batch, new_rows, new_cols, filters)` if data_format='channels_last'.
- `rows` and `cols` values might have changed due to padding.
-
- References:
- - [A guide to convolution arithmetic for deep
- learning](https://arxiv.org/abs/1603.07285v1)
- - [Deconvolutional
- Networks](http://www.matthewzeiler.com/pubs/cvpr2010/cvpr2010.pdf)
- """
-
- def __init__(self,
- filters,
- kernel_size,
- strides=(1, 1),
- padding='valid',
- data_format=None,
- activation=None,
- use_bias=True,
- kernel_initializer='glorot_uniform',
- bias_initializer='zeros',
- kernel_regularizer=None,
- bias_regularizer=None,
- activity_regularizer=None,
- kernel_constraint=None,
- bias_constraint=None,
- **kwargs):
- if data_format is None:
- data_format = K.image_data_format()
- super(Conv2DTranspose, self).__init__(
- filters=filters,
- kernel_size=kernel_size,
- strides=strides,
- padding=padding,
- data_format=data_format,
- activation=activations.get(activation),
- use_bias=use_bias,
- kernel_initializer=initializers.get(kernel_initializer),
- bias_initializer=initializers.get(bias_initializer),
- kernel_regularizer=regularizers.get(kernel_regularizer),
- bias_regularizer=regularizers.get(bias_regularizer),
- activity_regularizer=regularizers.get(activity_regularizer),
- kernel_constraint=constraints.get(kernel_constraint),
- bias_constraint=constraints.get(bias_constraint),
- **kwargs)
-
- def get_config(self):
- config = {
- 'filters': self.filters,
- 'kernel_size': self.kernel_size,
- 'strides': self.strides,
- 'padding': self.padding,
- 'data_format': self.data_format,
- 'activation': activations.serialize(self.activation),
- 'use_bias': self.use_bias,
- 'kernel_initializer': initializers.serialize(self.kernel_initializer),
- 'bias_initializer': initializers.serialize(self.bias_initializer),
- '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)
- }
- base_config = super(Conv2DTranspose, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Conv3DTranspose(tf_convolutional_layers.Conv3D, Layer):
- """Transposed convolution layer (sometimes called Deconvolution).
-
- The need for transposed convolutions generally arises
- from the desire to use a transformation going in the opposite direction
- of a normal convolution, i.e., from something that has the shape of the
- output of some convolution to something that has the shape of its input
- while maintaining a connectivity pattern that is compatible with
- said convolution.
-
- When using this layer as the first layer in a model,
- provide the keyword argument `input_shape`
- (tuple of integers, does not include the sample axis),
- e.g. `input_shape=(128, 128, 128, 3)` for a 128x128x128 volume with 3 channels
- if `data_format="channels_last"`.
-
- Arguments:
- filters: Integer, the dimensionality of the output space
- (i.e. the number of output filters in the convolution).
- kernel_size: An integer or tuple/list of 3 integers, specifying the
- depth, height and width of the 3D convolution window.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- strides: An integer or tuple/list of 3 integers,
- specifying the strides of the convolution along the depth, height
- and width.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- Specifying any stride value != 1 is incompatible with specifying
- any `dilation_rate` value != 1.
- padding: one of `"valid"` or `"same"` (case-insensitive).
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, depth, height, width, channels)` while `channels_first`
- corresponds to inputs with shape
- `(batch, channels, depth, height, width)`.
- 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 "channels_last".
- dilation_rate: an integer or tuple/list of 3 integers, specifying
- the dilation rate to use for dilated convolution.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- Currently, specifying any `dilation_rate` value != 1 is
- incompatible with specifying any stride value != 1.
- activation: Activation function to use
- (see [activations](../activations.md)).
- If you don't specify anything, no activation is applied
- (ie. "linear" activation: `a(x) = x`).
- use_bias: Boolean, whether the layer uses a bias vector.
- kernel_initializer: Initializer for the `kernel` weights matrix
- (see [initializers](../initializers.md)).
- bias_initializer: Initializer for the bias vector
- (see [initializers](../initializers.md)).
- kernel_regularizer: Regularizer function applied to
- the `kernel` weights matrix
- (see [regularizer](../regularizers.md)).
- bias_regularizer: Regularizer function applied to the bias vector
- (see [regularizer](../regularizers.md)).
- activity_regularizer: Regularizer function applied to
- the output of the layer (its "activation").
- (see [regularizer](../regularizers.md)).
- kernel_constraint: Constraint function applied to the kernel matrix
- (see [constraints](../constraints.md)).
- bias_constraint: Constraint function applied to the bias vector
- (see [constraints](../constraints.md)).
-
- Input shape:
- 5D tensor with shape:
- `(batch, channels, depth, rows, cols)` if data_format='channels_first'
- or 5D tensor with shape:
- `(batch, depth, rows, cols, channels)` if data_format='channels_last'.
-
- Output shape:
- 5D tensor with shape:
- `(batch, filters, new_depth, new_rows, new_cols)` if
- data_format='channels_first'
- or 5D tensor with shape:
- `(batch, new_depth, new_rows, new_cols, filters)` if
- data_format='channels_last'.
- `depth` and `rows` and `cols` values might have changed due to padding.
-
- References:
- - [A guide to convolution arithmetic for deep
- learning](https://arxiv.org/abs/1603.07285v1)
- - [Deconvolutional
- Networks](http://www.matthewzeiler.com/pubs/cvpr2010/cvpr2010.pdf)
- """
-
- def __init__(self,
- filters,
- kernel_size,
- strides=(1, 1, 1),
- padding='valid',
- data_format=None,
- activation=None,
- use_bias=True,
- kernel_initializer='glorot_uniform',
- bias_initializer='zeros',
- kernel_regularizer=None,
- bias_regularizer=None,
- activity_regularizer=None,
- kernel_constraint=None,
- bias_constraint=None,
- **kwargs):
- if data_format is None:
- data_format = K.image_data_format()
- super(Conv3DTranspose, self).__init__(
- filters=filters,
- kernel_size=kernel_size,
- strides=strides,
- padding=padding,
- data_format=data_format,
- activation=activations.get(activation),
- use_bias=use_bias,
- kernel_initializer=initializers.get(kernel_initializer),
- bias_initializer=initializers.get(bias_initializer),
- kernel_regularizer=regularizers.get(kernel_regularizer),
- bias_regularizer=regularizers.get(bias_regularizer),
- activity_regularizer=regularizers.get(activity_regularizer),
- kernel_constraint=constraints.get(kernel_constraint),
- bias_constraint=constraints.get(bias_constraint),
- **kwargs)
-
- def get_config(self):
- config = {
- 'filters': self.filters,
- 'kernel_size': self.kernel_size,
- 'strides': self.strides,
- 'padding': self.padding,
- 'data_format': self.data_format,
- 'activation': activations.serialize(self.activation),
- 'use_bias': self.use_bias,
- 'kernel_initializer': initializers.serialize(self.kernel_initializer),
- 'bias_initializer': initializers.serialize(self.bias_initializer),
- '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)
- }
- base_config = super(Conv3DTranspose, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class SeparableConv2D(tf_convolutional_layers.SeparableConv2D, Layer):
- """Depthwise separable 2D convolution.
-
- Separable convolutions consist in first performing
- a depthwise spatial convolution
- (which acts on each input channel separately)
- followed by a pointwise convolution which mixes together the resulting
- output channels. The `depth_multiplier` argument controls how many
- output channels are generated per input channel in the depthwise step.
-
- Intuitively, separable convolutions can be understood as
- a way to factorize a convolution kernel into two smaller kernels,
- or as an extreme version of an Inception block.
-
- Arguments:
- filters: Integer, the dimensionality of the output space
- (i.e. the number output of filters in the convolution).
- kernel_size: An integer or tuple/list of 2 integers, specifying the
- width and height of the 2D convolution window.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- strides: An integer or tuple/list of 2 integers,
- specifying the strides of the convolution along the width and height.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- Specifying any stride value != 1 is incompatible with specifying
- any `dilation_rate` value != 1.
- padding: one of `"valid"` or `"same"` (case-insensitive).
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, height, width, channels)` while `channels_first`
- corresponds to inputs with shape
- `(batch, channels, height, width)`.
- 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 "channels_last".
- depth_multiplier: The number of depthwise convolution output channels
- for each input channel.
- The total number of depthwise convolution output
- channels will be equal to `filterss_in * depth_multiplier`.
- activation: Activation function to use.
- If you don't specify anything, no activation is applied
- (ie. "linear" activation: `a(x) = x`).
- use_bias: Boolean, whether the layer uses a bias vector.
- depthwise_initializer: Initializer for the depthwise kernel matrix.
- pointwise_initializer: Initializer for the pointwise kernel matrix.
- bias_initializer: Initializer for the bias vector.
- depthwise_regularizer: Regularizer function applied to
- the depthwise kernel matrix.
- pointwise_regularizer: Regularizer function applied to
- the pointwise kernel matrix.
- bias_regularizer: Regularizer function applied to the bias vector.
- activity_regularizer: Regularizer function applied to
- the output of the layer (its "activation")..
- depthwise_constraint: Constraint function applied to
- the depthwise kernel matrix.
- pointwise_constraint: Constraint function applied to
- the pointwise kernel matrix.
- bias_constraint: Constraint function applied to the bias vector.
-
- Input shape:
- 4D tensor with shape:
- `(batch, channels, rows, cols)` if data_format='channels_first'
- or 4D tensor with shape:
- `(batch, rows, cols, channels)` if data_format='channels_last'.
-
- Output shape:
- 4D tensor with shape:
- `(batch, filters, new_rows, new_cols)` if data_format='channels_first'
- or 4D tensor with shape:
- `(batch, new_rows, new_cols, filters)` if data_format='channels_last'.
- `rows` and `cols` values might have changed due to padding.
- """
-
- def __init__(self,
- filters,
- kernel_size,
- strides=(1, 1),
- padding='valid',
- data_format=None,
- depth_multiplier=1,
- activation=None,
- use_bias=True,
- depthwise_initializer='glorot_uniform',
- pointwise_initializer='glorot_uniform',
- bias_initializer='zeros',
- depthwise_regularizer=None,
- pointwise_regularizer=None,
- bias_regularizer=None,
- activity_regularizer=None,
- depthwise_constraint=None,
- pointwise_constraint=None,
- bias_constraint=None,
- **kwargs):
- if data_format is None:
- data_format = K.image_data_format()
- super(SeparableConv2D, self).__init__(
- filters=filters,
- kernel_size=kernel_size,
- strides=strides,
- padding=padding,
- data_format=data_format,
- activation=activations.get(activation),
- use_bias=use_bias,
- depthwise_initializer=initializers.get(depthwise_initializer),
- pointwise_initializer=initializers.get(pointwise_initializer),
- bias_initializer=initializers.get(bias_initializer),
- depthwise_regularizer=regularizers.get(depthwise_regularizer),
- pointwise_regularizer=regularizers.get(pointwise_regularizer),
- bias_regularizer=regularizers.get(bias_regularizer),
- activity_regularizer=regularizers.get(activity_regularizer),
- depthwise_constraint=constraints.get(depthwise_constraint),
- pointwise_constraint=constraints.get(pointwise_constraint),
- bias_constraint=constraints.get(bias_constraint),
- **kwargs)
-
- def get_config(self):
- config = {
- 'filters': self.filters,
- 'kernel_size': self.kernel_size,
- 'strides': self.strides,
- 'padding': self.padding,
- 'data_format': self.data_format,
- 'activation': activations.serialize(self.activation),
- 'use_bias': self.use_bias,
- 'depthwise_initializer': initializers.serialize(
- self.depthwise_initializer),
- 'pointwise_initializer': initializers.serialize(
- self.pointwise_initializer),
- 'bias_initializer': initializers.serialize(self.bias_initializer),
- 'depthwise_regularizer': regularizers.serialize(
- self.depthwise_regularizer),
- 'pointwise_regularizer': regularizers.serialize(
- self.pointwise_regularizer),
- 'bias_regularizer': regularizers.serialize(self.bias_regularizer),
- 'activity_regularizer':
- regularizers.serialize(self.activity_regularizer),
- 'depthwise_constraint': constraints.serialize(
- self.depthwise_constraint),
- 'pointwise_constraint': constraints.serialize(
- self.pointwise_constraint),
- 'bias_constraint': constraints.serialize(self.bias_constraint)
- }
- base_config = super(SeparableConv2D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class UpSampling1D(Layer):
- """Upsampling layer for 1D inputs.
-
- Repeats each temporal step `size` times along the time axis.
-
- Arguments:
- size: integer. Upsampling factor.
-
- Input shape:
- 3D tensor with shape: `(batch, steps, features)`.
-
- Output shape:
- 3D tensor with shape: `(batch, upsampled_steps, features)`.
- """
-
- def __init__(self, size=2, **kwargs):
- super(UpSampling1D, self).__init__(**kwargs)
- self.size = int(size)
- self.input_spec = InputSpec(ndim=3)
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- size = self.size * input_shape[1] if input_shape[1] is not None else None
- return tensor_shape.TensorShape([input_shape[0], size, input_shape[2]])
-
- def call(self, inputs):
- output = K.repeat_elements(inputs, self.size, axis=1)
- return output
-
- def get_config(self):
- config = {'size': self.size}
- base_config = super(UpSampling1D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class UpSampling2D(Layer):
- """Upsampling layer for 2D inputs.
-
- Repeats the rows and columns of the data
- by size[0] and size[1] respectively.
-
- Arguments:
- size: int, or tuple of 2 integers.
- The upsampling factors for rows and columns.
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, height, width, channels)` while `channels_first`
- corresponds to inputs with shape
- `(batch, channels, height, width)`.
- 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 "channels_last".
-
- Input shape:
- 4D tensor with shape:
- - If `data_format` is `"channels_last"`:
- `(batch, rows, cols, channels)`
- - If `data_format` is `"channels_first"`:
- `(batch, channels, rows, cols)`
-
- Output shape:
- 4D tensor with shape:
- - If `data_format` is `"channels_last"`:
- `(batch, upsampled_rows, upsampled_cols, channels)`
- - If `data_format` is `"channels_first"`:
- `(batch, channels, upsampled_rows, upsampled_cols)`
- """
-
- def __init__(self, size=(2, 2), data_format=None, **kwargs):
- super(UpSampling2D, self).__init__(**kwargs)
- self.data_format = conv_utils.normalize_data_format(data_format)
- self.size = conv_utils.normalize_tuple(size, 2, 'size')
- self.input_spec = InputSpec(ndim=4)
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- if self.data_format == 'channels_first':
- height = self.size[0] * input_shape[
- 2] if input_shape[2] is not None else None
- width = self.size[1] * input_shape[
- 3] if input_shape[3] is not None else None
- return tensor_shape.TensorShape(
- [input_shape[0], input_shape[1], height, width])
- else:
- height = self.size[0] * input_shape[
- 1] if input_shape[1] is not None else None
- width = self.size[1] * input_shape[
- 2] if input_shape[2] is not None else None
- return tensor_shape.TensorShape(
- [input_shape[0], height, width, input_shape[3]])
-
- def call(self, inputs):
- return K.resize_images(inputs, self.size[0], self.size[1], self.data_format)
-
- def get_config(self):
- config = {'size': self.size, 'data_format': self.data_format}
- base_config = super(UpSampling2D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class UpSampling3D(Layer):
- """Upsampling layer for 3D inputs.
-
- Repeats the 1st, 2nd and 3rd dimensions
- of the data by size[0], size[1] and size[2] respectively.
-
- Arguments:
- size: int, or tuple of 3 integers.
- The upsampling factors for dim1, dim2 and dim3.
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
- while `channels_first` corresponds to inputs with shape
- `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
- 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 "channels_last".
-
- Input shape:
- 5D tensor with shape:
- - If `data_format` is `"channels_last"`:
- `(batch, dim1, dim2, dim3, channels)`
- - If `data_format` is `"channels_first"`:
- `(batch, channels, dim1, dim2, dim3)`
-
- Output shape:
- 5D tensor with shape:
- - If `data_format` is `"channels_last"`:
- `(batch, upsampled_dim1, upsampled_dim2, upsampled_dim3, channels)`
- - If `data_format` is `"channels_first"`:
- `(batch, channels, upsampled_dim1, upsampled_dim2, upsampled_dim3)`
- """
-
- def __init__(self, size=(2, 2, 2), data_format=None, **kwargs):
- self.data_format = conv_utils.normalize_data_format(data_format)
- self.size = conv_utils.normalize_tuple(size, 3, 'size')
- self.input_spec = InputSpec(ndim=5)
- super(UpSampling3D, self).__init__(**kwargs)
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- if self.data_format == 'channels_first':
- dim1 = self.size[0] * input_shape[
- 2] if input_shape[2] is not None else None
- dim2 = self.size[1] * input_shape[
- 3] if input_shape[3] is not None else None
- dim3 = self.size[2] * input_shape[
- 4] if input_shape[4] is not None else None
- return tensor_shape.TensorShape(
- [input_shape[0], input_shape[1], dim1, dim2, dim3])
- else:
- dim1 = self.size[0] * input_shape[
- 1] if input_shape[1] is not None else None
- dim2 = self.size[1] * input_shape[
- 2] if input_shape[2] is not None else None
- dim3 = self.size[2] * input_shape[
- 3] if input_shape[3] is not None else None
- return tensor_shape.TensorShape(
- [input_shape[0], dim1, dim2, dim3, input_shape[4]])
-
- def call(self, inputs):
- return K.resize_volumes(inputs, self.size[0], self.size[1], self.size[2],
- self.data_format)
-
- def get_config(self):
- config = {'size': self.size, 'data_format': self.data_format}
- base_config = super(UpSampling3D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class ZeroPadding1D(Layer):
- """Zero-padding layer for 1D input (e.g. temporal sequence).
-
- Arguments:
- padding: int, or tuple of int (length 2), or dictionary.
- - If int:
- How many zeros to add at the beginning and end of
- the padding dimension (axis 1).
- - If tuple of int (length 2):
- How many zeros to add at the beginning and at the end of
- the padding dimension (`(left_pad, right_pad)`).
-
- Input shape:
- 3D tensor with shape `(batch, axis_to_pad, features)`
-
- Output shape:
- 3D tensor with shape `(batch, padded_axis, features)`
- """
-
- def __init__(self, padding=1, **kwargs):
- super(ZeroPadding1D, self).__init__(**kwargs)
- self.padding = conv_utils.normalize_tuple(padding, 2, 'padding')
- self.input_spec = InputSpec(ndim=3)
-
- def _compute_output_shape(self, input_shape):
- if input_shape[1] is not None:
- length = input_shape[1] + self.padding[0] + self.padding[1]
- else:
- length = None
- return tensor_shape.TensorShape([input_shape[0], length, input_shape[2]])
-
- def call(self, inputs):
- return K.temporal_padding(inputs, padding=self.padding)
-
- def get_config(self):
- config = {'padding': self.padding}
- base_config = super(ZeroPadding1D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class ZeroPadding2D(Layer):
- """Zero-padding layer for 2D input (e.g. picture).
-
- This layer can add rows and columns of zeros
- at the top, bottom, left and right side of an image tensor.
-
- Arguments:
- padding: int, or tuple of 2 ints, or tuple of 2 tuples of 2 ints.
- - If int: the same symmetric padding
- is applied to width and height.
- - If tuple of 2 ints:
- interpreted as two different
- symmetric padding values for height and width:
- `(symmetric_height_pad, symmetric_width_pad)`.
- - If tuple of 2 tuples of 2 ints:
- interpreted as
- `((top_pad, bottom_pad), (left_pad, right_pad))`
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, height, width, channels)` while `channels_first`
- corresponds to inputs with shape
- `(batch, channels, height, width)`.
- 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 "channels_last".
-
- Input shape:
- 4D tensor with shape:
- - If `data_format` is `"channels_last"`:
- `(batch, rows, cols, channels)`
- - If `data_format` is `"channels_first"`:
- `(batch, channels, rows, cols)`
-
- Output shape:
- 4D tensor with shape:
- - If `data_format` is `"channels_last"`:
- `(batch, padded_rows, padded_cols, channels)`
- - If `data_format` is `"channels_first"`:
- `(batch, channels, padded_rows, padded_cols)`
- """
-
- def __init__(self, padding=(1, 1), data_format=None, **kwargs):
- super(ZeroPadding2D, self).__init__(**kwargs)
- self.data_format = conv_utils.normalize_data_format(data_format)
- if isinstance(padding, int):
- self.padding = ((padding, padding), (padding, padding))
- elif hasattr(padding, '__len__'):
- if len(padding) != 2:
- raise ValueError('`padding` should have two elements. '
- 'Found: ' + str(padding))
- height_padding = conv_utils.normalize_tuple(padding[0], 2,
- '1st entry of padding')
- width_padding = conv_utils.normalize_tuple(padding[1], 2,
- '2nd entry of padding')
- self.padding = (height_padding, width_padding)
- else:
- raise ValueError('`padding` should be either an int, '
- 'a tuple of 2 ints '
- '(symmetric_height_pad, symmetric_width_pad), '
- 'or a tuple of 2 tuples of 2 ints '
- '((top_pad, bottom_pad), (left_pad, right_pad)). '
- 'Found: ' + str(padding))
- self.input_spec = InputSpec(ndim=4)
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- if self.data_format == 'channels_first':
- if input_shape[2] is not None:
- rows = input_shape[2] + self.padding[0][0] + self.padding[0][1]
- else:
- rows = None
- if input_shape[3] is not None:
- cols = input_shape[3] + self.padding[1][0] + self.padding[1][1]
- else:
- cols = None
- return tensor_shape.TensorShape(
- [input_shape[0], input_shape[1], rows, cols])
- elif self.data_format == 'channels_last':
- if input_shape[1] is not None:
- rows = input_shape[1] + self.padding[0][0] + self.padding[0][1]
- else:
- rows = None
- if input_shape[2] is not None:
- cols = input_shape[2] + self.padding[1][0] + self.padding[1][1]
- else:
- cols = None
- return tensor_shape.TensorShape(
- [input_shape[0], rows, cols, input_shape[3]])
-
- def call(self, inputs):
- return K.spatial_2d_padding(
- inputs, padding=self.padding, data_format=self.data_format)
-
- def get_config(self):
- config = {'padding': self.padding, 'data_format': self.data_format}
- base_config = super(ZeroPadding2D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class ZeroPadding3D(Layer):
- """Zero-padding layer for 3D data (spatial or spatio-temporal).
-
- Arguments:
- padding: int, or tuple of 2 ints, or tuple of 2 tuples of 2 ints.
- - If int: the same symmetric padding
- is applied to width and height.
- - If tuple of 2 ints:
- interpreted as two different
- symmetric padding values for height and width:
- `(symmetric_dim1_pad, symmetric_dim2_pad, symmetric_dim3_pad)`.
- - If tuple of 2 tuples of 2 ints:
- interpreted as
- `((left_dim1_pad, right_dim1_pad), (left_dim2_pad,
- right_dim2_pad), (left_dim3_pad, right_dim3_pad))`
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
- while `channels_first` corresponds to inputs with shape
- `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
- 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 "channels_last".
-
- Input shape:
- 5D tensor with shape:
- - If `data_format` is `"channels_last"`:
- `(batch, first_axis_to_pad, second_axis_to_pad, third_axis_to_pad,
- depth)`
- - If `data_format` is `"channels_first"`:
- `(batch, depth, first_axis_to_pad, second_axis_to_pad,
- third_axis_to_pad)`
-
- Output shape:
- 5D tensor with shape:
- - If `data_format` is `"channels_last"`:
- `(batch, first_padded_axis, second_padded_axis, third_axis_to_pad,
- depth)`
- - If `data_format` is `"channels_first"`:
- `(batch, depth, first_padded_axis, second_padded_axis,
- third_axis_to_pad)`
- """
-
- def __init__(self, padding=(1, 1, 1), data_format=None, **kwargs):
- super(ZeroPadding3D, self).__init__(**kwargs)
- self.data_format = conv_utils.normalize_data_format(data_format)
- if isinstance(padding, int):
- self.padding = ((padding, padding), (padding, padding), (padding,
- padding))
- elif hasattr(padding, '__len__'):
- if len(padding) != 3:
- raise ValueError('`padding` should have 3 elements. '
- 'Found: ' + str(padding))
- dim1_padding = conv_utils.normalize_tuple(padding[0], 2,
- '1st entry of padding')
- dim2_padding = conv_utils.normalize_tuple(padding[1], 2,
- '2nd entry of padding')
- dim3_padding = conv_utils.normalize_tuple(padding[2], 2,
- '3rd entry of padding')
- self.padding = (dim1_padding, dim2_padding, dim3_padding)
- else:
- raise ValueError(
- '`padding` should be either an int, '
- 'a tuple of 3 ints '
- '(symmetric_dim1_pad, symmetric_dim2_pad, symmetric_dim3_pad), '
- 'or a tuple of 3 tuples of 2 ints '
- '((left_dim1_pad, right_dim1_pad),'
- ' (left_dim2_pad, right_dim2_pad),'
- ' (left_dim3_pad, right_dim2_pad)). '
- 'Found: ' + str(padding))
- self.input_spec = InputSpec(ndim=5)
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- if self.data_format == 'channels_first':
- if input_shape[2] is not None:
- dim1 = input_shape[2] + 2 * self.padding[0][0]
- else:
- dim1 = None
- if input_shape[3] is not None:
- dim2 = input_shape[3] + 2 * self.padding[1][0]
- else:
- dim2 = None
- if input_shape[4] is not None:
- dim3 = input_shape[4] + 2 * self.padding[2][0]
- else:
- dim3 = None
- return tensor_shape.TensorShape(
- [input_shape[0], input_shape[1], dim1, dim2, dim3])
- elif self.data_format == 'channels_last':
- if input_shape[1] is not None:
- dim1 = input_shape[1] + 2 * self.padding[0][1]
- else:
- dim1 = None
- if input_shape[2] is not None:
- dim2 = input_shape[2] + 2 * self.padding[1][1]
- else:
- dim2 = None
- if input_shape[3] is not None:
- dim3 = input_shape[3] + 2 * self.padding[2][1]
- else:
- dim3 = None
- return tensor_shape.TensorShape(
- [input_shape[0], dim1, dim2, dim3, input_shape[4]])
-
- def call(self, inputs):
- return K.spatial_3d_padding(
- inputs, padding=self.padding, data_format=self.data_format)
-
- def get_config(self):
- config = {'padding': self.padding, 'data_format': self.data_format}
- base_config = super(ZeroPadding3D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Cropping1D(Layer):
- """Cropping layer for 1D input (e.g. temporal sequence).
-
- It crops along the time dimension (axis 1).
-
- Arguments:
- cropping: int or tuple of int (length 2)
- How many units should be trimmed off at the beginning and end of
- the cropping dimension (axis 1).
- If a single int is provided,
- the same value will be used for both.
-
- Input shape:
- 3D tensor with shape `(batch, axis_to_crop, features)`
-
- Output shape:
- 3D tensor with shape `(batch, cropped_axis, features)`
- """
-
- def __init__(self, cropping=(1, 1), **kwargs):
- super(Cropping1D, self).__init__(**kwargs)
- self.cropping = conv_utils.normalize_tuple(cropping, 2, 'cropping')
- self.input_spec = InputSpec(ndim=3)
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- if input_shape[1] is not None:
- length = input_shape[1] - self.cropping[0] - self.cropping[1]
- else:
- length = None
- return tensor_shape.TensorShape([input_shape[0], length, input_shape[2]])
-
- def call(self, inputs):
- if self.cropping[1] == 0:
- return inputs[:, self.cropping[0]:, :]
- else:
- return inputs[:, self.cropping[0]:-self.cropping[1], :]
-
- def get_config(self):
- config = {'cropping': self.cropping}
- base_config = super(Cropping1D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Cropping2D(Layer):
- """Cropping layer for 2D input (e.g. picture).
-
- It crops along spatial dimensions, i.e. width and height.
-
- Arguments:
- cropping: int, or tuple of 2 ints, or tuple of 2 tuples of 2 ints.
- - If int: the same symmetric cropping
- is applied to width and height.
- - If tuple of 2 ints:
- interpreted as two different
- symmetric cropping values for height and width:
- `(symmetric_height_crop, symmetric_width_crop)`.
- - If tuple of 2 tuples of 2 ints:
- interpreted as
- `((top_crop, bottom_crop), (left_crop, right_crop))`
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, height, width, channels)` while `channels_first`
- corresponds to inputs with shape
- `(batch, channels, height, width)`.
- 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 "channels_last".
-
- Input shape:
- 4D tensor with shape:
- - If `data_format` is `"channels_last"`:
- `(batch, rows, cols, channels)`
- - If `data_format` is `"channels_first"`:
- `(batch, channels, rows, cols)`
-
- Output shape:
- 4D tensor with shape:
- - If `data_format` is `"channels_last"`:
- `(batch, cropped_rows, cropped_cols, channels)`
- - If `data_format` is `"channels_first"`:
- `(batch, channels, cropped_rows, cropped_cols)`
-
- Examples:
-
- ```python
- # Crop the input 2D images or feature maps
- model = Sequential()
- model.add(Cropping2D(cropping=((2, 2), (4, 4)),
- input_shape=(28, 28, 3)))
- # now model.output_shape == (None, 24, 20, 3)
- model.add(Conv2D(64, (3, 3), padding='same))
- model.add(Cropping2D(cropping=((2, 2), (2, 2))))
- # now model.output_shape == (None, 20, 16. 64)
- ```
- """
-
- def __init__(self, cropping=((0, 0), (0, 0)), data_format=None, **kwargs):
- super(Cropping2D, self).__init__(**kwargs)
- self.data_format = conv_utils.normalize_data_format(data_format)
- if isinstance(cropping, int):
- self.cropping = ((cropping, cropping), (cropping, cropping))
- elif hasattr(cropping, '__len__'):
- if len(cropping) != 2:
- raise ValueError('`cropping` should have two elements. '
- 'Found: ' + str(cropping))
- height_cropping = conv_utils.normalize_tuple(cropping[0], 2,
- '1st entry of cropping')
- width_cropping = conv_utils.normalize_tuple(cropping[1], 2,
- '2nd entry of cropping')
- self.cropping = (height_cropping, width_cropping)
- else:
- raise ValueError('`cropping` should be either an int, '
- 'a tuple of 2 ints '
- '(symmetric_height_crop, symmetric_width_crop), '
- 'or a tuple of 2 tuples of 2 ints '
- '((top_crop, bottom_crop), (left_crop, right_crop)). '
- 'Found: ' + str(cropping))
- self.input_spec = InputSpec(ndim=4)
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- # pylint: disable=invalid-unary-operand-type
- if self.data_format == 'channels_first':
- return tensor_shape.TensorShape([
- input_shape[0], input_shape[1],
- input_shape[2] - self.cropping[0][0] - self.cropping[0][1]
- if input_shape[2] else None,
- input_shape[3] - self.cropping[1][0] - self.cropping[1][1]
- if input_shape[3] else None
- ])
- else:
- return tensor_shape.TensorShape([
- input_shape[0],
- input_shape[1] - self.cropping[0][0] - self.cropping[0][1]
- if input_shape[1] else None,
- input_shape[2] - self.cropping[1][0] - self.cropping[1][1]
- if input_shape[2] else None, input_shape[3]
- ])
- # pylint: enable=invalid-unary-operand-type
-
- def call(self, inputs):
- # pylint: disable=invalid-unary-operand-type
- if self.data_format == 'channels_first':
- if self.cropping[0][1] == self.cropping[1][1] == 0:
- return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:]
- elif self.cropping[0][1] == 0:
- return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:
- -self.cropping[1][1]]
- elif self.cropping[1][1] == 0:
- return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1],
- self.cropping[1][0]:]
- return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1],
- self.cropping[1][0]:-self.cropping[1][1]]
- else:
- if self.cropping[0][1] == self.cropping[1][1] == 0:
- return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:, :]
- elif self.cropping[0][1] == 0:
- return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:
- -self.cropping[1][1], :]
- elif self.cropping[1][1] == 0:
- return inputs[:, self.cropping[0][0]:-self.cropping[0][1],
- self.cropping[1][0]:, :]
- return inputs[:, self.cropping[0][0]:-self.cropping[0][1], self.cropping[
- 1][0]:-self.cropping[1][1], :] # pylint: disable=invalid-unary-operand-type
- # pylint: enable=invalid-unary-operand-type
-
- def get_config(self):
- config = {'cropping': self.cropping, 'data_format': self.data_format}
- base_config = super(Cropping2D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Cropping3D(Layer):
- """Cropping layer for 3D data (e.g.
-
- spatial or spatio-temporal).
-
- Arguments:
- cropping: int, or tuple of 23ints, or tuple of 3 tuples of 2 ints.
- - If int: the same symmetric cropping
- is applied to depth, height, and width.
- - If tuple of 3 ints:
- interpreted as two different
- symmetric cropping values for depth, height, and width:
- `(symmetric_dim1_crop, symmetric_dim2_crop, symmetric_dim3_crop)`.
- - If tuple of 3 tuples of 2 ints:
- interpreted as
- `((left_dim1_crop, right_dim1_crop), (left_dim2_crop,
- right_dim2_crop), (left_dim3_crop, right_dim3_crop))`
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
- while `channels_first` corresponds to inputs with shape
- `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
- 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 "channels_last".
-
- Input shape:
- 5D tensor with shape:
- - If `data_format` is `"channels_last"`:
- `(batch, first_axis_to_crop, second_axis_to_crop, third_axis_to_crop,
- depth)`
- - If `data_format` is `"channels_first"`:
- `(batch, depth, first_axis_to_crop, second_axis_to_crop,
- third_axis_to_crop)`
-
- Output shape:
- 5D tensor with shape:
- - If `data_format` is `"channels_last"`:
- `(batch, first_cropped_axis, second_cropped_axis, third_cropped_axis,
- depth)`
- - If `data_format` is `"channels_first"`:
- `(batch, depth, first_cropped_axis, second_cropped_axis,
- third_cropped_axis)`
- """
-
- def __init__(self,
- cropping=((1, 1), (1, 1), (1, 1)),
- data_format=None,
- **kwargs):
- super(Cropping3D, self).__init__(**kwargs)
- self.data_format = conv_utils.normalize_data_format(data_format)
- if isinstance(cropping, int):
- self.cropping = ((cropping, cropping), (cropping, cropping), (cropping,
- cropping))
- elif hasattr(cropping, '__len__'):
- if len(cropping) != 3:
- raise ValueError('`cropping` should have 3 elements. '
- 'Found: ' + str(cropping))
- dim1_cropping = conv_utils.normalize_tuple(cropping[0], 2,
- '1st entry of cropping')
- dim2_cropping = conv_utils.normalize_tuple(cropping[1], 2,
- '2nd entry of cropping')
- dim3_cropping = conv_utils.normalize_tuple(cropping[2], 2,
- '3rd entry of cropping')
- self.cropping = (dim1_cropping, dim2_cropping, dim3_cropping)
- else:
- raise ValueError(
- '`cropping` should be either an int, '
- 'a tuple of 3 ints '
- '(symmetric_dim1_crop, symmetric_dim2_crop, symmetric_dim3_crop), '
- 'or a tuple of 3 tuples of 2 ints '
- '((left_dim1_crop, right_dim1_crop),'
- ' (left_dim2_crop, right_dim2_crop),'
- ' (left_dim3_crop, right_dim2_crop)). '
- 'Found: ' + str(cropping))
- self.input_spec = InputSpec(ndim=5)
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- # pylint: disable=invalid-unary-operand-type
- if self.data_format == 'channels_first':
- if input_shape[2] is not None:
- dim1 = input_shape[2] - self.cropping[0][0] - self.cropping[0][1]
- else:
- dim1 = None
- if input_shape[3] is not None:
- dim2 = input_shape[3] - self.cropping[1][0] - self.cropping[1][1]
- else:
- dim2 = None
- if input_shape[4] is not None:
- dim3 = input_shape[4] - self.cropping[2][0] - self.cropping[2][1]
- else:
- dim3 = None
- return tensor_shape.TensorShape(
- [input_shape[0], input_shape[1], dim1, dim2, dim3])
- elif self.data_format == 'channels_last':
- if input_shape[1] is not None:
- dim1 = input_shape[1] - self.cropping[0][0] - self.cropping[0][1]
- else:
- dim1 = None
- if input_shape[2] is not None:
- dim2 = input_shape[2] - self.cropping[1][0] - self.cropping[1][1]
- else:
- dim2 = None
- if input_shape[3] is not None:
- dim3 = input_shape[3] - self.cropping[2][0] - self.cropping[2][1]
- else:
- dim3 = None
- return tensor_shape.TensorShape(
- [input_shape[0], dim1, dim2, dim3, input_shape[4]])
- # pylint: enable=invalid-unary-operand-type
-
- def call(self, inputs):
- # pylint: disable=invalid-unary-operand-type
- if self.data_format == 'channels_first':
- if self.cropping[0][1] == self.cropping[1][1] == self.cropping[2][1] == 0:
- return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:,
- self.cropping[2][0]:]
- elif self.cropping[0][1] == self.cropping[1][1] == 0:
- return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:,
- self.cropping[2][0]:-self.cropping[2][1]]
- elif self.cropping[1][1] == self.cropping[2][1] == 0:
- return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1],
- self.cropping[1][0]:, self.cropping[2][0]:]
- elif self.cropping[0][1] == self.cropping[2][1] == 0:
- return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:
- -self.cropping[1][1], self.cropping[2][0]:]
- elif self.cropping[0][1] == 0:
- return inputs[:, :, self.cropping[0][0]:, self.cropping[1][
- 0]:-self.cropping[1][1], self.cropping[2][0]:-self.cropping[2][1]]
- elif self.cropping[1][1] == 0:
- return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1], self.
- cropping[1][0]:, self.cropping[2][0]:-self.cropping[2][1]]
- elif self.cropping[2][1] == 0:
- return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1], self.
- cropping[1][0]:-self.cropping[1][1], self.cropping[2][0]:]
- return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1],
- self.cropping[1][0]:-self.cropping[1][1], self.cropping[2][
- 0]:-self.cropping[2][1]]
- else:
- if self.cropping[0][1] == self.cropping[1][1] == self.cropping[2][1] == 0:
- return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:,
- self.cropping[2][0]:, :]
- elif self.cropping[0][1] == self.cropping[1][1] == 0:
- return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:,
- self.cropping[2][0]:-self.cropping[2][1], :]
- elif self.cropping[1][1] == self.cropping[2][1] == 0:
- return inputs[:, self.cropping[0][0]:-self.cropping[0][1],
- self.cropping[1][0]:, self.cropping[2][0]:, :]
- elif self.cropping[0][1] == self.cropping[2][1] == 0:
- return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:
- -self.cropping[1][1], self.cropping[2][0]:, :]
- elif self.cropping[0][1] == 0:
- return inputs[:, self.cropping[0][0]:, self.cropping[1][
- 0]:-self.cropping[1][1], self.cropping[2][0]:
- -self.cropping[2][1], :]
- elif self.cropping[1][1] == 0:
- return inputs[:, self.cropping[0][
- 0]:-self.cropping[0][1], self.cropping[1][0]:, self.cropping[2][0]:
- -self.cropping[2][1], :]
- elif self.cropping[2][1] == 0:
- return inputs[:, self.cropping[0][0]:-self.cropping[0][1],
- self.cropping[1][0]:-self.cropping[1][1], self.cropping[
- 2][0]:, :]
- return inputs[:, self.cropping[0][0]:-self.cropping[0][1], self.cropping[
- 1][0]:-self.cropping[1][1], self.cropping[2][0]: # pylint: disable=invalid-unary-operand-type
- -self.cropping[2][1], :] # pylint: disable=invalid-unary-operand-type
- # pylint: enable=invalid-unary-operand-type
-
- def get_config(self):
- config = {'cropping': self.cropping, 'data_format': self.data_format}
- base_config = super(Cropping3D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-# Aliases
-
-Convolution1D = Conv1D
-Convolution2D = Conv2D
-Convolution3D = Conv3D
-SeparableConvolution2D = SeparableConv2D
-Convolution2DTranspose = Conv2DTranspose
-Convolution3DTranspose = Conv3DTranspose
-Deconvolution2D = Deconv2D = Conv2DTranspose
-Deconvolution3D = Deconv3D = Conv3DTranspose
diff --git a/tensorflow/contrib/keras/python/keras/layers/convolutional_recurrent.py b/tensorflow/contrib/keras/python/keras/layers/convolutional_recurrent.py
deleted file mode 100644
index ed5aea2e57..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/convolutional_recurrent.py
+++ /dev/null
@@ -1,607 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Convolutional-recurrent layers.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python.keras import activations
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras import constraints
-from tensorflow.contrib.keras.python.keras import initializers
-from tensorflow.contrib.keras.python.keras import regularizers
-from tensorflow.contrib.keras.python.keras.engine import InputSpec
-from tensorflow.contrib.keras.python.keras.layers.recurrent import Recurrent
-from tensorflow.contrib.keras.python.keras.utils import conv_utils
-from tensorflow.python.framework import tensor_shape
-
-
-class ConvRecurrent2D(Recurrent):
- """Abstract base class for convolutional recurrent layers.
-
- Do not use in a model -- it's not a functional layer!
-
- Arguments:
- filters: Integer, the dimensionality of the output space
- (i.e. the number output of filters in the convolution).
- kernel_size: An integer or tuple/list of n integers, specifying the
- dimensions of the convolution window.
- strides: An integer or tuple/list of n integers,
- specifying the strides of the convolution.
- Specifying any stride value != 1 is incompatible with specifying
- any `dilation_rate` value != 1.
- padding: One of `"valid"` or `"same"` (case-insensitive).
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, time, ..., channels)`
- while `channels_first` corresponds to
- inputs with shape `(batch, time, channels, ...)`.
- 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 "channels_last".
- dilation_rate: An integer or tuple/list of n integers, specifying
- the dilation rate to use for dilated convolution.
- Currently, specifying any `dilation_rate` value != 1 is
- incompatible with specifying any `strides` value != 1.
- return_sequences: Boolean. Whether to return the last output
- in the output sequence, or the full sequence.
- go_backwards: Boolean (default False).
- If True, rocess the input sequence backwards.
- stateful: Boolean (default False). If True, the last state
- for each sample at index i in a batch will be used as initial
- state for the sample of index i in the following batch.
-
- Input shape:
- 5D tensor with shape `(num_samples, timesteps, channels, rows, cols)`.
-
- Output shape:
- - if `return_sequences`: 5D tensor with shape
- `(num_samples, timesteps, channels, rows, cols)`.
- - else, 4D tensor with shape `(num_samples, channels, rows, cols)`.
-
- # Masking
- This layer supports masking for input data with a variable number
- of timesteps. To introduce masks to your data,
- use an `Embedding` layer with the `mask_zero` parameter
- set to `True`.
- **Note:** for the time being, masking is only supported with Theano.
-
- # Note on using statefulness in RNNs
- You can set RNN layers to be 'stateful', which means that the states
- computed for the samples in one batch will be reused as initial states
- for the samples in the next batch.
- This assumes a one-to-one mapping between
- samples in different successive batches.
-
- To enable statefulness:
- - specify `stateful=True` in the layer constructor.
- - specify a fixed batch size for your model, by passing
- a `batch_input_size=(...)` to the first layer in your model.
- This is the expected shape of your inputs *including the batch
- size*.
- It should be a tuple of integers, e.g. `(32, 10, 100)`.
-
- To reset the states of your model, call `.reset_states()` on either
- a specific layer, or on your entire model.
- """
-
- def __init__(self,
- filters,
- kernel_size,
- strides=(1, 1),
- padding='valid',
- data_format=None,
- dilation_rate=(1, 1),
- return_sequences=False,
- go_backwards=False,
- stateful=False,
- **kwargs):
- super(ConvRecurrent2D, self).__init__(**kwargs)
- self.filters = filters
- self.kernel_size = conv_utils.normalize_tuple(kernel_size, 2, 'kernel_size')
- self.strides = conv_utils.normalize_tuple(strides, 2, 'strides')
- self.padding = conv_utils.normalize_padding(padding)
- self.data_format = conv_utils.normalize_data_format(data_format)
- self.dilation_rate = conv_utils.normalize_tuple(dilation_rate, 2,
- 'dilation_rate')
- self.return_sequences = return_sequences
- self.go_backwards = go_backwards
- self.stateful = stateful
- self.input_spec = [InputSpec(ndim=5)]
- self.state_spec = None
-
- def _compute_output_shape(self, input_shape):
- if isinstance(input_shape, list):
- input_shape = input_shape[0]
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- if self.data_format == 'channels_first':
- rows = input_shape[3]
- cols = input_shape[4]
- elif self.data_format == 'channels_last':
- rows = input_shape[2]
- cols = input_shape[3]
- rows = conv_utils.conv_output_length(
- rows,
- self.kernel_size[0],
- padding=self.padding,
- stride=self.strides[0],
- dilation=self.dilation_rate[0])
- cols = conv_utils.conv_output_length(
- cols,
- self.kernel_size[1],
- padding=self.padding,
- stride=self.strides[1],
- dilation=self.dilation_rate[1])
- if self.return_sequences:
- if self.data_format == 'channels_first':
- output_shape = [input_shape[0], input_shape[1],
- self.filters, rows, cols]
- elif self.data_format == 'channels_last':
- output_shape = [input_shape[0], input_shape[1],
- rows, cols, self.filters]
- else:
- if self.data_format == 'channels_first':
- output_shape = [input_shape[0], self.filters, rows, cols]
- elif self.data_format == 'channels_last':
- output_shape = [input_shape[0], rows, cols, self.filters]
-
- if self.return_state:
- if self.data_format == 'channels_first':
- output_shapes = [output_shape] + [(input_shape[0],
- self.filters,
- rows,
- cols) for _ in range(2)]
- elif self.data_format == 'channels_last':
- output_shapes = [output_shape] + [(input_shape[0],
- rows,
- cols,
- self.filters) for _ in range(2)]
- return [tensor_shape.TensorShape(shape) for shape in output_shapes]
- return tensor_shape.TensorShape(output_shape)
-
- def get_config(self):
- config = {
- 'filters': self.filters,
- 'kernel_size': self.kernel_size,
- 'strides': self.strides,
- 'padding': self.padding,
- 'data_format': self.data_format,
- 'dilation_rate': self.dilation_rate,
- 'return_sequences': self.return_sequences,
- 'go_backwards': self.go_backwards,
- 'stateful': self.stateful
- }
- base_config = super(ConvRecurrent2D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class ConvLSTM2D(ConvRecurrent2D):
- """Convolutional LSTM.
-
- It is similar to an LSTM layer, but the input transformations
- and recurrent transformations are both convolutional.
-
- Arguments:
- filters: Integer, the dimensionality of the output space
- (i.e. the number output of filters in the convolution).
- kernel_size: An integer or tuple/list of n integers, specifying the
- dimensions of the convolution window.
- strides: An integer or tuple/list of n integers,
- specifying the strides of the convolution.
- Specifying any stride value != 1 is incompatible with specifying
- any `dilation_rate` value != 1.
- padding: One of `"valid"` or `"same"` (case-insensitive).
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, time, ..., channels)`
- while `channels_first` corresponds to
- inputs with shape `(batch, time, channels, ...)`.
- 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 "channels_last".
- dilation_rate: An integer or tuple/list of n integers, specifying
- the dilation rate to use for dilated convolution.
- Currently, specifying any `dilation_rate` value != 1 is
- incompatible with specifying any `strides` value != 1.
- activation: Activation function to use.
- If you don't specify anything, no activation is applied
- (ie. "linear" activation: `a(x) = x`).
- recurrent_activation: Activation function to use
- for the recurrent step.
- use_bias: Boolean, whether the layer uses a bias vector.
- kernel_initializer: Initializer for the `kernel` weights matrix,
- used for the linear transformation of the inputs..
- recurrent_initializer: Initializer for the `recurrent_kernel`
- weights matrix,
- used for the linear transformation of the recurrent state..
- bias_initializer: Initializer for the bias vector.
- unit_forget_bias: Boolean.
- If True, add 1 to the bias of the forget gate at initialization.
- Use in combination with `bias_initializer="zeros"`.
- This is recommended in [Jozefowicz et
- al.](http://www.jmlr.org/proceedings/papers/v37/jozefowicz15.pdf)
- kernel_regularizer: Regularizer function applied to
- the `kernel` weights matrix.
- recurrent_regularizer: Regularizer function applied to
- the `recurrent_kernel` weights matrix.
- bias_regularizer: Regularizer function applied to the bias vector.
- activity_regularizer: Regularizer function applied to
- the output of the layer (its "activation")..
- kernel_constraint: Constraint function applied to
- the `kernel` weights matrix.
- recurrent_constraint: Constraint function applied to
- the `recurrent_kernel` weights matrix.
- bias_constraint: Constraint function applied to the bias vector.
- return_sequences: Boolean. Whether to return the last output
- in the output sequence, or the full sequence.
- go_backwards: Boolean (default False).
- If True, rocess the input sequence backwards.
- stateful: Boolean (default False). If True, the last state
- for each sample at index i in a batch will be used as initial
- state for the sample of index i in the following batch.
- dropout: Float between 0 and 1.
- Fraction of the units to drop for
- the linear transformation of the inputs.
- recurrent_dropout: Float between 0 and 1.
- Fraction of the units to drop for
- the linear transformation of the recurrent state.
-
- Input shape:
- - if data_format='channels_first'
- 5D tensor with shape:
- `(samples,time, channels, rows, cols)`
- - if data_format='channels_last'
- 5D tensor with shape:
- `(samples,time, rows, cols, channels)`
-
- Output shape:
- - if `return_sequences`
- - if data_format='channels_first'
- 5D tensor with shape:
- `(samples, time, filters, output_row, output_col)`
- - if data_format='channels_last'
- 5D tensor with shape:
- `(samples, time, output_row, output_col, filters)`
- - else
- - if data_format ='channels_first'
- 4D tensor with shape:
- `(samples, filters, output_row, output_col)`
- - if data_format='channels_last'
- 4D tensor with shape:
- `(samples, output_row, output_col, filters)`
- where o_row and o_col depend on the shape of the filter and
- the padding
-
- Raises:
- ValueError: in case of invalid constructor arguments.
-
- References:
- - [Convolutional LSTM Network: A Machine Learning Approach for
- Precipitation Nowcasting](http://arxiv.org/abs/1506.04214v1)
- The current implementation does not include the feedback loop on the
- cells output
- """
-
- def __init__(self,
- filters,
- kernel_size,
- strides=(1, 1),
- padding='valid',
- data_format=None,
- dilation_rate=(1, 1),
- activation='tanh',
- recurrent_activation='hard_sigmoid',
- use_bias=True,
- kernel_initializer='glorot_uniform',
- recurrent_initializer='orthogonal',
- bias_initializer='zeros',
- unit_forget_bias=True,
- kernel_regularizer=None,
- recurrent_regularizer=None,
- bias_regularizer=None,
- activity_regularizer=None,
- kernel_constraint=None,
- recurrent_constraint=None,
- bias_constraint=None,
- return_sequences=False,
- go_backwards=False,
- stateful=False,
- dropout=0.,
- recurrent_dropout=0.,
- **kwargs):
- super(ConvLSTM2D, self).__init__(
- filters,
- kernel_size,
- strides=strides,
- padding=padding,
- data_format=data_format,
- dilation_rate=dilation_rate,
- return_sequences=return_sequences,
- go_backwards=go_backwards,
- stateful=stateful,
- **kwargs)
- self.activation = activations.get(activation)
- self.recurrent_activation = activations.get(recurrent_activation)
- self.use_bias = use_bias
-
- self.kernel_initializer = initializers.get(kernel_initializer)
- self.recurrent_initializer = initializers.get(recurrent_initializer)
- self.bias_initializer = initializers.get(bias_initializer)
- self.unit_forget_bias = unit_forget_bias
-
- self.kernel_regularizer = regularizers.get(kernel_regularizer)
- self.recurrent_regularizer = regularizers.get(recurrent_regularizer)
- self.bias_regularizer = regularizers.get(bias_regularizer)
- self.activity_regularizer = regularizers.get(activity_regularizer)
-
- self.kernel_constraint = constraints.get(kernel_constraint)
- self.recurrent_constraint = constraints.get(recurrent_constraint)
- self.bias_constraint = constraints.get(bias_constraint)
-
- self.dropout = min(1., max(0., dropout))
- self.recurrent_dropout = min(1., max(0., recurrent_dropout))
- self.state_spec = [InputSpec(ndim=4), InputSpec(ndim=4)]
-
- def build(self, input_shape):
- if isinstance(input_shape, list):
- input_shape = input_shape[0]
- input_shape = tuple(tensor_shape.TensorShape(input_shape).as_list())
- batch_size = input_shape[0] if self.stateful else None
- self.input_spec[0] = InputSpec(shape=(batch_size, None) + input_shape[2:])
-
- if self.stateful:
- self.reset_states()
- else:
- # initial states: 2 all-zero tensor of shape (filters)
- self.states = [None, None]
-
- if self.data_format == 'channels_first':
- channel_axis = 2
- else:
- channel_axis = -1
- if input_shape[channel_axis] is None:
- raise ValueError('The channel dimension of the inputs '
- 'should be defined. Found `None`.')
- input_dim = input_shape[channel_axis]
- state_shape = [None] * 4
- state_shape[channel_axis] = input_dim
- state_shape = tuple(state_shape)
- self.state_spec = [
- InputSpec(shape=state_shape),
- InputSpec(shape=state_shape)
- ]
- kernel_shape = self.kernel_size + (input_dim, self.filters * 4)
- self.kernel_shape = kernel_shape
- recurrent_kernel_shape = self.kernel_size + (self.filters, self.filters * 4)
-
- self.kernel = self.add_weight(
- shape=kernel_shape,
- initializer=self.kernel_initializer,
- name='kernel',
- regularizer=self.kernel_regularizer,
- constraint=self.kernel_constraint)
- self.recurrent_kernel = self.add_weight(
- shape=recurrent_kernel_shape,
- initializer=self.recurrent_initializer,
- name='recurrent_kernel',
- regularizer=self.recurrent_regularizer,
- constraint=self.recurrent_constraint)
- if self.use_bias:
- self.bias = self.add_weight(
- shape=(self.filters * 4,),
- initializer=self.bias_initializer,
- name='bias',
- regularizer=self.bias_regularizer,
- constraint=self.bias_constraint)
- if self.unit_forget_bias:
- bias_value = np.zeros((self.filters * 4,))
- bias_value[self.filters:self.filters * 2] = 1.
- K.set_value(self.bias, bias_value)
- else:
- self.bias = None
-
- self.kernel_i = self.kernel[:, :, :, :self.filters]
- self.recurrent_kernel_i = self.recurrent_kernel[:, :, :, :self.filters]
- self.kernel_f = self.kernel[:, :, :, self.filters:self.filters * 2]
- self.recurrent_kernel_f = self.recurrent_kernel[:, :, :, self.filters:
- self.filters * 2]
- self.kernel_c = self.kernel[:, :, :, self.filters * 2:self.filters * 3]
- self.recurrent_kernel_c = self.recurrent_kernel[:, :, :, self.filters * 2:
- self.filters * 3]
- self.kernel_o = self.kernel[:, :, :, self.filters * 3:]
- self.recurrent_kernel_o = self.recurrent_kernel[:, :, :, self.filters * 3:]
-
- if self.use_bias:
- self.bias_i = self.bias[:self.filters]
- self.bias_f = self.bias[self.filters:self.filters * 2]
- self.bias_c = self.bias[self.filters * 2:self.filters * 3]
- self.bias_o = self.bias[self.filters * 3:]
- else:
- self.bias_i = None
- self.bias_f = None
- self.bias_c = None
- self.bias_o = None
- self.built = True
-
- def get_initial_state(self, inputs):
- # (samples, timesteps, rows, cols, filters)
- initial_state = K.zeros_like(inputs)
- # (samples, rows, cols, filters)
- initial_state = K.sum(initial_state, axis=1)
- shape = list(self.kernel_shape)
- shape[-1] = self.filters
- initial_state = self.input_conv(
- initial_state, K.zeros(tuple(shape)), padding=self.padding)
-
- initial_states = [initial_state for _ in range(2)]
- return initial_states
-
- def reset_states(self):
- if not self.stateful:
- raise RuntimeError('Layer must be stateful.')
- input_shape = self.input_spec[0].shape
-
- if not input_shape[0]:
- raise ValueError('If a RNN is stateful, a complete '
- 'input_shape must be provided '
- '(including batch size). '
- 'Got input shape: ' + str(input_shape))
-
- if self.return_state:
- output_shape = tuple(self._compute_output_shape(input_shape)[0].as_list())
- else:
- output_shape = tuple(self._compute_output_shape(input_shape).as_list())
- if self.return_sequences:
- output_shape = (input_shape[0],) + output_shape[2:]
- else:
- output_shape = (input_shape[0],) + output_shape[1:]
-
- if hasattr(self, 'states'):
- K.set_value(self.states[0],
- np.zeros(output_shape))
- K.set_value(self.states[1],
- np.zeros(output_shape))
- else:
- self.states = [
- K.zeros(output_shape),
- K.zeros(output_shape)
- ]
-
- def get_constants(self, inputs, training=None):
- constants = []
- if self.implementation == 0 and 0 < self.dropout < 1:
- ones = K.zeros_like(inputs)
- ones = K.sum(ones, axis=1)
- ones += 1
-
- def dropped_inputs():
- return K.dropout(ones, self.dropout)
-
- dp_mask = [
- K.in_train_phase(dropped_inputs, ones, training=training)
- for _ in range(4)
- ]
- constants.append(dp_mask)
- else:
- constants.append([K.cast_to_floatx(1.) for _ in range(4)])
-
- if 0 < self.recurrent_dropout < 1:
- shape = list(self.kernel_shape)
- shape[-1] = self.filters
- ones = K.zeros_like(inputs)
- ones = K.sum(ones, axis=1)
- ones = self.input_conv(ones, K.zeros(shape), padding=self.padding)
- ones += 1.
-
- def dropped_inputs(): # pylint: disable=function-redefined
- return K.dropout(ones, self.recurrent_dropout)
-
- rec_dp_mask = [
- K.in_train_phase(dropped_inputs, ones, training=training)
- for _ in range(4)
- ]
- constants.append(rec_dp_mask)
- else:
- constants.append([K.cast_to_floatx(1.) for _ in range(4)])
- return constants
-
- def input_conv(self, x, w, b=None, padding='valid'):
- conv_out = K.conv2d(
- x,
- w,
- strides=self.strides,
- padding=padding,
- data_format=self.data_format,
- dilation_rate=self.dilation_rate)
- if b is not None:
- conv_out = K.bias_add(conv_out, b, data_format=self.data_format)
- return conv_out
-
- def reccurent_conv(self, x, w):
- conv_out = K.conv2d(
- x, w, strides=(1, 1), padding='same', data_format=self.data_format)
- return conv_out
-
- def step(self, inputs, states):
- assert len(states) == 4
- h_tm1 = states[0]
- c_tm1 = states[1]
- dp_mask = states[2]
- rec_dp_mask = states[3]
-
- x_i = self.input_conv(
- inputs * dp_mask[0], self.kernel_i, self.bias_i, padding=self.padding)
- x_f = self.input_conv(
- inputs * dp_mask[1], self.kernel_f, self.bias_f, padding=self.padding)
- x_c = self.input_conv(
- inputs * dp_mask[2], self.kernel_c, self.bias_c, padding=self.padding)
- x_o = self.input_conv(
- inputs * dp_mask[3], self.kernel_o, self.bias_o, padding=self.padding)
- h_i = self.reccurent_conv(h_tm1 * rec_dp_mask[0], self.recurrent_kernel_i)
- h_f = self.reccurent_conv(h_tm1 * rec_dp_mask[1], self.recurrent_kernel_f)
- h_c = self.reccurent_conv(h_tm1 * rec_dp_mask[2], self.recurrent_kernel_c)
- h_o = self.reccurent_conv(h_tm1 * rec_dp_mask[3], self.recurrent_kernel_o)
-
- i = self.recurrent_activation(x_i + h_i)
- f = self.recurrent_activation(x_f + h_f)
- c = f * c_tm1 + i * self.activation(x_c + h_c)
- o = self.recurrent_activation(x_o + h_o)
- h = o * self.activation(c)
- return h, [h, c]
-
- def get_config(self):
- config = {
- 'activation':
- activations.serialize(self.activation),
- 'recurrent_activation':
- activations.serialize(self.recurrent_activation),
- 'use_bias':
- self.use_bias,
- 'kernel_initializer':
- initializers.serialize(self.kernel_initializer),
- 'recurrent_initializer':
- initializers.serialize(self.recurrent_initializer),
- 'bias_initializer':
- initializers.serialize(self.bias_initializer),
- 'unit_forget_bias':
- self.unit_forget_bias,
- 'kernel_regularizer':
- regularizers.serialize(self.kernel_regularizer),
- 'recurrent_regularizer':
- regularizers.serialize(self.recurrent_regularizer),
- 'bias_regularizer':
- regularizers.serialize(self.bias_regularizer),
- 'activity_regularizer':
- regularizers.serialize(self.activity_regularizer),
- 'kernel_constraint':
- constraints.serialize(self.kernel_constraint),
- 'recurrent_constraint':
- constraints.serialize(self.recurrent_constraint),
- 'bias_constraint':
- constraints.serialize(self.bias_constraint),
- 'dropout':
- self.dropout,
- 'recurrent_dropout':
- self.recurrent_dropout
- }
- base_config = super(ConvLSTM2D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
diff --git a/tensorflow/contrib/keras/python/keras/layers/convolutional_recurrent_test.py b/tensorflow/contrib/keras/python/keras/layers/convolutional_recurrent_test.py
deleted file mode 100644
index 1ce17f0c31..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/convolutional_recurrent_test.py
+++ /dev/null
@@ -1,184 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for convolutional recurrent layers."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-
-
-class ConvLSTMTest(test.TestCase):
-
- def test_conv_lstm(self):
- num_row = 3
- num_col = 3
- filters = 2
- num_samples = 1
- input_channel = 2
- input_num_row = 5
- input_num_col = 5
- sequence_len = 2
- for data_format in ['channels_first', 'channels_last']:
- if data_format == 'channels_first':
- inputs = np.random.rand(num_samples, sequence_len,
- input_channel,
- input_num_row, input_num_col)
- else:
- inputs = np.random.rand(num_samples, sequence_len,
- input_num_row, input_num_col,
- input_channel)
-
- for return_sequences in [True, False]:
- with self.test_session():
- # test for return state:
- x = keras.Input(batch_shape=inputs.shape)
- kwargs = {'data_format': data_format,
- 'return_sequences': return_sequences,
- 'return_state': True,
- 'stateful': True,
- 'filters': filters,
- 'kernel_size': (num_row, num_col),
- 'padding': 'valid'}
- layer = keras.layers.ConvLSTM2D(**kwargs)
- layer.build(inputs.shape)
- outputs = layer(x)
- _, states = outputs[0], outputs[1:]
- self.assertEqual(len(states), 2)
- model = keras.models.Model(x, states[0])
- state = model.predict(inputs)
- self.assertAllClose(
- keras.backend.eval(layer.states[0]), state, atol=1e-4)
-
- # test for output shape:
- testing_utils.layer_test(
- keras.layers.ConvLSTM2D,
- kwargs={'data_format': data_format,
- 'return_sequences': return_sequences,
- 'filters': filters,
- 'kernel_size': (num_row, num_col),
- 'padding': 'valid'},
- input_shape=inputs.shape)
-
- def test_conv_lstm_statefulness(self):
- # Tests for statefulness
- num_row = 3
- num_col = 3
- filters = 2
- num_samples = 1
- input_channel = 2
- input_num_row = 5
- input_num_col = 5
- sequence_len = 2
- inputs = np.random.rand(num_samples, sequence_len,
- input_num_row, input_num_col,
- input_channel)
-
- with self.test_session():
- model = keras.models.Sequential()
- kwargs = {'data_format': 'channels_last',
- 'return_sequences': False,
- 'filters': filters,
- 'kernel_size': (num_row, num_col),
- 'stateful': True,
- 'batch_input_shape': inputs.shape,
- 'padding': 'same'}
- layer = keras.layers.ConvLSTM2D(**kwargs)
-
- model.add(layer)
- model.compile(optimizer='sgd', loss='mse')
- out1 = model.predict(np.ones_like(inputs))
-
- # train once so that the states change
- model.train_on_batch(np.ones_like(inputs),
- np.random.random(out1.shape))
- out2 = model.predict(np.ones_like(inputs))
-
- # if the state is not reset, output should be different
- self.assertNotEqual(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_like(inputs))
- self.assertNotEqual(out3.max(), out2.max())
-
- # check that container-level reset_states() works
- model.reset_states()
- out4 = model.predict(np.ones_like(inputs))
- self.assertAllClose(out3, out4, atol=1e-5)
-
- # check that the call to `predict` updated the states
- out5 = model.predict(np.ones_like(inputs))
- self.assertNotEqual(out4.max(), out5.max())
-
- def test_conv_lstm_regularizers(self):
- # check regularizers
- num_row = 3
- num_col = 3
- filters = 2
- num_samples = 1
- input_channel = 2
- input_num_row = 5
- input_num_col = 5
- sequence_len = 2
- inputs = np.random.rand(num_samples, sequence_len,
- input_num_row, input_num_col,
- input_channel)
-
- with self.test_session():
- kwargs = {'data_format': 'channels_last',
- 'return_sequences': False,
- 'kernel_size': (num_row, num_col),
- 'stateful': True,
- 'filters': filters,
- 'batch_input_shape': inputs.shape,
- 'kernel_regularizer': keras.regularizers.L1L2(l1=0.01),
- 'recurrent_regularizer': keras.regularizers.L1L2(l1=0.01),
- 'activity_regularizer': 'l2',
- 'bias_regularizer': 'l2',
- 'kernel_constraint': 'max_norm',
- 'recurrent_constraint': 'max_norm',
- 'bias_constraint': 'max_norm',
- 'padding': 'same'}
-
- layer = keras.layers.ConvLSTM2D(**kwargs)
- layer.build(inputs.shape)
- self.assertEqual(len(layer.losses), 3)
- layer(keras.backend.variable(np.ones(inputs.shape)))
- self.assertEqual(len(layer.losses), 4)
-
- def test_conv_lstm_dropout(self):
- # check dropout
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.ConvLSTM2D,
- kwargs={'data_format': 'channels_last',
- 'return_sequences': False,
- 'filters': 2,
- 'kernel_size': (3, 3),
- 'padding': 'same',
- 'dropout': 0.1,
- 'recurrent_dropout': 0.1},
- input_shape=(1, 2, 5, 5, 2))
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/layers/convolutional_test.py b/tensorflow/contrib/keras/python/keras/layers/convolutional_test.py
deleted file mode 100644
index 00a7fbf8fb..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/convolutional_test.py
+++ /dev/null
@@ -1,842 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for convolutional layers."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-
-
-class Convolution1DTest(test.TestCase):
-
- def test_dilated_conv1d(self):
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.Conv1D,
- input_data=np.reshape(np.arange(4, dtype='float32'), (1, 4, 1)),
- kwargs={
- 'filters': 1,
- 'kernel_size': 2,
- 'dilation_rate': 1,
- 'padding': 'valid',
- 'kernel_initializer': 'ones',
- 'use_bias': False,
- },
- expected_output=[[[1], [3], [5]]])
-
- def test_conv_1d(self):
- batch_size = 2
- steps = 8
- input_dim = 2
- kernel_size = 3
- filters = 3
-
- for padding in ['valid', 'same']:
- for strides in [1, 2]:
- if padding == 'same' and strides != 1:
- continue
-
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.Conv1D,
- kwargs={
- 'filters': filters,
- 'kernel_size': kernel_size,
- 'padding': padding,
- 'strides': strides
- },
- input_shape=(batch_size, steps, input_dim))
-
- def test_conv_1d_regularizers(self):
- kwargs = {
- 'filters': 3,
- 'kernel_size': 3,
- 'padding': 'valid',
- 'kernel_regularizer': 'l2',
- 'bias_regularizer': 'l2',
- 'activity_regularizer': 'l2',
- 'strides': 1
- }
- with self.test_session(use_gpu=True):
- layer = keras.layers.Conv1D(**kwargs)
- layer.build((None, 5, 2))
- self.assertEqual(len(layer.losses), 2)
- layer(keras.backend.variable(np.ones((1, 5, 2))))
- self.assertEqual(len(layer.losses), 3)
-
- def test_conv_1d_constraints(self):
- k_constraint = lambda x: x
- b_constraint = lambda x: x
-
- kwargs = {
- 'filters': 3,
- 'kernel_size': 3,
- 'padding': 'valid',
- 'kernel_constraint': k_constraint,
- 'bias_constraint': b_constraint,
- 'strides': 1
- }
- with self.test_session(use_gpu=True):
- layer = keras.layers.Conv1D(**kwargs)
- layer.build((None, 5, 2))
- self.assertEqual(layer.kernel.constraint, k_constraint)
- self.assertEqual(layer.bias.constraint, b_constraint)
-
-
-class Conv2DTest(test.TestCase):
-
- def test_convolution_2d(self):
- num_samples = 2
- filters = 2
- stack_size = 3
- kernel_size = (3, 2)
- num_row = 7
- num_col = 6
-
- for padding in ['valid', 'same']:
- for strides in [(1, 1), (2, 2)]:
- if padding == 'same' and strides != (1, 1):
- continue
-
- with self.test_session(use_gpu=True):
- # Only runs on GPU with CUDA, channels_first is not supported on CPU.
- # TODO(b/62340061): Support channels_first on CPU.
- if test.is_gpu_available(cuda_only=True):
- testing_utils.layer_test(
- keras.layers.Conv2D,
- kwargs={
- 'filters': filters,
- 'kernel_size': kernel_size,
- 'padding': padding,
- 'strides': strides,
- 'data_format': 'channels_first'
- },
- input_shape=(num_samples, stack_size, num_row, num_col))
-
- def test_convolution_2d_regularizers(self):
- kwargs = {
- 'filters': 3,
- 'kernel_size': 3,
- 'padding': 'valid',
- 'kernel_regularizer': 'l2',
- 'bias_regularizer': 'l2',
- 'activity_regularizer': 'l2',
- 'strides': 1
- }
- with self.test_session(use_gpu=True):
- layer = keras.layers.Conv2D(**kwargs)
- layer.build((None, 5, 5, 2))
- self.assertEqual(len(layer.losses), 2)
- layer(keras.backend.variable(np.ones((1, 5, 5, 2))))
- self.assertEqual(len(layer.losses), 3)
-
- def test_convolution_2d_constraints(self):
- k_constraint = lambda x: x
- b_constraint = lambda x: x
-
- kwargs = {
- 'filters': 3,
- 'kernel_size': 3,
- 'padding': 'valid',
- 'kernel_constraint': k_constraint,
- 'bias_constraint': b_constraint,
- 'strides': 1
- }
- with self.test_session(use_gpu=True):
- layer = keras.layers.Conv2D(**kwargs)
- layer.build((None, 5, 5, 2))
- self.assertEqual(layer.kernel.constraint, k_constraint)
- self.assertEqual(layer.bias.constraint, b_constraint)
-
- def test_dilated_conv_2d(self):
- num_samples = 2
- filters = 2
- stack_size = 3
- kernel_size = (3, 2)
- num_row = 7
- num_col = 6
-
- # Test dilation
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.Conv2D,
- kwargs={
- 'filters': filters,
- 'kernel_size': kernel_size,
- 'dilation_rate': (2, 2)
- },
- input_shape=(num_samples, num_row, num_col, stack_size))
-
-
-class Conv2DTransposeTest(test.TestCase):
-
- def test_conv2d_transpose(self):
- num_samples = 2
- filters = 2
- stack_size = 3
- num_row = 5
- num_col = 6
-
- for padding in ['valid', 'same']:
- for strides in [(1, 1), (2, 2)]:
- if padding == 'same' and strides != (1, 1):
- continue
-
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.Conv2DTranspose,
- kwargs={
- 'filters': filters,
- 'kernel_size': 3,
- 'padding': padding,
- 'strides': strides,
- 'data_format': 'channels_last'
- },
- input_shape=(num_samples, num_row, num_col, stack_size))
-
- def test_conv2dtranspose_regularizers(self):
- kwargs = {
- 'filters': 3,
- 'kernel_size': 3,
- 'padding': 'valid',
- 'kernel_regularizer': 'l2',
- 'bias_regularizer': 'l2',
- 'activity_regularizer': 'l2',
- 'strides': 1
- }
- with self.test_session(use_gpu=True):
- layer = keras.layers.Conv2DTranspose(**kwargs)
- layer.build((None, 5, 5, 2))
- self.assertEqual(len(layer.losses), 2)
- layer(keras.backend.variable(np.ones((1, 5, 5, 2))))
- self.assertEqual(len(layer.losses), 3)
-
- def test_conv2dtranspose_constraints(self):
- k_constraint = lambda x: x
- b_constraint = lambda x: x
-
- kwargs = {
- 'filters': 3,
- 'kernel_size': 3,
- 'padding': 'valid',
- 'kernel_constraint': k_constraint,
- 'bias_constraint': b_constraint,
- 'strides': 1
- }
- with self.test_session(use_gpu=True):
- layer = keras.layers.Conv2DTranspose(**kwargs)
- layer.build((None, 5, 5, 2))
- self.assertEqual(layer.kernel.constraint, k_constraint)
- self.assertEqual(layer.bias.constraint, b_constraint)
-
-
-class Conv3DTransposeTest(test.TestCase):
-
- def test_conv3d_transpose(self):
- num_samples = 2
- filters = 2
- stack_size = 3
- num_row = 5
- num_col = 6
- depth = 4
-
- for padding in ['valid', 'same']:
- for strides in [(1, 1, 1), (2, 2, 2)]:
- if padding == 'same' and strides != (1, 1, 1):
- continue
-
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.Conv3DTranspose,
- kwargs={
- 'filters': filters,
- 'kernel_size': 3,
- 'padding': padding,
- 'strides': strides,
- 'data_format': 'channels_last'
- },
- input_shape=(num_samples, depth, num_row, num_col, stack_size))
-
- def test_conv3dtranspose_regularizers(self):
- kwargs = {
- 'filters': 3,
- 'kernel_size': 3,
- 'padding': 'valid',
- 'kernel_regularizer': 'l2',
- 'bias_regularizer': 'l2',
- 'activity_regularizer': 'l2',
- 'strides': 1
- }
- with self.test_session(use_gpu=True):
- layer = keras.layers.Conv3DTranspose(**kwargs)
- layer.build((None, 5, 5, 5, 2))
- self.assertEqual(len(layer.losses), 2)
- layer(keras.backend.variable(np.ones((1, 5, 5, 5, 2))))
- self.assertEqual(len(layer.losses), 3)
-
- def test_conv3dtranspose_constraints(self):
- k_constraint = lambda x: x
- b_constraint = lambda x: x
-
- kwargs = {
- 'filters': 3,
- 'kernel_size': 3,
- 'padding': 'valid',
- 'kernel_constraint': k_constraint,
- 'bias_constraint': b_constraint,
- 'strides': 1
- }
- with self.test_session(use_gpu=True):
- layer = keras.layers.Conv3DTranspose(**kwargs)
- layer.build((None, 5, 5, 5, 2))
- self.assertEqual(layer.kernel.constraint, k_constraint)
- self.assertEqual(layer.bias.constraint, b_constraint)
-
-
-class SeparableConv2DTest(test.TestCase):
-
- def test_separable_conv_2d(self):
- num_samples = 2
- filters = 6
- stack_size = 3
- num_row = 7
- num_col = 6
-
- for padding in ['valid', 'same']:
- for strides in [(1, 1), (2, 2)]:
- for multiplier in [1, 2]:
- if padding == 'same' and strides != (1, 1):
- continue
-
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.SeparableConv2D,
- kwargs={
- 'filters': filters,
- 'kernel_size': (3, 3),
- 'padding': padding,
- 'strides': strides,
- 'depth_multiplier': multiplier
- },
- input_shape=(num_samples, num_row, num_col, stack_size))
-
- def test_separable_conv2d_regularizers(self):
- kwargs = {
- 'filters': 3,
- 'kernel_size': 3,
- 'padding': 'valid',
- 'depthwise_regularizer': 'l2',
- 'pointwise_regularizer': 'l2',
- 'bias_regularizer': 'l2',
- 'activity_regularizer': 'l2',
- 'strides': 1
- }
- with self.test_session(use_gpu=True):
- layer = keras.layers.SeparableConv2D(**kwargs)
- layer.build((None, 5, 5, 2))
- self.assertEqual(len(layer.losses), 3)
- layer(keras.backend.variable(np.ones((1, 5, 5, 2))))
- self.assertEqual(len(layer.losses), 4)
-
- def test_separable_conv2d_constraints(self):
- d_constraint = lambda x: x
- p_constraint = lambda x: x
- b_constraint = lambda x: x
-
- kwargs = {
- 'filters': 3,
- 'kernel_size': 3,
- 'padding': 'valid',
- 'pointwise_constraint': p_constraint,
- 'depthwise_constraint': d_constraint,
- 'bias_constraint': b_constraint,
- 'strides': 1
- }
- with self.test_session(use_gpu=True):
- layer = keras.layers.SeparableConv2D(**kwargs)
- layer.build((None, 5, 5, 2))
- self.assertEqual(layer.depthwise_kernel.constraint, d_constraint)
- self.assertEqual(layer.pointwise_kernel.constraint, p_constraint)
- self.assertEqual(layer.bias.constraint, b_constraint)
-
-
-class Conv3DTest(test.TestCase):
-
- def test_convolution_3d(self):
- num_samples = 2
- filters = 2
- stack_size = 3
-
- input_len_dim1 = 9
- input_len_dim2 = 8
- input_len_dim3 = 8
-
- for padding in ['valid', 'same']:
- for strides in [(1, 1, 1), (2, 2, 2)]:
- if padding == 'same' and strides != (1, 1, 1):
- continue
-
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.Convolution3D,
- kwargs={
- 'filters': filters,
- 'kernel_size': 3,
- 'padding': padding,
- 'strides': strides
- },
- input_shape=(num_samples, input_len_dim1, input_len_dim2,
- input_len_dim3, stack_size))
-
- def test_convolution_3d_regularizers(self):
- kwargs = {
- 'filters': 3,
- 'kernel_size': 3,
- 'padding': 'valid',
- 'kernel_regularizer': 'l2',
- 'bias_regularizer': 'l2',
- 'activity_regularizer': 'l2',
- 'strides': 1
- }
- with self.test_session(use_gpu=True):
- layer = keras.layers.Conv3D(**kwargs)
- layer.build((None, 5, 5, 5, 2))
- self.assertEqual(len(layer.losses), 2)
- self.assertEqual(len(layer.losses), 2)
- layer(keras.backend.variable(np.ones((1, 5, 5, 5, 2))))
- self.assertEqual(len(layer.losses), 3)
-
- def test_convolution_3d_constraints(self):
- k_constraint = lambda x: x
- b_constraint = lambda x: x
-
- kwargs = {
- 'filters': 3,
- 'kernel_size': 3,
- 'padding': 'valid',
- 'kernel_constraint': k_constraint,
- 'bias_constraint': b_constraint,
- 'strides': 1
- }
- with self.test_session(use_gpu=True):
- layer = keras.layers.Conv3D(**kwargs)
- layer.build((None, 5, 5, 5, 2))
- self.assertEqual(layer.kernel.constraint, k_constraint)
- self.assertEqual(layer.bias.constraint, b_constraint)
-
-
-class ZeroPaddingTest(test.TestCase):
-
- def test_zero_padding_1d(self):
- num_samples = 2
- input_dim = 2
- num_steps = 5
- shape = (num_samples, num_steps, input_dim)
- inputs = np.ones(shape)
-
- # basic test
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.ZeroPadding1D,
- kwargs={'padding': 2},
- input_shape=inputs.shape)
- testing_utils.layer_test(
- keras.layers.ZeroPadding1D,
- kwargs={'padding': (1, 2)},
- input_shape=inputs.shape)
-
- # correctness test
- with self.test_session(use_gpu=True):
- layer = keras.layers.ZeroPadding1D(padding=2)
- layer.build(shape)
- output = layer(keras.backend.variable(inputs))
- np_output = keras.backend.eval(output)
- for offset in [0, 1, -1, -2]:
- np.testing.assert_allclose(np_output[:, offset, :], 0.)
- np.testing.assert_allclose(np_output[:, 2:-2, :], 1.)
-
- layer = keras.layers.ZeroPadding1D(padding=(1, 2))
- layer.build(shape)
- output = layer(keras.backend.variable(inputs))
- np_output = keras.backend.eval(output)
- for left_offset in [0]:
- np.testing.assert_allclose(np_output[:, left_offset, :], 0.)
- for right_offset in [-1, -2]:
- np.testing.assert_allclose(np_output[:, right_offset, :], 0.)
- np.testing.assert_allclose(np_output[:, 1:-2, :], 1.)
- layer.get_config()
-
- # test incorrect use
- with self.assertRaises(ValueError):
- keras.layers.ZeroPadding1D(padding=(1, 1, 1))
- with self.assertRaises(ValueError):
- keras.layers.ZeroPadding1D(padding=None)
-
- def test_zero_padding_2d(self):
- num_samples = 2
- stack_size = 2
- input_num_row = 4
- input_num_col = 5
- for data_format in ['channels_first', 'channels_last']:
- inputs = np.ones((num_samples, input_num_row, input_num_col, stack_size))
- inputs = np.ones((num_samples, stack_size, input_num_row, input_num_col))
-
- # basic test
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.ZeroPadding2D,
- kwargs={'padding': (2, 2),
- 'data_format': data_format},
- input_shape=inputs.shape)
- testing_utils.layer_test(
- keras.layers.ZeroPadding2D,
- kwargs={'padding': ((1, 2), (3, 4)),
- 'data_format': data_format},
- input_shape=inputs.shape)
-
- # correctness test
- with self.test_session(use_gpu=True):
- layer = keras.layers.ZeroPadding2D(
- padding=(2, 2), data_format=data_format)
- layer.build(inputs.shape)
- output = layer(keras.backend.variable(inputs))
- np_output = keras.backend.eval(output)
- if data_format == 'channels_last':
- for offset in [0, 1, -1, -2]:
- np.testing.assert_allclose(np_output[:, offset, :, :], 0.)
- np.testing.assert_allclose(np_output[:, :, offset, :], 0.)
- np.testing.assert_allclose(np_output[:, 2:-2, 2:-2, :], 1.)
- elif data_format == 'channels_first':
- for offset in [0, 1, -1, -2]:
- np.testing.assert_allclose(np_output[:, :, offset, :], 0.)
- np.testing.assert_allclose(np_output[:, :, :, offset], 0.)
- np.testing.assert_allclose(np_output[:, 2:-2, 2:-2, :], 1.)
-
- layer = keras.layers.ZeroPadding2D(
- padding=((1, 2), (3, 4)), data_format=data_format)
- layer.build(inputs.shape)
- output = layer(keras.backend.variable(inputs))
- np_output = keras.backend.eval(output)
- if data_format == 'channels_last':
- for top_offset in [0]:
- np.testing.assert_allclose(np_output[:, top_offset, :, :], 0.)
- for bottom_offset in [-1, -2]:
- np.testing.assert_allclose(np_output[:, bottom_offset, :, :], 0.)
- for left_offset in [0, 1, 2]:
- np.testing.assert_allclose(np_output[:, :, left_offset, :], 0.)
- for right_offset in [-1, -2, -3, -4]:
- np.testing.assert_allclose(np_output[:, :, right_offset, :], 0.)
- np.testing.assert_allclose(np_output[:, 1:-2, 3:-4, :], 1.)
- elif data_format == 'channels_first':
- for top_offset in [0]:
- np.testing.assert_allclose(np_output[:, :, top_offset, :], 0.)
- for bottom_offset in [-1, -2]:
- np.testing.assert_allclose(np_output[:, :, bottom_offset, :], 0.)
- for left_offset in [0, 1, 2]:
- np.testing.assert_allclose(np_output[:, :, :, left_offset], 0.)
- for right_offset in [-1, -2, -3, -4]:
- np.testing.assert_allclose(np_output[:, :, :, right_offset], 0.)
- np.testing.assert_allclose(np_output[:, :, 1:-2, 3:-4], 1.)
-
- # test incorrect use
- with self.assertRaises(ValueError):
- keras.layers.ZeroPadding2D(padding=(1, 1, 1))
- with self.assertRaises(ValueError):
- keras.layers.ZeroPadding2D(padding=None)
-
- def test_zero_padding_3d(self):
- num_samples = 2
- stack_size = 2
- input_len_dim1 = 4
- input_len_dim2 = 5
- input_len_dim3 = 3
-
- inputs = np.ones((num_samples, input_len_dim1, input_len_dim2,
- input_len_dim3, stack_size))
-
- # basic test
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.ZeroPadding3D,
- kwargs={'padding': (2, 2, 2)},
- input_shape=inputs.shape)
-
- # correctness test
- with self.test_session(use_gpu=True):
- layer = keras.layers.ZeroPadding3D(padding=(2, 2, 2))
- layer.build(inputs.shape)
- output = layer(keras.backend.variable(inputs))
- np_output = keras.backend.eval(output)
- for offset in [0, 1, -1, -2]:
- np.testing.assert_allclose(np_output[:, offset, :, :, :], 0.)
- np.testing.assert_allclose(np_output[:, :, offset, :, :], 0.)
- np.testing.assert_allclose(np_output[:, :, :, offset, :], 0.)
- np.testing.assert_allclose(np_output[:, 2:-2, 2:-2, 2:-2, :], 1.)
-
- # test incorrect use
- with self.assertRaises(ValueError):
- keras.layers.ZeroPadding3D(padding=(1, 1))
- with self.assertRaises(ValueError):
- keras.layers.ZeroPadding3D(padding=None)
-
-
-class UpSamplingTest(test.TestCase):
-
- def test_upsampling_1d(self):
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.UpSampling1D, kwargs={'size': 2}, input_shape=(3, 5, 4))
-
- def test_upsampling_2d(self):
- num_samples = 2
- stack_size = 2
- input_num_row = 11
- input_num_col = 12
-
- for data_format in ['channels_first', 'channels_last']:
- if data_format == 'channels_first':
- inputs = np.random.rand(num_samples, stack_size, input_num_row,
- input_num_col)
- else:
- inputs = np.random.rand(num_samples, input_num_row, input_num_col,
- stack_size)
-
- # basic test
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.UpSampling2D,
- kwargs={'size': (2, 2),
- 'data_format': data_format},
- input_shape=inputs.shape)
-
- for length_row in [2]:
- for length_col in [2, 3]:
- layer = keras.layers.UpSampling2D(
- size=(length_row, length_col), data_format=data_format)
- layer.build(inputs.shape)
- output = layer(keras.backend.variable(inputs))
- np_output = keras.backend.eval(output)
- if data_format == 'channels_first':
- assert np_output.shape[2] == length_row * input_num_row
- assert np_output.shape[3] == length_col * input_num_col
- else: # tf
- assert np_output.shape[1] == length_row * input_num_row
- assert np_output.shape[2] == length_col * input_num_col
-
- # compare with numpy
- if data_format == 'channels_first':
- expected_out = np.repeat(inputs, length_row, axis=2)
- expected_out = np.repeat(expected_out, length_col, axis=3)
- else: # tf
- expected_out = np.repeat(inputs, length_row, axis=1)
- expected_out = np.repeat(expected_out, length_col, axis=2)
-
- np.testing.assert_allclose(np_output, expected_out)
-
- def test_upsampling_3d(self):
- num_samples = 2
- stack_size = 2
- input_len_dim1 = 10
- input_len_dim2 = 11
- input_len_dim3 = 12
-
- for data_format in ['channels_first', 'channels_last']:
- if data_format == 'channels_first':
- inputs = np.random.rand(num_samples, stack_size, input_len_dim1,
- input_len_dim2, input_len_dim3)
- else:
- inputs = np.random.rand(num_samples, input_len_dim1, input_len_dim2,
- input_len_dim3, stack_size)
-
- # basic test
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.UpSampling3D,
- kwargs={'size': (2, 2, 2),
- 'data_format': data_format},
- input_shape=inputs.shape)
-
- for length_dim1 in [2, 3]:
- for length_dim2 in [2]:
- for length_dim3 in [3]:
- layer = keras.layers.UpSampling3D(
- size=(length_dim1, length_dim2, length_dim3),
- data_format=data_format)
- layer.build(inputs.shape)
- output = layer(keras.backend.variable(inputs))
- np_output = keras.backend.eval(output)
- if data_format == 'channels_first':
- assert np_output.shape[2] == length_dim1 * input_len_dim1
- assert np_output.shape[3] == length_dim2 * input_len_dim2
- assert np_output.shape[4] == length_dim3 * input_len_dim3
- else: # tf
- assert np_output.shape[1] == length_dim1 * input_len_dim1
- assert np_output.shape[2] == length_dim2 * input_len_dim2
- assert np_output.shape[3] == length_dim3 * input_len_dim3
-
- # compare with numpy
- if data_format == 'channels_first':
- expected_out = np.repeat(inputs, length_dim1, axis=2)
- expected_out = np.repeat(expected_out, length_dim2, axis=3)
- expected_out = np.repeat(expected_out, length_dim3, axis=4)
- else: # tf
- expected_out = np.repeat(inputs, length_dim1, axis=1)
- expected_out = np.repeat(expected_out, length_dim2, axis=2)
- expected_out = np.repeat(expected_out, length_dim3, axis=3)
-
- np.testing.assert_allclose(np_output, expected_out)
-
-
-class CroppingTest(test.TestCase):
-
- def test_cropping_1d(self):
- num_samples = 2
- time_length = 4
- input_len_dim1 = 2
- inputs = np.random.rand(num_samples, time_length, input_len_dim1)
-
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.Cropping1D,
- kwargs={'cropping': (2, 2)},
- input_shape=inputs.shape)
-
- # test incorrect use
- with self.assertRaises(ValueError):
- keras.layers.Cropping1D(cropping=(1, 1, 1))
- with self.assertRaises(ValueError):
- keras.layers.Cropping1D(cropping=None)
-
- def test_cropping_2d(self):
- num_samples = 2
- stack_size = 2
- input_len_dim1 = 9
- input_len_dim2 = 9
- cropping = ((2, 2), (3, 3))
-
- for data_format in ['channels_first', 'channels_last']:
- if data_format == 'channels_first':
- inputs = np.random.rand(num_samples, stack_size, input_len_dim1,
- input_len_dim2)
- else:
- inputs = np.random.rand(num_samples, input_len_dim1, input_len_dim2,
- stack_size)
- # basic test
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.Cropping2D,
- kwargs={'cropping': cropping,
- 'data_format': data_format},
- input_shape=inputs.shape)
- # correctness test
- with self.test_session(use_gpu=True):
- layer = keras.layers.Cropping2D(
- cropping=cropping, data_format=data_format)
- layer.build(inputs.shape)
- output = layer(keras.backend.variable(inputs))
- np_output = keras.backend.eval(output)
- # compare with numpy
- if data_format == 'channels_first':
- expected_out = inputs[:, :, cropping[0][0]:-cropping[0][1], cropping[
- 1][0]:-cropping[1][1]]
- else:
- expected_out = inputs[:, cropping[0][0]:-cropping[0][1], cropping[1][
- 0]:-cropping[1][1], :]
- np.testing.assert_allclose(np_output, expected_out)
-
- for data_format in ['channels_first', 'channels_last']:
- if data_format == 'channels_first':
- inputs = np.random.rand(num_samples, stack_size, input_len_dim1,
- input_len_dim2)
- else:
- inputs = np.random.rand(num_samples, input_len_dim1, input_len_dim2,
- stack_size)
- # another correctness test (no cropping)
- with self.test_session(use_gpu=True):
- cropping = ((0, 0), (0, 0))
- layer = keras.layers.Cropping2D(
- cropping=cropping, data_format=data_format)
- layer.build(inputs.shape)
- output = layer(keras.backend.variable(inputs))
- np_output = keras.backend.eval(output)
- # compare with input
- np.testing.assert_allclose(np_output, inputs)
-
- # test incorrect use
- with self.assertRaises(ValueError):
- keras.layers.Cropping2D(cropping=(1, 1, 1))
- with self.assertRaises(ValueError):
- keras.layers.Cropping2D(cropping=None)
-
- def test_cropping_3d(self):
- num_samples = 2
- stack_size = 2
- input_len_dim1 = 8
- input_len_dim2 = 8
- input_len_dim3 = 8
- croppings = [((2, 2), (1, 1), (2, 3)), 3, (0, 1, 1)]
-
- for cropping in croppings:
- for data_format in ['channels_last', 'channels_first']:
- if data_format == 'channels_first':
- inputs = np.random.rand(num_samples, stack_size, input_len_dim1,
- input_len_dim2, input_len_dim3)
- else:
- inputs = np.random.rand(num_samples, input_len_dim1, input_len_dim2,
- input_len_dim3, stack_size)
- # basic test
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.Cropping3D,
- kwargs={'cropping': cropping,
- 'data_format': data_format},
- input_shape=inputs.shape)
-
- if len(croppings) == 3 and len(croppings[0]) == 2:
- # correctness test
- with self.test_session(use_gpu=True):
- layer = keras.layers.Cropping3D(
- cropping=cropping, data_format=data_format)
- layer.build(inputs.shape)
- output = layer(keras.backend.variable(inputs))
- np_output = keras.backend.eval(output)
- # compare with numpy
- if data_format == 'channels_first':
- expected_out = inputs[:, :,
- cropping[0][0]:-cropping[0][1],
- cropping[1][0]:-cropping[1][1],
- cropping[2][0]:-cropping[2][1]]
- else:
- expected_out = inputs[:,
- cropping[0][0]:-cropping[0][1],
- cropping[1][0]:-cropping[1][1],
- cropping[2][0]:-cropping[2][1], :]
- np.testing.assert_allclose(np_output, expected_out)
-
- # test incorrect use
- with self.assertRaises(ValueError):
- keras.layers.Cropping3D(cropping=(1, 1))
- with self.assertRaises(ValueError):
- keras.layers.Cropping3D(cropping=None)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/layers/core.py b/tensorflow/contrib/keras/python/keras/layers/core.py
deleted file mode 100644
index e5df0c5800..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/core.py
+++ /dev/null
@@ -1,777 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Core Keras layers.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import copy
-import types as python_types
-
-import numpy as np
-
-from tensorflow.contrib.keras.python.keras import activations
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras import constraints
-from tensorflow.contrib.keras.python.keras import initializers
-from tensorflow.contrib.keras.python.keras import regularizers
-from tensorflow.contrib.keras.python.keras.engine import InputSpec
-from tensorflow.contrib.keras.python.keras.engine import Layer
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import deserialize_keras_object
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import func_dump
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import func_load
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import has_arg
-from tensorflow.python.framework import tensor_shape
-from tensorflow.python.layers import core as tf_core_layers
-
-
-class Masking(Layer):
- """Masks a sequence by using a mask value to skip timesteps.
-
- For each timestep in the input tensor (dimension #1 in the tensor),
- if all values in the input tensor at that timestep
- are equal to `mask_value`, then the timestep will be masked (skipped)
- in all downstream layers (as long as they support masking).
-
- If any downstream layer does not support masking yet receives such
- an input mask, an exception will be raised.
-
- Example:
-
- Consider a Numpy data array `x` of shape `(samples, timesteps, features)`,
- to be fed to a LSTM layer.
- You want to mask timestep #3 and #5 because you lack data for
- these timesteps. You can:
-
- - set `x[:, 3, :] = 0.` and `x[:, 5, :] = 0.`
- - insert a `Masking` layer with `mask_value=0.` before the LSTM layer:
-
- ```python
- model = Sequential()
- model.add(Masking(mask_value=0., input_shape=(timesteps, features)))
- model.add(LSTM(32))
- ```
- """
-
- def __init__(self, mask_value=0., **kwargs):
- super(Masking, self).__init__(**kwargs)
- self.supports_masking = True
- self.mask_value = mask_value
-
- def compute_mask(self, inputs, mask=None):
- return K.any(K.not_equal(inputs, self.mask_value), axis=-1)
-
- def call(self, inputs):
- boolean_mask = K.any(
- K.not_equal(inputs, self.mask_value), axis=-1, keepdims=True)
- return inputs * K.cast(boolean_mask, inputs.dtype)
-
- def get_config(self):
- config = {'mask_value': self.mask_value}
- base_config = super(Masking, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Dropout(tf_core_layers.Dropout, Layer):
- """Applies Dropout to the input.
-
- Dropout consists in randomly setting
- a fraction `rate` of input units to 0 at each update during training time,
- which helps prevent overfitting.
-
- Arguments:
- rate: float between 0 and 1. Fraction of the input units to drop.
- noise_shape: 1D integer tensor representing the shape of the
- binary dropout mask that will be multiplied with the input.
- For instance, if your inputs have shape
- `(batch_size, timesteps, features)` and
- you want the dropout mask to be the same for all timesteps,
- you can use `noise_shape=(batch_size, 1, features)`.
- seed: A Python integer to use as random seed.
- """
-
- def __init__(self, rate, noise_shape=None, seed=None, **kwargs):
- self.supports_masking = True
- # Inheritance call order:
- # 1) tf.layers.Dropout, 2) keras.layers.Layer, 3) tf.layers.Layer
- super(Dropout, self).__init__(rate=rate,
- noise_shape=noise_shape,
- seed=seed,
- **kwargs)
-
- def call(self, inputs, training=None):
- if training is None:
- training = K.learning_phase()
- output = super(Dropout, self).call(inputs, training=training)
- if training is K.learning_phase():
- output._uses_learning_phase = True # pylint: disable=protected-access
- return output
-
- def get_config(self):
- config = {'rate': self.rate}
- base_config = super(Dropout, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class SpatialDropout1D(Dropout):
- """Spatial 1D version of Dropout.
-
- This version performs the same function as Dropout, however it drops
- entire 1D feature maps instead of individual elements. If adjacent frames
- within feature maps are strongly correlated (as is normally the case in
- early convolution layers) then regular dropout will not regularize the
- activations and will otherwise just result in an effective learning rate
- decrease. In this case, SpatialDropout1D will help promote independence
- between feature maps and should be used instead.
-
- Arguments:
- rate: float between 0 and 1. Fraction of the input units to drop.
-
- Input shape:
- 3D tensor with shape:
- `(samples, timesteps, channels)`
-
- Output shape:
- Same as input
-
- References:
- - [Efficient Object Localization Using Convolutional
- Networks](https://arxiv.org/abs/1411.4280)
- """
-
- def __init__(self, rate, **kwargs):
- super(SpatialDropout1D, self).__init__(rate, **kwargs)
- self.input_spec = InputSpec(ndim=3)
-
- def _get_noise_shape(self, inputs):
- input_shape = K.shape(inputs)
- noise_shape = (input_shape[0], 1, input_shape[2])
- return noise_shape
-
-
-class SpatialDropout2D(Dropout):
- """Spatial 2D version of Dropout.
-
- This version performs the same function as Dropout, however it drops
- entire 2D feature maps instead of individual elements. If adjacent pixels
- within feature maps are strongly correlated (as is normally the case in
- early convolution layers) then regular dropout will not regularize the
- activations and will otherwise just result in an effective learning rate
- decrease. In this case, SpatialDropout2D will help promote independence
- between feature maps and should be used instead.
-
- Arguments:
- rate: float between 0 and 1. Fraction of the input units to drop.
- 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 "channels_last".
-
- Input shape:
- 4D tensor with shape:
- `(samples, channels, rows, cols)` if data_format='channels_first'
- or 4D tensor with shape:
- `(samples, rows, cols, channels)` if data_format='channels_last'.
-
- Output shape:
- Same as input
-
- References:
- - [Efficient Object Localization Using Convolutional
- Networks](https://arxiv.org/abs/1411.4280)
- """
-
- def __init__(self, rate, data_format=None, **kwargs):
- super(SpatialDropout2D, self).__init__(rate, **kwargs)
- if data_format is None:
- data_format = K.image_data_format()
- 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.input_spec = InputSpec(ndim=4)
-
- def _get_noise_shape(self, inputs):
- input_shape = K.shape(inputs)
- if self.data_format == 'channels_first':
- return (input_shape[0], input_shape[1], 1, 1)
- elif self.data_format == 'channels_last':
- return (input_shape[0], 1, 1, input_shape[3])
-
-
-class SpatialDropout3D(Dropout):
- """Spatial 3D version of Dropout.
-
- This version performs the same function as Dropout, however it drops
- entire 3D feature maps instead of individual elements. If adjacent voxels
- within feature maps are strongly correlated (as is normally the case in
- early convolution layers) then regular dropout will not regularize the
- activations and will otherwise just result in an effective learning rate
- decrease. In this case, SpatialDropout3D will help promote independence
- between feature maps and should be used instead.
-
- Arguments:
- rate: float between 0 and 1. Fraction of the input units to drop.
- 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 "channels_last".
-
- Input shape:
- 5D tensor with shape:
- `(samples, channels, dim1, dim2, dim3)` if data_format='channels_first'
- or 5D tensor with shape:
- `(samples, dim1, dim2, dim3, channels)` if data_format='channels_last'.
-
- Output shape:
- Same as input
-
- References:
- - [Efficient Object Localization Using Convolutional
- Networks](https://arxiv.org/abs/1411.4280)
- """
-
- def __init__(self, rate, data_format=None, **kwargs):
- super(SpatialDropout3D, self).__init__(rate, **kwargs)
- if data_format is None:
- data_format = K.image_data_format()
- 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.input_spec = InputSpec(ndim=5)
-
- def _get_noise_shape(self, inputs):
- input_shape = K.shape(inputs)
- if self.data_format == 'channels_first':
- return (input_shape[0], input_shape[1], 1, 1, 1)
- elif self.data_format == 'channels_last':
- return (input_shape[0], 1, 1, 1, input_shape[4])
-
-
-class Activation(Layer):
- """Applies an activation function to an output.
-
- Arguments:
- activation: name of activation function to use
- or alternatively, a Theano or TensorFlow operation.
-
- Input shape:
- Arbitrary. Use the keyword argument `input_shape`
- (tuple of integers, does not include the samples axis)
- when using this layer as the first layer in a model.
-
- Output shape:
- Same shape as input.
- """
-
- def __init__(self, activation, **kwargs):
- super(Activation, self).__init__(**kwargs)
- self.supports_masking = True
- self.activation = activations.get(activation)
-
- def call(self, inputs):
- return self.activation(inputs)
-
- def get_config(self):
- config = {'activation': activations.serialize(self.activation)}
- base_config = super(Activation, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Reshape(Layer):
- """Reshapes an output to a certain shape.
-
- Arguments:
- target_shape: target shape. Tuple of integers,
- does not include the samples dimension (batch size).
-
- Input shape:
- Arbitrary, although all dimensions in the input shaped must be fixed.
- Use the keyword argument `input_shape`
- (tuple of integers, does not include the samples axis)
- when using this layer as the first layer in a model.
-
- Output shape:
- `(batch_size,) + target_shape`
-
- Example:
-
- ```python
- # as first layer in a Sequential model
- model = Sequential()
- model.add(Reshape((3, 4), input_shape=(12,)))
- # now: model.output_shape == (None, 3, 4)
- # note: `None` is the batch dimension
-
- # as intermediate layer in a Sequential model
- model.add(Reshape((6, 2)))
- # now: model.output_shape == (None, 6, 2)
-
- # also supports shape inference using `-1` as dimension
- model.add(Reshape((-1, 2, 2)))
- # now: model.output_shape == (None, 3, 2, 2)
- ```
- """
-
- def __init__(self, target_shape, **kwargs):
- super(Reshape, self).__init__(**kwargs)
- self.target_shape = tuple(target_shape)
-
- def _fix_unknown_dimension(self, input_shape, output_shape):
- """Find and replace a missing dimension in an output shape.
-
- This is a near direct port of the internal Numpy function
- `_fix_unknown_dimension` in `numpy/core/src/multiarray/shape.c`
-
- Arguments:
- input_shape: shape of array being reshaped
- output_shape: desired shape of the array with at most
- a single -1 which indicates a dimension that should be
- derived from the input shape.
-
- Returns:
- The new output shape with a -1 replaced with its computed value.
-
- Raises a ValueError if the total array size of the output_shape is
- different then the input_shape, or more than one unknown dimension
- is specified.
-
- Raises:
- ValueError: in case of invalid values
- for `input_shape` or `input_shape`.
- """
- output_shape = list(output_shape)
- msg = 'total size of new array must be unchanged'
-
- known, unknown = 1, None
- for index, dim in enumerate(output_shape):
- if dim < 0:
- if unknown is None:
- unknown = index
- else:
- raise ValueError('Can only specify one unknown dimension.')
- else:
- known *= dim
-
- original = np.prod(input_shape, dtype=int)
- if unknown is not None:
- if known == 0 or original % known != 0:
- raise ValueError(msg)
- output_shape[unknown] = original // known
- elif original != known:
- raise ValueError(msg)
- return output_shape
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- output_shape = [input_shape[0]]
- output_shape += self._fix_unknown_dimension(input_shape[1:],
- self.target_shape)
- return tensor_shape.TensorShape(output_shape)
-
- def call(self, inputs):
- # In case the target shape is not fully defined,
- # we need access to the shape of x.
- target_shape = self.target_shape
- if -1 in target_shape:
- # target shape not fully defined
- target_shape = self._compute_output_shape(inputs.get_shape())
- target_shape = target_shape.as_list()[1:]
- return K.reshape(inputs, (-1,) + tuple(target_shape))
-
- def get_config(self):
- config = {'target_shape': self.target_shape}
- base_config = super(Reshape, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Permute(Layer):
- """Permutes the dimensions of the input according to a given pattern.
-
- Useful for e.g. connecting RNNs and convnets together.
-
- Example:
-
- ```python
- model = Sequential()
- model.add(Permute((2, 1), input_shape=(10, 64)))
- # now: model.output_shape == (None, 64, 10)
- # note: `None` is the batch dimension
- ```
-
- Arguments:
- dims: Tuple of integers. Permutation pattern, does not include the
- samples dimension. Indexing starts at 1.
- For instance, `(2, 1)` permutes the first and second dimension
- of the input.
-
- Input shape:
- Arbitrary. Use the keyword argument `input_shape`
- (tuple of integers, does not include the samples axis)
- when using this layer as the first layer in a model.
-
- Output shape:
- Same as the input shape, but with the dimensions re-ordered according
- to the specified pattern.
- """
-
- def __init__(self, dims, **kwargs):
- super(Permute, self).__init__(**kwargs)
- self.dims = tuple(dims)
- self.input_spec = InputSpec(ndim=len(self.dims) + 1)
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- output_shape = copy.copy(input_shape)
- for i, dim in enumerate(self.dims):
- target_dim = input_shape[dim]
- output_shape[i + 1] = target_dim
- return tensor_shape.TensorShape(output_shape)
-
- def call(self, inputs):
- return K.permute_dimensions(inputs, (0,) + self.dims)
-
- def get_config(self):
- config = {'dims': self.dims}
- base_config = super(Permute, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Flatten(Layer):
- """Flattens the input. Does not affect the batch size.
-
- Example:
-
- ```python
- model = Sequential()
- model.add(Convolution2D(64, 3, 3,
- border_mode='same',
- input_shape=(3, 32, 32)))
- # now: model.output_shape == (None, 64, 32, 32)
-
- model.add(Flatten())
- # now: model.output_shape == (None, 65536)
- ```
- """
-
- def __init__(self, **kwargs):
- super(Flatten, self).__init__(**kwargs)
- self.input_spec = InputSpec(min_ndim=3)
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- if not all(input_shape[1:]):
- raise ValueError('The shape of the input to "Flatten" '
- 'is not fully defined '
- '(got ' + str(input_shape[1:]) + '. '
- 'Make sure to pass a complete "input_shape" '
- 'or "batch_input_shape" argument to the first '
- 'layer in your model.')
- return tensor_shape.TensorShape([input_shape[0], np.prod(input_shape[1:])])
-
- def call(self, inputs):
- outputs = K.batch_flatten(inputs)
- outputs.set_shape(self._compute_output_shape(inputs.get_shape()))
- return outputs
-
-
-class RepeatVector(Layer):
- """Repeats the input n times.
-
- Example:
-
- ```python
- model = Sequential()
- model.add(Dense(32, input_dim=32))
- # now: model.output_shape == (None, 32)
- # note: `None` is the batch dimension
-
- model.add(RepeatVector(3))
- # now: model.output_shape == (None, 3, 32)
- ```
-
- Arguments:
- n: integer, repetition factor.
-
- Input shape:
- 2D tensor of shape `(num_samples, features)`.
-
- Output shape:
- 3D tensor of shape `(num_samples, n, features)`.
- """
-
- def __init__(self, n, **kwargs):
- super(RepeatVector, self).__init__(**kwargs)
- self.n = n
- self.input_spec = InputSpec(ndim=2)
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- return tensor_shape.TensorShape([input_shape[0], self.n, input_shape[1]])
-
- def call(self, inputs):
- return K.repeat(inputs, self.n)
-
- def get_config(self):
- config = {'n': self.n}
- base_config = super(RepeatVector, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Lambda(Layer):
- """Wraps arbitrary expression as a `Layer` object.
-
- Examples:
-
- ```python
- # add a x -> x^2 layer
- model.add(Lambda(lambda x: x ** 2))
- ```
- ```python
- # add a layer that returns the concatenation
- # of the positive part of the input and
- # the opposite of the negative part
-
- def antirectifier(x):
- x -= K.mean(x, axis=1, keepdims=True)
- x = K.l2_normalize(x, axis=1)
- pos = K.relu(x)
- neg = K.relu(-x)
- return K.concatenate([pos, neg], axis=1)
-
- model.add(Lambda(antirectifier))
- ```
-
- Arguments:
- function: The function to be evaluated.
- Takes input tensor as first argument.
- arguments: optional dictionary of keyword arguments to be passed
- to the function.
-
- Input shape:
- Arbitrary. Use the keyword argument input_shape
- (tuple of integers, does not include the samples axis)
- when using this layer as the first layer in a model.
-
- Output shape:
- Specified by `output_shape` argument
- (or auto-inferred when using TensorFlow).
- """
-
- def __init__(self, function, mask=None, arguments=None, **kwargs):
- super(Lambda, self).__init__(**kwargs)
- self.function = function
- self.arguments = arguments if arguments else {}
- if mask is not None:
- self.supports_masking = True
- self.mask = mask
-
- def call(self, inputs, mask=None):
- arguments = self.arguments
- if has_arg(self.function, 'mask'):
- arguments['mask'] = mask
- return self.function(inputs, **arguments)
-
- def compute_mask(self, inputs, mask=None):
- if callable(self.mask):
- return self.mask(inputs, mask)
- return self.mask
-
- def get_config(self):
- if isinstance(self.function, python_types.LambdaType):
- function = func_dump(self.function)
- function_type = 'lambda'
- else:
- function = self.function.__name__
- function_type = 'function'
-
- config = {
- 'function': function,
- 'function_type': function_type,
- 'arguments': self.arguments
- }
- base_config = super(Lambda, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
- @classmethod
- def from_config(cls, config, custom_objects=None):
- globs = globals()
- if custom_objects:
- globs = dict(list(globs.items()) + list(custom_objects.items()))
- function_type = config.pop('function_type')
- if function_type == 'function':
- # Simple lookup in custom objects
- function = deserialize_keras_object(
- config['function'],
- custom_objects=custom_objects,
- printable_module_name='function in Lambda layer')
- elif function_type == 'lambda':
- # Unsafe deserialization from bytecode
- function = func_load(config['function'], globs=globs)
- else:
- raise TypeError('Unknown function type:', function_type)
-
- # If arguments were numpy array, they have been saved as
- # list. We need to recover the ndarray
- if 'arguments' in config:
- for key in config['arguments']:
- if isinstance(config['arguments'][key], dict):
- arg_dict = config['arguments'][key]
- if 'type' in arg_dict and arg_dict['type'] == 'ndarray':
- # Overwrite the argument with its numpy translation
- config['arguments'][key] = np.array(arg_dict['value'])
-
- config['function'] = function
- return cls(**config)
-
-
-class Dense(tf_core_layers.Dense, Layer):
- """Just your regular densely-connected NN layer.
-
- `Dense` implements the operation:
- `output = activation(dot(input, kernel) + bias)`
- where `activation` is the element-wise activation function
- passed as the `activation` argument, `kernel` is a weights matrix
- created by the layer, and `bias` is a bias vector created by the layer
- (only applicable if `use_bias` is `True`).
-
- Note: if the input to the layer has a rank greater than 2, then
- it is flattened prior to the initial dot product with `kernel`.
-
- Example:
-
- ```python
- # as first layer in a sequential model:
- model = Sequential()
- model.add(Dense(32, input_shape=(16,)))
- # now the model will take as input arrays of shape (*, 16)
- # and output arrays of shape (*, 32)
-
- # after the first layer, you don't need to specify
- # the size of the input anymore:
- model.add(Dense(32))
- ```
-
- Arguments:
- units: Positive integer, dimensionality of the output space.
- activation: Activation function to use.
- If you don't specify anything, no activation is applied
- (ie. "linear" activation: `a(x) = x`).
- use_bias: Boolean, whether the layer uses a bias vector.
- kernel_initializer: Initializer for the `kernel` weights matrix.
- bias_initializer: Initializer for the bias vector.
- kernel_regularizer: Regularizer function applied to
- the `kernel` weights matrix.
- bias_regularizer: Regularizer function applied to the bias vector.
- activity_regularizer: Regularizer function applied to
- the output of the layer (its "activation")..
- kernel_constraint: Constraint function applied to
- the `kernel` weights matrix.
- bias_constraint: Constraint function applied to the bias vector.
-
- Input shape:
- nD tensor with shape: `(batch_size, ..., input_dim)`.
- The most common situation would be
- a 2D input with shape `(batch_size, input_dim)`.
-
- Output shape:
- nD tensor with shape: `(batch_size, ..., units)`.
- For instance, for a 2D input with shape `(batch_size, input_dim)`,
- the output would have shape `(batch_size, units)`.
- """
-
- def __init__(self,
- units,
- activation=None,
- use_bias=True,
- kernel_initializer='glorot_uniform',
- bias_initializer='zeros',
- kernel_regularizer=None,
- bias_regularizer=None,
- activity_regularizer=None,
- kernel_constraint=None,
- bias_constraint=None,
- **kwargs):
- if 'input_shape' not in kwargs and 'input_dim' in kwargs:
- kwargs['input_shape'] = (kwargs.pop('input_dim'),)
-
- # Inheritance call order:
- # 1) tf.layers.Dense, 2) keras.layers.Layer, 3) tf.layers.Layer
- super(Dense, self).__init__(
- units,
- activation=activations.get(activation),
- use_bias=use_bias,
- kernel_initializer=initializers.get(kernel_initializer),
- bias_initializer=initializers.get(bias_initializer),
- kernel_regularizer=regularizers.get(kernel_regularizer),
- bias_regularizer=regularizers.get(bias_regularizer),
- activity_regularizer=regularizers.get(activity_regularizer),
- kernel_constraint=constraints.get(kernel_constraint),
- bias_constraint=constraints.get(bias_constraint),
- **kwargs)
- self.supports_masking = True
-
- def get_config(self):
- config = {
- 'units': self.units,
- 'activation': activations.serialize(self.activation),
- 'use_bias': self.use_bias,
- 'kernel_initializer': initializers.serialize(self.kernel_initializer),
- 'bias_initializer': initializers.serialize(self.bias_initializer),
- '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)
- }
- base_config = super(Dense, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class ActivityRegularization(Layer):
- """Layer that applies an update to the cost function based input activity.
-
- Arguments:
- l1: L1 regularization factor (positive float).
- l2: L2 regularization factor (positive float).
-
- Input shape:
- Arbitrary. Use the keyword argument `input_shape`
- (tuple of integers, does not include the samples axis)
- when using this layer as the first layer in a model.
-
- Output shape:
- Same shape as input.
- """
-
- def __init__(self, l1=0., l2=0., **kwargs):
- super(ActivityRegularization, self).__init__(**kwargs)
- self.supports_masking = True
- self.l1 = l1
- self.l2 = l2
- self.activity_regularizer = regularizers.L1L2(l1=l1, l2=l2)
-
- def get_config(self):
- config = {'l1': self.l1, 'l2': self.l2}
- base_config = super(ActivityRegularization, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
diff --git a/tensorflow/contrib/keras/python/keras/layers/core_test.py b/tensorflow/contrib/keras/python/keras/layers/core_test.py
deleted file mode 100644
index 818c55afe4..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/core_test.py
+++ /dev/null
@@ -1,210 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for Keras core layers."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-
-
-class CoreLayersTest(test.TestCase):
-
- def test_masking(self):
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Masking, kwargs={}, input_shape=(3, 2, 3))
-
- def test_dropout(self):
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Dropout, kwargs={'rate': 0.5}, input_shape=(3, 2))
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Dropout,
- kwargs={'rate': 0.5,
- 'noise_shape': [3, 1]},
- input_shape=(3, 2))
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.SpatialDropout1D,
- kwargs={'rate': 0.5},
- input_shape=(2, 3, 4))
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.SpatialDropout2D,
- kwargs={'rate': 0.5},
- input_shape=(2, 3, 4, 5))
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.SpatialDropout2D,
- kwargs={'rate': 0.5, 'data_format': 'channels_first'},
- input_shape=(2, 3, 4, 5))
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.SpatialDropout3D,
- kwargs={'rate': 0.5},
- input_shape=(2, 3, 4, 4, 5))
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.SpatialDropout3D,
- kwargs={'rate': 0.5, 'data_format': 'channels_first'},
- input_shape=(2, 3, 4, 4, 5))
-
- def test_activation(self):
- # with string argument
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Activation,
- kwargs={'activation': 'relu'},
- input_shape=(3, 2))
-
- # with function argument
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Activation,
- kwargs={'activation': keras.backend.relu},
- input_shape=(3, 2))
-
- def test_reshape(self):
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Reshape,
- kwargs={'target_shape': (8, 1)},
- input_shape=(3, 2, 4))
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Reshape,
- kwargs={'target_shape': (-1, 1)},
- input_shape=(3, 2, 4))
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Reshape,
- kwargs={'target_shape': (1, -1)},
- input_shape=(3, 2, 4))
-
- def test_permute(self):
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Permute, kwargs={'dims': (2, 1)}, input_shape=(3, 2, 4))
-
- def test_flatten(self):
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Flatten, kwargs={}, input_shape=(3, 2, 4))
-
- def test_repeat_vector(self):
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.RepeatVector, kwargs={'n': 3}, input_shape=(3, 2))
-
- def test_lambda(self):
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Lambda,
- kwargs={'function': lambda x: x + 1},
- input_shape=(3, 2))
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Lambda,
- kwargs={
- 'function': lambda x, a, b: x * a + b,
- 'arguments': {
- 'a': 0.6,
- 'b': 0.4
- }
- },
- input_shape=(3, 2))
-
- with self.test_session():
- # test serialization with function
- def f(x):
- return x + 1
-
- ld = keras.layers.Lambda(f)
- config = ld.get_config()
- ld = keras.layers.deserialize({
- 'class_name': 'Lambda',
- 'config': config
- })
-
- # test with lambda
- ld = keras.layers.Lambda(
- lambda x: keras.backend.concatenate([keras.backend.square(x), x]))
- config = ld.get_config()
- ld = keras.layers.Lambda.from_config(config)
-
- def test_dense(self):
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Dense, kwargs={'units': 3}, input_shape=(3, 2))
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Dense, kwargs={'units': 3}, input_shape=(3, 4, 2))
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Dense, kwargs={'units': 3}, input_shape=(None, None, 2))
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Dense, kwargs={'units': 3}, input_shape=(3, 4, 5, 2))
-
- # Test regularization
- with self.test_session():
- layer = keras.layers.Dense(
- 3,
- kernel_regularizer=keras.regularizers.l1(0.01),
- bias_regularizer='l1',
- activity_regularizer='l2',
- name='dense_reg')
- layer(keras.backend.variable(np.ones((2, 4))))
- self.assertEqual(3, len(layer.losses))
-
- # Test constraints
- with self.test_session():
- k_constraint = keras.constraints.max_norm(0.01)
- b_constraint = keras.constraints.max_norm(0.01)
- layer = keras.layers.Dense(
- 3, kernel_constraint=k_constraint, bias_constraint=b_constraint)
- layer(keras.backend.variable(np.ones((2, 4))))
- self.assertEqual(layer.kernel.constraint, k_constraint)
- self.assertEqual(layer.bias.constraint, b_constraint)
-
- def test_activity_regularization(self):
- with self.test_session():
- layer = keras.layers.ActivityRegularization(l1=0.1)
- layer(keras.backend.variable(np.ones((2, 4))))
- self.assertEqual(1, len(layer.losses))
- _ = layer.get_config()
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/layers/embeddings.py b/tensorflow/contrib/keras/python/keras/layers/embeddings.py
deleted file mode 100644
index 9f617fd3e4..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/embeddings.py
+++ /dev/null
@@ -1,181 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Embedding layer.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras import constraints
-from tensorflow.contrib.keras.python.keras import initializers
-from tensorflow.contrib.keras.python.keras import regularizers
-from tensorflow.contrib.keras.python.keras.engine import Layer
-from tensorflow.python.framework import tensor_shape
-
-
-class Embedding(Layer):
- """Turns positive integers (indexes) into dense vectors of fixed size.
-
- eg. [[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]]
-
- This layer can only be used as the first layer in a model.
-
- Example:
-
- ```python
- model = Sequential()
- model.add(Embedding(1000, 64, input_length=10))
- # the model will take as input an integer matrix of size (batch,
- input_length).
- # the largest integer (i.e. word index) in the input should be no larger
- than 999 (vocabulary size).
- # now model.output_shape == (None, 10, 64), where None is the batch
- dimension.
-
- input_array = np.random.randint(1000, size=(32, 10))
-
- model.compile('rmsprop', 'mse')
- output_array = model.predict(input_array)
- assert output_array.shape == (32, 10, 64)
- ```
-
- Arguments:
- input_dim: int > 0. Size of the vocabulary,
- i.e. maximum integer index + 1.
- output_dim: int >= 0. Dimension of the dense embedding.
- embeddings_initializer: Initializer for the `embeddings` matrix.
- embeddings_regularizer: Regularizer function applied to
- the `embeddings` matrix.
- embeddings_constraint: Constraint function applied to
- the `embeddings` matrix.
- mask_zero: Whether or not the input value 0 is a special "padding"
- value that should be masked out.
- This is useful when using recurrent layers,
- which may take variable length inputs.
- If this is `True` then all subsequent layers
- in the model need to support masking or an exception will be raised.
- If mask_zero is set to True, as a consequence, index 0 cannot be
- used in the vocabulary (input_dim should equal size of
- vocabulary + 1).
- input_length: Length of input sequences, when it is constant.
- This argument is required if you are going to connect
- `Flatten` then `Dense` layers upstream
- (without it, the shape of the dense outputs cannot be computed).
-
- Input shape:
- 2D tensor with shape: `(batch_size, sequence_length)`.
-
- Output shape:
- 3D tensor with shape: `(batch_size, sequence_length, output_dim)`.
-
- References:
- - [A Theoretically Grounded Application of Dropout in Recurrent Neural
- Networks](http://arxiv.org/abs/1512.05287)
- """
-
- def __init__(self,
- input_dim,
- output_dim,
- embeddings_initializer='uniform',
- embeddings_regularizer=None,
- activity_regularizer=None,
- embeddings_constraint=None,
- mask_zero=False,
- input_length=None,
- **kwargs):
- if 'input_shape' not in kwargs:
- if input_length:
- kwargs['input_shape'] = (input_length,)
- else:
- kwargs['input_shape'] = (None,)
- super(Embedding, self).__init__(**kwargs)
-
- self.input_dim = input_dim
- self.output_dim = output_dim
- self.embeddings_initializer = initializers.get(embeddings_initializer)
- self.embeddings_regularizer = regularizers.get(embeddings_regularizer)
- self.activity_regularizer = regularizers.get(activity_regularizer)
- self.embeddings_constraint = constraints.get(embeddings_constraint)
- self.mask_zero = mask_zero
- self.input_length = input_length
-
- def build(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- self.embeddings = self.add_weight(
- shape=(self.input_dim, self.output_dim),
- initializer=self.embeddings_initializer,
- name='embeddings',
- regularizer=self.embeddings_regularizer,
- constraint=self.embeddings_constraint,
- dtype=self.dtype)
- self.built = True
-
- def compute_mask(self, inputs, mask=None):
- if not self.mask_zero:
- return None
- else:
- return K.not_equal(inputs, 0)
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- if self.input_length is None:
- return tensor_shape.TensorShape(input_shape + [self.output_dim])
- else:
- # input_length can be tuple if input is 3D or higher
- if isinstance(self.input_length, (list, tuple)):
- in_lens = list(self.input_length)
- else:
- in_lens = [self.input_length]
- if len(in_lens) != len(input_shape) - 1:
- ValueError('"input_length" is %s, but received input has shape %s' %
- (str(self.input_length), str(input_shape)))
- else:
- for i, (s1, s2) in enumerate(zip(in_lens, input_shape[1:])):
- if s1 is not None and s2 is not None and s1 != s2:
- ValueError('"input_length" is %s, but received input has shape %s' %
- (str(self.input_length), str(input_shape)))
- elif s1 is None:
- in_lens[i] = s2
- return tensor_shape.TensorShape(
- (input_shape[0],) + tuple(in_lens) + (self.output_dim,))
-
- def call(self, inputs):
- if K.dtype(inputs) != 'int32':
- inputs = K.cast(inputs, 'int32')
- out = K.gather(self.embeddings, inputs)
- return out
-
- def get_config(self):
- config = {
- 'input_dim':
- self.input_dim,
- 'output_dim':
- self.output_dim,
- 'embeddings_initializer':
- initializers.serialize(self.embeddings_initializer),
- 'embeddings_regularizer':
- regularizers.serialize(self.embeddings_regularizer),
- 'activity_regularizer':
- regularizers.serialize(self.activity_regularizer),
- 'embeddings_constraint':
- constraints.serialize(self.embeddings_constraint),
- 'mask_zero':
- self.mask_zero,
- 'input_length':
- self.input_length
- }
- base_config = super(Embedding, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
diff --git a/tensorflow/contrib/keras/python/keras/layers/embeddings_test.py b/tensorflow/contrib/keras/python/keras/layers/embeddings_test.py
deleted file mode 100644
index 5d6d386862..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/embeddings_test.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for embedding layers."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-
-
-class EmbeddingTest(test.TestCase):
-
- def test_embedding(self):
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Embedding,
- kwargs={'output_dim': 4,
- 'input_dim': 10,
- 'input_length': 2},
- input_shape=(3, 2),
- input_dtype='int32',
- expected_output_dtype='float32')
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Embedding,
- kwargs={'output_dim': 4,
- 'input_dim': 10,
- 'mask_zero': True},
- input_shape=(3, 2),
- input_dtype='int32',
- expected_output_dtype='float32')
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Embedding,
- kwargs={'output_dim': 4,
- 'input_dim': 10,
- 'mask_zero': True},
- input_shape=(3, 4, 2),
- input_dtype='int32',
- expected_output_dtype='float32')
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.Embedding,
- kwargs={'output_dim': 4,
- 'input_dim': 10,
- 'mask_zero': True,
- 'input_length': (None, 2)},
- input_shape=(3, 4, 2),
- input_dtype='int32',
- expected_output_dtype='float32')
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/layers/gru_test.py b/tensorflow/contrib/keras/python/keras/layers/gru_test.py
deleted file mode 100644
index 9af3290480..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/gru_test.py
+++ /dev/null
@@ -1,203 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for GRU layer."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-
-
-class GRULayerTest(test.TestCase):
-
- def test_return_sequences_GRU(self):
- num_samples = 2
- timesteps = 3
- embedding_dim = 4
- units = 2
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.GRU,
- kwargs={'units': units,
- 'return_sequences': True},
- input_shape=(num_samples, timesteps, embedding_dim))
-
- def test_dynamic_behavior_GRU(self):
- num_samples = 2
- timesteps = 3
- embedding_dim = 4
- units = 2
- with self.test_session():
- layer = keras.layers.GRU(units, input_shape=(None, embedding_dim))
- model = keras.models.Sequential()
- model.add(layer)
- model.compile('sgd', 'mse')
- x = np.random.random((num_samples, timesteps, embedding_dim))
- y = np.random.random((num_samples, units))
- model.train_on_batch(x, y)
-
- def test_dropout_GRU(self):
- num_samples = 2
- timesteps = 3
- embedding_dim = 4
- units = 2
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.GRU,
- kwargs={'units': units,
- 'dropout': 0.1,
- 'recurrent_dropout': 0.1},
- input_shape=(num_samples, timesteps, embedding_dim))
-
- def test_implementation_mode_GRU(self):
- num_samples = 2
- timesteps = 3
- embedding_dim = 4
- units = 2
- with self.test_session():
- for mode in [0, 1, 2]:
- testing_utils.layer_test(
- keras.layers.GRU,
- kwargs={'units': units,
- 'implementation': mode},
- input_shape=(num_samples, timesteps, embedding_dim))
-
- def test_statefulness_GRU(self):
- num_samples = 2
- timesteps = 3
- embedding_dim = 4
- units = 2
- layer_class = keras.layers.GRU
- with self.test_session():
- model = keras.models.Sequential()
- model.add(
- keras.layers.Embedding(
- 4,
- embedding_dim,
- mask_zero=True,
- input_length=timesteps,
- batch_input_shape=(num_samples, timesteps)))
- layer = layer_class(
- units, return_sequences=False, stateful=True, weights=None)
- model.add(layer)
- model.compile(optimizer='sgd', loss='mse')
- out1 = model.predict(np.ones((num_samples, timesteps)))
- self.assertEqual(out1.shape, (num_samples, units))
-
- # train once so that the states change
- model.train_on_batch(
- np.ones((num_samples, timesteps)), np.ones((num_samples, units)))
- out2 = model.predict(np.ones((num_samples, timesteps)))
-
- # if the state is not reset, output should be different
- self.assertNotEqual(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((num_samples, timesteps)))
- self.assertNotEqual(out2.max(), out3.max())
-
- # check that container-level reset_states() works
- model.reset_states()
- out4 = model.predict(np.ones((num_samples, timesteps)))
- np.testing.assert_allclose(out3, out4, atol=1e-5)
-
- # check that the call to `predict` updated the states
- out5 = model.predict(np.ones((num_samples, timesteps)))
- self.assertNotEqual(out4.max(), out5.max())
-
- # Check masking
- layer.reset_states()
-
- left_padded_input = np.ones((num_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((num_samples, timesteps))
- right_padded_input[0, -1:] = 0
- right_padded_input[1, -2:] = 0
- out7 = model.predict(right_padded_input)
-
- np.testing.assert_allclose(out7, out6, atol=1e-5)
-
- def test_regularizers_GRU(self):
- embedding_dim = 4
- layer_class = keras.layers.GRU
- with self.test_session():
- layer = layer_class(
- 5,
- return_sequences=False,
- weights=None,
- input_shape=(None, embedding_dim),
- kernel_regularizer=keras.regularizers.l1(0.01),
- recurrent_regularizer=keras.regularizers.l1(0.01),
- bias_regularizer='l2',
- activity_regularizer='l1')
- layer.build((None, None, 2))
- self.assertEqual(len(layer.losses), 3)
- layer(keras.backend.variable(np.ones((2, 3, 2))))
- self.assertEqual(len(layer.losses), 4)
-
- def test_constraints_GRU(self):
- embedding_dim = 4
- layer_class = keras.layers.GRU
- with self.test_session():
- k_constraint = keras.constraints.max_norm(0.01)
- r_constraint = keras.constraints.max_norm(0.01)
- b_constraint = keras.constraints.max_norm(0.01)
- layer = layer_class(
- 5,
- return_sequences=False,
- weights=None,
- input_shape=(None, embedding_dim),
- kernel_constraint=k_constraint,
- recurrent_constraint=r_constraint,
- bias_constraint=b_constraint)
- layer.build((None, None, embedding_dim))
- self.assertEqual(layer.kernel.constraint, k_constraint)
- self.assertEqual(layer.recurrent_kernel.constraint, r_constraint)
- self.assertEqual(layer.bias.constraint, b_constraint)
-
- def test_with_masking_layer_GRU(self):
- layer_class = keras.layers.GRU
- with self.test_session():
- inputs = np.random.random((2, 3, 4))
- targets = np.abs(np.random.random((2, 3, 5)))
- targets /= targets.sum(axis=-1, keepdims=True)
- model = keras.models.Sequential()
- model.add(keras.layers.Masking(input_shape=(3, 4)))
- model.add(layer_class(units=5, return_sequences=True, unroll=False))
- model.compile(loss='categorical_crossentropy', optimizer='adam')
- model.fit(inputs, targets, epochs=1, batch_size=2, verbose=1)
-
- def test_from_config_GRU(self):
- layer_class = keras.layers.GRU
- for stateful in (False, True):
- l1 = layer_class(units=1, stateful=stateful)
- l2 = layer_class.from_config(l1.get_config())
- assert l1.get_config() == l2.get_config()
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/layers/local.py b/tensorflow/contrib/keras/python/keras/layers/local.py
deleted file mode 100644
index 31a29cdaf4..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/local.py
+++ /dev/null
@@ -1,393 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Locally-connected layers.
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras import activations
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras import constraints
-from tensorflow.contrib.keras.python.keras import initializers
-from tensorflow.contrib.keras.python.keras import regularizers
-from tensorflow.contrib.keras.python.keras.engine import InputSpec
-from tensorflow.contrib.keras.python.keras.engine import Layer
-from tensorflow.contrib.keras.python.keras.utils import conv_utils
-from tensorflow.python.framework import tensor_shape
-
-
-class LocallyConnected1D(Layer):
- """Locally-connected layer for 1D inputs.
-
- The `LocallyConnected1D` layer works similarly to
- the `Conv1D` layer, except that weights are unshared,
- that is, a different set of filters is applied at each different patch
- of the input.
-
- Example:
- ```python
- # apply a unshared weight convolution 1d of length 3 to a sequence with
- # 10 timesteps, with 64 output filters
- model = Sequential()
- model.add(LocallyConnected1D(64, 3, input_shape=(10, 32)))
- # now model.output_shape == (None, 8, 64)
- # add a new conv1d on top
- model.add(LocallyConnected1D(32, 3))
- # now model.output_shape == (None, 6, 32)
- ```
-
- Arguments:
- filters: Integer, the dimensionality of the output space
- (i.e. the number output of filters in the convolution).
- kernel_size: An integer or tuple/list of a single integer,
- specifying the length of the 1D convolution window.
- strides: An integer or tuple/list of a single integer,
- specifying the stride length of the convolution.
- Specifying any stride value != 1 is incompatible with specifying
- any `dilation_rate` value != 1.
- padding: Currently only supports `"valid"` (case-insensitive).
- `"same"` may be supported in the future.
- activation: Activation function to use.
- If you don't specify anything, no activation is applied
- (ie. "linear" activation: `a(x) = x`).
- use_bias: Boolean, whether the layer uses a bias vector.
- kernel_initializer: Initializer for the `kernel` weights matrix.
- bias_initializer: Initializer for the bias vector.
- kernel_regularizer: Regularizer function applied to
- the `kernel` weights matrix.
- bias_regularizer: Regularizer function applied to the bias vector.
- activity_regularizer: Regularizer function applied to
- the output of the layer (its "activation")..
- kernel_constraint: Constraint function applied to the kernel matrix.
- bias_constraint: Constraint function applied to the bias vector.
-
- Input shape:
- 3D tensor with shape: `(batch_size, steps, input_dim)`
-
- Output shape:
- 3D tensor with shape: `(batch_size, new_steps, filters)`
- `steps` value might have changed due to padding or strides.
- """
-
- def __init__(self,
- filters,
- kernel_size,
- strides=1,
- padding='valid',
- data_format=None,
- activation=None,
- use_bias=True,
- kernel_initializer='glorot_uniform',
- bias_initializer='zeros',
- kernel_regularizer=None,
- bias_regularizer=None,
- activity_regularizer=None,
- kernel_constraint=None,
- bias_constraint=None,
- **kwargs):
- super(LocallyConnected1D, self).__init__(**kwargs)
- self.filters = filters
- self.kernel_size = conv_utils.normalize_tuple(kernel_size, 1, 'kernel_size')
- self.strides = conv_utils.normalize_tuple(strides, 1, 'strides')
- self.padding = conv_utils.normalize_padding(padding)
- if self.padding != 'valid':
- raise ValueError('Invalid border mode for LocallyConnected1D '
- '(only "valid" is supported): ' + padding)
- self.data_format = conv_utils.normalize_data_format(data_format)
- self.activation = activations.get(activation)
- self.use_bias = use_bias
- self.kernel_initializer = initializers.get(kernel_initializer)
- self.bias_initializer = initializers.get(bias_initializer)
- self.kernel_regularizer = regularizers.get(kernel_regularizer)
- self.bias_regularizer = regularizers.get(bias_regularizer)
- self.activity_regularizer = regularizers.get(activity_regularizer)
- self.kernel_constraint = constraints.get(kernel_constraint)
- self.bias_constraint = constraints.get(bias_constraint)
- self.input_spec = InputSpec(ndim=3)
-
- def build(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- input_dim = input_shape[2]
- if input_dim is None:
- raise ValueError('Axis 2 of input should be fully-defined. '
- 'Found shape:', input_shape)
- output_length = conv_utils.conv_output_length(
- input_shape[1], self.kernel_size[0], self.padding, self.strides[0])
- self.kernel_shape = (output_length, self.kernel_size[0] * input_dim,
- self.filters)
- self.kernel = self.add_weight(
- shape=self.kernel_shape,
- initializer=self.kernel_initializer,
- name='kernel',
- regularizer=self.kernel_regularizer,
- constraint=self.kernel_constraint)
- if self.use_bias:
- self.bias = self.add_weight(
- shape=(output_length, self.filters),
- initializer=self.bias_initializer,
- name='bias',
- regularizer=self.bias_regularizer,
- constraint=self.bias_constraint)
- else:
- self.bias = None
- self.input_spec = InputSpec(ndim=3, axes={2: input_dim})
- self.built = True
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- length = conv_utils.conv_output_length(input_shape[1], self.kernel_size[0],
- self.padding, self.strides[0])
- return tensor_shape.TensorShape([input_shape[0], length, self.filters])
-
- def call(self, inputs):
- output = K.local_conv1d(inputs, self.kernel, self.kernel_size, self.strides)
-
- if self.use_bias:
- output = K.bias_add(output, self.bias)
- if self.activation is not None:
- output = self.activation(output)
- return output
-
- def get_config(self):
- config = {
- 'filters': self.filters,
- 'kernel_size': self.kernel_size,
- 'strides': self.strides,
- 'padding': self.padding,
- 'activation': activations.serialize(self.activation),
- 'use_bias': self.use_bias,
- 'kernel_initializer': initializers.serialize(self.kernel_initializer),
- 'bias_initializer': initializers.serialize(self.bias_initializer),
- '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)
- }
- base_config = super(LocallyConnected1D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class LocallyConnected2D(Layer):
- """Locally-connected layer for 2D inputs.
-
- The `LocallyConnected2D` layer works similarly
- to the `Conv2D` layer, except that weights are unshared,
- that is, a different set of filters is applied at each
- different patch of the input.
-
- Examples:
- ```python
- # apply a 3x3 unshared weights convolution with 64 output filters on a
- 32x32 image
- # with `data_format="channels_last"`:
- model = Sequential()
- model.add(LocallyConnected2D(64, (3, 3), input_shape=(32, 32, 3)))
- # now model.output_shape == (None, 30, 30, 64)
- # notice that this layer will consume (30*30)*(3*3*3*64) + (30*30)*64
- parameters
-
- # add a 3x3 unshared weights convolution on top, with 32 output filters:
- model.add(LocallyConnected2D(32, (3, 3)))
- # now model.output_shape == (None, 28, 28, 32)
- ```
-
- Arguments:
- filters: Integer, the dimensionality of the output space
- (i.e. the number output of filters in the convolution).
- kernel_size: An integer or tuple/list of 2 integers, specifying the
- width and height of the 2D convolution window.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- strides: An integer or tuple/list of 2 integers,
- specifying the strides of the convolution along the width and height.
- Can be a single integer to specify the same value for
- all spatial dimensions.
- padding: Currently only support `"valid"` (case-insensitive).
- `"same"` will be supported in future.
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, height, width, channels)` while `channels_first`
- corresponds to inputs with shape
- `(batch, channels, height, width)`.
- 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 "channels_last".
- activation: Activation function to use.
- If you don't specify anything, no activation is applied
- (ie. "linear" activation: `a(x) = x`).
- use_bias: Boolean, whether the layer uses a bias vector.
- kernel_initializer: Initializer for the `kernel` weights matrix.
- bias_initializer: Initializer for the bias vector.
- kernel_regularizer: Regularizer function applied to
- the `kernel` weights matrix.
- bias_regularizer: Regularizer function applied to the bias vector.
- activity_regularizer: Regularizer function applied to
- the output of the layer (its "activation")..
- kernel_constraint: Constraint function applied to the kernel matrix.
- bias_constraint: Constraint function applied to the bias vector.
-
- Input shape:
- 4D tensor with shape:
- `(samples, channels, rows, cols)` if data_format='channels_first'
- or 4D tensor with shape:
- `(samples, rows, cols, channels)` if data_format='channels_last'.
-
- Output shape:
- 4D tensor with shape:
- `(samples, filters, new_rows, new_cols)` if data_format='channels_first'
- or 4D tensor with shape:
- `(samples, new_rows, new_cols, filters)` if data_format='channels_last'.
- `rows` and `cols` values might have changed due to padding.
- """
-
- def __init__(self,
- filters,
- kernel_size,
- strides=(1, 1),
- padding='valid',
- data_format=None,
- activation=None,
- use_bias=True,
- kernel_initializer='glorot_uniform',
- bias_initializer='zeros',
- kernel_regularizer=None,
- bias_regularizer=None,
- activity_regularizer=None,
- kernel_constraint=None,
- bias_constraint=None,
- **kwargs):
- super(LocallyConnected2D, self).__init__(**kwargs)
- self.filters = filters
- self.kernel_size = conv_utils.normalize_tuple(kernel_size, 2, 'kernel_size')
- self.strides = conv_utils.normalize_tuple(strides, 2, 'strides')
- self.padding = conv_utils.normalize_padding(padding)
- if self.padding != 'valid':
- raise ValueError('Invalid border mode for LocallyConnected2D '
- '(only "valid" is supported): ' + padding)
- self.data_format = conv_utils.normalize_data_format(data_format)
- self.activation = activations.get(activation)
- self.use_bias = use_bias
- self.kernel_initializer = initializers.get(kernel_initializer)
- self.bias_initializer = initializers.get(bias_initializer)
- self.kernel_regularizer = regularizers.get(kernel_regularizer)
- self.bias_regularizer = regularizers.get(bias_regularizer)
- self.activity_regularizer = regularizers.get(activity_regularizer)
- self.kernel_constraint = constraints.get(kernel_constraint)
- self.bias_constraint = constraints.get(bias_constraint)
- self.input_spec = InputSpec(ndim=4)
-
- def build(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- if self.data_format == 'channels_last':
- input_row, input_col = input_shape[1:-1]
- input_filter = input_shape[3]
- else:
- input_row, input_col = input_shape[2:]
- input_filter = input_shape[1]
- if input_row is None or input_col is None:
- raise ValueError('The spatial dimensions of the inputs to '
- ' a LocallyConnected2D layer '
- 'should be fully-defined, but layer received '
- 'the inputs shape ' + str(input_shape))
-
- output_row = conv_utils.conv_output_length(input_row, self.kernel_size[0],
- self.padding, self.strides[0])
- output_col = conv_utils.conv_output_length(input_col, self.kernel_size[1],
- self.padding, self.strides[1])
- self.output_row = output_row
- self.output_col = output_col
- self.kernel_shape = (
- output_row * output_col,
- self.kernel_size[0] * self.kernel_size[1] * input_filter, self.filters)
- self.kernel = self.add_weight(
- shape=self.kernel_shape,
- initializer=self.kernel_initializer,
- name='kernel',
- regularizer=self.kernel_regularizer,
- constraint=self.kernel_constraint)
- if self.use_bias:
- self.bias = self.add_weight(
- shape=(output_row, output_col, self.filters),
- initializer=self.bias_initializer,
- name='bias',
- regularizer=self.bias_regularizer,
- constraint=self.bias_constraint)
- else:
- self.bias = None
- if self.data_format == 'channels_first':
- self.input_spec = InputSpec(ndim=4, axes={1: input_filter})
- else:
- self.input_spec = InputSpec(ndim=4, axes={-1: input_filter})
- self.built = True
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- if self.data_format == 'channels_first':
- rows = input_shape[2]
- cols = input_shape[3]
- elif self.data_format == 'channels_last':
- rows = input_shape[1]
- cols = input_shape[2]
- rows = conv_utils.conv_output_length(rows, self.kernel_size[0],
- self.padding, self.strides[0])
- cols = conv_utils.conv_output_length(cols, self.kernel_size[1],
- self.padding, self.strides[1])
-
- if self.data_format == 'channels_first':
- return tensor_shape.TensorShape(
- [input_shape[0], self.filters, rows, cols])
- elif self.data_format == 'channels_last':
- return tensor_shape.TensorShape(
- [input_shape[0], rows, cols, self.filters])
-
- def call(self, inputs):
- output = K.local_conv2d(inputs,
- self.kernel,
- self.kernel_size,
- self.strides,
- (self.output_row, self.output_col),
- self.data_format)
- if self.use_bias:
- output = K.bias_add(output, self.bias, data_format=self.data_format)
-
- output = self.activation(output)
- return output
-
- def get_config(self):
- config = {
- 'filters': self.filters,
- 'kernel_size': self.kernel_size,
- 'strides': self.strides,
- 'padding': self.padding,
- 'data_format': self.data_format,
- 'activation': activations.serialize(self.activation),
- 'use_bias': self.use_bias,
- 'kernel_initializer': initializers.serialize(self.kernel_initializer),
- 'bias_initializer': initializers.serialize(self.bias_initializer),
- '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)
- }
- base_config = super(LocallyConnected2D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
diff --git a/tensorflow/contrib/keras/python/keras/layers/local_test.py b/tensorflow/contrib/keras/python/keras/layers/local_test.py
deleted file mode 100644
index 6da20d8f83..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/local_test.py
+++ /dev/null
@@ -1,171 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for locally-connected layers."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-
-
-class LocallyConnectedLayersTest(test.TestCase):
-
- def test_locallyconnected_1d(self):
- num_samples = 2
- num_steps = 8
- input_dim = 5
- filter_length = 3
- filters = 4
-
- for padding in ['valid']:
- for strides in [1]:
- if padding == 'same' and strides != 1:
- continue
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.LocallyConnected1D,
- kwargs={
- 'filters': filters,
- 'kernel_size': filter_length,
- 'padding': padding,
- 'strides': strides
- },
- input_shape=(num_samples, num_steps, input_dim))
-
- def test_locallyconnected_1d_regularization(self):
- num_samples = 2
- num_steps = 8
- input_dim = 5
- filter_length = 3
- filters = 4
- kwargs = {
- 'filters': filters,
- 'kernel_size': filter_length,
- 'kernel_regularizer': 'l2',
- 'bias_regularizer': 'l2',
- 'activity_regularizer': 'l2',
- }
-
- with self.test_session():
- layer = keras.layers.LocallyConnected1D(**kwargs)
- layer.build((num_samples, num_steps, input_dim))
- self.assertEqual(len(layer.losses), 2)
- layer(
- keras.backend.variable(np.ones((num_samples, num_steps, input_dim))))
- self.assertEqual(len(layer.losses), 3)
-
- k_constraint = keras.constraints.max_norm(0.01)
- b_constraint = keras.constraints.max_norm(0.01)
- kwargs = {
- 'filters': filters,
- 'kernel_size': filter_length,
- 'kernel_constraint': k_constraint,
- 'bias_constraint': b_constraint,
- }
- with self.test_session():
- layer = keras.layers.LocallyConnected1D(**kwargs)
- layer.build((num_samples, num_steps, input_dim))
- self.assertEqual(layer.kernel.constraint, k_constraint)
- self.assertEqual(layer.bias.constraint, b_constraint)
-
- def test_locallyconnected_2d(self):
- num_samples = 8
- filters = 3
- stack_size = 4
- num_row = 6
- num_col = 10
-
- for padding in ['valid']:
- for strides in [(1, 1), (2, 2)]:
- if padding == 'same' and strides != (1, 1):
- continue
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.LocallyConnected2D,
- kwargs={
- 'filters': filters,
- 'kernel_size': 3,
- 'padding': padding,
- 'kernel_regularizer': 'l2',
- 'bias_regularizer': 'l2',
- 'activity_regularizer': 'l2',
- 'strides': strides,
- 'data_format': 'channels_last'
- },
- input_shape=(num_samples, num_row, num_col, stack_size))
-
- def test_locallyconnected_2d_channels_first(self):
- num_samples = 8
- filters = 3
- stack_size = 4
- num_row = 6
- num_col = 10
-
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.LocallyConnected2D,
- kwargs={
- 'filters': filters,
- 'kernel_size': 3,
- 'data_format': 'channels_first'
- },
- input_shape=(num_samples, num_row, num_col, stack_size))
-
- def test_locallyconnected_2d_regularization(self):
- num_samples = 8
- filters = 3
- stack_size = 4
- num_row = 6
- num_col = 10
- kwargs = {
- 'filters': filters,
- 'kernel_size': 3,
- 'kernel_regularizer': 'l2',
- 'bias_regularizer': 'l2',
- 'activity_regularizer': 'l2',
- }
- with self.test_session():
- layer = keras.layers.LocallyConnected2D(**kwargs)
- layer.build((num_samples, num_row, num_col, stack_size))
- self.assertEqual(len(layer.losses), 2)
- layer(
- keras.backend.variable(
- np.ones((num_samples, num_row, num_col, stack_size))))
- self.assertEqual(len(layer.losses), 3)
-
- k_constraint = keras.constraints.max_norm(0.01)
- b_constraint = keras.constraints.max_norm(0.01)
- kwargs = {
- 'filters': filters,
- 'kernel_size': 3,
- 'kernel_constraint': k_constraint,
- 'bias_constraint': b_constraint,
- }
- with self.test_session():
- layer = keras.layers.LocallyConnected2D(**kwargs)
- layer.build((num_samples, num_row, num_col, stack_size))
- self.assertEqual(layer.kernel.constraint, k_constraint)
- self.assertEqual(layer.bias.constraint, b_constraint)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/layers/lstm_test.py b/tensorflow/contrib/keras/python/keras/layers/lstm_test.py
deleted file mode 100644
index d39ea90523..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/lstm_test.py
+++ /dev/null
@@ -1,369 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for LSTM layer."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-
-
-class LSTMLayerTest(test.TestCase):
-
- def test_return_sequences_LSTM(self):
- num_samples = 2
- timesteps = 3
- embedding_dim = 4
- units = 2
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.LSTM,
- kwargs={'units': units,
- 'return_sequences': True},
- input_shape=(num_samples, timesteps, embedding_dim))
-
- def test_dynamic_behavior_LSTM(self):
- num_samples = 2
- timesteps = 3
- embedding_dim = 4
- units = 2
- with self.test_session():
- layer = keras.layers.LSTM(units, input_shape=(None, embedding_dim))
- model = keras.models.Sequential()
- model.add(layer)
- model.compile('sgd', 'mse')
- x = np.random.random((num_samples, timesteps, embedding_dim))
- y = np.random.random((num_samples, units))
- model.train_on_batch(x, y)
-
- def test_dropout_LSTM(self):
- num_samples = 2
- timesteps = 3
- embedding_dim = 4
- units = 2
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.LSTM,
- kwargs={'units': units,
- 'dropout': 0.1,
- 'recurrent_dropout': 0.1},
- input_shape=(num_samples, timesteps, embedding_dim))
-
- def test_implementation_mode_LSTM(self):
- num_samples = 2
- timesteps = 3
- embedding_dim = 4
- units = 2
- with self.test_session():
- for mode in [0, 1, 2]:
- testing_utils.layer_test(
- keras.layers.LSTM,
- kwargs={'units': units,
- 'implementation': mode},
- input_shape=(num_samples, timesteps, embedding_dim))
-
- def test_statefulness_LSTM(self):
- num_samples = 2
- timesteps = 3
- embedding_dim = 4
- units = 2
- layer_class = keras.layers.LSTM
- with self.test_session():
- model = keras.models.Sequential()
- model.add(
- keras.layers.Embedding(
- 4,
- embedding_dim,
- mask_zero=True,
- input_length=timesteps,
- batch_input_shape=(num_samples, timesteps)))
- layer = layer_class(
- units, return_sequences=False, stateful=True, weights=None)
- model.add(layer)
- model.compile(optimizer='sgd', loss='mse')
- out1 = model.predict(np.ones((num_samples, timesteps)))
- self.assertEqual(out1.shape, (num_samples, units))
-
- # train once so that the states change
- model.train_on_batch(
- np.ones((num_samples, timesteps)), np.ones((num_samples, units)))
- out2 = model.predict(np.ones((num_samples, timesteps)))
-
- # if the state is not reset, output should be different
- self.assertNotEqual(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((num_samples, timesteps)))
- self.assertNotEqual(out2.max(), out3.max())
-
- # check that container-level reset_states() works
- model.reset_states()
- out4 = model.predict(np.ones((num_samples, timesteps)))
- self.assertAllClose(out3, out4, atol=1e-5)
-
- # check that the call to `predict` updated the states
- out5 = model.predict(np.ones((num_samples, timesteps)))
- self.assertNotEqual(out4.max(), out5.max())
-
- # Check masking
- layer.reset_states()
-
- left_padded_input = np.ones((num_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((num_samples, timesteps))
- right_padded_input[0, -1:] = 0
- right_padded_input[1, -2:] = 0
- out7 = model.predict(right_padded_input)
-
- self.assertAllClose(out7, out6, atol=1e-5)
-
- def test_regularizers_LSTM(self):
- embedding_dim = 4
- layer_class = keras.layers.LSTM
- with self.test_session():
- layer = layer_class(
- 5,
- return_sequences=False,
- weights=None,
- input_shape=(None, embedding_dim),
- kernel_regularizer=keras.regularizers.l1(0.01),
- recurrent_regularizer=keras.regularizers.l1(0.01),
- bias_regularizer='l2',
- activity_regularizer='l1')
- layer.build((None, None, 2))
- self.assertEqual(len(layer.losses), 3)
- layer(keras.backend.variable(np.ones((2, 3, 2))))
- self.assertEqual(len(layer.losses), 4)
-
- def test_constraints_LSTM(self):
- embedding_dim = 4
- layer_class = keras.layers.LSTM
- with self.test_session():
- k_constraint = keras.constraints.max_norm(0.01)
- r_constraint = keras.constraints.max_norm(0.01)
- b_constraint = keras.constraints.max_norm(0.01)
- layer = layer_class(
- 5,
- return_sequences=False,
- weights=None,
- input_shape=(None, embedding_dim),
- kernel_constraint=k_constraint,
- recurrent_constraint=r_constraint,
- bias_constraint=b_constraint)
- layer.build((None, None, embedding_dim))
- self.assertEqual(layer.kernel.constraint, k_constraint)
- self.assertEqual(layer.recurrent_kernel.constraint, r_constraint)
- self.assertEqual(layer.bias.constraint, b_constraint)
-
- def test_with_masking_layer_LSTM(self):
- layer_class = keras.layers.LSTM
- with self.test_session():
- inputs = np.random.random((2, 3, 4))
- targets = np.abs(np.random.random((2, 3, 5)))
- targets /= targets.sum(axis=-1, keepdims=True)
- model = keras.models.Sequential()
- model.add(keras.layers.Masking(input_shape=(3, 4)))
- model.add(layer_class(units=5, return_sequences=True, unroll=False))
- model.compile(loss='categorical_crossentropy', optimizer='adam')
- model.fit(inputs, targets, epochs=1, batch_size=2, verbose=1)
-
- def test_from_config_LSTM(self):
- layer_class = keras.layers.LSTM
- for stateful in (False, True):
- l1 = layer_class(units=1, stateful=stateful)
- l2 = layer_class.from_config(l1.get_config())
- assert l1.get_config() == l2.get_config()
-
- def test_specify_initial_state_keras_tensor(self):
- num_states = 2
- timesteps = 3
- embedding_dim = 4
- units = 3
- num_samples = 2
-
- with self.test_session():
- # Test with Keras tensor
- inputs = keras.Input((timesteps, embedding_dim))
- initial_state = [keras.Input((units,)) for _ in range(num_states)]
- layer = keras.layers.LSTM(units)
- if len(initial_state) == 1:
- output = layer(inputs, initial_state=initial_state[0])
- else:
- output = layer(inputs, initial_state=initial_state)
- assert initial_state[0] in layer.inbound_nodes[0].input_tensors
-
- model = keras.models.Model([inputs] + initial_state, output)
- model.compile(loss='categorical_crossentropy', optimizer='adam')
-
- inputs = np.random.random((num_samples, timesteps, embedding_dim))
- initial_state = [np.random.random((num_samples, units))
- for _ in range(num_states)]
- targets = np.random.random((num_samples, units))
- model.train_on_batch([inputs] + initial_state, targets)
-
- def test_specify_initial_state_non_keras_tensor(self):
- num_states = 2
- timesteps = 3
- embedding_dim = 4
- units = 3
- num_samples = 2
-
- with self.test_session():
- # Test with non-Keras tensor
- inputs = keras.Input((timesteps, embedding_dim))
- initial_state = [keras.backend.random_normal_variable(
- (num_samples, units), 0, 1)
- for _ in range(num_states)]
- layer = keras.layers.LSTM(units)
- output = layer(inputs, initial_state=initial_state)
-
- model = keras.models.Model(inputs, output)
- model.compile(loss='categorical_crossentropy', optimizer='adam')
-
- inputs = np.random.random((num_samples, timesteps, embedding_dim))
- targets = np.random.random((num_samples, units))
- model.train_on_batch(inputs, targets)
-
- def test_reset_states_with_values(self):
- num_states = 2
- timesteps = 3
- embedding_dim = 4
- units = 3
- num_samples = 2
-
- with self.test_session():
- layer = keras.layers.LSTM(units, stateful=True)
- layer.build((num_samples, timesteps, embedding_dim))
- layer.reset_states()
- assert len(layer.states) == num_states
- assert layer.states[0] is not None
- self.assertAllClose(
- keras.backend.eval(layer.states[0]),
- np.zeros(keras.backend.int_shape(layer.states[0])),
- atol=1e-4)
- state_shapes = [keras.backend.int_shape(state) for state in layer.states]
- values = [np.ones(shape) for shape in state_shapes]
- if len(values) == 1:
- values = values[0]
- layer.reset_states(values)
- self.assertAllClose(
- keras.backend.eval(layer.states[0]),
- np.ones(keras.backend.int_shape(layer.states[0])),
- atol=1e-4)
-
- # Test with invalid data
- with self.assertRaises(ValueError):
- layer.reset_states([1] * (len(layer.states) + 1))
-
- def test_specify_state_with_masking(self):
- num_states = 2
- timesteps = 3
- embedding_dim = 4
- units = 3
- num_samples = 2
-
- with self.test_session():
- inputs = keras.Input((timesteps, embedding_dim))
- _ = keras.layers.Masking()(inputs)
- initial_state = [keras.Input((units,)) for _ in range(num_states)]
- output = keras.layers.LSTM(units)(inputs, initial_state=initial_state)
-
- model = keras.models.Model([inputs] + initial_state, output)
- model.compile(loss='categorical_crossentropy', optimizer='adam')
-
- inputs = np.random.random((num_samples, timesteps, embedding_dim))
- initial_state = [np.random.random((num_samples, units))
- for _ in range(num_states)]
- targets = np.random.random((num_samples, units))
- model.train_on_batch([inputs] + initial_state, targets)
-
- def test_return_state(self):
- num_states = 2
- timesteps = 3
- embedding_dim = 4
- units = 3
- num_samples = 2
-
- with self.test_session():
- inputs = keras.Input(batch_shape=(num_samples, timesteps, embedding_dim))
- layer = keras.layers.LSTM(units, return_state=True, stateful=True)
- outputs = layer(inputs)
- state = outputs[1:]
- assert len(state) == num_states
- model = keras.models.Model(inputs, state[0])
-
- inputs = np.random.random((num_samples, timesteps, embedding_dim))
- state = model.predict(inputs)
- self.assertAllClose(keras.backend.eval(layer.states[0]), state, atol=1e-4)
-
- def test_state_reuse(self):
- timesteps = 3
- embedding_dim = 4
- units = 3
- num_samples = 2
-
- with self.test_session():
- inputs = keras.Input(batch_shape=(num_samples, timesteps, embedding_dim))
- layer = keras.layers.LSTM(units, return_state=True, return_sequences=True)
- outputs = layer(inputs)
- output, state = outputs[0], outputs[1:]
- output = keras.layers.LSTM(units)(output, initial_state=state)
- model = keras.models.Model(inputs, output)
-
- inputs = np.random.random((num_samples, timesteps, embedding_dim))
- outputs = model.predict(inputs)
-
- def test_initial_states_as_other_inputs(self):
- timesteps = 3
- embedding_dim = 4
- units = 3
- num_samples = 2
- num_states = 2
- layer_class = keras.layers.LSTM
-
- with self.test_session():
- # Test with Keras tensor
- main_inputs = keras.Input((timesteps, embedding_dim))
- initial_state = [keras.Input((units,)) for _ in range(num_states)]
- inputs = [main_inputs] + initial_state
-
- layer = layer_class(units)
- output = layer(inputs)
- assert initial_state[0] in layer.inbound_nodes[0].input_tensors
-
- model = keras.models.Model(inputs, output)
- model.compile(loss='categorical_crossentropy', optimizer='adam')
-
- main_inputs = np.random.random((num_samples, timesteps, embedding_dim))
- initial_state = [np.random.random((num_samples, units))
- for _ in range(num_states)]
- targets = np.random.random((num_samples, units))
- model.train_on_batch([main_inputs] + initial_state, targets)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/layers/merge.py b/tensorflow/contrib/keras/python/keras/layers/merge.py
deleted file mode 100644
index 486036a156..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/merge.py
+++ /dev/null
@@ -1,617 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-# pylint: disable=not-callable
-# pylint: disable=redefined-builtin
-"""Layers can merge several input tensors into a single output tensor.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.engine.topology import Layer
-from tensorflow.python.framework import tensor_shape
-
-
-class _Merge(Layer):
- """Generic merge layer for elementwise merge functions.
-
- Used to implement `Sum`, `Average`, etc.
-
- Arguments:
- **kwargs: standard layer keyword arguments.
- """
-
- def __init__(self, **kwargs):
- super(_Merge, self).__init__(**kwargs)
- self.supports_masking = True
-
- def _merge_function(self, inputs):
- raise NotImplementedError
-
- def _compute_elemwise_op_output_shape(self, shape1, shape2):
- """Computes the shape of the resultant of an elementwise operation.
-
- Arguments:
- shape1: tuple or None. Shape of the first tensor
- shape2: tuple or None. Shape of the second tensor
-
- Returns:
- expected output shape when an element-wise operation is
- carried out on 2 tensors with shapes shape1 and shape2.
- tuple or None.
-
- Raises:
- ValueError: if shape1 and shape2 are not compatible for
- element-wise operations.
- """
- if None in [shape1, shape2]:
- return None
- elif len(shape1) < len(shape2):
- return self._compute_elemwise_op_output_shape(shape2, shape1)
- elif not shape2:
- return shape1
- output_shape = list(shape1[:-len(shape2)])
- for i, j in zip(shape1[-len(shape2):], shape2):
- if i is None or j is None:
- output_shape.append(None)
- elif i == 1:
- output_shape.append(j)
- elif j == 1:
- output_shape.append(i)
- else:
- if i != j:
- raise ValueError('Operands could not be broadcast '
- 'together with shapes ' + str(shape1) + ' ' +
- str(shape2))
- output_shape.append(i)
- return tuple(output_shape)
-
- def build(self, input_shape):
- # Used purely for shape validation.
- if not isinstance(input_shape, list):
- raise ValueError('A merge layer should be called ' 'on a list of inputs.')
- if len(input_shape) < 2:
- raise ValueError('A merge layer should be called '
- 'on a list of at least 2 inputs. '
- 'Got ' + str(len(input_shape)) + ' inputs.')
- input_shape = [tensor_shape.TensorShape(s).as_list() for s in input_shape]
- batch_sizes = [s[0] for s in input_shape if s is not None]
- batch_sizes = set(batch_sizes)
- batch_sizes -= set([None])
- if len(batch_sizes) > 1:
- raise ValueError('Can not merge tensors with different '
- 'batch sizes. Got tensors with shapes : ' +
- str(input_shape))
- if input_shape[0] is None:
- output_shape = None
- else:
- output_shape = input_shape[0][1:]
- for i in range(1, len(input_shape)):
- if input_shape[i] is None:
- shape = None
- else:
- shape = input_shape[i][1:]
- output_shape = self._compute_elemwise_op_output_shape(output_shape, shape)
- # If the inputs have different ranks, we have to reshape them
- # to make them broadcastable.
- if None not in input_shape and len(set(map(len, input_shape))) == 1:
- self._reshape_required = False
- else:
- self._reshape_required = True
- self.built = True
-
- def call(self, inputs):
- if self._reshape_required:
- reshaped_inputs = []
- input_ndims = list(map(K.ndim, inputs))
- if None not in input_ndims:
- # If ranks of all inputs are available,
- # we simply expand each of them at axis=1
- # until all of them have the same rank.
- max_ndim = max(input_ndims)
- for x in inputs:
- x_ndim = K.ndim(x)
- for _ in range(max_ndim - x_ndim):
- x = K.expand_dims(x, 1)
- reshaped_inputs.append(x)
- return self._merge_function(reshaped_inputs)
- else:
- # Transpose all inputs so that batch size is the last dimension.
- # (batch_size, dim1, dim2, ... ) -> (dim1, dim2, ... , batch_size)
- transposed = False
- for x in inputs:
- x_ndim = K.ndim(x)
- if x_ndim is None:
- x_shape = K.shape(x)
- batch_size = x_shape[0]
- new_shape = K.concatenate([x_shape[1:], K.expand_dims(batch_size)])
- x_transposed = K.reshape(x,
- K.stack([batch_size,
- K.prod(x_shape[1:])]))
- x_transposed = K.permute_dimensions(x_transposed, (1, 0))
- x_transposed = K.reshape(x_transposed, new_shape)
- reshaped_inputs.append(x_transposed)
- transposed = True
- elif x_ndim > 1:
- dims = list(range(1, x_ndim)) + [0]
- reshaped_inputs.append(K.permute_dimensions(x, dims))
- transposed = True
- else:
- # We don't transpose inputs if they are 1D vectors or scalars.
- reshaped_inputs.append(x)
- y = self._merge_function(reshaped_inputs)
- y_ndim = K.ndim(y)
- if transposed:
- # If inputs have been transposed, we have to transpose the output too.
- if y_ndim is None:
- y_shape = K.shape(y)
- y_ndim = K.shape(y_shape)[0]
- batch_size = y_shape[y_ndim - 1]
- new_shape = K.concatenate(
- [K.expand_dims(batch_size), y_shape[:y_ndim - 1]])
- y = K.reshape(y, (-1, batch_size))
- y = K.permute_dimensions(y, (1, 0))
- y = K.reshape(y, new_shape)
- elif y_ndim > 1:
- dims = [y_ndim - 1] + list(range(y_ndim - 1))
- y = K.permute_dimensions(y, dims)
- return y
- else:
- return self._merge_function(inputs)
-
- def _compute_output_shape(self, input_shape):
- if input_shape[0] is None:
- output_shape = None
- else:
- output_shape = input_shape[0][1:]
- for i in range(1, len(input_shape)):
- if input_shape[i] is None:
- shape = None
- else:
- shape = input_shape[i][1:]
- output_shape = self._compute_elemwise_op_output_shape(output_shape, shape)
- batch_sizes = [s[0] for s in input_shape if s is not None]
- batch_sizes = set(batch_sizes)
- batch_sizes -= set([None])
- if len(batch_sizes) == 1:
- output_shape = (list(batch_sizes)[0],) + output_shape
- else:
- output_shape = (None,) + output_shape
- return output_shape
-
- def compute_mask(self, inputs, mask=None):
- if mask is None:
- return None
- if not isinstance(mask, list):
- raise ValueError('`mask` should be a list.')
- if not isinstance(inputs, list):
- raise ValueError('`inputs` should be a list.')
- if len(mask) != len(inputs):
- raise ValueError('The lists `inputs` and `mask` '
- 'should have the same length.')
- if all([m is None for m in mask]):
- return None
- masks = [K.expand_dims(m, 0) for m in mask if m is not None]
- return K.all(K.concatenate(masks, axis=0), axis=0, keepdims=False)
-
-
-class Add(_Merge):
- """Layer that adds a list of inputs.
-
- It takes as input a list of tensors,
- all of the same shape, and returns
- a single tensor (also of the same shape).
- """
-
- def _merge_function(self, inputs):
- output = inputs[0]
- for i in range(1, len(inputs)):
- output += inputs[i]
- return output
-
-
-class Subtract(_Merge):
- """Layer that subtracts two inputs.
-
- It takes as input a list of tensors of size 2,
- both of the same shape, and returns a single tensor, (inputs[0] - inputs[1]),
- also of the same shape.
-
- Examples:
-
- ```python
- import keras
-
- input1 = keras.layers.Input(shape=(16,))
- x1 = keras.layers.Dense(8, activation='relu')(input1)
- input2 = keras.layers.Input(shape=(32,))
- x2 = keras.layers.Dense(8, activation='relu')(input2)
- # Equivalent to subtracted = keras.layers.subtract([x1, x2])
- subtracted = keras.layers.Subtract()([x1, x2])
-
- out = keras.layers.Dense(4)(subtracted)
- model = keras.models.Model(inputs=[input1, input2], outputs=out)
- ```
- """
-
- def _merge_function(self, inputs):
- if len(inputs) != 2:
- raise ValueError('`Subtract` layer should be called '
- 'on exactly 2 inputs. Received: %s' % inputs)
- return inputs[0] - inputs[1]
-
-
-class Multiply(_Merge):
- """Layer that multiplies (element-wise) a list of inputs.
-
- It takes as input a list of tensors,
- all of the same shape, and returns
- a single tensor (also of the same shape).
- """
-
- def _merge_function(self, inputs):
- output = inputs[0]
- for i in range(1, len(inputs)):
- output *= inputs[i]
- return output
-
-
-class Average(_Merge):
- """Layer that averages a list of inputs.
-
- It takes as input a list of tensors,
- all of the same shape, and returns
- a single tensor (also of the same shape).
- """
-
- def _merge_function(self, inputs):
- output = inputs[0]
- for i in range(1, len(inputs)):
- output += inputs[i]
- return output / len(inputs)
-
-
-class Maximum(_Merge):
- """Layer that computes the maximum (element-wise) a list of inputs.
-
- It takes as input a list of tensors,
- all of the same shape, and returns
- a single tensor (also of the same shape).
- """
-
- def _merge_function(self, inputs):
- output = inputs[0]
- for i in range(1, len(inputs)):
- output = K.maximum(output, inputs[i])
- return output
-
-
-class Concatenate(_Merge):
- """Layer that concatenates a list of inputs.
-
- It takes as input a list of tensors,
- all of the same shape expect for the concatenation axis,
- and returns a single tensor, the concatenation of all inputs.
-
- Arguments:
- axis: Axis along which to concatenate.
- **kwargs: standard layer keyword arguments.
- """
-
- def __init__(self, axis=-1, **kwargs):
- super(Concatenate, self).__init__(**kwargs)
- self.axis = axis
- self.supports_masking = True
-
- def build(self, input_shape):
- # Used purely for shape validation.
- if not isinstance(input_shape, list):
- raise ValueError('`Concatenate` layer should be called '
- 'on a list of inputs')
- if all([shape is None for shape in input_shape]):
- return
- reduced_inputs_shapes = [
- tensor_shape.TensorShape(shape).as_list() for shape in input_shape
- ]
- shape_set = set()
- for i in range(len(reduced_inputs_shapes)):
- del reduced_inputs_shapes[i][self.axis]
- shape_set.add(tuple(reduced_inputs_shapes[i]))
- if len(shape_set) > 1:
- raise ValueError('`Concatenate` layer requires '
- 'inputs with matching shapes '
- 'except for the concat axis. '
- 'Got inputs shapes: %s' % (input_shape))
- self.built = True
-
- def call(self, inputs):
- if not isinstance(inputs, list):
- raise ValueError('A `Concatenate` layer should be called '
- 'on a list of inputs.')
- return K.concatenate(inputs, axis=self.axis)
-
- def _compute_output_shape(self, input_shape):
- if not isinstance(input_shape, list):
- raise ValueError('A `Concatenate` layer should be called '
- 'on a list of inputs.')
- input_shapes = input_shape
- output_shape = tensor_shape.TensorShape(input_shapes[0]).as_list()
- for shape in input_shapes[1:]:
- shape = tensor_shape.TensorShape(shape).as_list()
- if output_shape[self.axis] is None or shape[self.axis] is None:
- output_shape[self.axis] = None
- break
- output_shape[self.axis] += shape[self.axis]
- return tensor_shape.TensorShape(output_shape)
-
- def compute_mask(self, inputs, mask=None):
- if mask is None:
- return None
- if not isinstance(mask, list):
- raise ValueError('`mask` should be a list.')
- if not isinstance(inputs, list):
- raise ValueError('`inputs` should be a list.')
- if len(mask) != len(inputs):
- raise ValueError('The lists `inputs` and `mask` '
- 'should have the same length.')
- if all([m is None for m in mask]):
- return None
- # Make a list of masks while making sure
- # the dimensionality of each mask
- # is the same as the corresponding input.
- masks = []
- for input_i, mask_i in zip(inputs, mask):
- if mask_i is None:
- # Input is unmasked. Append all 1s to masks,
- # but cast it to bool first
- masks.append(K.cast(K.ones_like(input_i), 'bool'))
- elif K.ndim(mask_i) < K.ndim(input_i):
- # Mask is smaller than the input, expand it
- masks.append(K.expand_dims(mask_i))
- else:
- masks.append(mask_i)
- concatenated = K.concatenate(masks, axis=self.axis)
- return K.all(concatenated, axis=-1, keepdims=False)
-
- def get_config(self):
- config = {
- 'axis': self.axis,
- }
- base_config = super(Concatenate, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Dot(_Merge):
- """Layer that computes a dot product between samples in two tensors.
-
- E.g. if applied to two tensors `a` and `b` of shape `(batch_size, n)`,
- the output will be a tensor of shape `(batch_size, 1)`
- where each entry `i` will be the dot product between
- `a[i]` and `b[i]`.
-
- Arguments:
- axes: Integer or tuple of integers,
- axis or axes along which to take the dot product.
- normalize: Whether to L2-normalize samples along the
- dot product axis before taking the dot product.
- If set to True, then the output of the dot product
- is the cosine proximity between the two samples.
- **kwargs: Standard layer keyword arguments.
- """
-
- def __init__(self, axes, normalize=False, **kwargs):
- super(Dot, self).__init__(**kwargs)
- if not isinstance(axes, int):
- if not isinstance(axes, (list, tuple)):
- raise TypeError('Invalid type for `axes` - '
- 'should be a list or an int.')
- if len(axes) != 2:
- raise ValueError('Invalid format for `axes` - '
- 'should contain two elements.')
- if not isinstance(axes[0], int) or not isinstance(axes[1], int):
- raise ValueError('Invalid format for `axes` - '
- 'list elements should be "int".')
- self.axes = axes
- self.normalize = normalize
- self.supports_masking = True
-
- def build(self, input_shape):
- # Used purely for shape validation.
- if not isinstance(input_shape, list) or len(input_shape) != 2:
- raise ValueError('A `Dot` layer should be called '
- 'on a list of 2 inputs.')
- shape1 = tensor_shape.TensorShape(input_shape[0]).as_list()
- shape2 = tensor_shape.TensorShape(input_shape[1]).as_list()
- if shape1 is None or shape2 is None:
- return
- if isinstance(self.axes, int):
- if self.axes < 0:
- axes = [self.axes % len(shape1), self.axes % len(shape2)]
- else:
- axes = [self.axes] * 2
- else:
- axes = self.axes
- if shape1[axes[0]] != shape2[axes[1]]:
- raise ValueError('Dimension incompatibility '
- '%s != %s. ' % (shape1[axes[0]], shape2[axes[1]]) +
- 'Layer shapes: %s, %s' % (shape1, shape2))
- self.built = True
-
- def call(self, inputs):
- x1 = inputs[0]
- x2 = inputs[1]
- if isinstance(self.axes, int):
- if self.axes < 0:
- axes = [self.axes % K.ndim(x1), self.axes % K.ndim(x2)]
- else:
- axes = [self.axes] * 2
- else:
- axes = []
- for i in range(len(self.axes)):
- if self.axes[i] < 0:
- axes.append(self.axes[i] % K.ndim(inputs[i]))
- else:
- axes.append(self.axes[i])
- if self.normalize:
- x1 = K.l2_normalize(x1, axis=axes[0])
- x2 = K.l2_normalize(x2, axis=axes[1])
- output = K.batch_dot(x1, x2, axes)
- return output
-
- def _compute_output_shape(self, input_shape):
- if not isinstance(input_shape, list) or len(input_shape) != 2:
- raise ValueError('A `Dot` layer should be called '
- 'on a list of 2 inputs.')
- shape1 = tensor_shape.TensorShape(input_shape[0]).as_list()
- shape2 = tensor_shape.TensorShape(input_shape[1]).as_list()
- if isinstance(self.axes, int):
- if self.axes < 0:
- axes = [self.axes % len(shape1), self.axes % len(shape2)]
- else:
- axes = [self.axes] * 2
- else:
- axes = self.axes
- shape1.pop(axes[0])
- shape2.pop(axes[1])
- shape2.pop(0)
- output_shape = shape1 + shape2
- if len(output_shape) == 1:
- output_shape += [1]
- return tensor_shape.TensorShape(output_shape)
-
- def compute_mask(self, inputs, mask=None):
- return None
-
- def get_config(self):
- config = {
- 'axes': self.axes,
- 'normalize': self.normalize,
- }
- base_config = super(Dot, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-def add(inputs, **kwargs):
- """Functional interface to the `Add` layer.
-
- Arguments:
- inputs: A list of input tensors (at least 2).
- **kwargs: Standard layer keyword arguments.
-
- Returns:
- A tensor, the sum of the inputs.
- """
- return Add(**kwargs)(inputs)
-
-
-def subtract(inputs, **kwargs):
- """Functional interface to the `Subtract` layer.
-
- Arguments:
- inputs: A list of input tensors (exactly 2).
- **kwargs: Standard layer keyword arguments.
-
- Returns:
- A tensor, the difference of the inputs.
-
- Examples:
-
- ```python
- import keras
-
- input1 = keras.layers.Input(shape=(16,))
- x1 = keras.layers.Dense(8, activation='relu')(input1)
- input2 = keras.layers.Input(shape=(32,))
- x2 = keras.layers.Dense(8, activation='relu')(input2)
- subtracted = keras.layers.subtract([x1, x2])
-
- out = keras.layers.Dense(4)(subtracted)
- model = keras.models.Model(inputs=[input1, input2], outputs=out)
- ```
- """
- return Subtract(**kwargs)(inputs)
-
-
-def multiply(inputs, **kwargs):
- """Functional interface to the `Multiply` layer.
-
- Arguments:
- inputs: A list of input tensors (at least 2).
- **kwargs: Standard layer keyword arguments.
-
- Returns:
- A tensor, the element-wise product of the inputs.
- """
- return Multiply(**kwargs)(inputs)
-
-
-def average(inputs, **kwargs):
- """Functional interface to the `Average` layer.
-
- Arguments:
- inputs: A list of input tensors (at least 2).
- **kwargs: Standard layer keyword arguments.
-
- Returns:
- A tensor, the average of the inputs.
- """
- return Average(**kwargs)(inputs)
-
-
-def maximum(inputs, **kwargs):
- """Functional interface to the `Maximum` layer.
-
- Arguments:
- inputs: A list of input tensors (at least 2).
- **kwargs: Standard layer keyword arguments.
-
- Returns:
- A tensor, the element-wise maximum of the inputs.
- """
- return Maximum(**kwargs)(inputs)
-
-
-def concatenate(inputs, axis=-1, **kwargs):
- """Functional interface to the `Concatenate` layer.
-
- Arguments:
- inputs: A list of input tensors (at least 2).
- axis: Concatenation axis.
- **kwargs: Standard layer keyword arguments.
-
- Returns:
- A tensor, the concatenation of the inputs alongside axis `axis`.
- """
- return Concatenate(axis=axis, **kwargs)(inputs)
-
-
-def dot(inputs, axes, normalize=False, **kwargs):
- """Functional interface to the `Dot` layer.
-
- Arguments:
- inputs: A list of input tensors (at least 2).
- axes: Integer or tuple of integers,
- axis or axes along which to take the dot product.
- normalize: Whether to L2-normalize samples along the
- dot product axis before taking the dot product.
- If set to True, then the output of the dot product
- is the cosine proximity between the two samples.
- **kwargs: Standard layer keyword arguments.
-
- Returns:
- A tensor, the dot product of the samples from the inputs.
- """
- return Dot(axes=axes, normalize=normalize, **kwargs)(inputs)
diff --git a/tensorflow/contrib/keras/python/keras/layers/merge_test.py b/tensorflow/contrib/keras/python/keras/layers/merge_test.py
deleted file mode 100644
index aca6728e2a..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/merge_test.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for merge layers."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.ops import array_ops
-from tensorflow.python.platform import test
-
-
-class MergeLayersTest(test.TestCase):
-
- def test_merge_add(self):
- with self.test_session():
- i1 = keras.layers.Input(shape=(4, 5))
- i2 = keras.layers.Input(shape=(4, 5))
- i3 = keras.layers.Input(shape=(4, 5))
-
- o = keras.layers.add([i1, i2, i3])
- self.assertListEqual(o.get_shape().as_list(), [None, 4, 5])
- model = keras.models.Model([i1, i2, i3], o)
-
- x1 = np.random.random((2, 4, 5))
- x2 = np.random.random((2, 4, 5))
- x3 = np.random.random((2, 4, 5))
- out = model.predict([x1, x2, x3])
- self.assertEqual(out.shape, (2, 4, 5))
- self.assertAllClose(out, x1 + x2 + x3, atol=1e-4)
-
- # test masking
- i1 = keras.layers.Input(shape=(4, 5))
- i2 = keras.layers.Input(shape=(4, 5))
- m1 = keras.layers.Masking()(i1)
- layer = keras.layers.Add()
- o = layer([m1, i2])
- self.assertListEqual(o.get_shape().as_list(), [None, 4, 5])
- mask = layer.output_mask
- self.assertListEqual(mask.get_shape().as_list(), [None, 4])
-
- # test missing shape
- i1 = array_ops.placeholder(shape=(4, None), dtype='float32')
- i2 = array_ops.placeholder(shape=(4, 5), dtype='float32')
- layer = keras.layers.Add()
- o = layer([i1, i2])
-
- def test_merge_elementwise_errors(self):
- i1 = keras.layers.Input(shape=(4, 5))
- i2 = keras.layers.Input(shape=(4, 6))
- with self.assertRaises(ValueError):
- keras.layers.add([i1, i2])
- with self.assertRaises(ValueError):
- keras.layers.add([i1])
- with self.assertRaises(ValueError):
- keras.layers.add(i1)
- with self.assertRaises(ValueError):
- keras.layers.add([i1])
-
- def test_merge_multiply(self):
- with self.test_session():
- i1 = keras.layers.Input(shape=(4, 5))
- i2 = keras.layers.Input(shape=(4, 5))
- i3 = keras.layers.Input(shape=(4, 5))
- o = keras.layers.multiply([i1, i2, i3])
- self.assertListEqual(o.get_shape().as_list(), [None, 4, 5])
- model = keras.models.Model([i1, i2, i3], o)
-
- x1 = np.random.random((2, 4, 5))
- x2 = np.random.random((2, 4, 5))
- x3 = np.random.random((2, 4, 5))
- out = model.predict([x1, x2, x3])
- self.assertEqual(out.shape, (2, 4, 5))
- self.assertAllClose(out, x1 * x2 * x3, atol=1e-4)
-
- def test_merge_average(self):
- with self.test_session():
- i1 = keras.layers.Input(shape=(4, 5))
- i2 = keras.layers.Input(shape=(4, 5))
- o = keras.layers.average([i1, i2])
- self.assertListEqual(o.get_shape().as_list(), [None, 4, 5])
- model = keras.models.Model([i1, i2], o)
-
- x1 = np.random.random((2, 4, 5))
- x2 = np.random.random((2, 4, 5))
- out = model.predict([x1, x2])
- self.assertEqual(out.shape, (2, 4, 5))
- self.assertAllClose(out, 0.5 * (x1 + x2), atol=1e-4)
-
- def test_merge_maximum(self):
- with self.test_session():
- i1 = keras.layers.Input(shape=(4, 5))
- i2 = keras.layers.Input(shape=(4, 5))
- o = keras.layers.maximum([i1, i2])
- self.assertListEqual(o.get_shape().as_list(), [None, 4, 5])
- model = keras.models.Model([i1, i2], o)
-
- x1 = np.random.random((2, 4, 5))
- x2 = np.random.random((2, 4, 5))
- out = model.predict([x1, x2])
- self.assertEqual(out.shape, (2, 4, 5))
- self.assertAllClose(out, np.maximum(x1, x2), atol=1e-4)
-
- def test_merge_concatenate(self):
- with self.test_session():
- i1 = keras.layers.Input(shape=(4, 5))
- i2 = keras.layers.Input(shape=(4, 5))
- o = keras.layers.concatenate([i1, i2], axis=1)
- self.assertListEqual(o.get_shape().as_list(), [None, 8, 5])
- model = keras.models.Model([i1, i2], o)
-
- x1 = np.random.random((2, 4, 5))
- x2 = np.random.random((2, 4, 5))
- out = model.predict([x1, x2])
- self.assertEqual(out.shape, (2, 8, 5))
- self.assertAllClose(out, np.concatenate([x1, x2], axis=1), atol=1e-4)
-
- # test masking
- m1 = keras.layers.Masking()(i1)
- layer = keras.layers.Concatenate()
- o = layer([m1, i2])
- self.assertListEqual(o.get_shape().as_list(), [None, 4, 10])
- mask = layer.output_mask
- self.assertListEqual(mask.get_shape().as_list(), [None, 4])
-
- def test_concatenate_errors(self):
- i1 = keras.layers.Input(shape=(4, 5))
- i2 = keras.layers.Input(shape=(3, 5))
- with self.assertRaises(ValueError):
- keras.layers.concatenate([i1, i2], axis=-1)
- with self.assertRaises(ValueError):
- keras.layers.concatenate(i1, axis=-1)
- with self.assertRaises(ValueError):
- keras.layers.concatenate([i1], axis=-1)
-
- def test_merge_dot(self):
- with self.test_session():
- i1 = keras.layers.Input(shape=(4,))
- i2 = keras.layers.Input(shape=(4,))
- o = keras.layers.dot([i1, i2], axes=1)
- self.assertListEqual(o.get_shape().as_list(), [None, 1])
- model = keras.models.Model([i1, i2], o)
- _ = keras.layers.Dot(axes=1).get_config()
-
- x1 = np.random.random((2, 4))
- x2 = np.random.random((2, 4))
- out = model.predict([x1, x2])
- self.assertEqual(out.shape, (2, 1))
- expected = np.zeros((2, 1))
- expected[0, 0] = np.dot(x1[0], x2[0])
- expected[1, 0] = np.dot(x1[1], x2[1])
- self.assertAllClose(out, expected, atol=1e-4)
-
- # Test with negative tuple of axes.
- o = keras.layers.dot([i1, i2], axes=(-1, -1))
- self.assertListEqual(o.get_shape().as_list(), [None, 1])
- model = keras.models.Model([i1, i2], o)
- out = model.predict([x1, x2])
- self.assertEqual(out.shape, (2, 1))
- self.assertAllClose(out, expected, atol=1e-4)
-
- # test _compute_output_shape
- layer = keras.layers.Dot(axes=-1)
- self.assertEqual(layer._compute_output_shape([(4, 5), (4, 5)]), (4, 1))
-
- def test_dot_errors(self):
- i1 = keras.layers.Input(shape=(4, 5))
- i2 = keras.layers.Input(shape=(4, 6))
- i3 = keras.layers.Input(shape=(4, 6))
- with self.assertRaises(ValueError):
- keras.layers.dot([i1, i2], axes=-1)
- with self.assertRaises(ValueError):
- keras.layers.dot(i1, axes=-1)
- with self.assertRaises(ValueError):
- keras.layers.dot([i1], axes=-1)
- with self.assertRaises(ValueError):
- keras.layers.dot([i1, i2, i3], axes=-1)
- with self.assertRaises(ValueError):
- dot = keras.layers.Dot(1)
- dot._compute_output_shape(1)
-
- def test_merge_subtract(self):
- i1 = keras.layers.Input(shape=(4, 5))
- i2 = keras.layers.Input(shape=(4, 5))
- y = keras.layers.subtract([i1, i2])
- self.assertEqual(y.get_shape().as_list(), [None, 4, 5])
-
- # Test invalid use cases
- i1 = keras.layers.Input(shape=(4, 5))
- i2 = keras.layers.Input(shape=(3, 5))
- with self.assertRaises(ValueError):
- keras.layers.subtract([i1, i2])
- with self.assertRaises(ValueError):
- keras.layers.subtract([i1, i1, i1])
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/layers/noise.py b/tensorflow/contrib/keras/python/keras/layers/noise.py
deleted file mode 100644
index e3cfa1f711..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/noise.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Layers for regularization models via the addition of noise.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.engine import Layer
-
-
-class GaussianNoise(Layer):
- """Apply additive zero-centered Gaussian noise.
-
- This is useful to mitigate overfitting
- (you could see it as a form of random data augmentation).
- Gaussian Noise (GS) is a natural choice as corruption process
- for real valued inputs.
-
- As it is a regularization layer, it is only active at training time.
-
- Arguments:
- stddev: float, standard deviation of the noise distribution.
-
- Input shape:
- Arbitrary. Use the keyword argument `input_shape`
- (tuple of integers, does not include the samples axis)
- when using this layer as the first layer in a model.
-
- Output shape:
- Same shape as input.
- """
-
- def __init__(self, stddev, **kwargs):
- super(GaussianNoise, self).__init__(**kwargs)
- self.supports_masking = True
- self.stddev = stddev
-
- def call(self, inputs, training=None):
-
- def noised():
- return inputs + K.random_normal(
- shape=K.shape(inputs), mean=0., stddev=self.stddev)
-
- return K.in_train_phase(noised, inputs, training=training)
-
- def get_config(self):
- config = {'stddev': self.stddev}
- base_config = super(GaussianNoise, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class GaussianDropout(Layer):
- """Apply multiplicative 1-centered Gaussian noise.
-
- As it is a regularization layer, it is only active at training time.
-
- Arguments:
- rate: float, drop probability (as with `Dropout`).
- The multiplicative noise will have
- standard deviation `sqrt(rate / (1 - rate))`.
-
- Input shape:
- Arbitrary. Use the keyword argument `input_shape`
- (tuple of integers, does not include the samples axis)
- when using this layer as the first layer in a model.
-
- Output shape:
- Same shape as input.
-
- References:
- - [Dropout: A Simple Way to Prevent Neural Networks from Overfitting
- Srivastava, Hinton, et al.
- 2014](http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf)
- """
-
- def __init__(self, rate, **kwargs):
- super(GaussianDropout, self).__init__(**kwargs)
- self.supports_masking = True
- self.rate = rate
-
- def call(self, inputs, training=None):
- if 0 < self.rate < 1:
-
- def noised():
- stddev = np.sqrt(self.rate / (1.0 - self.rate))
- return inputs * K.random_normal(
- shape=K.shape(inputs), mean=1.0, stddev=stddev)
-
- return K.in_train_phase(noised, inputs, training=training)
- return inputs
-
- def get_config(self):
- config = {'rate': self.rate}
- base_config = super(GaussianDropout, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class AlphaDropout(Layer):
- """Applies Alpha Dropout to the input.
-
- Alpha Dropout is a `Dropout` that keeps mean and variance of inputs
- to their original values, in order to ensure the self-normalizing property
- even after this dropout.
- Alpha Dropout fits well to Scaled Exponential Linear Units
- by randomly setting activations to the negative saturation value.
-
- Arguments:
- rate: float, drop probability (as with `Dropout`).
- The multiplicative noise will have
- standard deviation `sqrt(rate / (1 - rate))`.
- seed: A Python integer to use as random seed.
-
- Input shape:
- Arbitrary. Use the keyword argument `input_shape`
- (tuple of integers, does not include the samples axis)
- when using this layer as the first layer in a model.
-
- Output shape:
- Same shape as input.
-
- References:
- - [Self-Normalizing Neural Networks](https://arxiv.org/abs/1706.02515)
- """
-
- def __init__(self, rate, noise_shape=None, seed=None, **kwargs):
- super(AlphaDropout, self).__init__(**kwargs)
- self.rate = rate
- self.noise_shape = noise_shape
- self.seed = seed
- self.supports_masking = True
-
- def _get_noise_shape(self, inputs):
- return self.noise_shape if self.noise_shape else K.shape(inputs)
-
- def call(self, inputs, training=None):
- if 0. < self.rate < 1.:
- noise_shape = self._get_noise_shape(inputs)
- alpha = 1.6732632423543772848170429916717
- scale = 1.0507009873554804934193349852946
-
- def dropped_inputs(inputs=inputs, rate=self.rate, seed=self.seed):
- alpha_p = -alpha * scale
- kept_idx = K.greater_equal(K.random_uniform(noise_shape, seed=seed),
- rate)
- kept_idx = K.cast(kept_idx, K.floatx())
- a = ((1 - rate) * (1 + rate * alpha_p ** 2)) ** -0.5
- b = -a * alpha_p * rate
- x = inputs * kept_idx + alpha_p * (1 - kept_idx)
- return a * x + b
-
- return K.in_train_phase(dropped_inputs, inputs, training=training)
- return inputs
-
- def get_config(self):
- config = {'rate': self.rate}
- base_config = super(AlphaDropout, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
diff --git a/tensorflow/contrib/keras/python/keras/layers/noise_test.py b/tensorflow/contrib/keras/python/keras/layers/noise_test.py
deleted file mode 100644
index 8fb1339c2e..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/noise_test.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for noise layers."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-
-
-class NoiseLayersTest(test.TestCase):
-
- def test_GaussianNoise(self):
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.GaussianNoise,
- kwargs={'stddev': 1.},
- input_shape=(3, 2, 3))
-
- def test_GaussianDropout(self):
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.GaussianDropout,
- kwargs={'rate': 0.5},
- input_shape=(3, 2, 3))
-
- def test_AlphaDropout(self):
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.AlphaDropout,
- kwargs={'rate': 0.2},
- input_shape=(3, 2, 3))
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/layers/normalization.py b/tensorflow/contrib/keras/python/keras/layers/normalization.py
deleted file mode 100644
index 7b98fe9e85..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/normalization.py
+++ /dev/null
@@ -1,134 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Normalization layers.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras import constraints
-from tensorflow.contrib.keras.python.keras import initializers
-from tensorflow.contrib.keras.python.keras import regularizers
-from tensorflow.contrib.keras.python.keras.engine import Layer
-from tensorflow.python.layers import normalization as tf_normalization_layers
-
-
-class BatchNormalization(tf_normalization_layers.BatchNormalization, Layer):
- """Batch normalization layer (Ioffe and Szegedy, 2014).
-
- Normalize the activations of the previous layer at each batch,
- i.e. applies a transformation that maintains the mean activation
- close to 0 and the activation standard deviation close to 1.
-
- Arguments:
- axis: Integer, the axis that should be normalized
- (typically the features axis).
- For instance, after a `Conv2D` layer with
- `data_format="channels_first"`,
- set `axis=1` in `BatchNormalization`.
- momentum: Momentum for the moving average.
- epsilon: Small float added to variance to avoid dividing by zero.
- center: If True, add offset of `beta` to normalized tensor.
- If False, `beta` is ignored.
- scale: If True, multiply by `gamma`.
- If False, `gamma` is not used.
- When the next layer is linear (also e.g. `nn.relu`),
- this can be disabled since the scaling
- will be done by the next layer.
- beta_initializer: Initializer for the beta weight.
- gamma_initializer: Initializer for the gamma weight.
- moving_mean_initializer: Initializer for the moving mean.
- moving_variance_initializer: Initializer for the moving variance.
- beta_regularizer: Optional regularizer for the beta weight.
- gamma_regularizer: Optional regularizer for the gamma weight.
- beta_constraint: Optional constraint for the beta weight.
- gamma_constraint: Optional constraint for the gamma weight.
-
- Input shape:
- Arbitrary. Use the keyword argument `input_shape`
- (tuple of integers, does not include the samples axis)
- when using this layer as the first layer in a model.
-
- Output shape:
- Same shape as input.
-
- References:
- - [Batch Normalization: Accelerating Deep Network Training by Reducing
- Internal Covariate Shift](https://arxiv.org/abs/1502.03167)
- """
-
- def __init__(self,
- axis=-1,
- momentum=0.99,
- epsilon=1e-3,
- center=True,
- scale=True,
- beta_initializer='zeros',
- gamma_initializer='ones',
- moving_mean_initializer='zeros',
- moving_variance_initializer='ones',
- beta_regularizer=None,
- gamma_regularizer=None,
- beta_constraint=None,
- gamma_constraint=None,
- **kwargs):
- self.supports_masking = True
- super(BatchNormalization, self).__init__(
- axis=axis,
- momentum=momentum,
- epsilon=epsilon,
- center=center,
- scale=scale,
- beta_initializer=initializers.get(beta_initializer),
- gamma_initializer=initializers.get(gamma_initializer),
- moving_mean_initializer=initializers.get(moving_mean_initializer),
- moving_variance_initializer=initializers.get(
- moving_variance_initializer),
- beta_regularizer=regularizers.get(beta_regularizer),
- gamma_regularizer=regularizers.get(gamma_regularizer),
- beta_constraint=constraints.get(beta_constraint),
- gamma_constraint=constraints.get(gamma_constraint),
- **kwargs
- )
-
- def call(self, inputs, training=None):
- if training is None:
- training = K.learning_phase()
- output = super(BatchNormalization, self).call(inputs, training=training)
- if training is K.learning_phase():
- output._uses_learning_phase = True # pylint: disable=protected-access
- return output
-
- def get_config(self):
- config = {
- 'axis': self.axis,
- 'momentum': self.momentum,
- 'epsilon': self.epsilon,
- 'center': self.center,
- 'scale': self.scale,
- 'beta_initializer': initializers.serialize(self.beta_initializer),
- 'gamma_initializer': initializers.serialize(self.gamma_initializer),
- 'moving_mean_initializer':
- initializers.serialize(self.moving_mean_initializer),
- 'moving_variance_initializer':
- initializers.serialize(self.moving_variance_initializer),
- 'beta_regularizer': regularizers.serialize(self.beta_regularizer),
- 'gamma_regularizer': regularizers.serialize(self.gamma_regularizer),
- 'beta_constraint': constraints.serialize(self.beta_constraint),
- 'gamma_constraint': constraints.serialize(self.gamma_constraint)
- }
- base_config = super(BatchNormalization, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
diff --git a/tensorflow/contrib/keras/python/keras/layers/normalization_test.py b/tensorflow/contrib/keras/python/keras/layers/normalization_test.py
deleted file mode 100644
index eaeafb0c62..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/normalization_test.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for normalization layers."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-
-
-class NormalizationLayersTest(test.TestCase):
-
- def test_basic_batchnorm(self):
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.BatchNormalization,
- kwargs={
- 'momentum': 0.9,
- 'epsilon': 0.1,
- 'gamma_regularizer': keras.regularizers.l2(0.01),
- 'beta_regularizer': keras.regularizers.l2(0.01)
- },
- input_shape=(3, 4, 2))
- testing_utils.layer_test(
- keras.layers.BatchNormalization,
- kwargs={
- 'gamma_initializer': 'ones',
- 'beta_initializer': 'ones',
- 'moving_mean_initializer': 'zeros',
- 'moving_variance_initializer': 'ones'
- },
- input_shape=(3, 4, 2))
- testing_utils.layer_test(
- keras.layers.BatchNormalization,
- kwargs={'scale': False,
- 'center': False},
- input_shape=(3, 3))
-
- def test_batchnorm_weights(self):
- with self.test_session():
- layer = keras.layers.BatchNormalization(scale=False, center=False)
- layer.build((None, 3, 4))
- self.assertEqual(len(layer.trainable_weights), 0)
- self.assertEqual(len(layer.weights), 2)
-
- layer = keras.layers.BatchNormalization()
- layer.build((None, 3, 4))
- self.assertEqual(len(layer.trainable_weights), 2)
- self.assertEqual(len(layer.weights), 4)
-
- def test_batchnorm_regularization(self):
- with self.test_session():
- layer = keras.layers.BatchNormalization(
- gamma_regularizer='l1', beta_regularizer='l1')
- layer.build((None, 3, 4))
- self.assertEqual(len(layer.losses), 2)
- max_norm = keras.constraints.max_norm
- layer = keras.layers.BatchNormalization(
- gamma_constraint=max_norm, beta_constraint=max_norm)
- layer.build((None, 3, 4))
- self.assertEqual(layer.gamma.constraint, max_norm)
- self.assertEqual(layer.beta.constraint, max_norm)
-
- def test_batchnorm_correctness(self):
- with self.test_session():
- model = keras.models.Sequential()
- norm = keras.layers.BatchNormalization(input_shape=(10,), momentum=0.8)
- model.add(norm)
- model.compile(loss='mse', optimizer='sgd')
-
- # centered on 5.0, variance 10.0
- x = np.random.normal(loc=5.0, scale=10.0, size=(1000, 10))
- model.fit(x, x, epochs=4, verbose=0)
- out = model.predict(x)
- out -= keras.backend.eval(norm.beta)
- out /= keras.backend.eval(norm.gamma)
-
- np.testing.assert_allclose(out.mean(), 0.0, atol=1e-1)
- np.testing.assert_allclose(out.std(), 1.0, atol=1e-1)
-
- def test_batchnorm_convnet(self):
- if test.is_gpu_available(cuda_only=True):
- with self.test_session(use_gpu=True):
- model = keras.models.Sequential()
- norm = keras.layers.BatchNormalization(
- axis=1, input_shape=(3, 4, 4), momentum=0.8)
- model.add(norm)
- model.compile(loss='mse', optimizer='sgd')
-
- # centered on 5.0, variance 10.0
- x = np.random.normal(loc=5.0, scale=10.0, size=(1000, 3, 4, 4))
- model.fit(x, x, epochs=4, verbose=0)
- out = model.predict(x)
- out -= np.reshape(keras.backend.eval(norm.beta), (1, 3, 1, 1))
- out /= np.reshape(keras.backend.eval(norm.gamma), (1, 3, 1, 1))
-
- np.testing.assert_allclose(np.mean(out, axis=(0, 2, 3)), 0.0, atol=1e-1)
- np.testing.assert_allclose(np.std(out, axis=(0, 2, 3)), 1.0, atol=1e-1)
-
- def test_shared_batchnorm(self):
- """Test that a BN layer can be shared across different data streams.
- """
- with self.test_session():
- # Test single layer reuse
- bn = keras.layers.BatchNormalization()
- x1 = keras.layers.Input(shape=(10,))
- _ = bn(x1)
-
- x2 = keras.layers.Input(shape=(10,))
- y2 = bn(x2)
-
- x = np.random.normal(loc=5.0, scale=10.0, size=(2, 10))
- model = keras.models.Model(x2, y2)
-
- model.compile('sgd', 'mse')
- model.train_on_batch(x, x)
-
- assert len(model.updates) == 2
-
- # Test model-level reuse
- x3 = keras.layers.Input(shape=(10,))
- y3 = model(x3)
- new_model = keras.models.Model(x3, y3)
- assert len(model.updates) == 2
- new_model.compile('sgd', 'mse')
- new_model.train_on_batch(x, x)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/layers/pooling.py b/tensorflow/contrib/keras/python/keras/layers/pooling.py
deleted file mode 100644
index 704f05e494..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/pooling.py
+++ /dev/null
@@ -1,595 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Pooling layers.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.engine import InputSpec
-from tensorflow.contrib.keras.python.keras.engine import Layer
-from tensorflow.contrib.keras.python.keras.utils import conv_utils
-from tensorflow.python.framework import tensor_shape
-from tensorflow.python.layers import pooling as tf_pooling_layers
-
-
-class MaxPooling1D(tf_pooling_layers.MaxPooling1D, Layer):
- """Max pooling operation for temporal data.
-
- Arguments:
- pool_size: Integer, size of the max pooling windows.
- strides: Integer, or None. Factor by which to downscale.
- E.g. 2 will halve the input.
- If None, it will default to `pool_size`.
- padding: One of `"valid"` or `"same"` (case-insensitive).
-
- Input shape:
- 3D tensor with shape: `(batch_size, steps, features)`.
-
- Output shape:
- 3D tensor with shape: `(batch_size, downsampled_steps, features)`.
- """
-
- def __init__(self, pool_size=2, strides=None, padding='valid', **kwargs):
- if strides is None:
- strides = pool_size
- super(MaxPooling1D, self).__init__(pool_size, strides, padding, **kwargs)
-
- def get_config(self):
- config = {
- 'strides': self.strides,
- 'pool_size': self.pool_size,
- 'padding': self.padding
- }
- base_config = super(MaxPooling1D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class AveragePooling1D(tf_pooling_layers.AveragePooling1D, Layer):
- """Average pooling for temporal data.
-
- Arguments:
- pool_size: Integer, size of the max pooling windows.
- strides: Integer, or None. Factor by which to downscale.
- E.g. 2 will halve the input.
- If None, it will default to `pool_size`.
- padding: One of `"valid"` or `"same"` (case-insensitive).
-
- Input shape:
- 3D tensor with shape: `(batch_size, steps, features)`.
-
- Output shape:
- 3D tensor with shape: `(batch_size, downsampled_steps, features)`.
- """
-
- def __init__(self, pool_size=2, strides=None, padding='valid', **kwargs):
- if strides is None:
- strides = pool_size
- super(AveragePooling1D, self).__init__(pool_size, strides, padding,
- **kwargs)
-
- def get_config(self):
- config = {
- 'strides': self.strides,
- 'pool_size': self.pool_size,
- 'padding': self.padding
- }
- base_config = super(AveragePooling1D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class MaxPooling2D(tf_pooling_layers.MaxPooling2D, Layer):
- """Max pooling operation for spatial data.
-
- Arguments:
- pool_size: integer or tuple of 2 integers,
- factors by which to downscale (vertical, horizontal).
- (2, 2) will halve the input in both spatial dimension.
- If only one integer is specified, the same window length
- will be used for both dimensions.
- strides: Integer, tuple of 2 integers, or None.
- Strides values.
- If None, it will default to `pool_size`.
- padding: One of `"valid"` or `"same"` (case-insensitive).
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, height, width, channels)` while `channels_first`
- corresponds to inputs with shape
- `(batch, channels, height, width)`.
- 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 "channels_last".
-
- Input shape:
- - If `data_format='channels_last'`:
- 4D tensor with shape:
- `(batch_size, rows, cols, channels)`
- - If `data_format='channels_first'`:
- 4D tensor with shape:
- `(batch_size, channels, rows, cols)`
-
- Output shape:
- - If `data_format='channels_last'`:
- 4D tensor with shape:
- `(batch_size, pooled_rows, pooled_cols, channels)`
- - If `data_format='channels_first'`:
- 4D tensor with shape:
- `(batch_size, channels, pooled_rows, pooled_cols)`
- """
-
- def __init__(self,
- pool_size=(2, 2),
- strides=None,
- padding='valid',
- data_format=None,
- **kwargs):
- if data_format is None:
- data_format = K.image_data_format()
- if strides is None:
- strides = pool_size
- super(MaxPooling2D, self).__init__(pool_size, strides, padding, data_format,
- **kwargs)
-
- def get_config(self):
- config = {
- 'pool_size': self.pool_size,
- 'padding': self.padding,
- 'strides': self.strides,
- 'data_format': self.data_format
- }
- base_config = super(MaxPooling2D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class AveragePooling2D(tf_pooling_layers.AveragePooling2D, Layer):
- """Average pooling operation for spatial data.
-
- Arguments:
- pool_size: integer or tuple of 2 integers,
- factors by which to downscale (vertical, horizontal).
- (2, 2) will halve the input in both spatial dimension.
- If only one integer is specified, the same window length
- will be used for both dimensions.
- strides: Integer, tuple of 2 integers, or None.
- Strides values.
- If None, it will default to `pool_size`.
- padding: One of `"valid"` or `"same"` (case-insensitive).
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, height, width, channels)` while `channels_first`
- corresponds to inputs with shape
- `(batch, channels, height, width)`.
- 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 "channels_last".
-
- Input shape:
- - If `data_format='channels_last'`:
- 4D tensor with shape:
- `(batch_size, rows, cols, channels)`
- - If `data_format='channels_first'`:
- 4D tensor with shape:
- `(batch_size, channels, rows, cols)`
-
- Output shape:
- - If `data_format='channels_last'`:
- 4D tensor with shape:
- `(batch_size, pooled_rows, pooled_cols, channels)`
- - If `data_format='channels_first'`:
- 4D tensor with shape:
- `(batch_size, channels, pooled_rows, pooled_cols)`
- """
-
- def __init__(self,
- pool_size=(2, 2),
- strides=None,
- padding='valid',
- data_format=None,
- **kwargs):
- if data_format is None:
- data_format = K.image_data_format()
- if strides is None:
- strides = pool_size
- super(AveragePooling2D, self).__init__(pool_size, strides, padding,
- data_format, **kwargs)
-
- def get_config(self):
- config = {
- 'pool_size': self.pool_size,
- 'padding': self.padding,
- 'strides': self.strides,
- 'data_format': self.data_format
- }
- base_config = super(AveragePooling2D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class MaxPooling3D(tf_pooling_layers.MaxPooling3D, Layer):
- """Max pooling operation for 3D data (spatial or spatio-temporal).
-
- Arguments:
- pool_size: tuple of 3 integers,
- factors by which to downscale (dim1, dim2, dim3).
- (2, 2, 2) will halve the size of the 3D input in each dimension.
- strides: tuple of 3 integers, or None. Strides values.
- padding: One of `"valid"` or `"same"` (case-insensitive).
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
- while `channels_first` corresponds to inputs with shape
- `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
- 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 "channels_last".
-
- Input shape:
- - If `data_format='channels_last'`:
- 5D tensor with shape:
- `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
- - If `data_format='channels_first'`:
- 5D tensor with shape:
- `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`
-
- Output shape:
- - If `data_format='channels_last'`:
- 5D tensor with shape:
- `(batch_size, pooled_dim1, pooled_dim2, pooled_dim3, channels)`
- - If `data_format='channels_first'`:
- 5D tensor with shape:
- `(batch_size, channels, pooled_dim1, pooled_dim2, pooled_dim3)`
- """
-
- def __init__(self,
- pool_size=(2, 2, 2),
- strides=None,
- padding='valid',
- data_format=None,
- **kwargs):
- if data_format is None:
- data_format = K.image_data_format()
- if strides is None:
- strides = pool_size
- super(MaxPooling3D, self).__init__(pool_size, strides, padding, data_format,
- **kwargs)
-
- def get_config(self):
- config = {
- 'pool_size': self.pool_size,
- 'padding': self.padding,
- 'strides': self.strides,
- 'data_format': self.data_format
- }
- base_config = super(MaxPooling3D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class AveragePooling3D(tf_pooling_layers.AveragePooling3D, Layer):
- """Average pooling operation for 3D data (spatial or spatio-temporal).
-
- Arguments:
- pool_size: tuple of 3 integers,
- factors by which to downscale (dim1, dim2, dim3).
- (2, 2, 2) will halve the size of the 3D input in each dimension.
- strides: tuple of 3 integers, or None. Strides values.
- padding: One of `"valid"` or `"same"` (case-insensitive).
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
- while `channels_first` corresponds to inputs with shape
- `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
- 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 "channels_last".
-
- Input shape:
- - If `data_format='channels_last'`:
- 5D tensor with shape:
- `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
- - If `data_format='channels_first'`:
- 5D tensor with shape:
- `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`
-
- Output shape:
- - If `data_format='channels_last'`:
- 5D tensor with shape:
- `(batch_size, pooled_dim1, pooled_dim2, pooled_dim3, channels)`
- - If `data_format='channels_first'`:
- 5D tensor with shape:
- `(batch_size, channels, pooled_dim1, pooled_dim2, pooled_dim3)`
- """
-
- def __init__(self,
- pool_size=(2, 2, 2),
- strides=None,
- padding='valid',
- data_format=None,
- **kwargs):
- if data_format is None:
- data_format = K.image_data_format()
- if strides is None:
- strides = pool_size
- super(AveragePooling3D, self).__init__(pool_size, strides, padding,
- data_format, **kwargs)
-
- def get_config(self):
- config = {
- 'pool_size': self.pool_size,
- 'padding': self.padding,
- 'strides': self.strides,
- 'data_format': self.data_format
- }
- base_config = super(AveragePooling3D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class _GlobalPooling1D(Layer):
- """Abstract class for different global pooling 1D layers.
- """
-
- def __init__(self, **kwargs):
- super(_GlobalPooling1D, self).__init__(**kwargs)
- self.input_spec = InputSpec(ndim=3)
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- return tensor_shape.TensorShape([input_shape[0], input_shape[2]])
-
- def call(self, inputs):
- raise NotImplementedError
-
-
-class GlobalAveragePooling1D(_GlobalPooling1D):
- """Global average pooling operation for temporal data.
-
- Input shape:
- 3D tensor with shape: `(batch_size, steps, features)`.
-
- Output shape:
- 2D tensor with shape:
- `(batch_size, channels)`
- """
-
- def call(self, inputs):
- return K.mean(inputs, axis=1)
-
-
-class GlobalMaxPooling1D(_GlobalPooling1D):
- """Global max pooling operation for temporal data.
-
- Input shape:
- 3D tensor with shape: `(batch_size, steps, features)`.
-
- Output shape:
- 2D tensor with shape:
- `(batch_size, channels)`
- """
-
- def call(self, inputs):
- return K.max(inputs, axis=1)
-
-
-class _GlobalPooling2D(Layer):
- """Abstract class for different global pooling 2D layers.
- """
-
- def __init__(self, data_format=None, **kwargs):
- super(_GlobalPooling2D, self).__init__(**kwargs)
- self.data_format = conv_utils.normalize_data_format(data_format)
- self.input_spec = InputSpec(ndim=4)
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- if self.data_format == 'channels_last':
- return tensor_shape.TensorShape([input_shape[0], input_shape[3]])
- else:
- return tensor_shape.TensorShape([input_shape[0], input_shape[1]])
-
- def call(self, inputs):
- raise NotImplementedError
-
- def get_config(self):
- config = {'data_format': self.data_format}
- base_config = super(_GlobalPooling2D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class GlobalAveragePooling2D(_GlobalPooling2D):
- """Global average pooling operation for spatial data.
-
- Arguments:
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, height, width, channels)` while `channels_first`
- corresponds to inputs with shape
- `(batch, channels, height, width)`.
- 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 "channels_last".
-
- Input shape:
- - If `data_format='channels_last'`:
- 4D tensor with shape:
- `(batch_size, rows, cols, channels)`
- - If `data_format='channels_first'`:
- 4D tensor with shape:
- `(batch_size, channels, rows, cols)`
-
- Output shape:
- 2D tensor with shape:
- `(batch_size, channels)`
- """
-
- def call(self, inputs):
- if self.data_format == 'channels_last':
- return K.mean(inputs, axis=[1, 2])
- else:
- return K.mean(inputs, axis=[2, 3])
-
-
-class GlobalMaxPooling2D(_GlobalPooling2D):
- """Global max pooling operation for spatial data.
-
- Arguments:
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, height, width, channels)` while `channels_first`
- corresponds to inputs with shape
- `(batch, channels, height, width)`.
- 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 "channels_last".
-
- Input shape:
- - If `data_format='channels_last'`:
- 4D tensor with shape:
- `(batch_size, rows, cols, channels)`
- - If `data_format='channels_first'`:
- 4D tensor with shape:
- `(batch_size, channels, rows, cols)`
-
- Output shape:
- 2D tensor with shape:
- `(batch_size, channels)`
- """
-
- def call(self, inputs):
- if self.data_format == 'channels_last':
- return K.max(inputs, axis=[1, 2])
- else:
- return K.max(inputs, axis=[2, 3])
-
-
-class _GlobalPooling3D(Layer):
- """Abstract class for different global pooling 3D layers.
- """
-
- def __init__(self, data_format=None, **kwargs):
- super(_GlobalPooling3D, self).__init__(**kwargs)
- self.data_format = conv_utils.normalize_data_format(data_format)
- self.input_spec = InputSpec(ndim=5)
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- if self.data_format == 'channels_last':
- return tensor_shape.TensorShape([input_shape[0], input_shape[4]])
- else:
- return tensor_shape.TensorShape([input_shape[0], input_shape[1]])
-
- def call(self, inputs):
- raise NotImplementedError
-
- def get_config(self):
- config = {'data_format': self.data_format}
- base_config = super(_GlobalPooling3D, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class GlobalAveragePooling3D(_GlobalPooling3D):
- """Global Average pooling operation for 3D data.
-
- Arguments:
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
- while `channels_first` corresponds to inputs with shape
- `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
- 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 "channels_last".
-
- Input shape:
- - If `data_format='channels_last'`:
- 5D tensor with shape:
- `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
- - If `data_format='channels_first'`:
- 5D tensor with shape:
- `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`
-
- Output shape:
- 2D tensor with shape:
- `(batch_size, channels)`
- """
-
- def call(self, inputs):
- if self.data_format == 'channels_last':
- return K.mean(inputs, axis=[1, 2, 3])
- else:
- return K.mean(inputs, axis=[2, 3, 4])
-
-
-class GlobalMaxPooling3D(_GlobalPooling3D):
- """Global Max pooling operation for 3D data.
-
- Arguments:
- data_format: A string,
- one of `channels_last` (default) or `channels_first`.
- The ordering of the dimensions in the inputs.
- `channels_last` corresponds to inputs with shape
- `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
- while `channels_first` corresponds to inputs with shape
- `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
- 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 "channels_last".
-
- Input shape:
- - If `data_format='channels_last'`:
- 5D tensor with shape:
- `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
- - If `data_format='channels_first'`:
- 5D tensor with shape:
- `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`
-
- Output shape:
- 2D tensor with shape:
- `(batch_size, channels)`
- """
-
- def call(self, inputs):
- if self.data_format == 'channels_last':
- return K.max(inputs, axis=[1, 2, 3])
- else:
- return K.max(inputs, axis=[2, 3, 4])
-
-
-# Aliases
-
-AvgPool1D = AveragePooling1D
-MaxPool1D = MaxPooling1D
-AvgPool2D = AveragePooling2D
-MaxPool2D = MaxPooling2D
-AvgPool3D = AveragePooling3D
-MaxPool3D = MaxPooling3D
-GlobalMaxPool1D = GlobalMaxPooling1D
-GlobalMaxPool2D = GlobalMaxPooling2D
-GlobalMaxPool3D = GlobalMaxPooling3D
-GlobalAvgPool1D = GlobalAveragePooling1D
-GlobalAvgPool2D = GlobalAveragePooling2D
-GlobalAvgPool3D = GlobalAveragePooling3D
diff --git a/tensorflow/contrib/keras/python/keras/layers/pooling_test.py b/tensorflow/contrib/keras/python/keras/layers/pooling_test.py
deleted file mode 100644
index d8a6a1673b..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/pooling_test.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for pooling layers."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-
-
-class GlobalPoolingTest(test.TestCase):
-
- def test_globalpooling_1d(self):
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(keras.layers.pooling.GlobalMaxPooling1D,
- input_shape=(3, 4, 5))
- testing_utils.layer_test(
- keras.layers.pooling.GlobalAveragePooling1D, input_shape=(3, 4, 5))
-
- def test_globalpooling_2d(self):
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.pooling.GlobalMaxPooling2D,
- kwargs={'data_format': 'channels_first'},
- input_shape=(3, 4, 5, 6))
- testing_utils.layer_test(
- keras.layers.pooling.GlobalMaxPooling2D,
- kwargs={'data_format': 'channels_last'},
- input_shape=(3, 5, 6, 4))
- testing_utils.layer_test(
- keras.layers.pooling.GlobalAveragePooling2D,
- kwargs={'data_format': 'channels_first'},
- input_shape=(3, 4, 5, 6))
- testing_utils.layer_test(
- keras.layers.pooling.GlobalAveragePooling2D,
- kwargs={'data_format': 'channels_last'},
- input_shape=(3, 5, 6, 4))
-
- def test_globalpooling_3d(self):
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.pooling.GlobalMaxPooling3D,
- kwargs={'data_format': 'channels_first'},
- input_shape=(3, 4, 3, 4, 3))
- testing_utils.layer_test(
- keras.layers.pooling.GlobalMaxPooling3D,
- kwargs={'data_format': 'channels_last'},
- input_shape=(3, 4, 3, 4, 3))
- testing_utils.layer_test(
- keras.layers.pooling.GlobalAveragePooling3D,
- kwargs={'data_format': 'channels_first'},
- input_shape=(3, 4, 3, 4, 3))
- testing_utils.layer_test(
- keras.layers.pooling.GlobalAveragePooling3D,
- kwargs={'data_format': 'channels_last'},
- input_shape=(3, 4, 3, 4, 3))
-
-
-class Pooling2DTest(test.TestCase):
-
- def test_maxpooling_2d(self):
- pool_size = (3, 3)
- with self.test_session(use_gpu=True):
- for strides in [(1, 1), (2, 2)]:
- testing_utils.layer_test(
- keras.layers.MaxPooling2D,
- kwargs={
- 'strides': strides,
- 'padding': 'valid',
- 'pool_size': pool_size
- },
- input_shape=(3, 5, 6, 4))
-
- def test_averagepooling_2d(self):
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.AveragePooling2D,
- kwargs={'strides': (2, 2),
- 'padding': 'same',
- 'pool_size': (2, 2)},
- input_shape=(3, 5, 6, 4))
- testing_utils.layer_test(
- keras.layers.AveragePooling2D,
- kwargs={'strides': (2, 2),
- 'padding': 'valid',
- 'pool_size': (3, 3)},
- input_shape=(3, 5, 6, 4))
- # Only runs on GPU with CUDA, channels_first is not supported on CPU.
- # TODO(b/62340061): Support channels_first on CPU.
- if test.is_gpu_available(cuda_only=True):
- testing_utils.layer_test(
- keras.layers.AveragePooling2D,
- kwargs={
- 'strides': (1, 1),
- 'padding': 'valid',
- 'pool_size': (2, 2),
- 'data_format': 'channels_first'
- },
- input_shape=(3, 4, 5, 6))
-
-
-class Pooling3DTest(test.TestCase):
-
- def test_maxpooling_3d(self):
- pool_size = (3, 3, 3)
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.MaxPooling3D,
- kwargs={'strides': 2,
- 'padding': 'valid',
- 'pool_size': pool_size},
- input_shape=(3, 11, 12, 10, 4))
- testing_utils.layer_test(
- keras.layers.MaxPooling3D,
- kwargs={
- 'strides': 3,
- 'padding': 'valid',
- 'data_format': 'channels_first',
- 'pool_size': pool_size
- },
- input_shape=(3, 4, 11, 12, 10))
-
- def test_averagepooling_3d(self):
- pool_size = (3, 3, 3)
- with self.test_session(use_gpu=True):
- testing_utils.layer_test(
- keras.layers.AveragePooling3D,
- kwargs={'strides': 2,
- 'padding': 'valid',
- 'pool_size': pool_size},
- input_shape=(3, 11, 12, 10, 4))
- testing_utils.layer_test(
- keras.layers.AveragePooling3D,
- kwargs={
- 'strides': 3,
- 'padding': 'valid',
- 'data_format': 'channels_first',
- 'pool_size': pool_size
- },
- input_shape=(3, 4, 11, 12, 10))
-
-
-class Pooling1DTest(test.TestCase):
-
- def test_maxpooling_1d(self):
- with self.test_session(use_gpu=True):
- for padding in ['valid', 'same']:
- for stride in [1, 2]:
- testing_utils.layer_test(
- keras.layers.MaxPooling1D,
- kwargs={'strides': stride,
- 'padding': padding},
- input_shape=(3, 5, 4))
-
- def test_averagepooling_1d(self):
- with self.test_session(use_gpu=True):
- for padding in ['valid', 'same']:
- for stride in [1, 2]:
- testing_utils.layer_test(
- keras.layers.AveragePooling1D,
- kwargs={'strides': stride,
- 'padding': padding},
- input_shape=(3, 5, 4))
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/layers/recurrent.py b/tensorflow/contrib/keras/python/keras/layers/recurrent.py
deleted file mode 100644
index 988ddf54cc..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/recurrent.py
+++ /dev/null
@@ -1,1270 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-# pylint: disable=protected-access
-"""Recurrent layers.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python.keras import activations
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras import constraints
-from tensorflow.contrib.keras.python.keras import initializers
-from tensorflow.contrib.keras.python.keras import regularizers
-from tensorflow.contrib.keras.python.keras.engine import InputSpec
-from tensorflow.contrib.keras.python.keras.engine import Layer
-from tensorflow.python.framework import tensor_shape
-
-
-# pylint: disable=access-member-before-definition
-
-
-def _time_distributed_dense(x,
- w,
- b=None,
- dropout=None,
- input_dim=None,
- output_dim=None,
- timesteps=None,
- training=None):
- """Apply `y . w + b` for every temporal slice y of x.
-
- Arguments:
- x: input tensor.
- w: weight matrix.
- b: optional bias vector.
- dropout: wether to apply dropout (same dropout mask
- for every temporal slice of the input).
- input_dim: integer; optional dimensionality of the input.
- output_dim: integer; optional dimensionality of the output.
- timesteps: integer; optional number of timesteps.
- training: training phase tensor or boolean.
-
- Returns:
- Output tensor.
- """
- if not input_dim:
- input_dim = K.shape(x)[2]
- if not timesteps:
- timesteps = K.shape(x)[1]
- if not output_dim:
- output_dim = K.shape(w)[1]
-
- if dropout is not None and 0. < dropout < 1.:
- # apply the same dropout pattern at every timestep
- ones = K.ones_like(K.reshape(x[:, 0, :], (-1, input_dim)))
- dropout_matrix = K.dropout(ones, dropout)
- expanded_dropout_matrix = K.repeat(dropout_matrix, timesteps)
- x = K.in_train_phase(x * expanded_dropout_matrix, x, training=training)
-
- # collapse time dimension and batch dimension together
- x = K.reshape(x, (-1, input_dim))
- x = K.dot(x, w)
- if b is not None:
- x = K.bias_add(x, b)
- # reshape to 3D tensor
- if K.backend() == 'tensorflow':
- x = K.reshape(x, K.stack([-1, timesteps, output_dim]))
- x.set_shape([None, None, output_dim])
- else:
- x = K.reshape(x, (-1, timesteps, output_dim))
- return x
-
-
-class Recurrent(Layer):
- """Abstract base class for recurrent layers.
-
- Do not use in a model -- it's not a valid layer!
- Use its children classes `LSTM`, `GRU` and `SimpleRNN` instead.
-
- All recurrent layers (`LSTM`, `GRU`, `SimpleRNN`) also
- follow the specifications of this class and accept
- the keyword arguments listed below.
-
- Example:
-
- ```python
- # as the first layer in a Sequential model
- model = Sequential()
- model.add(LSTM(32, input_shape=(10, 64)))
- # now model.output_shape == (None, 32)
- # note: `None` is the batch dimension.
-
- # for subsequent layers, no need to specify the input size:
- model.add(LSTM(16))
-
- # to stack recurrent layers, you must use return_sequences=True
- # on any recurrent layer that feeds into another recurrent layer.
- # note that you only need to specify the input size on the first layer.
- model = Sequential()
- model.add(LSTM(64, input_dim=64, input_length=10, return_sequences=True))
- model.add(LSTM(32, return_sequences=True))
- model.add(LSTM(10))
- ```
-
- Arguments:
- weights: list of Numpy arrays to set as initial weights.
- The list should have 3 elements, of shapes:
- `[(input_dim, output_dim), (output_dim, output_dim), (output_dim,)]`.
- return_sequences: Boolean. Whether to return the last output
- in the output sequence, or the full sequence.
- return_state: Boolean. Whether to return the last state
- in addition to the output.
- go_backwards: Boolean (default False).
- If True, process the input sequence backwards and return the
- reversed sequence.
- stateful: Boolean (default False). If True, the last state
- for each sample at index i in a batch will be used as initial
- state for the sample of index i in the following batch.
- unroll: Boolean (default False).
- If True, the network will be unrolled,
- else a symbolic loop will be used.
- Unrolling can speed-up a RNN,
- although it tends to be more memory-intensive.
- Unrolling is only suitable for short sequences.
- implementation: one of {0, 1, or 2}.
- If set to 0, the RNN will use
- an implementation that uses fewer, larger matrix products,
- thus running faster on CPU but consuming more memory.
- If set to 1, the RNN will use more matrix products,
- but smaller ones, thus running slower
- (may actually be faster on GPU) while consuming less memory.
- If set to 2 (LSTM/GRU only),
- the RNN will combine the input gate,
- the forget gate and the output gate into a single matrix,
- enabling more time-efficient parallelization on the GPU.
- Note: RNN dropout must be shared for all gates,
- resulting in a slightly reduced regularization.
- input_dim: dimensionality of the input (integer).
- This argument (or alternatively, the keyword argument `input_shape`)
- is required when using this layer as the first layer in a model.
- input_length: Length of input sequences, to be specified
- when it is constant.
- This argument is required if you are going to connect
- `Flatten` then `Dense` layers upstream
- (without it, the shape of the dense outputs cannot be computed).
- Note that if the recurrent layer is not the first layer
- in your model, you would need to specify the input length
- at the level of the first layer
- (e.g. via the `input_shape` argument)
-
- Input shape:s
- 3D tensor with shape `(batch_size, timesteps, input_dim)`,
- (Optional) 2D tensors with shape `(batch_size, output_dim)`.
-
- Output shape:
- - if `return_state`: a list of tensors. The first tensor is
- the output. The remaining tensors are the last states,
- each with shape `(batch_size, units)`.
- - if `return_sequences`: 3D tensor with shape
- `(batch_size, timesteps, units)`.
- - else, 2D tensor with shape `(batch_size, units)`.
-
- # Masking
- This layer supports masking for input data with a variable number
- of timesteps. To introduce masks to your data,
- use an `Embedding` layer with the `mask_zero` parameter
- set to `True`.
-
- # Note on using statefulness in RNNs
- You can set RNN layers to be 'stateful', which means that the states
- computed for the samples in one batch will be reused as initial states
- for the samples in the next batch. This assumes a one-to-one mapping
- between samples in different successive batches.
-
- To enable statefulness:
- - specify `stateful=True` in the layer constructor.
- - specify a fixed batch size for your model, by passing
- if sequential model:
- `batch_input_shape=(...)` to the first layer in your model.
- else for functional model with 1 or more Input layers:
- `batch_shape=(...)` to all the first layers in your model.
- This is the expected shape of your inputs
- *including the batch size*.
- It should be a tuple of integers, e.g. `(32, 10, 100)`.
- - specify `shuffle=False` when calling fit().
-
- To reset the states of your model, call `.reset_states()` on either
- a specific layer, or on your entire model.
-
- # Note on specifying the initial state of RNNs
- You can specify the initial state of RNN layers symbolically by
- calling them with the keyword argument `initial_state`. The value of
- `initial_state` should be a tensor or list of tensors representing
- the initial state of the RNN layer.
-
- You can specify the initial state of RNN layers numerically by
- calling `reset_states` with the keyword argument `states`. The value of
- `states` should be a numpy array or list of numpy arrays representing
- the initial state of the RNN layer.
- """
-
- def __init__(self,
- return_sequences=False,
- return_state=False,
- go_backwards=False,
- stateful=False,
- unroll=False,
- implementation=0,
- **kwargs):
- super(Recurrent, self).__init__(**kwargs)
- self.return_sequences = return_sequences
- self.return_state = return_state
- self.go_backwards = go_backwards
- self.stateful = stateful
- self.unroll = unroll
- self.implementation = implementation
- self.supports_masking = True
- self.input_spec = [InputSpec(ndim=3)]
- self.state_spec = None
- self.dropout = 0
- self.recurrent_dropout = 0
-
- def _compute_output_shape(self, input_shape):
- if isinstance(input_shape, list):
- input_shape = input_shape[0]
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- if self.return_sequences:
- output_shape = (input_shape[0], input_shape[1], self.units)
- else:
- output_shape = (input_shape[0], self.units)
-
- if self.return_state:
- state_shape = [tensor_shape.TensorShape(
- (input_shape[0], self.units)) for _ in self.states]
- return [tensor_shape.TensorShape(output_shape)] + state_shape
- return tensor_shape.TensorShape(output_shape)
-
- def compute_mask(self, inputs, mask):
- if isinstance(mask, list):
- mask = mask[0]
- output_mask = mask if self.return_sequences else None
- if self.return_state:
- state_mask = [None for _ in self.states]
- return [output_mask] + state_mask
- return output_mask
-
- def step(self, inputs, states):
- raise NotImplementedError
-
- def get_constants(self, inputs, training=None):
- return []
-
- def get_initial_state(self, inputs):
- # build an all-zero tensor of shape (samples, output_dim)
- initial_state = K.zeros_like(inputs) # (samples, timesteps, input_dim)
- initial_state = K.sum(initial_state, axis=(1, 2)) # (samples,)
- initial_state = K.expand_dims(initial_state) # (samples, 1)
- initial_state = K.tile(initial_state, [1,
- self.units]) # (samples, output_dim)
- initial_state = [initial_state for _ in range(len(self.states))]
- return initial_state
-
- def preprocess_input(self, inputs, training=None):
- return inputs
-
- def __call__(self, inputs, initial_state=None, **kwargs):
- if (isinstance(inputs, (list, tuple)) and
- len(inputs) > 1
- and initial_state is None):
- initial_state = inputs[1:]
- inputs = inputs[0]
-
- # If `initial_state` is specified,
- # and if it a Keras tensor,
- # then add it to the inputs and temporarily
- # modify the input spec to include the state.
- if initial_state is None:
- return super(Recurrent, self).__call__(inputs, **kwargs)
-
- if not isinstance(initial_state, (list, tuple)):
- initial_state = [initial_state]
-
- is_keras_tensor = hasattr(initial_state[0], '_keras_history')
- for tensor in initial_state:
- if hasattr(tensor, '_keras_history') != is_keras_tensor:
- raise ValueError('The initial state of an RNN layer cannot be'
- ' specified with a mix of Keras tensors and'
- ' non-Keras tensors')
-
- if is_keras_tensor:
- # Compute the full input spec, including state
- input_spec = self.input_spec
- state_spec = self.state_spec
- if not isinstance(input_spec, list):
- input_spec = [input_spec]
- if not isinstance(state_spec, list):
- state_spec = [state_spec]
- self.input_spec = input_spec + state_spec
-
- # Compute the full inputs, including state
- inputs = [inputs] + list(initial_state)
-
- # Perform the call
- output = super(Recurrent, self).__call__(inputs, **kwargs)
-
- # Restore original input spec
- self.input_spec = input_spec
- return output
- else:
- kwargs['initial_state'] = initial_state
- return super(Recurrent, self).__call__(inputs, **kwargs)
-
- def call(self, inputs, mask=None, training=None, initial_state=None):
- # input shape: `(samples, time (padded with zeros), input_dim)`
- # note that the .build() method of subclasses MUST define
- # self.input_spec and self.state_spec with complete input shapes.
- if isinstance(inputs, list):
- initial_state = inputs[1:]
- inputs = inputs[0]
- elif initial_state is not None:
- pass
- elif self.stateful:
- initial_state = self.states
- else:
- initial_state = self.get_initial_state(inputs)
-
- if isinstance(mask, list):
- mask = mask[0]
-
- if len(initial_state) != len(self.states):
- raise ValueError('Layer has ' + str(len(self.states)) +
- ' states but was passed ' + str(len(initial_state)) +
- ' initial states.')
- input_shape = K.int_shape(inputs)
- if self.unroll and input_shape[1] is None:
- raise ValueError('Cannot unroll a RNN if the '
- 'time dimension is undefined. \n'
- '- If using a Sequential model, '
- 'specify the time dimension by passing '
- 'an `input_shape` or `batch_input_shape` '
- 'argument to your first layer. If your '
- 'first layer is an Embedding, you can '
- 'also use the `input_length` argument.\n'
- '- If using the functional API, specify '
- 'the time dimension by passing a `shape` '
- 'or `batch_shape` argument to your Input layer.')
- constants = self.get_constants(inputs, training=None)
- preprocessed_input = self.preprocess_input(inputs, training=None)
- last_output, outputs, states = K.rnn(
- self.step,
- preprocessed_input,
- initial_state,
- go_backwards=self.go_backwards,
- mask=mask,
- constants=constants,
- unroll=self.unroll)
- if self.stateful:
- updates = []
- for i in range(len(states)):
- updates.append((self.states[i], states[i]))
- self.add_update(updates, inputs)
-
- # Properly set learning phase
- if 0 < self.dropout + self.recurrent_dropout:
- last_output._uses_learning_phase = True
- outputs._uses_learning_phase = True
-
- if not self.return_sequences:
- outputs = last_output
-
- if self.return_state:
- if not isinstance(states, (list, tuple)):
- states = [states]
- else:
- states = list(states)
- return [outputs] + states
- return outputs
-
- def reset_states(self, states=None):
- if not self.stateful:
- raise AttributeError('Layer must be stateful.')
- batch_size = self.input_spec[0].shape[0]
- if not batch_size:
- raise ValueError('If a RNN is stateful, it needs to know '
- 'its batch size. Specify the batch size '
- 'of your input tensors: \n'
- '- If using a Sequential model, '
- 'specify the batch size by passing '
- 'a `batch_input_shape` '
- 'argument to your first layer.\n'
- '- If using the functional API, specify '
- 'the time dimension by passing a '
- '`batch_shape` argument to your Input layer.')
- # initialize state if None
- if self.states[0] is None:
- self.states = [K.zeros((batch_size, self.units)) for _ in self.states]
- elif states is None:
- for state in self.states:
- K.set_value(state, np.zeros((batch_size, self.units)))
- else:
- if not isinstance(states, (list, tuple)):
- states = [states]
- if len(states) != len(self.states):
- raise ValueError('Layer ' + self.name + ' expects ' +
- str(len(self.states)) + ' states, '
- 'but it received ' + str(len(states)) +
- ' state values. Input received: ' + str(states))
- for index, (value, state) in enumerate(zip(states, self.states)):
- if value.shape != (batch_size, self.units):
- raise ValueError('State ' + str(index) +
- ' is incompatible with layer ' + self.name +
- ': expected shape=' + str((batch_size, self.units)) +
- ', found shape=' + str(value.shape))
- K.set_value(state, value)
-
- def get_config(self):
- config = {
- 'return_sequences': self.return_sequences,
- 'return_state': self.return_state,
- 'go_backwards': self.go_backwards,
- 'stateful': self.stateful,
- 'unroll': self.unroll,
- 'implementation': self.implementation
- }
- base_config = super(Recurrent, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class SimpleRNN(Recurrent):
- """Fully-connected RNN where the output is to be fed back to input.
-
- Arguments:
- units: Positive integer, dimensionality of the output space.
- activation: Activation function to use.
- If you don't specify anything, no activation is applied
- If you pass None, no activation is applied
- (ie. "linear" activation: `a(x) = x`).
- use_bias: Boolean, whether the layer uses a bias vector.
- kernel_initializer: Initializer for the `kernel` weights matrix,
- used for the linear transformation of the inputs..
- recurrent_initializer: Initializer for the `recurrent_kernel`
- weights matrix,
- used for the linear transformation of the recurrent state..
- bias_initializer: Initializer for the bias vector.
- kernel_regularizer: Regularizer function applied to
- the `kernel` weights matrix.
- recurrent_regularizer: Regularizer function applied to
- the `recurrent_kernel` weights matrix.
- bias_regularizer: Regularizer function applied to the bias vector.
- activity_regularizer: Regularizer function applied to
- the output of the layer (its "activation")..
- kernel_constraint: Constraint function applied to
- the `kernel` weights matrix.
- recurrent_constraint: Constraint function applied to
- the `recurrent_kernel` weights matrix.
- bias_constraint: Constraint function applied to the bias vector.
- dropout: Float between 0 and 1.
- Fraction of the units to drop for
- the linear transformation of the inputs.
- recurrent_dropout: Float between 0 and 1.
- Fraction of the units to drop for
- the linear transformation of the recurrent state.
-
- References:
- - [A Theoretically Grounded Application of Dropout in Recurrent Neural
- Networks](http://arxiv.org/abs/1512.05287)
- """
-
- def __init__(self,
- units,
- activation='tanh',
- use_bias=True,
- kernel_initializer='glorot_uniform',
- recurrent_initializer='orthogonal',
- bias_initializer='zeros',
- kernel_regularizer=None,
- recurrent_regularizer=None,
- bias_regularizer=None,
- activity_regularizer=None,
- kernel_constraint=None,
- recurrent_constraint=None,
- bias_constraint=None,
- dropout=0.,
- recurrent_dropout=0.,
- **kwargs):
- super(SimpleRNN, self).__init__(**kwargs)
- self.units = units
- self.activation = activations.get(activation)
- self.use_bias = use_bias
-
- self.kernel_initializer = initializers.get(kernel_initializer)
- self.recurrent_initializer = initializers.get(recurrent_initializer)
- self.bias_initializer = initializers.get(bias_initializer)
-
- self.kernel_regularizer = regularizers.get(kernel_regularizer)
- self.recurrent_regularizer = regularizers.get(recurrent_regularizer)
- self.bias_regularizer = regularizers.get(bias_regularizer)
- self.activity_regularizer = regularizers.get(activity_regularizer)
-
- self.kernel_constraint = constraints.get(kernel_constraint)
- self.recurrent_constraint = constraints.get(recurrent_constraint)
- self.bias_constraint = constraints.get(bias_constraint)
-
- self.dropout = min(1., max(0., dropout))
- self.recurrent_dropout = min(1., max(0., recurrent_dropout))
- self.state_spec = InputSpec(shape=(None, self.units))
-
- def build(self, input_shape):
- if isinstance(input_shape, list):
- input_shape = input_shape[0]
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
-
- batch_size = input_shape[0] if self.stateful else None
- self.input_dim = input_shape[2]
- self.input_spec[0] = InputSpec(shape=(batch_size, None, self.input_dim))
-
- self.states = [None]
- if self.stateful:
- self.reset_states()
-
- self.kernel = self.add_weight(
- shape=(self.input_dim, self.units),
- name='kernel',
- initializer=self.kernel_initializer,
- regularizer=self.kernel_regularizer,
- constraint=self.kernel_constraint)
- self.recurrent_kernel = self.add_weight(
- shape=(self.units, self.units),
- name='recurrent_kernel',
- initializer=self.recurrent_initializer,
- regularizer=self.recurrent_regularizer,
- constraint=self.recurrent_constraint)
- if self.use_bias:
- self.bias = self.add_weight(
- shape=(self.units,),
- name='bias',
- initializer=self.bias_initializer,
- regularizer=self.bias_regularizer,
- constraint=self.bias_constraint)
- else:
- self.bias = None
- self.built = True
-
- def preprocess_input(self, inputs, training=None):
- if self.implementation > 0:
- return inputs
- else:
- input_shape = inputs.get_shape().as_list()
- input_dim = input_shape[2]
- timesteps = input_shape[1]
- return _time_distributed_dense(
- inputs,
- self.kernel,
- self.bias,
- self.dropout,
- input_dim,
- self.units,
- timesteps,
- training=training)
-
- def step(self, inputs, states):
- if self.implementation == 0:
- h = inputs
- else:
- if 0 < self.dropout < 1:
- h = K.dot(inputs * states[1], self.kernel)
- else:
- h = K.dot(inputs, self.kernel)
- if self.bias is not None:
- h = K.bias_add(h, self.bias)
-
- prev_output = states[0]
- if 0 < self.recurrent_dropout < 1:
- prev_output *= states[2]
- output = h + K.dot(prev_output, self.recurrent_kernel)
- if self.activation is not None:
- output = self.activation(output)
-
- # Properly set learning phase on output tensor.
- if 0 < self.dropout + self.recurrent_dropout:
- output._uses_learning_phase = True
- return output, [output]
-
- def get_constants(self, inputs, training=None):
- constants = []
- if self.implementation != 0 and 0 < self.dropout < 1:
- input_shape = K.int_shape(inputs)
- input_dim = input_shape[-1]
- ones = K.ones_like(K.reshape(inputs[:, 0, 0], (-1, 1)))
- ones = K.tile(ones, (1, int(input_dim)))
-
- def dropped_inputs():
- return K.dropout(ones, self.dropout)
-
- dp_mask = K.in_train_phase(dropped_inputs, ones, training=training)
- constants.append(dp_mask)
- else:
- constants.append(K.cast_to_floatx(1.))
-
- if 0 < self.recurrent_dropout < 1:
- ones = K.ones_like(K.reshape(inputs[:, 0, 0], (-1, 1)))
- ones = K.tile(ones, (1, self.units))
-
- def dropped_inputs(): # pylint: disable=function-redefined
- return K.dropout(ones, self.recurrent_dropout)
-
- rec_dp_mask = K.in_train_phase(dropped_inputs, ones, training=training)
- constants.append(rec_dp_mask)
- else:
- constants.append(K.cast_to_floatx(1.))
- return constants
-
- def get_config(self):
- config = {
- 'units': self.units,
- 'activation': activations.serialize(self.activation),
- 'use_bias': self.use_bias,
- 'kernel_initializer': initializers.serialize(self.kernel_initializer),
- 'recurrent_initializer':
- initializers.serialize(self.recurrent_initializer),
- 'bias_initializer': initializers.serialize(self.bias_initializer),
- 'kernel_regularizer': regularizers.serialize(self.kernel_regularizer),
- 'recurrent_regularizer':
- regularizers.serialize(self.recurrent_regularizer),
- 'bias_regularizer': regularizers.serialize(self.bias_regularizer),
- 'activity_regularizer':
- regularizers.serialize(self.activity_regularizer),
- 'kernel_constraint': constraints.serialize(self.kernel_constraint),
- 'recurrent_constraint':
- constraints.serialize(self.recurrent_constraint),
- 'bias_constraint': constraints.serialize(self.bias_constraint),
- 'dropout': self.dropout,
- 'recurrent_dropout': self.recurrent_dropout
- }
- base_config = super(SimpleRNN, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class GRU(Recurrent):
- """Gated Recurrent Unit - Cho et al.
-
- 2014.
-
- Arguments:
- units: Positive integer, dimensionality of the output space.
- activation: Activation function to use.
- If you pass None, no activation is applied
- (ie. "linear" activation: `a(x) = x`).
- recurrent_activation: Activation function to use
- for the recurrent step.
- use_bias: Boolean, whether the layer uses a bias vector.
- kernel_initializer: Initializer for the `kernel` weights matrix,
- used for the linear transformation of the inputs..
- recurrent_initializer: Initializer for the `recurrent_kernel`
- weights matrix,
- used for the linear transformation of the recurrent state..
- bias_initializer: Initializer for the bias vector.
- kernel_regularizer: Regularizer function applied to
- the `kernel` weights matrix.
- recurrent_regularizer: Regularizer function applied to
- the `recurrent_kernel` weights matrix.
- bias_regularizer: Regularizer function applied to the bias vector.
- activity_regularizer: Regularizer function applied to
- the output of the layer (its "activation")..
- kernel_constraint: Constraint function applied to
- the `kernel` weights matrix.
- recurrent_constraint: Constraint function applied to
- the `recurrent_kernel` weights matrix.
- bias_constraint: Constraint function applied to the bias vector.
- dropout: Float between 0 and 1.
- Fraction of the units to drop for
- the linear transformation of the inputs.
- recurrent_dropout: Float between 0 and 1.
- Fraction of the units to drop for
- the linear transformation of the recurrent state.
-
- References:
- - [On the Properties of Neural Machine Translation: Encoder-Decoder
- Approaches](https://arxiv.org/abs/1409.1259)
- - [Empirical Evaluation of Gated Recurrent Neural Networks on Sequence
- Modeling](http://arxiv.org/abs/1412.3555v1)
- - [A Theoretically Grounded Application of Dropout in Recurrent Neural
- Networks](http://arxiv.org/abs/1512.05287)
- """
-
- def __init__(self,
- units,
- activation='tanh',
- recurrent_activation='hard_sigmoid',
- use_bias=True,
- kernel_initializer='glorot_uniform',
- recurrent_initializer='orthogonal',
- bias_initializer='zeros',
- kernel_regularizer=None,
- recurrent_regularizer=None,
- bias_regularizer=None,
- activity_regularizer=None,
- kernel_constraint=None,
- recurrent_constraint=None,
- bias_constraint=None,
- dropout=0.,
- recurrent_dropout=0.,
- **kwargs):
- super(GRU, self).__init__(**kwargs)
- self.units = units
- self.activation = activations.get(activation)
- self.recurrent_activation = activations.get(recurrent_activation)
- self.use_bias = use_bias
-
- self.kernel_initializer = initializers.get(kernel_initializer)
- self.recurrent_initializer = initializers.get(recurrent_initializer)
- self.bias_initializer = initializers.get(bias_initializer)
-
- self.kernel_regularizer = regularizers.get(kernel_regularizer)
- self.recurrent_regularizer = regularizers.get(recurrent_regularizer)
- self.bias_regularizer = regularizers.get(bias_regularizer)
- self.activity_regularizer = regularizers.get(activity_regularizer)
-
- self.kernel_constraint = constraints.get(kernel_constraint)
- self.recurrent_constraint = constraints.get(recurrent_constraint)
- self.bias_constraint = constraints.get(bias_constraint)
-
- self.dropout = min(1., max(0., dropout))
- self.recurrent_dropout = min(1., max(0., recurrent_dropout))
- self.state_spec = InputSpec(shape=(None, self.units))
-
- def build(self, input_shape):
- if isinstance(input_shape, list):
- input_shape = input_shape[0]
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- batch_size = input_shape[0] if self.stateful else None
- self.input_dim = input_shape[2]
- self.input_spec[0] = InputSpec(shape=(batch_size, None, self.input_dim))
-
- self.states = [None]
- if self.stateful:
- self.reset_states()
-
- self.kernel = self.add_weight(
- shape=(self.input_dim, self.units * 3),
- name='kernel',
- initializer=self.kernel_initializer,
- regularizer=self.kernel_regularizer,
- constraint=self.kernel_constraint)
- self.recurrent_kernel = self.add_weight(
- shape=(self.units, self.units * 3),
- name='recurrent_kernel',
- initializer=self.recurrent_initializer,
- regularizer=self.recurrent_regularizer,
- constraint=self.recurrent_constraint)
-
- if self.use_bias:
- self.bias = self.add_weight(
- shape=(self.units * 3,),
- name='bias',
- initializer=self.bias_initializer,
- regularizer=self.bias_regularizer,
- constraint=self.bias_constraint)
- else:
- self.bias = None
-
- self.kernel_z = self.kernel[:, :self.units]
- self.recurrent_kernel_z = self.recurrent_kernel[:, :self.units]
- self.kernel_r = self.kernel[:, self.units:self.units * 2]
- self.recurrent_kernel_r = self.recurrent_kernel[:, self.units:
- self.units * 2]
- self.kernel_h = self.kernel[:, self.units * 2:]
- self.recurrent_kernel_h = self.recurrent_kernel[:, self.units * 2:]
-
- if self.use_bias:
- self.bias_z = self.bias[:self.units]
- self.bias_r = self.bias[self.units:self.units * 2]
- self.bias_h = self.bias[self.units * 2:]
- else:
- self.bias_z = None
- self.bias_r = None
- self.bias_h = None
- self.built = True
-
- def preprocess_input(self, inputs, training=None):
- if self.implementation == 0:
- input_shape = inputs.get_shape().as_list()
- input_dim = input_shape[2]
- timesteps = input_shape[1]
-
- x_z = _time_distributed_dense(
- inputs,
- self.kernel_z,
- self.bias_z,
- self.dropout,
- input_dim,
- self.units,
- timesteps,
- training=training)
- x_r = _time_distributed_dense(
- inputs,
- self.kernel_r,
- self.bias_r,
- self.dropout,
- input_dim,
- self.units,
- timesteps,
- training=training)
- x_h = _time_distributed_dense(
- inputs,
- self.kernel_h,
- self.bias_h,
- self.dropout,
- input_dim,
- self.units,
- timesteps,
- training=training)
- return K.concatenate([x_z, x_r, x_h], axis=2)
- else:
- return inputs
-
- def get_constants(self, inputs, training=None):
- constants = []
- if self.implementation != 0 and 0 < self.dropout < 1:
- input_shape = K.int_shape(inputs)
- input_dim = input_shape[-1]
- ones = K.ones_like(K.reshape(inputs[:, 0, 0], (-1, 1)))
- ones = K.tile(ones, (1, int(input_dim)))
-
- def dropped_inputs():
- return K.dropout(ones, self.dropout)
-
- dp_mask = [
- K.in_train_phase(dropped_inputs, ones, training=training)
- for _ in range(3)
- ]
- constants.append(dp_mask)
- else:
- constants.append([K.cast_to_floatx(1.) for _ in range(3)])
-
- if 0 < self.recurrent_dropout < 1:
- ones = K.ones_like(K.reshape(inputs[:, 0, 0], (-1, 1)))
- ones = K.tile(ones, (1, self.units))
-
- def dropped_inputs(): # pylint: disable=function-redefined
- return K.dropout(ones, self.recurrent_dropout)
-
- rec_dp_mask = [
- K.in_train_phase(dropped_inputs, ones, training=training)
- for _ in range(3)
- ]
- constants.append(rec_dp_mask)
- else:
- constants.append([K.cast_to_floatx(1.) for _ in range(3)])
- return constants
-
- def step(self, inputs, states):
- h_tm1 = states[0] # previous memory
- dp_mask = states[1] # dropout matrices for recurrent units
- rec_dp_mask = states[2]
-
- if self.implementation == 2:
- matrix_x = K.dot(inputs * dp_mask[0], self.kernel)
- if self.use_bias:
- matrix_x = K.bias_add(matrix_x, self.bias)
- matrix_inner = K.dot(h_tm1 * rec_dp_mask[0],
- self.recurrent_kernel[:, :2 * self.units])
-
- x_z = matrix_x[:, :self.units]
- x_r = matrix_x[:, self.units:2 * self.units]
- recurrent_z = matrix_inner[:, :self.units]
- recurrent_r = matrix_inner[:, self.units:2 * self.units]
-
- z = self.recurrent_activation(x_z + recurrent_z)
- r = self.recurrent_activation(x_r + recurrent_r)
-
- x_h = matrix_x[:, 2 * self.units:]
- recurrent_h = K.dot(r * h_tm1 * rec_dp_mask[0],
- self.recurrent_kernel[:, 2 * self.units:])
- hh = self.activation(x_h + recurrent_h)
- else:
- if self.implementation == 0:
- x_z = inputs[:, :self.units]
- x_r = inputs[:, self.units:2 * self.units]
- x_h = inputs[:, 2 * self.units:]
- elif self.implementation == 1:
- x_z = K.dot(inputs * dp_mask[0], self.kernel_z)
- x_r = K.dot(inputs * dp_mask[1], self.kernel_r)
- x_h = K.dot(inputs * dp_mask[2], self.kernel_h)
- if self.use_bias:
- x_z = K.bias_add(x_z, self.bias_z)
- x_r = K.bias_add(x_r, self.bias_r)
- x_h = K.bias_add(x_h, self.bias_h)
- else:
- raise ValueError('Unknown `implementation` mode.')
- z = self.recurrent_activation(x_z + K.dot(h_tm1 * rec_dp_mask[0],
- self.recurrent_kernel_z))
- r = self.recurrent_activation(x_r + K.dot(h_tm1 * rec_dp_mask[1],
- self.recurrent_kernel_r))
-
- hh = self.activation(x_h + K.dot(r * h_tm1 * rec_dp_mask[2],
- self.recurrent_kernel_h))
- h = z * h_tm1 + (1 - z) * hh
- if 0 < self.dropout + self.recurrent_dropout:
- h._uses_learning_phase = True
- return h, [h]
-
- def get_config(self):
- config = {
- 'units': self.units,
- 'activation': activations.serialize(self.activation),
- 'recurrent_activation':
- activations.serialize(self.recurrent_activation),
- 'use_bias': self.use_bias,
- 'kernel_initializer': initializers.serialize(self.kernel_initializer),
- 'recurrent_initializer':
- initializers.serialize(self.recurrent_initializer),
- 'bias_initializer': initializers.serialize(self.bias_initializer),
- 'kernel_regularizer': regularizers.serialize(self.kernel_regularizer),
- 'recurrent_regularizer':
- regularizers.serialize(self.recurrent_regularizer),
- 'bias_regularizer': regularizers.serialize(self.bias_regularizer),
- 'activity_regularizer':
- regularizers.serialize(self.activity_regularizer),
- 'kernel_constraint': constraints.serialize(self.kernel_constraint),
- 'recurrent_constraint':
- constraints.serialize(self.recurrent_constraint),
- 'bias_constraint': constraints.serialize(self.bias_constraint),
- 'dropout': self.dropout,
- 'recurrent_dropout': self.recurrent_dropout
- }
- base_config = super(GRU, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class LSTM(Recurrent):
- """Long-Short Term Memory unit - Hochreiter 1997.
-
- For a step-by-step description of the algorithm, see
- [this tutorial](http://deeplearning.net/tutorial/lstm.html).
-
- Arguments:
- units: Positive integer, dimensionality of the output space.
- activation: Activation function to use.
- If you pass None, no activation is applied
- (ie. "linear" activation: `a(x) = x`).
- recurrent_activation: Activation function to use
- for the recurrent step.
- use_bias: Boolean, whether the layer uses a bias vector.
- kernel_initializer: Initializer for the `kernel` weights matrix,
- used for the linear transformation of the inputs..
- recurrent_initializer: Initializer for the `recurrent_kernel`
- weights matrix,
- used for the linear transformation of the recurrent state..
- bias_initializer: Initializer for the bias vector.
- unit_forget_bias: Boolean.
- If True, add 1 to the bias of the forget gate at initialization.
- Setting it to true will also force `bias_initializer="zeros"`.
- This is recommended in [Jozefowicz et
- al.](http://www.jmlr.org/proceedings/papers/v37/jozefowicz15.pdf)
- kernel_regularizer: Regularizer function applied to
- the `kernel` weights matrix.
- recurrent_regularizer: Regularizer function applied to
- the `recurrent_kernel` weights matrix.
- bias_regularizer: Regularizer function applied to the bias vector.
- activity_regularizer: Regularizer function applied to
- the output of the layer (its "activation")..
- kernel_constraint: Constraint function applied to
- the `kernel` weights matrix.
- recurrent_constraint: Constraint function applied to
- the `recurrent_kernel` weights matrix.
- bias_constraint: Constraint function applied to the bias vector.
- dropout: Float between 0 and 1.
- Fraction of the units to drop for
- the linear transformation of the inputs.
- recurrent_dropout: Float between 0 and 1.
- Fraction of the units to drop for
- the linear transformation of the recurrent state.
-
- References:
- - [Long short-term
- memory]((http://www.bioinf.jku.at/publications/older/2604.pdf)
- (original 1997 paper)
- - [Supervised sequence labeling with recurrent neural
- networks](http://www.cs.toronto.edu/~graves/preprint.pdf)
- - [A Theoretically Grounded Application of Dropout in Recurrent Neural
- Networks](http://arxiv.org/abs/1512.05287)
- """
-
- def __init__(self,
- units,
- activation='tanh',
- recurrent_activation='hard_sigmoid',
- use_bias=True,
- kernel_initializer='glorot_uniform',
- recurrent_initializer='orthogonal',
- bias_initializer='zeros',
- unit_forget_bias=True,
- kernel_regularizer=None,
- recurrent_regularizer=None,
- bias_regularizer=None,
- activity_regularizer=None,
- kernel_constraint=None,
- recurrent_constraint=None,
- bias_constraint=None,
- dropout=0.,
- recurrent_dropout=0.,
- **kwargs):
- super(LSTM, self).__init__(**kwargs)
- self.units = units
- self.activation = activations.get(activation)
- self.recurrent_activation = activations.get(recurrent_activation)
- self.use_bias = use_bias
-
- self.kernel_initializer = initializers.get(kernel_initializer)
- self.recurrent_initializer = initializers.get(recurrent_initializer)
- self.bias_initializer = initializers.get(bias_initializer)
- self.unit_forget_bias = unit_forget_bias
-
- self.kernel_regularizer = regularizers.get(kernel_regularizer)
- self.recurrent_regularizer = regularizers.get(recurrent_regularizer)
- self.bias_regularizer = regularizers.get(bias_regularizer)
- self.activity_regularizer = regularizers.get(activity_regularizer)
-
- self.kernel_constraint = constraints.get(kernel_constraint)
- self.recurrent_constraint = constraints.get(recurrent_constraint)
- self.bias_constraint = constraints.get(bias_constraint)
-
- self.dropout = min(1., max(0., dropout))
- self.recurrent_dropout = min(1., max(0., recurrent_dropout))
- self.state_spec = [
- InputSpec(shape=(None, self.units)),
- InputSpec(shape=(None, self.units))
- ]
-
- def build(self, input_shape):
- if isinstance(input_shape, list):
- input_shape = input_shape[0]
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- batch_size = input_shape[0] if self.stateful else None
- self.input_dim = input_shape[2]
- self.input_spec[0] = InputSpec(shape=(batch_size, None, self.input_dim))
-
- self.states = [None, None]
- if self.stateful:
- self.reset_states()
-
- self.kernel = self.add_weight(
- shape=(self.input_dim, self.units * 4),
- name='kernel',
- initializer=self.kernel_initializer,
- regularizer=self.kernel_regularizer,
- constraint=self.kernel_constraint)
- self.recurrent_kernel = self.add_weight(
- shape=(self.units, self.units * 4),
- name='recurrent_kernel',
- initializer=self.recurrent_initializer,
- regularizer=self.recurrent_regularizer,
- constraint=self.recurrent_constraint)
-
- if self.use_bias:
- if self.unit_forget_bias:
-
- def bias_initializer(_, *args, **kwargs):
- return K.concatenate([
- self.bias_initializer((self.units,), *args, **kwargs),
- initializers.Ones()((self.units,), *args, **kwargs),
- self.bias_initializer((self.units * 2,), *args, **kwargs),
- ])
- else:
- bias_initializer = self.bias_initializer
- self.bias = self.add_weight(
- shape=(self.units * 4,),
- name='bias',
- initializer=bias_initializer,
- regularizer=self.bias_regularizer,
- constraint=self.bias_constraint)
- else:
- self.bias = None
-
- self.kernel_i = self.kernel[:, :self.units]
- self.kernel_f = self.kernel[:, self.units:self.units * 2]
- self.kernel_c = self.kernel[:, self.units * 2:self.units * 3]
- self.kernel_o = self.kernel[:, self.units * 3:]
-
- self.recurrent_kernel_i = self.recurrent_kernel[:, :self.units]
- self.recurrent_kernel_f = self.recurrent_kernel[:, self.units:
- self.units * 2]
- self.recurrent_kernel_c = self.recurrent_kernel[:, self.units * 2:
- self.units * 3]
- self.recurrent_kernel_o = self.recurrent_kernel[:, self.units * 3:]
-
- if self.use_bias:
- self.bias_i = self.bias[:self.units]
- self.bias_f = self.bias[self.units:self.units * 2]
- self.bias_c = self.bias[self.units * 2:self.units * 3]
- self.bias_o = self.bias[self.units * 3:]
- else:
- self.bias_i = None
- self.bias_f = None
- self.bias_c = None
- self.bias_o = None
- self.built = True
-
- def preprocess_input(self, inputs, training=None):
- if self.implementation == 0:
- input_shape = inputs.get_shape().as_list()
- input_dim = input_shape[2]
- timesteps = input_shape[1]
-
- x_i = _time_distributed_dense(
- inputs,
- self.kernel_i,
- self.bias_i,
- self.dropout,
- input_dim,
- self.units,
- timesteps,
- training=training)
- x_f = _time_distributed_dense(
- inputs,
- self.kernel_f,
- self.bias_f,
- self.dropout,
- input_dim,
- self.units,
- timesteps,
- training=training)
- x_c = _time_distributed_dense(
- inputs,
- self.kernel_c,
- self.bias_c,
- self.dropout,
- input_dim,
- self.units,
- timesteps,
- training=training)
- x_o = _time_distributed_dense(
- inputs,
- self.kernel_o,
- self.bias_o,
- self.dropout,
- input_dim,
- self.units,
- timesteps,
- training=training)
- return K.concatenate([x_i, x_f, x_c, x_o], axis=2)
- else:
- return inputs
-
- def get_constants(self, inputs, training=None):
- constants = []
- if self.implementation != 0 and 0 < self.dropout < 1:
- input_shape = K.int_shape(inputs)
- input_dim = input_shape[-1]
- ones = K.ones_like(K.reshape(inputs[:, 0, 0], (-1, 1)))
- ones = K.tile(ones, (1, int(input_dim)))
-
- def dropped_inputs():
- return K.dropout(ones, self.dropout)
-
- dp_mask = [
- K.in_train_phase(dropped_inputs, ones, training=training)
- for _ in range(4)
- ]
- constants.append(dp_mask)
- else:
- constants.append([K.cast_to_floatx(1.) for _ in range(4)])
-
- if 0 < self.recurrent_dropout < 1:
- ones = K.ones_like(K.reshape(inputs[:, 0, 0], (-1, 1)))
- ones = K.tile(ones, (1, self.units))
-
- def dropped_inputs(): # pylint: disable=function-redefined
- return K.dropout(ones, self.recurrent_dropout)
-
- rec_dp_mask = [
- K.in_train_phase(dropped_inputs, ones, training=training)
- for _ in range(4)
- ]
- constants.append(rec_dp_mask)
- else:
- constants.append([K.cast_to_floatx(1.) for _ in range(4)])
- return constants
-
- def step(self, inputs, states):
- h_tm1 = states[0]
- c_tm1 = states[1]
- dp_mask = states[2]
- rec_dp_mask = states[3]
-
- if self.implementation == 2:
- z = K.dot(inputs * dp_mask[0], self.kernel)
- z += K.dot(h_tm1 * rec_dp_mask[0], self.recurrent_kernel)
- if self.use_bias:
- z = K.bias_add(z, self.bias)
-
- z0 = z[:, :self.units]
- z1 = z[:, self.units:2 * self.units]
- z2 = z[:, 2 * self.units:3 * self.units]
- z3 = z[:, 3 * self.units:]
-
- i = self.recurrent_activation(z0)
- f = self.recurrent_activation(z1)
- c = f * c_tm1 + i * self.activation(z2)
- o = self.recurrent_activation(z3)
- else:
- if self.implementation == 0:
- x_i = inputs[:, :self.units]
- x_f = inputs[:, self.units:2 * self.units]
- x_c = inputs[:, 2 * self.units:3 * self.units]
- x_o = inputs[:, 3 * self.units:]
- elif self.implementation == 1:
- x_i = K.dot(inputs * dp_mask[0], self.kernel_i) + self.bias_i
- x_f = K.dot(inputs * dp_mask[1], self.kernel_f) + self.bias_f
- x_c = K.dot(inputs * dp_mask[2], self.kernel_c) + self.bias_c
- x_o = K.dot(inputs * dp_mask[3], self.kernel_o) + self.bias_o
- else:
- raise ValueError('Unknown `implementation` mode.')
-
- i = self.recurrent_activation(x_i + K.dot(h_tm1 * rec_dp_mask[0],
- self.recurrent_kernel_i))
- f = self.recurrent_activation(x_f + K.dot(h_tm1 * rec_dp_mask[1],
- self.recurrent_kernel_f))
- c = f * c_tm1 + i * self.activation(
- x_c + K.dot(h_tm1 * rec_dp_mask[2], self.recurrent_kernel_c))
- o = self.recurrent_activation(x_o + K.dot(h_tm1 * rec_dp_mask[3],
- self.recurrent_kernel_o))
- h = o * self.activation(c)
- if 0 < self.dropout + self.recurrent_dropout:
- h._uses_learning_phase = True
- return h, [h, c]
-
- def get_config(self):
- config = {
- 'units': self.units,
- 'activation': activations.serialize(self.activation),
- 'recurrent_activation':
- activations.serialize(self.recurrent_activation),
- 'use_bias': self.use_bias,
- 'kernel_initializer': initializers.serialize(self.kernel_initializer),
- 'recurrent_initializer':
- initializers.serialize(self.recurrent_initializer),
- 'bias_initializer': initializers.serialize(self.bias_initializer),
- 'unit_forget_bias': self.unit_forget_bias,
- 'kernel_regularizer': regularizers.serialize(self.kernel_regularizer),
- 'recurrent_regularizer':
- regularizers.serialize(self.recurrent_regularizer),
- 'bias_regularizer': regularizers.serialize(self.bias_regularizer),
- 'activity_regularizer':
- regularizers.serialize(self.activity_regularizer),
- 'kernel_constraint': constraints.serialize(self.kernel_constraint),
- 'recurrent_constraint':
- constraints.serialize(self.recurrent_constraint),
- 'bias_constraint': constraints.serialize(self.bias_constraint),
- 'dropout': self.dropout,
- 'recurrent_dropout': self.recurrent_dropout
- }
- base_config = super(LSTM, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
diff --git a/tensorflow/contrib/keras/python/keras/layers/serialization.py b/tensorflow/contrib/keras/python/keras/layers/serialization.py
deleted file mode 100644
index f9c21a3e67..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/serialization.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Layer serialization/deserialization functions.
-"""
-# pylint: disable=wildcard-import
-# pylint: disable=unused-import
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras.engine import Input
-from tensorflow.contrib.keras.python.keras.engine import InputLayer
-from tensorflow.contrib.keras.python.keras.layers.advanced_activations import *
-from tensorflow.contrib.keras.python.keras.layers.convolutional import *
-from tensorflow.contrib.keras.python.keras.layers.convolutional_recurrent import *
-from tensorflow.contrib.keras.python.keras.layers.core import *
-from tensorflow.contrib.keras.python.keras.layers.embeddings import *
-from tensorflow.contrib.keras.python.keras.layers.local import *
-from tensorflow.contrib.keras.python.keras.layers.merge import *
-from tensorflow.contrib.keras.python.keras.layers.noise import *
-from tensorflow.contrib.keras.python.keras.layers.normalization import *
-from tensorflow.contrib.keras.python.keras.layers.pooling import *
-from tensorflow.contrib.keras.python.keras.layers.recurrent import *
-from tensorflow.contrib.keras.python.keras.layers.wrappers import *
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import deserialize_keras_object
-
-
-def serialize(layer):
- return {'class_name': layer.__class__.__name__, 'config': layer.get_config()}
-
-
-def deserialize(config, custom_objects=None):
- """Instantiates a layer from a config dictionary.
-
- Arguments:
- config: dict of the form {'class_name': str, 'config': dict}
- custom_objects: dict mapping class names (or function names)
- of custom (non-Keras) objects to class/functions
-
- Returns:
- Layer instance (may be Model, Sequential, Layer...)
- """
- from tensorflow.contrib.keras.python.keras import models # pylint: disable=g-import-not-at-top
- globs = globals() # All layers.
- globs['Model'] = models.Model
- globs['Sequential'] = models.Sequential
- return deserialize_keras_object(
- config,
- module_objects=globs,
- custom_objects=custom_objects,
- printable_module_name='layer')
diff --git a/tensorflow/contrib/keras/python/keras/layers/serialization_test.py b/tensorflow/contrib/keras/python/keras/layers/serialization_test.py
deleted file mode 100644
index fb2e506a4c..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/serialization_test.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for layer serialization utils."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-class LayerSerializationTest(test.TestCase):
-
- def test_serialize_deserialize(self):
- layer = keras.layers.Dense(
- 3, activation='relu', kernel_initializer='ones', bias_regularizer='l2')
- config = keras.layers.serialize(layer)
- new_layer = keras.layers.deserialize(config)
- self.assertEqual(new_layer.activation, keras.activations.relu)
- self.assertEqual(new_layer.bias_regularizer.__class__,
- keras.regularizers.L1L2)
- self.assertEqual(new_layer.kernel_initializer.__class__,
- keras.initializers.Ones)
- self.assertEqual(new_layer.units, 3)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/layers/simplernn_test.py b/tensorflow/contrib/keras/python/keras/layers/simplernn_test.py
deleted file mode 100644
index 3d67011352..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/simplernn_test.py
+++ /dev/null
@@ -1,203 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for SimpleRNN layer."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-
-
-class SimpleRNNLayerTest(test.TestCase):
-
- def test_return_sequences_SimpleRNN(self):
- num_samples = 2
- timesteps = 3
- embedding_dim = 4
- units = 2
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.SimpleRNN,
- kwargs={'units': units,
- 'return_sequences': True},
- input_shape=(num_samples, timesteps, embedding_dim))
-
- def test_dynamic_behavior_SimpleRNN(self):
- num_samples = 2
- timesteps = 3
- embedding_dim = 4
- units = 2
- with self.test_session():
- layer = keras.layers.SimpleRNN(units, input_shape=(None, embedding_dim))
- model = keras.models.Sequential()
- model.add(layer)
- model.compile('sgd', 'mse')
- x = np.random.random((num_samples, timesteps, embedding_dim))
- y = np.random.random((num_samples, units))
- model.train_on_batch(x, y)
-
- def test_dropout_SimpleRNN(self):
- num_samples = 2
- timesteps = 3
- embedding_dim = 4
- units = 2
- with self.test_session():
- testing_utils.layer_test(
- keras.layers.SimpleRNN,
- kwargs={'units': units,
- 'dropout': 0.1,
- 'recurrent_dropout': 0.1},
- input_shape=(num_samples, timesteps, embedding_dim))
-
- def test_implementation_mode_SimpleRNN(self):
- num_samples = 2
- timesteps = 3
- embedding_dim = 4
- units = 2
- with self.test_session():
- for mode in [0, 1, 2]:
- testing_utils.layer_test(
- keras.layers.SimpleRNN,
- kwargs={'units': units,
- 'implementation': mode},
- input_shape=(num_samples, timesteps, embedding_dim))
-
- def test_statefulness_SimpleRNN(self):
- num_samples = 2
- timesteps = 3
- embedding_dim = 4
- units = 2
- layer_class = keras.layers.SimpleRNN
- with self.test_session():
- model = keras.models.Sequential()
- model.add(
- keras.layers.Embedding(
- 4,
- embedding_dim,
- mask_zero=True,
- input_length=timesteps,
- batch_input_shape=(num_samples, timesteps)))
- layer = layer_class(
- units, return_sequences=False, stateful=True, weights=None)
- model.add(layer)
- model.compile(optimizer='sgd', loss='mse')
- out1 = model.predict(np.ones((num_samples, timesteps)))
- self.assertEqual(out1.shape, (num_samples, units))
-
- # train once so that the states change
- model.train_on_batch(
- np.ones((num_samples, timesteps)), np.ones((num_samples, units)))
- out2 = model.predict(np.ones((num_samples, timesteps)))
-
- # if the state is not reset, output should be different
- self.assertNotEqual(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((num_samples, timesteps)))
- self.assertNotEqual(out2.max(), out3.max())
-
- # check that container-level reset_states() works
- model.reset_states()
- out4 = model.predict(np.ones((num_samples, timesteps)))
- np.testing.assert_allclose(out3, out4, atol=1e-5)
-
- # check that the call to `predict` updated the states
- out5 = model.predict(np.ones((num_samples, timesteps)))
- self.assertNotEqual(out4.max(), out5.max())
-
- # Check masking
- layer.reset_states()
-
- left_padded_input = np.ones((num_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((num_samples, timesteps))
- right_padded_input[0, -1:] = 0
- right_padded_input[1, -2:] = 0
- out7 = model.predict(right_padded_input)
-
- np.testing.assert_allclose(out7, out6, atol=1e-5)
-
- def test_regularizers_SimpleRNN(self):
- embedding_dim = 4
- layer_class = keras.layers.SimpleRNN
- with self.test_session():
- layer = layer_class(
- 5,
- return_sequences=False,
- weights=None,
- input_shape=(None, embedding_dim),
- kernel_regularizer=keras.regularizers.l1(0.01),
- recurrent_regularizer=keras.regularizers.l1(0.01),
- bias_regularizer='l2',
- activity_regularizer='l1')
- layer.build((None, None, 2))
- self.assertEqual(len(layer.losses), 3)
- layer(keras.backend.variable(np.ones((2, 3, 2))))
- self.assertEqual(len(layer.losses), 4)
-
- def test_constraints_SimpleRNN(self):
- embedding_dim = 4
- layer_class = keras.layers.SimpleRNN
- with self.test_session():
- k_constraint = keras.constraints.max_norm(0.01)
- r_constraint = keras.constraints.max_norm(0.01)
- b_constraint = keras.constraints.max_norm(0.01)
- layer = layer_class(
- 5,
- return_sequences=False,
- weights=None,
- input_shape=(None, embedding_dim),
- kernel_constraint=k_constraint,
- recurrent_constraint=r_constraint,
- bias_constraint=b_constraint)
- layer.build((None, None, embedding_dim))
- self.assertEqual(layer.kernel.constraint, k_constraint)
- self.assertEqual(layer.recurrent_kernel.constraint, r_constraint)
- self.assertEqual(layer.bias.constraint, b_constraint)
-
- def test_with_masking_layer_SimpleRNN(self):
- layer_class = keras.layers.SimpleRNN
- with self.test_session():
- inputs = np.random.random((2, 3, 4))
- targets = np.abs(np.random.random((2, 3, 5)))
- targets /= targets.sum(axis=-1, keepdims=True)
- model = keras.models.Sequential()
- model.add(keras.layers.Masking(input_shape=(3, 4)))
- model.add(layer_class(units=5, return_sequences=True, unroll=False))
- model.compile(loss='categorical_crossentropy', optimizer='adam')
- model.fit(inputs, targets, epochs=1, batch_size=2, verbose=1)
-
- def test_from_config_SimpleRNN(self):
- layer_class = keras.layers.SimpleRNN
- for stateful in (False, True):
- l1 = layer_class(units=1, stateful=stateful)
- l2 = layer_class.from_config(l1.get_config())
- assert l1.get_config() == l2.get_config()
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/layers/wrappers.py b/tensorflow/contrib/keras/python/keras/layers/wrappers.py
deleted file mode 100644
index 9defd6cd1c..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/wrappers.py
+++ /dev/null
@@ -1,408 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-# pylint: disable=protected-access
-"""Wrapper layers: layers that augment the functionality of another layer.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import copy
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.engine import InputSpec
-from tensorflow.contrib.keras.python.keras.engine import Layer
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import has_arg
-from tensorflow.python.framework import tensor_shape
-from tensorflow.python.layers import base as tf_base_layers
-
-
-class Wrapper(Layer):
- """Abstract wrapper base class.
-
- Wrappers take another layer and augment it in various ways.
- Do not use this class as a layer, it is only an abstract base class.
- Two usable wrappers are the `TimeDistributed` and `Bidirectional` wrappers.
-
- Arguments:
- layer: The layer to be wrapped.
- """
-
- def __init__(self, layer, **kwargs):
- self.layer = layer
- # Tracks mapping of Wrapper inputs to inner layer inputs. Useful when
- # the inner layer has update ops that depend on its inputs (as opposed
- # to the inputs to the Wrapper layer).
- self._input_map = {}
- super(Wrapper, self).__init__(**kwargs)
-
- def build(self, input_shape=None):
- self.built = True
-
- @property
- def activity_regularizer(self):
- if hasattr(self.layer, 'activity_regularizer'):
- return self.layer.activity_regularizer
- else:
- return None
-
- @property
- def trainable_weights(self):
- return self.layer.trainable_weights
-
- @property
- def non_trainable_weights(self):
- return self.layer.non_trainable_weights
-
- @property
- def updates(self):
- if hasattr(self.layer, 'updates'):
- return self.layer.updates
- return []
-
- def get_updates_for(self, inputs=None):
- # If the wrapper modifies the inputs, use the modified inputs to
- # get the updates from the inner layer.
- inner_inputs = inputs
- if inputs is not None:
- uid = tf_base_layers._object_list_uid(inputs)
- if uid in self._input_map:
- inner_inputs = self._input_map[uid]
-
- updates = self.layer.get_updates_for(inner_inputs)
- updates += super(Wrapper, self).get_updates_for(inputs)
- return updates
-
- @property
- def losses(self):
- if hasattr(self.layer, 'losses'):
- return self.layer.losses
- return []
-
- def get_losses_for(self, inputs=None):
- if inputs is None:
- losses = self.layer.get_losses_for(None)
- return losses + super(Wrapper, self).get_losses_for(None)
- return super(Wrapper, self).get_losses_for(inputs)
-
- @property
- def constraints(self):
- return self.layer.constraints
-
- def get_weights(self):
- return self.layer.get_weights()
-
- def set_weights(self, weights):
- self.layer.set_weights(weights)
-
- def get_config(self):
- config = {
- 'layer': {
- 'class_name': self.layer.__class__.__name__,
- 'config': self.layer.get_config()
- }
- }
- base_config = super(Wrapper, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
- @classmethod
- def from_config(cls, config, custom_objects=None):
- from tensorflow.contrib.keras.python.keras.layers import deserialize as deserialize_layer # pylint: disable=g-import-not-at-top
- layer = deserialize_layer(
- config.pop('layer'), custom_objects=custom_objects)
- return cls(layer, **config)
-
-
-class TimeDistributed(Wrapper):
- """This wrapper allows to apply a layer to every temporal slice of an input.
-
- The input should be at least 3D, and the dimension of index one
- will be considered to be the temporal dimension.
-
- Consider a batch of 32 samples,
- where each sample is a sequence of 10 vectors of 16 dimensions.
- The batch input shape of the layer is then `(32, 10, 16)`,
- and the `input_shape`, not including the samples dimension, is `(10, 16)`.
-
- You can then use `TimeDistributed` to apply a `Dense` layer
- to each of the 10 timesteps, independently:
-
- ```python
- # as the first layer in a model
- model = Sequential()
- model.add(TimeDistributed(Dense(8), input_shape=(10, 16)))
- # now model.output_shape == (None, 10, 8)
- ```
-
- The output will then have shape `(32, 10, 8)`.
-
- In subsequent layers, there is no need for the `input_shape`:
-
- ```python
- model.add(TimeDistributed(Dense(32)))
- # now model.output_shape == (None, 10, 32)
- ```
-
- The output will then have shape `(32, 10, 32)`.
-
- `TimeDistributed` can be used with arbitrary layers, not just `Dense`,
- for instance with a `Conv2D` layer:
-
- ```python
- model = Sequential()
- model.add(TimeDistributed(Conv2D(64, (3, 3)),
- input_shape=(10, 299, 299, 3)))
- ```
-
- Arguments:
- layer: a layer instance.
- """
-
- def __init__(self, layer, **kwargs):
- super(TimeDistributed, self).__init__(layer, **kwargs)
- self.supports_masking = True
-
- def build(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- assert len(input_shape) >= 3
- self.input_spec = InputSpec(shape=input_shape)
- child_input_shape = [input_shape[0]] + input_shape[2:]
- if not self.layer.built:
- self.layer.build(child_input_shape)
- self.layer.built = True
- super(TimeDistributed, self).build()
- self.built = True
-
- def _compute_output_shape(self, input_shape):
- input_shape = tensor_shape.TensorShape(input_shape).as_list()
- child_input_shape = tensor_shape.TensorShape([input_shape[0]] +
- input_shape[2:])
- child_output_shape = self.layer._compute_output_shape( # pylint: disable=protected-access
- child_input_shape).as_list()
- timesteps = input_shape[1]
- return tensor_shape.TensorShape([child_output_shape[0], timesteps] +
- child_output_shape[1:])
-
- def call(self, inputs, training=None, mask=None):
- kwargs = {}
- if has_arg(self.layer.call, 'training'):
- kwargs['training'] = training
- uses_learning_phase = False # pylint: disable=redefined-outer-name
-
- input_shape = K.int_shape(inputs)
- if input_shape[0]:
- # batch size matters, use rnn-based implementation
- def step(x, _):
- global uses_learning_phase # pylint: disable=global-variable-undefined
- output = self.layer.call(x, **kwargs)
- if hasattr(output, '_uses_learning_phase'):
- uses_learning_phase = (output._uses_learning_phase or
- uses_learning_phase)
- return output, []
-
- _, outputs, _ = K.rnn(
- step,
- inputs,
- initial_states=[],
- unroll=False)
- y = outputs
- else:
- # No batch size specified, therefore the layer will be able
- # to process batches of any size.
- # We can go with reshape-based implementation for performance.
- input_length = input_shape[1]
- if not input_length:
- input_length = K.shape(inputs)[1]
- # Shape: (num_samples * timesteps, ...). And track the
- # transformation in self._input_map.
- input_uid = tf_base_layers._object_list_uid(inputs)
- inputs = K.reshape(inputs, (-1,) + input_shape[2:])
- self._input_map[input_uid] = inputs
- # (num_samples * timesteps, ...)
- y = self.layer.call(inputs, **kwargs)
- if hasattr(y, '_uses_learning_phase'):
- uses_learning_phase = y._uses_learning_phase
- # Shape: (num_samples, timesteps, ...)
- output_shape = self._compute_output_shape(input_shape).as_list()
- y = K.reshape(y, (-1, input_length) + tuple(output_shape[2:]))
-
- # Apply activity regularizer if any:
- if (hasattr(self.layer, 'activity_regularizer') and
- self.layer.activity_regularizer is not None):
- regularization_loss = self.layer.activity_regularizer(y)
- self.add_loss(regularization_loss, inputs)
-
- if uses_learning_phase:
- y._uses_learning_phase = True
- return y
-
-
-class Bidirectional(Wrapper):
- """Bidirectional wrapper for RNNs.
-
- Arguments:
- layer: `Recurrent` instance.
- merge_mode: Mode by which outputs of the
- forward and backward RNNs will be combined.
- One of {'sum', 'mul', 'concat', 'ave', None}.
- If None, the outputs will not be combined,
- they will be returned as a list.
-
- Raises:
- ValueError: In case of invalid `merge_mode` argument.
-
- Examples:
-
- ```python
- model = Sequential()
- model.add(Bidirectional(LSTM(10, return_sequences=True), input_shape=(5,
- 10)))
- model.add(Bidirectional(LSTM(10)))
- model.add(Dense(5))
- model.add(Activation('softmax'))
- model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
- ```
- """
-
- def __init__(self, layer, merge_mode='concat', weights=None, **kwargs):
- super(Bidirectional, self).__init__(layer, **kwargs)
- if merge_mode not in ['sum', 'mul', 'ave', 'concat', None]:
- raise ValueError('Invalid merge mode. '
- 'Merge mode should be one of '
- '{"sum", "mul", "ave", "concat", None}')
- self.forward_layer = copy.copy(layer)
- config = layer.get_config()
- config['go_backwards'] = not config['go_backwards']
- self.backward_layer = layer.__class__.from_config(config)
- self.forward_layer.name = 'forward_' + self.forward_layer.name
- self.backward_layer.name = 'backward_' + self.backward_layer.name
- self.merge_mode = merge_mode
- if weights:
- nw = len(weights)
- self.forward_layer.initial_weights = weights[:nw // 2]
- self.backward_layer.initial_weights = weights[nw // 2:]
- self.stateful = layer.stateful
- self.return_sequences = layer.return_sequences
- self.supports_masking = True
-
- def get_weights(self):
- return self.forward_layer.get_weights() + self.backward_layer.get_weights()
-
- def set_weights(self, weights):
- nw = len(weights)
- self.forward_layer.set_weights(weights[:nw // 2])
- self.backward_layer.set_weights(weights[nw // 2:])
-
- def _compute_output_shape(self, input_shape):
- input_shape = tuple(tensor_shape.TensorShape(input_shape).as_list())
- if self.merge_mode in ['sum', 'ave', 'mul']:
- return self.forward_layer._compute_output_shape(input_shape) # pylint: disable=protected-access
- elif self.merge_mode == 'concat':
- shape = self.forward_layer._compute_output_shape(input_shape).as_list() # pylint: disable=protected-access
- shape[-1] *= 2
- return tensor_shape.TensorShape(shape)
- elif self.merge_mode is None:
- shape = self.forward_layer._compute_output_shape(input_shape) # pylint: disable=protected-access
- return [shape, copy.copy(shape)]
-
- def call(self, inputs, training=None, mask=None):
- kwargs = {}
- if has_arg(self.layer.call, 'training'):
- kwargs['training'] = training
- if has_arg(self.layer.call, 'mask'):
- kwargs['mask'] = mask
-
- y = self.forward_layer.call(inputs, **kwargs)
- y_rev = self.backward_layer.call(inputs, **kwargs)
- if self.return_sequences:
- y_rev = K.reverse(y_rev, 1)
- if self.merge_mode == 'concat':
- output = K.concatenate([y, y_rev])
- elif self.merge_mode == 'sum':
- output = y + y_rev
- elif self.merge_mode == 'ave':
- output = (y + y_rev) / 2
- elif self.merge_mode == 'mul':
- output = y * y_rev
- elif self.merge_mode is None:
- output = [y, y_rev]
-
- # Properly set learning phase
- if 0 < self.layer.dropout + self.layer.recurrent_dropout:
- if self.merge_mode is None:
- for out in output:
- out._uses_learning_phase = True
- else:
- output._uses_learning_phase = True
- return output
-
- def reset_states(self):
- self.forward_layer.reset_states()
- self.backward_layer.reset_states()
-
- def build(self, input_shape):
- with K.name_scope(self.forward_layer.name):
- self.forward_layer.build(input_shape)
- with K.name_scope(self.backward_layer.name):
- self.backward_layer.build(input_shape)
- self.built = True
-
- def compute_mask(self, inputs, mask):
- if self.return_sequences:
- if not self.merge_mode:
- return [mask, mask]
- else:
- return mask
- else:
- return None
-
- @property
- def trainable_weights(self):
- if hasattr(self.forward_layer, 'trainable_weights'):
- return (self.forward_layer.trainable_weights +
- self.backward_layer.trainable_weights)
- return []
-
- @property
- def non_trainable_weights(self):
- if hasattr(self.forward_layer, 'non_trainable_weights'):
- return (self.forward_layer.non_trainable_weights +
- self.backward_layer.non_trainable_weights)
- return []
-
- @property
- def updates(self):
- if hasattr(self.forward_layer, 'updates'):
- return self.forward_layer.updates + self.backward_layer.updates
- return []
-
- @property
- def losses(self):
- if hasattr(self.forward_layer, 'losses'):
- return self.forward_layer.losses + self.backward_layer.losses
- return []
-
- @property
- def constraints(self):
- constraints = {}
- if hasattr(self.forward_layer, 'constraints'):
- constraints.update(self.forward_layer.constraints)
- constraints.update(self.backward_layer.constraints)
- return constraints
-
- def get_config(self):
- config = {'merge_mode': self.merge_mode}
- base_config = super(Bidirectional, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
diff --git a/tensorflow/contrib/keras/python/keras/layers/wrappers_test.py b/tensorflow/contrib/keras/python/keras/layers/wrappers_test.py
deleted file mode 100644
index d8e6c89564..0000000000
--- a/tensorflow/contrib/keras/python/keras/layers/wrappers_test.py
+++ /dev/null
@@ -1,243 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for layer wrappers."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-class TimeDistributedTest(test.TestCase):
-
- def test_timedistributed_dense(self):
- # first, test with Dense layer
- with self.test_session():
- model = keras.models.Sequential()
- model.add(
- keras.layers.TimeDistributed(
- keras.layers.Dense(2), input_shape=(3, 4)))
- model.compile(optimizer='rmsprop', loss='mse')
- model.fit(
- np.random.random((10, 3, 4)),
- np.random.random((10, 3, 2)),
- epochs=1,
- batch_size=10)
-
- # test config
- model.get_config()
-
- def test_timedistributed_static_batch_size(self):
- with self.test_session():
- model = keras.models.Sequential()
- model.add(
- keras.layers.TimeDistributed(
- keras.layers.Dense(2), input_shape=(3, 4), batch_size=10))
- model.compile(optimizer='rmsprop', loss='mse')
- model.fit(
- np.random.random((10, 3, 4)),
- np.random.random((10, 3, 2)),
- epochs=1,
- batch_size=10)
-
- def test_timedistributed_conv2d(self):
- # test with Conv2D
- with self.test_session():
- model = keras.models.Sequential()
- model.add(
- keras.layers.TimeDistributed(
- keras.layers.Conv2D(5, (2, 2), padding='same'),
- input_shape=(2, 4, 4, 3)))
- model.add(keras.layers.Activation('relu'))
- model.compile(optimizer='rmsprop', loss='mse')
- model.train_on_batch(
- np.random.random((1, 2, 4, 4, 3)), np.random.random((1, 2, 4, 4, 5)))
-
- model = keras.models.model_from_json(model.to_json())
- model.summary()
-
- def test_timedistributed_stacked(self):
- # test stacked layers
- with self.test_session():
- model = keras.models.Sequential()
- model.add(
- keras.layers.TimeDistributed(
- keras.layers.Dense(2), input_shape=(3, 4)))
- model.add(keras.layers.TimeDistributed(keras.layers.Dense(3)))
- model.add(keras.layers.Activation('relu'))
- model.compile(optimizer='rmsprop', loss='mse')
-
- model.fit(
- np.random.random((10, 3, 4)),
- np.random.random((10, 3, 3)),
- epochs=1,
- batch_size=10)
-
- def test_regularizers(self):
- with self.test_session():
- model = keras.models.Sequential()
- model.add(
- keras.layers.TimeDistributed(
- keras.layers.Dense(2, kernel_regularizer='l1'),
- input_shape=(3, 4)))
- model.add(keras.layers.Activation('relu'))
- model.compile(optimizer='rmsprop', loss='mse')
- self.assertEqual(len(model.losses), 1)
-
- def test_TimeDistributed_learning_phase(self):
- with self.test_session():
- # test layers that need learning_phase to be set
- np.random.seed(1234)
- x = keras.layers.Input(shape=(3, 2))
- y = keras.layers.TimeDistributed(
- keras.layers.Dropout(.999))(x, training=True)
- model = keras.models.Model(x, y)
- y = model.predict(np.random.random((10, 3, 2)))
- self.assertAllClose(np.mean(y), 0., atol=1e-1, rtol=1e-1)
-
- def test_TimeDistributed_batchnorm(self):
- with self.test_session():
- # test that wrapped BN updates still work.
- model = keras.models.Sequential()
- model.add(keras.layers.TimeDistributed(
- keras.layers.BatchNormalization(center=True, scale=True),
- name='bn',
- input_shape=(10, 2)))
- model.compile(optimizer='rmsprop', loss='mse')
- # Assert that mean and variance are 0 and 1.
- td = model.layers[0]
- self.assertAllClose(td.get_weights()[2], np.array([0, 0]))
- assert np.array_equal(td.get_weights()[3], np.array([1, 1]))
- # Train
- model.train_on_batch(np.random.normal(loc=2, scale=2, size=(1, 10, 2)),
- np.broadcast_to(np.array([0, 1]), (1, 10, 2)))
- # Assert that mean and variance changed.
- assert not np.array_equal(td.get_weights()[2], np.array([0, 0]))
- assert not np.array_equal(td.get_weights()[3], np.array([1, 1]))
- # Verify input_map has one mapping from inputs to reshaped inputs.
- self.assertEqual(len(td._input_map.keys()), 1)
-
-
-class BidirectionalTest(test.TestCase):
-
- def test_bidirectional(self):
- rnn = keras.layers.SimpleRNN
- samples = 2
- dim = 2
- timesteps = 2
- output_dim = 2
- with self.test_session():
- for mode in ['sum', 'concat', 'ave', 'mul']:
- x = np.random.random((samples, timesteps, dim))
- target_dim = 2 * output_dim if mode == 'concat' else output_dim
- y = np.random.random((samples, target_dim))
-
- # test with Sequential model
- model = keras.models.Sequential()
- model.add(
- keras.layers.Bidirectional(
- rnn(output_dim), merge_mode=mode, input_shape=(timesteps, dim)))
- model.compile(loss='mse', optimizer='sgd')
- model.fit(x, y, epochs=1, batch_size=1)
-
- # test compute output shape
- ref_shape = model.layers[-1].output.get_shape()
- shape = model.layers[-1]._compute_output_shape(
- (None, timesteps, dim))
- self.assertListEqual(shape.as_list(), ref_shape.as_list())
-
- # test config
- model.get_config()
- model = keras.models.model_from_json(model.to_json())
- model.summary()
-
- def test_bidirectional_weight_loading(self):
- rnn = keras.layers.SimpleRNN
- samples = 2
- dim = 2
- timesteps = 2
- output_dim = 2
- with self.test_session():
- x = np.random.random((samples, timesteps, dim))
- model = keras.models.Sequential()
- model.add(
- keras.layers.Bidirectional(
- rnn(output_dim), input_shape=(timesteps, dim)))
- y_ref = model.predict(x)
- weights = model.layers[-1].get_weights()
- model.layers[-1].set_weights(weights)
- y = model.predict(x)
- self.assertAllClose(y, y_ref)
-
- def test_bidirectional_stacked(self):
- # test stacked bidirectional layers
- rnn = keras.layers.SimpleRNN
- samples = 2
- dim = 2
- timesteps = 2
- output_dim = 2
- mode = 'sum'
-
- with self.test_session():
- x = np.random.random((samples, timesteps, dim))
- target_dim = 2 * output_dim if mode == 'concat' else output_dim
- y = np.random.random((samples, target_dim))
-
- model = keras.models.Sequential()
- model.add(
- keras.layers.Bidirectional(
- rnn(output_dim, return_sequences=True),
- merge_mode=mode,
- input_shape=(timesteps, dim)))
- model.add(keras.layers.Bidirectional(rnn(output_dim), merge_mode=mode))
- model.compile(loss='mse', optimizer='sgd')
- model.fit(x, y, epochs=1, batch_size=1)
-
- # test with functional API
- inputs = keras.layers.Input((timesteps, dim))
- output = keras.layers.Bidirectional(
- rnn(output_dim), merge_mode=mode)(inputs)
- model = keras.models.Model(inputs, output)
- model.compile(loss='mse', optimizer='sgd')
- model.fit(x, y, epochs=1, batch_size=1)
-
- def test_bidirectional_statefulness(self):
- # Bidirectional and stateful
- rnn = keras.layers.SimpleRNN
- samples = 2
- dim = 2
- timesteps = 2
- output_dim = 2
- mode = 'sum'
-
- with self.test_session():
- x = np.random.random((samples, timesteps, dim))
- target_dim = 2 * output_dim if mode == 'concat' else output_dim
- y = np.random.random((samples, target_dim))
-
- inputs = keras.layers.Input(batch_shape=(1, timesteps, dim))
- output = keras.layers.Bidirectional(
- rnn(output_dim, stateful=True), merge_mode=mode)(inputs)
- model = keras.models.Model(inputs, output)
- model.compile(loss='mse', optimizer='sgd')
- model.fit(x, y, epochs=1, batch_size=1)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/losses.py b/tensorflow/contrib/keras/python/keras/losses.py
deleted file mode 100644
index e94fca479f..0000000000
--- a/tensorflow/contrib/keras/python/keras/losses.py
+++ /dev/null
@@ -1,129 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Built-in Keras loss functions.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import six
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import deserialize_keras_object
-
-
-def mean_squared_error(y_true, y_pred):
- return K.mean(K.square(y_pred - y_true), axis=-1)
-
-
-def mean_absolute_error(y_true, y_pred):
- return K.mean(K.abs(y_pred - y_true), axis=-1)
-
-
-def mean_absolute_percentage_error(y_true, y_pred):
- # Equivalent to MAE, but sometimes easier to interpret.
- diff = K.abs((y_true - y_pred) / K.clip(K.abs(y_true), K.epsilon(), None))
- return 100. * K.mean(diff, axis=-1)
-
-
-def mean_squared_logarithmic_error(y_true, y_pred):
- first_log = K.log(K.clip(y_pred, K.epsilon(), None) + 1.)
- second_log = K.log(K.clip(y_true, K.epsilon(), None) + 1.)
- return K.mean(K.square(first_log - second_log), axis=-1)
-
-
-def squared_hinge(y_true, y_pred):
- return K.mean(K.square(K.maximum(1. - y_true * y_pred, 0.)), axis=-1)
-
-
-def hinge(y_true, y_pred):
- return K.mean(K.maximum(1. - y_true * y_pred, 0.), axis=-1)
-
-
-def categorical_hinge(y_true, y_pred):
- pos = K.sum(y_true * y_pred, axis=-1)
- neg = K.max((1. - y_true) * y_pred, axis=-1)
- return K.maximum(neg - pos + 1., 0.)
-
-
-def logcosh(y_true, y_pred):
-
- def cosh(x):
- return (K.exp(x) + K.exp(-x)) / 2
-
- return K.mean(K.log(cosh(y_pred - y_true)), axis=-1)
-
-
-def categorical_crossentropy(y_true, y_pred):
- return K.categorical_crossentropy(y_true, y_pred)
-
-
-def sparse_categorical_crossentropy(y_true, y_pred):
- return K.sparse_categorical_crossentropy(y_true, y_pred)
-
-
-def binary_crossentropy(y_true, y_pred):
- return K.mean(K.binary_crossentropy(y_true, y_pred), axis=-1)
-
-
-def kullback_leibler_divergence(y_true, y_pred):
- y_true = K.clip(y_true, K.epsilon(), 1)
- y_pred = K.clip(y_pred, K.epsilon(), 1)
- return K.sum(y_true * K.log(y_true / y_pred), axis=-1)
-
-
-def poisson(y_true, y_pred):
- return K.mean(y_pred - y_true * K.log(y_pred + K.epsilon()), axis=-1)
-
-
-def cosine_proximity(y_true, y_pred):
- y_true = K.l2_normalize(y_true, axis=-1)
- y_pred = K.l2_normalize(y_pred, axis=-1)
- return -K.mean(y_true * y_pred, axis=-1)
-
-
-# Aliases.
-
-mse = MSE = mean_squared_error
-mae = MAE = mean_absolute_error
-mape = MAPE = mean_absolute_percentage_error
-msle = MSLE = mean_squared_logarithmic_error
-kld = KLD = kullback_leibler_divergence
-cosine = cosine_proximity
-
-
-def serialize(loss):
- return loss.__name__
-
-
-def deserialize(name, custom_objects=None):
- return deserialize_keras_object(
- name,
- module_objects=globals(),
- custom_objects=custom_objects,
- printable_module_name='loss function')
-
-
-def get(identifier):
- if identifier is None:
- return None
- if isinstance(identifier, six.string_types):
- identifier = str(identifier)
- return deserialize(identifier)
- elif callable(identifier):
- return identifier
- else:
- raise ValueError('Could not interpret '
- 'loss function identifier:', identifier)
diff --git a/tensorflow/contrib/keras/python/keras/losses_test.py b/tensorflow/contrib/keras/python/keras/losses_test.py
deleted file mode 100644
index 6bdcc0b5ff..0000000000
--- a/tensorflow/contrib/keras/python/keras/losses_test.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for Keras loss functions."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-ALL_LOSSES = [keras.losses.mean_squared_error,
- keras.losses.mean_absolute_error,
- keras.losses.mean_absolute_percentage_error,
- keras.losses.mean_squared_logarithmic_error,
- keras.losses.squared_hinge,
- keras.losses.hinge,
- keras.losses.categorical_crossentropy,
- keras.losses.binary_crossentropy,
- keras.losses.kullback_leibler_divergence,
- keras.losses.poisson,
- keras.losses.cosine_proximity,
- keras.losses.logcosh,
- keras.losses.categorical_hinge]
-
-
-class KerasLossesTest(test.TestCase):
-
- def test_objective_shapes_3d(self):
- with self.test_session():
- y_a = keras.backend.variable(np.random.random((5, 6, 7)))
- y_b = keras.backend.variable(np.random.random((5, 6, 7)))
- for obj in ALL_LOSSES:
- objective_output = obj(y_a, y_b)
- self.assertListEqual(objective_output.get_shape().as_list(), [5, 6])
-
- def test_objective_shapes_2d(self):
- with self.test_session():
- y_a = keras.backend.variable(np.random.random((6, 7)))
- y_b = keras.backend.variable(np.random.random((6, 7)))
- for obj in ALL_LOSSES:
- objective_output = obj(y_a, y_b)
- self.assertListEqual(objective_output.get_shape().as_list(), [6,])
-
- def test_cce_one_hot(self):
- with self.test_session():
- y_a = keras.backend.variable(np.random.randint(0, 7, (5, 6)))
- y_b = keras.backend.variable(np.random.random((5, 6, 7)))
- objective_output = keras.losses.sparse_categorical_crossentropy(y_a, y_b)
- assert keras.backend.eval(objective_output).shape == (5, 6)
-
- y_a = keras.backend.variable(np.random.randint(0, 7, (6,)))
- y_b = keras.backend.variable(np.random.random((6, 7)))
- objective_output = keras.losses.sparse_categorical_crossentropy(y_a, y_b)
- assert keras.backend.eval(objective_output).shape == (6,)
-
- def test_serialization(self):
- fn = keras.losses.get('mse')
- config = keras.losses.serialize(fn)
- new_fn = keras.losses.deserialize(config)
- self.assertEqual(fn, new_fn)
-
- def test_categorical_hinge(self):
- y_pred = keras.backend.variable(np.array([[0.3, 0.2, 0.1],
- [0.1, 0.2, 0.7]]))
- y_true = keras.backend.variable(np.array([[0, 1, 0], [1, 0, 0]]))
- expected_loss = ((0.3 - 0.2 + 1) + (0.7 - 0.1 + 1)) / 2.0
- loss = keras.backend.eval(keras.losses.categorical_hinge(y_true, y_pred))
- self.assertAllClose(expected_loss, np.mean(loss))
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/metrics.py b/tensorflow/contrib/keras/python/keras/metrics.py
deleted file mode 100644
index 999e9cb9d4..0000000000
--- a/tensorflow/contrib/keras/python/keras/metrics.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Built-in Keras metrics functions.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import six
-
-from tensorflow.contrib.keras.python.keras import backend as K
-# pylint: disable=unused-import
-from tensorflow.contrib.keras.python.keras.losses import binary_crossentropy
-from tensorflow.contrib.keras.python.keras.losses import categorical_crossentropy
-from tensorflow.contrib.keras.python.keras.losses import cosine_proximity
-from tensorflow.contrib.keras.python.keras.losses import hinge
-from tensorflow.contrib.keras.python.keras.losses import kullback_leibler_divergence
-from tensorflow.contrib.keras.python.keras.losses import logcosh
-from tensorflow.contrib.keras.python.keras.losses import mean_absolute_error
-from tensorflow.contrib.keras.python.keras.losses import mean_absolute_percentage_error
-from tensorflow.contrib.keras.python.keras.losses import mean_squared_error
-from tensorflow.contrib.keras.python.keras.losses import mean_squared_logarithmic_error
-from tensorflow.contrib.keras.python.keras.losses import poisson
-from tensorflow.contrib.keras.python.keras.losses import sparse_categorical_crossentropy
-from tensorflow.contrib.keras.python.keras.losses import squared_hinge
-# pylint: disable=unused-import
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import deserialize_keras_object
-
-
-def binary_accuracy(y_true, y_pred):
- return K.mean(K.equal(y_true, K.round(y_pred)), axis=-1)
-
-
-def categorical_accuracy(y_true, y_pred):
- return K.cast(
- K.equal(K.argmax(y_true, axis=-1), K.argmax(y_pred, axis=-1)), K.floatx())
-
-
-def sparse_categorical_accuracy(y_true, y_pred):
- return K.cast(
- K.equal(
- K.max(y_true, axis=-1), K.cast(K.argmax(y_pred, axis=-1),
- K.floatx())), K.floatx())
-
-
-def top_k_categorical_accuracy(y_true, y_pred, k=5):
- return K.mean(K.in_top_k(y_pred, K.argmax(y_true, axis=-1), k), axis=-1)
-
-
-def sparse_top_k_categorical_accuracy(y_true, y_pred, k=5):
- return K.mean(K.in_top_k(y_pred,
- K.cast(K.max(y_true, axis=-1), 'int32'), k), axis=-1)
-
-
-# Aliases
-
-mse = MSE = mean_squared_error
-mae = MAE = mean_absolute_error
-mape = MAPE = mean_absolute_percentage_error
-msle = MSLE = mean_squared_logarithmic_error
-cosine = cosine_proximity
-
-
-def serialize(metric):
- return metric.__name__
-
-
-def deserialize(name, custom_objects=None):
- return deserialize_keras_object(
- name,
- module_objects=globals(),
- custom_objects=custom_objects,
- printable_module_name='metric function')
-
-
-def get(identifier):
- if isinstance(identifier, six.string_types):
- identifier = str(identifier)
- return deserialize(identifier)
- elif callable(identifier):
- return identifier
- else:
- raise ValueError('Could not interpret '
- 'metric function identifier:', identifier)
diff --git a/tensorflow/contrib/keras/python/keras/metrics_test.py b/tensorflow/contrib/keras/python/keras/metrics_test.py
deleted file mode 100644
index 84c6528174..0000000000
--- a/tensorflow/contrib/keras/python/keras/metrics_test.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for Keras metrics functions."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-class KerasMetricsTest(test.TestCase):
-
- def test_metrics(self):
- with self.test_session():
- y_a = keras.backend.variable(np.random.random((6, 7)))
- y_b = keras.backend.variable(np.random.random((6, 7)))
- for metric in [keras.metrics.binary_accuracy,
- keras.metrics.categorical_accuracy]:
- output = metric(y_a, y_b)
- self.assertEqual(keras.backend.eval(output).shape, (6,))
-
- def test_sparse_categorical_accuracy(self):
- with self.test_session():
- metric = keras.metrics.sparse_categorical_accuracy
- y_a = keras.backend.variable(np.random.randint(0, 7, (6,)))
- y_b = keras.backend.variable(np.random.random((6, 7)))
- self.assertEqual(keras.backend.eval(metric(y_a, y_b)).shape, (6,))
-
- def test_sparse_top_k_categorical_accuracy(self):
- with self.test_session():
- y_pred = keras.backend.variable(np.array([[0.3, 0.2, 0.1],
- [0.1, 0.2, 0.7]]))
- y_true = keras.backend.variable(np.array([[1], [0]]))
- result = keras.backend.eval(
- keras.metrics.sparse_top_k_categorical_accuracy(y_true, y_pred, k=3))
- self.assertEqual(result, 1)
- result = keras.backend.eval(
- keras.metrics.sparse_top_k_categorical_accuracy(y_true, y_pred, k=2))
- self.assertEqual(result, 0.5)
- result = keras.backend.eval(
- keras.metrics.sparse_top_k_categorical_accuracy(y_true, y_pred, k=1))
- self.assertEqual(result, 0.)
-
- def test_top_k_categorical_accuracy(self):
- with self.test_session():
- y_pred = keras.backend.variable(np.array([[0.3, 0.2, 0.1],
- [0.1, 0.2, 0.7]]))
- y_true = keras.backend.variable(np.array([[0, 1, 0], [1, 0, 0]]))
- result = keras.backend.eval(
- keras.metrics.top_k_categorical_accuracy(y_true, y_pred, k=3))
- self.assertEqual(result, 1)
- result = keras.backend.eval(
- keras.metrics.top_k_categorical_accuracy(y_true, y_pred, k=2))
- self.assertEqual(result, 0.5)
- result = keras.backend.eval(
- keras.metrics.top_k_categorical_accuracy(y_true, y_pred, k=1))
- self.assertEqual(result, 0.)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/models.py b/tensorflow/contrib/keras/python/keras/models.py
deleted file mode 100644
index ff06782a44..0000000000
--- a/tensorflow/contrib/keras/python/keras/models.py
+++ /dev/null
@@ -1,1458 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-# pylint: disable=protected-access
-"""Home of the Sequential model, and the `save_model`/`load_model` functions.
-"""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import copy
-import json
-import os
-
-import numpy as np
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras import layers as layer_module
-from tensorflow.contrib.keras.python.keras import optimizers
-from tensorflow.contrib.keras.python.keras.engine import topology
-from tensorflow.contrib.keras.python.keras.engine.topology import Input
-from tensorflow.contrib.keras.python.keras.engine.topology import Layer
-from tensorflow.contrib.keras.python.keras.engine.topology import TFBaseLayer
-from tensorflow.contrib.keras.python.keras.engine.training import Model
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import has_arg
-from tensorflow.contrib.keras.python.keras.utils.io_utils import ask_to_proceed_with_overwrite
-from tensorflow.python.framework import ops
-from tensorflow.python.platform import tf_logging as logging
-
-
-# pylint: disable=g-import-not-at-top
-try:
- import h5py
-except ImportError:
- h5py = None
-
-try:
- import yaml
-except ImportError:
- yaml = None
-# pylint: enable=g-import-not-at-top
-
-
-def save_model(model, filepath, overwrite=True, include_optimizer=True):
- """Save a model to a HDF5 file.
-
- The saved model contains:
- - the model's configuration (topology)
- - the model's weights
- - the model's optimizer's state (if any)
-
- Thus the saved model can be reinstantiated in
- the exact same state, without any of the code
- used for model definition or training.
-
- Arguments:
- model: Keras model instance to be saved.
- filepath: String, path where to save the model.
- overwrite: Whether we should overwrite any existing
- model at the target location, or instead
- ask the user with a manual prompt.
- include_optimizer: If True, save optimizer's state together.
-
- Raises:
- ImportError: if h5py is not available.
- """
-
- if h5py is None:
- raise ImportError('`save_model` requires h5py.')
-
- def get_json_type(obj):
- """Serialize any object to a JSON-serializable structure.
-
- Arguments:
- obj: the object to serialize
-
- Returns:
- JSON-serializable structure representing `obj`.
-
- Raises:
- TypeError: if `obj` cannot be serialized.
- """
- # if obj is a serializable Keras class instance
- # e.g. optimizer, layer
- if hasattr(obj, 'get_config'):
- return {'class_name': obj.__class__.__name__, 'config': obj.get_config()}
-
- # if obj is any numpy type
- if type(obj).__module__ == np.__name__:
- if isinstance(obj, np.ndarray):
- return {'type': type(obj), 'value': obj.tolist()}
- else:
- return obj.item()
-
- # misc functions (e.g. loss function)
- if callable(obj):
- return obj.__name__
-
- # if obj is a python 'type'
- if type(obj).__name__ == type.__name__:
- return obj.__name__
-
- raise TypeError('Not JSON Serializable:', obj)
-
- from tensorflow.contrib.keras.python.keras import __version__ as keras_version # pylint: disable=g-import-not-at-top
-
- # If file exists and should not be overwritten.
- if not overwrite and os.path.isfile(filepath):
- proceed = ask_to_proceed_with_overwrite(filepath)
- if not proceed:
- return
-
- with h5py.File(filepath, mode='w') as f:
- f.attrs['keras_version'] = str(keras_version).encode('utf8')
- f.attrs['backend'] = K.backend().encode('utf8')
- f.attrs['model_config'] = json.dumps(
- {
- 'class_name': model.__class__.__name__,
- 'config': model.get_config()
- },
- default=get_json_type).encode('utf8')
-
- model_weights_group = f.create_group('model_weights')
- model_layers = model.layers
- topology.save_weights_to_hdf5_group(model_weights_group, model_layers)
-
- if include_optimizer and hasattr(model, 'optimizer'):
- if isinstance(model.optimizer, optimizers.TFOptimizer):
- logging.warning(
- 'TensorFlow optimizers do not '
- 'make it possible to access '
- 'optimizer attributes or optimizer state '
- 'after instantiation. '
- 'As a result, we cannot save the optimizer '
- 'as part of the model save file.'
- 'You will have to compile your model again after loading it. '
- 'Prefer using a Keras optimizer instead '
- '(see keras.io/optimizers).')
- else:
- f.attrs['training_config'] = json.dumps(
- {
- 'optimizer_config': {
- 'class_name': model.optimizer.__class__.__name__,
- 'config': model.optimizer.get_config()
- },
- 'loss': model.loss,
- 'metrics': model.metrics,
- 'sample_weight_mode': model.sample_weight_mode,
- 'loss_weights': model.loss_weights,
- },
- default=get_json_type).encode('utf8')
-
- # Save optimizer weights.
- symbolic_weights = getattr(model.optimizer, 'weights')
- if symbolic_weights:
- optimizer_weights_group = f.create_group('optimizer_weights')
- weight_values = K.batch_get_value(symbolic_weights)
- weight_names = []
- for w, val in zip(symbolic_weights, weight_values):
- name = str(w.name)
- weight_names.append(name.encode('utf8'))
- optimizer_weights_group.attrs['weight_names'] = weight_names
- for name, val in zip(weight_names, weight_values):
- param_dset = optimizer_weights_group.create_dataset(
- name, val.shape, dtype=val.dtype)
- if not val.shape:
- # scalar
- param_dset[()] = val
- else:
- param_dset[:] = val
- f.flush()
-
-
-def load_model(filepath, custom_objects=None, compile=True): # pylint: disable=redefined-builtin
- """Loads a model saved via `save_model`.
-
- Arguments:
- filepath: String, path to the saved model.
- custom_objects: Optional dictionary mapping names
- (strings) to custom classes or functions to be
- considered during deserialization.
- compile: Boolean, whether to compile the model
- after loading.
-
- Returns:
- A Keras model instance. If an optimizer was found
- as part of the saved model, the model is already
- compiled. Otherwise, the model is uncompiled and
- a warning will be displayed. When `compile` is set
- to False, the compilation is omitted without any
- warning.
-
- Raises:
- ImportError: if h5py is not available.
- ValueError: In case of an invalid savefile.
- """
- if h5py is None:
- raise ImportError('`load_model` requires h5py.')
-
- if not custom_objects:
- custom_objects = {}
-
- def convert_custom_objects(obj):
- """Handles custom object lookup.
-
- Arguments:
- obj: object, dict, or list.
-
- Returns:
- The same structure, where occurrences
- of a custom object name have been replaced
- with the custom object.
- """
- if isinstance(obj, list):
- deserialized = []
- for value in obj:
- deserialized.append(convert_custom_objects(value))
- return deserialized
- if isinstance(obj, dict):
- deserialized = {}
- for key, value in obj.items():
- deserialized[key] = convert_custom_objects(value)
- return deserialized
- if obj in custom_objects:
- return custom_objects[obj]
- return obj
-
- with h5py.File(filepath, mode='r') as f:
- # instantiate model
- model_config = f.attrs.get('model_config')
- if model_config is None:
- raise ValueError('No model found in config file.')
- model_config = json.loads(model_config.decode('utf-8'))
- model = model_from_config(model_config, custom_objects=custom_objects)
-
- # set weights
- topology.load_weights_from_hdf5_group(f['model_weights'], model.layers)
-
- # Early return if compilation is not required.
- if not compile:
- return model
-
- # instantiate optimizer
- training_config = f.attrs.get('training_config')
- if training_config is None:
- logging.warning('No training configuration found in save file: '
- 'the model was *not* compiled. Compile it manually.')
- return model
- training_config = json.loads(training_config.decode('utf-8'))
- optimizer_config = training_config['optimizer_config']
- optimizer = optimizers.deserialize(
- optimizer_config, custom_objects=custom_objects)
-
- # Recover loss functions and metrics.
- loss = convert_custom_objects(training_config['loss'])
- metrics = convert_custom_objects(training_config['metrics'])
- sample_weight_mode = training_config['sample_weight_mode']
- loss_weights = training_config['loss_weights']
-
- # Compile model.
- model.compile(
- optimizer=optimizer,
- loss=loss,
- metrics=metrics,
- loss_weights=loss_weights,
- sample_weight_mode=sample_weight_mode)
-
- # Set optimizer weights.
- if 'optimizer_weights' in f:
- # Build train function (to get weight updates).
- if isinstance(model, Sequential):
- model.model._make_train_function()
- else:
- model._make_train_function()
- optimizer_weights_group = f['optimizer_weights']
- optimizer_weight_names = [
- n.decode('utf8')
- for n in optimizer_weights_group.attrs['weight_names']
- ]
- optimizer_weight_values = [
- optimizer_weights_group[n] for n in optimizer_weight_names
- ]
- try:
- model.optimizer.set_weights(optimizer_weight_values)
- except ValueError:
- logging.warning('Error in loading the saved optimizer '
- 'state. As a result, your model is '
- 'starting with a freshly initialized '
- 'optimizer.')
- return model
-
-
-def model_from_config(config, custom_objects=None):
- """Instantiates a Keras model from its config.
-
- Arguments:
- config: Configuration dictionary.
- custom_objects: Optional dictionary mapping names
- (strings) to custom classes or functions to be
- considered during deserialization.
-
- Returns:
- A Keras model instance (uncompiled).
-
- Raises:
- TypeError: if `config` is not a dictionary.
- """
- if isinstance(config, list):
- raise TypeError('`model_from_config` expects a dictionary, not a list. '
- 'Maybe you meant to use '
- '`Sequential.from_config(config)`?')
- return layer_module.deserialize(config, custom_objects=custom_objects)
-
-
-def model_from_yaml(yaml_string, custom_objects=None):
- """Parses a yaml model configuration file and returns a model instance.
-
- Arguments:
- yaml_string: YAML string encoding a model configuration.
- custom_objects: Optional dictionary mapping names
- (strings) to custom classes or functions to be
- considered during deserialization.
-
- Returns:
- A Keras model instance (uncompiled).
-
- Raises:
- ImportError: if yaml module is not found.
- """
- if yaml is None:
- raise ImportError('Requires yaml module installed.')
- config = yaml.load(yaml_string)
- return layer_module.deserialize(config, custom_objects=custom_objects)
-
-
-def model_from_json(json_string, custom_objects=None):
- """Parses a JSON model configuration file and returns a model instance.
-
- Arguments:
- json_string: JSON string encoding a model configuration.
- custom_objects: Optional dictionary mapping names
- (strings) to custom classes or functions to be
- considered during deserialization.
-
- Returns:
- A Keras model instance (uncompiled).
- """
- config = json.loads(json_string)
- return layer_module.deserialize(config, custom_objects=custom_objects)
-
-
-class Sequential(Model):
- """Linear stack of layers.
-
- Arguments:
- layers: list of layers to add to the model.
-
- # Note
- The first layer passed to a Sequential model
- should have a defined input shape. What that
- means is that it should have received an `input_shape`
- or `batch_input_shape` argument,
- or for some type of layers (recurrent, Dense...)
- an `input_dim` argument.
-
- Example:
-
- ```python
- model = Sequential()
- # first layer must have a defined input shape
- model.add(Dense(32, input_dim=500))
- # afterwards, Keras does automatic shape inference
- model.add(Dense(32))
-
- # also possible (equivalent to the above):
- model = Sequential()
- model.add(Dense(32, input_shape=(500,)))
- model.add(Dense(32))
-
- # also possible (equivalent to the above):
- model = Sequential()
- # here the batch dimension is None,
- # which means any batch size will be accepted by the model.
- model.add(Dense(32, batch_input_shape=(None, 500)))
- model.add(Dense(32))
- ```
- """
-
- def __init__(self, layers=None, name=None):
- self.layers = [] # Stack of layers.
- self.model = None # Internal Model instance.
- self.inputs = [] # List of input tensors
- self.outputs = [] # List of length 1: the output tensor (unique).
- self._trainable = True
- self._initial_weights = None
- self._input_layers = []
-
- # Model attributes.
- self.inbound_nodes = []
- self.outbound_nodes = []
- self.built = False
-
- # Set model name.
- if not name:
- prefix = 'sequential_'
- name = prefix + str(K.get_uid(prefix))
- self.name = name
-
- # The following properties are not actually used by Keras;
- # they exist for compatibility with TF's variable scoping mechanism.
- self._updates = []
- self._losses = []
- self._scope = None
- self._reuse = None
- self._base_name = name
- self._graph = ops.get_default_graph()
-
- # Add to the model any layers passed to the constructor.
- if layers:
- for layer in layers:
- self.add(layer)
-
- def add(self, layer):
- """Adds a layer instance on top of the layer stack.
-
- Arguments:
- layer: layer instance.
-
- Raises:
- TypeError: If `layer` is not a layer instance.
- ValueError: In case the `layer` argument does not
- know its input shape.
- ValueError: In case the `layer` argument has
- multiple output tensors, or is already connected
- somewhere else (forbidden in `Sequential` models).
- """
- if not isinstance(layer, (Layer, TFBaseLayer)):
- raise TypeError('The added layer must be '
- 'an instance of class Layer. '
- 'Found: ' + str(layer))
- if not self.outputs:
- # first layer in model: check that it is an input layer
- if not layer.inbound_nodes:
- # create an input layer
- if not hasattr(layer, 'batch_input_shape'):
- raise ValueError('The first layer in a '
- 'Sequential model must '
- 'get an `input_shape` or '
- '`batch_input_shape` argument.')
- # Instantiate the input layer.
- x = Input(
- batch_shape=layer.batch_input_shape,
- dtype=layer.dtype,
- name=layer.name + '_input')
- # This will build the current layer
- # and create the node connecting the current layer
- # to the input layer we just created.
- layer(x)
-
- if len(layer.inbound_nodes) != 1:
- raise ValueError('A layer added to a Sequential model must '
- 'not already be connected somewhere else. '
- 'Model received layer ' + layer.name + ' which has ' +
- str(len(layer.inbound_nodes)) +
- ' pre-existing inbound connections.')
-
- if len(layer.inbound_nodes[0].output_tensors) != 1:
- raise ValueError('All layers in a Sequential model '
- 'should have a single output tensor. '
- 'For multi-output layers, '
- 'use the functional API.')
-
- self.outputs = [layer.inbound_nodes[0].output_tensors[0]]
- self.inputs = topology.get_source_inputs(self.outputs[0])
-
- # We create an input node, which we will keep updated
- # as we add more layers
- topology.Node(
- outbound_layer=self,
- inbound_layers=[],
- node_indices=[],
- tensor_indices=[],
- input_tensors=self.inputs,
- output_tensors=self.outputs)
- else:
- output_tensor = layer(self.outputs[0])
- if isinstance(output_tensor, list):
- raise TypeError('All layers in a Sequential model '
- 'should have a single output tensor. '
- 'For multi-output layers, '
- 'use the functional API.')
- self.outputs = [output_tensor]
- # update self.inbound_nodes
- self.inbound_nodes[0].output_tensors = self.outputs
- self.inbound_nodes[0].output_shapes = [K.int_shape(self.outputs[0])]
-
- self.layers.append(layer)
- self.built = False
-
- def pop(self):
- """Removes the last layer in the model.
-
- Raises:
- TypeError: if there are no layers in the model.
- """
- if not self.layers:
- raise TypeError('There are no layers in the model.')
-
- self.layers.pop()
- if not self.layers:
- self.outputs = []
- self.inbound_nodes = []
- self.outbound_nodes = []
- else:
- self.layers[-1].outbound_nodes = []
- self.outputs = [self.layers[-1].output]
- # update self.inbound_nodes
- self.inbound_nodes[0].output_tensors = self.outputs
- self.inbound_nodes[0].output_shapes = [K.int_shape(self.outputs[0])]
- self.built = False
-
- def get_layer(self, name=None, index=None):
- """Retrieve a layer that is part of the model.
-
- Returns a layer based on either its name (unique)
- or its index in the graph. Indices are based on
- order of horizontal graph traversal (bottom-up).
-
- Arguments:
- name: string, name of layer.
- index: integer, index of layer.
-
- Returns:
- A layer instance.
- """
- if not self.built:
- self.build()
- return self.model.get_layer(name, index)
-
- def call(self, inputs, mask=None):
- if not self.built:
- self.build()
- return self.model.call(inputs, mask)
-
- def build(self, input_shape=None):
- if not self.inputs or not self.outputs:
- raise TypeError('Sequential model cannot be built: model is empty.'
- ' Add some layers first.')
- # actually create the model
- self.model = Model(self.inputs, self.outputs[0], name=self.name + '_model')
- self.model.trainable = self.trainable
-
- # mirror model attributes
- self.supports_masking = self.model.supports_masking
- self._output_mask_cache = self.model._output_mask_cache
- self._output_tensor_cache = self.model._output_tensor_cache
- self._output_shape_cache = self.model._output_shape_cache
- self._input_layers = self.model._input_layers
- self._output_layers = self.model._output_layers
- self._input_coordinates = self.model._input_coordinates
- self._output_coordinates = self.model._output_coordinates
- self._nodes_by_depth = self.model._nodes_by_depth
- self._network_nodes = self.model._network_nodes
- self.output_names = self.model.output_names
- self.input_names = self.model.input_names
- self._feed_input_names = self.model._feed_input_names
- self._feed_inputs = self.model._feed_inputs
-
- # Make sure child model callbacks
- # will call the parent Sequential model.
- self.model.callback_model = self
-
- self.built = True
-
- @property
- def uses_learning_phase(self):
- if not self.built:
- self.build()
- return self.model.uses_learning_phase
-
- def _gather_list_attr(self, attr):
- all_attrs = []
- for layer in self.layers:
- all_attrs += getattr(layer, attr, [])
- return all_attrs
-
- @property
- def trainable(self):
- return self._trainable
-
- @trainable.setter
- def trainable(self, value):
- if self.model:
- self.model.trainable = value
- self._trainable = value
-
- @property
- def trainable_weights(self):
- if not self.trainable:
- return []
- return self._gather_list_attr('trainable_weights')
-
- @property
- def non_trainable_weights(self):
- weights = self._gather_list_attr('non_trainable_weights')
- if not self.trainable:
- trainable_weights = self._gather_list_attr('trainable_weights')
- return trainable_weights + weights
- return weights
-
- @property
- def updates(self):
- if not self.built:
- self.build()
- return self.model.updates
-
- @property
- def state_updates(self):
- if not self.built:
- self.build()
- return self.model.state_updates
-
- def get_updates_for(self, inputs):
- if not self.built:
- self.build()
- return self.model.get_updates_for(inputs)
-
- @property
- def losses(self):
- if not self.built:
- self.build()
- return self.model.losses
-
- def get_losses_for(self, inputs):
- if not self.built:
- self.build()
- return self.model.get_losses_for(inputs)
-
- @property
- def regularizers(self):
- if not self.built:
- self.build()
- return self.model.regularizers
-
- def get_weights(self):
- """Retrieves the weights of the model.
-
- Returns:
- A flat list of Numpy arrays
- (one array per model weight).
- """
- if not self.built:
- self.build()
- return self.model.get_weights()
-
- def set_weights(self, weights):
- """Sets the weights of the model.
-
- Arguments:
- weights: Should be a list
- of Numpy arrays with shapes and types matching
- the output of `model.get_weights()`.
- """
- if not self.built:
- self.build()
- self.model.set_weights(weights)
-
- def load_weights(self, filepath, by_name=False):
- if h5py is None:
- raise ImportError('`load_weights` requires h5py.')
- f = h5py.File(filepath, mode='r')
- if 'layer_names' not in f.attrs and 'model_weights' in f:
- f = f['model_weights']
- layers = self.layers
- if by_name:
- topology.load_weights_from_hdf5_group_by_name(f, layers)
- else:
- topology.load_weights_from_hdf5_group(f, layers)
- if hasattr(f, 'close'):
- f.close()
-
- def save_weights(self, filepath, overwrite=True):
- if h5py is None:
- raise ImportError('`save_weights` requires h5py.')
- # If file exists and should not be overwritten:
- if not overwrite and os.path.isfile(filepath):
- proceed = ask_to_proceed_with_overwrite(filepath)
- if not proceed:
- return
- layers = self.layers
- f = h5py.File(filepath, 'w')
- topology.save_weights_to_hdf5_group(f, layers)
- f.flush()
- f.close()
-
- def compile(self,
- optimizer,
- loss,
- metrics=None,
- sample_weight_mode=None,
- weighted_metrics=None,
- **kwargs):
- """Configures the learning process.
-
- Arguments:
- optimizer: str (name of optimizer) or optimizer object.
- See [optimizers](/optimizers).
- loss: str (name of objective function) or objective function.
- See [losses](/losses).
- metrics: list of metrics to be evaluated by the model
- during training and testing.
- Typically you will use `metrics=['accuracy']`.
- See [metrics](/metrics).
- sample_weight_mode: if you need to do timestep-wise
- sample weighting (2D weights), set this to "temporal".
- "None" defaults to sample-wise weights (1D).
- weighted_metrics: list of metrics to be evaluated and weighted
- by `sample_weight` or `class_weight` during training and testing.
- **kwargs: These are passed into `tf.Session.run`.
-
- Example:
- ```python
- model = Sequential()
- model.add(Dense(32, input_shape=(500,)))
- model.add(Dense(10, activation='softmax'))
- model.compile(optimizer='rmsprop',
- loss='categorical_crossentropy',
- metrics=['accuracy'])
- ```
- """
- # create the underlying model
- self.build()
- # call compile method of Model class
- self.model.compile(
- optimizer,
- loss,
- metrics=metrics,
- sample_weight_mode=sample_weight_mode,
- weighted_metrics=weighted_metrics,
- **kwargs)
- self.optimizer = self.model.optimizer
- self.loss = self.model.loss
- self.total_loss = self.model.total_loss
- self.loss_weights = self.model.loss_weights
- self.metrics = self.model.metrics
- self.weighted_metrics = self.model.weighted_metrics
- self.metrics_tensors = self.model.metrics_tensors
- self.metrics_names = self.model.metrics_names
- self.sample_weight_mode = self.model.sample_weight_mode
- self.sample_weights = self.model.sample_weights
- self.targets = self.model.targets
-
- def fit(self,
- x,
- y,
- batch_size=32,
- epochs=10,
- verbose=1,
- callbacks=None,
- validation_split=0.,
- validation_data=None,
- shuffle=True,
- class_weight=None,
- sample_weight=None,
- initial_epoch=0):
- """Trains the model for a fixed number of epochs.
-
- Arguments:
- x: input data, as a Numpy array or list of Numpy arrays
- (if the model has multiple inputs).
- y: labels, as a Numpy array.
- batch_size: integer. Number of samples per gradient update.
- epochs: integer, the number of epochs to train the model.
- verbose: 0 for no logging to stdout,
- 1 for progress bar logging, 2 for one log line per epoch.
- callbacks: list of `keras.callbacks.Callback` instances.
- List of callbacks to apply during training.
- See [callbacks](/callbacks).
- validation_split: float (0. < x < 1).
- Fraction of the data to use as held-out validation data.
- validation_data: tuple (x_val, y_val) or tuple
- (x_val, y_val, val_sample_weights) to be used as held-out
- validation data. Will override validation_split.
- shuffle: boolean or str (for 'batch').
- Whether to shuffle the samples at each epoch.
- 'batch' is a special option for dealing with the
- limitations of HDF5 data; it shuffles in batch-sized chunks.
- class_weight: dictionary mapping classes to a weight value,
- used for scaling the loss function (during training only).
- sample_weight: Numpy array of weights for
- the training samples, used for scaling the loss function
- (during training only). You can either pass a flat (1D)
- Numpy array with the same length as the input samples
- (1:1 mapping between weights and samples),
- or in the case of temporal data,
- you can pass a 2D array with shape (samples, sequence_length),
- to apply a different weight to every timestep of every sample.
- In this case you should make sure to specify
- sample_weight_mode="temporal" in compile().
- initial_epoch: epoch at which to start training
- (useful for resuming a previous training run)
-
- Returns:
- A `History` object. Its `History.history` attribute is
- a record of training loss values and metrics values
- at successive epochs, as well as validation loss values
- and validation metrics values (if applicable).
-
- Raises:
- RuntimeError: if the model was never compiled.
- """
- if not self.built:
- raise RuntimeError('The model needs to be compiled ' 'before being used.')
- return self.model.fit(
- x,
- y,
- batch_size=batch_size,
- epochs=epochs,
- verbose=verbose,
- callbacks=callbacks,
- validation_split=validation_split,
- validation_data=validation_data,
- shuffle=shuffle,
- class_weight=class_weight,
- sample_weight=sample_weight,
- initial_epoch=initial_epoch)
-
- def evaluate(self, x, y, batch_size=32, verbose=1, sample_weight=None):
- """Computes the loss on some input data, batch by batch.
-
- Arguments:
- x: input data, as a Numpy array or list of Numpy arrays
- (if the model has multiple inputs).
- y: labels, as a Numpy array.
- batch_size: integer. Number of samples per gradient update.
- verbose: verbosity mode, 0 or 1.
- sample_weight: sample weights, as a Numpy array.
-
- Returns:
- Scalar test loss (if the model has no metrics)
- or list of scalars (if the model computes other metrics).
- The attribute `model.metrics_names` will give you
- the display labels for the scalar outputs.
-
- Raises:
- RuntimeError: if the model was never compiled.
- """
- if not self.built:
- raise RuntimeError('The model needs to be compiled ' 'before being used.')
- return self.model.evaluate(
- x,
- y,
- batch_size=batch_size,
- verbose=verbose,
- sample_weight=sample_weight)
-
- def predict(self, x, batch_size=32, verbose=0):
- """Generates output predictions for the input samples.
-
- The input samples are processed batch by batch.
-
- Arguments:
- x: the input data, as a Numpy array.
- batch_size: integer.
- verbose: verbosity mode, 0 or 1.
-
- Returns:
- A Numpy array of predictions.
- """
- if not self.built:
- self.build()
- return self.model.predict(x, batch_size=batch_size, verbose=verbose)
-
- def predict_on_batch(self, x):
- """Returns predictions for a single batch of samples.
-
- Arguments:
- x: input data, as a Numpy array or list of Numpy arrays
- (if the model has multiple inputs).
-
- Returns:
- A Numpy array of predictions.
- """
- if not self.built:
- self.build()
- return self.model.predict_on_batch(x)
-
- def train_on_batch(self, x, y, class_weight=None, sample_weight=None):
- """Single gradient update over one batch of samples.
-
- Arguments:
- x: input data, as a Numpy array or list of Numpy arrays
- (if the model has multiple inputs).
- y: labels, as a Numpy array.
- class_weight: dictionary mapping classes to a weight value,
- used for scaling the loss function (during training only).
- sample_weight: sample weights, as a Numpy array.
-
- Returns:
- Scalar training loss (if the model has no metrics)
- or list of scalars (if the model computes other metrics).
- The attribute `model.metrics_names` will give you
- the display labels for the scalar outputs.
-
- Raises:
- RuntimeError: if the model was never compiled.
- """
- if not self.built:
- raise RuntimeError('The model needs to be compiled ' 'before being used.')
- return self.model.train_on_batch(
- x, y, sample_weight=sample_weight, class_weight=class_weight)
-
- def test_on_batch(self, x, y, sample_weight=None):
- """Evaluates the model over a single batch of samples.
-
- Arguments:
- x: input data, as a Numpy array or list of Numpy arrays
- (if the model has multiple inputs).
- y: labels, as a Numpy array.
- sample_weight: sample weights, as a Numpy array.
-
- Returns:
- Scalar test loss (if the model has no metrics)
- or list of scalars (if the model computes other metrics).
- The attribute `model.metrics_names` will give you
- the display labels for the scalar outputs.
-
- Raises:
- RuntimeError: if the model was never compiled.
- """
- if not self.built:
- raise RuntimeError('The model needs to be compiled ' 'before being used.')
- return self.model.test_on_batch(x, y, sample_weight=sample_weight)
-
- def predict_proba(self, x, batch_size=32, verbose=1):
- """Generates class probability predictions for the input samples.
-
- The input samples are processed batch by batch.
-
- Arguments:
- x: input data, as a Numpy array or list of Numpy arrays
- (if the model has multiple inputs).
- batch_size: integer.
- verbose: verbosity mode, 0 or 1.
-
- Returns:
- A Numpy array of probability predictions.
- """
- preds = self.predict(x, batch_size, verbose)
- if preds.min() < 0. or preds.max() > 1.:
- logging.warning('Network returning invalid probability values. '
- 'The last layer might not normalize predictions '
- 'into probabilities '
- '(like softmax or sigmoid would).')
- return preds
-
- def predict_classes(self, x, batch_size=32, verbose=1):
- """Generate class predictions for the input samples.
-
- The input samples are processed batch by batch.
-
- Arguments:
- x: input data, as a Numpy array or list of Numpy arrays
- (if the model has multiple inputs).
- batch_size: integer.
- verbose: verbosity mode, 0 or 1.
-
- Returns:
- A numpy array of class predictions.
- """
- proba = self.predict(x, batch_size=batch_size, verbose=verbose)
- if proba.shape[-1] > 1:
- return proba.argmax(axis=-1)
- else:
- return (proba > 0.5).astype('int32')
-
- def fit_generator(self,
- generator,
- steps_per_epoch,
- epochs=1,
- verbose=1,
- callbacks=None,
- validation_data=None,
- validation_steps=None,
- class_weight=None,
- max_queue_size=10,
- workers=1,
- use_multiprocessing=False,
- initial_epoch=0,
- **kwargs):
- """Fits the model on data generated batch-by-batch by a Python generator.
-
- The generator is run in parallel to the model, for efficiency.
- For instance, this allows you to do real-time data augmentation
- on images on CPU in parallel to training your model on GPU.
-
- Arguments:
- generator: A generator.
- The output of the generator must be either
- - a tuple (inputs, targets)
- - a tuple (inputs, targets, sample_weights).
- All arrays should contain the same number of samples.
- The generator is expected to loop over its data
- indefinitely. An epoch finishes when `steps_per_epoch`
- batches have been seen by the model.
- steps_per_epoch: Total number of steps (batches of samples)
- to yield from `generator` before declaring one epoch
- finished and starting the next epoch. It should typically
- be equal to the number of unique samples of your dataset
- divided by the batch size.
- epochs: Integer, total number of iterations on the data.
- verbose: Verbosity mode, 0, 1, or 2.
- callbacks: List of callbacks to be called during training.
- validation_data: This can be either
- - A generator for the validation data
- - A tuple (inputs, targets)
- - A tuple (inputs, targets, sample_weights).
- validation_steps: Only relevant if `validation_data`
- is a generator.
- Number of steps to yield from validation generator
- at the end of every epoch. It should typically
- be equal to the number of unique samples of your
- validation dataset divided by the batch size.
- class_weight: Dictionary mapping class indices to a weight
- for the class.
- max_queue_size: Maximum size for the generator queue
- workers: Maximum number of processes to spin up
- use_multiprocessing: If True, use process based threading.
- Note that because
- this implementation relies on multiprocessing,
- you should not pass
- non picklable arguments to the generator
- as they can't be passed
- easily to children processes.
- initial_epoch: Epoch at which to start training
- (useful for resuming a previous training run)
- **kwargs: support for legacy arguments.
-
- Returns:
- A `History` object.
-
- Raises:
- RuntimeError: if the model was never compiled.
- ValueError: In case the generator yields
- data in an invalid format.
-
- Example:
-
- ```python
- def generate_arrays_from_file(path):
- while 1:
- f = open(path)
- for line in f:
- # create Numpy arrays of input data
- # and labels, from each line in the file
- x, y = process_line(line)
- yield (x, y)
- f.close()
-
- model.fit_generator(generate_arrays_from_file('/my_file.txt'),
- steps_per_epoch=1000, epochs=10)
- ```
- """
- # Legacy support
- if 'max_q_size' in kwargs:
- max_queue_size = kwargs.pop('max_q_size')
- logging.warning('The argument `max_q_size` has been renamed '
- '`max_queue_size`. Update your method calls accordingly.')
- if 'pickle_safe' in kwargs:
- use_multiprocessing = kwargs.pop('pickle_safe')
- logging.warning('The argument `pickle_safe` has been renamed '
- '`use_multiprocessing`. '
- 'Update your method calls accordingly.')
- if kwargs:
- raise ValueError('Unrecognized keyword arguments: ' + str(kwargs))
-
- if not self.built:
- raise RuntimeError('The model needs to be compiled ' 'before being used.')
- return self.model.fit_generator(
- generator,
- steps_per_epoch,
- epochs,
- verbose=verbose,
- callbacks=callbacks,
- validation_data=validation_data,
- validation_steps=validation_steps,
- class_weight=class_weight,
- max_queue_size=max_queue_size,
- workers=workers,
- use_multiprocessing=use_multiprocessing,
- initial_epoch=initial_epoch)
-
- def evaluate_generator(self,
- generator,
- steps,
- max_queue_size=10,
- workers=1,
- use_multiprocessing=False,
- **kwargs):
- """Evaluates the model on a data generator.
-
- The generator should return the same kind of data
- as accepted by `test_on_batch`.
-
- Arguments:
- generator: Generator yielding tuples (inputs, targets)
- or (inputs, targets, sample_weights)
- steps: Total number of steps (batches of samples)
- to yield from `generator` before stopping.
- max_queue_size: maximum size for the generator queue
- workers: maximum number of processes to spin up
- use_multiprocessing: if True, use process based threading.
- Note that because this implementation
- relies on multiprocessing, you should not pass
- non picklable arguments to the generator
- as they can't be passed easily to children processes.
- **kwargs: support for legacy arguments.
-
- Returns:
- Scalar test loss (if the model has no metrics)
- or list of scalars (if the model computes other metrics).
- The attribute `model.metrics_names` will give you
- the display labels for the scalar outputs.
-
- Raises:
- RuntimeError: if the model was never compiled.
- ValueError: In case the generator yields
- data in an invalid format.
- """
- # Legacy support
- if 'max_q_size' in kwargs:
- max_queue_size = kwargs.pop('max_q_size')
- logging.warning('The argument `max_q_size` has been renamed '
- '`max_queue_size`. Update your method calls accordingly.')
- if 'pickle_safe' in kwargs:
- use_multiprocessing = kwargs.pop('pickle_safe')
- logging.warning('The argument `pickle_safe` has been renamed '
- '`use_multiprocessing`. '
- 'Update your method calls accordingly.')
- if kwargs:
- raise ValueError('Unrecognized keyword arguments: ' + str(kwargs))
-
- if not self.built:
- raise RuntimeError('The model needs to be compiled ' 'before being used.')
- return self.model.evaluate_generator(
- generator,
- steps,
- max_queue_size=max_queue_size,
- workers=workers,
- use_multiprocessing=use_multiprocessing)
-
- def predict_generator(self,
- generator,
- steps,
- max_queue_size=10,
- workers=1,
- use_multiprocessing=False,
- verbose=0,
- **kwargs):
- """Generates predictions for the input samples from a data generator.
-
- The generator should return the same kind of data as accepted by
- `predict_on_batch`.
-
- Arguments:
- generator: generator yielding batches of input samples.
- steps: Total number of steps (batches of samples)
- to yield from `generator` before stopping.
- max_queue_size: maximum size for the generator queue
- workers: maximum number of processes to spin up
- use_multiprocessing: if True, use process based threading.
- Note that because this implementation
- relies on multiprocessing, you should not pass
- non picklable arguments to the generator
- as they can't be passed easily to children processes.
- verbose: verbosity mode, 0 or 1.
- **kwargs: support for legacy arguments.
-
- Returns:
- A Numpy array of predictions.
-
- Raises:
- ValueError: In case the generator yields
- data in an invalid format.
- """
- # Legacy support
- if 'max_q_size' in kwargs:
- max_queue_size = kwargs.pop('max_q_size')
- logging.warning('The argument `max_q_size` has been renamed '
- '`max_queue_size`. Update your method calls accordingly.')
- if 'pickle_safe' in kwargs:
- use_multiprocessing = kwargs.pop('pickle_safe')
- logging.warning('The argument `pickle_safe` has been renamed '
- '`use_multiprocessing`. '
- 'Update your method calls accordingly.')
- if kwargs:
- raise ValueError('Unrecognized keyword arguments: ' + str(kwargs))
-
- if not self.built:
- self.build()
- return self.model.predict_generator(
- generator,
- steps,
- max_queue_size=max_queue_size,
- workers=workers,
- use_multiprocessing=use_multiprocessing,
- verbose=verbose)
-
- def get_config(self):
- config = []
- for layer in self.layers:
- config.append({
- 'class_name': layer.__class__.__name__,
- 'config': layer.get_config()
- })
- return copy.deepcopy(config)
-
- @classmethod
- def from_config(cls, config, custom_objects=None):
- model = cls()
- for conf in config:
- layer = layer_module.deserialize(conf, custom_objects=custom_objects)
- model.add(layer)
- return model
-
-
-def _clone_functional_model(model, input_tensors=None):
- """Clone a functional `Model` instance.
-
- Model cloning is similar to calling a model on new inputs,
- except that it creates new layers (and thus new weights) instead
- of sharing the weights of the existing layers.
-
- Arguments:
- model: Instance of `Model`.
- input_tensors: optional list of input tensors
- to build the model upon. If not provided,
- placeholders will be created.
-
- Returns:
- An instance of `Model` reproducing the behavior
- of the original model, on top of new inputs tensors,
- using newly instantiated weights.
-
- Raises:
- ValueError: in case of invalid `model` argument value.
- """
- if not isinstance(model, Model):
- raise ValueError('Expected `model` argument '
- 'to be a `Model` instance, got ', model)
- if isinstance(model, Sequential):
- raise ValueError('Expected `model` argument '
- 'to be a functional `Model` instance, '
- 'got a `Sequential` instance instead:', model)
-
- layer_map = {} # Cache for created layers.
- tensor_map = {} # Map {reference_tensor: (corresponding_tensor, mask)}
- if input_tensors is None:
- # Create placeholders to build the model on top of.
- input_layers = []
- input_tensors = []
- for layer in model._input_layers:
- input_tensor = Input(
- batch_shape=layer.batch_input_shape,
- dtype=layer.dtype,
- sparse=layer.sparse,
- name=layer.name)
- input_tensors.append(input_tensor)
- # Cache newly created input layer.
- newly_created_input_layer = input_tensor._keras_history[0]
- layer_map[layer] = newly_created_input_layer
- for original_input_layer, cloned_input_layer in zip(model._input_layers,
- input_layers):
- layer_map[original_input_layer] = cloned_input_layer
- else:
- # Make sure that all input tensors come from a Keras layer.
- # If tensor comes from an input layer: cache the input layer.
- input_tensors = topology._to_list(input_tensors)
- input_tensors_ = []
- for i, x in enumerate(input_tensors):
- if not K.is_keras_tensor(x):
- name = model._input_layers[i].name
- input_tensor = Input(tensor=x, name='input_wrapper_for_' + name)
- input_tensors_.append(input_tensor)
- # Cache newly created input layer.
- original_input_layer = x._keras_history[0]
- newly_created_input_layer = input_tensor._keras_history[0]
- layer_map[original_input_layer] = newly_created_input_layer
- else:
- input_tensors_.append(x)
- input_tensors = input_tensors_
-
- for x, y in zip(model.inputs, input_tensors):
- tensor_map[x] = (y, None) # tensor, mask
-
- # Iterated over every node in the reference model, in depth order.
- depth_keys = list(model._nodes_by_depth.keys())
- depth_keys.sort(reverse=True)
- for depth in depth_keys:
- nodes = model._nodes_by_depth[depth]
- for node in nodes:
- # Recover the corresponding layer.
- layer = node.outbound_layer
-
- # Get or create layer.
- if layer not in layer_map:
- # Clone layer.
- new_layer = layer.__class__.from_config(layer.get_config())
- layer_map[layer] = new_layer
- layer = new_layer
- else:
- # Reuse previously cloned layer.
- layer = layer_map[layer]
- # Don't call InputLayer multiple times.
- if isinstance(layer, topology.InputLayer):
- continue
-
- # Gather inputs to call the new layer.
- referenceinput_tensors_ = node.input_tensors
- reference_output_tensors = node.output_tensors
-
- # If all previous input tensors are available in tensor_map,
- # then call node.inbound_layer on them.
- computed_data = [] # List of tuples (input, mask).
- for x in referenceinput_tensors_:
- if x in tensor_map:
- computed_data.append(tensor_map[x])
-
- if len(computed_data) == len(referenceinput_tensors_):
- # Call layer.
- if node.arguments:
- kwargs = node.arguments
- else:
- kwargs = {}
- if len(computed_data) == 1:
- computed_tensor, computed_mask = computed_data[0]
- if has_arg(layer.call, 'mask'):
- if 'mask' not in kwargs:
- kwargs['mask'] = computed_mask
- output_tensors = topology._to_list(layer(computed_tensor, **kwargs))
- output_masks = topology._to_list(
- layer.compute_mask(computed_tensor, computed_mask))
- computed_tensors = [computed_tensor]
- computed_masks = [computed_mask]
- else:
- computed_tensors = [x[0] for x in computed_data]
- computed_masks = [x[1] for x in computed_data]
- if has_arg(layer.call, 'mask'):
- if 'mask' not in kwargs:
- kwargs['mask'] = computed_masks
- output_tensors = topology._to_list(layer(computed_tensors, **kwargs))
- output_masks = topology._to_list(
- layer.compute_mask(computed_tensors, computed_masks))
- # Update tensor_map.
- for x, y, mask in zip(reference_output_tensors, output_tensors,
- output_masks):
- tensor_map[x] = (y, mask)
-
- # Check that we did compute the model outputs,
- # then instantiate a new model from inputs and outputs.
- output_tensors = []
- for x in model.outputs:
- assert x in tensor_map, 'Could not compute output ' + str(x)
- tensor, _ = tensor_map[x]
- output_tensors.append(tensor)
- return Model(input_tensors, output_tensors, name=model.name)
-
-
-def _clone_sequential_model(model, input_tensors=None):
- """Clone a `Sequential` model instance.
-
- Model cloning is similar to calling a model on new inputs,
- except that it creates new layers (and thus new weights) instead
- of sharing the weights of the existing layers.
-
- Arguments:
- model: Instance of `Sequential`.
- input_tensors: optional list of input tensors
- to build the model upon. If not provided,
- placeholders will be created.
-
- Returns:
- An instance of `Sequential` reproducing the behavior
- of the original model, on top of new inputs tensors,
- using newly instantiated weights.
-
- Raises:
- ValueError: in case of invalid `model` argument value.
- """
- if not isinstance(model, Sequential):
- raise ValueError('Expected `model` argument '
- 'to be a `Sequential` model instance, '
- 'but got:', model)
-
- def clone(layer):
- return layer.__class__.from_config(layer.get_config())
-
- layers = [clone(layer) for layer in model.layers]
- if input_tensors is None:
- return Sequential(layers=layers, name=model.name)
- else:
- if len(topology._to_list(input_tensors)) != 1:
- raise ValueError('To clone a `Sequential` model, we expect '
- ' at most one tensor '
- 'as part of `input_tensors`.')
- x = topology._to_list(input_tensors)[0]
- if K.is_keras_tensor(x):
- origin_layer = x._keras_history[0]
- if isinstance(origin_layer, topology.InputLayer):
- return Sequential(layers=[origin_layer] + layers, name=model.name)
- else:
- raise ValueError('Cannot clone a `Sequential` model on top '
- 'of a tensor that comes from a Keras layer '
- 'other than an `InputLayer`. '
- 'Use the functional API instead.')
- input_tensor = Input(tensor=x, name='input_wrapper_for_' + str(x.name))
- input_layer = input_tensor._keras_history[0]
- return Sequential(layers=[input_layer] + layers, name=model.name)
-
-
-def clone_model(model, input_tensors=None):
- """Clone any `Model` instance.
-
- Model cloning is similar to calling a model on new inputs,
- except that it creates new layers (and thus new weights) instead
- of sharing the weights of the existing layers.
-
- Arguments:
- model: Instance of `Model`
- (could be a functional model or a Sequential model).
- input_tensors: optional list of input tensors
- to build the model upon. If not provided,
- placeholders will be created.
-
- Returns:
- An instance of `Model` reproducing the behavior
- of the original model, on top of new inputs tensors,
- using newly instantiated weights.
-
- Raises:
- ValueError: in case of invalid `model` argument value.
- """
- if isinstance(model, Sequential):
- return _clone_sequential_model(model, input_tensors=input_tensors)
- else:
- return _clone_functional_model(model, input_tensors=input_tensors)
diff --git a/tensorflow/contrib/keras/python/keras/models_test.py b/tensorflow/contrib/keras/python/keras/models_test.py
deleted file mode 100644
index 1a4e6fb4c8..0000000000
--- a/tensorflow/contrib/keras/python/keras/models_test.py
+++ /dev/null
@@ -1,419 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for training routines."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import os
-import shutil
-import tempfile
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-from tensorflow.python.training import training as training_module
-
-try:
- import h5py # pylint:disable=g-import-not-at-top
-except ImportError:
- h5py = None
-
-
-class TestModelSaving(test.TestCase):
-
- def test_sequential_model_saving(self):
- if h5py is None:
- return # Skip test if models cannot be saved.
-
- with self.test_session():
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(2, input_shape=(3,)))
- model.add(keras.layers.RepeatVector(3))
- model.add(keras.layers.TimeDistributed(keras.layers.Dense(3)))
- model.compile(loss=keras.losses.MSE,
- optimizer=keras.optimizers.RMSprop(lr=0.0001),
- metrics=[keras.metrics.categorical_accuracy],
- sample_weight_mode='temporal')
- x = np.random.random((1, 3))
- y = np.random.random((1, 3, 3))
- model.train_on_batch(x, y)
-
- out = model.predict(x)
- _, fname = tempfile.mkstemp('.h5')
- keras.models.save_model(model, fname)
-
- new_model = keras.models.load_model(fname)
- os.remove(fname)
-
- out2 = new_model.predict(x)
- self.assertAllClose(out, out2, atol=1e-05)
-
- # test that new updates are the same with both models
- x = np.random.random((1, 3))
- y = np.random.random((1, 3, 3))
- model.train_on_batch(x, y)
- new_model.train_on_batch(x, y)
- out = model.predict(x)
- out2 = new_model.predict(x)
- self.assertAllClose(out, out2, atol=1e-05)
-
- def test_sequential_model_saving_2(self):
- if h5py is None:
- return # Skip test if models cannot be saved.
-
- with self.test_session():
- # test with custom optimizer, loss
-
- class CustomOp(keras.optimizers.RMSprop):
- pass
-
- def custom_loss(y_true, y_pred):
- return keras.losses.mse(y_true, y_pred)
-
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(2, input_shape=(3,)))
- model.add(keras.layers.Dense(3))
- model.compile(loss=custom_loss, optimizer=CustomOp(), metrics=['acc'])
-
- x = np.random.random((1, 3))
- y = np.random.random((1, 3))
- model.train_on_batch(x, y)
-
- out = model.predict(x)
- _, fname = tempfile.mkstemp('.h5')
- keras.models.save_model(model, fname)
-
- model = keras.models.load_model(
- fname,
- custom_objects={'CustomOp': CustomOp,
- 'custom_loss': custom_loss})
- os.remove(fname)
-
- out2 = model.predict(x)
- self.assertAllClose(out, out2, atol=1e-05)
-
- def test_functional_model_saving(self):
- if h5py is None:
- return # Skip test if models cannot be saved.
-
- with self.test_session():
- inputs = keras.layers.Input(shape=(3,))
- x = keras.layers.Dense(2)(inputs)
- output = keras.layers.Dense(3)(x)
-
- model = keras.models.Model(inputs, output)
- model.compile(loss=keras.losses.MSE,
- optimizer=keras.optimizers.RMSprop(lr=0.0001),
- metrics=[keras.metrics.categorical_accuracy])
- x = np.random.random((1, 3))
- y = np.random.random((1, 3))
- model.train_on_batch(x, y)
-
- out = model.predict(x)
- _, fname = tempfile.mkstemp('.h5')
- keras.models.save_model(model, fname)
-
- model = keras.models.load_model(fname)
- os.remove(fname)
-
- out2 = model.predict(x)
- self.assertAllClose(out, out2, atol=1e-05)
-
- def test_saving_without_compilation(self):
- if h5py is None:
- return # Skip test if models cannot be saved.
-
- with self.test_session():
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(2, input_shape=(3,)))
- model.add(keras.layers.Dense(3))
- model.compile(loss='mse', optimizer='sgd', metrics=['acc'])
-
- _, fname = tempfile.mkstemp('.h5')
- keras.models.save_model(model, fname)
- model = keras.models.load_model(fname)
- os.remove(fname)
-
- def test_saving_with_tf_optimizer(self):
- if h5py is None:
- return # Skip test if models cannot be saved.
-
- with self.test_session():
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(2, input_shape=(3,)))
- model.add(keras.layers.Dense(3))
- model.compile(loss='mse',
- optimizer=training_module.AdadeltaOptimizer(0.1),
- metrics=['acc'])
-
- _, fname = tempfile.mkstemp('.h5')
- keras.models.save_model(model, fname)
- model = keras.models.load_model(fname)
- os.remove(fname)
-
- def test_saving_right_after_compilation(self):
- if h5py is None:
- return # Skip test if models cannot be saved.
-
- with self.test_session():
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(2, input_shape=(3,)))
- model.add(keras.layers.Dense(3))
- model.compile(loss='mse', optimizer='sgd', metrics=['acc'])
- model.model._make_train_function()
-
- _, fname = tempfile.mkstemp('.h5')
- keras.models.save_model(model, fname)
- model = keras.models.load_model(fname)
- os.remove(fname)
-
- def test_saving_lambda_numpy_array_arguments(self):
- if h5py is None:
- return # Skip test if models cannot be saved.
-
- mean = np.random.random((4, 2, 3))
- std = np.abs(np.random.random((4, 2, 3))) + 1e-5
- inputs = keras.layers.Input(shape=(4, 2, 3))
- output = keras.layers.Lambda(lambda image, mu, std: (image - mu) / std,
- arguments={'mu': mean, 'std': std})(inputs)
- model = keras.models.Model(inputs, output)
- model.compile(loss='mse', optimizer='sgd', metrics=['acc'])
-
- _, fname = tempfile.mkstemp('.h5')
- keras.models.save_model(model, fname)
-
- model = keras.models.load_model(fname)
- os.remove(fname)
-
- self.assertAllClose(mean, model.layers[1].arguments['mu'])
- self.assertAllClose(std, model.layers[1].arguments['std'])
-
-
-class TestSequential(test.TestCase):
- """Most Sequential model API tests are covered in `training_test.py`.
- """
-
- def test_basic_methods(self):
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(1, input_dim=2))
- model.add(keras.layers.Dropout(0.3, name='dp'))
- model.add(keras.layers.Dense(2, kernel_regularizer='l2',
- kernel_constraint='max_norm'))
- model.build()
- self.assertEqual(model.state_updates, model.model.state_updates)
- self.assertEqual(model.get_layer(name='dp').name, 'dp')
-
- def test_sequential_pop(self):
- num_hidden = 5
- input_dim = 3
- batch_size = 5
- num_classes = 2
- with self.test_session():
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(num_hidden, input_dim=input_dim))
- model.add(keras.layers.Dense(num_classes))
- model.compile(loss='mse', optimizer='sgd')
- x = np.random.random((batch_size, input_dim))
- y = np.random.random((batch_size, num_classes))
- model.fit(x, y, epochs=1)
- model.pop()
- self.assertEqual(len(model.layers), 1)
- self.assertEqual(model.output_shape, (None, num_hidden))
- model.compile(loss='mse', optimizer='sgd')
- y = np.random.random((batch_size, num_hidden))
- model.fit(x, y, epochs=1)
-
- # Test popping single-layer model
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(num_hidden, input_dim=input_dim))
- model.pop()
- self.assertEqual(len(model.layers), 0)
- self.assertEqual(len(model.outputs), 0)
-
- # Invalid use case
- model = keras.models.Sequential()
- with self.assertRaises(TypeError):
- model.pop()
-
- def test_sequential_weight_loading(self):
- if h5py is None:
- return
-
- temp_dir = self.get_temp_dir()
- self.addCleanup(shutil.rmtree, temp_dir)
- h5_path = os.path.join(temp_dir, 'test.h5')
-
- num_hidden = 5
- input_dim = 3
- batch_size = 5
- num_classes = 2
-
- with self.test_session():
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(num_hidden, input_dim=input_dim))
- model.add(keras.layers.Dense(num_classes))
-
- x = np.random.random((batch_size, input_dim))
- ref_y = model.predict(x)
-
- model.save_weights(h5_path)
-
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(num_hidden, input_dim=input_dim))
- model.add(keras.layers.Dense(num_classes))
- model.load_weights(h5_path)
- y = model.predict(x)
-
- self.assertAllClose(y, ref_y)
-
- def test_invalid_use_cases(self):
- with self.test_session():
- # Added objects must be layer instances
- with self.assertRaises(TypeError):
- model = keras.models.Sequential()
- model.add(None)
-
- # Added layers must have an inputs shape
- with self.assertRaises(ValueError):
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(1))
-
- # Added layers cannot have multiple outputs
- class MyLayer(keras.layers.Layer):
-
- def call(self, inputs):
- return [3 * inputs, 2 * inputs]
-
- def _compute_output_shape(self, input_shape):
- return [input_shape, input_shape]
-
- with self.assertRaises(ValueError):
- model = keras.models.Sequential()
- model.add(MyLayer(input_shape=(3,)))
- with self.assertRaises(TypeError):
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(1, input_dim=1))
- model.add(MyLayer())
-
- # Building empty model
- model = keras.models.Sequential()
- with self.assertRaises(TypeError):
- model.build()
-
-
-class TestModelCloning(test.TestCase):
-
- def test_clone_sequential_model(self):
- with self.test_session():
- val_a = np.random.random((10, 4))
- val_out = np.random.random((10, 4))
-
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(4, input_shape=(4,)))
- model.add(keras.layers.Dropout(0.5))
- model.add(keras.layers.Dense(4))
-
- # Everything should work in a new session.
- keras.backend.clear_session()
-
- with self.test_session():
- # With placeholder creation
- new_model = keras.models.clone_model(model)
- new_model.compile('rmsprop', 'mse')
- new_model.train_on_batch(val_a, val_out)
-
- # On top of new tensor
- input_a = keras.Input(shape=(4,))
- new_model = keras.models.clone_model(
- model, input_tensors=input_a)
- new_model.compile('rmsprop', 'mse')
- new_model.train_on_batch(val_a, val_out)
-
- # On top of new, non-Keras tensor
- input_a = keras.backend.variable(val_a)
- new_model = keras.models.clone_model(
- model, input_tensors=input_a)
- new_model.compile('rmsprop', 'mse')
- new_model.train_on_batch(None, val_out)
-
- def test_clone_functional_model(self):
- with self.test_session():
- val_a = np.random.random((10, 4))
- val_b = np.random.random((10, 4))
- val_out = np.random.random((10, 4))
-
- input_a = keras.Input(shape=(4,))
- input_b = keras.Input(shape=(4,))
- dense_1 = keras.layers.Dense(4,)
- dense_2 = keras.layers.Dense(4,)
-
- x_a = dense_1(input_a)
- x_a = keras.layers.Dropout(0.5)(x_a)
- x_b = dense_1(input_b)
- x_a = dense_2(x_a)
- outputs = keras.layers.add([x_a, x_b])
- model = keras.models.Model([input_a, input_b], outputs)
-
- # Everything should work in a new session.
- keras.backend.clear_session()
-
- with self.test_session():
- # With placeholder creation
- new_model = keras.models.clone_model(model)
- new_model.compile('rmsprop', 'mse')
- new_model.train_on_batch([val_a, val_b], val_out)
-
- # On top of new tensors
- input_a = keras.Input(shape=(4,), name='a')
- input_b = keras.Input(shape=(4,), name='b')
- new_model = keras.models.clone_model(
- model, input_tensors=[input_a, input_b])
- new_model.compile('rmsprop', 'mse')
- new_model.train_on_batch([val_a, val_b], val_out)
-
- # On top of new, non-Keras tensors
- input_a = keras.backend.variable(val_a)
- input_b = keras.backend.variable(val_b)
- new_model = keras.models.clone_model(
- model, input_tensors=[input_a, input_b])
- new_model.compile('rmsprop', 'mse')
- new_model.train_on_batch(None, val_out)
-
- def test_model_cloning_invalid_use_cases(self):
- seq_model = keras.models.Sequential()
- seq_model.add(keras.layers.Dense(4, input_shape=(4,)))
-
- x = keras.Input((4,))
- y = keras.layers.Dense(4)(x)
- fn_model = keras.models.Model(x, y)
-
- with self.assertRaises(ValueError):
- keras.models._clone_functional_model(seq_model)
- with self.assertRaises(ValueError):
- keras.models._clone_functional_model(None)
- with self.assertRaises(ValueError):
- keras.models._clone_sequential_model(fn_model)
-
- with self.assertRaises(ValueError):
- keras.models._clone_sequential_model(seq_model, input_tensors=[x, x])
- with self.assertRaises(ValueError):
- keras.models._clone_sequential_model(seq_model, input_tensors=y)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/optimizers.py b/tensorflow/contrib/keras/python/keras/optimizers.py
deleted file mode 100644
index f137563d6d..0000000000
--- a/tensorflow/contrib/keras/python/keras/optimizers.py
+++ /dev/null
@@ -1,771 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Keras optimizer classes (will eventually be replaced with core optimizers).
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import copy
-
-import six
-from six.moves import zip # pylint: disable=redefined-builtin
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import deserialize_keras_object
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import serialize_keras_object
-from tensorflow.python.framework import dtypes as dtypes_module
-from tensorflow.python.framework import ops
-from tensorflow.python.ops import control_flow_ops
-from tensorflow.python.ops import math_ops
-from tensorflow.python.training import optimizer as tf_optimizer_module
-
-
-def clip_norm(g, c, n):
- """Clip a tensor by norm.
-
- Arguments:
- g: gradient tensor to clip.
- c: clipping threshold.
- n: norm of gradient tensor.
-
- Returns:
- Clipped gradient tensor.
- """
- if c > 0:
- condition = n >= c
- then_expression = lambda: math_ops.scalar_mul(c / n, g)
- else_expression = lambda: g
-
- # saving the shape to avoid converting sparse tensor to dense
- if isinstance(g, ops.Tensor):
- g_shape = copy.copy(g.get_shape())
- elif isinstance(g, ops.IndexedSlices):
- g_shape = copy.copy(g.dense_shape)
- if condition.dtype != dtypes_module.bool:
- condition = math_ops.cast(condition, 'bool')
- g = control_flow_ops.cond(condition, then_expression, else_expression)
- if isinstance(g, ops.Tensor):
- g.set_shape(g_shape)
- elif isinstance(g, ops.IndexedSlices):
- g._dense_shape = g_shape # pylint: disable=protected-access
- return g
-
-
-class Optimizer(object):
- """Abstract optimizer base class.
-
- Note: this is the parent class of all optimizers, not an actual optimizer
- that can be used for training models.
-
- All Keras optimizers support the following keyword arguments:
-
- clipnorm: float >= 0. Gradients will be clipped
- when their L2 norm exceeds this value.
- clipvalue: float >= 0. Gradients will be clipped
- when their absolute value exceeds this value.
- """
-
- def __init__(self, **kwargs):
- allowed_kwargs = {'clipnorm', 'clipvalue'}
- for k in kwargs:
- if k not in allowed_kwargs:
- raise TypeError('Unexpected keyword argument '
- 'passed to optimizer: ' + str(k))
- self.__dict__.update(kwargs)
- self.updates = []
- self.weights = []
-
- def get_updates(self, loss, params):
- raise NotImplementedError
-
- def get_gradients(self, loss, params):
- grads = K.gradients(loss, params)
- if hasattr(self, 'clipnorm') and self.clipnorm > 0:
- norm = K.sqrt(sum([K.sum(K.square(g)) for g in grads]))
- grads = [clip_norm(g, self.clipnorm, norm) for g in grads]
- if hasattr(self, 'clipvalue') and self.clipvalue > 0:
- grads = [K.clip(g, -self.clipvalue, self.clipvalue) for g in grads]
- return grads
-
- def set_weights(self, weights):
- """Sets the weights of the optimizer, from Numpy arrays.
-
- Should only be called after computing the gradients
- (otherwise the optimizer has no weights).
-
- Arguments:
- weights: a list of Numpy arrays. The number
- of arrays and their shape must match
- number of the dimensions of the weights
- of the optimizer (i.e. it should match the
- output of `get_weights`).
-
- Raises:
- ValueError: in case of incompatible weight shapes.
- """
- params = self.weights
- weight_value_tuples = []
- param_values = K.batch_get_value(params)
- for pv, p, w in zip(param_values, params, weights):
- if pv.shape != w.shape:
- raise ValueError('Optimizer weight shape ' + str(pv.shape) +
- ' not compatible with '
- 'provided weight shape ' + str(w.shape))
- weight_value_tuples.append((p, w))
- K.batch_set_value(weight_value_tuples)
-
- def get_weights(self):
- """Returns the current value of the weights of the optimizer.
-
- Returns:
- A list of numpy arrays.
- """
- return K.batch_get_value(self.weights)
-
- def get_config(self):
- config = {}
- if hasattr(self, 'clipnorm'):
- config['clipnorm'] = self.clipnorm
- if hasattr(self, 'clipvalue'):
- config['clipvalue'] = self.clipvalue
- return config
-
- @classmethod
- def from_config(cls, config):
- return cls(**config)
-
-
-class SGD(Optimizer):
- """Stochastic gradient descent optimizer.
-
- Includes support for momentum,
- learning rate decay, and Nesterov momentum.
-
- Arguments:
- lr: float >= 0. Learning rate.
- momentum: float >= 0. Parameter updates momentum.
- decay: float >= 0. Learning rate decay over each update.
- nesterov: boolean. Whether to apply Nesterov momentum.
- """
-
- def __init__(self, lr=0.01, momentum=0., decay=0., nesterov=False, **kwargs):
- super(SGD, self).__init__(**kwargs)
- with K.name_scope(self.__class__.__name__):
- self.iterations = K.variable(0, dtype='int64', name='iterations')
- self.lr = K.variable(lr, name='lr')
- self.momentum = K.variable(momentum, name='momentum')
- self.decay = K.variable(decay, name='decay')
- self.initial_decay = decay
- self.nesterov = nesterov
-
- def get_updates(self, loss, params):
- grads = self.get_gradients(loss, params)
- self.updates = [K.update_add(self.iterations, 1)]
-
- lr = self.lr
- if self.initial_decay > 0:
- lr *= (1. / (1. + self.decay * K.cast(self.iterations,
- K.dtype(self.decay))))
-
- # momentum
- shapes = [K.int_shape(p) for p in params]
- moments = [K.zeros(shape) for shape in shapes]
- self.weights = [self.iterations] + moments
- for p, g, m in zip(params, grads, moments):
- v = self.momentum * m - lr * g # velocity
- self.updates.append(K.update(m, v))
-
- if self.nesterov:
- new_p = p + self.momentum * v - lr * g
- else:
- new_p = p + v
-
- # Apply constraints.
- if getattr(p, 'constraint', None) is not None:
- new_p = p.constraint(new_p)
-
- self.updates.append(K.update(p, new_p))
- return self.updates
-
- def get_config(self):
- config = {
- 'lr': float(K.get_value(self.lr)),
- 'momentum': float(K.get_value(self.momentum)),
- 'decay': float(K.get_value(self.decay)),
- 'nesterov': self.nesterov
- }
- base_config = super(SGD, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class RMSprop(Optimizer):
- """RMSProp optimizer.
-
- It is recommended to leave the parameters of this optimizer
- at their default values
- (except the learning rate, which can be freely tuned).
-
- This optimizer is usually a good choice for recurrent
- neural networks.
-
- Arguments:
- lr: float >= 0. Learning rate.
- rho: float >= 0.
- epsilon: float >= 0. Fuzz factor.
- decay: float >= 0. Learning rate decay over each update.
- """
-
- def __init__(self, lr=0.001, rho=0.9, epsilon=1e-8, decay=0., **kwargs):
- super(RMSprop, self).__init__(**kwargs)
- with K.name_scope(self.__class__.__name__):
- self.lr = K.variable(lr, name='lr')
- self.rho = K.variable(rho, name='rho')
- self.decay = K.variable(decay, name='decay')
- self.iterations = K.variable(0, dtype='int64', name='iterations')
- self.epsilon = epsilon
- self.initial_decay = decay
-
- def get_updates(self, loss, params):
- grads = self.get_gradients(loss, params)
- accumulators = [
- K.zeros(K.int_shape(p), dtype=K.dtype(p)) for p in params
- ]
- self.weights = accumulators
- self.updates = [K.update_add(self.iterations, 1)]
-
- lr = self.lr
- if self.initial_decay > 0:
- lr *= (1. / (1. + self.decay * K.cast(self.iterations,
- K.dtype(self.decay))))
-
- for p, g, a in zip(params, grads, accumulators):
- # update accumulator
- new_a = self.rho * a + (1. - self.rho) * K.square(g)
- self.updates.append(K.update(a, new_a))
- new_p = p - lr * g / (K.sqrt(new_a) + self.epsilon)
-
- # Apply constraints.
- if getattr(p, 'constraint', None) is not None:
- new_p = p.constraint(new_p)
-
- self.updates.append(K.update(p, new_p))
- return self.updates
-
- def get_config(self):
- config = {
- 'lr': float(K.get_value(self.lr)),
- 'rho': float(K.get_value(self.rho)),
- 'decay': float(K.get_value(self.decay)),
- 'epsilon': self.epsilon
- }
- base_config = super(RMSprop, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Adagrad(Optimizer):
- """Adagrad optimizer.
-
- It is recommended to leave the parameters of this optimizer
- at their default values.
-
- Arguments:
- lr: float >= 0. Learning rate.
- epsilon: float >= 0.
- decay: float >= 0. Learning rate decay over each update.
-
- References:
- - [Adaptive Subgradient Methods for Online Learning and Stochastic
- Optimization](http://www.jmlr.org/papers/volume12/duchi11a/duchi11a.pdf)
- """
-
- def __init__(self, lr=0.01, epsilon=1e-8, decay=0., **kwargs):
- super(Adagrad, self).__init__(**kwargs)
- with K.name_scope(self.__class__.__name__):
- self.lr = K.variable(lr, name='lr')
- self.decay = K.variable(decay, name='decay')
- self.iterations = K.variable(0, dtype='int64', name='iterations')
- self.epsilon = epsilon
- self.initial_decay = decay
-
- def get_updates(self, loss, params):
- grads = self.get_gradients(loss, params)
- shapes = [K.int_shape(p) for p in params]
- accumulators = [K.zeros(shape) for shape in shapes]
- self.weights = accumulators
- self.updates = [K.update_add(self.iterations, 1)]
-
- lr = self.lr
- if self.initial_decay > 0:
- lr *= (1. / (1. + self.decay * K.cast(self.iterations,
- K.dtype(self.decay))))
-
- for p, g, a in zip(params, grads, accumulators):
- new_a = a + K.square(g) # update accumulator
- self.updates.append(K.update(a, new_a))
- new_p = p - lr * g / (K.sqrt(new_a) + self.epsilon)
-
- # Apply constraints.
- if getattr(p, 'constraint', None) is not None:
- new_p = p.constraint(new_p)
-
- self.updates.append(K.update(p, new_p))
- return self.updates
-
- def get_config(self):
- config = {
- 'lr': float(K.get_value(self.lr)),
- 'decay': float(K.get_value(self.decay)),
- 'epsilon': self.epsilon
- }
- base_config = super(Adagrad, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Adadelta(Optimizer):
- """Adadelta optimizer.
-
- It is recommended to leave the parameters of this optimizer
- at their default values.
-
- Arguments:
- lr: float >= 0. Learning rate.
- It is recommended to leave it at the default value.
- rho: float >= 0.
- epsilon: float >= 0. Fuzz factor.
- decay: float >= 0. Learning rate decay over each update.
-
- References:
- - [Adadelta - an adaptive learning rate
- method](http://arxiv.org/abs/1212.5701)
- """
-
- def __init__(self, lr=1.0, rho=0.95, epsilon=1e-8, decay=0., **kwargs):
- super(Adadelta, self).__init__(**kwargs)
- with K.name_scope(self.__class__.__name__):
- self.lr = K.variable(lr, name='lr')
- self.decay = K.variable(decay, name='decay')
- self.iterations = K.variable(0, dtype='int64', name='iterations')
- self.rho = rho
- self.epsilon = epsilon
- self.initial_decay = decay
-
- def get_updates(self, loss, params):
- grads = self.get_gradients(loss, params)
- shapes = [K.int_shape(p) for p in params]
- accumulators = [K.zeros(shape) for shape in shapes]
- delta_accumulators = [K.zeros(shape) for shape in shapes]
- self.weights = accumulators + delta_accumulators
- self.updates = [K.update_add(self.iterations, 1)]
-
- lr = self.lr
- if self.initial_decay > 0:
- lr *= (1. / (1. + self.decay * K.cast(self.iterations,
- K.dtype(self.decay))))
-
- for p, g, a, d_a in zip(params, grads, accumulators, delta_accumulators):
- # update accumulator
- new_a = self.rho * a + (1. - self.rho) * K.square(g)
- self.updates.append(K.update(a, new_a))
-
- # use the new accumulator and the *old* delta_accumulator
- update = g * K.sqrt(d_a + self.epsilon) / K.sqrt(new_a + self.epsilon)
- new_p = p - lr * update
-
- # Apply constraints.
- if getattr(p, 'constraint', None) is not None:
- new_p = p.constraint(new_p)
-
- self.updates.append(K.update(p, new_p))
-
- # update delta_accumulator
- new_d_a = self.rho * d_a + (1 - self.rho) * K.square(update)
- self.updates.append(K.update(d_a, new_d_a))
- return self.updates
-
- def get_config(self):
- config = {
- 'lr': float(K.get_value(self.lr)),
- 'rho': self.rho,
- 'decay': float(K.get_value(self.decay)),
- 'epsilon': self.epsilon
- }
- base_config = super(Adadelta, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Adam(Optimizer):
- """Adam optimizer.
-
- Default parameters follow those provided in the original paper.
-
- Arguments:
- lr: float >= 0. Learning rate.
- beta_1: float, 0 < beta < 1. Generally close to 1.
- beta_2: float, 0 < beta < 1. Generally close to 1.
- epsilon: float >= 0. Fuzz factor.
- decay: float >= 0. Learning rate decay over each update.
-
- References:
- - [Adam - A Method for Stochastic
- Optimization](http://arxiv.org/abs/1412.6980v8)
- """
-
- def __init__(self,
- lr=0.001,
- beta_1=0.9,
- beta_2=0.999,
- epsilon=1e-8,
- decay=0.,
- **kwargs):
- super(Adam, self).__init__(**kwargs)
- with K.name_scope(self.__class__.__name__):
- self.iterations = K.variable(0, dtype='int64', name='iterations')
- self.lr = K.variable(lr, name='lr')
- self.beta_1 = K.variable(beta_1, name='beta_1')
- self.beta_2 = K.variable(beta_2, name='beta_2')
- self.decay = K.variable(decay, name='decay')
- self.epsilon = epsilon
- self.initial_decay = decay
-
- def get_updates(self, loss, params):
- grads = self.get_gradients(loss, params)
- self.updates = [K.update_add(self.iterations, 1)]
-
- lr = self.lr
- if self.initial_decay > 0:
- lr *= (1. / (1. + self.decay * K.cast(self.iterations,
- K.dtype(self.decay))))
-
- t = K.cast(self.iterations, K.floatx()) + 1
- lr_t = lr * (K.sqrt(1. - K.pow(self.beta_2, t)) /
- (1. - K.pow(self.beta_1, t)))
-
- ms = [K.zeros(K.int_shape(p), dtype=K.dtype(p)) for p in params]
- vs = [K.zeros(K.int_shape(p), dtype=K.dtype(p)) for p in params]
- self.weights = [self.iterations] + ms + vs
-
- for p, g, m, v in zip(params, grads, ms, vs):
- m_t = (self.beta_1 * m) + (1. - self.beta_1) * g
- v_t = (self.beta_2 * v) + (1. - self.beta_2) * K.square(g)
- p_t = p - lr_t * m_t / (K.sqrt(v_t) + self.epsilon)
-
- self.updates.append(K.update(m, m_t))
- self.updates.append(K.update(v, v_t))
- new_p = p_t
-
- # Apply constraints.
- if getattr(p, 'constraint', None) is not None:
- new_p = p.constraint(new_p)
-
- self.updates.append(K.update(p, new_p))
- return self.updates
-
- def get_config(self):
- config = {
- 'lr': float(K.get_value(self.lr)),
- 'beta_1': float(K.get_value(self.beta_1)),
- 'beta_2': float(K.get_value(self.beta_2)),
- 'decay': float(K.get_value(self.decay)),
- 'epsilon': self.epsilon
- }
- base_config = super(Adam, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Adamax(Optimizer):
- """Adamax optimizer from Adam paper's Section 7.
-
- It is a variant of Adam based on the infinity norm.
- Default parameters follow those provided in the paper.
-
- Arguments:
- lr: float >= 0. Learning rate.
- beta_1/beta_2: floats, 0 < beta < 1. Generally close to 1.
- epsilon: float >= 0. Fuzz factor.
- decay: float >= 0. Learning rate decay over each update.
-
- References:
- - [Adam - A Method for Stochastic
- Optimization](http://arxiv.org/abs/1412.6980v8)
- """
-
- def __init__(self,
- lr=0.002,
- beta_1=0.9,
- beta_2=0.999,
- epsilon=1e-8,
- decay=0.,
- **kwargs):
- super(Adamax, self).__init__(**kwargs)
- with K.name_scope(self.__class__.__name__):
- self.iterations = K.variable(0, dtype='int64', name='iterations')
- self.lr = K.variable(lr, name='lr')
- self.beta_1 = K.variable(beta_1, name='beta_1')
- self.beta_2 = K.variable(beta_2, name='beta_2')
- self.decay = K.variable(decay, name='decay')
- self.epsilon = epsilon
- self.initial_decay = decay
-
- def get_updates(self, loss, params):
- grads = self.get_gradients(loss, params)
- self.updates = [K.update_add(self.iterations, 1)]
-
- lr = self.lr
- if self.initial_decay > 0:
- lr *= (1. / (1. + self.decay * K.cast(self.iterations,
- K.dtype(self.decay))))
-
- t = K.cast(self.iterations, K.floatx()) + 1
- lr_t = lr / (1. - K.pow(self.beta_1, t))
-
- shapes = [K.int_shape(p) for p in params]
- # zero init of 1st moment
- ms = [K.zeros(shape) for shape in shapes]
- # zero init of exponentially weighted infinity norm
- us = [K.zeros(shape) for shape in shapes]
- self.weights = [self.iterations] + ms + us
-
- for p, g, m, u in zip(params, grads, ms, us):
-
- m_t = (self.beta_1 * m) + (1. - self.beta_1) * g
- u_t = K.maximum(self.beta_2 * u, K.abs(g))
- p_t = p - lr_t * m_t / (u_t + self.epsilon)
-
- self.updates.append(K.update(m, m_t))
- self.updates.append(K.update(u, u_t))
- new_p = p_t
-
- # Apply constraints.
- if getattr(p, 'constraint', None) is not None:
- new_p = p.constraint(new_p)
-
- self.updates.append(K.update(p, new_p))
- return self.updates
-
- def get_config(self):
- config = {
- 'lr': float(K.get_value(self.lr)),
- 'beta_1': float(K.get_value(self.beta_1)),
- 'beta_2': float(K.get_value(self.beta_2)),
- 'decay': float(K.get_value(self.decay)),
- 'epsilon': self.epsilon
- }
- base_config = super(Adamax, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class Nadam(Optimizer):
- """Nesterov Adam optimizer.
-
- Much like Adam is essentially RMSprop with momentum,
- Nadam is Adam RMSprop with Nesterov momentum.
-
- Default parameters follow those provided in the paper.
- It is recommended to leave the parameters of this optimizer
- at their default values.
-
- Arguments:
- lr: float >= 0. Learning rate.
- beta_1/beta_2: floats, 0 < beta < 1. Generally close to 1.
- epsilon: float >= 0. Fuzz factor.
-
- References:
- - [Nadam report](http://cs229.stanford.edu/proj2015/054_report.pdf)
- - [On the importance of initialization and momentum in deep
- learning](http://www.cs.toronto.edu/~fritz/absps/momentum.pdf)
- """
-
- def __init__(self,
- lr=0.002,
- beta_1=0.9,
- beta_2=0.999,
- epsilon=1e-8,
- schedule_decay=0.004,
- **kwargs):
- super(Nadam, self).__init__(**kwargs)
- with K.name_scope(self.__class__.__name__):
- self.iterations = K.variable(0, dtype='int64', name='iterations')
- self.m_schedule = K.variable(1., name='m_schedule')
- self.lr = K.variable(lr, name='lr')
- self.beta_1 = K.variable(beta_1, name='beta_1')
- self.beta_2 = K.variable(beta_2, name='beta_2')
- self.epsilon = epsilon
- self.schedule_decay = schedule_decay
-
- def get_updates(self, loss, params):
- grads = self.get_gradients(loss, params)
- self.updates = [K.update_add(self.iterations, 1)]
- t = K.cast(self.iterations, K.floatx()) + 1
-
- # Due to the recommendations in [2], i.e. warming momentum schedule
- momentum_cache_t = self.beta_1 * (
- 1. - 0.5 * (K.pow(K.cast_to_floatx(0.96), t * self.schedule_decay)))
- momentum_cache_t_1 = self.beta_1 * (
- 1. - 0.5 *
- (K.pow(K.cast_to_floatx(0.96), (t + 1) * self.schedule_decay)))
- m_schedule_new = self.m_schedule * momentum_cache_t
- m_schedule_next = self.m_schedule * momentum_cache_t * momentum_cache_t_1
- self.updates.append((self.m_schedule, m_schedule_new))
-
- shapes = [K.int_shape(p) for p in params]
- ms = [K.zeros(shape) for shape in shapes]
- vs = [K.zeros(shape) for shape in shapes]
-
- self.weights = [self.iterations] + ms + vs
-
- for p, g, m, v in zip(params, grads, ms, vs):
- # the following equations given in [1]
- g_prime = g / (1. - m_schedule_new)
- m_t = self.beta_1 * m + (1. - self.beta_1) * g
- m_t_prime = m_t / (1. - m_schedule_next)
- v_t = self.beta_2 * v + (1. - self.beta_2) * K.square(g)
- v_t_prime = v_t / (1. - K.pow(self.beta_2, t))
- m_t_bar = (
- 1. - momentum_cache_t) * g_prime + momentum_cache_t_1 * m_t_prime
-
- self.updates.append(K.update(m, m_t))
- self.updates.append(K.update(v, v_t))
-
- p_t = p - self.lr * m_t_bar / (K.sqrt(v_t_prime) + self.epsilon)
- new_p = p_t
-
- # Apply constraints.
- if getattr(p, 'constraint', None) is not None:
- new_p = p.constraint(new_p)
-
- self.updates.append(K.update(p, new_p))
- return self.updates
-
- def get_config(self):
- config = {
- 'lr': float(K.get_value(self.lr)),
- 'beta_1': float(K.get_value(self.beta_1)),
- 'beta_2': float(K.get_value(self.beta_2)),
- 'epsilon': self.epsilon,
- 'schedule_decay': self.schedule_decay
- }
- base_config = super(Nadam, self).get_config()
- return dict(list(base_config.items()) + list(config.items()))
-
-
-class TFOptimizer(Optimizer):
- """Wrapper class for native TensorFlow optimizers.
- """
-
- def __init__(self, optimizer): # pylint: disable=super-init-not-called
- self.optimizer = optimizer
- with K.name_scope(self.__class__.__name__):
- self.iterations = K.variable(0, dtype='int64', name='iterations')
-
- def get_updates(self, loss, params):
- grads = self.optimizer.compute_gradients(loss, params)
- self.updates = [K.update_add(self.iterations, 1)]
- opt_update = self.optimizer.apply_gradients(
- grads, global_step=self.iterations)
- self.updates.append(opt_update)
- return self.updates
-
- @property
- def weights(self):
- raise NotImplementedError
-
- def get_config(self):
- raise NotImplementedError
-
- def from_config(self, config):
- raise NotImplementedError
-
-
-# Aliases.
-
-# pylint: disable=invalid-name
-sgd = SGD
-rmsprop = RMSprop
-adagrad = Adagrad
-adadelta = Adadelta
-adam = Adam
-adamax = Adamax
-nadam = Nadam
-
-# pylint: enable=invalid-name
-
-
-def serialize(optimizer):
- return serialize_keras_object(optimizer)
-
-
-def deserialize(config, custom_objects=None):
- """Inverse of the `serialize` function.
-
- Arguments:
- config: Optimizer configuration dictionary.
- custom_objects: Optional dictionary mapping
- names (strings) to custom objects
- (classes and functions)
- to be considered during deserialization.
-
- Returns:
- A Keras Optimizer instance.
- """
- all_classes = {
- 'sgd': SGD,
- 'rmsprop': RMSprop,
- 'adagrad': Adagrad,
- 'adadelta': Adadelta,
- 'adam': Adam,
- 'adamax': Adamax,
- 'nadam': Nadam,
- 'tfoptimizer': TFOptimizer,
- }
- # Make deserialization case-insensitive for built-in optimizers.
- if config['class_name'].lower() in all_classes:
- config['class_name'] = config['class_name'].lower()
- return deserialize_keras_object(
- config,
- module_objects=all_classes,
- custom_objects=custom_objects,
- printable_module_name='optimizer')
-
-
-def get(identifier):
- """Retrieves a Keras Optimizer instance.
-
- Arguments:
- identifier: Optimizer identifier, one of
- - String: name of an optimizer
- - Dictionary: configuration dictionary.
- - Keras Optimizer instance (it will be returned unchanged).
- - TensorFlow Optimizer instance
- (it will be wrapped as a Keras Optimizer).
-
- Returns:
- A Keras Optimizer instance.
-
- Raises:
- ValueError: If `identifier` cannot be interpreted.
- """
- # Wrap TF optimizer instances
- if isinstance(identifier, tf_optimizer_module.Optimizer):
- return TFOptimizer(identifier)
- if isinstance(identifier, dict):
- return deserialize(identifier)
- elif isinstance(identifier, six.string_types):
- config = {'class_name': str(identifier), 'config': {}}
- return deserialize(config)
- if isinstance(identifier, Optimizer):
- return identifier
- else:
- raise ValueError('Could not interpret optimizer identifier:', identifier)
diff --git a/tensorflow/contrib/keras/python/keras/optimizers_test.py b/tensorflow/contrib/keras/python/keras/optimizers_test.py
deleted file mode 100644
index a105d13cf9..0000000000
--- a/tensorflow/contrib/keras/python/keras/optimizers_test.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for Keras optimizers."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-from tensorflow.python.training.adam import AdamOptimizer
-
-
-def _get_model(input_dim, num_hidden, output_dim):
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(num_hidden,
- activation='relu',
- input_shape=(input_dim,)))
- model.add(keras.layers.Dense(output_dim, activation='softmax'))
- return model
-
-
-def _test_optimizer(optimizer, target=0.75):
- np.random.seed(1337)
- (x_train, y_train), _ = testing_utils.get_test_data(train_samples=1000,
- test_samples=200,
- input_shape=(10,),
- num_classes=2)
- y_train = keras.utils.to_categorical(y_train)
- model = _get_model(x_train.shape[1], 20, y_train.shape[1])
- model.compile(loss='categorical_crossentropy',
- optimizer=optimizer,
- metrics=['accuracy'])
- history = model.fit(x_train, y_train, epochs=2, batch_size=16, verbose=0)
- assert history.history['acc'][-1] >= target
- config = keras.optimizers.serialize(optimizer)
- optim = keras.optimizers.deserialize(config)
- new_config = keras.optimizers.serialize(optim)
- new_config['class_name'] = new_config['class_name'].lower()
- assert config == new_config
-
- # Test constraints.
- model = keras.models.Sequential()
- dense = keras.layers.Dense(10,
- input_shape=(x_train.shape[1],),
- kernel_constraint=lambda x: 0. * x + 1.,
- bias_constraint=lambda x: 0. * x + 2.,
- activation='relu')
- model.add(dense)
- model.add(keras.layers.Dense(y_train.shape[1], activation='softmax'))
- model.compile(loss='categorical_crossentropy',
- optimizer=optimizer,
- metrics=['accuracy'])
- model.train_on_batch(x_train[:10], y_train[:10])
- kernel, bias = dense.get_weights()
- np.testing.assert_allclose(kernel, 1., atol=1e-3)
- np.testing.assert_allclose(bias, 2., atol=1e-3)
-
-
-class KerasOptimizersTest(test.TestCase):
-
- def test_sgd(self):
- with self.test_session():
- _test_optimizer(keras.optimizers.SGD(lr=0.01,
- momentum=0.9,
- nesterov=True))
-
- def test_rmsprop(self):
- with self.test_session():
- _test_optimizer(keras.optimizers.RMSprop())
- _test_optimizer(keras.optimizers.RMSprop(decay=1e-3))
-
- def test_adagrad(self):
- with self.test_session():
- _test_optimizer(keras.optimizers.Adagrad())
- _test_optimizer(keras.optimizers.Adagrad(decay=1e-3))
-
- def test_adadelta(self):
- with self.test_session():
- _test_optimizer(keras.optimizers.Adadelta(), target=0.6)
- _test_optimizer(keras.optimizers.Adadelta(decay=1e-3), target=0.6)
-
- def test_adam(self):
- with self.test_session():
- _test_optimizer(keras.optimizers.Adam())
- _test_optimizer(keras.optimizers.Adam(decay=1e-3))
-
- def test_adamax(self):
- with self.test_session():
- _test_optimizer(keras.optimizers.Adamax())
- _test_optimizer(keras.optimizers.Adamax(decay=1e-3))
-
- def test_nadam(self):
- with self.test_session():
- _test_optimizer(keras.optimizers.Nadam())
-
- def test_clipnorm(self):
- with self.test_session():
- _test_optimizer(keras.optimizers.SGD(lr=0.01,
- momentum=0.9,
- clipnorm=0.5))
-
- def test_clipvalue(self):
- with self.test_session():
- _test_optimizer(keras.optimizers.SGD(lr=0.01,
- momentum=0.9,
- clipvalue=0.5))
-
- def test_tfoptimizer(self):
- optimizer = keras.optimizers.TFOptimizer(AdamOptimizer(0.01))
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(
- 2, input_shape=(3,), kernel_constraint=keras.constraints.MaxNorm(1)))
- # This is possible
- model.compile(loss='mean_squared_error', optimizer=optimizer)
- model.fit(np.random.random((5, 3)),
- np.random.random((5, 2)),
- epochs=1,
- batch_size=5,
- verbose=0)
- # not supported
- with self.assertRaises(NotImplementedError):
- _ = optimizer.weights
- with self.assertRaises(NotImplementedError):
- optimizer.get_config()
- with self.assertRaises(NotImplementedError):
- optimizer.from_config(None)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/preprocessing/__init__.py b/tensorflow/contrib/keras/python/keras/preprocessing/__init__.py
deleted file mode 100644
index 9ae14c9674..0000000000
--- a/tensorflow/contrib/keras/python/keras/preprocessing/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Data preprocessing module.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras.preprocessing import image
-from tensorflow.contrib.keras.python.keras.preprocessing import sequence
-from tensorflow.contrib.keras.python.keras.preprocessing import text
-
diff --git a/tensorflow/contrib/keras/python/keras/preprocessing/image.py b/tensorflow/contrib/keras/python/keras/preprocessing/image.py
deleted file mode 100644
index 4d6e0e0fcb..0000000000
--- a/tensorflow/contrib/keras/python/keras/preprocessing/image.py
+++ /dev/null
@@ -1,1172 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Fairly basic set of tools for real-time data augmentation on image data.
-
-Can easily be extended to include new transformations,
-new preprocessing methods, etc...
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from functools import partial
-import multiprocessing.pool
-import os
-import re
-import threading
-
-import numpy as np
-from six.moves import range # pylint: disable=redefined-builtin
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.python.platform import tf_logging as logging
-
-
-# pylint: disable=g-import-not-at-top
-try:
- from PIL import Image as pil_image
-except ImportError:
- pil_image = None
-try:
- from scipy import linalg
- import scipy.ndimage as ndi
-except ImportError:
- linalg = None
- ndi = None
-# pylint: enable=g-import-not-at-top
-
-
-def random_rotation(x,
- rg,
- row_axis=1,
- col_axis=2,
- channel_axis=0,
- fill_mode='nearest',
- cval=0.):
- """Performs a random rotation of a Numpy image tensor.
-
- Arguments:
- x: Input tensor. Must be 3D.
- rg: Rotation range, in degrees.
- row_axis: Index of axis for rows in the input tensor.
- col_axis: Index of axis for columns in the input tensor.
- channel_axis: Index of axis for channels in the input tensor.
- fill_mode: Points outside the boundaries of the input
- are filled according to the given mode
- (one of `{'constant', 'nearest', 'reflect', 'wrap'}`).
- cval: Value used for points outside the boundaries
- of the input if `mode='constant'`.
-
- Returns:
- Rotated Numpy image tensor.
- """
- theta = np.pi / 180 * np.random.uniform(-rg, rg)
- rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
- [np.sin(theta), np.cos(theta), 0], [0, 0, 1]])
-
- h, w = x.shape[row_axis], x.shape[col_axis]
- transform_matrix = transform_matrix_offset_center(rotation_matrix, h, w)
- x = apply_transform(x, transform_matrix, channel_axis, fill_mode, cval)
- return x
-
-
-def random_shift(x,
- wrg,
- hrg,
- row_axis=1,
- col_axis=2,
- channel_axis=0,
- fill_mode='nearest',
- cval=0.):
- """Performs a random spatial shift of a Numpy image tensor.
-
- Arguments:
- x: Input tensor. Must be 3D.
- wrg: Width shift range, as a float fraction of the width.
- hrg: Height shift range, as a float fraction of the height.
- row_axis: Index of axis for rows in the input tensor.
- col_axis: Index of axis for columns in the input tensor.
- channel_axis: Index of axis for channels in the input tensor.
- fill_mode: Points outside the boundaries of the input
- are filled according to the given mode
- (one of `{'constant', 'nearest', 'reflect', 'wrap'}`).
- cval: Value used for points outside the boundaries
- of the input if `mode='constant'`.
-
- Returns:
- Shifted Numpy image tensor.
- """
- h, w = x.shape[row_axis], x.shape[col_axis]
- tx = np.random.uniform(-hrg, hrg) * h
- ty = np.random.uniform(-wrg, wrg) * w
- translation_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]])
-
- transform_matrix = translation_matrix # no need to do offset
- x = apply_transform(x, transform_matrix, channel_axis, fill_mode, cval)
- return x
-
-
-def random_shear(x,
- intensity,
- row_axis=1,
- col_axis=2,
- channel_axis=0,
- fill_mode='nearest',
- cval=0.):
- """Performs a random spatial shear of a Numpy image tensor.
-
- Arguments:
- x: Input tensor. Must be 3D.
- intensity: Transformation intensity.
- row_axis: Index of axis for rows in the input tensor.
- col_axis: Index of axis for columns in the input tensor.
- channel_axis: Index of axis for channels in the input tensor.
- fill_mode: Points outside the boundaries of the input
- are filled according to the given mode
- (one of `{'constant', 'nearest', 'reflect', 'wrap'}`).
- cval: Value used for points outside the boundaries
- of the input if `mode='constant'`.
-
- Returns:
- Sheared Numpy image tensor.
- """
- shear = np.random.uniform(-intensity, intensity)
- shear_matrix = np.array([[1, -np.sin(shear), 0], [0, np.cos(shear), 0],
- [0, 0, 1]])
-
- h, w = x.shape[row_axis], x.shape[col_axis]
- transform_matrix = transform_matrix_offset_center(shear_matrix, h, w)
- x = apply_transform(x, transform_matrix, channel_axis, fill_mode, cval)
- return x
-
-
-def random_zoom(x,
- zoom_range,
- row_axis=1,
- col_axis=2,
- channel_axis=0,
- fill_mode='nearest',
- cval=0.):
- """Performs a random spatial zoom of a Numpy image tensor.
-
- Arguments:
- x: Input tensor. Must be 3D.
- zoom_range: Tuple of floats; zoom range for width and height.
- row_axis: Index of axis for rows in the input tensor.
- col_axis: Index of axis for columns in the input tensor.
- channel_axis: Index of axis for channels in the input tensor.
- fill_mode: Points outside the boundaries of the input
- are filled according to the given mode
- (one of `{'constant', 'nearest', 'reflect', 'wrap'}`).
- cval: Value used for points outside the boundaries
- of the input if `mode='constant'`.
-
- Returns:
- Zoomed Numpy image tensor.
-
- Raises:
- ValueError: if `zoom_range` isn't a tuple.
- """
- if len(zoom_range) != 2:
- raise ValueError('`zoom_range` should be a tuple or list of two floats. '
- 'Received arg: ', zoom_range)
-
- if zoom_range[0] == 1 and zoom_range[1] == 1:
- zx, zy = 1, 1
- else:
- zx, zy = np.random.uniform(zoom_range[0], zoom_range[1], 2)
- zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]])
-
- h, w = x.shape[row_axis], x.shape[col_axis]
- transform_matrix = transform_matrix_offset_center(zoom_matrix, h, w)
- x = apply_transform(x, transform_matrix, channel_axis, fill_mode, cval)
- return x
-
-
-def random_channel_shift(x, intensity, channel_axis=0):
- x = np.rollaxis(x, channel_axis, 0)
- min_x, max_x = np.min(x), np.max(x)
- channel_images = [
- np.clip(x_channel + np.random.uniform(-intensity, intensity), min_x,
- max_x) for x_channel in x
- ]
- x = np.stack(channel_images, axis=0)
- x = np.rollaxis(x, 0, channel_axis + 1)
- return x
-
-
-def transform_matrix_offset_center(matrix, x, y):
- o_x = float(x) / 2 + 0.5
- o_y = float(y) / 2 + 0.5
- offset_matrix = np.array([[1, 0, o_x], [0, 1, o_y], [0, 0, 1]])
- reset_matrix = np.array([[1, 0, -o_x], [0, 1, -o_y], [0, 0, 1]])
- transform_matrix = np.dot(np.dot(offset_matrix, matrix), reset_matrix)
- return transform_matrix
-
-
-def apply_transform(x,
- transform_matrix,
- channel_axis=0,
- fill_mode='nearest',
- cval=0.):
- """Apply the image transformation specified by a matrix.
-
- Arguments:
- x: 2D numpy array, single image.
- transform_matrix: Numpy array specifying the geometric transformation.
- channel_axis: Index of axis for channels in the input tensor.
- fill_mode: Points outside the boundaries of the input
- are filled according to the given mode
- (one of `{'constant', 'nearest', 'reflect', 'wrap'}`).
- cval: Value used for points outside the boundaries
- of the input if `mode='constant'`.
-
- Returns:
- The transformed version of the input.
- """
- x = np.rollaxis(x, channel_axis, 0)
- final_affine_matrix = transform_matrix[:2, :2]
- final_offset = transform_matrix[:2, 2]
- channel_images = [
- ndi.interpolation.affine_transform(
- x_channel,
- final_affine_matrix,
- final_offset,
- order=0,
- mode=fill_mode,
- cval=cval) for x_channel in x
- ]
- x = np.stack(channel_images, axis=0)
- x = np.rollaxis(x, 0, channel_axis + 1)
- return x
-
-
-def flip_axis(x, axis):
- x = np.asarray(x).swapaxes(axis, 0)
- x = x[::-1, ...]
- x = x.swapaxes(0, axis)
- return x
-
-
-def array_to_img(x, data_format=None, scale=True):
- """Converts a 3D Numpy array to a PIL Image instance.
-
- Arguments:
- x: Input Numpy array.
- data_format: Image data format.
- scale: Whether to rescale image values
- to be within [0, 255].
-
- Returns:
- A PIL Image instance.
-
- Raises:
- ImportError: if PIL is not available.
- ValueError: if invalid `x` or `data_format` is passed.
- """
- if pil_image is None:
- raise ImportError('Could not import PIL.Image. '
- 'The use of `array_to_img` requires PIL.')
- x = np.asarray(x, dtype=K.floatx())
- if x.ndim != 3:
- raise ValueError('Expected image array to have rank 3 (single image). '
- 'Got array with shape:', x.shape)
-
- if data_format is None:
- data_format = K.image_data_format()
- if data_format not in {'channels_first', 'channels_last'}:
- raise ValueError('Invalid data_format:', data_format)
-
- # Original Numpy array x has format (height, width, channel)
- # or (channel, height, width)
- # but target PIL image has format (width, height, channel)
- if data_format == 'channels_first':
- x = x.transpose(1, 2, 0)
- if scale:
- x = x + max(-np.min(x), 0) # pylint: disable=g-no-augmented-assignment
- x_max = np.max(x)
- if x_max != 0:
- x /= x_max
- x *= 255
- if x.shape[2] == 3:
- # RGB
- return pil_image.fromarray(x.astype('uint8'), 'RGB')
- elif x.shape[2] == 1:
- # grayscale
- return pil_image.fromarray(x[:, :, 0].astype('uint8'), 'L')
- else:
- raise ValueError('Unsupported channel number: ', x.shape[2])
-
-
-def img_to_array(img, data_format=None):
- """Converts a PIL Image instance to a Numpy array.
-
- Arguments:
- img: PIL Image instance.
- data_format: Image data format.
-
- Returns:
- A 3D Numpy array.
-
- Raises:
- ValueError: if invalid `img` or `data_format` is passed.
- """
- if data_format is None:
- data_format = K.image_data_format()
- if data_format not in {'channels_first', 'channels_last'}:
- raise ValueError('Unknown data_format: ', data_format)
- # Numpy array x has format (height, width, channel)
- # or (channel, height, width)
- # but original PIL image has format (width, height, channel)
- x = np.asarray(img, dtype=K.floatx())
- if len(x.shape) == 3:
- if data_format == 'channels_first':
- x = x.transpose(2, 0, 1)
- elif len(x.shape) == 2:
- if data_format == 'channels_first':
- x = x.reshape((1, x.shape[0], x.shape[1]))
- else:
- x = x.reshape((x.shape[0], x.shape[1], 1))
- else:
- raise ValueError('Unsupported image shape: ', x.shape)
- return x
-
-
-def load_img(path, grayscale=False, target_size=None):
- """Loads an image into PIL format.
-
- Arguments:
- path: Path to image file
- grayscale: Boolean, whether to load the image as grayscale.
- target_size: Either `None` (default to original size)
- or tuple of ints `(img_height, img_width)`.
-
- Returns:
- A PIL Image instance.
-
- Raises:
- ImportError: if PIL is not available.
- """
- if pil_image is None:
- raise ImportError('Could not import PIL.Image. '
- 'The use of `array_to_img` requires PIL.')
- img = pil_image.open(path)
- if grayscale:
- if img.mode != 'L':
- img = img.convert('L')
- else:
- if img.mode != 'RGB':
- img = img.convert('RGB')
- if target_size:
- hw_tuple = (target_size[1], target_size[0])
- if img.size != hw_tuple:
- img = img.resize(hw_tuple)
- return img
-
-
-def list_pictures(directory, ext='jpg|jpeg|bmp|png'):
- return [
- os.path.join(root, f)
- for root, _, files in os.walk(directory) for f in files
- if re.match(r'([\w]+\.(?:' + ext + '))', f)
- ]
-
-
-class ImageDataGenerator(object):
- """Generate minibatches of image data with real-time data augmentation.
-
- Arguments:
- featurewise_center: set input mean to 0 over the dataset.
- samplewise_center: set each sample mean to 0.
- featurewise_std_normalization: divide inputs by std of the dataset.
- samplewise_std_normalization: divide each input by its std.
- zca_whitening: apply ZCA whitening.
- zca_epsilon: epsilon for ZCA whitening. Default is 1e-6.
- rotation_range: degrees (0 to 180).
- width_shift_range: fraction of total width.
- height_shift_range: fraction of total height.
- shear_range: shear intensity (shear angle in radians).
- zoom_range: amount of zoom. if scalar z, zoom will be randomly picked
- in the range [1-z, 1+z]. A sequence of two can be passed instead
- to select this range.
- channel_shift_range: shift range for each channels.
- fill_mode: points outside the boundaries are filled according to the
- given mode ('constant', 'nearest', 'reflect' or 'wrap'). Default
- is 'nearest'.
- cval: value used for points outside the boundaries when fill_mode is
- 'constant'. Default is 0.
- horizontal_flip: whether to randomly flip images horizontally.
- vertical_flip: whether to randomly flip images vertically.
- rescale: rescaling factor. If None or 0, no rescaling is applied,
- otherwise we multiply the data by the value provided. This is
- applied after the `preprocessing_function` (if any provided)
- but before any other transformation.
- preprocessing_function: function that will be implied on each input.
- The function will run before any other modification on it.
- The function should take one argument:
- one image (Numpy tensor with rank 3),
- and should output a Numpy tensor with the same shape.
- data_format: 'channels_first' or 'channels_last'. In 'channels_first'
- mode, the channels dimension
- (the depth) is at index 1, in 'channels_last' mode it is 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 "channels_last".
- """
-
- def __init__(self,
- featurewise_center=False,
- samplewise_center=False,
- featurewise_std_normalization=False,
- samplewise_std_normalization=False,
- zca_whitening=False,
- zca_epsilon=1e-6,
- rotation_range=0.,
- width_shift_range=0.,
- height_shift_range=0.,
- shear_range=0.,
- zoom_range=0.,
- channel_shift_range=0.,
- fill_mode='nearest',
- cval=0.,
- horizontal_flip=False,
- vertical_flip=False,
- rescale=None,
- preprocessing_function=None,
- data_format=None):
- if data_format is None:
- data_format = K.image_data_format()
- self.featurewise_center = featurewise_center
- self.samplewise_center = samplewise_center
- self.featurewise_std_normalization = featurewise_std_normalization
- self.samplewise_std_normalization = samplewise_std_normalization
- self.zca_whitening = zca_whitening
- self.zca_epsilon = zca_epsilon
- self.rotation_range = rotation_range
- self.width_shift_range = width_shift_range
- self.height_shift_range = height_shift_range
- self.shear_range = shear_range
- self.zoom_range = zoom_range
- self.channel_shift_range = channel_shift_range
- self.fill_mode = fill_mode
- self.cval = cval
- self.horizontal_flip = horizontal_flip
- self.vertical_flip = vertical_flip
- self.rescale = rescale
- self.preprocessing_function = preprocessing_function
-
- if data_format not in {'channels_last', 'channels_first'}:
- raise ValueError(
- '`data_format` should be `"channels_last"` (channel after row and '
- 'column) or `"channels_first"` (channel before row and column). '
- 'Received arg: ', data_format)
- self.data_format = data_format
- if data_format == 'channels_first':
- self.channel_axis = 1
- self.row_axis = 2
- self.col_axis = 3
- if data_format == 'channels_last':
- self.channel_axis = 3
- self.row_axis = 1
- self.col_axis = 2
-
- self.mean = None
- self.std = None
- self.principal_components = None
-
- if np.isscalar(zoom_range):
- self.zoom_range = [1 - zoom_range, 1 + zoom_range]
- elif len(zoom_range) == 2:
- self.zoom_range = [zoom_range[0], zoom_range[1]]
- else:
- raise ValueError('`zoom_range` should be a float or '
- 'a tuple or list of two floats. '
- 'Received arg: ', zoom_range)
-
- def flow(self,
- x,
- y=None,
- batch_size=32,
- shuffle=True,
- seed=None,
- save_to_dir=None,
- save_prefix='',
- save_format='png'):
- return NumpyArrayIterator(
- x,
- y,
- self,
- batch_size=batch_size,
- shuffle=shuffle,
- seed=seed,
- data_format=self.data_format,
- save_to_dir=save_to_dir,
- save_prefix=save_prefix,
- save_format=save_format)
-
- def flow_from_directory(self,
- directory,
- target_size=(256, 256),
- color_mode='rgb',
- classes=None,
- class_mode='categorical',
- batch_size=32,
- shuffle=True,
- seed=None,
- save_to_dir=None,
- save_prefix='',
- save_format='png',
- follow_links=False):
- return DirectoryIterator(
- directory,
- self,
- target_size=target_size,
- color_mode=color_mode,
- classes=classes,
- class_mode=class_mode,
- data_format=self.data_format,
- batch_size=batch_size,
- shuffle=shuffle,
- seed=seed,
- save_to_dir=save_to_dir,
- save_prefix=save_prefix,
- save_format=save_format,
- follow_links=follow_links)
-
- def standardize(self, x):
- """Apply the normalization configuration to a batch of inputs.
-
- Arguments:
- x: batch of inputs to be normalized.
-
- Returns:
- The inputs, normalized.
- """
- if self.preprocessing_function:
- x = self.preprocessing_function(x)
- if self.rescale:
- x *= self.rescale
- # x is a single image, so it doesn't have image number at index 0
- img_channel_axis = self.channel_axis - 1
- if self.samplewise_center:
- x -= np.mean(x, axis=img_channel_axis, keepdims=True)
- if self.samplewise_std_normalization:
- x /= (np.std(x, axis=img_channel_axis, keepdims=True) + 1e-7)
-
- if self.featurewise_center:
- if self.mean is not None:
- x -= self.mean
- else:
- logging.warning('This ImageDataGenerator specifies '
- '`featurewise_center`, but it hasn\'t'
- 'been fit on any training data. Fit it '
- 'first by calling `.fit(numpy_data)`.')
- if self.featurewise_std_normalization:
- if self.std is not None:
- x /= (self.std + 1e-7)
- else:
- logging.warning('This ImageDataGenerator specifies '
- '`featurewise_std_normalization`, but it hasn\'t'
- 'been fit on any training data. Fit it '
- 'first by calling `.fit(numpy_data)`.')
- if self.zca_whitening:
- if self.principal_components is not None:
- flatx = np.reshape(x, (-1, np.prod(x.shape[-3:])))
- whitex = np.dot(flatx, self.principal_components)
- x = np.reshape(whitex, x.shape)
- else:
- logging.warning('This ImageDataGenerator specifies '
- '`zca_whitening`, but it hasn\'t'
- 'been fit on any training data. Fit it '
- 'first by calling `.fit(numpy_data)`.')
- return x
-
- def random_transform(self, x, seed=None):
- """Randomly augment a single image tensor.
-
- Arguments:
- x: 3D tensor, single image.
- seed: random seed.
-
- Returns:
- A randomly transformed version of the input (same shape).
-
- Raises:
- ImportError: if Scipy is not available.
- """
- if ndi is None:
- raise ImportError('Scipy is required for image transformations.')
-
- # x is a single image, so it doesn't have image number at index 0
- img_row_axis = self.row_axis - 1
- img_col_axis = self.col_axis - 1
- img_channel_axis = self.channel_axis - 1
-
- if seed is not None:
- np.random.seed(seed)
-
- # use composition of homographies
- # to generate final transform that needs to be applied
- if self.rotation_range:
- theta = np.pi / 180 * np.random.uniform(-self.rotation_range,
- self.rotation_range)
- else:
- theta = 0
-
- if self.height_shift_range:
- tx = np.random.uniform(-self.height_shift_range,
- self.height_shift_range) * x.shape[img_row_axis]
- else:
- tx = 0
-
- if self.width_shift_range:
- ty = np.random.uniform(-self.width_shift_range,
- self.width_shift_range) * x.shape[img_col_axis]
- else:
- ty = 0
-
- if self.shear_range:
- shear = np.random.uniform(-self.shear_range, self.shear_range)
- else:
- shear = 0
-
- if self.zoom_range[0] == 1 and self.zoom_range[1] == 1:
- zx, zy = 1, 1
- else:
- zx, zy = np.random.uniform(self.zoom_range[0], self.zoom_range[1], 2)
-
- transform_matrix = None
- if theta != 0:
- rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
- [np.sin(theta),
- np.cos(theta), 0], [0, 0, 1]])
- transform_matrix = rotation_matrix
-
- if tx != 0 or ty != 0:
- shift_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]])
- transform_matrix = shift_matrix if transform_matrix is None else np.dot(
- transform_matrix, shift_matrix)
-
- if shear != 0:
- shear_matrix = np.array([[1, -np.sin(shear), 0], [0, np.cos(shear), 0],
- [0, 0, 1]])
- transform_matrix = shear_matrix if transform_matrix is None else np.dot(
- transform_matrix, shear_matrix)
-
- if zx != 1 or zy != 1:
- zoom_matrix = np.array([[zx, 0, 0], [0, zy, 0], [0, 0, 1]])
- transform_matrix = zoom_matrix if transform_matrix is None else np.dot(
- transform_matrix, zoom_matrix)
-
- if transform_matrix is not None:
- h, w = x.shape[img_row_axis], x.shape[img_col_axis]
- transform_matrix = transform_matrix_offset_center(transform_matrix, h, w)
- x = apply_transform(
- x,
- transform_matrix,
- img_channel_axis,
- fill_mode=self.fill_mode,
- cval=self.cval)
-
- if self.channel_shift_range != 0:
- x = random_channel_shift(x, self.channel_shift_range, img_channel_axis)
- if self.horizontal_flip:
- if np.random.random() < 0.5:
- x = flip_axis(x, img_col_axis)
-
- if self.vertical_flip:
- if np.random.random() < 0.5:
- x = flip_axis(x, img_row_axis)
-
- return x
-
- def fit(self, x, augment=False, rounds=1, seed=None):
- """Fits internal statistics to some sample data.
-
- Required for featurewise_center, featurewise_std_normalization
- and zca_whitening.
-
- Arguments:
- x: Numpy array, the data to fit on. Should have rank 4.
- In case of grayscale data,
- the channels axis should have value 1, and in case
- of RGB data, it should have value 3.
- augment: Whether to fit on randomly augmented samples
- rounds: If `augment`,
- how many augmentation passes to do over the data
- seed: random seed.
-
- Raises:
- ValueError: in case of invalid input `x`.
- ImportError: if Scipy is not available.
- """
- x = np.asarray(x, dtype=K.floatx())
- if x.ndim != 4:
- raise ValueError('Input to `.fit()` should have rank 4. '
- 'Got array with shape: ' + str(x.shape))
- if x.shape[self.channel_axis] not in {3, 4}:
- logging.warning(
- 'Expected input to be images (as Numpy array) '
- 'following the data format convention "' + self.data_format + '" '
- '(channels on axis ' + str(self.channel_axis) + '), i.e. expected '
- 'either 1, 3 or 4 channels on axis ' + str(self.channel_axis) + '. '
- 'However, it was passed an array with shape ' + str(x.shape) + ' (' +
- str(x.shape[self.channel_axis]) + ' channels).')
-
- if seed is not None:
- np.random.seed(seed)
-
- x = np.copy(x)
- if augment:
- ax = np.zeros(
- tuple([rounds * x.shape[0]] + list(x.shape)[1:]), dtype=K.floatx())
- for r in range(rounds):
- for i in range(x.shape[0]):
- ax[i + r * x.shape[0]] = self.random_transform(x[i])
- x = ax
-
- if self.featurewise_center:
- self.mean = np.mean(x, axis=(0, self.row_axis, self.col_axis))
- broadcast_shape = [1, 1, 1]
- broadcast_shape[self.channel_axis - 1] = x.shape[self.channel_axis]
- self.mean = np.reshape(self.mean, broadcast_shape)
- x -= self.mean
-
- if self.featurewise_std_normalization:
- self.std = np.std(x, axis=(0, self.row_axis, self.col_axis))
- broadcast_shape = [1, 1, 1]
- broadcast_shape[self.channel_axis - 1] = x.shape[self.channel_axis]
- self.std = np.reshape(self.std, broadcast_shape)
- x /= (self.std + K.epsilon())
-
- if self.zca_whitening:
- if linalg is None:
- raise ImportError('Scipy is required for zca_whitening.')
-
- flat_x = np.reshape(x, (x.shape[0], x.shape[1] * x.shape[2] * x.shape[3]))
- sigma = np.dot(flat_x.T, flat_x) / flat_x.shape[0]
- u, s, _ = linalg.svd(sigma)
- self.principal_components = np.dot(
- np.dot(u, np.diag(1. / np.sqrt(s + self.zca_epsilon))), u.T)
-
-
-class Iterator(object):
- """Abstract base class for image data iterators.
-
- Arguments:
- n: Integer, total number of samples in the dataset to loop over.
- batch_size: Integer, size of a batch.
- shuffle: Boolean, whether to shuffle the data between epochs.
- seed: Random seeding for data shuffling.
- """
-
- def __init__(self, n, batch_size, shuffle, seed):
- self.n = n
- self.batch_size = batch_size
- self.shuffle = shuffle
- self.batch_index = 0
- self.total_batches_seen = 0
- self.lock = threading.Lock()
- self.index_generator = self._flow_index(n, batch_size, shuffle, seed)
-
- def reset(self):
- self.batch_index = 0
-
- def _flow_index(self, n, batch_size=32, shuffle=False, seed=None):
- # Ensure self.batch_index is 0.
- self.reset()
- while 1:
- if seed is not None:
- np.random.seed(seed + self.total_batches_seen)
- if self.batch_index == 0:
- index_array = np.arange(n)
- if shuffle:
- index_array = np.random.permutation(n)
-
- current_index = (self.batch_index * batch_size) % n
- if n > current_index + batch_size:
- current_batch_size = batch_size
- self.batch_index += 1
- else:
- current_batch_size = n - current_index
- self.batch_index = 0
- self.total_batches_seen += 1
- yield (index_array[current_index:current_index + current_batch_size],
- current_index, current_batch_size)
-
- def __iter__(self): # pylint: disable=non-iterator-returned
- # Needed if we want to do something like:
- # for x, y in data_gen.flow(...):
- return self
-
- def __next__(self, *args, **kwargs):
- return self.next(*args, **kwargs)
-
-
-class NumpyArrayIterator(Iterator):
- """Iterator yielding data from a Numpy array.
-
- Arguments:
- x: Numpy array of input data.
- y: Numpy array of targets data.
- image_data_generator: Instance of `ImageDataGenerator`
- to use for random transformations and normalization.
- batch_size: Integer, size of a batch.
- shuffle: Boolean, whether to shuffle the data between epochs.
- seed: Random seed for data shuffling.
- data_format: String, one of `channels_first`, `channels_last`.
- save_to_dir: Optional directory where to save the pictures
- being yielded, in a viewable format. This is useful
- for visualizing the random transformations being
- applied, for debugging purposes.
- save_prefix: String prefix to use for saving sample
- images (if `save_to_dir` is set).
- save_format: Format to use for saving sample images
- (if `save_to_dir` is set).
- """
-
- def __init__(self,
- x,
- y,
- image_data_generator,
- batch_size=32,
- shuffle=False,
- seed=None,
- data_format=None,
- save_to_dir=None,
- save_prefix='',
- save_format='png'):
- if y is not None and len(x) != len(y):
- raise ValueError('X (images tensor) and y (labels) '
- 'should have the same length. '
- 'Found: X.shape = %s, y.shape = %s' %
- (np.asarray(x).shape, np.asarray(y).shape))
-
- if data_format is None:
- data_format = K.image_data_format()
- self.x = np.asarray(x, dtype=K.floatx())
-
- if self.x.ndim != 4:
- raise ValueError('Input data in `NumpyArrayIterator` '
- 'should have rank 4. You passed an array '
- 'with shape', self.x.shape)
- channels_axis = 3 if data_format == 'channels_last' else 1
- if self.x.shape[channels_axis] not in {1, 3, 4}:
- logging.warning(
- 'NumpyArrayIterator is set to use the '
- 'data format convention "' + data_format + '" '
- '(channels on axis ' + str(channels_axis) + '), i.e. expected '
- 'either 1, 3 or 4 channels on axis ' + str(channels_axis) + '. '
- 'However, it was passed an array with shape ' + str(self.x.shape) +
- ' (' + str(self.x.shape[channels_axis]) + ' channels).')
- if y is not None:
- self.y = np.asarray(y)
- else:
- self.y = None
- self.image_data_generator = image_data_generator
- self.data_format = data_format
- self.save_to_dir = save_to_dir
- self.save_prefix = save_prefix
- self.save_format = save_format
- super(NumpyArrayIterator, self).__init__(x.shape[0], batch_size, shuffle,
- seed)
-
- def next(self):
- """For python 2.x.
-
- Returns:
- The next batch.
- """
- # Keeps under lock only the mechanism which advances
- # the indexing of each batch.
- with self.lock:
- index_array, current_index, current_batch_size = next(
- self.index_generator)
- # The transformation of images is not under thread lock
- # so it can be done in parallel
- batch_x = np.zeros(
- tuple([current_batch_size] + list(self.x.shape)[1:]), dtype=K.floatx())
- for i, j in enumerate(index_array):
- x = self.x[j]
- x = self.image_data_generator.random_transform(x.astype(K.floatx()))
- x = self.image_data_generator.standardize(x)
- batch_x[i] = x
- if self.save_to_dir:
- for i in range(current_batch_size):
- img = array_to_img(batch_x[i], self.data_format, scale=True)
- fname = '{prefix}_{index}_{hash}.{format}'.format(
- prefix=self.save_prefix,
- index=current_index + i,
- hash=np.random.randint(1e4),
- format=self.save_format)
- img.save(os.path.join(self.save_to_dir, fname))
- if self.y is None:
- return batch_x
- batch_y = self.y[index_array]
- return batch_x, batch_y
-
-
-def _count_valid_files_in_directory(directory, white_list_formats,
- follow_links):
- """Count files with extension in `white_list_formats` in a directory.
-
- Arguments:
- directory: absolute path to the directory containing files to be counted
- white_list_formats: set of strings containing allowed extensions for
- the files to be counted.
- follow_links: boolean.
-
- Returns:
- the count of files with extension in `white_list_formats` contained in
- the directory.
- """
-
- def _recursive_list(subpath):
- return sorted(
- os.walk(subpath, followlinks=follow_links), key=lambda tpl: tpl[0])
-
- samples = 0
- for _, _, files in _recursive_list(directory):
- for fname in files:
- is_valid = False
- for extension in white_list_formats:
- if fname.lower().endswith('.' + extension):
- is_valid = True
- break
- if is_valid:
- samples += 1
- return samples
-
-
-def _list_valid_filenames_in_directory(directory, white_list_formats,
- class_indices, follow_links):
- """List paths of files in `subdir` with extensions in `white_list_formats`.
-
- Arguments:
- directory: absolute path to a directory containing the files to list.
- The directory name is used as class label and must be a key of
- `class_indices`.
- white_list_formats: set of strings containing allowed extensions for
- the files to be counted.
- class_indices: dictionary mapping a class name to its index.
- follow_links: boolean.
-
- Returns:
- classes: a list of class indices
- filenames: the path of valid files in `directory`, relative from
- `directory`'s parent (e.g., if `directory` is "dataset/class1",
- the filenames will be ["class1/file1.jpg", "class1/file2.jpg", ...]).
- """
-
- def _recursive_list(subpath):
- return sorted(
- os.walk(subpath, followlinks=follow_links), key=lambda tpl: tpl[0])
-
- classes = []
- filenames = []
- subdir = os.path.basename(directory)
- basedir = os.path.dirname(directory)
- for root, _, files in _recursive_list(directory):
- for fname in files:
- is_valid = False
- for extension in white_list_formats:
- if fname.lower().endswith('.' + extension):
- is_valid = True
- break
- if is_valid:
- classes.append(class_indices[subdir])
- # add filename relative to directory
- absolute_path = os.path.join(root, fname)
- filenames.append(os.path.relpath(absolute_path, basedir))
- return classes, filenames
-
-
-class DirectoryIterator(Iterator):
- """Iterator capable of reading images from a directory on disk.
-
- Arguments:
- directory: Path to the directory to read images from.
- Each subdirectory in this directory will be
- considered to contain images from one class,
- or alternatively you could specify class subdirectories
- via the `classes` argument.
- image_data_generator: Instance of `ImageDataGenerator`
- to use for random transformations and normalization.
- target_size: tuple of integers, dimensions to resize input images to.
- color_mode: One of `"rgb"`, `"grayscale"`. Color mode to read images.
- classes: Optional list of strings, names of sudirectories
- containing images from each class (e.g. `["dogs", "cats"]`).
- It will be computed automatically if not set.
- class_mode: Mode for yielding the targets:
- `"binary"`: binary targets (if there are only two classes),
- `"categorical"`: categorical targets,
- `"sparse"`: integer targets,
- `"input"`: targets are images identical to input images (mainly
- used to work with autoencoders),
- `None`: no targets get yielded (only input images are yielded).
- batch_size: Integer, size of a batch.
- shuffle: Boolean, whether to shuffle the data between epochs.
- seed: Random seed for data shuffling.
- data_format: String, one of `channels_first`, `channels_last`.
- save_to_dir: Optional directory where to save the pictures
- being yielded, in a viewable format. This is useful
- for visualizing the random transformations being
- applied, for debugging purposes.
- save_prefix: String prefix to use for saving sample
- images (if `save_to_dir` is set).
- save_format: Format to use for saving sample images
- (if `save_to_dir` is set).
- """
-
- def __init__(self,
- directory,
- image_data_generator,
- target_size=(256, 256),
- color_mode='rgb',
- classes=None,
- class_mode='categorical',
- batch_size=32,
- shuffle=True,
- seed=None,
- data_format=None,
- save_to_dir=None,
- save_prefix='',
- save_format='png',
- follow_links=False):
- if data_format is None:
- data_format = K.image_data_format()
- self.directory = directory
- self.image_data_generator = image_data_generator
- self.target_size = tuple(target_size)
- if color_mode not in {'rgb', 'grayscale'}:
- raise ValueError('Invalid color mode:', color_mode,
- '; expected "rgb" or "grayscale".')
- self.color_mode = color_mode
- self.data_format = data_format
- if self.color_mode == 'rgb':
- if self.data_format == 'channels_last':
- self.image_shape = self.target_size + (3,)
- else:
- self.image_shape = (3,) + self.target_size
- else:
- if self.data_format == 'channels_last':
- self.image_shape = self.target_size + (1,)
- else:
- self.image_shape = (1,) + self.target_size
- self.classes = classes
- if class_mode not in {'categorical', 'binary', 'sparse', 'input', None}:
- raise ValueError('Invalid class_mode:', class_mode,
- '; expected one of "categorical", '
- '"binary", "sparse", "input"'
- ' or None.')
- self.class_mode = class_mode
- self.save_to_dir = save_to_dir
- self.save_prefix = save_prefix
- self.save_format = save_format
-
- white_list_formats = {'png', 'jpg', 'jpeg', 'bmp', 'ppm'}
-
- # first, count the number of samples and classes
- self.samples = 0
-
- if not classes:
- classes = []
- for subdir in sorted(os.listdir(directory)):
- if os.path.isdir(os.path.join(directory, subdir)):
- classes.append(subdir)
- self.num_class = len(classes)
- self.class_indices = dict(zip(classes, range(len(classes))))
-
- pool = multiprocessing.pool.ThreadPool()
- function_partial = partial(
- _count_valid_files_in_directory,
- white_list_formats=white_list_formats,
- follow_links=follow_links)
- self.samples = sum(
- pool.map(function_partial, (os.path.join(directory, subdir)
- for subdir in classes)))
-
- print('Found %d images belonging to %d classes.' % (self.samples,
- self.num_class))
-
- # second, build an index of the images in the different class subfolders
- results = []
-
- self.filenames = []
- self.classes = np.zeros((self.samples,), dtype='int32')
- i = 0
- for dirpath in (os.path.join(directory, subdir) for subdir in classes):
- results.append(
- pool.apply_async(_list_valid_filenames_in_directory, (
- dirpath, white_list_formats, self.class_indices, follow_links)))
- for res in results:
- classes, filenames = res.get()
- self.classes[i:i + len(classes)] = classes
- self.filenames += filenames
- i += len(classes)
- pool.close()
- pool.join()
- super(DirectoryIterator, self).__init__(self.samples, batch_size, shuffle,
- seed)
-
- def next(self):
- """For python 2.x.
-
- Returns:
- The next batch.
- """
- with self.lock:
- index_array, current_index, current_batch_size = next(
- self.index_generator)
- # The transformation of images is not under thread lock
- # so it can be done in parallel
- batch_x = np.zeros(
- (current_batch_size,) + self.image_shape, dtype=K.floatx())
- grayscale = self.color_mode == 'grayscale'
- # build batch of image data
- for i, j in enumerate(index_array):
- fname = self.filenames[j]
- img = load_img(
- os.path.join(self.directory, fname),
- grayscale=grayscale,
- target_size=self.target_size)
- x = img_to_array(img, data_format=self.data_format)
- x = self.image_data_generator.random_transform(x)
- x = self.image_data_generator.standardize(x)
- batch_x[i] = x
- # optionally save augmented images to disk for debugging purposes
- if self.save_to_dir:
- for i in range(current_batch_size):
- img = array_to_img(batch_x[i], self.data_format, scale=True)
- fname = '{prefix}_{index}_{hash}.{format}'.format(
- prefix=self.save_prefix,
- index=current_index + i,
- hash=np.random.randint(1e4),
- format=self.save_format)
- img.save(os.path.join(self.save_to_dir, fname))
- # build batch of labels
- if self.class_mode == 'input':
- batch_y = batch_x.copy()
- elif self.class_mode == 'sparse':
- batch_y = self.classes[index_array]
- elif self.class_mode == 'binary':
- batch_y = self.classes[index_array].astype(K.floatx())
- elif self.class_mode == 'categorical':
- batch_y = np.zeros((len(batch_x), self.num_class), dtype=K.floatx())
- for i, label in enumerate(self.classes[index_array]):
- batch_y[i, label] = 1.
- else:
- return batch_x
- return batch_x, batch_y
diff --git a/tensorflow/contrib/keras/python/keras/preprocessing/image_test.py b/tensorflow/contrib/keras/python/keras/preprocessing/image_test.py
deleted file mode 100644
index d9ecb19003..0000000000
--- a/tensorflow/contrib/keras/python/keras/preprocessing/image_test.py
+++ /dev/null
@@ -1,254 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for image preprocessing utils."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import os
-import shutil
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-try:
- import PIL # pylint:disable=g-import-not-at-top
-except ImportError:
- PIL = None
-
-
-def _generate_test_images():
- img_w = img_h = 20
- rgb_images = []
- gray_images = []
- for _ in range(8):
- bias = np.random.rand(img_w, img_h, 1) * 64
- variance = np.random.rand(img_w, img_h, 1) * (255 - 64)
- imarray = np.random.rand(img_w, img_h, 3) * variance + bias
- im = keras.preprocessing.image.array_to_img(imarray, scale=False)
- rgb_images.append(im)
-
- imarray = np.random.rand(img_w, img_h, 1) * variance + bias
- im = keras.preprocessing.image.array_to_img(imarray, scale=False)
- gray_images.append(im)
-
- return [rgb_images, gray_images]
-
-
-class TestImage(test.TestCase):
-
- def test_image_data_generator(self):
- if PIL is None:
- return # Skip test if PIL is not available.
-
- for test_images in _generate_test_images():
- img_list = []
- for im in test_images:
- img_list.append(keras.preprocessing.image.img_to_array(im)[None, ...])
-
- images = np.vstack(img_list)
- generator = keras.preprocessing.image.ImageDataGenerator(
- featurewise_center=True,
- samplewise_center=True,
- featurewise_std_normalization=True,
- samplewise_std_normalization=True,
- zca_whitening=True,
- rotation_range=90.,
- width_shift_range=0.1,
- height_shift_range=0.1,
- shear_range=0.5,
- zoom_range=0.2,
- channel_shift_range=0.,
- fill_mode='nearest',
- cval=0.5,
- horizontal_flip=True,
- vertical_flip=True)
- # Basic test before fit
- x = np.random.random((32, 10, 10, 3))
- generator.flow(x)
-
- # Fit
- generator.fit(images, augment=True)
-
- for x, _ in generator.flow(
- images,
- np.arange(images.shape[0]),
- shuffle=True):
- self.assertEqual(x.shape[1:], images.shape[1:])
- break
-
- def test_image_data_generator_invalid_data(self):
- generator = keras.preprocessing.image.ImageDataGenerator(
- featurewise_center=True,
- samplewise_center=True,
- featurewise_std_normalization=True,
- samplewise_std_normalization=True,
- zca_whitening=True,
- data_format='channels_last')
-
- # Test fit with invalid data
- with self.assertRaises(ValueError):
- x = np.random.random((3, 10, 10))
- generator.fit(x)
- # Test flow with invalid data
- with self.assertRaises(ValueError):
- generator.flow(np.arange(5))
- # Invalid number of channels: will work but raise a warning
- x = np.random.random((32, 10, 10, 5))
- generator.flow(x)
-
- with self.assertRaises(ValueError):
- generator = keras.preprocessing.image.ImageDataGenerator(
- data_format='unknown')
-
- generator = keras.preprocessing.image.ImageDataGenerator(
- zoom_range=(2, 2))
- with self.assertRaises(ValueError):
- generator = keras.preprocessing.image.ImageDataGenerator(
- zoom_range=(2, 2, 2))
-
- def test_image_data_generator_fit(self):
- generator = keras.preprocessing.image.ImageDataGenerator(
- featurewise_center=True,
- samplewise_center=True,
- featurewise_std_normalization=True,
- samplewise_std_normalization=True,
- zca_whitening=True,
- data_format='channels_last')
- # Test grayscale
- x = np.random.random((32, 10, 10, 1))
- generator.fit(x)
- # Test RBG
- x = np.random.random((32, 10, 10, 3))
- generator.fit(x)
- generator = keras.preprocessing.image.ImageDataGenerator(
- featurewise_center=True,
- samplewise_center=True,
- featurewise_std_normalization=True,
- samplewise_std_normalization=True,
- zca_whitening=True,
- data_format='channels_first')
- # Test grayscale
- x = np.random.random((32, 1, 10, 10))
- generator.fit(x)
- # Test RBG
- x = np.random.random((32, 3, 10, 10))
- generator.fit(x)
-
- def test_directory_iterator(self):
- if PIL is None:
- return # Skip test if PIL is not available.
-
- num_classes = 2
-
- temp_dir = self.get_temp_dir()
- self.addCleanup(shutil.rmtree, temp_dir)
-
- # create folders and subfolders
- paths = []
- for cl in range(num_classes):
- class_directory = 'class-{}'.format(cl)
- classpaths = [
- class_directory, os.path.join(class_directory, 'subfolder-1'),
- os.path.join(class_directory, 'subfolder-2'), os.path.join(
- class_directory, 'subfolder-1', 'sub-subfolder')
- ]
- for path in classpaths:
- os.mkdir(os.path.join(temp_dir, path))
- paths.append(classpaths)
-
- # save the images in the paths
- count = 0
- filenames = []
- for test_images in _generate_test_images():
- for im in test_images:
- # rotate image class
- im_class = count % num_classes
- # rotate subfolders
- classpaths = paths[im_class]
- filename = os.path.join(classpaths[count % len(classpaths)],
- 'image-{}.jpg'.format(count))
- filenames.append(filename)
- im.save(os.path.join(temp_dir, filename))
- count += 1
-
- # Test image loading util
- fname = os.path.join(temp_dir, filenames[0])
- _ = keras.preprocessing.image.load_img(fname)
- _ = keras.preprocessing.image.load_img(fname, grayscale=True)
- _ = keras.preprocessing.image.load_img(fname, target_size=(10, 10))
-
- # create iterator
- generator = keras.preprocessing.image.ImageDataGenerator()
- dir_iterator = generator.flow_from_directory(temp_dir)
-
- # check number of classes and images
- self.assertEqual(len(dir_iterator.class_indices), num_classes)
- self.assertEqual(len(dir_iterator.classes), count)
- self.assertEqual(sorted(dir_iterator.filenames), sorted(filenames))
- _ = dir_iterator.next()
-
- def test_img_utils(self):
- if PIL is None:
- return # Skip test if PIL is not available.
-
- height, width = 10, 8
-
- # Test channels_first data format
- x = np.random.random((3, height, width))
- img = keras.preprocessing.image.array_to_img(
- x, data_format='channels_first')
- self.assertEqual(img.size, (width, height))
- x = keras.preprocessing.image.img_to_array(
- img, data_format='channels_first')
- self.assertEqual(x.shape, (3, height, width))
- # Test 2D
- x = np.random.random((1, height, width))
- img = keras.preprocessing.image.array_to_img(
- x, data_format='channels_first')
- self.assertEqual(img.size, (width, height))
- x = keras.preprocessing.image.img_to_array(
- img, data_format='channels_first')
- self.assertEqual(x.shape, (1, height, width))
-
- # Test channels_last data format
- x = np.random.random((height, width, 3))
- img = keras.preprocessing.image.array_to_img(x, data_format='channels_last')
- self.assertEqual(img.size, (width, height))
- x = keras.preprocessing.image.img_to_array(img, data_format='channels_last')
- self.assertEqual(x.shape, (height, width, 3))
- # Test 2D
- x = np.random.random((height, width, 1))
- img = keras.preprocessing.image.array_to_img(x, data_format='channels_last')
- self.assertEqual(img.size, (width, height))
- x = keras.preprocessing.image.img_to_array(img, data_format='channels_last')
- self.assertEqual(x.shape, (height, width, 1))
-
- def test_img_transforms(self):
- x = np.random.random((3, 200, 200))
- _ = keras.preprocessing.image.random_rotation(x, 20)
- _ = keras.preprocessing.image.random_shift(x, 0.2, 0.2)
- _ = keras.preprocessing.image.random_shear(x, 2.)
- _ = keras.preprocessing.image.random_zoom(x, (0.5, 0.5))
- with self.assertRaises(ValueError):
- keras.preprocessing.image.random_zoom(x, (0, 0, 0))
- _ = keras.preprocessing.image.random_channel_shift(x, 2.)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/preprocessing/sequence.py b/tensorflow/contrib/keras/python/keras/preprocessing/sequence.py
deleted file mode 100644
index a5deec87af..0000000000
--- a/tensorflow/contrib/keras/python/keras/preprocessing/sequence.py
+++ /dev/null
@@ -1,226 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Preprocessing utilities for sequence data.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import random
-
-import numpy as np
-from six.moves import range # pylint: disable=redefined-builtin
-
-
-def pad_sequences(sequences,
- maxlen=None,
- dtype='int32',
- padding='pre',
- truncating='pre',
- value=0.):
- """Pads each sequence to the same length (length of the longest sequence).
-
- If maxlen is provided, any sequence longer
- than maxlen is truncated to maxlen.
- Truncation happens off either the beginning (default) or
- the end of the sequence.
-
- Supports post-padding and pre-padding (default).
-
- Arguments:
- sequences: list of lists where each element is a sequence
- maxlen: int, maximum length
- dtype: type to cast the resulting sequence.
- padding: 'pre' or 'post', pad either before or after each sequence.
- truncating: 'pre' or 'post', remove values from sequences larger than
- maxlen either in the beginning or in the end of the sequence
- value: float, value to pad the sequences to the desired value.
-
- Returns:
- x: numpy array with dimensions (number_of_sequences, maxlen)
-
- Raises:
- ValueError: in case of invalid values for `truncating` or `padding`,
- or in case of invalid shape for a `sequences` entry.
- """
- if not hasattr(sequences, '__len__'):
- raise ValueError('`sequences` must be iterable.')
- lengths = []
- for x in sequences:
- if not hasattr(x, '__len__'):
- raise ValueError('`sequences` must be a list of iterables. '
- 'Found non-iterable: ' + str(x))
- lengths.append(len(x))
-
- num_samples = len(sequences)
- if maxlen is None:
- maxlen = np.max(lengths)
-
- # take the sample shape from the first non empty sequence
- # checking for consistency in the main loop below.
- sample_shape = tuple()
- for s in sequences:
- if len(s) > 0: # pylint: disable=g-explicit-length-test
- sample_shape = np.asarray(s).shape[1:]
- break
-
- x = (np.ones((num_samples, maxlen) + sample_shape) * value).astype(dtype)
- for idx, s in enumerate(sequences):
- if not len(s): # pylint: disable=g-explicit-length-test
- continue # empty list/array was found
- if truncating == 'pre':
- trunc = s[-maxlen:] # pylint: disable=invalid-unary-operand-type
- elif truncating == 'post':
- trunc = s[:maxlen]
- else:
- raise ValueError('Truncating type "%s" not understood' % truncating)
-
- # check `trunc` has expected shape
- trunc = np.asarray(trunc, dtype=dtype)
- if trunc.shape[1:] != sample_shape:
- raise ValueError(
- 'Shape of sample %s of sequence at position %s is different from '
- 'expected shape %s'
- % (trunc.shape[1:], idx, sample_shape))
-
- if padding == 'post':
- x[idx, :len(trunc)] = trunc
- elif padding == 'pre':
- x[idx, -len(trunc):] = trunc
- else:
- raise ValueError('Padding type "%s" not understood' % padding)
- return x
-
-
-def make_sampling_table(size, sampling_factor=1e-5):
- """Generates a word rank-based probabilistic sampling table.
-
- This generates an array where the ith element
- is the probability that a word of rank i would be sampled,
- according to the sampling distribution used in word2vec.
-
- The word2vec formula is:
- p(word) = min(1, sqrt(word.frequency/sampling_factor) /
- (word.frequency/sampling_factor))
-
- We assume that the word frequencies follow Zipf's law (s=1) to derive
- a numerical approximation of frequency(rank):
- frequency(rank) ~ 1/(rank * (log(rank) + gamma) + 1/2 - 1/(12*rank))
- where gamma is the Euler-Mascheroni constant.
-
- Arguments:
- size: int, number of possible words to sample.
- sampling_factor: the sampling factor in the word2vec formula.
-
- Returns:
- A 1D Numpy array of length `size` where the ith entry
- is the probability that a word of rank i should be sampled.
- """
- gamma = 0.577
- rank = np.array(list(range(size)))
- rank[0] = 1
- inv_fq = rank * (np.log(rank) + gamma) + 0.5 - 1. / (12. * rank)
- f = sampling_factor * inv_fq
-
- return np.minimum(1., f / np.sqrt(f))
-
-
-def skipgrams(sequence,
- vocabulary_size,
- window_size=4,
- negative_samples=1.,
- shuffle=True,
- categorical=False,
- sampling_table=None,
- seed=None):
- """Generates skipgram word pairs.
-
- Takes a sequence (list of indexes of words),
- returns couples of [word_index, other_word index] and labels (1s or 0s),
- where label = 1 if 'other_word' belongs to the context of 'word',
- and label=0 if 'other_word' is randomly sampled
-
- Arguments:
- sequence: a word sequence (sentence), encoded as a list
- of word indices (integers). If using a `sampling_table`,
- word indices are expected to match the rank
- of the words in a reference dataset (e.g. 10 would encode
- the 10-th most frequently occurring token).
- Note that index 0 is expected to be a non-word and will be skipped.
- vocabulary_size: int. maximum possible word index + 1
- window_size: int. actually half-window.
- The window of a word wi will be [i-window_size, i+window_size+1]
- negative_samples: float >= 0. 0 for no negative (=random) samples.
- 1 for same number as positive samples. etc.
- shuffle: whether to shuffle the word couples before returning them.
- categorical: bool. if False, labels will be
- integers (eg. [0, 1, 1 .. ]),
- if True labels will be categorical eg. [[1,0],[0,1],[0,1] .. ]
- sampling_table: 1D array of size `vocabulary_size` where the entry i
- encodes the probabibily to sample a word of rank i.
- seed: Random seed.
-
- Returns:
- couples, labels: where `couples` are int pairs and
- `labels` are either 0 or 1.
-
- # Note
- By convention, index 0 in the vocabulary is
- a non-word and will be skipped.
- """
- couples = []
- labels = []
- for i, wi in enumerate(sequence):
- if not wi:
- continue
- if sampling_table is not None:
- if sampling_table[wi] < random.random():
- continue
-
- window_start = max(0, i - window_size)
- window_end = min(len(sequence), i + window_size + 1)
- for j in range(window_start, window_end):
- if j != i:
- wj = sequence[j]
- if not wj:
- continue
- couples.append([wi, wj])
- if categorical:
- labels.append([0, 1])
- else:
- labels.append(1)
-
- if negative_samples > 0:
- num_negative_samples = int(len(labels) * negative_samples)
- words = [c[0] for c in couples]
- random.shuffle(words)
-
- couples += [[words[i % len(words)],
- random.randint(1, vocabulary_size - 1)]
- for i in range(num_negative_samples)]
- if categorical:
- labels += [[1, 0]] * num_negative_samples
- else:
- labels += [0] * num_negative_samples
-
- if shuffle:
- if seed is None:
- seed = random.randint(0, 10e6)
- random.seed(seed)
- random.shuffle(couples)
- random.seed(seed)
- random.shuffle(labels)
-
- return couples, labels
diff --git a/tensorflow/contrib/keras/python/keras/preprocessing/sequence_test.py b/tensorflow/contrib/keras/python/keras/preprocessing/sequence_test.py
deleted file mode 100644
index 4e54b95c8b..0000000000
--- a/tensorflow/contrib/keras/python/keras/preprocessing/sequence_test.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for sequence data preprocessing utils."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-class TestSequence(test.TestCase):
-
- def test_pad_sequences(self):
- a = [[1], [1, 2], [1, 2, 3]]
-
- # test padding
- b = keras.preprocessing.sequence.pad_sequences(a, maxlen=3, padding='pre')
- self.assertAllClose(b, [[0, 0, 1], [0, 1, 2], [1, 2, 3]])
- b = keras.preprocessing.sequence.pad_sequences(a, maxlen=3, padding='post')
- self.assertAllClose(b, [[1, 0, 0], [1, 2, 0], [1, 2, 3]])
-
- # test truncating
- b = keras.preprocessing.sequence.pad_sequences(
- a, maxlen=2, truncating='pre')
- self.assertAllClose(b, [[0, 1], [1, 2], [2, 3]])
- b = keras.preprocessing.sequence.pad_sequences(
- a, maxlen=2, truncating='post')
- self.assertAllClose(b, [[0, 1], [1, 2], [1, 2]])
-
- # test value
- b = keras.preprocessing.sequence.pad_sequences(a, maxlen=3, value=1)
- self.assertAllClose(b, [[1, 1, 1], [1, 1, 2], [1, 2, 3]])
-
- def test_pad_sequences_vector(self):
- a = [[[1, 1]], [[2, 1], [2, 2]], [[3, 1], [3, 2], [3, 3]]]
-
- # test padding
- b = keras.preprocessing.sequence.pad_sequences(a, maxlen=3, padding='pre')
- self.assertAllClose(b, [[[0, 0], [0, 0], [1, 1]], [[0, 0], [2, 1], [2, 2]],
- [[3, 1], [3, 2], [3, 3]]])
- b = keras.preprocessing.sequence.pad_sequences(a, maxlen=3, padding='post')
- self.assertAllClose(b, [[[1, 1], [0, 0], [0, 0]], [[2, 1], [2, 2], [0, 0]],
- [[3, 1], [3, 2], [3, 3]]])
-
- # test truncating
- b = keras.preprocessing.sequence.pad_sequences(
- a, maxlen=2, truncating='pre')
- self.assertAllClose(b, [[[0, 0], [1, 1]], [[2, 1], [2, 2]], [[3, 2], [3,
- 3]]])
-
- b = keras.preprocessing.sequence.pad_sequences(
- a, maxlen=2, truncating='post')
- self.assertAllClose(b, [[[0, 0], [1, 1]], [[2, 1], [2, 2]], [[3, 1], [3,
- 2]]])
-
- # test value
- b = keras.preprocessing.sequence.pad_sequences(a, maxlen=3, value=1)
- self.assertAllClose(b, [[[1, 1], [1, 1], [1, 1]], [[1, 1], [2, 1], [2, 2]],
- [[3, 1], [3, 2], [3, 3]]])
-
- def test_make_sampling_table(self):
- a = keras.preprocessing.sequence.make_sampling_table(3)
- self.assertAllClose(
- a, np.asarray([0.00315225, 0.00315225, 0.00547597]), rtol=.1)
-
- def test_skipgrams(self):
- # test with no window size and binary labels
- couples, labels = keras.preprocessing.sequence.skipgrams(
- np.arange(3), vocabulary_size=3)
- for couple in couples:
- assert couple[0] in [0, 1, 2] and couple[1] in [0, 1, 2]
-
- # test window size and categorical labels
- couples, labels = keras.preprocessing.sequence.skipgrams(
- np.arange(5), vocabulary_size=5, window_size=1, categorical=True)
- for couple in couples:
- assert couple[0] - couple[1] <= 3
- for l in labels:
- assert len(l) == 2
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/preprocessing/text.py b/tensorflow/contrib/keras/python/keras/preprocessing/text.py
deleted file mode 100644
index 47e5aa064f..0000000000
--- a/tensorflow/contrib/keras/python/keras/preprocessing/text.py
+++ /dev/null
@@ -1,322 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Utilities for text input preprocessing.
-
-May benefit from a fast Cython rewrite.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from collections import OrderedDict
-from hashlib import md5
-import string
-import sys
-
-import numpy as np
-from six.moves import range # pylint: disable=redefined-builtin
-from six.moves import zip # pylint: disable=redefined-builtin
-
-if sys.version_info < (3,):
- maketrans = string.maketrans
-else:
- maketrans = str.maketrans
-
-
-def text_to_word_sequence(text,
- filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n',
- lower=True,
- split=' '):
- """Converts a text to a sequence of words (or tokens).
-
- Arguments:
- text: Input text (string).
- filters: Sequence of characters to filter out.
- lower: Whether to convert the input to lowercase.
- split: Sentence split marker (string).
-
- Returns:
- A list of words (or tokens).
- """
- if lower:
- text = text.lower()
-
- if sys.version_info < (3,) and isinstance(text, unicode):
- translate_map = dict((ord(c), unicode(split)) for c in filters)
- else:
- translate_map = maketrans(filters, split * len(filters))
-
- text = text.translate(translate_map)
- seq = text.split(split)
- return [i for i in seq if i]
-
-
-def one_hot(text,
- n,
- filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n',
- lower=True,
- split=' '):
- return hashing_trick(
- text, n, hash_function=hash, filters=filters, lower=lower, split=split)
-
-
-def hashing_trick(text,
- n,
- hash_function=None,
- filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n',
- lower=True,
- split=' '):
- """Converts a text to a sequence of indexes in a fixed-size hashing space.
-
- Arguments:
- text: Input text (string).
- n: Dimension of the hashing space.
- hash_function: if `None` uses python `hash` function, can be 'md5' or
- any function that takes in input a string and returns a int.
- Note that `hash` is not a stable hashing function, so
- it is not consistent across different runs, while 'md5'
- is a stable hashing function.
- filters: Sequence of characters to filter out.
- lower: Whether to convert the input to lowercase.
- split: Sentence split marker (string).
-
- Returns:
- A list of integer word indices (unicity non-guaranteed).
-
- `0` is a reserved index that won't be assigned to any word.
-
- Two or more words may be assigned to the same index, due to possible
- collisions by the hashing function.
- """
- if hash_function is None:
- hash_function = hash
- elif hash_function == 'md5':
- hash_function = lambda w: int(md5(w.encode()).hexdigest(), 16)
-
- seq = text_to_word_sequence(text, filters=filters, lower=lower, split=split)
- return [(hash_function(w) % (n - 1) + 1) for w in seq]
-
-
-class Tokenizer(object):
- """Text tokenization utility class.
-
- This class allows to vectorize a text corpus, by turning each
- text into either a sequence of integers (each integer being the index
- of a token in a dictionary) or into a vector where the coefficient
- for each token could be binary, based on word count, based on tf-idf...
-
- Arguments:
- num_words: the maximum number of words to keep, based
- on word frequency. Only the most common `num_words` words will
- be kept.
- filters: a string where each element is a character that will be
- filtered from the texts. The default is all punctuation, plus
- tabs and line breaks, minus the `'` character.
- lower: boolean. Whether to convert the texts to lowercase.
- split: character or string to use for token splitting.
- char_level: if True, every character will be treated as a token.
-
- By default, all punctuation is removed, turning the texts into
- space-separated sequences of words
- (words maybe include the `'` character). These sequences are then
- split into lists of tokens. They will then be indexed or vectorized.
-
- `0` is a reserved index that won't be assigned to any word.
- """
-
- def __init__(self,
- num_words=None,
- filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n',
- lower=True,
- split=' ',
- char_level=False):
- self.word_counts = OrderedDict()
- self.word_docs = {}
- self.filters = filters
- self.split = split
- self.lower = lower
- self.num_words = num_words
- self.document_count = 0
- self.char_level = char_level
-
- def fit_on_texts(self, texts):
- """Updates internal vocabulary based on a list of texts.
-
- Required before using `texts_to_sequences` or `texts_to_matrix`.
-
- Arguments:
- texts: can be a list of strings,
- or a generator of strings (for memory-efficiency)
- """
- self.document_count = 0
- for text in texts:
- self.document_count += 1
- seq = text if self.char_level else text_to_word_sequence(
- text, self.filters, self.lower, self.split)
- for w in seq:
- if w in self.word_counts:
- self.word_counts[w] += 1
- else:
- self.word_counts[w] = 1
- for w in set(seq):
- if w in self.word_docs:
- self.word_docs[w] += 1
- else:
- self.word_docs[w] = 1
-
- wcounts = list(self.word_counts.items())
- wcounts.sort(key=lambda x: x[1], reverse=True)
- sorted_voc = [wc[0] for wc in wcounts]
- # note that index 0 is reserved, never assigned to an existing word
- self.word_index = dict(
- list(zip(sorted_voc, list(range(1, len(sorted_voc) + 1)))))
-
- self.index_docs = {}
- for w, c in list(self.word_docs.items()):
- self.index_docs[self.word_index[w]] = c
-
- def fit_on_sequences(self, sequences):
- """Updates internal vocabulary based on a list of sequences.
-
- Required before using `sequences_to_matrix`
- (if `fit_on_texts` was never called).
-
- Arguments:
- sequences: A list of sequence.
- A "sequence" is a list of integer word indices.
- """
- self.document_count = len(sequences)
- self.index_docs = {}
- for seq in sequences:
- seq = set(seq)
- for i in seq:
- if i not in self.index_docs:
- self.index_docs[i] = 1
- else:
- self.index_docs[i] += 1
-
- def texts_to_sequences(self, texts):
- """Transforms each text in texts in a sequence of integers.
-
- Only top "num_words" most frequent words will be taken into account.
- Only words known by the tokenizer will be taken into account.
-
- Arguments:
- texts: A list of texts (strings).
-
- Returns:
- A list of sequences.
- """
- res = []
- for vect in self.texts_to_sequences_generator(texts):
- res.append(vect)
- return res
-
- def texts_to_sequences_generator(self, texts):
- """Transforms each text in texts in a sequence of integers.
-
- Only top "num_words" most frequent words will be taken into account.
- Only words known by the tokenizer will be taken into account.
-
- Arguments:
- texts: A list of texts (strings).
-
- Yields:
- Yields individual sequences.
- """
- num_words = self.num_words
- for text in texts:
- seq = text if self.char_level else text_to_word_sequence(
- text, self.filters, self.lower, self.split)
- vect = []
- for w in seq:
- i = self.word_index.get(w)
- if i is not None:
- if num_words and i >= num_words:
- continue
- else:
- vect.append(i)
- yield vect
-
- def texts_to_matrix(self, texts, mode='binary'):
- """Convert a list of texts to a Numpy matrix.
-
- Arguments:
- texts: list of strings.
- mode: one of "binary", "count", "tfidf", "freq".
-
- Returns:
- A Numpy matrix.
- """
- sequences = self.texts_to_sequences(texts)
- return self.sequences_to_matrix(sequences, mode=mode)
-
- def sequences_to_matrix(self, sequences, mode='binary'):
- """Converts a list of sequences into a Numpy matrix.
-
- Arguments:
- sequences: list of sequences
- (a sequence is a list of integer word indices).
- mode: one of "binary", "count", "tfidf", "freq"
-
- Returns:
- A Numpy matrix.
-
- Raises:
- ValueError: In case of invalid `mode` argument,
- or if the Tokenizer requires to be fit to sample data.
- """
- if not self.num_words:
- if self.word_index:
- num_words = len(self.word_index) + 1
- else:
- raise ValueError('Specify a dimension (num_words argument), '
- 'or fit on some text data first.')
- else:
- num_words = self.num_words
-
- if mode == 'tfidf' and not self.document_count:
- raise ValueError('Fit the Tokenizer on some data '
- 'before using tfidf mode.')
-
- x = np.zeros((len(sequences), num_words))
- for i, seq in enumerate(sequences):
- if not seq:
- continue
- counts = {}
- for j in seq:
- if j >= num_words:
- continue
- if j not in counts:
- counts[j] = 1.
- else:
- counts[j] += 1
- for j, c in list(counts.items()):
- if mode == 'count':
- x[i][j] = c
- elif mode == 'freq':
- x[i][j] = c / len(seq)
- elif mode == 'binary':
- x[i][j] = 1
- elif mode == 'tfidf':
- # Use weighting scheme 2 in
- # https://en.wikipedia.org/wiki/Tf%E2%80%93idf
- tf = 1 + np.log(c)
- idf = np.log(1 + self.document_count /
- (1 + self.index_docs.get(j, 0)))
- x[i][j] = tf * idf
- else:
- raise ValueError('Unknown vectorization mode:', mode)
- return x
diff --git a/tensorflow/contrib/keras/python/keras/preprocessing/text_test.py b/tensorflow/contrib/keras/python/keras/preprocessing/text_test.py
deleted file mode 100644
index 7deeff0873..0000000000
--- a/tensorflow/contrib/keras/python/keras/preprocessing/text_test.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for text data preprocessing utils."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-class TestText(test.TestCase):
-
- def test_one_hot(self):
- text = 'The cat sat on the mat.'
- encoded = keras.preprocessing.text.one_hot(text, 5)
- self.assertEqual(len(encoded), 6)
- self.assertLessEqual(np.max(encoded), 4)
- self.assertGreaterEqual(np.min(encoded), 0)
-
- # Test on unicode.
- text = u'The cat sat on the mat.'
- encoded = keras.preprocessing.text.one_hot(text, 5)
- self.assertEqual(len(encoded), 6)
- self.assertLessEqual(np.max(encoded), 4)
- self.assertGreaterEqual(np.min(encoded), 0)
-
- def test_tokenizer(self):
- texts = [
- 'The cat sat on the mat.',
- 'The dog sat on the log.',
- 'Dogs and cats living together.'
- ]
- tokenizer = keras.preprocessing.text.Tokenizer(num_words=10)
- tokenizer.fit_on_texts(texts)
-
- sequences = []
- for seq in tokenizer.texts_to_sequences_generator(texts):
- sequences.append(seq)
- self.assertLess(np.max(np.max(sequences)), 10)
- self.assertEqual(np.min(np.min(sequences)), 1)
-
- tokenizer.fit_on_sequences(sequences)
-
- for mode in ['binary', 'count', 'tfidf', 'freq']:
- matrix = tokenizer.texts_to_matrix(texts, mode)
- self.assertEqual(matrix.shape, (3, 10))
-
- def test_hashing_trick_hash(self):
- text = 'The cat sat on the mat.'
- encoded = keras.preprocessing.text.hashing_trick(text, 5)
- self.assertEqual(len(encoded), 6)
- self.assertLessEqual(np.max(encoded), 4)
- self.assertGreaterEqual(np.min(encoded), 1)
-
- def test_hashing_trick_md5(self):
- text = 'The cat sat on the mat.'
- encoded = keras.preprocessing.text.hashing_trick(
- text, 5, hash_function='md5')
- self.assertEqual(len(encoded), 6)
- self.assertLessEqual(np.max(encoded), 4)
- self.assertGreaterEqual(np.min(encoded), 1)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/regularizers.py b/tensorflow/contrib/keras/python/keras/regularizers.py
deleted file mode 100644
index 36cc5c47e4..0000000000
--- a/tensorflow/contrib/keras/python/keras/regularizers.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Keras built-in regularizers.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import six
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import deserialize_keras_object
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import serialize_keras_object
-
-
-class Regularizer(object):
- """Regularizer base class.
- """
-
- def __call__(self, x):
- return 0.
-
- @classmethod
- def from_config(cls, config):
- return cls(**config)
-
-
-class L1L2(Regularizer):
- """Regularizer for L1 and L2 regularization.
-
- Arguments:
- l1: Float; L1 regularization factor.
- l2: Float; L2 regularization factor.
- """
-
- def __init__(self, l1=0., l2=0.): # pylint: disable=redefined-outer-name
- self.l1 = K.cast_to_floatx(l1)
- self.l2 = K.cast_to_floatx(l2)
-
- def __call__(self, x):
- regularization = 0.
- if self.l1:
- regularization += K.sum(self.l1 * K.abs(x))
- if self.l2:
- regularization += K.sum(self.l2 * K.square(x))
- return regularization
-
- def get_config(self):
- return {'l1': float(self.l1), 'l2': float(self.l2)}
-
-
-# Aliases.
-
-
-def l1(l=0.01):
- return L1L2(l1=l)
-
-
-def l2(l=0.01):
- return L1L2(l2=l)
-
-
-def l1_l2(l1=0.01, l2=0.01): # pylint: disable=redefined-outer-name
- return L1L2(l1=l1, l2=l2)
-
-
-def serialize(regularizer):
- return serialize_keras_object(regularizer)
-
-
-def deserialize(config, custom_objects=None):
- return deserialize_keras_object(
- config,
- module_objects=globals(),
- custom_objects=custom_objects,
- printable_module_name='regularizer')
-
-
-def get(identifier):
- if identifier is None:
- return None
- if isinstance(identifier, dict):
- return deserialize(identifier)
- elif isinstance(identifier, six.string_types):
- config = {'class_name': str(identifier), 'config': {}}
- return deserialize(config)
- elif callable(identifier):
- return identifier
- else:
- raise ValueError('Could not interpret regularizer identifier:', identifier)
diff --git a/tensorflow/contrib/keras/python/keras/regularizers_test.py b/tensorflow/contrib/keras/python/keras/regularizers_test.py
deleted file mode 100644
index 528024994f..0000000000
--- a/tensorflow/contrib/keras/python/keras/regularizers_test.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for Keras regularizers."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-
-
-DATA_DIM = 5
-NUM_CLASSES = 2
-
-
-def get_data():
- (x_train, y_train), (x_test, y_test) = testing_utils.get_test_data(
- train_samples=10,
- test_samples=10,
- input_shape=(DATA_DIM,),
- num_classes=NUM_CLASSES)
- y_train = keras.utils.to_categorical(y_train, NUM_CLASSES)
- y_test = keras.utils.to_categorical(y_test, NUM_CLASSES)
- return (x_train, y_train), (x_test, y_test)
-
-
-def create_model(kernel_regularizer=None, activity_regularizer=None):
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(NUM_CLASSES,
- kernel_regularizer=kernel_regularizer,
- activity_regularizer=activity_regularizer,
- input_shape=(DATA_DIM,)))
- return model
-
-
-class KerasRegularizersTest(test.TestCase):
-
- def test_kernel_regularization(self):
- with self.test_session():
- (x_train, y_train), _ = get_data()
- for reg in [keras.regularizers.l1(),
- keras.regularizers.l2(),
- keras.regularizers.l1_l2()]:
- model = create_model(kernel_regularizer=reg)
- model.compile(loss='categorical_crossentropy', optimizer='sgd')
- assert len(model.losses) == 1
- model.fit(x_train, y_train, batch_size=10,
- epochs=1, verbose=0)
-
- def test_activity_regularization(self):
- with self.test_session():
- (x_train, y_train), _ = get_data()
- for reg in [keras.regularizers.l1(), keras.regularizers.l2()]:
- model = create_model(activity_regularizer=reg)
- model.compile(loss='categorical_crossentropy', optimizer='sgd')
- assert len(model.losses) == 1
- model.fit(x_train, y_train, batch_size=10,
- epochs=1, verbose=0)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/testing_utils.py b/tensorflow/contrib/keras/python/keras/testing_utils.py
deleted file mode 100644
index 2f51ace945..0000000000
--- a/tensorflow/contrib/keras/python/keras/testing_utils.py
+++ /dev/null
@@ -1,165 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Utilities for unit-testing Keras."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.util import tf_inspect
-
-
-def get_test_data(train_samples,
- test_samples,
- input_shape,
- num_classes):
- """Generates test data to train a model on.
-
- Arguments:
- train_samples: Integer, how many training samples to generate.
- test_samples: Integer, how many test samples to generate.
- input_shape: Tuple of integers, shape of the inputs.
- num_classes: Integer, number of classes for the data and targets.
- Only relevant if `classification=True`.
-
- Returns:
- A tuple of Numpy arrays: `(x_train, y_train), (x_test, y_test)`.
- """
- num_sample = train_samples + test_samples
- templates = 2 * num_classes * np.random.random((num_classes,) + input_shape)
- y = np.random.randint(0, num_classes, size=(num_sample,))
- x = np.zeros((num_sample,) + input_shape)
- for i in range(num_sample):
- x[i] = templates[y[i]] + np.random.normal(loc=0, scale=1., size=input_shape)
- return ((x[:train_samples], y[:train_samples]),
- (x[train_samples:], y[train_samples:]))
-
-
-def layer_test(layer_cls, kwargs=None, input_shape=None, input_dtype=None,
- input_data=None, expected_output=None,
- expected_output_dtype=None):
- """Test routine for a layer with a single input and single output.
-
- Arguments:
- layer_cls: Layer class object.
- kwargs: Optional dictionary of keyword arguments for instantiating the
- layer.
- input_shape: Input shape tuple.
- input_dtype: Data type of the input data.
- input_data: Numpy array of input data.
- expected_output: Shape tuple for the expected shape of the output.
- expected_output_dtype: Data type expected for the output.
-
- Returns:
- The output data (Numpy array) returned by the layer, for additional
- checks to be done by the calling code.
- """
- if input_data is None:
- assert input_shape
- if not input_dtype:
- input_dtype = 'float32'
- input_data_shape = list(input_shape)
- for i, e in enumerate(input_data_shape):
- if e is None:
- input_data_shape[i] = np.random.randint(1, 4)
- input_data = 10 * np.random.random(input_data_shape)
- if input_dtype[:5] == 'float':
- input_data -= 0.5
- input_data = input_data.astype(input_dtype)
- elif input_shape is None:
- input_shape = input_data.shape
- if input_dtype is None:
- input_dtype = input_data.dtype
- if expected_output_dtype is None:
- expected_output_dtype = input_dtype
-
- # instantiation
- kwargs = kwargs or {}
- layer = layer_cls(**kwargs)
-
- # test get_weights , set_weights at layer level
- weights = layer.get_weights()
- layer.set_weights(weights)
-
- # test and instantiation from weights
- if 'weights' in tf_inspect.getargspec(layer_cls.__init__):
- kwargs['weights'] = weights
- layer = layer_cls(**kwargs)
-
- # test in functional API
- x = keras.layers.Input(shape=input_shape[1:], dtype=input_dtype)
- y = layer(x)
- assert keras.backend.dtype(y) == expected_output_dtype
-
- # check shape inference
- model = keras.models.Model(x, y)
- expected_output_shape = tuple(
- layer._compute_output_shape(input_shape).as_list()) # pylint: disable=protected-access
- actual_output = model.predict(input_data)
- actual_output_shape = actual_output.shape
- for expected_dim, actual_dim in zip(expected_output_shape,
- actual_output_shape):
- if expected_dim is not None:
- assert expected_dim == actual_dim
- if expected_output is not None:
- np.testing.assert_allclose(actual_output, expected_output, rtol=1e-3)
-
- # test serialization, weight setting at model level
- model_config = model.get_config()
- recovered_model = keras.models.Model.from_config(model_config)
- if model.weights:
- weights = model.get_weights()
- recovered_model.set_weights(weights)
- output = recovered_model.predict(input_data)
- np.testing.assert_allclose(output, actual_output, rtol=1e-3)
-
- # test training mode (e.g. useful for dropout tests)
- model.compile('rmsprop', 'mse')
- model.train_on_batch(input_data, actual_output)
-
- # test as first layer in Sequential API
- layer_config = layer.get_config()
- layer_config['batch_input_shape'] = input_shape
- layer = layer.__class__.from_config(layer_config)
-
- model = keras.models.Sequential()
- model.add(layer)
- actual_output = model.predict(input_data)
- actual_output_shape = actual_output.shape
- for expected_dim, actual_dim in zip(expected_output_shape,
- actual_output_shape):
- if expected_dim is not None:
- assert expected_dim == actual_dim
- if expected_output is not None:
- np.testing.assert_allclose(actual_output, expected_output, rtol=1e-3)
-
- # test serialization, weight setting at model level
- model_config = model.get_config()
- recovered_model = keras.models.Sequential.from_config(model_config)
- if model.weights:
- weights = model.get_weights()
- recovered_model.set_weights(weights)
- output = recovered_model.predict(input_data)
- np.testing.assert_allclose(output, actual_output, rtol=1e-3)
-
- # test training mode (e.g. useful for dropout tests)
- model.compile('rmsprop', 'mse')
- model.train_on_batch(input_data, actual_output)
-
- # for further checks in the caller function
- return actual_output
diff --git a/tensorflow/contrib/keras/python/keras/utils/__init__.py b/tensorflow/contrib/keras/python/keras/utils/__init__.py
deleted file mode 100644
index 3b197653f3..0000000000
--- a/tensorflow/contrib/keras/python/keras/utils/__init__.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Keras utilities.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras.utils import conv_utils
-from tensorflow.contrib.keras.python.keras.utils import data_utils
-from tensorflow.contrib.keras.python.keras.utils import generic_utils
-from tensorflow.contrib.keras.python.keras.utils import io_utils
-from tensorflow.contrib.keras.python.keras.utils import np_utils
-from tensorflow.contrib.keras.python.keras.utils.data_utils import GeneratorEnqueuer
-from tensorflow.contrib.keras.python.keras.utils.data_utils import get_file
-from tensorflow.contrib.keras.python.keras.utils.data_utils import OrderedEnqueuer
-from tensorflow.contrib.keras.python.keras.utils.data_utils import Sequence
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import custom_object_scope
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import CustomObjectScope
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import deserialize_keras_object
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import get_custom_objects
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import Progbar
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import serialize_keras_object
-from tensorflow.contrib.keras.python.keras.utils.io_utils import HDF5Matrix
-from tensorflow.contrib.keras.python.keras.utils.layer_utils import convert_all_kernels_in_model
-from tensorflow.contrib.keras.python.keras.utils.np_utils import normalize
-from tensorflow.contrib.keras.python.keras.utils.np_utils import to_categorical
-from tensorflow.contrib.keras.python.keras.utils.vis_utils import plot_model
-
-
-# Globally-importable utils.
diff --git a/tensorflow/contrib/keras/python/keras/utils/conv_utils.py b/tensorflow/contrib/keras/python/keras/utils/conv_utils.py
deleted file mode 100644
index ea3a70edab..0000000000
--- a/tensorflow/contrib/keras/python/keras/utils/conv_utils.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Utilities used by convolution layers.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-from six.moves import range # pylint: disable=redefined-builtin
-
-# pylint: disable=unused-import
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.python.layers.utils import conv_input_length
-from tensorflow.python.layers.utils import conv_output_length
-from tensorflow.python.layers.utils import deconv_output_length as deconv_length
-from tensorflow.python.layers.utils import normalize_tuple
-
-
-def normalize_data_format(value):
- if value is None:
- value = K.image_data_format()
- data_format = value.lower()
- if data_format not in {'channels_first', 'channels_last'}:
- raise ValueError('The `data_format` argument must be one of '
- '"channels_first", "channels_last". Received: ' +
- str(value))
- return data_format
-
-
-def normalize_padding(value):
- padding = value.lower()
- if padding not in {'valid', 'same', 'causal'}:
- raise ValueError('The `padding` argument must be one of '
- '"valid", "same" (or "causal", only for `Conv1D). '
- 'Received: ' + str(padding))
- return padding
-
-
-def convert_kernel(kernel):
- """Converts a Numpy kernel matrix from Theano format to TensorFlow format.
-
- Also works reciprocally, since the transformation is its own inverse.
-
- Arguments:
- kernel: Numpy array (3D, 4D or 5D).
-
- Returns:
- The converted kernel.
-
- Raises:
- ValueError: in case of invalid kernel shape or invalid data_format.
- """
- kernel = np.asarray(kernel)
- if not 3 <= kernel.ndim <= 5:
- raise ValueError('Invalid kernel shape:', kernel.shape)
- slices = [slice(None, None, -1) for _ in range(kernel.ndim)]
- no_flip = (slice(None, None), slice(None, None))
- slices[-2:] = no_flip
- return np.copy(kernel[slices])
diff --git a/tensorflow/contrib/keras/python/keras/utils/data_utils.py b/tensorflow/contrib/keras/python/keras/utils/data_utils.py
deleted file mode 100644
index 08ab8d7204..0000000000
--- a/tensorflow/contrib/keras/python/keras/utils/data_utils.py
+++ /dev/null
@@ -1,664 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Utilities for file download and caching."""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from abc import abstractmethod
-import hashlib
-import multiprocessing
-from multiprocessing.pool import ThreadPool
-import os
-import random
-import shutil
-import sys
-import tarfile
-import threading
-import time
-import zipfile
-
-import numpy as np
-import six
-from six.moves.urllib.error import HTTPError
-from six.moves.urllib.error import URLError
-from six.moves.urllib.request import urlopen
-
-from tensorflow.contrib.keras.python.keras.utils.generic_utils import Progbar
-
-try:
- import queue # pylint:disable=g-import-not-at-top
-except ImportError:
- import Queue as queue # pylint:disable=g-import-not-at-top
-
-
-if sys.version_info[0] == 2:
-
- def urlretrieve(url, filename, reporthook=None, data=None):
- """Replacement for `urlretrive` for Python 2.
-
- Under Python 2, `urlretrieve` relies on `FancyURLopener` from legacy
- `urllib` module, known to have issues with proxy management.
-
- Arguments:
- url: url to retrieve.
- filename: where to store the retrieved data locally.
- reporthook: a hook function that will be called once
- on establishment of the network connection and once
- after each block read thereafter.
- The hook will be passed three arguments;
- a count of blocks transferred so far,
- a block size in bytes, and the total size of the file.
- data: `data` argument passed to `urlopen`.
- """
-
- def chunk_read(response, chunk_size=8192, reporthook=None):
- content_type = response.info().get('Content-Length')
- total_size = -1
- if content_type is not None:
- total_size = int(content_type.strip())
- count = 0
- while 1:
- chunk = response.read(chunk_size)
- count += 1
- if not chunk:
- reporthook(count, total_size, total_size)
- break
- if reporthook:
- reporthook(count, chunk_size, total_size)
- yield chunk
-
- response = urlopen(url, data)
- with open(filename, 'wb') as fd:
- for chunk in chunk_read(response, reporthook=reporthook):
- fd.write(chunk)
-else:
- from six.moves.urllib.request import urlretrieve # pylint: disable=g-import-not-at-top
-
-
-def _extract_archive(file_path, path='.', archive_format='auto'):
- """Extracts an archive if it matches tar, tar.gz, tar.bz, or zip formats.
-
- Arguments:
- file_path: path to the archive file
- path: path to extract the archive file
- archive_format: Archive format to try for extracting the file.
- Options are 'auto', 'tar', 'zip', and None.
- 'tar' includes tar, tar.gz, and tar.bz files.
- The default 'auto' is ['tar', 'zip'].
- None or an empty list will return no matches found.
-
- Returns:
- True if a match was found and an archive extraction was completed,
- False otherwise.
- """
- if archive_format is None:
- return False
- if archive_format is 'auto':
- archive_format = ['tar', 'zip']
- if isinstance(archive_format, six.string_types):
- archive_format = [archive_format]
-
- for archive_type in archive_format:
- if archive_type is 'tar':
- open_fn = tarfile.open
- is_match_fn = tarfile.is_tarfile
- if archive_type is 'zip':
- open_fn = zipfile.ZipFile
- is_match_fn = zipfile.is_zipfile
-
- if is_match_fn(file_path):
- with open_fn(file_path) as archive:
- try:
- archive.extractall(path)
- except (tarfile.TarError, RuntimeError, KeyboardInterrupt):
- if os.path.exists(path):
- if os.path.isfile(path):
- os.remove(path)
- else:
- shutil.rmtree(path)
- raise
- return True
- return False
-
-
-def get_file(fname,
- origin,
- untar=False,
- md5_hash=None,
- file_hash=None,
- cache_subdir='datasets',
- hash_algorithm='auto',
- extract=False,
- archive_format='auto',
- cache_dir=None):
- """Downloads a file from a URL if it not already in the cache.
-
- By default the file at the url `origin` is downloaded to the
- cache_dir `~/.keras`, placed in the cache_subdir `datasets`,
- and given the filename `fname`. The final location of a file
- `example.txt` would therefore be `~/.keras/datasets/example.txt`.
-
- Files in tar, tar.gz, tar.bz, and zip formats can also be extracted.
- Passing a hash will verify the file after download. The command line
- programs `shasum` and `sha256sum` can compute the hash.
-
- Arguments:
- fname: Name of the file. If an absolute path `/path/to/file.txt` is
- specified the file will be saved at that location.
- origin: Original URL of the file.
- untar: Deprecated in favor of 'extract'.
- boolean, whether the file should be decompressed
- md5_hash: Deprecated in favor of 'file_hash'.
- md5 hash of the file for verification
- file_hash: The expected hash string of the file after download.
- The sha256 and md5 hash algorithms are both supported.
- cache_subdir: Subdirectory under the Keras cache dir where the file is
- saved. If an absolute path `/path/to/folder` is
- specified the file will be saved at that location.
- hash_algorithm: Select the hash algorithm to verify the file.
- options are 'md5', 'sha256', and 'auto'.
- The default 'auto' detects the hash algorithm in use.
- extract: True tries extracting the file as an Archive, like tar or zip.
- archive_format: Archive format to try for extracting the file.
- Options are 'auto', 'tar', 'zip', and None.
- 'tar' includes tar, tar.gz, and tar.bz files.
- The default 'auto' is ['tar', 'zip'].
- None or an empty list will return no matches found.
- cache_dir: Location to store cached files, when None it
- defaults to the [Keras
- Directory](/faq/#where-is-the-keras-configuration-filed-stored).
-
- Returns:
- Path to the downloaded file
- """
- if cache_dir is None:
- cache_dir = os.path.expanduser(os.path.join('~', '.keras'))
- if md5_hash is not None and file_hash is None:
- file_hash = md5_hash
- hash_algorithm = 'md5'
- datadir_base = os.path.expanduser(cache_dir)
- if not os.access(datadir_base, os.W_OK):
- datadir_base = os.path.join('/tmp', '.keras')
- datadir = os.path.join(datadir_base, cache_subdir)
- if not os.path.exists(datadir):
- os.makedirs(datadir)
-
- if untar:
- untar_fpath = os.path.join(datadir, fname)
- fpath = untar_fpath + '.tar.gz'
- else:
- fpath = os.path.join(datadir, fname)
-
- download = False
- if os.path.exists(fpath):
- # File found; verify integrity if a hash was provided.
- if file_hash is not None:
- if not validate_file(fpath, file_hash, algorithm=hash_algorithm):
- print('A local file was found, but it seems to be '
- 'incomplete or outdated because the ' + hash_algorithm +
- ' file hash does not match the original value of ' + file_hash +
- ' so we will re-download the data.')
- download = True
- else:
- download = True
-
- if download:
- print('Downloading data from', origin)
-
- class ProgressTracker(object):
- # Maintain progbar for the lifetime of download.
- # This design was chosen for Python 2.7 compatibility.
- progbar = None
-
- def dl_progress(count, block_size, total_size):
- if ProgressTracker.progbar is None:
- if total_size is -1:
- total_size = None
- ProgressTracker.progbar = Progbar(total_size)
- else:
- ProgressTracker.progbar.update(count * block_size)
-
- error_msg = 'URL fetch failure on {}: {} -- {}'
- try:
- try:
- urlretrieve(origin, fpath, dl_progress)
- except URLError as e:
- raise Exception(error_msg.format(origin, e.errno, e.reason))
- except HTTPError as e:
- raise Exception(error_msg.format(origin, e.code, e.msg))
- except (Exception, KeyboardInterrupt) as e:
- if os.path.exists(fpath):
- os.remove(fpath)
- raise
- ProgressTracker.progbar = None
-
- if untar:
- if not os.path.exists(untar_fpath):
- _extract_archive(fpath, datadir, archive_format='tar')
- return untar_fpath
-
- if extract:
- _extract_archive(fpath, datadir, archive_format)
-
- return fpath
-
-
-def _hash_file(fpath, algorithm='sha256', chunk_size=65535):
- """Calculates a file sha256 or md5 hash.
-
- Example:
-
- ```python
- >>> from keras.data_utils import _hash_file
- >>> _hash_file('/path/to/file.zip')
- 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
- ```
-
- Arguments:
- fpath: path to the file being validated
- algorithm: hash algorithm, one of 'auto', 'sha256', or 'md5'.
- The default 'auto' detects the hash algorithm in use.
- chunk_size: Bytes to read at a time, important for large files.
-
- Returns:
- The file hash
- """
- if (algorithm is 'sha256') or (algorithm is 'auto' and len(hash) is 64):
- hasher = hashlib.sha256()
- else:
- hasher = hashlib.md5()
-
- with open(fpath, 'rb') as fpath_file:
- for chunk in iter(lambda: fpath_file.read(chunk_size), b''):
- hasher.update(chunk)
-
- return hasher.hexdigest()
-
-
-def validate_file(fpath, file_hash, algorithm='auto', chunk_size=65535):
- """Validates a file against a sha256 or md5 hash.
-
- Arguments:
- fpath: path to the file being validated
- file_hash: The expected hash string of the file.
- The sha256 and md5 hash algorithms are both supported.
- algorithm: Hash algorithm, one of 'auto', 'sha256', or 'md5'.
- The default 'auto' detects the hash algorithm in use.
- chunk_size: Bytes to read at a time, important for large files.
-
- Returns:
- Whether the file is valid
- """
- if ((algorithm is 'sha256') or
- (algorithm is 'auto' and len(file_hash) is 64)):
- hasher = 'sha256'
- else:
- hasher = 'md5'
-
- if str(_hash_file(fpath, hasher, chunk_size)) == str(file_hash):
- return True
- else:
- return False
-
-
-class Sequence(object):
- """Base object for fitting to a sequence of data, such as a dataset.
-
- Every `Sequence` must implements the `__getitem__` and the `__len__` methods.
-
- Examples:
-
- ```python
- from skimage.io import imread
- from skimage.transform import resize
- import numpy as np
-
- # Here, `x_set` is list of path to the images
- # and `y_set` are the associated classes.
-
- class CIFAR10Sequence(Sequence):
- def __init__(self, x_set, y_set, batch_size):
- self.X,self.y = x_set,y_set
- self.batch_size = batch_size
-
- def __len__(self):
- return len(self.X) // self.batch_size
-
- def __getitem__(self,idx):
- batch_x = self.X[idx*self.batch_size:(idx+1)*self.batch_size]
- batch_y = self.y[idx*self.batch_size:(idx+1)*self.batch_size]
-
- return np.array([
- resize(imread(file_name), (200,200))
- for file_name in batch_x]), np.array(batch_y)
- ```
- """
-
- @abstractmethod
- def __getitem__(self, index):
- """Gets batch at position `index`.
-
- Arguments:
- index: position of the batch in the Sequence.
-
- Returns:
- A batch
- """
- raise NotImplementedError
-
- @abstractmethod
- def __len__(self):
- """Number of batch in the Sequence.
-
- Returns:
- The number of batches in the Sequence.
- """
- raise NotImplementedError
-
- @abstractmethod
- def on_epoch_end(self):
- """Method called at the end of every epoch.
- """
- raise NotImplementedError
-
-
-def get_index(ds, i):
- """Quick fix for Python2, otherwise, it cannot be pickled.
-
- Arguments:
- ds: a Holder or Sequence object.
- i: index
-
- Returns:
- The value at index `i`.
- """
- return ds[i]
-
-
-class SequenceEnqueuer(object):
- """Base class to enqueue inputs.
-
- The task of an Enqueuer is to use parallelism to speed up preprocessing.
- This is done with processes or threads.
-
- Examples:
-
- ```python
- enqueuer = SequenceEnqueuer(...)
- enqueuer.start()
- datas = enqueuer.get()
- for data in datas:
- # Use the inputs; training, evaluating, predicting.
- # ... stop sometime.
- enqueuer.close()
- ```
-
- The `enqueuer.get()` should be an infinite stream of datas.
-
- """
-
- @abstractmethod
- def is_running(self):
- raise NotImplementedError
-
- @abstractmethod
- def start(self, workers=1, max_queue_size=10):
- """Starts the handler's workers.
-
- Arguments:
- workers: number of worker threads
- max_queue_size: queue size
- (when full, threads could block on `put()`).
- """
- raise NotImplementedError
-
- @abstractmethod
- def stop(self, timeout=None):
- """Stop running threads and wait for them to exit, if necessary.
-
- Should be called by the same thread which called start().
-
- Arguments:
- timeout: maximum time to wait on thread.join()
- """
- raise NotImplementedError
-
- @abstractmethod
- def get(self):
- """Creates a generator to extract data from the queue.
-
- Skip the data if it is `None`.
-
- Returns:
- Generator yielding tuples `(inputs, targets)`
- or `(inputs, targets, sample_weights)`.
- """
- raise NotImplementedError
-
-
-class OrderedEnqueuer(SequenceEnqueuer):
- """Builds a Enqueuer from a Sequence.
-
- Used in `fit_generator`, `evaluate_generator`, `predict_generator`.
-
- Arguments:
- sequence: A `keras.utils.data_utils.Sequence` object.
- use_multiprocessing: use multiprocessing if True, otherwise threading
- scheduling: Sequential querying of datas if 'sequential', random
- otherwise.
- shuffle: Whether to shuffle the data at the beginning of each epoch.
- """
-
- def __init__(self,
- sequence,
- use_multiprocessing=False,
- shuffle=False):
- self.sequence = sequence
- self.use_multiprocessing = use_multiprocessing
- self.shuffle = shuffle
- self.workers = 0
- self.executor = None
- self.queue = None
- self.run_thread = None
- self.stop_signal = None
-
- def is_running(self):
- return self.stop_signal is not None and not self.stop_signal.is_set()
-
- def start(self, workers=1, max_queue_size=10):
- """Start the handler's workers.
-
- Arguments:
- workers: number of worker threads
- max_queue_size: queue size
- (when full, workers could block on `put()`)
- """
- if self.use_multiprocessing:
- self.executor = multiprocessing.Pool(workers)
- else:
- self.executor = ThreadPool(workers)
- self.queue = queue.Queue(max_queue_size)
- self.stop_signal = threading.Event()
- self.run_thread = threading.Thread(target=self._run)
- self.run_thread.daemon = True
- self.run_thread.start()
-
- def _run(self):
- """Submits requests to the executor and queues the `Future` objects."""
- sequence = list(range(len(self.sequence)))
- while True:
- if self.shuffle:
- random.shuffle(sequence)
- for i in sequence:
- if self.stop_signal.is_set():
- return
- self.queue.put(
- self.executor.apply_async(get_index, (self.sequence, i)),
- block=True)
- self.sequence.on_epoch_end()
-
- def get(self):
- """Creates a generator to extract data from the queue.
-
- Skip the data if it is `None`.
-
- Yields:
- Tuples (inputs, targets)
- or (inputs, targets, sample_weights)
- """
- try:
- while self.is_running():
- inputs = self.queue.get(block=True).get()
- if inputs is not None:
- yield inputs
- except Exception as e:
- self.stop()
- raise StopIteration(e)
-
- def stop(self, timeout=None):
- """Stops running threads and wait for them to exit, if necessary.
-
- Should be called by the same thread which called `start()`.
-
- Arguments:
- timeout: maximum time to wait on `thread.join()`
- """
- self.stop_signal.set()
- with self.queue.mutex:
- self.queue.queue.clear()
- self.queue.unfinished_tasks = 0
- self.queue.not_full.notify()
- self.executor.close()
- self.executor.join()
- self.run_thread.join(timeout)
-
-
-class GeneratorEnqueuer(SequenceEnqueuer):
- """Builds a queue out of a data generator.
-
- Used in `fit_generator`, `evaluate_generator`, `predict_generator`.
-
- Arguments:
- generator: a generator function which endlessly yields data
- use_multiprocessing: use multiprocessing if True, otherwise threading
- wait_time: time to sleep in-between calls to `put()`
- random_seed: Initial seed for workers,
- will be incremented by one for each workers.
- """
-
- def __init__(self,
- generator,
- use_multiprocessing=False,
- wait_time=0.05,
- random_seed=None):
- self.wait_time = wait_time
- self._generator = generator
- self._use_multiprocessing = use_multiprocessing
- self._threads = []
- self._stop_event = None
- self.queue = None
- self.random_seed = random_seed
-
- def start(self, workers=1, max_queue_size=10):
- """Kicks off threads which add data from the generator into the queue.
-
- Arguments:
- workers: number of worker threads
- max_queue_size: queue size
- (when full, threads could block on `put()`)
- """
-
- def data_generator_task():
- while not self._stop_event.is_set():
- try:
- if self._use_multiprocessing or self.queue.qsize() < max_queue_size:
- generator_output = next(self._generator)
- self.queue.put(generator_output)
- else:
- time.sleep(self.wait_time)
- except Exception:
- self._stop_event.set()
- raise
-
- try:
- if self._use_multiprocessing:
- self.queue = multiprocessing.Queue(maxsize=max_queue_size)
- self._stop_event = multiprocessing.Event()
- else:
- self.queue = queue.Queue()
- self._stop_event = threading.Event()
-
- for _ in range(workers):
- if self._use_multiprocessing:
- # Reset random seed else all children processes
- # share the same seed
- np.random.seed(self.random_seed)
- thread = multiprocessing.Process(target=data_generator_task)
- thread.daemon = True
- if self.random_seed is not None:
- self.random_seed += 1
- else:
- thread = threading.Thread(target=data_generator_task)
- self._threads.append(thread)
- thread.start()
- except:
- self.stop()
- raise
-
- def is_running(self):
- return self._stop_event is not None and not self._stop_event.is_set()
-
- def stop(self, timeout=None):
- """Stops running threads and wait for them to exit, if necessary.
-
- Should be called by the same thread which called `start()`.
-
- Arguments:
- timeout: maximum time to wait on `thread.join()`.
- """
- if self.is_running():
- self._stop_event.set()
-
- for thread in self._threads:
- if thread.is_alive():
- if self._use_multiprocessing:
- thread.terminate()
- else:
- thread.join(timeout)
-
- if self._use_multiprocessing:
- if self.queue is not None:
- self.queue.close()
-
- self._threads = []
- self._stop_event = None
- self.queue = None
-
- def get(self):
- """Creates a generator to extract data from the queue.
-
- Skip the data if it is `None`.
-
- Yields:
- Data arrays.
- """
- while self.is_running():
- if not self.queue.empty():
- inputs = self.queue.get()
- if inputs is not None:
- yield inputs
- else:
- time.sleep(self.wait_time)
diff --git a/tensorflow/contrib/keras/python/keras/utils/data_utils_test.py b/tensorflow/contrib/keras/python/keras/utils/data_utils_test.py
deleted file mode 100644
index 55d08a34d0..0000000000
--- a/tensorflow/contrib/keras/python/keras/utils/data_utils_test.py
+++ /dev/null
@@ -1,233 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for data_utils."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from itertools import cycle
-import os
-import tarfile
-import threading
-import zipfile
-
-import numpy as np
-from six.moves.urllib.parse import urljoin
-from six.moves.urllib.request import pathname2url
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-class TestGetFileAndValidateIt(test.TestCase):
-
- def test_get_file_and_validate_it(self):
- """Tests get_file from a url, plus extraction and validation.
- """
- dest_dir = self.get_temp_dir()
- orig_dir = self.get_temp_dir()
-
- text_file_path = os.path.join(orig_dir, 'test.txt')
- zip_file_path = os.path.join(orig_dir, 'test.zip')
- tar_file_path = os.path.join(orig_dir, 'test.tar.gz')
-
- with open(text_file_path, 'w') as text_file:
- text_file.write('Float like a butterfly, sting like a bee.')
-
- with tarfile.open(tar_file_path, 'w:gz') as tar_file:
- tar_file.add(text_file_path)
-
- with zipfile.ZipFile(zip_file_path, 'w') as zip_file:
- zip_file.write(text_file_path)
-
- origin = urljoin('file://', pathname2url(os.path.abspath(tar_file_path)))
-
- path = keras.utils.data_utils.get_file('test.txt', origin,
- untar=True, cache_subdir=dest_dir)
- filepath = path + '.tar.gz'
- hashval_sha256 = keras.utils.data_utils._hash_file(filepath)
- hashval_md5 = keras.utils.data_utils._hash_file(filepath, algorithm='md5')
- path = keras.utils.data_utils.get_file(
- 'test.txt', origin, md5_hash=hashval_md5,
- untar=True, cache_subdir=dest_dir)
- path = keras.utils.data_utils.get_file(
- filepath, origin, file_hash=hashval_sha256,
- extract=True, cache_subdir=dest_dir)
- self.assertTrue(os.path.exists(filepath))
- self.assertTrue(keras.utils.data_utils.validate_file(filepath,
- hashval_sha256))
- self.assertTrue(keras.utils.data_utils.validate_file(filepath, hashval_md5))
- os.remove(filepath)
-
- origin = urljoin('file://', pathname2url(os.path.abspath(zip_file_path)))
-
- hashval_sha256 = keras.utils.data_utils._hash_file(zip_file_path)
- hashval_md5 = keras.utils.data_utils._hash_file(zip_file_path,
- algorithm='md5')
- path = keras.utils.data_utils.get_file(
- 'test', origin, md5_hash=hashval_md5,
- extract=True, cache_subdir=dest_dir)
- path = keras.utils.data_utils.get_file(
- 'test', origin, file_hash=hashval_sha256,
- extract=True, cache_subdir=dest_dir)
- self.assertTrue(os.path.exists(path))
- self.assertTrue(keras.utils.data_utils.validate_file(path, hashval_sha256))
- self.assertTrue(keras.utils.data_utils.validate_file(path, hashval_md5))
-
-
-class ThreadsafeIter(object):
-
- def __init__(self, it):
- self.it = it
- self.lock = threading.Lock()
-
- def __iter__(self):
- return self
-
- def __next__(self):
- return self.next()
-
- def next(self):
- with self.lock:
- return next(self.it)
-
-
-def threadsafe_generator(f):
-
- def g(*a, **kw):
- return ThreadsafeIter(f(*a, **kw))
-
- return g
-
-
-class TestSequence(keras.utils.data_utils.Sequence):
-
- def __init__(self, shape):
- self.shape = shape
-
- def __getitem__(self, item):
- return np.ones(self.shape, dtype=np.uint8) * item
-
- def __len__(self):
- return 100
-
-
-class FaultSequence(keras.utils.data_utils.Sequence):
-
- def __getitem__(self, item):
- raise IndexError(item, 'item is not present')
-
- def __len__(self):
- return 100
-
-
-@threadsafe_generator
-def create_generator_from_sequence_threads(ds):
- for i in cycle(range(len(ds))):
- yield ds[i]
-
-
-def create_generator_from_sequence_pcs(ds):
- for i in cycle(range(len(ds))):
- yield ds[i]
-
-
-class TestEnqueuers(test.TestCase):
-
- def test_generator_enqueuer_threads(self):
- enqueuer = keras.utils.data_utils.GeneratorEnqueuer(
- create_generator_from_sequence_threads(TestSequence([3, 200, 200, 3])),
- use_multiprocessing=False)
- enqueuer.start(3, 10)
- gen_output = enqueuer.get()
- acc = []
- for _ in range(100):
- acc.append(int(next(gen_output)[0, 0, 0, 0]))
-
- self.assertEqual(len(set(acc) - set(range(100))), 0)
- enqueuer.stop()
-
- def test_generator_enqueuer_processes(self):
- enqueuer = keras.utils.data_utils.GeneratorEnqueuer(
- create_generator_from_sequence_pcs(TestSequence([3, 200, 200, 3])),
- use_multiprocessing=True)
- enqueuer.start(3, 10)
- gen_output = enqueuer.get()
- acc = []
- for _ in range(100):
- acc.append(int(next(gen_output)[0, 0, 0, 0]))
- self.assertNotEqual(acc, list(range(100)))
- enqueuer.stop()
-
- def test_generator_enqueuer_fail_threads(self):
- enqueuer = keras.utils.data_utils.GeneratorEnqueuer(
- create_generator_from_sequence_threads(FaultSequence()),
- use_multiprocessing=False)
- enqueuer.start(3, 10)
- gen_output = enqueuer.get()
- with self.assertRaises(StopIteration):
- next(gen_output)
-
- def test_generator_enqueuer_fail_processes(self):
- enqueuer = keras.utils.data_utils.GeneratorEnqueuer(
- create_generator_from_sequence_pcs(FaultSequence()),
- use_multiprocessing=True)
- enqueuer.start(3, 10)
- gen_output = enqueuer.get()
- with self.assertRaises(StopIteration):
- next(gen_output)
-
- def test_ordered_enqueuer_threads(self):
- enqueuer = keras.utils.data_utils.OrderedEnqueuer(
- TestSequence([3, 200, 200, 3]), use_multiprocessing=False)
- enqueuer.start(3, 10)
- gen_output = enqueuer.get()
- acc = []
- for _ in range(100):
- acc.append(next(gen_output)[0, 0, 0, 0])
- self.assertEqual(acc, list(range(100)))
- enqueuer.stop()
-
- def test_ordered_enqueuer_processes(self):
- enqueuer = keras.utils.data_utils.OrderedEnqueuer(
- TestSequence([3, 200, 200, 3]), use_multiprocessing=True)
- enqueuer.start(3, 10)
- gen_output = enqueuer.get()
- acc = []
- for _ in range(100):
- acc.append(next(gen_output)[0, 0, 0, 0])
- self.assertEqual(acc, list(range(100)))
- enqueuer.stop()
-
- def test_ordered_enqueuer_fail_threads(self):
- enqueuer = keras.utils.data_utils.OrderedEnqueuer(
- FaultSequence(), use_multiprocessing=False)
- enqueuer.start(3, 10)
- gen_output = enqueuer.get()
- with self.assertRaises(StopIteration):
- next(gen_output)
-
- def test_ordered_enqueuer_fail_processes(self):
- enqueuer = keras.utils.data_utils.OrderedEnqueuer(
- FaultSequence(), use_multiprocessing=True)
- enqueuer.start(3, 10)
- gen_output = enqueuer.get()
- with self.assertRaises(StopIteration):
- next(gen_output)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/utils/generic_utils.py b/tensorflow/contrib/keras/python/keras/utils/generic_utils.py
deleted file mode 100644
index 39a10c8650..0000000000
--- a/tensorflow/contrib/keras/python/keras/utils/generic_utils.py
+++ /dev/null
@@ -1,368 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Python utilities required by Keras."""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import marshal
-import os
-import sys
-import time
-import types as python_types
-
-import numpy as np
-import six
-
-from tensorflow.python.util import tf_decorator
-from tensorflow.python.util import tf_inspect
-
-_GLOBAL_CUSTOM_OBJECTS = {}
-
-
-class CustomObjectScope(object):
- """Provides a scope that changes to `_GLOBAL_CUSTOM_OBJECTS` cannot escape.
-
- Code within a `with` statement will be able to access custom objects
- by name. Changes to global custom objects persist
- within the enclosing `with` statement. At end of the `with` statement,
- global custom objects are reverted to state
- at beginning of the `with` statement.
-
- Example:
-
- Consider a custom object `MyObject`
-
- ```python
- with CustomObjectScope({'MyObject':MyObject}):
- layer = Dense(..., kernel_regularizer='MyObject')
- # save, load, etc. will recognize custom object by name
- ```
- """
-
- def __init__(self, *args):
- self.custom_objects = args
- self.backup = None
-
- def __enter__(self):
- self.backup = _GLOBAL_CUSTOM_OBJECTS.copy()
- for objects in self.custom_objects:
- _GLOBAL_CUSTOM_OBJECTS.update(objects)
- return self
-
- def __exit__(self, *args, **kwargs):
- _GLOBAL_CUSTOM_OBJECTS.clear()
- _GLOBAL_CUSTOM_OBJECTS.update(self.backup)
-
-
-def custom_object_scope(*args):
- """Provides a scope that changes to `_GLOBAL_CUSTOM_OBJECTS` cannot escape.
-
- Convenience wrapper for `CustomObjectScope`.
- Code within a `with` statement will be able to access custom objects
- by name. Changes to global custom objects persist
- within the enclosing `with` statement. At end of the `with` statement,
- global custom objects are reverted to state
- at beginning of the `with` statement.
-
- Example:
-
- Consider a custom object `MyObject`
-
- ```python
- with custom_object_scope({'MyObject':MyObject}):
- layer = Dense(..., kernel_regularizer='MyObject')
- # save, load, etc. will recognize custom object by name
- ```
-
- Arguments:
- *args: Variable length list of dictionaries of name,
- class pairs to add to custom objects.
-
- Returns:
- Object of type `CustomObjectScope`.
- """
- return CustomObjectScope(*args)
-
-
-def get_custom_objects():
- """Retrieves a live reference to the global dictionary of custom objects.
-
- Updating and clearing custom objects using `custom_object_scope`
- is preferred, but `get_custom_objects` can
- be used to directly access `_GLOBAL_CUSTOM_OBJECTS`.
-
- Example:
-
- ```python
- get_custom_objects().clear()
- get_custom_objects()['MyObject'] = MyObject
- ```
-
- Returns:
- Global dictionary of names to classes (`_GLOBAL_CUSTOM_OBJECTS`).
- """
- return _GLOBAL_CUSTOM_OBJECTS
-
-
-def serialize_keras_object(instance):
- _, instance = tf_decorator.unwrap(instance)
- if instance is None:
- return None
- if hasattr(instance, 'get_config'):
- return {
- 'class_name': instance.__class__.__name__,
- 'config': instance.get_config()
- }
- if hasattr(instance, '__name__'):
- return instance.__name__
- else:
- raise ValueError('Cannot serialize', instance)
-
-
-def deserialize_keras_object(identifier,
- module_objects=None,
- custom_objects=None,
- printable_module_name='object'):
- if isinstance(identifier, dict):
- # In this case we are dealing with a Keras config dictionary.
- config = identifier
- if 'class_name' not in config or 'config' not in config:
- raise ValueError('Improper config format: ' + str(config))
- class_name = config['class_name']
- if custom_objects and class_name in custom_objects:
- cls = custom_objects[class_name]
- elif class_name in _GLOBAL_CUSTOM_OBJECTS:
- cls = _GLOBAL_CUSTOM_OBJECTS[class_name]
- else:
- module_objects = module_objects or {}
- cls = module_objects.get(class_name)
- if cls is None:
- raise ValueError('Unknown ' + printable_module_name + ': ' + class_name)
- if hasattr(cls, 'from_config'):
- arg_spec = tf_inspect.getargspec(cls.from_config)
- custom_objects = custom_objects or {}
-
- if 'custom_objects' in arg_spec.args:
- return cls.from_config(
- config['config'],
- custom_objects=dict(
- list(_GLOBAL_CUSTOM_OBJECTS.items()) +
- list(custom_objects.items())))
- with CustomObjectScope(custom_objects):
- return cls.from_config(config['config'])
- else:
- # Then `cls` may be a function returning a class.
- # in this case by convention `config` holds
- # the kwargs of the function.
- custom_objects = custom_objects or {}
- with CustomObjectScope(custom_objects):
- return cls(**config['config'])
- elif isinstance(identifier, six.string_types):
- function_name = identifier
- if custom_objects and function_name in custom_objects:
- fn = custom_objects.get(function_name)
- elif function_name in _GLOBAL_CUSTOM_OBJECTS:
- fn = _GLOBAL_CUSTOM_OBJECTS[function_name]
- else:
- fn = module_objects.get(function_name)
- if fn is None:
- raise ValueError('Unknown ' + printable_module_name + ':' +
- function_name)
- return fn
- else:
- raise ValueError('Could not interpret serialized ' + printable_module_name +
- ': ' + identifier)
-
-
-def func_dump(func):
- """Serializes a user defined function.
-
- Arguments:
- func: the function to serialize.
-
- Returns:
- A tuple `(code, defaults, closure)`.
- """
- if os.name == 'nt':
- code = marshal.dumps(
- func.__code__).replace(b'\\', b'/').decode('raw_unicode_escape')
- else:
- code = marshal.dumps(func.__code__).decode('raw_unicode_escape')
- defaults = func.__defaults__
- if func.__closure__:
- closure = tuple(c.cell_contents for c in func.__closure__)
- else:
- closure = None
- return code, defaults, closure
-
-
-def func_load(code, defaults=None, closure=None, globs=None):
- """Deserializes a user defined function.
-
- Arguments:
- code: bytecode of the function.
- defaults: defaults of the function.
- closure: closure of the function.
- globs: dictionary of global objects.
-
- Returns:
- A function object.
- """
- if isinstance(code, (tuple, list)): # unpack previous dump
- code, defaults, closure = code
- if isinstance(defaults, list):
- defaults = tuple(defaults)
- code = marshal.loads(code.encode('raw_unicode_escape'))
- if globs is None:
- globs = globals()
- return python_types.FunctionType(
- code, globs, name=code.co_name, argdefs=defaults, closure=closure)
-
-
-def has_arg(fn, name, accept_all=False):
- """Checks if a callable accepts a given keyword argument.
-
- Arguments:
- fn: Callable to inspect.
- name: Check if `fn` can be called with `name` as a keyword argument.
- accept_all: What to return if there is no parameter called `name`
- but the function accepts a `**kwargs` argument.
-
- Returns:
- bool, whether `fn` accepts a `name` keyword argument.
- """
- arg_spec = tf_inspect.getargspec(fn)
- if accept_all and arg_spec.keywords is not None:
- return True
- return name in arg_spec.args
-
-
-class Progbar(object):
- """Displays a progress bar.
-
- Arguments:
- target: Total number of steps expected, None if unknown.
- interval: Minimum visual progress update interval (in seconds).
- """
-
- def __init__(self, target, width=30, verbose=1, interval=0.05):
- self.width = width
- if target is None:
- target = -1
- self.target = target
- self.sum_values = {}
- self.unique_values = []
- self.start = time.time()
- self.last_update = 0
- self.interval = interval
- self.total_width = 0
- self.seen_so_far = 0
- self.verbose = verbose
-
- def update(self, current, values=None, force=False):
- """Updates the progress bar.
-
- Arguments:
- current: Index of current step.
- values: List of tuples (name, value_for_last_step).
- The progress bar will display averages for these values.
- force: Whether to force visual progress update.
- """
- values = values or []
- for k, v in values:
- if k not in self.sum_values:
- self.sum_values[k] = [
- v * (current - self.seen_so_far), current - self.seen_so_far
- ]
- self.unique_values.append(k)
- else:
- self.sum_values[k][0] += v * (current - self.seen_so_far)
- self.sum_values[k][1] += (current - self.seen_so_far)
- self.seen_so_far = current
-
- now = time.time()
- if self.verbose == 1:
- if not force and (now - self.last_update) < self.interval:
- return
-
- prev_total_width = self.total_width
- sys.stdout.write('\b' * prev_total_width)
- sys.stdout.write('\r')
-
- if self.target is not -1:
- numdigits = int(np.floor(np.log10(self.target))) + 1
- barstr = '%%%dd/%%%dd [' % (numdigits, numdigits)
- bar = barstr % (current, self.target)
- prog = float(current) / self.target
- prog_width = int(self.width * prog)
- if prog_width > 0:
- bar += ('=' * (prog_width - 1))
- if current < self.target:
- bar += '>'
- else:
- bar += '='
- bar += ('.' * (self.width - prog_width))
- bar += ']'
- sys.stdout.write(bar)
- self.total_width = len(bar)
-
- if current:
- time_per_unit = (now - self.start) / current
- else:
- time_per_unit = 0
- eta = time_per_unit * (self.target - current)
- info = ''
- if current < self.target and self.target is not -1:
- info += ' - ETA: %ds' % eta
- else:
- info += ' - %ds' % (now - self.start)
- for k in self.unique_values:
- info += ' - %s:' % k
- if isinstance(self.sum_values[k], list):
- avg = np.mean(self.sum_values[k][0] / max(1, self.sum_values[k][1]))
- if abs(avg) > 1e-3:
- info += ' %.4f' % avg
- else:
- info += ' %.4e' % avg
- else:
- info += ' %s' % self.sum_values[k]
-
- self.total_width += len(info)
- if prev_total_width > self.total_width:
- info += ((prev_total_width - self.total_width) * ' ')
-
- sys.stdout.write(info)
- sys.stdout.flush()
-
- if current >= self.target:
- sys.stdout.write('\n')
-
- if self.verbose == 2:
- if current >= self.target:
- info = '%ds' % (now - self.start)
- for k in self.unique_values:
- info += ' - %s:' % k
- avg = np.mean(self.sum_values[k][0] / max(1, self.sum_values[k][1]))
- if avg > 1e-3:
- info += ' %.4f' % avg
- else:
- info += ' %.4e' % avg
- sys.stdout.write(info + '\n')
-
- self.last_update = now
-
- def add(self, n, values=None):
- self.update(self.seen_so_far + n, values)
diff --git a/tensorflow/contrib/keras/python/keras/utils/generic_utils_test.py b/tensorflow/contrib/keras/python/keras/utils/generic_utils_test.py
deleted file mode 100644
index 8a6519f4cc..0000000000
--- a/tensorflow/contrib/keras/python/keras/utils/generic_utils_test.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for Keras generic Python utils."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-
-class HasArgTest(test.TestCase):
-
- def test_has_arg(self):
-
- def f_x(x):
- return x
-
- def f_x_args(x, *args):
- _ = args
- return x
-
- def f_x_kwargs(x, **kwargs):
- _ = kwargs
- return x
-
- self.assertTrue(keras.utils.generic_utils.has_arg(
- f_x, 'x', accept_all=False))
- self.assertFalse(keras.utils.generic_utils.has_arg(
- f_x, 'y', accept_all=False))
- self.assertTrue(keras.utils.generic_utils.has_arg(
- f_x_args, 'x', accept_all=False))
- self.assertFalse(keras.utils.generic_utils.has_arg(
- f_x_args, 'y', accept_all=False))
- self.assertTrue(keras.utils.generic_utils.has_arg(
- f_x_kwargs, 'x', accept_all=False))
- self.assertFalse(keras.utils.generic_utils.has_arg(
- f_x_kwargs, 'y', accept_all=False))
- self.assertTrue(keras.utils.generic_utils.has_arg(
- f_x_kwargs, 'y', accept_all=True))
-
-
-class TestCustomObjectScope(test.TestCase):
-
- def test_custom_object_scope(self):
-
- def custom_fn():
- pass
-
- class CustomClass(object):
- pass
-
- with keras.utils.generic_utils.custom_object_scope(
- {'CustomClass': CustomClass, 'custom_fn': custom_fn}):
- act = keras.activations.get('custom_fn')
- self.assertEqual(act, custom_fn)
- cl = keras.regularizers.get('CustomClass')
- self.assertEqual(cl.__class__, CustomClass)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/utils/io_utils.py b/tensorflow/contrib/keras/python/keras/utils/io_utils.py
deleted file mode 100644
index 5f2ba99be7..0000000000
--- a/tensorflow/contrib/keras/python/keras/utils/io_utils.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Utilities related to disk I/O."""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from collections import defaultdict
-import sys
-
-import numpy as np
-
-
-try:
- import h5py # pylint:disable=g-import-not-at-top
-except ImportError:
- h5py = None
-
-
-class HDF5Matrix(object):
- """Representation of HDF5 dataset to be used instead of a Numpy array.
-
- Example:
-
- ```python
- x_data = HDF5Matrix('input/file.hdf5', 'data')
- model.predict(x_data)
- ```
-
- Providing `start` and `end` allows use of a slice of the dataset.
-
- Optionally, a normalizer function (or lambda) can be given. This will
- be called on every slice of data retrieved.
-
- Arguments:
- datapath: string, path to a HDF5 file
- dataset: string, name of the HDF5 dataset in the file specified
- in datapath
- start: int, start of desired slice of the specified dataset
- end: int, end of desired slice of the specified dataset
- normalizer: function to be called on data when retrieved
-
- Returns:
- An array-like HDF5 dataset.
- """
- refs = defaultdict(int)
-
- def __init__(self, datapath, dataset, start=0, end=None, normalizer=None):
- if h5py is None:
- raise ImportError('The use of HDF5Matrix requires '
- 'HDF5 and h5py installed.')
-
- if datapath not in list(self.refs.keys()):
- f = h5py.File(datapath)
- self.refs[datapath] = f
- else:
- f = self.refs[datapath]
- self.data = f[dataset]
- self.start = start
- if end is None:
- self.end = self.data.shape[0]
- else:
- self.end = end
- self.normalizer = normalizer
-
- def __len__(self):
- return self.end - self.start
-
- def __getitem__(self, key):
- if isinstance(key, slice):
- start, stop = key.start, key.stop
- if start is None:
- start = 0
- if stop is None:
- stop = self.data.shape[0]
- if stop + self.start <= self.end:
- idx = slice(start + self.start, stop + self.start)
- else:
- raise IndexError
- elif isinstance(key, (int, np.integer)):
- if key + self.start < self.end:
- idx = key + self.start
- else:
- raise IndexError
- elif isinstance(key, np.ndarray):
- if np.max(key) + self.start < self.end:
- idx = (self.start + key).tolist()
- else:
- raise IndexError
- elif isinstance(key, list):
- if max(key) + self.start < self.end:
- idx = [x + self.start for x in key]
- else:
- raise IndexError
- else:
- raise IndexError
- if self.normalizer is not None:
- return self.normalizer(self.data[idx])
- else:
- return self.data[idx]
-
- @property
- def shape(self):
- """Gets a numpy-style shape tuple giving the dataset dimensions.
-
- Returns:
- A numpy-style shape tuple.
- """
- return (self.end - self.start,) + self.data.shape[1:]
-
- @property
- def dtype(self):
- """Gets the datatype of the dataset.
-
- Returns:
- A numpy dtype string.
- """
- return self.data.dtype
-
- @property
- def ndim(self):
- """Gets the number of dimensions (rank) of the dataset.
-
- Returns:
- An integer denoting the number of dimensions (rank) of the dataset.
- """
- return self.data.ndim
-
- @property
- def size(self):
- """Gets the total dataset size (number of elements).
-
- Returns:
- An integer denoting the number of elements in the dataset.
- """
- return np.prod(self.shape)
-
-
-def ask_to_proceed_with_overwrite(filepath):
- """Produces a prompt asking about overwriting a file.
-
- Arguments:
- filepath: the path to the file to be overwritten.
-
- Returns:
- True if we can proceed with overwrite, False otherwise.
- """
- get_input = input
- if sys.version_info[:2] <= (2, 7):
- get_input = raw_input
- overwrite = get_input('[WARNING] %s already exists - overwrite? '
- '[y/n]' % (filepath))
- while overwrite not in ['y', 'n']:
- overwrite = get_input('Enter "y" (overwrite) or "n" (cancel).')
- if overwrite == 'n':
- return False
- print('[TIP] Next time specify overwrite=True!')
- return True
diff --git a/tensorflow/contrib/keras/python/keras/utils/io_utils_test.py b/tensorflow/contrib/keras/python/keras/utils/io_utils_test.py
deleted file mode 100644
index f6820ee039..0000000000
--- a/tensorflow/contrib/keras/python/keras/utils/io_utils_test.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for io_utils."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import os
-import shutil
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.python.platform import test
-
-try:
- import h5py # pylint:disable=g-import-not-at-top
-except ImportError:
- h5py = None
-
-
-def create_dataset(h5_path='test.h5'):
- x = np.random.randn(200, 10).astype('float32')
- y = np.random.randint(0, 2, size=(200, 1))
- f = h5py.File(h5_path, 'w')
- # Creating dataset to store features
- x_dset = f.create_dataset('my_data', (200, 10), dtype='f')
- x_dset[:] = x
- # Creating dataset to store labels
- y_dset = f.create_dataset('my_labels', (200, 1), dtype='i')
- y_dset[:] = y
- f.close()
-
-
-class TestIOUtils(test.TestCase):
-
- def test_HDF5Matrix(self):
- if h5py is None:
- return
-
- temp_dir = self.get_temp_dir()
- self.addCleanup(shutil.rmtree, temp_dir)
-
- h5_path = os.path.join(temp_dir, 'test.h5')
- create_dataset(h5_path)
-
- with self.test_session():
- # Instantiating HDF5Matrix for the training set,
- # which is a slice of the first 150 elements
- x_train = keras.utils.io_utils.HDF5Matrix(
- h5_path, 'my_data', start=0, end=150)
- y_train = keras.utils.io_utils.HDF5Matrix(
- h5_path, 'my_labels', start=0, end=150)
-
- # Likewise for the test set
- x_test = keras.utils.io_utils.HDF5Matrix(
- h5_path, 'my_data', start=150, end=200)
- y_test = keras.utils.io_utils.HDF5Matrix(
- h5_path, 'my_labels', start=150, end=200)
-
- # HDF5Matrix behave more or less like Numpy matrices
- # with regard to indexing
- self.assertEqual(y_train.shape, (150, 1))
- # But they don't support negative indices, so don't try print(x_train[-1])
-
- self.assertEqual(y_train.dtype, np.dtype('i'))
- self.assertEqual(y_train.ndim, 2)
- self.assertEqual(y_train.size, 150)
-
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(64, input_shape=(10,), activation='relu'))
- model.add(keras.layers.Dense(1, activation='sigmoid'))
- model.compile(loss='binary_crossentropy', optimizer='sgd')
-
- # Note: you have to use shuffle='batch' or False with HDF5Matrix
- model.fit(x_train, y_train, batch_size=32, shuffle='batch', verbose=False)
- # test that evalutation and prediction
- # don't crash and return reasonable results
- out_pred = model.predict(x_test, batch_size=32, verbose=False)
- out_eval = model.evaluate(x_test, y_test, batch_size=32, verbose=False)
-
- self.assertEqual(out_pred.shape, (50, 1))
- self.assertEqual(out_eval.shape, ())
- self.assertGreater(out_eval, 0)
-
-
-if __name__ == '__main__':
- test.main()
diff --git a/tensorflow/contrib/keras/python/keras/utils/layer_utils.py b/tensorflow/contrib/keras/python/keras/utils/layer_utils.py
deleted file mode 100644
index 12d5368b08..0000000000
--- a/tensorflow/contrib/keras/python/keras/utils/layer_utils.py
+++ /dev/null
@@ -1,219 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Utilities related to Keras layers.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python.keras import backend as K
-from tensorflow.contrib.keras.python.keras.utils.conv_utils import convert_kernel
-
-
-def print_summary(model, line_length=None, positions=None, print_fn=None):
- """Prints a summary of a model.
-
- Arguments:
- model: Keras model instance.
- line_length: Total length of printed lines
- (e.g. set this to adapt the display to different
- terminal window sizes).
- positions: Relative or absolute positions of log elements in each line.
- If not provided, defaults to `[.33, .55, .67, 1.]`.
- print_fn: Print function to use (defaults to `print`).
- It will be called on each line of the summary.
- You can set it to a custom function
- in order to capture the string summary.
- """
- if print_fn is None:
- print_fn = print
-
- if model.__class__.__name__ == 'Sequential':
- sequential_like = True
- else:
- sequential_like = True
- for v in model._nodes_by_depth.values(): # pylint: disable=protected-access
- if (len(v) > 1) or (len(v) == 1 and len(v[0].inbound_layers) > 1):
- # If the model has multiple nodes or if the nodes have
- # multiple inbound_layers, the model is no longer sequential.
- sequential_like = False
- break
-
- if sequential_like:
- line_length = line_length or 65
- positions = positions or [.45, .85, 1.]
- if positions[-1] <= 1:
- positions = [int(line_length * p) for p in positions]
- # header names for the different log elements
- to_display = ['Layer (type)', 'Output Shape', 'Param #']
- else:
- line_length = line_length or 100
- positions = positions or [.33, .55, .67, 1.]
- if positions[-1] <= 1:
- positions = [int(line_length * p) for p in positions]
- # header names for the different log elements
- to_display = ['Layer (type)', 'Output Shape', 'Param #', 'Connected to']
- relevant_nodes = []
- for v in model._nodes_by_depth.values(): # pylint: disable=protected-access
- relevant_nodes += v
-
- def print_row(fields, positions):
- line = ''
- for i in range(len(fields)):
- if i > 0:
- line = line[:-1] + ' '
- line += str(fields[i])
- line = line[:positions[i]]
- line += ' ' * (positions[i] - len(line))
- print_fn(line)
-
- print_fn('_' * line_length)
- print_row(to_display, positions)
- print_fn('=' * line_length)
-
- def print_layer_summary(layer):
- try:
- output_shape = layer.output_shape
- except AttributeError:
- output_shape = 'multiple'
- name = layer.name
- cls_name = layer.__class__.__name__
- fields = [name + ' (' + cls_name + ')', output_shape, layer.count_params()]
- print_row(fields, positions)
-
- def print_layer_summary_with_connections(layer):
- """Prints a summary for a single layer.
-
- Arguments:
- layer: target layer.
- """
- try:
- output_shape = layer.output_shape
- except AttributeError:
- output_shape = 'multiple'
- connections = []
- for node in layer.inbound_nodes:
- if relevant_nodes and node not in relevant_nodes:
- # node is not part of the current network
- continue
- for i in range(len(node.inbound_layers)):
- inbound_layer = node.inbound_layers[i].name
- inbound_node_index = node.node_indices[i]
- inbound_tensor_index = node.tensor_indices[i]
- connections.append(inbound_layer + '[' + str(inbound_node_index) + ']['
- + str(inbound_tensor_index) + ']')
-
- name = layer.name
- cls_name = layer.__class__.__name__
- if not connections:
- first_connection = ''
- else:
- first_connection = connections[0]
- fields = [
- name + ' (' + cls_name + ')', output_shape,
- layer.count_params(), first_connection
- ]
- print_row(fields, positions)
- if len(connections) > 1:
- for i in range(1, len(connections)):
- fields = ['', '', '', connections[i]]
- print_row(fields, positions)
-
- layers = model.layers
- for i in range(len(layers)):
- if sequential_like:
- print_layer_summary(layers[i])
- else:
- print_layer_summary_with_connections(layers[i])
- if i == len(layers) - 1:
- print_fn('=' * line_length)
- else:
- print_fn('_' * line_length)
-
- trainable_count = int(
- np.sum([K.count_params(p) for p in set(model.trainable_weights)]))
- non_trainable_count = int(
- np.sum([K.count_params(p) for p in set(model.non_trainable_weights)]))
-
- print_fn('Total params: {:,}'.format(trainable_count + non_trainable_count))
- print_fn('Trainable params: {:,}'.format(trainable_count))
- print_fn('Non-trainable params: {:,}'.format(non_trainable_count))
- print_fn('_' * line_length)
-
-
-def convert_all_kernels_in_model(model):
- """Converts all convolution kernels in a model from Theano to TensorFlow.
-
- Also works from TensorFlow to Theano.
-
- Arguments:
- model: target model for the conversion.
- """
- # Note: SeparableConvolution not included
- # since only supported by TF.
- conv_classes = {
- 'Conv1D',
- 'Conv2D',
- 'Conv3D',
- 'Conv2DTranspose',
- }
- to_assign = []
- for layer in model.layers:
- if layer.__class__.__name__ in conv_classes:
- original_kernel = K.get_value(layer.kernel)
- converted_kernel = convert_kernel(original_kernel)
- to_assign.append((layer.kernel, converted_kernel))
- K.batch_set_value(to_assign)
-
-
-def convert_dense_weights_data_format(dense,
- previous_feature_map_shape,
- target_data_format='channels_first'):
- """Utility useful when changing a convnet's `data_format`.
-
- When porting the weights of a convnet from one data format to the other,
- if the convnet includes a `Flatten` layer
- (applied to the last convolutional feature map)
- followed by a `Dense` layer, the weights of that `Dense` layer
- should be updated to reflect the new dimension ordering.
-
- Arguments:
- dense: The target `Dense` layer.
- previous_feature_map_shape: A shape tuple of 3 integers,
- e.g. `(512, 7, 7)`. The shape of the convolutional
- feature map right before the `Flatten` layer that
- came before the target `Dense` layer.
- target_data_format: One of "channels_last", "channels_first".
- Set it "channels_last"
- if converting a "channels_first" model to "channels_last",
- or reciprocally.
- """
- assert target_data_format in {'channels_last', 'channels_first'}
- kernel, bias = dense.get_weights()
- for i in range(kernel.shape[1]):
- if target_data_format == 'channels_first':
- c, h, w = previous_feature_map_shape
- original_fm_shape = (h, w, c)
- ki = kernel[:, i].reshape(original_fm_shape)
- ki = np.transpose(ki, (2, 0, 1)) # last -> first
- else:
- h, w, c = previous_feature_map_shape
- original_fm_shape = (c, h, w)
- ki = kernel[:, i].reshape(original_fm_shape)
- ki = np.transpose(ki, (1, 2, 0)) # first -> last
- kernel[:, i] = np.reshape(ki, (np.prod(previous_feature_map_shape),))
- dense.set_weights([kernel, bias])
diff --git a/tensorflow/contrib/keras/python/keras/utils/np_utils.py b/tensorflow/contrib/keras/python/keras/utils/np_utils.py
deleted file mode 100644
index a23172d342..0000000000
--- a/tensorflow/contrib/keras/python/keras/utils/np_utils.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Numpy-related utilities."""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-
-def to_categorical(y, num_classes=None):
- """Converts a class vector (integers) to binary class matrix.
-
- E.g. for use with categorical_crossentropy.
-
- Arguments:
- y: class vector to be converted into a matrix
- (integers from 0 to num_classes).
- num_classes: total number of classes.
-
- Returns:
- A binary matrix representation of the input.
- """
- y = np.array(y, dtype='int').ravel()
- if not num_classes:
- num_classes = np.max(y) + 1
- n = y.shape[0]
- categorical = np.zeros((n, num_classes))
- categorical[np.arange(n), y] = 1
- return categorical
-
-
-def normalize(x, axis=-1, order=2):
- """Normalizes a Numpy array.
-
- Arguments:
- x: Numpy array to normalize.
- axis: axis along which to normalize.
- order: Normalization order (e.g. 2 for L2 norm).
-
- Returns:
- A normalized copy of the array.
- """
- l2 = np.atleast_1d(np.linalg.norm(x, order, axis))
- l2[l2 == 0] = 1
- return x / np.expand_dims(l2, axis)
diff --git a/tensorflow/contrib/keras/python/keras/utils/vis_utils.py b/tensorflow/contrib/keras/python/keras/utils/vis_utils.py
deleted file mode 100644
index 949767299b..0000000000
--- a/tensorflow/contrib/keras/python/keras/utils/vis_utils.py
+++ /dev/null
@@ -1,154 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Utilities related to model visualization."""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import os
-import sys
-
-try:
- # pydot-ng is a fork of pydot that is better maintained.
- import pydot_ng as pydot # pylint: disable=g-import-not-at-top
-except ImportError:
- # Fall back on pydot if necessary.
- # Silence a `print` statement that occurs in case of import error,
- # by temporarily replacing sys.stdout.
- _stdout = sys.stdout
- sys.stdout = sys.stderr
- try:
- import pydot # pylint: disable=g-import-not-at-top
- except ImportError:
- pydot = None
- finally:
- # Restore sys.stdout.
- sys.stdout = _stdout
-
-
-def _check_pydot():
- try:
- # Attempt to create an image of a blank graph
- # to check the pydot/graphviz installation.
- pydot.Dot.create(pydot.Dot())
- except Exception:
- # pydot raises a generic Exception here,
- # so no specific class can be caught.
- raise ImportError('Failed to import pydot. You must install pydot'
- ' and graphviz for `pydotprint` to work.')
-
-
-def model_to_dot(model, show_shapes=False, show_layer_names=True, rankdir='TB'):
- """Convert a Keras model to dot format.
-
- Arguments:
- model: A Keras model instance.
- show_shapes: whether to display shape information.
- show_layer_names: whether to display layer names.
- rankdir: `rankdir` argument passed to PyDot,
- a string specifying the format of the plot:
- 'TB' creates a vertical plot;
- 'LR' creates a horizontal plot.
-
- Returns:
- A `pydot.Dot` instance representing the Keras model.
- """
- from tensorflow.contrib.keras.python.keras.layers.wrappers import Wrapper # pylint: disable=g-import-not-at-top
- from tensorflow.contrib.keras.python.keras.models import Sequential # pylint: disable=g-import-not-at-top
-
- _check_pydot()
- dot = pydot.Dot()
- dot.set('rankdir', rankdir)
- dot.set('concentrate', True)
- dot.set_node_defaults(shape='record')
-
- if isinstance(model, Sequential):
- if not model.built:
- model.build()
- model = model.model
- layers = model.layers
-
- # Create graph nodes.
- for layer in layers:
- layer_id = str(id(layer))
-
- # Append a wrapped layer's label to node's label, if it exists.
- layer_name = layer.name
- class_name = layer.__class__.__name__
- if isinstance(layer, Wrapper):
- layer_name = '{}({})'.format(layer_name, layer.layer.name)
- child_class_name = layer.layer.__class__.__name__
- class_name = '{}({})'.format(class_name, child_class_name)
-
- # Create node's label.
- if show_layer_names:
- label = '{}: {}'.format(layer_name, class_name)
- else:
- label = class_name
-
- # Rebuild the label as a table including input/output shapes.
- if show_shapes:
- try:
- outputlabels = str(layer.output_shape)
- except AttributeError:
- outputlabels = 'multiple'
- if hasattr(layer, 'input_shape'):
- inputlabels = str(layer.input_shape)
- elif hasattr(layer, 'input_shapes'):
- inputlabels = ', '.join([str(ishape) for ishape in layer.input_shapes])
- else:
- inputlabels = 'multiple'
- label = '%s\n|{input:|output:}|{{%s}|{%s}}' % (label, inputlabels,
- outputlabels)
- node = pydot.Node(layer_id, label=label)
- dot.add_node(node)
-
- # Connect nodes with edges.
- for layer in layers:
- layer_id = str(id(layer))
- for i, node in enumerate(layer.inbound_nodes):
- node_key = layer.name + '_ib-' + str(i)
- if node_key in model.container_nodes:
- for inbound_layer in node.inbound_layers:
- inbound_layer_id = str(id(inbound_layer))
- layer_id = str(id(layer))
- dot.add_edge(pydot.Edge(inbound_layer_id, layer_id))
- return dot
-
-
-def plot_model(model,
- to_file='model.png',
- show_shapes=False,
- show_layer_names=True,
- rankdir='TB'):
- """Converts a Keras model to dot format and save to a file.
-
- Arguments:
- model: A Keras model instance
- to_file: File name of the plot image.
- show_shapes: whether to display shape information.
- show_layer_names: whether to display layer names.
- rankdir: `rankdir` argument passed to PyDot,
- a string specifying the format of the plot:
- 'TB' creates a vertical plot;
- 'LR' creates a horizontal plot.
- """
- dot = model_to_dot(model, show_shapes, show_layer_names, rankdir)
- _, extension = os.path.splitext(to_file)
- if not extension:
- extension = 'png'
- else:
- extension = extension[1:]
- dot.write(to_file, format=extension)
diff --git a/tensorflow/contrib/keras/python/keras/wrappers/__init__.py b/tensorflow/contrib/keras/python/keras/wrappers/__init__.py
deleted file mode 100644
index 51244ff681..0000000000
--- a/tensorflow/contrib/keras/python/keras/wrappers/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Keras API wrappers.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-from tensorflow.contrib.keras.python.keras.wrappers import scikit_learn
-
diff --git a/tensorflow/contrib/keras/python/keras/wrappers/scikit_learn.py b/tensorflow/contrib/keras/python/keras/wrappers/scikit_learn.py
deleted file mode 100644
index 0d04fc120f..0000000000
--- a/tensorflow/contrib/keras/python/keras/wrappers/scikit_learn.py
+++ /dev/null
@@ -1,356 +0,0 @@
-# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""API wrapper allowing to use certain Keras models with the Scikit-Learn API.
-"""
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import copy
-import types
-
-import numpy as np
-
-from tensorflow.contrib.keras.python.keras.models import Sequential
-from tensorflow.contrib.keras.python.keras.utils.np_utils import to_categorical
-from tensorflow.python.util import tf_inspect
-
-
-class BaseWrapper(object):
- """Base class for the Keras scikit-learn wrapper.
-
- Warning: This class should not be used directly.
- Use descendant classes instead.
-
- Arguments:
- build_fn: callable function or class instance
- **sk_params: model parameters & fitting parameters
-
- The build_fn should construct, compile and return a Keras model, which
- will then be used to fit/predict. One of the following
- three values could be passed to build_fn:
- 1. A function
- 2. An instance of a class that implements the __call__ method
- 3. None. This means you implement a class that inherits from either
- `KerasClassifier` or `KerasRegressor`. The __call__ method of the
- present class will then be treated as the default build_fn.
-
- `sk_params` takes both model parameters and fitting parameters. Legal model
- parameters are the arguments of `build_fn`. Note that like all other
- estimators in scikit-learn, 'build_fn' should provide default values for
- its arguments, so that you could create the estimator without passing any
- values to `sk_params`.
-
- `sk_params` could also accept parameters for calling `fit`, `predict`,
- `predict_proba`, and `score` methods (e.g., `epochs`, `batch_size`).
- fitting (predicting) parameters are selected in the following order:
-
- 1. Values passed to the dictionary arguments of
- `fit`, `predict`, `predict_proba`, and `score` methods
- 2. Values passed to `sk_params`
- 3. The default values of the `keras.models.Sequential`
- `fit`, `predict`, `predict_proba` and `score` methods
-
- When using scikit-learn's `grid_search` API, legal tunable parameters are
- those you could pass to `sk_params`, including fitting parameters.
- In other words, you could use `grid_search` to search for the best
- `batch_size` or `epochs` as well as the model parameters.
- """
-
- def __init__(self, build_fn=None, **sk_params):
- self.build_fn = build_fn
- self.sk_params = sk_params
- self.check_params(sk_params)
-
- def check_params(self, params):
- """Checks for user typos in "params".
-
- Arguments:
- params: dictionary; the parameters to be checked
-
- Raises:
- ValueError: if any member of `params` is not a valid argument.
- """
- legal_params_fns = [
- Sequential.fit, Sequential.predict, Sequential.predict_classes,
- Sequential.evaluate
- ]
- if self.build_fn is None:
- legal_params_fns.append(self.__call__)
- elif (not isinstance(self.build_fn, types.FunctionType) and
- not isinstance(self.build_fn, types.MethodType)):
- legal_params_fns.append(self.build_fn.__call__)
- else:
- legal_params_fns.append(self.build_fn)
-
- legal_params = []
- for fn in legal_params_fns:
- legal_params += tf_inspect.getargspec(fn)[0]
- legal_params = set(legal_params)
-
- for params_name in params:
- if params_name not in legal_params:
- if params_name != 'nb_epoch':
- raise ValueError('{} is not a legal parameter'.format(params_name))
-
- def get_params(self, **params): # pylint: disable=unused-argument
- """Gets parameters for this estimator.
-
- Arguments:
- **params: ignored (exists for API compatibility).
-
- Returns:
- Dictionary of parameter names mapped to their values.
- """
- res = copy.deepcopy(self.sk_params)
- res.update({'build_fn': self.build_fn})
- return res
-
- def set_params(self, **params):
- """Sets the parameters of this estimator.
-
- Arguments:
- **params: Dictionary of parameter names mapped to their values.
-
- Returns:
- self
- """
- self.check_params(params)
- self.sk_params.update(params)
- return self
-
- def fit(self, x, y, **kwargs):
- """Constructs a new model with `build_fn` & fit the model to `(x, y)`.
-
- Arguments:
- x : array-like, shape `(n_samples, n_features)`
- Training samples where n_samples in the number of samples
- and n_features is the number of features.
- y : array-like, shape `(n_samples,)` or `(n_samples, n_outputs)`
- True labels for X.
- **kwargs: dictionary arguments
- Legal arguments are the arguments of `Sequential.fit`
-
- Returns:
- history : object
- details about the training history at each epoch.
- """
- if self.build_fn is None:
- self.model = self.__call__(**self.filter_sk_params(self.__call__))
- elif (not isinstance(self.build_fn, types.FunctionType) and
- not isinstance(self.build_fn, types.MethodType)):
- self.model = self.build_fn(
- **self.filter_sk_params(self.build_fn.__call__))
- else:
- self.model = self.build_fn(**self.filter_sk_params(self.build_fn))
-
- loss_name = self.model.loss
- if hasattr(loss_name, '__name__'):
- loss_name = loss_name.__name__
- if loss_name == 'categorical_crossentropy' and len(y.shape) != 2:
- y = to_categorical(y)
-
- fit_args = copy.deepcopy(self.filter_sk_params(Sequential.fit))
- fit_args.update(kwargs)
-
- history = self.model.fit(x, y, **fit_args)
-
- return history
-
- def filter_sk_params(self, fn, override=None):
- """Filters `sk_params` and return those in `fn`'s arguments.
-
- Arguments:
- fn : arbitrary function
- override: dictionary, values to override sk_params
-
- Returns:
- res : dictionary dictionary containing variables
- in both sk_params and fn's arguments.
- """
- override = override or {}
- res = {}
- fn_args = tf_inspect.getargspec(fn)[0]
- for name, value in self.sk_params.items():
- if name in fn_args:
- res.update({name: value})
- res.update(override)
- return res
-
-
-class KerasClassifier(BaseWrapper):
- """Implementation of the scikit-learn classifier API for Keras.
- """
-
- def fit(self, x, y, **kwargs):
- """Constructs a new model with `build_fn` & fit the model to `(x, y)`.
-
- Arguments:
- x : array-like, shape `(n_samples, n_features)`
- Training samples where n_samples in the number of samples
- and n_features is the number of features.
- y : array-like, shape `(n_samples,)` or `(n_samples, n_outputs)`
- True labels for X.
- **kwargs: dictionary arguments
- Legal arguments are the arguments of `Sequential.fit`
-
- Returns:
- history : object
- details about the training history at each epoch.
-
- Raises:
- ValueError: In case of invalid shape for `y` argument.
- """
- y = np.array(y)
- if len(y.shape) == 2 and y.shape[1] > 1:
- self.classes_ = np.arange(y.shape[1])
- elif (len(y.shape) == 2 and y.shape[1] == 1) or len(y.shape) == 1:
- self.classes_ = np.unique(y)
- y = np.searchsorted(self.classes_, y)
- else:
- raise ValueError('Invalid shape for y: ' + str(y.shape))
- self.n_classes_ = len(self.classes_)
- return super(KerasClassifier, self).fit(x, y, **kwargs)
-
- def predict(self, x, **kwargs):
- """Returns the class predictions for the given test data.
-
- Arguments:
- x: array-like, shape `(n_samples, n_features)`
- Test samples where n_samples in the number of samples
- and n_features is the number of features.
- **kwargs: dictionary arguments
- Legal arguments are the arguments
- of `Sequential.predict_classes`.
-
- Returns:
- preds: array-like, shape `(n_samples,)`
- Class predictions.
- """
- kwargs = self.filter_sk_params(Sequential.predict_classes, kwargs)
- classes = self.model.predict_classes(x, **kwargs)
- return self.classes_[classes]
-
- def predict_proba(self, x, **kwargs):
- """Returns class probability estimates for the given test data.
-
- Arguments:
- x: array-like, shape `(n_samples, n_features)`
- Test samples where n_samples in the number of samples
- and n_features is the number of features.
- **kwargs: dictionary arguments
- Legal arguments are the arguments
- of `Sequential.predict_classes`.
-
- Returns:
- proba: array-like, shape `(n_samples, n_outputs)`
- Class probability estimates.
- In the case of binary classification,
- tp match the scikit-learn API,
- will return an array of shape '(n_samples, 2)'
- (instead of `(n_sample, 1)` as in Keras).
- """
- kwargs = self.filter_sk_params(Sequential.predict_proba, kwargs)
- probs = self.model.predict_proba(x, **kwargs)
-
- # check if binary classification
- if probs.shape[1] == 1:
- # first column is probability of class 0 and second is of class 1
- probs = np.hstack([1 - probs, probs])
- return probs
-
- def score(self, x, y, **kwargs):
- """Returns the mean accuracy on the given test data and labels.
-
- Arguments:
- x: array-like, shape `(n_samples, n_features)`
- Test samples where n_samples in the number of samples
- and n_features is the number of features.
- y: array-like, shape `(n_samples,)` or `(n_samples, n_outputs)`
- True labels for x.
- **kwargs: dictionary arguments
- Legal arguments are the arguments of `Sequential.evaluate`.
-
- Returns:
- score: float
- Mean accuracy of predictions on X wrt. y.
-
- Raises:
- ValueError: If the underlying model isn't configured to
- compute accuracy. You should pass `metrics=["accuracy"]` to
- the `.compile()` method of the model.
- """
- y = np.searchsorted(self.classes_, y)
- kwargs = self.filter_sk_params(Sequential.evaluate, kwargs)
-
- loss_name = self.model.loss
- if hasattr(loss_name, '__name__'):
- loss_name = loss_name.__name__
- if loss_name == 'categorical_crossentropy' and len(y.shape) != 2:
- y = to_categorical(y)
-
- outputs = self.model.evaluate(x, y, **kwargs)
- if not isinstance(outputs, list):
- outputs = [outputs]
- for name, output in zip(self.model.metrics_names, outputs):
- if name == 'acc':
- return output
- raise ValueError('The model is not configured to compute accuracy. '
- 'You should pass `metrics=["accuracy"]` to '
- 'the `model.compile()` method.')
-
-
-class KerasRegressor(BaseWrapper):
- """Implementation of the scikit-learn regressor API for Keras.
- """
-
- def predict(self, x, **kwargs):
- """Returns predictions for the given test data.
-
- Arguments:
- x: array-like, shape `(n_samples, n_features)`
- Test samples where n_samples in the number of samples
- and n_features is the number of features.
- **kwargs: dictionary arguments
- Legal arguments are the arguments of `Sequential.predict`.
-
- Returns:
- preds: array-like, shape `(n_samples,)`
- Predictions.
- """
- kwargs = self.filter_sk_params(Sequential.predict, kwargs)
- return np.squeeze(self.model.predict(x, **kwargs))
-
- def score(self, x, y, **kwargs):
- """Returns the mean loss on the given test data and labels.
-
- Arguments:
- x: array-like, shape `(n_samples, n_features)`
- Test samples where n_samples in the number of samples
- and n_features is the number of features.
- y: array-like, shape `(n_samples,)`
- True labels for X.
- **kwargs: dictionary arguments
- Legal arguments are the arguments of `Sequential.evaluate`.
-
- Returns:
- score: float
- Mean accuracy of predictions on X wrt. y.
- """
- kwargs = self.filter_sk_params(Sequential.evaluate, kwargs)
- loss = self.model.evaluate(x, y, **kwargs)
- if isinstance(loss, list):
- return loss[0]
- return loss
diff --git a/tensorflow/contrib/keras/python/keras/wrappers/scikit_learn_test.py b/tensorflow/contrib/keras/python/keras/wrappers/scikit_learn_test.py
deleted file mode 100644
index 95e0b951eb..0000000000
--- a/tensorflow/contrib/keras/python/keras/wrappers/scikit_learn_test.py
+++ /dev/null
@@ -1,190 +0,0 @@
-# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ==============================================================================
-"""Tests for Scikit-learn API wrapper."""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import numpy as np
-
-from tensorflow.contrib.keras.python import keras
-from tensorflow.contrib.keras.python.keras import testing_utils
-from tensorflow.python.platform import test
-
-INPUT_DIM = 5
-HIDDEN_DIM = 5
-TRAIN_SAMPLES = 10
-TEST_SAMPLES = 5
-NUM_CLASSES = 2
-BATCH_SIZE = 5
-EPOCHS = 1
-
-
-def build_fn_clf(hidden_dim):
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(INPUT_DIM, input_shape=(INPUT_DIM,)))
- model.add(keras.layers.Activation('relu'))
- model.add(keras.layers.Dense(hidden_dim))
- model.add(keras.layers.Activation('relu'))
- model.add(keras.layers.Dense(NUM_CLASSES))
- model.add(keras.layers.Activation('softmax'))
- model.compile(
- optimizer='sgd', loss='categorical_crossentropy', metrics=['accuracy'])
- return model
-
-
-def assert_classification_works(clf):
- np.random.seed(42)
- (x_train, y_train), (x_test, _) = testing_utils.get_test_data(
- train_samples=TRAIN_SAMPLES,
- test_samples=TEST_SAMPLES,
- input_shape=(INPUT_DIM,),
- num_classes=NUM_CLASSES)
-
- clf.fit(x_train, y_train, batch_size=BATCH_SIZE, epochs=EPOCHS)
-
- score = clf.score(x_train, y_train, batch_size=BATCH_SIZE)
- assert np.isscalar(score) and np.isfinite(score)
-
- preds = clf.predict(x_test, batch_size=BATCH_SIZE)
- assert preds.shape == (TEST_SAMPLES,)
- for prediction in np.unique(preds):
- assert prediction in range(NUM_CLASSES)
-
- proba = clf.predict_proba(x_test, batch_size=BATCH_SIZE)
- assert proba.shape == (TEST_SAMPLES, NUM_CLASSES)
- assert np.allclose(np.sum(proba, axis=1), np.ones(TEST_SAMPLES))
-
-
-def build_fn_reg(hidden_dim):
- model = keras.models.Sequential()
- model.add(keras.layers.Dense(INPUT_DIM, input_shape=(INPUT_DIM,)))
- model.add(keras.layers.Activation('relu'))
- model.add(keras.layers.Dense(hidden_dim))
- model.add(keras.layers.Activation('relu'))
- model.add(keras.layers.Dense(1))
- model.add(keras.layers.Activation('linear'))
- model.compile(
- optimizer='sgd', loss='mean_absolute_error', metrics=['accuracy'])
- return model
-
-
-def assert_regression_works(reg):
- np.random.seed(42)
- (x_train, y_train), (x_test, _) = testing_utils.get_test_data(
- train_samples=TRAIN_SAMPLES,
- test_samples=TEST_SAMPLES,
- input_shape=(INPUT_DIM,),
- num_classes=NUM_CLASSES)
-
- reg.fit(x_train, y_train, batch_size=BATCH_SIZE, epochs=EPOCHS)
-
- score = reg.score(x_train, y_train, batch_size=BATCH_SIZE)
- assert np.isscalar(score) and np.isfinite(score)
-
- preds = reg.predict(x_test, batch_size=BATCH_SIZE)
- assert preds.shape == (TEST_SAMPLES,)
-
-
-class ScikitLearnAPIWrapperTest(test.TestCase):
-
- def test_classify_build_fn(self):
- with self.test_session():
- clf = keras.wrappers.scikit_learn.KerasClassifier(
- build_fn=build_fn_clf,
- hidden_dim=HIDDEN_DIM,
- batch_size=BATCH_SIZE,
- epochs=EPOCHS)
-
- assert_classification_works(clf)
-
- def test_classify_class_build_fn(self):
-
- class ClassBuildFnClf(object):
-
- def __call__(self, hidden_dim):
- return build_fn_clf(hidden_dim)
-
- with self.test_session():
- clf = keras.wrappers.scikit_learn.KerasClassifier(
- build_fn=ClassBuildFnClf(),
- hidden_dim=HIDDEN_DIM,
- batch_size=BATCH_SIZE,
- epochs=EPOCHS)
-
- assert_classification_works(clf)
-
- def test_classify_inherit_class_build_fn(self):
-
- class InheritClassBuildFnClf(keras.wrappers.scikit_learn.KerasClassifier):
-
- def __call__(self, hidden_dim):
- return build_fn_clf(hidden_dim)
-
- with self.test_session():
- clf = InheritClassBuildFnClf(
- build_fn=None,
- hidden_dim=HIDDEN_DIM,
- batch_size=BATCH_SIZE,
- epochs=EPOCHS)
-
- assert_classification_works(clf)
-
- def test_regression_build_fn(self):
- with self.test_session():
- reg = keras.wrappers.scikit_learn.KerasRegressor(
- build_fn=build_fn_reg,
- hidden_dim=HIDDEN_DIM,
- batch_size=BATCH_SIZE,
- epochs=EPOCHS)
-
- assert_regression_works(reg)
-
- def test_regression_class_build_fn(self):
-
- class ClassBuildFnReg(object):
-
- def __call__(self, hidden_dim):
- return build_fn_reg(hidden_dim)
-
- with self.test_session():
- reg = keras.wrappers.scikit_learn.KerasRegressor(
- build_fn=ClassBuildFnReg(),
- hidden_dim=HIDDEN_DIM,
- batch_size=BATCH_SIZE,
- epochs=EPOCHS)
-
- assert_regression_works(reg)
-
- def test_regression_inherit_class_build_fn(self):
-
- class InheritClassBuildFnReg(keras.wrappers.scikit_learn.KerasRegressor):
-
- def __call__(self, hidden_dim):
- return build_fn_reg(hidden_dim)
-
- with self.test_session():
- reg = InheritClassBuildFnReg(
- build_fn=None,
- hidden_dim=HIDDEN_DIM,
- batch_size=BATCH_SIZE,
- epochs=EPOCHS)
-
- assert_regression_works(reg)
-
-
-if __name__ == '__main__':
- test.main()