Comparar commits
102 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| afbd5d34a3 | |||
| 99e4e481c5 | |||
| 2061f41987 | |||
| 457b0c1d3e | |||
| bf5735b577 | |||
| 1f82b19349 | |||
| b8b2fc4e6c | |||
| b5411f10a1 | |||
| fce18b245c | |||
| e872da85e4 | |||
| a2a2e49457 | |||
| 032abdb666 | |||
| 8100ac79c1 | |||
| 16db6db6ae | |||
| 4026f89bd1 | |||
| 5436b4fb00 | |||
| 6c199c41dd | |||
| 1a7e51cfc8 | |||
| df14349c2a | |||
| 855e8dccde | |||
| 850d92516c | |||
| 96909acd1e | |||
| 9479666083 | |||
| c0e972f3b4 | |||
| a517bc69fb | |||
| 57d7fce61d | |||
| 4a5a3dd685 | |||
| 819f3e2ba5 | |||
| 6ef5bb2ddc | |||
| 01081d4899 | |||
| f37c7d4fd9 | |||
| 4a2ff8d019 | |||
| 59b1e2a25c | |||
| 240eda535d | |||
| 9d62df3f21 | |||
| 776a15aad9 | |||
| 4b79df99b9 | |||
| 3acd5b2e86 | |||
| 5952ea52aa | |||
| 50eb3bfa1b | |||
| b6b5343af3 | |||
| ff7209cc16 | |||
| 4736730e22 | |||
| 38cdc03cc4 | |||
| c00a73a65e | |||
| 6a835faf79 | |||
| 3f9379ec3e | |||
| c11bbd807c | |||
| ba3ea75307 | |||
| 4b975c113c | |||
| 50ee2f9602 | |||
| 565d1d5116 | |||
| 4794363fae | |||
| c2cc739938 | |||
| 6790c0d247 | |||
| a92026d719 | |||
| d14df154e5 | |||
| 1b6e14e944 | |||
| 27329b8400 | |||
| 28f3eaedd1 | |||
| 2abdcdfb8e | |||
| 4b7122ef9c | |||
| 9840b5ad24 | |||
| 4adb619518 | |||
| cff822c9df | |||
| f9ede2ba1b | |||
| 71b5c2d05b | |||
| d69432cd0a | |||
| 8a99aaf604 | |||
| aabe81e82b | |||
| 94545cea9b | |||
| c25a319463 | |||
| 1847036cfd | |||
| 3865b589e1 | |||
| 2832c740aa | |||
| 9ee8425072 | |||
| 1db4438ac9 | |||
| 1bd4fac1a7 | |||
| a58fb1d917 | |||
| 5ae17cd983 | |||
| 9b0ff98ead | |||
| 27e943eda2 | |||
| 71b74d6b89 | |||
| afd9d8087d | |||
| dc66ca402a | |||
| 7b231e2819 | |||
| 369bfcb1bf | |||
| 2ca7908f59 | |||
| d684124d89 | |||
| d2a609e459 | |||
| bd4d40e514 | |||
| 5abbd05245 | |||
| 265464141e | |||
| 6feb1d9e27 | |||
| 7936401a87 | |||
| 672fe90dd9 | |||
| d5a384ed61 | |||
| 22b943e935 | |||
| 94268267c4 | |||
| 350da1a3c3 | |||
| 3fc74cfc0b | |||
| c6e6acdebf |
@@ -17,10 +17,6 @@ matrix:
|
||||
env: KERAS_BACKEND=theano
|
||||
- python: 3.5
|
||||
env: KERAS_BACKEND=theano
|
||||
- python: 2.7
|
||||
env: KERAS_BACKEND=cntk
|
||||
- python: 3.5
|
||||
env: KERAS_BACKEND=cntk
|
||||
install:
|
||||
# code below is taken from http://conda.pydata.org/docs/travis.html
|
||||
# We do this conditionally because it saves us some downloading if the
|
||||
@@ -53,22 +49,6 @@ install:
|
||||
|
||||
# install TensorFlow (CPU version).
|
||||
- pip install tensorflow
|
||||
|
||||
# install cntk
|
||||
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
|
||||
pip install https://cntk.ai/PythonWheel/CPU-Only/cntk-2.0-cp27-cp27mu-linux_x86_64.whl;
|
||||
elif [[ "$TRAVIS_PYTHON_VERSION" == "3.5" ]]; then
|
||||
pip install https://cntk.ai/PythonWheel/CPU-Only/cntk-2.0-cp35-cp35m-linux_x86_64.whl;
|
||||
fi
|
||||
|
||||
#install open mpi
|
||||
- rm -rf ~/mpi
|
||||
- mkdir ~/mpi
|
||||
- pushd ~/mpi
|
||||
- wget http://cntk.ai/PythonWheel/ForKeras/depends/openmpi_1.10-3.zip
|
||||
- unzip ./openmpi_1.10-3.zip
|
||||
- sudo dpkg -i openmpi_1.10-3.deb
|
||||
- popd
|
||||
|
||||
# command to run tests
|
||||
script:
|
||||
|
||||
+6
-12
@@ -19,7 +19,6 @@ To easily update Theano: `pip install git+git://github.com/Theano/Theano.git --u
|
||||
|
||||
The more information you provide, the easier it is for us to validate that there is a bug and the faster we'll be able to take action. If you want your issue to be resolved quickly, following the steps above is crucial.
|
||||
|
||||
---
|
||||
|
||||
## Requesting a Feature
|
||||
|
||||
@@ -32,15 +31,11 @@ You can also use Github issues to request features you would like to see in Kera
|
||||
3. After discussing the feature you may choose to attempt a Pull Request. If you're at all able, start writing some code. We always have more work to do than time to do it. If you can write some code then that will speed the process along.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Requests for Contributions
|
||||
|
||||
[This is the board](https://github.com/fchollet/keras/projects/1) where we list current outstanding issues and features to be added. If you want to start contributing to Keras, this is the place to start.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Pull Requests
|
||||
|
||||
**Where should I submit my pull request?**
|
||||
@@ -59,16 +54,16 @@ Here's a quick guide to submitting your improvements:
|
||||
4. Write tests. Your code should have full unit test coverage. If you want to see your PR merged promptly, this is crucial.
|
||||
|
||||
5. Run our test suite locally. It's easy: from the Keras folder, simply run: `py.test tests/`.
|
||||
- You will need to install the test requirements as well: `pip install -e .[tests]`.
|
||||
- You will need to install the test requirements as well: `pip install -e .[tests]`.
|
||||
|
||||
6. Make sure all tests are passing:
|
||||
- with the Theano backend, on Python 2.7 and Python 3.5. Make sure you have the development version of Theano.
|
||||
- with the TensorFlow backend, on Python 2.7 and Python 3.5. Make sure you have the development version of TensorFlow.
|
||||
- with the Theano backend, on Python 2.7 and Python 3.5. Make sure you have the development version of Theano.
|
||||
- with the TensorFlow backend, on Python 2.7 and Python 3.5. Make sure you have the development version of TensorFlow.
|
||||
|
||||
7. We use PEP8 syntax conventions, but we aren't dogmatic when it comes to line length. Make sure your lines stay reasonably sized, though. To make your life easier, we recommend running a PEP8 linter:
|
||||
- Install PEP8 packages: `pip install pep8 pytest-pep8 autopep8`
|
||||
- Run a standalone PEP8 check: `py.test --pep8 -m pep8`
|
||||
- You can automatically fix some PEP8 error by running: `autopep8 -i --select <errors> <FILENAME>` for example: `autopep8 -i --select E128 tests/keras/backend/test_backends.py`
|
||||
- Install PEP8 packages: `pip install pep8 pytest-pep8 autopep8`
|
||||
- Run a standalone PEP8 check: `py.test --pep8 -m pep8`
|
||||
- You can automatically fix some PEP8 error by running: `autopep8 -i --select <errors> <FILENAME>` for example: `autopep8 -i --select E128 tests/keras/backend/test_backends.py`
|
||||
|
||||
8. When committing, use appropriate, descriptive commit messages.
|
||||
|
||||
@@ -76,7 +71,6 @@ Here's a quick guide to submitting your improvements:
|
||||
|
||||
10. Submit your PR. If your changes have been approved in a previous discussion, and if you have complete (and passing) unit tests as well as proper docstrings/documentation, your PR is likely to be merged promptly. Otherwise, well...
|
||||
|
||||
---
|
||||
|
||||
## Adding new examples
|
||||
|
||||
|
||||
+1
-5
@@ -8,12 +8,8 @@ All contributions by Google:
|
||||
Copyright (c) 2015, Google, Inc.
|
||||
All rights reserved.
|
||||
|
||||
All contributions by Microsoft:
|
||||
Copyright (c) 2017, Microsoft, Inc.
|
||||
All rights reserved.
|
||||
|
||||
All other contributions:
|
||||
Copyright (c) 2015 - 2017, the respective contributors.
|
||||
Copyright (c) 2015, the respective contributors.
|
||||
All rights reserved.
|
||||
|
||||
Each contributor holds copyright over their respective contributions.
|
||||
|
||||
+3
-8
@@ -1,11 +1,11 @@
|
||||
# Keras: Deep Learning for Python
|
||||
# Keras: Deep Learning library for TensorFlow and Theano
|
||||
|
||||
[](https://travis-ci.org/fchollet/keras)
|
||||
[](https://github.com/fchollet/keras/blob/master/LICENSE)
|
||||
|
||||
## You have just found Keras.
|
||||
|
||||
Keras is a high-level neural networks API, written in Python and capable of running on top of either [TensorFlow](https://github.com/tensorflow/tensorflow), [CNTK](https://github.com/Microsoft/cntk) or [Theano](https://github.com/Theano/Theano). It was developed with a focus on enabling fast experimentation. *Being able to go from idea to result with the least possible delay is key to doing good research.*
|
||||
Keras is a high-level neural networks API, written in Python and capable of running on top of either [TensorFlow](https://github.com/tensorflow/tensorflow) or [Theano](https://github.com/Theano/Theano). It was developed with a focus on enabling fast experimentation. *Being able to go from idea to result with the least possible delay is key to doing good research.*
|
||||
|
||||
Use Keras if you need a deep learning library that:
|
||||
|
||||
@@ -125,11 +125,6 @@ Keras uses the following dependencies:
|
||||
- TensorFlow
|
||||
- [See installation instructions](https://www.tensorflow.org/install/).
|
||||
|
||||
*When using the CNTK backend:*
|
||||
|
||||
- CNTK
|
||||
- [See installation instructions](https://docs.microsoft.com/en-us/cognitive-toolkit/setup-cntk-on-your-machine).
|
||||
|
||||
*When using the Theano backend:*
|
||||
|
||||
- Theano
|
||||
@@ -148,7 +143,7 @@ sudo pip install keras
|
||||
------------------
|
||||
|
||||
|
||||
## Switching from TensorFlow to CNTK or Theano
|
||||
## Switching from TensorFlow to Theano
|
||||
|
||||
By default, Keras will use TensorFlow as its tensor manipulation library. [Follow these instructions](http://keras.io/backend/) to configure the Keras backend.
|
||||
|
||||
|
||||
externo
+3
-3
@@ -130,10 +130,10 @@ for i, layer in enumerate(base_model.layers):
|
||||
print(i, layer.name)
|
||||
|
||||
# we chose to train the top 2 inception blocks, i.e. we will freeze
|
||||
# the first 249 layers and unfreeze the rest:
|
||||
for layer in model.layers[:249]:
|
||||
# the first 172 layers and unfreeze the rest:
|
||||
for layer in model.layers[:172]:
|
||||
layer.trainable = False
|
||||
for layer in model.layers[249:]:
|
||||
for layer in model.layers[172:]:
|
||||
layer.trainable = True
|
||||
|
||||
# we need to recompile the model for these modifications to take effect
|
||||
|
||||
externo
+4
-5
@@ -4,13 +4,12 @@
|
||||
|
||||
Keras is a model-level library, providing high-level building blocks for developing deep learning models. It does not handle itself low-level operations such as tensor products, convolutions and so on. Instead, it relies on a specialized, well-optimized tensor manipulation library to do so, serving as the "backend engine" of Keras. Rather than picking one single tensor library and making the implementation of Keras tied to that library, Keras handles the problem in a modular way, and several different backend engines can be plugged seamlessly into Keras.
|
||||
|
||||
At this time, Keras has three backend implementations available: the **TensorFlow** backend, the **Theano** backend, and the **CNTK** backend.
|
||||
At this time, Keras has two backend implementations available: the **TensorFlow** backend and the **Theano** backend.
|
||||
|
||||
- [TensorFlow](http://www.tensorflow.org/) is an open-source symbolic tensor manipulation framework developed by Google, Inc.
|
||||
- [Theano](http://deeplearning.net/software/theano/) is an open-source symbolic tensor manipulation framework developed by LISA/MILA Lab at Université de Montréal.
|
||||
- [CNTK](https://www.microsoft.com/en-us/cognitive-toolkit/) is an open-source, commercial-grade toolkit for deep learning developed by Microsoft.
|
||||
|
||||
In the future, we are likely to add more backend options.
|
||||
In the future, we are likely to add more backend options. Go ask Microsoft about how their CNTK backend project is doing.
|
||||
|
||||
----
|
||||
|
||||
@@ -35,7 +34,7 @@ The default configuration file looks like this:
|
||||
}
|
||||
```
|
||||
|
||||
Simply change the field `backend` to `"theano"`, `"tensorflow"`, or `"cntk"`, and Keras will use the new configuration next time you run any Keras code.
|
||||
Simply change the field `backend` to either `"theano"` or `"tensorflow"`, and Keras will use the new configuration next time you run any Keras code.
|
||||
|
||||
You can also define the environment variable ``KERAS_BACKEND`` and this will
|
||||
override what is defined in your config file :
|
||||
@@ -66,7 +65,7 @@ You can change these settings by editing `$HOME/.keras/keras.json`.
|
||||
- For 3D data, `"channels_last"` assumes `(conv_dim1, conv_dim2, conv_dim3, channels)` while `"channels_first"` assumes `(channels, conv_dim1, conv_dim2, conv_dim3)`.
|
||||
* `epsilon`: float, a numeric fuzzing constant used to avoid dividing by zero in some operations.
|
||||
* `floatx`: string, `"float16"`, `"float32"`, or `"float64"`. Default float precision.
|
||||
* `backend`: string, `"tensorflow"`, `"theano"`, or `"cntk"`.
|
||||
* `backend`: string, `"tensorflow"` or `"theano"`.
|
||||
|
||||
----
|
||||
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ Please cite Keras in your publications if it helps your research. Here is an exa
|
||||
|
||||
### How can I run Keras on GPU?
|
||||
|
||||
If you are running on the TensorFlow or CNTK backends, your code will automatically run on GPU if any available GPU is detected.
|
||||
If you are running on the TensorFlow backend, your code will automatically run on GPU if any available GPU is detected.
|
||||
|
||||
If you are running on the Theano backend, you can use one of the following methods:
|
||||
|
||||
|
||||
@@ -361,7 +361,7 @@ from keras.models import Model, Sequential
|
||||
# First, let's define a vision model using a Sequential model.
|
||||
# This model will encode an image into a vector.
|
||||
vision_model = Sequential()
|
||||
vision_model.add(Conv2D(64, (3, 3), activation='relu', padding='same', input_shape=(3, 224, 224)))
|
||||
vision_model.add(Conv2D(64, (3, 3) activation='relu', padding='same', input_shape=(3, 224, 224)))
|
||||
vision_model.add(Conv2D(64, (3, 3), activation='relu'))
|
||||
vision_model.add(MaxPooling2D((2, 2)))
|
||||
vision_model.add(Conv2D(128, (3, 3), activation='relu', padding='same'))
|
||||
|
||||
externo
+1
-1
@@ -1,3 +1,3 @@
|
||||
# Keras: The Python Deep Learning library
|
||||
# Keras: Deep Learning library for Theano and TensorFlow
|
||||
|
||||
{{autogenerated}}
|
||||
@@ -21,8 +21,7 @@ class MyLayer(Layer):
|
||||
|
||||
def build(self, input_shape):
|
||||
# Create a trainable weight variable for this layer.
|
||||
self.kernel = self.add_weight(name='kernel',
|
||||
shape=(input_shape[1], self.output_dim),
|
||||
self.kernel = self.add_weight(shape=(input_shape[1], self.output_dim),
|
||||
initializer='uniform',
|
||||
trainable=True)
|
||||
super(MyLayer, self).build(input_shape) # Be sure to call this somewhere!
|
||||
|
||||
@@ -24,7 +24,7 @@ print('Loading data...')
|
||||
print(len(x_train), 'train sequences')
|
||||
print(len(x_test), 'test sequences')
|
||||
|
||||
print('Pad sequences (samples x time)')
|
||||
print("Pad sequences (samples x time)")
|
||||
x_train = sequence.pad_sequences(x_train, maxlen=maxlen)
|
||||
x_test = sequence.pad_sequences(x_test, maxlen=maxlen)
|
||||
print('x_train shape:', x_train.shape)
|
||||
|
||||
@@ -57,7 +57,7 @@ from scipy.optimize import fmin_l_bfgs_b
|
||||
import time
|
||||
import argparse
|
||||
|
||||
from keras.applications import vgg19
|
||||
from keras.applications import vgg16
|
||||
from keras import backend as K
|
||||
|
||||
parser = argparse.ArgumentParser(description='Neural style transfer with Keras.')
|
||||
@@ -99,7 +99,7 @@ def preprocess_image(image_path):
|
||||
img = load_img(image_path, target_size=(img_nrows, img_ncols))
|
||||
img = img_to_array(img)
|
||||
img = np.expand_dims(img, axis=0)
|
||||
img = vgg19.preprocess_input(img)
|
||||
img = vgg16.preprocess_input(img)
|
||||
return img
|
||||
|
||||
# util function to convert a tensor into a valid image
|
||||
@@ -137,7 +137,7 @@ input_tensor = K.concatenate([base_image,
|
||||
|
||||
# build the VGG16 network with our 3 images as input
|
||||
# the model will be loaded with pre-trained ImageNet weights
|
||||
model = vgg19.VGG19(input_tensor=input_tensor,
|
||||
model = vgg16.VGG16(input_tensor=input_tensor,
|
||||
weights='imagenet', include_top=False)
|
||||
print('Model loaded.')
|
||||
|
||||
@@ -199,7 +199,7 @@ def total_variation_loss(x):
|
||||
|
||||
# combine these loss functions into a single scalar
|
||||
loss = K.variable(0.)
|
||||
layer_features = outputs_dict['block5_conv2']
|
||||
layer_features = outputs_dict['block4_conv2']
|
||||
base_image_features = layer_features[0, :, :, :]
|
||||
combination_features = layer_features[2, :, :, :]
|
||||
loss += content_weight * content_loss(base_image_features,
|
||||
@@ -273,7 +273,10 @@ evaluator = Evaluator()
|
||||
|
||||
# run scipy-based optimization (L-BFGS) over the pixels of the generated image
|
||||
# so as to minimize the neural style loss
|
||||
x = preprocess_image(base_image_path)
|
||||
if K.image_data_format() == 'channels_first':
|
||||
x = np.random.uniform(0, 255, (1, 3, img_nrows, img_ncols)) - 128.
|
||||
else:
|
||||
x = np.random.uniform(0, 255, (1, img_nrows, img_ncols, 3)) - 128.
|
||||
|
||||
for i in range(iterations):
|
||||
print('Start of iteration', i)
|
||||
|
||||
+13
-8
@@ -1,23 +1,28 @@
|
||||
"""The Keras API.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from . import activations
|
||||
from . import applications
|
||||
from . import backend
|
||||
from . import datasets
|
||||
from . import engine
|
||||
from . import layers
|
||||
from . import preprocessing
|
||||
from . import utils
|
||||
from . import wrappers
|
||||
from . import callbacks
|
||||
from . import constraints
|
||||
from . import datasets
|
||||
from . import engine
|
||||
from . import initializers
|
||||
from . import layers
|
||||
from . import losses
|
||||
from . import metrics
|
||||
from . import models
|
||||
from . import losses
|
||||
from . import optimizers
|
||||
from . import preprocessing
|
||||
from . import regularizers
|
||||
from . import utils
|
||||
from . import wrappers
|
||||
|
||||
# Importable from root because it's technically not a layer
|
||||
from .layers import Input
|
||||
|
||||
__version__ = '2.0.5'
|
||||
__version__ = '2.0.4-tf'
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
"""Keras built-in activation functions.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
import six
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import warnings
|
||||
from . import backend as K
|
||||
import six
|
||||
from .utils.generic_utils import deserialize_keras_object
|
||||
from .engine import Layer
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
"""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 .inception_v3 import InceptionV3
|
||||
from .resnet50 import ResNet50
|
||||
from .vgg16 import VGG16
|
||||
from .vgg19 import VGG19
|
||||
from .resnet50 import ResNet50
|
||||
from .inception_v3 import InceptionV3
|
||||
from .xception import Xception
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
"""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 ..utils.data_utils import get_file
|
||||
from .. import backend as K
|
||||
from ..utils.data_utils import get_file
|
||||
|
||||
CLASS_INDEX = None
|
||||
CLASS_INDEX_PATH = 'https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.json'
|
||||
|
||||
@@ -10,27 +10,29 @@ and that the input preprocessing function is also different (same as Xception).
|
||||
- [Rethinking the Inception Architecture for Computer Vision](http://arxiv.org/abs/1512.00567)
|
||||
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import warnings
|
||||
|
||||
from ..models import Model
|
||||
from .. import backend as K
|
||||
from .. import layers
|
||||
from ..engine.topology import get_source_inputs
|
||||
from .imagenet_utils import _obtain_input_shape
|
||||
from .imagenet_utils import decode_predictions # pylint: disable=unused-import
|
||||
from ..layers import AveragePooling2D
|
||||
from ..layers import Activation
|
||||
from ..layers import Dense
|
||||
from ..layers import Input
|
||||
from ..layers import BatchNormalization
|
||||
from ..layers import Conv2D
|
||||
from ..layers import MaxPooling2D
|
||||
from ..layers import AveragePooling2D
|
||||
from ..layers import Dense
|
||||
from ..layers import GlobalAveragePooling2D
|
||||
from ..layers import GlobalMaxPooling2D
|
||||
from ..engine.topology import get_source_inputs
|
||||
from ..layers import Input
|
||||
from ..layers import MaxPooling2D
|
||||
from ..models import Model
|
||||
from ..utils.data_utils import get_file
|
||||
from .. import backend as K
|
||||
from .imagenet_utils import decode_predictions
|
||||
from .imagenet_utils import _obtain_input_shape
|
||||
from ..utils.layer_utils import convert_all_kernels_in_model
|
||||
|
||||
|
||||
WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.5/inception_v3_weights_tf_dim_ordering_tf_kernels.h5'
|
||||
@@ -156,10 +158,7 @@ def InceptionV3(include_top=True,
|
||||
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
|
||||
img_input = Input(tensor=input_tensor, shape=input_shape)
|
||||
|
||||
if K.image_data_format() == 'channels_first':
|
||||
channel_axis = 1
|
||||
|
||||
@@ -7,31 +7,32 @@
|
||||
|
||||
Adapted from code contributed by BigMoyan.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import warnings
|
||||
|
||||
from ..layers import Input
|
||||
from .. import backend as K
|
||||
from .. import layers
|
||||
from ..layers import Dense
|
||||
from ..engine.topology import get_source_inputs
|
||||
from .imagenet_utils import _obtain_input_shape
|
||||
from .imagenet_utils import decode_predictions # pylint: disable=unused-import
|
||||
from .imagenet_utils import preprocess_input # pylint: disable=unused-import
|
||||
from ..layers import Activation
|
||||
from ..layers import Flatten
|
||||
from ..layers import Conv2D
|
||||
from ..layers import MaxPooling2D
|
||||
from ..layers import ZeroPadding2D
|
||||
from ..layers import AveragePooling2D
|
||||
from ..layers import BatchNormalization
|
||||
from ..layers import Conv2D
|
||||
from ..layers import Dense
|
||||
from ..layers import Flatten
|
||||
from ..layers import GlobalAveragePooling2D
|
||||
from ..layers import GlobalMaxPooling2D
|
||||
from ..layers import BatchNormalization
|
||||
from ..layers import Input
|
||||
from ..layers import MaxPooling2D
|
||||
from ..layers import ZeroPadding2D
|
||||
from ..models import Model
|
||||
from .. import backend as K
|
||||
from ..engine.topology import get_source_inputs
|
||||
from ..utils import layer_utils
|
||||
from ..utils.data_utils import get_file
|
||||
from .imagenet_utils import decode_predictions
|
||||
from .imagenet_utils import preprocess_input
|
||||
from .imagenet_utils import _obtain_input_shape
|
||||
|
||||
|
||||
WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.2/resnet50_weights_tf_dim_ordering_tf_kernels.h5'
|
||||
@@ -43,7 +44,7 @@ def identity_block(input_tensor, kernel_size, filters, stage, block):
|
||||
|
||||
# Arguments
|
||||
input_tensor: input tensor
|
||||
kernel_size: default 3, the kernel size of middle conv layer at main path
|
||||
kernel_size: defualt 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
|
||||
@@ -77,14 +78,15 @@ def identity_block(input_tensor, kernel_size, filters, stage, block):
|
||||
|
||||
|
||||
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
|
||||
"""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
|
||||
kernel_size: defualt 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.
|
||||
@@ -194,10 +196,8 @@ def ResNet50(include_top=True, weights='imagenet',
|
||||
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
|
||||
img_input = Input(tensor=input_tensor, shape=input_shape)
|
||||
|
||||
if K.image_data_format() == 'channels_last':
|
||||
bn_axis = 3
|
||||
else:
|
||||
|
||||
@@ -6,26 +6,27 @@
|
||||
- [Very Deep Convolutional Networks for Large-Scale Image Recognition](https://arxiv.org/abs/1409.1556)
|
||||
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import warnings
|
||||
|
||||
from ..models import Model
|
||||
from ..layers import Flatten
|
||||
from ..layers import Dense
|
||||
from ..layers import Input
|
||||
from .. import backend as K
|
||||
from ..engine.topology import get_source_inputs
|
||||
from .imagenet_utils import _obtain_input_shape
|
||||
from .imagenet_utils import decode_predictions # pylint: disable=unused-import
|
||||
from .imagenet_utils import preprocess_input # pylint: disable=unused-import
|
||||
from ..layers import Conv2D
|
||||
from ..layers import MaxPooling2D
|
||||
from ..layers import Dense
|
||||
from ..layers import Flatten
|
||||
from ..layers import GlobalAveragePooling2D
|
||||
from ..layers import GlobalMaxPooling2D
|
||||
from ..engine.topology import get_source_inputs
|
||||
from ..layers import Input
|
||||
from ..layers import MaxPooling2D
|
||||
from ..models import Model
|
||||
from ..utils import layer_utils
|
||||
from ..utils.data_utils import get_file
|
||||
from .. import backend as K
|
||||
from .imagenet_utils import decode_predictions
|
||||
from .imagenet_utils import preprocess_input
|
||||
from .imagenet_utils import _obtain_input_shape
|
||||
|
||||
|
||||
WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels.h5'
|
||||
@@ -103,10 +104,8 @@ def VGG16(include_top=True, weights='imagenet',
|
||||
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
|
||||
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)
|
||||
|
||||
@@ -6,26 +6,27 @@
|
||||
- [Very Deep Convolutional Networks for Large-Scale Image Recognition](https://arxiv.org/abs/1409.1556)
|
||||
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import warnings
|
||||
|
||||
from ..models import Model
|
||||
from ..layers import Flatten
|
||||
from ..layers import Dense
|
||||
from ..layers import Input
|
||||
from .. import backend as K
|
||||
from ..engine.topology import get_source_inputs
|
||||
from .imagenet_utils import _obtain_input_shape
|
||||
from .imagenet_utils import decode_predictions # pylint: disable=unused-import
|
||||
from .imagenet_utils import preprocess_input # pylint: disable=unused-import
|
||||
from ..layers import Conv2D
|
||||
from ..layers import MaxPooling2D
|
||||
from ..layers import Dense
|
||||
from ..layers import Flatten
|
||||
from ..layers import GlobalAveragePooling2D
|
||||
from ..layers import GlobalMaxPooling2D
|
||||
from ..engine.topology import get_source_inputs
|
||||
from ..layers import Input
|
||||
from ..layers import MaxPooling2D
|
||||
from ..models import Model
|
||||
from ..utils import layer_utils
|
||||
from ..utils.data_utils import get_file
|
||||
from .. import backend as K
|
||||
from .imagenet_utils import decode_predictions
|
||||
from .imagenet_utils import preprocess_input
|
||||
from .imagenet_utils import _obtain_input_shape
|
||||
|
||||
|
||||
WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg19_weights_tf_dim_ordering_tf_kernels.h5'
|
||||
@@ -103,10 +104,8 @@ def VGG19(include_top=True, weights='imagenet',
|
||||
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
|
||||
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)
|
||||
|
||||
@@ -17,27 +17,28 @@ due to its reliance on `SeparableConvolution` layers.
|
||||
- [Xception: Deep Learning with Depthwise Separable Convolutions](https://arxiv.org/abs/1610.02357)
|
||||
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import warnings
|
||||
|
||||
from ..models import Model
|
||||
from .. import backend as K
|
||||
from .. import layers
|
||||
from ..layers import Dense
|
||||
from ..layers import Input
|
||||
from ..layers import BatchNormalization
|
||||
from ..engine.topology import get_source_inputs
|
||||
from .imagenet_utils import _obtain_input_shape
|
||||
from .imagenet_utils import decode_predictions # pylint: disable=unused-import
|
||||
from ..layers import Activation
|
||||
from ..layers import BatchNormalization
|
||||
from ..layers import Conv2D
|
||||
from ..layers import SeparableConv2D
|
||||
from ..layers import MaxPooling2D
|
||||
from ..layers import Dense
|
||||
from ..layers import GlobalAveragePooling2D
|
||||
from ..layers import GlobalMaxPooling2D
|
||||
from ..engine.topology import get_source_inputs
|
||||
from ..layers import Input
|
||||
from ..layers import MaxPooling2D
|
||||
from ..layers import SeparableConv2D
|
||||
from ..models import Model
|
||||
from ..utils.data_utils import get_file
|
||||
from .. import backend as K
|
||||
from .imagenet_utils import decode_predictions
|
||||
from .imagenet_utils import _obtain_input_shape
|
||||
|
||||
|
||||
TF_WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.4/xception_weights_tf_dim_ordering_tf_kernels.h5'
|
||||
@@ -133,10 +134,7 @@ def Xception(include_top=True, weights='imagenet',
|
||||
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
|
||||
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)
|
||||
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,101 +0,0 @@
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
import os
|
||||
import json
|
||||
import sys
|
||||
from .common import epsilon
|
||||
from .common import floatx
|
||||
from .common import set_epsilon
|
||||
from .common import set_floatx
|
||||
from .common import cast_to_floatx
|
||||
from .common import image_data_format
|
||||
from .common import set_image_data_format
|
||||
|
||||
# Obtain Keras base dir path: either ~/.keras or /tmp.
|
||||
_keras_base_dir = os.path.expanduser('~')
|
||||
if not os.access(_keras_base_dir, os.W_OK):
|
||||
_keras_base_dir = '/tmp'
|
||||
_keras_dir = os.path.join(_keras_base_dir, '.keras')
|
||||
|
||||
# Default backend: TensorFlow.
|
||||
_BACKEND = 'tensorflow'
|
||||
|
||||
# Attempt to read Keras config file.
|
||||
_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)
|
||||
_backend = _config.get('backend', _BACKEND)
|
||||
assert _backend in {'theano', 'tensorflow', 'cntk'}
|
||||
_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)
|
||||
_BACKEND = _backend
|
||||
|
||||
# Save config file, if possible.
|
||||
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': _BACKEND,
|
||||
'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
|
||||
|
||||
# Set backend based on KERAS_BACKEND flag, if applicable.
|
||||
if 'KERAS_BACKEND' in os.environ:
|
||||
_backend = os.environ['KERAS_BACKEND']
|
||||
assert _backend in {'theano', 'tensorflow', 'cntk'}
|
||||
_BACKEND = _backend
|
||||
|
||||
# Import backend functions.
|
||||
if _BACKEND == 'cntk':
|
||||
sys.stderr.write('Using CNTK backend\n')
|
||||
from .cntk_backend import *
|
||||
elif _BACKEND == 'theano':
|
||||
sys.stderr.write('Using Theano backend.\n')
|
||||
from .theano_backend import *
|
||||
elif _BACKEND == 'tensorflow':
|
||||
sys.stderr.write('Using TensorFlow backend.\n')
|
||||
from .tensorflow_backend import *
|
||||
else:
|
||||
raise ValueError('Unknown backend: ' + str(_BACKEND))
|
||||
|
||||
|
||||
def backend():
|
||||
"""Publicly accessible method
|
||||
for determining the current backend.
|
||||
|
||||
# Returns
|
||||
String, the name of the backend Keras is currently using.
|
||||
|
||||
# Example
|
||||
```python
|
||||
>>> keras.backend.backend()
|
||||
'tensorflow'
|
||||
```
|
||||
"""
|
||||
return _BACKEND
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,188 +0,0 @@
|
||||
import numpy as np
|
||||
|
||||
# the type of float to use throughout the session.
|
||||
_FLOATX = 'float32'
|
||||
_EPSILON = 10e-8
|
||||
_IMAGE_DATA_FORMAT = 'channels_last'
|
||||
|
||||
|
||||
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(e):
|
||||
"""Sets the value of the fuzz
|
||||
factor used in numeric expressions.
|
||||
|
||||
# Arguments
|
||||
e: 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 = e
|
||||
|
||||
|
||||
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(floatx):
|
||||
"""Sets the default float type.
|
||||
|
||||
# Arguments
|
||||
String: 'float16', 'float32', or 'float64'.
|
||||
|
||||
# Example
|
||||
```python
|
||||
>>> from keras import backend as K
|
||||
>>> K.floatx()
|
||||
'float32'
|
||||
>>> K.set_floatx('float16')
|
||||
>>> K.floatx()
|
||||
'float16'
|
||||
```
|
||||
"""
|
||||
global _FLOATX
|
||||
if floatx not in {'float16', 'float32', 'float64'}:
|
||||
raise ValueError('Unknown floatx type: ' + str(floatx))
|
||||
_FLOATX = str(floatx)
|
||||
|
||||
|
||||
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 ('channels_first' or 'channels_last').
|
||||
|
||||
# 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 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'
|
||||
```
|
||||
"""
|
||||
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)
|
||||
|
||||
|
||||
# Legacy methods
|
||||
|
||||
def set_image_dim_ordering(dim_ordering):
|
||||
"""Legacy setter for `image_data_format`.
|
||||
|
||||
# Arguments
|
||||
dim_ordering: string. `tf` or `th`.
|
||||
|
||||
# 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: if `dim_ordering` is invalid.
|
||||
"""
|
||||
global _IMAGE_DATA_FORMAT
|
||||
if dim_ordering not in {'tf', 'th'}:
|
||||
raise ValueError('Unknown dim_ordering:', dim_ordering)
|
||||
if dim_ordering == 'th':
|
||||
data_format = 'channels_first'
|
||||
else:
|
||||
data_format = 'channels_last'
|
||||
_IMAGE_DATA_FORMAT = data_format
|
||||
|
||||
|
||||
def image_dim_ordering():
|
||||
"""Legacy getter for `image_data_format`.
|
||||
|
||||
# Returns
|
||||
string, one of `'th'`, `'tf'`
|
||||
"""
|
||||
if _IMAGE_DATA_FORMAT == 'channels_first':
|
||||
return 'th'
|
||||
else:
|
||||
return 'tf'
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+38
-40
@@ -1,29 +1,33 @@
|
||||
"""Keras callbacks: utilities called at certain points during model training.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
from collections import deque
|
||||
from collections import Iterable
|
||||
from collections import OrderedDict
|
||||
import csv
|
||||
import six
|
||||
|
||||
import numpy as np
|
||||
import time
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
import warnings
|
||||
|
||||
from collections import deque
|
||||
from collections import OrderedDict
|
||||
from collections import Iterable
|
||||
from .utils.generic_utils import Progbar
|
||||
from . import backend as K
|
||||
import numpy as np
|
||||
from tensorflow.python.summary import summary as tf_summary
|
||||
from tensorflow.contrib.tensorboard.plugins import projector
|
||||
from tensorflow.python.training import saver as saver_lib
|
||||
from tensorflow.python.ops import array_ops
|
||||
from .utils.generic_utils import Progbar
|
||||
|
||||
# pylint: disable=g-import-not-at-top
|
||||
try:
|
||||
import requests
|
||||
except ImportError:
|
||||
requests = None
|
||||
|
||||
if K.backend() == 'tensorflow':
|
||||
import tensorflow as tf
|
||||
from tensorflow.contrib.tensorboard.plugins import projector
|
||||
# pylint: enable=g-import-not-at-top
|
||||
|
||||
|
||||
class CallbackList(object):
|
||||
@@ -580,6 +584,7 @@ class LearningRateScheduler(Callback):
|
||||
|
||||
|
||||
class TensorBoard(Callback):
|
||||
# pylint: disable=line-too-long
|
||||
"""Tensorboard basic visualizations.
|
||||
|
||||
This callback writes a log for TensorBoard, which allows
|
||||
@@ -623,6 +628,7 @@ class TensorBoard(Callback):
|
||||
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,
|
||||
@@ -634,9 +640,6 @@ class TensorBoard(Callback):
|
||||
embeddings_layer_names=None,
|
||||
embeddings_metadata=None):
|
||||
super(TensorBoard, self).__init__()
|
||||
if K.backend() != 'tensorflow':
|
||||
raise RuntimeError('TensorBoard callback only works '
|
||||
'with the TensorFlow backend.')
|
||||
self.log_dir = log_dir
|
||||
self.histogram_freq = histogram_freq
|
||||
self.merged = None
|
||||
@@ -653,57 +656,52 @@ class TensorBoard(Callback):
|
||||
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:
|
||||
tf.summary.histogram(weight.name, weight)
|
||||
tf_summary.histogram(weight.name, weight)
|
||||
if self.write_grads:
|
||||
grads = model.optimizer.get_gradients(model.total_loss,
|
||||
weight)
|
||||
tf.summary.histogram('{}_grad'.format(weight.name), grads)
|
||||
tf_summary.histogram('{}_grad'.format(weight.name), grads)
|
||||
if self.write_images:
|
||||
w_img = tf.squeeze(weight)
|
||||
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 = tf.transpose(w_img)
|
||||
w_img = array_ops.transpose(w_img)
|
||||
shape = K.int_shape(w_img)
|
||||
w_img = tf.reshape(w_img, [1,
|
||||
shape[0],
|
||||
shape[1],
|
||||
1])
|
||||
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 = tf.transpose(w_img, perm=[2, 0, 1])
|
||||
w_img = array_ops.transpose(w_img, perm=[2, 0, 1])
|
||||
shape = K.int_shape(w_img)
|
||||
w_img = tf.reshape(w_img, [shape[0],
|
||||
shape[1],
|
||||
shape[2],
|
||||
1])
|
||||
w_img = array_ops.reshape(
|
||||
w_img, [shape[0], shape[1], shape[2], 1])
|
||||
elif len(shape) == 1: # bias case
|
||||
w_img = tf.reshape(w_img, [1,
|
||||
shape[0],
|
||||
1,
|
||||
1])
|
||||
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(weight.name, w_img)
|
||||
tf_summary.image(weight.name, w_img)
|
||||
|
||||
if hasattr(layer, 'output'):
|
||||
tf.summary.histogram('{}_out'.format(layer.name),
|
||||
tf_summary.histogram('{}_out'.format(layer.name),
|
||||
layer.output)
|
||||
self.merged = tf.summary.merge_all()
|
||||
self.merged = tf_summary.merge_all()
|
||||
|
||||
if self.write_graph:
|
||||
self.writer = tf.summary.FileWriter(self.log_dir,
|
||||
self.writer = tf_summary.FileWriter(self.log_dir,
|
||||
self.sess.graph)
|
||||
else:
|
||||
self.writer = tf.summary.FileWriter(self.log_dir)
|
||||
self.writer = tf_summary.FileWriter(self.log_dir)
|
||||
|
||||
if self.embeddings_freq:
|
||||
embeddings_layer_names = self.embeddings_layer_names
|
||||
@@ -716,7 +714,7 @@ class TensorBoard(Callback):
|
||||
for layer in self.model.layers
|
||||
if layer.name in embeddings_layer_names}
|
||||
|
||||
self.saver = tf.train.Saver(list(embeddings.values()))
|
||||
self.saver = saver_lib.Saver(list(embeddings.values()))
|
||||
|
||||
embeddings_metadata = {}
|
||||
|
||||
@@ -779,7 +777,7 @@ class TensorBoard(Callback):
|
||||
for name, value in logs.items():
|
||||
if name in ['batch', 'size']:
|
||||
continue
|
||||
summary = tf.Summary()
|
||||
summary = tf_summary.Summary()
|
||||
summary_value = summary.value.add()
|
||||
summary_value.simple_value = value.item()
|
||||
summary_value.tag = name
|
||||
|
||||
+10
-9
@@ -1,8 +1,13 @@
|
||||
"""Constraints: functions that impose constraints on weights values.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
import six
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from . import backend as K
|
||||
from .utils.generic_utils import serialize_keras_object
|
||||
import six
|
||||
from .utils.generic_utils import deserialize_keras_object
|
||||
from .utils.generic_utils import serialize_keras_object
|
||||
|
||||
|
||||
class Constraint(object):
|
||||
@@ -58,7 +63,7 @@ class NonNeg(Constraint):
|
||||
"""
|
||||
|
||||
def __call__(self, w):
|
||||
w *= K.cast(K.greater_equal(w, 0.), K.floatx())
|
||||
w *= K.cast(w >= 0., K.floatx())
|
||||
return w
|
||||
|
||||
|
||||
@@ -142,16 +147,12 @@ class MinMaxNorm(Constraint):
|
||||
|
||||
# Aliases.
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
max_norm = MaxNorm
|
||||
non_neg = NonNeg
|
||||
unit_norm = UnitNorm
|
||||
min_max_norm = MinMaxNorm
|
||||
|
||||
|
||||
# Legacy aliases.
|
||||
maxnorm = max_norm
|
||||
nonneg = non_neg
|
||||
unitnorm = unit_norm
|
||||
# pylint: enable=invalid-name
|
||||
|
||||
|
||||
def serialize(constraint):
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""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 . import mnist
|
||||
from . import imdb
|
||||
from . import reuters
|
||||
from . import boston_housing
|
||||
from . import cifar10
|
||||
from . import cifar100
|
||||
from . import boston_housing
|
||||
from . import imdb
|
||||
from . import mnist
|
||||
from . import reuters
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
from ..utils.data_utils import get_file
|
||||
"""Boston housing price regression dataset.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
from ..utils.data_utils import get_file
|
||||
|
||||
|
||||
def load_data(path='boston_housing.npz', seed=113, test_split=0.2):
|
||||
@@ -16,9 +22,7 @@ def load_data(path='boston_housing.npz', seed=113, test_split=0.2):
|
||||
Tuple of Numpy arrays: `(x_train, y_train), (x_test, y_test)`.
|
||||
"""
|
||||
assert 0 <= test_split < 1
|
||||
path = get_file(path,
|
||||
origin='https://s3.amazonaws.com/keras-datasets/boston_housing.npz',
|
||||
file_hash='f553886a1f8d56431e820c5b82552d9d95cfcb96d1e678153f8839538947dff5')
|
||||
path = get_file(path, origin='https://s3.amazonaws.com/keras-datasets/boston_housing.npz')
|
||||
f = np.load(path)
|
||||
x = f['x']
|
||||
y = f['y']
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
"""Utilities used by the CIFAR10 and CIFAR100 datasets.
|
||||
"""
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
from six.moves import cPickle
|
||||
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
"""CIFAR10 small image classification dataset.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from .cifar import load_batch
|
||||
from ..utils.data_utils import get_file
|
||||
from .. import backend as K
|
||||
import numpy as np
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
|
||||
from .. import backend as K
|
||||
from .cifar import load_batch
|
||||
import numpy as np
|
||||
from ..utils.data_utils import get_file
|
||||
|
||||
|
||||
def load_data():
|
||||
"""Loads CIFAR10 dataset.
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
"""CIFAR100 small image classification dataset.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from .cifar import load_batch
|
||||
from ..utils.data_utils import get_file
|
||||
from .. import backend as K
|
||||
import numpy as np
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
|
||||
from .. import backend as K
|
||||
from .cifar import load_batch
|
||||
import numpy as np
|
||||
from ..utils.data_utils import get_file
|
||||
|
||||
|
||||
def load_data(label_mode='fine'):
|
||||
"""Loads CIFAR100 dataset.
|
||||
|
||||
+10
-13
@@ -1,14 +1,19 @@
|
||||
"""IMDB movie review sentiment classification dataset.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from ..utils.data_utils import get_file
|
||||
from six.moves import zip
|
||||
import numpy as np
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import json
|
||||
import warnings
|
||||
|
||||
import numpy as np
|
||||
from six.moves import zip
|
||||
from ..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, **kwargs):
|
||||
start_char=1, oov_char=2, index_from=3):
|
||||
"""Loads the IMDB dataset.
|
||||
|
||||
# Arguments
|
||||
@@ -39,14 +44,6 @@ def load_data(path='imdb.npz', num_words=None, skip_top=0,
|
||||
Words that were not seen in the training set but are in the test set
|
||||
have simply been skipped.
|
||||
"""
|
||||
# Legacy support
|
||||
if 'nb_words' in kwargs:
|
||||
warnings.warn('The `nb_words` argument in `load_data` '
|
||||
'has been renamed `num_words`.')
|
||||
num_words = kwargs.pop('nb_words')
|
||||
if kwargs:
|
||||
raise TypeError('Unrecognized keyword arguments: ' + str(kwargs))
|
||||
|
||||
path = get_file(path,
|
||||
origin='https://s3.amazonaws.com/text-datasets/imdb.npz')
|
||||
f = np.load(path)
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
from ..utils.data_utils import get_file
|
||||
"""MNIST handwritten digits classification dataset.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
from ..utils.data_utils import get_file
|
||||
|
||||
|
||||
def load_data(path='mnist.npz'):
|
||||
|
||||
+10
-13
@@ -1,15 +1,20 @@
|
||||
"""Reuters newswire topic classification dataset.
|
||||
"""
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import
|
||||
from ..utils.data_utils import get_file
|
||||
from six.moves import zip
|
||||
import numpy as np
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import json
|
||||
import warnings
|
||||
|
||||
import numpy as np
|
||||
from six.moves import zip
|
||||
from ..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, **kwargs):
|
||||
start_char=1, oov_char=2, index_from=3):
|
||||
"""Loads the Reuters newswire classification dataset.
|
||||
|
||||
# Arguments
|
||||
@@ -37,14 +42,6 @@ def load_data(path='reuters.npz', num_words=None, skip_top=0,
|
||||
Words that were not seen in the training set but are in the test set
|
||||
have simply been skipped.
|
||||
"""
|
||||
# Legacy support
|
||||
if 'nb_words' in kwargs:
|
||||
warnings.warn('The `nb_words` argument in `load_data` '
|
||||
'has been renamed `num_words`.')
|
||||
num_words = kwargs.pop('nb_words')
|
||||
if kwargs:
|
||||
raise TypeError('Unrecognized keyword arguments: ' + str(kwargs))
|
||||
|
||||
path = get_file(path, origin='https://s3.amazonaws.com/text-datasets/reuters.npz')
|
||||
npzfile = np.load(path)
|
||||
xs = npzfile['x']
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
# note: topology.Node is an internal class,
|
||||
"""The Keras Engine: graph topology and training loop functionality.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
# Note: topology.Node is an internal class,
|
||||
# it isn't meant to be used by Keras users.
|
||||
from .topology import InputSpec
|
||||
from .topology import get_source_inputs
|
||||
from .topology import Input
|
||||
from .topology import InputLayer
|
||||
from .topology import InputSpec
|
||||
from .topology import Layer
|
||||
from .topology import get_source_inputs
|
||||
from .training import Model
|
||||
|
||||
+120
-155
@@ -1,30 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import print_function
|
||||
"""Base layer code and base model (Container) code.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
import json
|
||||
import yaml
|
||||
import warnings
|
||||
import copy
|
||||
import inspect
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import inspect
|
||||
from six.moves import zip
|
||||
import warnings
|
||||
|
||||
from .. import backend as K
|
||||
from .. import initializers
|
||||
import numpy as np
|
||||
from six.moves import zip
|
||||
from tensorflow.python.framework import tensor_shape
|
||||
from ..utils.io_utils import ask_to_proceed_with_overwrite
|
||||
from ..utils.layer_utils import print_summary as print_layer_summary
|
||||
from ..utils import conv_utils
|
||||
from ..legacy import interfaces
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
class InputSpec(object):
|
||||
"""Specifies the ndim, dtype and shape of every input to a layer.
|
||||
@@ -93,15 +101,11 @@ class Node(object):
|
||||
output_tensors: list of output tensors.
|
||||
input_masks: list of input masks (a mask can be a tensor, or None).
|
||||
output_masks: list of output masks (a mask can be a tensor, or None).
|
||||
input_shapes: list of input shape tuples.
|
||||
output_shapes: list of output shape tuples.
|
||||
arguments: dictionary of keyword arguments that were passed to the
|
||||
`call` method of the layer at the call that created the node.
|
||||
|
||||
`node_indices` and `tensor_indices` are basically fine-grained coordinates
|
||||
describing the origin of the `input_tensors`, verifying the following:
|
||||
|
||||
`input_tensors[i] == inbound_layers[i].inbound_nodes[node_indices[i]].output_tensors[tensor_indices[i]]`
|
||||
describing the origin of the `input_tensors`.
|
||||
|
||||
A node from layer A to layer B is added to:
|
||||
A.outbound_nodes
|
||||
@@ -112,7 +116,6 @@ class Node(object):
|
||||
inbound_layers, node_indices, tensor_indices,
|
||||
input_tensors, output_tensors,
|
||||
input_masks, output_masks,
|
||||
input_shapes, output_shapes,
|
||||
arguments=None):
|
||||
# Layer instance (NOT a list).
|
||||
# this is the layer that takes a list of input tensors
|
||||
@@ -150,9 +153,9 @@ class Node(object):
|
||||
# Following 2 properties: input and output shapes.
|
||||
|
||||
# List of shape tuples, shapes of input_tensors.
|
||||
self.input_shapes = input_shapes
|
||||
self.input_shapes = [K.int_shape(x) for x in input_tensors]
|
||||
# List of shape tuples, shapes of output_tensors.
|
||||
self.output_shapes = output_shapes
|
||||
self.output_shapes = [K.int_shape(x) for x in output_tensors]
|
||||
|
||||
# Optional keyword arguments to layer's `call`.
|
||||
self.arguments = arguments
|
||||
@@ -221,12 +224,12 @@ class Layer(object):
|
||||
`self._add_inbound_node(last_layer)`
|
||||
- Add layer to tensor history
|
||||
If layer is not built:
|
||||
- Build from x._keras_shape
|
||||
- Build from inputs shape
|
||||
get_weights()
|
||||
set_weights(weights)
|
||||
get_config()
|
||||
count_params()
|
||||
compute_output_shape(input_shape)
|
||||
_compute_output_shape(input_shape)
|
||||
compute_mask(x, mask)
|
||||
get_input_at(node_index)
|
||||
get_output_at(node_index)
|
||||
@@ -360,7 +363,6 @@ class Layer(object):
|
||||
def non_trainable_weights(self, weights):
|
||||
self._non_trainable_weights = weights
|
||||
|
||||
@interfaces.legacy_add_weight_support
|
||||
def add_weight(self,
|
||||
name,
|
||||
shape,
|
||||
@@ -385,6 +387,7 @@ class Layer(object):
|
||||
# Returns
|
||||
The created weight variable.
|
||||
"""
|
||||
shape = tuple(tensor_shape.TensorShape(shape).as_list())
|
||||
initializer = initializers.get(initializer)
|
||||
if dtype is None:
|
||||
dtype = K.floatx()
|
||||
@@ -415,9 +418,7 @@ class Layer(object):
|
||||
"""
|
||||
inputs = _to_list(inputs)
|
||||
for x in inputs:
|
||||
try:
|
||||
K.is_keras_tensor(x)
|
||||
except ValueError:
|
||||
if not isinstance(x, K.tensor_types()):
|
||||
raise ValueError('Layer ' + self.name + ' was called with '
|
||||
'an input that isn\'t a symbolic tensor. '
|
||||
'Received type: ' +
|
||||
@@ -481,6 +482,8 @@ class Layer(object):
|
||||
x_shape = None
|
||||
if x_shape is not None:
|
||||
for axis, value in spec.axes.items():
|
||||
if hasattr(value, 'value'):
|
||||
value = value.value
|
||||
if value is not None and x_shape[int(axis)] not in {value, None}:
|
||||
raise ValueError('Input ' + str(input_index) +
|
||||
' is incompatible with layer ' +
|
||||
@@ -496,6 +499,8 @@ class Layer(object):
|
||||
x_shape = None
|
||||
if x_shape is not None:
|
||||
for spec_dim, dim in zip(spec.shape, x_shape):
|
||||
if hasattr(spec_dim, 'value'):
|
||||
spec_dim = spec_dim.value
|
||||
if spec_dim is not None and dim is not None:
|
||||
if spec_dim != dim:
|
||||
raise ValueError(
|
||||
@@ -505,7 +510,7 @@ class Layer(object):
|
||||
str(spec.shape) + ', found shape=' +
|
||||
str(x_shape))
|
||||
|
||||
def call(self, inputs, **kwargs):
|
||||
def call(self, inputs, **kwargs): # pylint: disable=unused-argument
|
||||
"""This is where the layer's logic lives.
|
||||
|
||||
# Arguments
|
||||
@@ -523,10 +528,7 @@ class Layer(object):
|
||||
If a Keras tensor is passed:
|
||||
- We call self._add_inbound_node().
|
||||
- If necessary, we `build` the layer to match
|
||||
the _keras_shape of the input(s).
|
||||
- We update the _keras_shape of every input tensor with
|
||||
its new shape (obtained via self.compute_output_shape).
|
||||
This is done as part of _add_inbound_node().
|
||||
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().
|
||||
@@ -554,17 +556,7 @@ class Layer(object):
|
||||
# Collect input shapes to build layer.
|
||||
input_shapes = []
|
||||
for x_elem in _to_list(inputs):
|
||||
if hasattr(x_elem, '_keras_shape'):
|
||||
input_shapes.append(x_elem._keras_shape)
|
||||
elif hasattr(K, 'int_shape'):
|
||||
input_shapes.append(K.int_shape(x_elem))
|
||||
else:
|
||||
raise ValueError('You tried to call layer "' + self.name +
|
||||
'". This layer has no information'
|
||||
' about its expected input shape, '
|
||||
'and thus cannot be built. '
|
||||
'You can build it manually via: '
|
||||
'`layer.build(batch_input_shape)`')
|
||||
input_shapes.append(K.int_shape(x_elem))
|
||||
if len(input_shapes) == 1:
|
||||
self.build(input_shapes[0])
|
||||
else:
|
||||
@@ -589,8 +581,6 @@ class Layer(object):
|
||||
# If mask is explicitly passed to __call__,
|
||||
# we should override the default mask.
|
||||
kwargs['mask'] = previous_mask
|
||||
# Handle automatic shape inference (only useful for Theano).
|
||||
input_shape = _collect_input_shape(inputs)
|
||||
|
||||
# Actually call the layer, collecting output(s), mask(s), and shape(s).
|
||||
output = self.call(inputs, **kwargs)
|
||||
@@ -610,15 +600,6 @@ class Layer(object):
|
||||
else:
|
||||
output = output_ls_copy
|
||||
|
||||
# Infering the output shape is only relevant for Theano.
|
||||
if all([s is not None for s in _to_list(input_shape)]):
|
||||
output_shape = self.compute_output_shape(input_shape)
|
||||
else:
|
||||
if isinstance(input_shape, list):
|
||||
output_shape = [None for _ in input_shape]
|
||||
else:
|
||||
output_shape = None
|
||||
|
||||
# Add an inbound node to the layer, so that it keeps track
|
||||
# of the call and of all new variables created during the call.
|
||||
# This also updates the layer history of the output tensor(s).
|
||||
@@ -626,7 +607,6 @@ class Layer(object):
|
||||
# this does nothing.
|
||||
self._add_inbound_node(input_tensors=inputs, output_tensors=output,
|
||||
input_masks=previous_mask, output_masks=output_mask,
|
||||
input_shapes=input_shape, output_shapes=output_shape,
|
||||
arguments=user_kwargs)
|
||||
|
||||
# Apply activity regularizer if any:
|
||||
@@ -637,7 +617,7 @@ class Layer(object):
|
||||
|
||||
def _add_inbound_node(self, input_tensors, output_tensors,
|
||||
input_masks, output_masks,
|
||||
input_shapes, output_shapes, arguments=None):
|
||||
arguments=None):
|
||||
"""Internal method to create an inbound node for the layer.
|
||||
|
||||
# Arguments
|
||||
@@ -645,8 +625,6 @@ class Layer(object):
|
||||
output_tensors: list of output tensors.
|
||||
input_masks: list of input masks (a mask can be a tensor, or None).
|
||||
output_masks: list of output masks (a mask can be a tensor, or None).
|
||||
input_shapes: list of input shape tuples.
|
||||
output_shapes: list of output shape tuples.
|
||||
arguments: dictionary of keyword arguments that were passed to the
|
||||
`call` method of the layer at the call that created the node.
|
||||
"""
|
||||
@@ -654,8 +632,6 @@ class Layer(object):
|
||||
output_tensors = _to_list(output_tensors)
|
||||
input_masks = _to_list(input_masks)
|
||||
output_masks = _to_list(output_masks)
|
||||
input_shapes = _to_list(input_shapes)
|
||||
output_shapes = _to_list(output_shapes)
|
||||
|
||||
# Collect input tensor(s) coordinates.
|
||||
inbound_layers = []
|
||||
@@ -682,14 +658,11 @@ class Layer(object):
|
||||
output_tensors=output_tensors,
|
||||
input_masks=input_masks,
|
||||
output_masks=output_masks,
|
||||
input_shapes=input_shapes,
|
||||
output_shapes=output_shapes,
|
||||
arguments=arguments
|
||||
)
|
||||
|
||||
# Update tensor history, _keras_shape and _uses_learning_phase.
|
||||
# Update tensor history and `_uses_learning_phase`.
|
||||
for i in range(len(output_tensors)):
|
||||
output_tensors[i]._keras_shape = output_shapes[i]
|
||||
uses_lp = any([getattr(x, '_uses_learning_phase', False) for x in input_tensors])
|
||||
uses_lp = getattr(self, 'uses_learning_phase', False) or uses_lp
|
||||
output_tensors[i]._uses_learning_phase = getattr(output_tensors[i], '_uses_learning_phase', False) or uses_lp
|
||||
@@ -697,7 +670,7 @@ class Layer(object):
|
||||
len(self.inbound_nodes) - 1,
|
||||
i)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
def _compute_output_shape(self, input_shape):
|
||||
"""Computes the output shape of the layer.
|
||||
|
||||
Assumes that the layer will be built
|
||||
@@ -712,13 +685,12 @@ class Layer(object):
|
||||
# Returns
|
||||
An input shape tuple.
|
||||
"""
|
||||
if hasattr(self, 'get_output_shape_for'):
|
||||
msg = "Class `{}.{}` defines `get_output_shape_for` but does not override `compute_output_shape`. " + \
|
||||
"If this is a Keras 1 layer, please implement `compute_output_shape` to support Keras 2."
|
||||
warnings.warn(msg.format(type(self).__module__, type(self).__name__), stacklevel=2)
|
||||
return input_shape
|
||||
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):
|
||||
def compute_mask(self, inputs, mask=None): # pylint: disable=unused-argument
|
||||
"""Computes an output mask tensor.
|
||||
|
||||
# Arguments
|
||||
@@ -748,7 +720,7 @@ class Layer(object):
|
||||
# carry over the input mask
|
||||
return mask
|
||||
|
||||
def build(self, input_shape):
|
||||
def build(self, input_shape): # pylint: disable=unused-argument
|
||||
"""Creates the layer weights.
|
||||
|
||||
Must be implemented on all layers that have weights.
|
||||
@@ -1020,9 +992,9 @@ class Layer(object):
|
||||
if len(all_input_shapes) == 1:
|
||||
input_shapes = self.inbound_nodes[0].input_shapes
|
||||
if len(input_shapes) == 1:
|
||||
return input_shapes[0]
|
||||
return tuple(tensor_shape.TensorShape(input_shapes[0]).as_list())
|
||||
else:
|
||||
return input_shapes
|
||||
return [tuple(tensor_shape.TensorShape(shape).as_list()) for shape in input_shapes]
|
||||
else:
|
||||
raise AttributeError('The layer "' + str(self.name) +
|
||||
' has multiple inbound nodes, '
|
||||
@@ -1054,9 +1026,9 @@ class Layer(object):
|
||||
if len(all_output_shapes) == 1:
|
||||
output_shapes = self.inbound_nodes[0].output_shapes
|
||||
if len(output_shapes) == 1:
|
||||
return output_shapes[0]
|
||||
return tuple(tensor_shape.TensorShape(output_shapes[0]).as_list())
|
||||
else:
|
||||
return output_shapes
|
||||
return [tuple(tensor_shape.TensorShape(shape).as_list()) for shape in output_shapes]
|
||||
else:
|
||||
raise AttributeError('The layer "' + str(self.name) +
|
||||
' has multiple inbound nodes, '
|
||||
@@ -1081,14 +1053,14 @@ class Layer(object):
|
||||
(e.g. L2 weight regularization, which only depends
|
||||
on the layer's weights variables, not on any inputs tensors).
|
||||
"""
|
||||
if losses is None or losses == []:
|
||||
if losses is None or losses == []: # pylint: disable=g-explicit-bool-comparison
|
||||
return
|
||||
# Update self.losses
|
||||
losses = _to_list(losses)
|
||||
if hasattr(self, '_losses'):
|
||||
self._losses += losses
|
||||
# Update self._per_input_updates
|
||||
if isinstance(input, list) and inputs == []:
|
||||
if inputs == []: # pylint: disable=g-explicit-bool-comparison
|
||||
inputs = None
|
||||
if inputs is not None:
|
||||
inputs_hash = _object_list_uid(inputs)
|
||||
@@ -1113,14 +1085,14 @@ class Layer(object):
|
||||
the updates as conditional on these inputs.
|
||||
If None is passed, the updates are assumed unconditional.
|
||||
"""
|
||||
if updates is None or updates == []:
|
||||
if updates is None or updates == []: # pylint: disable=g-explicit-bool-comparison
|
||||
return
|
||||
# Update self.updates
|
||||
updates = _to_list(updates)
|
||||
if hasattr(self, '_updates'):
|
||||
self._updates += updates
|
||||
# Update self._per_input_updates
|
||||
if isinstance(inputs, list) and inputs == []:
|
||||
if inputs == []: # pylint: disable=g-explicit-bool-comparison
|
||||
inputs = None
|
||||
if inputs is not None:
|
||||
inputs_hash = _object_list_uid(inputs)
|
||||
@@ -1253,7 +1225,7 @@ class Layer(object):
|
||||
"""
|
||||
if not self.built:
|
||||
if self.__class__.__name__ == 'Sequential':
|
||||
self.build()
|
||||
self.build() # pylint: disable=no-value-for-parameter
|
||||
else:
|
||||
raise RuntimeError('You tried to call `count_params` on ' +
|
||||
self.name + ', but the layer isn\'t built. '
|
||||
@@ -1281,7 +1253,6 @@ class InputLayer(Layer):
|
||||
name: Name of the layer (string).
|
||||
"""
|
||||
|
||||
@interfaces.legacy_input_support
|
||||
def __init__(self, input_shape=None, batch_size=None,
|
||||
batch_input_shape=None,
|
||||
dtype=None, input_tensor=None, sparse=False, name=None):
|
||||
@@ -1298,8 +1269,7 @@ class InputLayer(Layer):
|
||||
raise ValueError('Only provide the input_shape OR '
|
||||
'batch_input_shape argument to '
|
||||
'InputLayer, not both at the same time.')
|
||||
if input_tensor is not None and batch_input_shape is None:
|
||||
# If input_tensor is set, and batch_input_shape is not set:
|
||||
if input_tensor is not None:
|
||||
# Attempt automatic input shape inference.
|
||||
try:
|
||||
batch_input_shape = K.int_shape(input_tensor)
|
||||
@@ -1337,7 +1307,6 @@ class InputLayer(Layer):
|
||||
name=self.name)
|
||||
else:
|
||||
self.is_placeholder = False
|
||||
input_tensor._keras_shape = batch_input_shape
|
||||
# Create an input node to add to self.outbound_node
|
||||
# and set output_tensors' _keras_history.
|
||||
input_tensor._uses_learning_phase = False
|
||||
@@ -1349,9 +1318,7 @@ class InputLayer(Layer):
|
||||
input_tensors=[input_tensor],
|
||||
output_tensors=[input_tensor],
|
||||
input_masks=[None],
|
||||
output_masks=[None],
|
||||
input_shapes=[batch_input_shape],
|
||||
output_shapes=[batch_input_shape])
|
||||
output_masks=[None])
|
||||
|
||||
def get_config(self):
|
||||
config = {'batch_input_shape': self.batch_input_shape,
|
||||
@@ -1361,9 +1328,13 @@ class InputLayer(Layer):
|
||||
return config
|
||||
|
||||
|
||||
def Input(shape=None, batch_shape=None,
|
||||
name=None, dtype=K.floatx(), sparse=False,
|
||||
tensor=None):
|
||||
def Input( # pylint: disable=invalid-name
|
||||
shape=None,
|
||||
batch_shape=None,
|
||||
name=None,
|
||||
dtype=K.floatx(),
|
||||
sparse=False,
|
||||
tensor=None):
|
||||
"""`Input()` is used to instantiate a Keras tensor.
|
||||
|
||||
A Keras tensor is a tensor object from the underlying backend
|
||||
@@ -1375,10 +1346,8 @@ def Input(shape=None, batch_shape=None,
|
||||
it becomes possible to do:
|
||||
`model = Model(input=[a, b], output=c)`
|
||||
|
||||
The added Keras attributes are:
|
||||
._keras_shape: Integer shape tuple propagated
|
||||
via Keras-side shape inference.
|
||||
._keras_history: Last layer applied to the tensor.
|
||||
The added Keras attribute is:
|
||||
`_keras_history`: Last layer applied to the tensor.
|
||||
the entire layer graph is retrievable from that layer,
|
||||
recursively.
|
||||
|
||||
@@ -1424,7 +1393,7 @@ def Input(shape=None, batch_shape=None,
|
||||
name=name, dtype=dtype,
|
||||
sparse=sparse,
|
||||
input_tensor=tensor)
|
||||
# Return tensor including _keras_shape and _keras_history.
|
||||
# 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:
|
||||
@@ -1468,13 +1437,9 @@ class Container(Layer):
|
||||
|
||||
# Class Methods
|
||||
from_config
|
||||
|
||||
# Raises
|
||||
TypeError: if input tensors are not Keras tensors from InputLayer objects
|
||||
"""
|
||||
|
||||
@interfaces.legacy_model_constructor_support
|
||||
def __init__(self, inputs, outputs, name=None):
|
||||
def __init__(self, inputs, outputs, name=None): # pylint: disable=super-init-not-called
|
||||
# Handle `name` argument.
|
||||
if not name:
|
||||
prefix = self.__class__.__name__.lower()
|
||||
@@ -1497,19 +1462,13 @@ class Container(Layer):
|
||||
self.outputs = [outputs]
|
||||
|
||||
# Check for redundancy in inputs.
|
||||
if len(set(self.inputs)) != len(self.inputs):
|
||||
inputs_set = set(self.inputs)
|
||||
if len(inputs_set) != len(self.inputs):
|
||||
raise ValueError('The list of inputs passed to the model '
|
||||
'is redundant. '
|
||||
'All inputs should only appear once.'
|
||||
' Found: ' + str(self.inputs))
|
||||
|
||||
# Check for redundancy in outputs.
|
||||
if len(set(self.outputs)) != len(self.outputs):
|
||||
warnings.warn('The list of outputs passed to the model '
|
||||
'is redundant. '
|
||||
'All outputs should only appear once.'
|
||||
' Found: ' + str(self.outputs))
|
||||
|
||||
# List of initial layers (1 to 1 mapping with self.inputs,
|
||||
# hence the same layer might appear twice)
|
||||
self.input_layers = []
|
||||
@@ -1611,25 +1570,16 @@ class Container(Layer):
|
||||
self._feed_inputs = []
|
||||
self._feed_input_shapes = []
|
||||
for i, layer in enumerate(self.input_layers):
|
||||
# Check that layer is an InputLayer.
|
||||
if not isinstance(layer, InputLayer):
|
||||
raise TypeError(
|
||||
'Input layers to a `Model` must be `InputLayer` objects. '
|
||||
'Received inputs: {}. '
|
||||
'Input {} (0-based) originates '
|
||||
'from layer type `{}`.'.format(inputs,
|
||||
i,
|
||||
layer.__class__.__name__))
|
||||
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(self.inputs[i]._keras_shape)
|
||||
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 = [x._keras_shape for x in self.inputs]
|
||||
self.internal_output_shapes = [x._keras_shape for x in self.outputs]
|
||||
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]
|
||||
|
||||
# Container_nodes: set of nodes included in the graph
|
||||
# (not all nodes included in the layers
|
||||
@@ -1812,9 +1762,7 @@ class Container(Layer):
|
||||
output_tensors=self.outputs,
|
||||
# No container-level masking for now.
|
||||
input_masks=[None for _ in self.inputs],
|
||||
output_masks=[None for _ in self.outputs],
|
||||
input_shapes=[x._keras_shape for x in self.inputs],
|
||||
output_shapes=[x._keras_shape for x in self.outputs])
|
||||
output_masks=[None for _ in self.outputs])
|
||||
self.built = True
|
||||
|
||||
# The following are implemented as property functions:
|
||||
@@ -2075,8 +2023,20 @@ class Container(Layer):
|
||||
_, output_masks, _ = self.run_internal_graph(inputs, masks)
|
||||
return output_masks
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
input_shapes = _to_list(input_shape)
|
||||
def _compute_output_shape(self, input_shape):
|
||||
if isinstance(input_shape, list):
|
||||
input_shapes = []
|
||||
for shape in input_shape:
|
||||
if shape is not None:
|
||||
input_shapes.append(tuple(tensor_shape.TensorShape(shape).as_list()))
|
||||
else:
|
||||
input_shapes.append(None)
|
||||
else:
|
||||
if input_shape is not None:
|
||||
input_shapes = [tuple(tensor_shape.TensorShape(input_shape).as_list())]
|
||||
else:
|
||||
input_shapes = [None]
|
||||
|
||||
if len(input_shapes) != len(self.input_layers):
|
||||
raise ValueError('Invalid input_shape argument ' +
|
||||
str(input_shape) + ': model has ' +
|
||||
@@ -2085,9 +2045,13 @@ class Container(Layer):
|
||||
cache_key = ','.join([str(x) for x in input_shapes])
|
||||
if cache_key in self._output_shape_cache:
|
||||
output_shapes = self._output_shape_cache[cache_key]
|
||||
if isinstance(output_shapes, list) and len(output_shapes) == 1:
|
||||
return output_shapes[0]
|
||||
return output_shapes
|
||||
if isinstance(output_shapes, list):
|
||||
if len(output_shapes) == 1:
|
||||
return tensor_shape.TensorShape(output_shapes[0])
|
||||
else:
|
||||
return [tensor_shape.TensorShape(shape) for shape in output_shapes]
|
||||
else:
|
||||
return tensor_shape.TensorShape(output_shapes)
|
||||
else:
|
||||
# Bad luck, we have to run the graph manually.
|
||||
layers_to_output_shapes = {}
|
||||
@@ -2124,11 +2088,14 @@ class Container(Layer):
|
||||
input_shapes.append(input_shape)
|
||||
|
||||
if len(input_shapes) == 1:
|
||||
output_shape = layer.compute_output_shape(input_shapes[0])
|
||||
output_shape = layer._compute_output_shape(input_shapes[0])
|
||||
else:
|
||||
output_shape = layer.compute_output_shape(input_shapes)
|
||||
output_shape = layer._compute_output_shape(input_shapes)
|
||||
if isinstance(output_shape, list):
|
||||
output_shapes = [tuple(tensor_shape.TensorShape(shape).as_list()) for shape in output_shape]
|
||||
else:
|
||||
output_shapes = [tuple(tensor_shape.TensorShape(output_shape).as_list())]
|
||||
|
||||
output_shapes = _to_list(output_shape)
|
||||
node_index = layer.inbound_nodes.index(node)
|
||||
for j in range(len(output_shapes)):
|
||||
shape_key = layer.name + '_%s_%s' % (node_index, j)
|
||||
@@ -2149,9 +2116,13 @@ class Container(Layer):
|
||||
output_shapes.append(layers_to_output_shapes[key])
|
||||
# Store in cache.
|
||||
self._output_shape_cache[cache_key] = output_shapes
|
||||
if isinstance(output_shapes, list) and len(output_shapes) == 1:
|
||||
return output_shapes[0]
|
||||
return output_shapes
|
||||
if isinstance(output_shapes, list):
|
||||
if len(output_shapes) == 1:
|
||||
return tensor_shape.TensorShape(output_shapes[0])
|
||||
else:
|
||||
return [tensor_shape.TensorShape(shape) for shape in output_shapes]
|
||||
else:
|
||||
return tensor_shape.TensorShape(output_shapes)
|
||||
|
||||
def run_internal_graph(self, inputs, masks=None):
|
||||
"""Computes output tensors for new inputs.
|
||||
@@ -2242,17 +2213,13 @@ class Container(Layer):
|
||||
# (e.g. weight regularizers).
|
||||
self.add_loss(layer.get_losses_for(None), None)
|
||||
|
||||
# Update _keras_shape.
|
||||
if all([hasattr(x, '_keras_shape') for x in computed_tensors]):
|
||||
if len(computed_tensors) == 1:
|
||||
shapes = _to_list(layer.compute_output_shape(computed_tensors[0]._keras_shape))
|
||||
uses_learning_phase = computed_tensors[0]._uses_learning_phase
|
||||
else:
|
||||
shapes = _to_list(layer.compute_output_shape([x._keras_shape for x in computed_tensors]))
|
||||
uses_learning_phase = any([x._uses_learning_phase for x in computed_tensors])
|
||||
for x, s in zip(output_tensors, shapes):
|
||||
x._keras_shape = s
|
||||
x._uses_learning_phase = getattr(x, '_uses_learning_phase', False) or uses_learning_phase
|
||||
# Update `_uses_learning_phase`.
|
||||
if len(computed_tensors) == 1:
|
||||
uses_learning_phase = getattr(computed_tensors[0], '_uses_learning_phase', False)
|
||||
else:
|
||||
uses_learning_phase = any([getattr(x, '_uses_learning_phase', False) for x in computed_tensors])
|
||||
for x in output_tensors:
|
||||
x._uses_learning_phase = getattr(x, '_uses_learning_phase', False) or uses_learning_phase
|
||||
|
||||
# Update tensor_map.
|
||||
for x, y, mask in zip(reference_output_tensors, output_tensors, output_masks):
|
||||
@@ -2264,11 +2231,7 @@ class Container(Layer):
|
||||
for x in self.outputs:
|
||||
assert str(id(x)) in tensor_map, 'Could not compute output ' + str(x)
|
||||
tensor, mask = tensor_map[str(id(x))]
|
||||
if hasattr(tensor, '_keras_shape') and output_shapes is not None:
|
||||
shape = tensor._keras_shape
|
||||
output_shapes.append(shape)
|
||||
else:
|
||||
output_shapes = None
|
||||
output_shapes.append(K.int_shape(x))
|
||||
output_tensors.append(tensor)
|
||||
output_masks.append(mask)
|
||||
|
||||
@@ -2290,7 +2253,7 @@ class Container(Layer):
|
||||
self._output_mask_cache[cache_key] = output_masks
|
||||
|
||||
if output_shapes is not None:
|
||||
input_shapes = [x._keras_shape for x in inputs]
|
||||
input_shapes = [K.int_shape(x) for x in inputs]
|
||||
cache_key = ','.join([str(x) for x in input_shapes])
|
||||
if len(output_shapes) == 1:
|
||||
output_shapes = output_shapes[0]
|
||||
@@ -2414,7 +2377,7 @@ class Container(Layer):
|
||||
layer_name = layer_data['name']
|
||||
|
||||
# Instantiate layer.
|
||||
from ..layers import deserialize as deserialize_layer
|
||||
from ..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
|
||||
@@ -2502,7 +2465,7 @@ class Container(Layer):
|
||||
model = load_model('my_model.h5')
|
||||
```
|
||||
"""
|
||||
from ..models import save_model
|
||||
from ..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):
|
||||
@@ -2580,7 +2543,7 @@ class Container(Layer):
|
||||
# Returns
|
||||
Model config with Keras version information added.
|
||||
"""
|
||||
from .. import __version__ as keras_version
|
||||
from .. import __version__ as keras_version # pylint: disable=g-import-not-at-top
|
||||
|
||||
config = self.get_config()
|
||||
model_config = {
|
||||
@@ -2634,7 +2597,12 @@ class Container(Layer):
|
||||
|
||||
# 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):
|
||||
@@ -2765,17 +2733,14 @@ def _collect_input_shape(input_tensors):
|
||||
input_tensors = _to_list(input_tensors)
|
||||
shapes = []
|
||||
for x in input_tensors:
|
||||
try:
|
||||
shapes.append(K.int_shape(x))
|
||||
except TypeError:
|
||||
shapes.append(None)
|
||||
shapes.append(K.int_shape(x))
|
||||
if len(shapes) == 1:
|
||||
return shapes[0]
|
||||
return shapes
|
||||
|
||||
|
||||
def save_weights_to_hdf5_group(f, layers):
|
||||
from .. import __version__ as keras_version
|
||||
from .. 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')
|
||||
|
||||
+44
-58
@@ -1,28 +1,32 @@
|
||||
"""Keras training and evaluation routines.
|
||||
"""
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import warnings
|
||||
import copy
|
||||
import time
|
||||
import numpy as np
|
||||
import multiprocessing
|
||||
import threading
|
||||
import six
|
||||
import time
|
||||
import warnings
|
||||
|
||||
from .. import backend as K
|
||||
from .. import callbacks as cbks
|
||||
from .. import losses
|
||||
from .. import metrics as metrics_module
|
||||
from .. import optimizers
|
||||
import numpy as np
|
||||
import six
|
||||
from .topology import Container
|
||||
from ..utils.generic_utils import Progbar
|
||||
|
||||
# pylint: disable=g-import-not-at-top
|
||||
try:
|
||||
import queue
|
||||
except ImportError:
|
||||
import Queue as queue
|
||||
|
||||
from .topology import Container
|
||||
from .. import backend as K
|
||||
from .. import optimizers
|
||||
from .. import losses
|
||||
from .. import metrics as metrics_module
|
||||
from ..utils.generic_utils import Progbar
|
||||
from .. import callbacks as cbks
|
||||
from ..legacy import interfaces
|
||||
# pylint: enable=g-import-not-at-top
|
||||
|
||||
|
||||
def _standardize_input_data(data, names, shapes=None,
|
||||
@@ -155,7 +159,7 @@ def _standardize_sample_or_class_weights(x_weight, output_names, weight_type):
|
||||
# Raises
|
||||
ValueError: In case of invalid user-provided argument.
|
||||
"""
|
||||
if x_weight is None or len(x_weight) == 0:
|
||||
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:
|
||||
@@ -241,7 +245,7 @@ def _check_array_lengths(inputs, targets, weights):
|
||||
|
||||
|
||||
def _check_loss_and_target_compatibility(targets, loss_fns, output_shapes):
|
||||
"""Does validation on the compatibility of targets and loss functions.
|
||||
"""Does validation on the compatiblity of targets and loss functions.
|
||||
|
||||
This helps prevent users from using loss functions incorrectly.
|
||||
|
||||
@@ -435,7 +439,6 @@ def _weighted_masked_objective(fn):
|
||||
# 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
|
||||
@@ -484,7 +487,6 @@ def _masked_objective(fn):
|
||||
# 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
|
||||
@@ -708,13 +710,12 @@ class Model(Container):
|
||||
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.
|
||||
**kwargs: when using the Theano backend, these arguments
|
||||
are passed into K.function. When using the Tensorflow backend,
|
||||
these arguments are passed into `tf.Session.run`.
|
||||
**kwargs: Additional arguments passed to `tf.Session.run`.
|
||||
|
||||
# Raises
|
||||
ValueError: In case of invalid arguments for
|
||||
`optimizer`, `loss`, `metrics` or `sample_weight_mode`.
|
||||
RuntimeError: If the model has no loss to optimize.
|
||||
"""
|
||||
loss = loss or {}
|
||||
self.optimizer = optimizers.get(optimizer)
|
||||
@@ -984,27 +985,25 @@ class Model(Container):
|
||||
# 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
|
||||
self._function_kwargs = kwargs
|
||||
|
||||
# Collected trainable weights and sort them deterministically.
|
||||
trainable_weights = self.trainable_weights
|
||||
# Sort weights by name.
|
||||
if trainable_weights:
|
||||
if K.backend() == 'theano':
|
||||
trainable_weights.sort(key=lambda x: x.name if x.name else x.auto_name)
|
||||
else:
|
||||
trainable_weights.sort(key=lambda x: x.name)
|
||||
trainable_weights.sort(key=lambda x: x.name)
|
||||
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
|
||||
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()]
|
||||
|
||||
@@ -1024,7 +1023,9 @@ class Model(Container):
|
||||
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
|
||||
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.
|
||||
@@ -1038,6 +1039,7 @@ class Model(Container):
|
||||
def _make_predict_function(self):
|
||||
if not hasattr(self, 'predict_function'):
|
||||
self.predict_function = None
|
||||
self._function_kwargs = {}
|
||||
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()]
|
||||
@@ -1045,12 +1047,11 @@ class Model(Container):
|
||||
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)
|
||||
**self._function_kwargs)
|
||||
|
||||
def _fit_loop(self, f, ins, out_labels=None, batch_size=32,
|
||||
epochs=100, verbose=1, callbacks=None,
|
||||
@@ -1358,8 +1359,7 @@ class Model(Container):
|
||||
shuffle=True,
|
||||
class_weight=None,
|
||||
sample_weight=None,
|
||||
initial_epoch=0,
|
||||
**kwargs):
|
||||
initial_epoch=0):
|
||||
"""Trains the model for a fixed number of epochs (iterations on a dataset).
|
||||
|
||||
# Arguments
|
||||
@@ -1418,14 +1418,6 @@ class Model(Container):
|
||||
ValueError: In case of mismatch between the provided input data
|
||||
and what the model expects.
|
||||
"""
|
||||
# Legacy support
|
||||
if 'nb_epoch' in kwargs:
|
||||
warnings.warn('The `nb_epoch` argument in `fit` '
|
||||
'has been renamed `epochs`.', stacklevel=2)
|
||||
epochs = kwargs.pop('nb_epoch')
|
||||
if kwargs:
|
||||
raise TypeError('Unrecognized keyword arguments: ' + str(kwargs))
|
||||
|
||||
# Validate user data.
|
||||
x, y, sample_weights = self._standardize_user_data(
|
||||
x, y,
|
||||
@@ -1437,10 +1429,10 @@ class Model(Container):
|
||||
if validation_data:
|
||||
do_validation = True
|
||||
if len(validation_data) == 2:
|
||||
val_x, val_y = validation_data
|
||||
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
|
||||
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) '
|
||||
@@ -1462,10 +1454,7 @@ class Model(Container):
|
||||
|
||||
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))
|
||||
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 = (
|
||||
@@ -1707,7 +1696,6 @@ class Model(Container):
|
||||
return outputs[0]
|
||||
return outputs
|
||||
|
||||
@interfaces.legacy_generator_methods_support
|
||||
def fit_generator(self, generator,
|
||||
steps_per_epoch,
|
||||
epochs=1,
|
||||
@@ -1834,10 +1822,10 @@ class Model(Container):
|
||||
|
||||
if do_validation and not val_gen:
|
||||
if len(validation_data) == 2:
|
||||
val_x, val_y = validation_data
|
||||
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
|
||||
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)` '
|
||||
@@ -1876,10 +1864,10 @@ class Model(Container):
|
||||
'or `(x, y)`. Found: ' +
|
||||
str(generator_output))
|
||||
if len(generator_output) == 2:
|
||||
x, y = generator_output
|
||||
x, y = generator_output # pylint: disable=unpacking-non-sequence
|
||||
sample_weight = None
|
||||
elif len(generator_output) == 3:
|
||||
x, y, sample_weight = generator_output
|
||||
x, y, sample_weight = generator_output # pylint: disable=unpacking-non-sequence
|
||||
else:
|
||||
raise ValueError('output of generator should be '
|
||||
'a tuple `(x, y, sample_weight)` '
|
||||
@@ -1948,7 +1936,6 @@ class Model(Container):
|
||||
callbacks.on_train_end()
|
||||
return self.history
|
||||
|
||||
@interfaces.legacy_generator_methods_support
|
||||
def evaluate_generator(self, generator, steps,
|
||||
max_q_size=10, workers=1, pickle_safe=False):
|
||||
"""Evaluates the model on a data generator.
|
||||
@@ -2009,10 +1996,10 @@ class Model(Container):
|
||||
'or (x, y). Found: ' +
|
||||
str(generator_output))
|
||||
if len(generator_output) == 2:
|
||||
x, y = generator_output
|
||||
x, y = generator_output # pylint: disable=unpacking-non-sequence
|
||||
sample_weight = None
|
||||
elif len(generator_output) == 3:
|
||||
x, y, sample_weight = generator_output
|
||||
x, y, sample_weight = generator_output # pylint: disable=unpacking-non-sequence
|
||||
else:
|
||||
raise ValueError('output of generator should be a tuple '
|
||||
'(x, y, sample_weight) '
|
||||
@@ -2045,7 +2032,6 @@ class Model(Container):
|
||||
weights=batch_sizes))
|
||||
return averages
|
||||
|
||||
@interfaces.legacy_generator_methods_support
|
||||
def predict_generator(self, generator, steps,
|
||||
max_q_size=10, workers=1,
|
||||
pickle_safe=False, verbose=0):
|
||||
@@ -2104,9 +2090,9 @@ class Model(Container):
|
||||
# Compatibility with the generators
|
||||
# used for training.
|
||||
if len(generator_output) == 2:
|
||||
x, _ = generator_output
|
||||
x, _ = generator_output # pylint: disable=unpacking-non-sequence
|
||||
elif len(generator_output) == 3:
|
||||
x, _, _ = generator_output
|
||||
x, _, _ = generator_output # pylint: disable=unpacking-non-sequence
|
||||
else:
|
||||
raise ValueError('output of generator should be '
|
||||
'a tuple `(x, y, sample_weight)` '
|
||||
|
||||
+17
-6
@@ -1,9 +1,17 @@
|
||||
"""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 math
|
||||
|
||||
from . import backend as K
|
||||
import numpy as np
|
||||
import six
|
||||
from . import backend as K
|
||||
from .utils.generic_utils import serialize_keras_object
|
||||
from tensorflow.python.framework import tensor_shape
|
||||
from .utils.generic_utils import deserialize_keras_object
|
||||
from .utils.generic_utils import serialize_keras_object
|
||||
|
||||
|
||||
class Initializer(object):
|
||||
@@ -199,11 +207,11 @@ class VarianceScaling(Initializer):
|
||||
else:
|
||||
scale /= max(1., float(fan_in + fan_out) / 2)
|
||||
if self.distribution == 'normal':
|
||||
stddev = np.sqrt(scale)
|
||||
stddev = math.sqrt(scale)
|
||||
return K.truncated_normal(shape, 0., stddev,
|
||||
dtype=dtype, seed=self.seed)
|
||||
else:
|
||||
limit = np.sqrt(3. * scale)
|
||||
limit = math.sqrt(3. * scale)
|
||||
return K.random_uniform(shape, -limit, limit,
|
||||
dtype=dtype, seed=self.seed)
|
||||
|
||||
@@ -395,6 +403,7 @@ def he_uniform(seed=None):
|
||||
|
||||
# Compatibility aliases
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
zero = zeros = Zeros
|
||||
one = ones = Ones
|
||||
constant = Constant
|
||||
@@ -403,6 +412,7 @@ normal = random_normal = RandomNormal
|
||||
truncated_normal = TruncatedNormal
|
||||
identity = Identity
|
||||
orthogonal = Orthogonal
|
||||
# pylint: enable=invalid-name
|
||||
|
||||
# Utility functions
|
||||
|
||||
@@ -423,6 +433,7 @@ def _compute_fans(shape, data_format='channels_last'):
|
||||
# Raises
|
||||
ValueError: in case of invalid `data_format` argument.
|
||||
"""
|
||||
shape = tensor_shape.TensorShape(shape).as_list()
|
||||
if len(shape) == 2:
|
||||
fan_in = shape[0]
|
||||
fan_out = shape[1]
|
||||
@@ -442,8 +453,8 @@ def _compute_fans(shape, data_format='channels_last'):
|
||||
raise ValueError('Invalid data_format: ' + data_format)
|
||||
else:
|
||||
# No specific assumptions.
|
||||
fan_in = np.sqrt(np.prod(shape))
|
||||
fan_out = np.sqrt(np.prod(shape))
|
||||
fan_in = math.sqrt(np.prod(shape))
|
||||
fan_out = math.sqrt(np.prod(shape))
|
||||
return fan_in, fan_out
|
||||
|
||||
|
||||
|
||||
+17
-45
@@ -1,54 +1,26 @@
|
||||
"""Keras layers module.
|
||||
"""
|
||||
# pylint: disable=wildcard-import
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from ..utils.generic_utils import deserialize_keras_object
|
||||
from ..engine import Layer
|
||||
from .advanced_activations import *
|
||||
from .convolutional import *
|
||||
from .convolutional_recurrent import *
|
||||
from .core import *
|
||||
from .embeddings import *
|
||||
from ..engine import Input
|
||||
from ..engine import InputLayer
|
||||
from ..engine import InputSpec
|
||||
from .merge import *
|
||||
from .core import *
|
||||
from .convolutional import *
|
||||
from .pooling import *
|
||||
from ..engine import Layer
|
||||
from .local import *
|
||||
from .recurrent import *
|
||||
from .normalization import *
|
||||
from .embeddings import *
|
||||
from .merge import *
|
||||
from .noise import *
|
||||
from .advanced_activations import *
|
||||
from .normalization import *
|
||||
from .pooling import *
|
||||
from .recurrent import *
|
||||
from .serialization import deserialize
|
||||
from .serialization import serialize
|
||||
from .wrappers import *
|
||||
from .convolutional_recurrent import *
|
||||
from ..legacy.layers import *
|
||||
|
||||
|
||||
def serialize(layer):
|
||||
"""Serialize a layer.
|
||||
|
||||
# Arguments
|
||||
layer: a Layer object.
|
||||
|
||||
# Returns
|
||||
dictionary with config.
|
||||
"""
|
||||
return {'class_name': layer.__class__.__name__,
|
||||
'config': layer.get_config()}
|
||||
|
||||
|
||||
def deserialize(config, custom_objects=None):
|
||||
"""Instantiate 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 .. import models
|
||||
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')
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
"""Layers that act as activation functions.
|
||||
"""
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from .. import backend as K
|
||||
from .. import constraints
|
||||
from .. import initializers
|
||||
from .. import regularizers
|
||||
from .. import constraints
|
||||
from ..engine import Layer
|
||||
from ..engine import InputSpec
|
||||
from .. import backend as K
|
||||
from ..legacy import interfaces
|
||||
from ..engine import Layer
|
||||
from tensorflow.python.framework import tensor_shape
|
||||
|
||||
|
||||
class LeakyReLU(Layer):
|
||||
@@ -28,8 +32,6 @@ class LeakyReLU(Layer):
|
||||
# Arguments
|
||||
alpha: float >= 0. Negative slope coefficient.
|
||||
|
||||
# References
|
||||
- [Rectifier Nonlinearities Improve Neural Network Acoustic Models](https://web.stanford.edu/~awni/papers/relu_hybrid_icml2013_final.pdf)
|
||||
"""
|
||||
|
||||
def __init__(self, alpha=0.3, **kwargs):
|
||||
@@ -75,11 +77,8 @@ class PReLU(Layer):
|
||||
so that each filter only has one set of parameters,
|
||||
set `shared_axes=[1, 2]`.
|
||||
|
||||
# References
|
||||
- [Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification](https://arxiv.org/abs/1502.01852)
|
||||
"""
|
||||
|
||||
@interfaces.legacy_prelu_support
|
||||
def __init__(self, alpha_initializer='zeros',
|
||||
alpha_regularizer=None,
|
||||
alpha_constraint=None,
|
||||
@@ -98,7 +97,8 @@ class PReLU(Layer):
|
||||
self.shared_axes = list(shared_axes)
|
||||
|
||||
def build(self, input_shape):
|
||||
param_shape = list(input_shape[1:])
|
||||
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:
|
||||
@@ -156,8 +156,6 @@ class ELU(Layer):
|
||||
# Arguments
|
||||
alpha: scale for the negative factor.
|
||||
|
||||
# References
|
||||
- [Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs)](https://arxiv.org/abs/1511.07289v1)
|
||||
"""
|
||||
|
||||
def __init__(self, alpha=1.0, **kwargs):
|
||||
@@ -192,8 +190,6 @@ class ThresholdedReLU(Layer):
|
||||
# Arguments
|
||||
theta: float >= 0. Threshold location of activation.
|
||||
|
||||
# References
|
||||
- [Zero-Bias Autoencoders and the Benefits of Co-Adapting Features](http://arxiv.org/abs/1402.3337)
|
||||
"""
|
||||
|
||||
def __init__(self, theta=1.0, **kwargs):
|
||||
@@ -202,7 +198,7 @@ class ThresholdedReLU(Layer):
|
||||
self.theta = K.cast_to_floatx(theta)
|
||||
|
||||
def call(self, inputs, mask=None):
|
||||
return inputs * K.cast(K.greater(inputs, self.theta), K.floatx())
|
||||
return inputs * K.cast(inputs > self.theta, K.floatx())
|
||||
|
||||
def get_config(self):
|
||||
config = {'theta': float(self.theta)}
|
||||
|
||||
+242
-307
@@ -1,26 +1,30 @@
|
||||
"""Keras convolution layers and image transformation layers.
|
||||
"""
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from .. import backend as K
|
||||
from .. import activations
|
||||
from .. import backend as K
|
||||
from .. import constraints
|
||||
from .. import initializers
|
||||
from .. import regularizers
|
||||
from .. import constraints
|
||||
from ..engine import Layer
|
||||
from ..engine import InputSpec
|
||||
from ..engine import Layer
|
||||
from ..utils import conv_utils
|
||||
from ..legacy import interfaces
|
||||
|
||||
# imports for backwards namespace compatibility
|
||||
# pylint: disable=unused-import
|
||||
from .pooling import AveragePooling1D
|
||||
from .pooling import AveragePooling2D
|
||||
from .pooling import AveragePooling3D
|
||||
from .pooling import MaxPooling1D
|
||||
from .pooling import MaxPooling2D
|
||||
from .pooling import MaxPooling3D
|
||||
# pylint: enable=unused-import
|
||||
|
||||
from ..legacy.layers import AtrousConvolution1D
|
||||
from ..legacy.layers import AtrousConvolution2D
|
||||
from tensorflow.python.framework import tensor_shape
|
||||
|
||||
|
||||
class _Conv(Layer):
|
||||
@@ -57,27 +61,19 @@ class _Conv(Layer):
|
||||
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
|
||||
(see [activations](../activations.md)).
|
||||
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
|
||||
(see [initializers](../initializers.md)).
|
||||
bias_initializer: Initializer for the bias vector
|
||||
(see [initializers](../initializers.md)).
|
||||
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
|
||||
(see [regularizer](../regularizers.md)).
|
||||
bias_regularizer: Regularizer function applied to the bias vector
|
||||
(see [regularizer](../regularizers.md)).
|
||||
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").
|
||||
(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)).
|
||||
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.
|
||||
"""
|
||||
|
||||
def __init__(self, rank,
|
||||
@@ -117,6 +113,7 @@ class _Conv(Layer):
|
||||
self.input_spec = InputSpec(ndim=self.rank + 2)
|
||||
|
||||
def build(self, input_shape):
|
||||
input_shape = tensor_shape.TensorShape(input_shape).as_list()
|
||||
if self.data_format == 'channels_first':
|
||||
channel_axis = 1
|
||||
else:
|
||||
@@ -181,7 +178,8 @@ class _Conv(Layer):
|
||||
return self.activation(outputs)
|
||||
return outputs
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
def _compute_output_shape(self, input_shape):
|
||||
input_shape = tensor_shape.TensorShape(input_shape).as_list()
|
||||
if self.data_format == 'channels_last':
|
||||
space = input_shape[1:-1]
|
||||
new_space = []
|
||||
@@ -193,8 +191,8 @@ class _Conv(Layer):
|
||||
stride=self.strides[i],
|
||||
dilation=self.dilation_rate[i])
|
||||
new_space.append(new_dim)
|
||||
return (input_shape[0],) + tuple(new_space) + (self.filters,)
|
||||
if self.data_format == 'channels_first':
|
||||
return tensor_shape.TensorShape([input_shape[0]] + new_space + [self.filters])
|
||||
else:
|
||||
space = input_shape[2:]
|
||||
new_space = []
|
||||
for i in range(len(space)):
|
||||
@@ -205,7 +203,7 @@ class _Conv(Layer):
|
||||
stride=self.strides[i],
|
||||
dilation=self.dilation_rate[i])
|
||||
new_space.append(new_dim)
|
||||
return (input_shape[0], self.filters) + tuple(new_space)
|
||||
return tensor_shape.TensorShape([input_shape[0], self.filters] + new_space)
|
||||
|
||||
def get_config(self):
|
||||
config = {
|
||||
@@ -256,9 +254,6 @@ class Conv1D(_Conv):
|
||||
Specifying any stride value != 1 is incompatible with specifying
|
||||
any `dilation_rate` value != 1.
|
||||
padding: One of `"valid"`, `"causal"` or `"same"` (case-insensitive).
|
||||
`"valid"` means "no padding".
|
||||
`"same"` results in padding the input such that
|
||||
the output has the same length as the original input.
|
||||
`"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.
|
||||
@@ -267,27 +262,19 @@ class Conv1D(_Conv):
|
||||
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
|
||||
(see [activations](../activations.md)).
|
||||
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
|
||||
(see [initializers](../initializers.md)).
|
||||
bias_initializer: Initializer for the bias vector
|
||||
(see [initializers](../initializers.md)).
|
||||
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
|
||||
(see [regularizer](../regularizers.md)).
|
||||
bias_regularizer: Regularizer function applied to the bias vector
|
||||
(see [regularizer](../regularizers.md)).
|
||||
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").
|
||||
(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)).
|
||||
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)`
|
||||
@@ -297,7 +284,6 @@ class Conv1D(_Conv):
|
||||
`steps` value might have changed due to padding or strides.
|
||||
"""
|
||||
|
||||
@interfaces.legacy_conv1d_support
|
||||
def __init__(self, filters,
|
||||
kernel_size,
|
||||
strides=1,
|
||||
@@ -385,27 +371,19 @@ class Conv2D(_Conv):
|
||||
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)).
|
||||
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
|
||||
(see [initializers](../initializers.md)).
|
||||
bias_initializer: Initializer for the bias vector
|
||||
(see [initializers](../initializers.md)).
|
||||
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
|
||||
(see [regularizer](../regularizers.md)).
|
||||
bias_regularizer: Regularizer function applied to the bias vector
|
||||
(see [regularizer](../regularizers.md)).
|
||||
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").
|
||||
(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)).
|
||||
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:
|
||||
@@ -421,7 +399,6 @@ class Conv2D(_Conv):
|
||||
`rows` and `cols` values might have changed due to padding.
|
||||
"""
|
||||
|
||||
@interfaces.legacy_conv2d_support
|
||||
def __init__(self, filters,
|
||||
kernel_size,
|
||||
strides=(1, 1),
|
||||
@@ -510,27 +487,19 @@ class Conv3D(_Conv):
|
||||
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)).
|
||||
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
|
||||
(see [initializers](../initializers.md)).
|
||||
bias_initializer: Initializer for the bias vector
|
||||
(see [initializers](../initializers.md)).
|
||||
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
|
||||
(see [regularizer](../regularizers.md)).
|
||||
bias_regularizer: Regularizer function applied to the bias vector
|
||||
(see [regularizer](../regularizers.md)).
|
||||
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").
|
||||
(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)).
|
||||
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:
|
||||
@@ -546,7 +515,6 @@ class Conv3D(_Conv):
|
||||
`new_conv_dim1`, `new_conv_dim2` and `new_conv_dim3` values might have changed due to padding.
|
||||
"""
|
||||
|
||||
@interfaces.legacy_conv3d_support
|
||||
def __init__(self, filters,
|
||||
kernel_size,
|
||||
strides=(1, 1, 1),
|
||||
@@ -635,27 +603,19 @@ class Conv2DTranspose(Conv2D):
|
||||
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)).
|
||||
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
|
||||
(see [initializers](../initializers.md)).
|
||||
bias_initializer: Initializer for the bias vector
|
||||
(see [initializers](../initializers.md)).
|
||||
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
|
||||
(see [regularizer](../regularizers.md)).
|
||||
bias_regularizer: Regularizer function applied to the bias vector
|
||||
(see [regularizer](../regularizers.md)).
|
||||
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").
|
||||
(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)).
|
||||
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:
|
||||
@@ -675,7 +635,6 @@ class Conv2DTranspose(Conv2D):
|
||||
- [Deconvolutional Networks](http://www.matthewzeiler.com/pubs/cvpr2010/cvpr2010.pdf)
|
||||
"""
|
||||
|
||||
@interfaces.legacy_deconv2d_support
|
||||
def __init__(self, filters,
|
||||
kernel_size,
|
||||
strides=(1, 1),
|
||||
@@ -710,6 +669,7 @@ class Conv2DTranspose(Conv2D):
|
||||
self.input_spec = InputSpec(ndim=4)
|
||||
|
||||
def build(self, input_shape):
|
||||
input_shape = tensor_shape.TensorShape(input_shape).as_list()
|
||||
if len(input_shape) != 4:
|
||||
raise ValueError('Inputs should have rank ' +
|
||||
str(4) +
|
||||
@@ -783,7 +743,8 @@ class Conv2DTranspose(Conv2D):
|
||||
return self.activation(outputs)
|
||||
return outputs
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
def _compute_output_shape(self, input_shape):
|
||||
input_shape = tensor_shape.TensorShape(input_shape).as_list()
|
||||
output_shape = list(input_shape)
|
||||
if self.data_format == 'channels_first':
|
||||
c_axis, h_axis, w_axis = 1, 2, 3
|
||||
@@ -798,7 +759,7 @@ class Conv2DTranspose(Conv2D):
|
||||
output_shape[h_axis], stride_h, kernel_h, self.padding)
|
||||
output_shape[w_axis] = conv_utils.deconv_length(
|
||||
output_shape[w_axis], stride_w, kernel_w, self.padding)
|
||||
return tuple(output_shape)
|
||||
return tensor_shape.TensorShape(output_shape)
|
||||
|
||||
def get_config(self):
|
||||
config = super(Conv2DTranspose, self).get_config()
|
||||
@@ -848,36 +809,25 @@ class SeparableConv2D(Conv2D):
|
||||
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
|
||||
(see [activations](../activations.md)).
|
||||
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
|
||||
(see [initializers](../initializers.md)).
|
||||
pointwise_initializer: Initializer for the pointwise kernel matrix
|
||||
(see [initializers](../initializers.md)).
|
||||
bias_initializer: Initializer for the bias vector
|
||||
(see [initializers](../initializers.md)).
|
||||
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
|
||||
(see [regularizer](../regularizers.md)).
|
||||
the depthwise kernel matrix.
|
||||
pointwise_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)).
|
||||
the depthwise kernel matrix.
|
||||
bias_regularizer: Regularizer function applied to the bias vector.
|
||||
activity_regularizer: Regularizer function applied to
|
||||
the output of the layer (its "activation").
|
||||
(see [regularizer](../regularizers.md)).
|
||||
the output of the layer (its "activation")..
|
||||
depthwise_constraint: Constraint function applied to
|
||||
the depthwise kernel matrix
|
||||
(see [constraints](../constraints.md)).
|
||||
the depthwise kernel matrix.
|
||||
pointwise_constraint: Constraint function applied to
|
||||
the pointwise kernel matrix
|
||||
(see [constraints](../constraints.md)).
|
||||
bias_constraint: Constraint function applied to the bias vector
|
||||
(see [constraints](../constraints.md)).
|
||||
the pointwise kernel matrix.
|
||||
bias_constraint: Constraint function applied to the bias vector.
|
||||
|
||||
# Input shape
|
||||
4D tensor with shape:
|
||||
@@ -893,7 +843,6 @@ class SeparableConv2D(Conv2D):
|
||||
`rows` and `cols` values might have changed due to padding.
|
||||
"""
|
||||
|
||||
@interfaces.legacy_separable_conv2d_support
|
||||
def __init__(self, filters,
|
||||
kernel_size,
|
||||
strides=(1, 1),
|
||||
@@ -934,6 +883,7 @@ class SeparableConv2D(Conv2D):
|
||||
self.pointwise_constraint = constraints.get(pointwise_constraint)
|
||||
|
||||
def build(self, input_shape):
|
||||
input_shape = tensor_shape.TensorShape(input_shape).as_list()
|
||||
if len(input_shape) < 4:
|
||||
raise ValueError('Inputs to `SeparableConv2D` should have rank 4. '
|
||||
'Received input shape:', str(input_shape))
|
||||
@@ -998,11 +948,12 @@ class SeparableConv2D(Conv2D):
|
||||
return self.activation(outputs)
|
||||
return outputs
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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':
|
||||
else:
|
||||
rows = input_shape[1]
|
||||
cols = input_shape[2]
|
||||
|
||||
@@ -1013,9 +964,9 @@ class SeparableConv2D(Conv2D):
|
||||
self.padding,
|
||||
self.strides[1])
|
||||
if self.data_format == 'channels_first':
|
||||
return (input_shape[0], self.filters, rows, cols)
|
||||
elif self.data_format == 'channels_last':
|
||||
return (input_shape[0], rows, cols, self.filters)
|
||||
return tensor_shape.TensorShape([input_shape[0], self.filters, rows, cols])
|
||||
else:
|
||||
return tensor_shape.TensorShape([input_shape[0], rows, cols, self.filters])
|
||||
|
||||
def get_config(self):
|
||||
config = super(SeparableConv2D, self).get_config()
|
||||
@@ -1047,15 +998,15 @@ class UpSampling1D(Layer):
|
||||
3D tensor with shape: `(batch, upsampled_steps, features)`.
|
||||
"""
|
||||
|
||||
@interfaces.legacy_upsampling1d_support
|
||||
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):
|
||||
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 (input_shape[0], size, input_shape[2])
|
||||
return tensor_shape.TensorShape([input_shape[0], size, input_shape[2]])
|
||||
|
||||
def call(self, inputs):
|
||||
output = K.repeat_elements(inputs, self.size, axis=1)
|
||||
@@ -1102,28 +1053,28 @@ class UpSampling2D(Layer):
|
||||
`(batch, channels, upsampled_rows, upsampled_cols)`
|
||||
"""
|
||||
|
||||
@interfaces.legacy_upsampling2d_support
|
||||
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):
|
||||
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 (input_shape[0],
|
||||
input_shape[1],
|
||||
height,
|
||||
width)
|
||||
elif self.data_format == 'channels_last':
|
||||
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 (input_shape[0],
|
||||
height,
|
||||
width,
|
||||
input_shape[3])
|
||||
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],
|
||||
@@ -1171,32 +1122,32 @@ class UpSampling3D(Layer):
|
||||
`(batch, channels, upsampled_dim1, upsampled_dim2, upsampled_dim3)`
|
||||
"""
|
||||
|
||||
@interfaces.legacy_upsampling3d_support
|
||||
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):
|
||||
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 (input_shape[0],
|
||||
input_shape[1],
|
||||
dim1,
|
||||
dim2,
|
||||
dim3)
|
||||
elif self.data_format == 'channels_last':
|
||||
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 (input_shape[0],
|
||||
dim1,
|
||||
dim2,
|
||||
dim3,
|
||||
input_shape[4])
|
||||
return tensor_shape.TensorShape([input_shape[0],
|
||||
dim1,
|
||||
dim2,
|
||||
dim3,
|
||||
input_shape[4]])
|
||||
|
||||
def call(self, inputs):
|
||||
return K.resize_volumes(inputs,
|
||||
@@ -1234,14 +1185,14 @@ class ZeroPadding1D(Layer):
|
||||
self.padding = conv_utils.normalize_tuple(padding, 2, 'padding')
|
||||
self.input_spec = InputSpec(ndim=3)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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 (input_shape[0],
|
||||
length,
|
||||
input_shape[2])
|
||||
return tensor_shape.TensorShape([input_shape[0],
|
||||
length,
|
||||
input_shape[2]])
|
||||
|
||||
def call(self, inputs):
|
||||
return K.temporal_padding(inputs, padding=self.padding)
|
||||
@@ -1255,7 +1206,7 @@ class ZeroPadding1D(Layer):
|
||||
class ZeroPadding2D(Layer):
|
||||
"""Zero-padding layer for 2D input (e.g. picture).
|
||||
|
||||
This layer can add rows and columns of zeros
|
||||
This layer can add rows and columns or zeros
|
||||
at the top, bottom, left and right side of an image tensor.
|
||||
|
||||
# Arguments
|
||||
@@ -1295,7 +1246,6 @@ class ZeroPadding2D(Layer):
|
||||
`(batch, channels, padded_rows, padded_cols)`
|
||||
"""
|
||||
|
||||
@interfaces.legacy_zeropadding2d_support
|
||||
def __init__(self,
|
||||
padding=(1, 1),
|
||||
data_format=None,
|
||||
@@ -1322,7 +1272,8 @@ class ZeroPadding2D(Layer):
|
||||
'Found: ' + str(padding))
|
||||
self.input_spec = InputSpec(ndim=4)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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]
|
||||
@@ -1332,10 +1283,10 @@ class ZeroPadding2D(Layer):
|
||||
cols = input_shape[3] + self.padding[1][0] + self.padding[1][1]
|
||||
else:
|
||||
cols = None
|
||||
return (input_shape[0],
|
||||
input_shape[1],
|
||||
rows,
|
||||
cols)
|
||||
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]
|
||||
@@ -1345,10 +1296,10 @@ class ZeroPadding2D(Layer):
|
||||
cols = input_shape[2] + self.padding[1][0] + self.padding[1][1]
|
||||
else:
|
||||
cols = None
|
||||
return (input_shape[0],
|
||||
rows,
|
||||
cols,
|
||||
input_shape[3])
|
||||
return tensor_shape.TensorShape([input_shape[0],
|
||||
rows,
|
||||
cols,
|
||||
input_shape[3]])
|
||||
|
||||
def call(self, inputs):
|
||||
return K.spatial_2d_padding(inputs,
|
||||
@@ -1402,7 +1353,6 @@ class ZeroPadding3D(Layer):
|
||||
`(batch, depth, first_padded_axis, second_padded_axis, third_axis_to_pad)`
|
||||
"""
|
||||
|
||||
@interfaces.legacy_zeropadding3d_support
|
||||
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)
|
||||
@@ -1430,7 +1380,8 @@ class ZeroPadding3D(Layer):
|
||||
'Found: ' + str(padding))
|
||||
self.input_spec = InputSpec(ndim=5)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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] + self.padding[0][0] + self.padding[0][1]
|
||||
@@ -1444,11 +1395,11 @@ class ZeroPadding3D(Layer):
|
||||
dim3 = input_shape[4] + self.padding[2][0] + self.padding[2][1]
|
||||
else:
|
||||
dim3 = None
|
||||
return (input_shape[0],
|
||||
input_shape[1],
|
||||
dim1,
|
||||
dim2,
|
||||
dim3)
|
||||
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.padding[0][0] + self.padding[0][1]
|
||||
@@ -1462,11 +1413,11 @@ class ZeroPadding3D(Layer):
|
||||
dim3 = input_shape[3] + self.padding[2][0] + self.padding[2][1]
|
||||
else:
|
||||
dim3 = None
|
||||
return (input_shape[0],
|
||||
dim1,
|
||||
dim2,
|
||||
dim3,
|
||||
input_shape[4])
|
||||
return tensor_shape.TensorShape([input_shape[0],
|
||||
dim1,
|
||||
dim2,
|
||||
dim3,
|
||||
input_shape[4]])
|
||||
|
||||
def call(self, inputs):
|
||||
return K.spatial_3d_padding(inputs,
|
||||
@@ -1504,14 +1455,15 @@ class Cropping1D(Layer):
|
||||
self.cropping = conv_utils.normalize_tuple(cropping, 2, 'cropping')
|
||||
self.input_spec = InputSpec(ndim=3)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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 (input_shape[0],
|
||||
length,
|
||||
input_shape[2])
|
||||
return tensor_shape.TensorShape([input_shape[0],
|
||||
length,
|
||||
input_shape[2]])
|
||||
|
||||
def call(self, inputs):
|
||||
if self.cropping[1] == 0:
|
||||
@@ -1580,7 +1532,6 @@ class Cropping2D(Layer):
|
||||
```
|
||||
"""
|
||||
|
||||
@interfaces.legacy_cropping2d_support
|
||||
def __init__(self, cropping=((0, 0), (0, 0)),
|
||||
data_format=None, **kwargs):
|
||||
super(Cropping2D, self).__init__(**kwargs)
|
||||
@@ -1607,19 +1558,27 @@ class Cropping2D(Layer):
|
||||
'Found: ' + str(cropping))
|
||||
self.input_spec = InputSpec(ndim=4)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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 (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)
|
||||
elif self.data_format == 'channels_last':
|
||||
return (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])
|
||||
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[:,
|
||||
@@ -1640,7 +1599,7 @@ class Cropping2D(Layer):
|
||||
:,
|
||||
self.cropping[0][0]: -self.cropping[0][1],
|
||||
self.cropping[1][0]: -self.cropping[1][1]]
|
||||
elif self.data_format == 'channels_last':
|
||||
else:
|
||||
if self.cropping[0][1] == self.cropping[1][1] == 0:
|
||||
return inputs[:,
|
||||
self.cropping[0][0]:,
|
||||
@@ -1660,6 +1619,7 @@ class Cropping2D(Layer):
|
||||
self.cropping[0][0]: -self.cropping[0][1],
|
||||
self.cropping[1][0]: -self.cropping[1][1],
|
||||
:]
|
||||
# pylint: enable=invalid-unary-operand-type
|
||||
|
||||
def get_config(self):
|
||||
config = {'cropping': self.cropping,
|
||||
@@ -1708,7 +1668,6 @@ class Cropping3D(Layer):
|
||||
`(batch, depth, first_cropped_axis, second_cropped_axis, third_cropped_axis)`
|
||||
"""
|
||||
|
||||
@interfaces.legacy_cropping3d_support
|
||||
def __init__(self, cropping=((1, 1), (1, 1), (1, 1)),
|
||||
data_format=None, **kwargs):
|
||||
super(Cropping3D, self).__init__(**kwargs)
|
||||
@@ -1739,7 +1698,9 @@ class Cropping3D(Layer):
|
||||
'Found: ' + str(cropping))
|
||||
self.input_spec = InputSpec(ndim=5)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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]
|
||||
@@ -1753,11 +1714,11 @@ class Cropping3D(Layer):
|
||||
dim3 = input_shape[4] - self.cropping[2][0] - self.cropping[2][1]
|
||||
else:
|
||||
dim3 = None
|
||||
return (input_shape[0],
|
||||
input_shape[1],
|
||||
dim1,
|
||||
dim2,
|
||||
dim3)
|
||||
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]
|
||||
@@ -1771,110 +1732,88 @@ class Cropping3D(Layer):
|
||||
dim3 = input_shape[3] - self.cropping[2][0] - self.cropping[2][1]
|
||||
else:
|
||||
dim3 = None
|
||||
return (input_shape[0],
|
||||
dim1,
|
||||
dim2,
|
||||
dim3,
|
||||
input_shape[4])
|
||||
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]:]
|
||||
if self.cropping[0][1] == 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[1][1],
|
||||
self.cropping[2][0]: -self.cropping[2][1]]
|
||||
|
||||
elif self.data_format == 'channels_last':
|
||||
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],
|
||||
:]
|
||||
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]:-self.cropping[2][1], :]
|
||||
# pylint: enable=invalid-unary-operand-type
|
||||
|
||||
def get_config(self):
|
||||
config = {'cropping': self.cropping,
|
||||
@@ -1891,7 +1830,3 @@ Convolution3D = Conv3D
|
||||
SeparableConvolution2D = SeparableConv2D
|
||||
Convolution2DTranspose = Conv2DTranspose
|
||||
Deconvolution2D = Deconv2D = Conv2DTranspose
|
||||
|
||||
# Legacy aliases
|
||||
AtrousConv1D = AtrousConvolution1D
|
||||
AtrousConv2D = AtrousConvolution2D
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Convolutional-recurrent layers.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from .. import backend as K
|
||||
from .. import activations
|
||||
from .. import backend as K
|
||||
from .. import constraints
|
||||
from .. import initializers
|
||||
from .. import regularizers
|
||||
from .. import constraints
|
||||
from .recurrent import Recurrent
|
||||
|
||||
import numpy as np
|
||||
from ..engine import InputSpec
|
||||
import numpy as np
|
||||
from .recurrent import Recurrent
|
||||
from tensorflow.python.framework import tensor_shape
|
||||
from ..utils import conv_utils
|
||||
from ..legacy import interfaces
|
||||
|
||||
|
||||
class ConvRecurrent2D(Recurrent):
|
||||
@@ -62,7 +65,7 @@ class ConvRecurrent2D(Recurrent):
|
||||
# Masking
|
||||
This layer supports masking for input data with a variable number
|
||||
of timesteps. To introduce masks to your data,
|
||||
use an [Embedding](embeddings.md) layer with the `mask_zero` parameter
|
||||
use an `Embedding` layer with the `mask_zero` parameter
|
||||
set to `True`.
|
||||
**Note:** for the time being, masking is only supported with Theano.
|
||||
|
||||
@@ -108,9 +111,10 @@ class ConvRecurrent2D(Recurrent):
|
||||
self.input_spec = [InputSpec(ndim=5)]
|
||||
self.state_spec = None
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
if isinstance(input_shape, list):
|
||||
def _compute_output_shape(self, input_shape):
|
||||
if type(input_shape) is 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]
|
||||
@@ -129,16 +133,28 @@ class ConvRecurrent2D(Recurrent):
|
||||
dilation=self.dilation_rate[1])
|
||||
if self.return_sequences:
|
||||
if self.data_format == 'channels_first':
|
||||
return (input_shape[0], input_shape[1],
|
||||
self.filters, rows, cols)
|
||||
return tensor_shape.TensorShape([input_shape[0],
|
||||
input_shape[1],
|
||||
self.filters,
|
||||
rows,
|
||||
cols])
|
||||
elif self.data_format == 'channels_last':
|
||||
return (input_shape[0], input_shape[1],
|
||||
rows, cols, self.filters)
|
||||
return tensor_shape.TensorShape([input_shape[0],
|
||||
input_shape[1],
|
||||
rows,
|
||||
cols,
|
||||
self.filters])
|
||||
else:
|
||||
if self.data_format == 'channels_first':
|
||||
return (input_shape[0], self.filters, rows, cols)
|
||||
return tensor_shape.TensorShape([input_shape[0],
|
||||
self.filters,
|
||||
rows,
|
||||
cols])
|
||||
elif self.data_format == 'channels_last':
|
||||
return (input_shape[0], rows, cols, self.filters)
|
||||
return tensor_shape.TensorShape([input_shape[0],
|
||||
rows,
|
||||
cols,
|
||||
self.filters])
|
||||
|
||||
def get_config(self):
|
||||
config = {'filters': self.filters,
|
||||
@@ -184,46 +200,34 @@ class ConvLSTM2D(ConvRecurrent2D):
|
||||
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
|
||||
(see [activations](../activations.md)).
|
||||
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
|
||||
(see [activations](../activations.md)).
|
||||
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.
|
||||
(see [initializers](../initializers.md)).
|
||||
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.
|
||||
(see [initializers](../initializers.md)).
|
||||
bias_initializer: Initializer for the bias vector
|
||||
(see [initializers](../initializers.md)).
|
||||
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
|
||||
(see [regularizer](../regularizers.md)).
|
||||
the `kernel` weights matrix.
|
||||
recurrent_regularizer: Regularizer function applied to
|
||||
the `recurrent_kernel` weights matrix
|
||||
(see [regularizer](../regularizers.md)).
|
||||
bias_regularizer: Regularizer function applied to the bias vector
|
||||
(see [regularizer](../regularizers.md)).
|
||||
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").
|
||||
(see [regularizer](../regularizers.md)).
|
||||
the output of the layer (its "activation")..
|
||||
kernel_constraint: Constraint function applied to
|
||||
the `kernel` weights matrix
|
||||
(see [constraints](../constraints.md)).
|
||||
the `kernel` weights matrix.
|
||||
recurrent_constraint: Constraint function applied to
|
||||
the `recurrent_kernel` weights matrix
|
||||
(see [constraints](../constraints.md)).
|
||||
bias_constraint: Constraint function applied to the bias vector
|
||||
(see [constraints](../constraints.md)).
|
||||
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).
|
||||
@@ -274,7 +278,6 @@ class ConvLSTM2D(ConvRecurrent2D):
|
||||
cells output
|
||||
"""
|
||||
|
||||
@interfaces.legacy_convlstm2d_support
|
||||
def __init__(self, filters,
|
||||
kernel_size,
|
||||
strides=(1, 1),
|
||||
@@ -336,8 +339,10 @@ class ConvLSTM2D(ConvRecurrent2D):
|
||||
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:
|
||||
@@ -423,7 +428,8 @@ class ConvLSTM2D(ConvRecurrent2D):
|
||||
if not self.stateful:
|
||||
raise RuntimeError('Layer must be stateful.')
|
||||
input_shape = self.input_spec[0].shape
|
||||
output_shape = self.compute_output_shape(input_shape)
|
||||
output_shape = self._compute_output_shape(input_shape)
|
||||
|
||||
if not input_shape[0]:
|
||||
raise ValueError('If a RNN is stateful, a complete '
|
||||
'input_shape must be provided '
|
||||
@@ -474,7 +480,7 @@ class ConvLSTM2D(ConvRecurrent2D):
|
||||
padding=self.padding)
|
||||
ones += 1.
|
||||
|
||||
def dropped_inputs():
|
||||
def dropped_inputs(): # pylint: disable=function-redefined
|
||||
return K.dropout(ones, self.recurrent_dropout)
|
||||
rec_dp_mask = [K.in_train_phase(dropped_inputs,
|
||||
ones,
|
||||
|
||||
+62
-170
@@ -1,25 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Core Keras layers.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
|
||||
import numpy as np
|
||||
from __future__ import print_function
|
||||
|
||||
import copy
|
||||
import inspect
|
||||
import types as python_types
|
||||
import warnings
|
||||
|
||||
from .. import backend as K
|
||||
from .. import activations
|
||||
from .. import backend as K
|
||||
from .. import constraints
|
||||
from .. import initializers
|
||||
from .. import regularizers
|
||||
from .. import constraints
|
||||
from ..engine import InputSpec
|
||||
from ..engine import Layer
|
||||
import numpy as np
|
||||
from tensorflow.python.framework import tensor_shape
|
||||
from ..utils.generic_utils import deserialize_keras_object
|
||||
from ..utils.generic_utils import func_dump
|
||||
from ..utils.generic_utils import func_load
|
||||
from ..utils.generic_utils import deserialize_keras_object
|
||||
from ..legacy import interfaces
|
||||
|
||||
|
||||
class Masking(Layer):
|
||||
@@ -85,11 +86,8 @@ class Dropout(Layer):
|
||||
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.
|
||||
|
||||
# References
|
||||
- [Dropout: A Simple Way to Prevent Neural Networks from Overfitting](http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf)
|
||||
"""
|
||||
@interfaces.legacy_dropout_support
|
||||
|
||||
def __init__(self, rate, noise_shape=None, seed=None, **kwargs):
|
||||
super(Dropout, self).__init__(**kwargs)
|
||||
self.rate = min(1., max(0., rate))
|
||||
@@ -142,7 +140,6 @@ class SpatialDropout1D(Dropout):
|
||||
- [Efficient Object Localization Using Convolutional Networks](https://arxiv.org/abs/1411.4280)
|
||||
"""
|
||||
|
||||
@interfaces.legacy_spatialdropout1d_support
|
||||
def __init__(self, rate, **kwargs):
|
||||
super(SpatialDropout1D, self).__init__(rate, **kwargs)
|
||||
self.input_spec = InputSpec(ndim=3)
|
||||
@@ -187,7 +184,6 @@ class SpatialDropout2D(Dropout):
|
||||
- [Efficient Object Localization Using Convolutional Networks](https://arxiv.org/abs/1411.4280)
|
||||
"""
|
||||
|
||||
@interfaces.legacy_spatialdropoutNd_support
|
||||
def __init__(self, rate, data_format=None, **kwargs):
|
||||
super(SpatialDropout2D, self).__init__(rate, **kwargs)
|
||||
if data_format is None:
|
||||
@@ -242,7 +238,6 @@ class SpatialDropout3D(Dropout):
|
||||
- [Efficient Object Localization Using Convolutional Networks](https://arxiv.org/abs/1411.4280)
|
||||
"""
|
||||
|
||||
@interfaces.legacy_spatialdropoutNd_support
|
||||
def __init__(self, rate, data_format=None, **kwargs):
|
||||
super(SpatialDropout3D, self).__init__(rate, **kwargs)
|
||||
if data_format is None:
|
||||
@@ -269,7 +264,6 @@ class Activation(Layer):
|
||||
|
||||
# Arguments
|
||||
activation: name of activation function to use
|
||||
(see: [activations](../activations.md)),
|
||||
or alternatively, a Theano or TensorFlow operation.
|
||||
|
||||
# Input shape
|
||||
@@ -299,13 +293,13 @@ class Reshape(Layer):
|
||||
"""Reshapes an output to a certain shape.
|
||||
|
||||
# Arguments
|
||||
target_shape: target shape. Tuple of integers.
|
||||
Does not include the batch axis.
|
||||
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 batch axis)
|
||||
(tuple of integers, does not include the samples axis)
|
||||
when using this layer as the first layer in a model.
|
||||
|
||||
# Output shape
|
||||
@@ -335,22 +329,27 @@ class Reshape(Layer):
|
||||
self.target_shape = tuple(target_shape)
|
||||
|
||||
def _fix_unknown_dimension(self, input_shape, output_shape):
|
||||
"""Finds and replaces a missing dimension in an 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: original shape of array being reshaped
|
||||
output_shape: target shape of the array, with at most
|
||||
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.
|
||||
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 then one unknown dimension
|
||||
is specified.
|
||||
|
||||
# Raises
|
||||
ValueError: if `input_shape` and `output_shape` do not match.
|
||||
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'
|
||||
@@ -372,28 +371,24 @@ class Reshape(Layer):
|
||||
output_shape[unknown] = original // known
|
||||
elif original != known:
|
||||
raise ValueError(msg)
|
||||
return output_shape
|
||||
|
||||
return tuple(output_shape)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
return (input_shape[0],) + self._fix_unknown_dimension(
|
||||
input_shape[1:], self.target_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 `inputs`.
|
||||
# solution: rely on `K.int_shape`.
|
||||
# we need access to the shape of x.
|
||||
target_shape = self.target_shape
|
||||
if -1 in target_shape:
|
||||
# Target shape not fully defined.
|
||||
input_shape = None
|
||||
try:
|
||||
input_shape = K.int_shape(inputs)
|
||||
except TypeError:
|
||||
pass
|
||||
if input_shape is not None:
|
||||
target_shape = self.compute_output_shape(input_shape)[1:]
|
||||
return K.reshape(inputs, (-1,) + 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}
|
||||
@@ -436,13 +431,13 @@ class Permute(Layer):
|
||||
self.dims = tuple(dims)
|
||||
self.input_spec = InputSpec(ndim=len(self.dims) + 1)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
input_shape = list(input_shape)
|
||||
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 tuple(output_shape)
|
||||
return tensor_shape.TensorShape(output_shape)
|
||||
|
||||
def call(self, inputs):
|
||||
return K.permute_dimensions(inputs, (0,) + self.dims)
|
||||
@@ -474,7 +469,8 @@ class Flatten(Layer):
|
||||
super(Flatten, self).__init__(**kwargs)
|
||||
self.input_spec = InputSpec(min_ndim=3)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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 '
|
||||
@@ -482,10 +478,12 @@ class Flatten(Layer):
|
||||
'Make sure to pass a complete "input_shape" '
|
||||
'or "batch_input_shape" argument to the first '
|
||||
'layer in your model.')
|
||||
return (input_shape[0], np.prod(input_shape[1:]))
|
||||
return tensor_shape.TensorShape([input_shape[0], np.prod(input_shape[1:])])
|
||||
|
||||
def call(self, inputs):
|
||||
return K.batch_flatten(inputs)
|
||||
outputs = K.batch_flatten(inputs)
|
||||
outputs.set_shape(self._compute_output_shape(inputs.get_shape()))
|
||||
return outputs
|
||||
|
||||
|
||||
class RepeatVector(Layer):
|
||||
@@ -518,8 +516,9 @@ class RepeatVector(Layer):
|
||||
self.n = n
|
||||
self.input_spec = InputSpec(ndim=2)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
return (input_shape[0], self.n, input_shape[1])
|
||||
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)
|
||||
@@ -551,30 +550,12 @@ class Lambda(Layer):
|
||||
neg = K.relu(-x)
|
||||
return K.concatenate([pos, neg], axis=1)
|
||||
|
||||
def antirectifier_output_shape(input_shape):
|
||||
shape = list(input_shape)
|
||||
assert len(shape) == 2 # only valid for 2D tensors
|
||||
shape[-1] *= 2
|
||||
return tuple(shape)
|
||||
|
||||
model.add(Lambda(antirectifier,
|
||||
output_shape=antirectifier_output_shape))
|
||||
model.add(Lambda(antirectifier))
|
||||
```
|
||||
|
||||
# Arguments
|
||||
function: The function to be evaluated.
|
||||
Takes input tensor as first argument.
|
||||
output_shape: Expected output shape from function.
|
||||
Only relevant when using Theano.
|
||||
Can be a tuple or function.
|
||||
If a tuple, it only specifies the first dimension onward;
|
||||
sample dimension is assumed either the same as the input:
|
||||
`output_shape = (input_shape[0], ) + output_shape`
|
||||
or, the input is `None` and
|
||||
the sample dimension is also `None`:
|
||||
`output_shape = (None, ) + output_shape`
|
||||
If a function, it specifies the entire shape as a function of the
|
||||
input shape: `output_shape = f(input_shape)`
|
||||
arguments: optional dictionary of keyword arguments to be passed
|
||||
to the function.
|
||||
|
||||
@@ -588,9 +569,10 @@ class Lambda(Layer):
|
||||
(or auto-inferred when using TensorFlow).
|
||||
"""
|
||||
|
||||
@interfaces.legacy_lambda_support
|
||||
def __init__(self, function, output_shape=None,
|
||||
mask=None, arguments=None, **kwargs):
|
||||
def __init__(self, function,
|
||||
mask=None,
|
||||
arguments=None,
|
||||
**kwargs):
|
||||
super(Lambda, self).__init__(**kwargs)
|
||||
self.function = function
|
||||
self.arguments = arguments if arguments else {}
|
||||
@@ -598,52 +580,6 @@ class Lambda(Layer):
|
||||
self.supports_masking = True
|
||||
self.mask = mask
|
||||
|
||||
if output_shape is None:
|
||||
self._output_shape = None
|
||||
elif isinstance(output_shape, (tuple, list)):
|
||||
self._output_shape = tuple(output_shape)
|
||||
else:
|
||||
if not callable(output_shape):
|
||||
raise TypeError('In Lambda, `output_shape` '
|
||||
'must be a list, a tuple, or a function.')
|
||||
self._output_shape = output_shape
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
if self._output_shape is None:
|
||||
# With TensorFlow, we can infer the output shape directly:
|
||||
if K.backend() == 'tensorflow':
|
||||
if isinstance(input_shape, list):
|
||||
xs = [K.placeholder(shape=shape) for shape in input_shape]
|
||||
x = self.call(xs)
|
||||
else:
|
||||
x = K.placeholder(shape=input_shape)
|
||||
x = self.call(x)
|
||||
if isinstance(x, list):
|
||||
return [K.int_shape(x_elem) for x_elem in x]
|
||||
else:
|
||||
return K.int_shape(x)
|
||||
# Otherwise, we default to the input shape.
|
||||
warnings.warn('`output_shape` argument not specified for layer {} '
|
||||
'and cannot be automatically inferred '
|
||||
'with the Theano backend. '
|
||||
'Defaulting to output shape `{}` '
|
||||
'(same as input shape). '
|
||||
'If the expected output shape is different, '
|
||||
'specify it via the `output_shape` argument.'
|
||||
.format(self.name, input_shape))
|
||||
return input_shape
|
||||
elif isinstance(self._output_shape, (tuple, list)):
|
||||
if isinstance(input_shape, list):
|
||||
num_samples = input_shape[0][0]
|
||||
else:
|
||||
num_samples = input_shape[0] if input_shape else None
|
||||
return (num_samples,) + tuple(self._output_shape)
|
||||
else:
|
||||
shape = self._output_shape(input_shape)
|
||||
if not isinstance(shape, (list, tuple)):
|
||||
raise ValueError('output_shape function must return a tuple')
|
||||
return tuple(shape)
|
||||
|
||||
def call(self, inputs, mask=None):
|
||||
arguments = self.arguments
|
||||
arg_spec = inspect.getargspec(self.function)
|
||||
@@ -664,20 +600,8 @@ class Lambda(Layer):
|
||||
function = self.function.__name__
|
||||
function_type = 'function'
|
||||
|
||||
if isinstance(self._output_shape, python_types.LambdaType):
|
||||
output_shape = func_dump(self._output_shape)
|
||||
output_shape_type = 'lambda'
|
||||
elif callable(self._output_shape):
|
||||
output_shape = self._output_shape.__name__
|
||||
output_shape_type = 'function'
|
||||
else:
|
||||
output_shape = self._output_shape
|
||||
output_shape_type = 'raw'
|
||||
|
||||
config = {'function': function,
|
||||
'function_type': function_type,
|
||||
'output_shape': output_shape,
|
||||
'output_shape_type': output_shape_type,
|
||||
'arguments': self.arguments}
|
||||
base_config = super(Lambda, self).get_config()
|
||||
return dict(list(base_config.items()) + list(config.items()))
|
||||
@@ -700,31 +624,7 @@ class Lambda(Layer):
|
||||
else:
|
||||
raise TypeError('Unknown function type:', function_type)
|
||||
|
||||
output_shape_type = config.pop('output_shape_type')
|
||||
if output_shape_type == 'function':
|
||||
# Simple lookup in custom objects
|
||||
output_shape = deserialize_keras_object(
|
||||
config['output_shape'],
|
||||
custom_objects=custom_objects,
|
||||
printable_module_name='output_shape function in Lambda layer')
|
||||
elif output_shape_type == 'lambda':
|
||||
# Unsafe deserialization from bytecode
|
||||
output_shape = func_load(config['output_shape'], globs=globs)
|
||||
else:
|
||||
output_shape = config['output_shape']
|
||||
|
||||
# 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
|
||||
config['output_shape'] = output_shape
|
||||
return cls(**config)
|
||||
|
||||
|
||||
@@ -757,28 +657,20 @@ class Dense(Layer):
|
||||
|
||||
# Arguments
|
||||
units: Positive integer, dimensionality of the output space.
|
||||
activation: Activation function to use
|
||||
(see [activations](../activations.md)).
|
||||
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
|
||||
(see [initializers](../initializers.md)).
|
||||
bias_initializer: Initializer for the bias vector
|
||||
(see [initializers](../initializers.md)).
|
||||
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
|
||||
(see [regularizer](../regularizers.md)).
|
||||
bias_regularizer: Regularizer function applied to the bias vector
|
||||
(see [regularizer](../regularizers.md)).
|
||||
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").
|
||||
(see [regularizer](../regularizers.md)).
|
||||
the output of the layer (its "activation")..
|
||||
kernel_constraint: Constraint function applied to
|
||||
the `kernel` weights matrix
|
||||
(see [constraints](../constraints.md)).
|
||||
bias_constraint: Constraint function applied to the bias vector
|
||||
(see [constraints](../constraints.md)).
|
||||
the `kernel` weights matrix.
|
||||
bias_constraint: Constraint function applied to the bias vector.
|
||||
|
||||
# Input shape
|
||||
nD tensor with shape: `(batch_size, ..., input_dim)`.
|
||||
@@ -791,7 +683,6 @@ class Dense(Layer):
|
||||
the output would have shape `(batch_size, units)`.
|
||||
"""
|
||||
|
||||
@interfaces.legacy_dense_support
|
||||
def __init__(self, units,
|
||||
activation=None,
|
||||
use_bias=True,
|
||||
@@ -847,12 +738,13 @@ class Dense(Layer):
|
||||
output = self.activation(output)
|
||||
return output
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
def _compute_output_shape(self, input_shape):
|
||||
input_shape = tensor_shape.TensorShape(input_shape).as_list()
|
||||
assert input_shape and len(input_shape) >= 2
|
||||
assert input_shape[-1]
|
||||
output_shape = list(input_shape)
|
||||
output_shape[-1] = self.units
|
||||
return tuple(output_shape)
|
||||
return tensor_shape.TensorShape(output_shape)
|
||||
|
||||
def get_config(self):
|
||||
config = {
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
"""Embedding layer.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from .. import backend as K
|
||||
from .. import constraints
|
||||
from .. import initializers
|
||||
from .. import regularizers
|
||||
from .. import constraints
|
||||
from ..engine import Layer
|
||||
from ..legacy import interfaces
|
||||
from tensorflow.python.framework import tensor_shape
|
||||
|
||||
|
||||
class Embedding(Layer):
|
||||
@@ -34,18 +38,15 @@ class Embedding(Layer):
|
||||
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
|
||||
(see [initializers](../initializers.md)).
|
||||
embeddings_initializer: Initializer for the `embeddings` matrix.
|
||||
embeddings_regularizer: Regularizer function applied to
|
||||
the `embeddings` matrix
|
||||
(see [regularizer](../regularizers.md)).
|
||||
the `embeddings` matrix.
|
||||
embeddings_constraint: Constraint function applied to
|
||||
the `embeddings` matrix
|
||||
(see [constraints](../constraints.md)).
|
||||
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](recurrent.md)
|
||||
which may take variable length input.
|
||||
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
|
||||
@@ -66,7 +67,6 @@ class Embedding(Layer):
|
||||
- [A Theoretically Grounded Application of Dropout in Recurrent Neural Networks](http://arxiv.org/abs/1512.05287)
|
||||
"""
|
||||
|
||||
@interfaces.legacy_embedding_support
|
||||
def __init__(self, input_dim, output_dim,
|
||||
embeddings_initializer='uniform',
|
||||
embeddings_regularizer=None,
|
||||
@@ -93,6 +93,7 @@ class Embedding(Layer):
|
||||
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,
|
||||
@@ -107,26 +108,15 @@ class Embedding(Layer):
|
||||
else:
|
||||
return K.not_equal(inputs, 0)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
if self.input_length is None:
|
||||
return input_shape + (self.output_dim,)
|
||||
def _compute_output_shape(self, input_shape):
|
||||
input_shape = tensor_shape.TensorShape(input_shape).as_list()
|
||||
if not self.input_length:
|
||||
input_length = input_shape[1]
|
||||
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 (input_shape[0],) + tuple(in_lens) + (self.output_dim,)
|
||||
input_length = self.input_length
|
||||
return tensor_shape.TensorShape([input_shape[0],
|
||||
input_length,
|
||||
self.output_dim])
|
||||
|
||||
def call(self, inputs):
|
||||
if K.dtype(inputs) != 'int32':
|
||||
|
||||
+101
-57
@@ -1,15 +1,19 @@
|
||||
"""Locally-connected layers.
|
||||
"""
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from .. import backend as K
|
||||
from .. import activations
|
||||
from .. import backend as K
|
||||
from .. import constraints
|
||||
from .. import initializers
|
||||
from .. import regularizers
|
||||
from .. import constraints
|
||||
from ..engine import Layer
|
||||
from ..engine import InputSpec
|
||||
from ..engine import Layer
|
||||
from tensorflow.python.framework import tensor_shape
|
||||
from ..utils import conv_utils
|
||||
from ..legacy import interfaces
|
||||
|
||||
|
||||
class LocallyConnected1D(Layer):
|
||||
@@ -43,27 +47,19 @@ class LocallyConnected1D(Layer):
|
||||
any `dilation_rate` value != 1.
|
||||
padding: Currently only supports `"valid"` (case-insensitive).
|
||||
`"same"` may be supported in the future.
|
||||
activation: Activation function to use
|
||||
(see [activations](../activations.md)).
|
||||
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
|
||||
(see [initializers](../initializers.md)).
|
||||
bias_initializer: Initializer for the bias vector
|
||||
(see [initializers](../initializers.md)).
|
||||
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
|
||||
(see [regularizer](../regularizers.md)).
|
||||
bias_regularizer: Regularizer function applied to the bias vector
|
||||
(see [regularizer](../regularizers.md)).
|
||||
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").
|
||||
(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)).
|
||||
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)`
|
||||
@@ -73,7 +69,6 @@ class LocallyConnected1D(Layer):
|
||||
`steps` value might have changed due to padding or strides.
|
||||
"""
|
||||
|
||||
@interfaces.legacy_conv1d_support
|
||||
def __init__(self, filters,
|
||||
kernel_size,
|
||||
strides=1,
|
||||
@@ -110,6 +105,7 @@ class LocallyConnected1D(Layer):
|
||||
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. '
|
||||
@@ -139,19 +135,31 @@ class LocallyConnected1D(Layer):
|
||||
self.input_spec = InputSpec(ndim=3, axes={2: input_dim})
|
||||
self.built = True
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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 (input_shape[0], length, self.filters)
|
||||
return tensor_shape.TensorShape([input_shape[0], length, self.filters])
|
||||
|
||||
def call(self, inputs):
|
||||
output_length, _, filters = self.kernel_shape
|
||||
stride = self.strides[0]
|
||||
output_length, feature_dim, filters = self.kernel_shape
|
||||
|
||||
xs = []
|
||||
for i in range(output_length):
|
||||
slice_length = slice(i * stride,
|
||||
i * stride + self.kernel_size[0])
|
||||
xs.append(K.reshape(inputs[:, slice_length, :],
|
||||
(1, -1, feature_dim)))
|
||||
x_aggregate = K.concatenate(xs, axis=0)
|
||||
# Shape: `(output_length, batch_size, filters)`.
|
||||
output = K.batch_dot(x_aggregate, self.kernel)
|
||||
output = K.permute_dimensions(output, (1, 0, 2))
|
||||
|
||||
output = K.local_conv1d(inputs, self.kernel, self.kernel_size, self.strides)
|
||||
if self.use_bias:
|
||||
output = K.bias_add(output, self.bias)
|
||||
output += K.reshape(self.bias, (1, output_length, filters))
|
||||
if self.activation is not None:
|
||||
output = self.activation(output)
|
||||
return output
|
||||
@@ -221,27 +229,19 @@ class LocallyConnected2D(Layer):
|
||||
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)).
|
||||
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
|
||||
(see [initializers](../initializers.md)).
|
||||
bias_initializer: Initializer for the bias vector
|
||||
(see [initializers](../initializers.md)).
|
||||
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
|
||||
(see [regularizer](../regularizers.md)).
|
||||
bias_regularizer: Regularizer function applied to the bias vector
|
||||
(see [regularizer](../regularizers.md)).
|
||||
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").
|
||||
(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)).
|
||||
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:
|
||||
@@ -257,7 +257,6 @@ class LocallyConnected2D(Layer):
|
||||
`rows` and `cols` values might have changed due to padding.
|
||||
"""
|
||||
|
||||
@interfaces.legacy_conv2d_support
|
||||
def __init__(self, filters,
|
||||
kernel_size,
|
||||
strides=(1, 1),
|
||||
@@ -294,6 +293,7 @@ class LocallyConnected2D(Layer):
|
||||
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]
|
||||
@@ -305,6 +305,7 @@ class LocallyConnected2D(Layer):
|
||||
' 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],
|
||||
@@ -333,38 +334,81 @@ class LocallyConnected2D(Layer):
|
||||
self.input_spec = InputSpec(ndim=4, axes={-1: input_filter})
|
||||
self.built = True
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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 (input_shape[0], self.filters, rows, cols)
|
||||
return tensor_shape.TensorShape([input_shape[0], self.filters, rows, cols])
|
||||
elif self.data_format == 'channels_last':
|
||||
return (input_shape[0], rows, cols, self.filters)
|
||||
return tensor_shape.TensorShape([input_shape[0], rows, cols, self.filters])
|
||||
|
||||
def call(self, inputs):
|
||||
_, _, filters = self.kernel_shape
|
||||
stride_row, stride_col = self.strides
|
||||
_, feature_dim, filters = self.kernel_shape
|
||||
|
||||
output = K.local_conv2d(inputs,
|
||||
self.kernel,
|
||||
self.kernel_size,
|
||||
self.strides,
|
||||
(self.output_row, self.output_col),
|
||||
self.data_format)
|
||||
if self.data_format == 'channels_first':
|
||||
if K.backend() == 'theano':
|
||||
output = []
|
||||
for i in range(self.output_row):
|
||||
for j in range(self.output_col):
|
||||
slice_row = slice(i * stride_row,
|
||||
i * stride_row + self.kernel_size[0])
|
||||
slice_col = slice(j * stride_col,
|
||||
j * stride_col + self.kernel_size[1])
|
||||
x_flatten = K.reshape(inputs[:, :, slice_row, slice_col],
|
||||
(1, -1, feature_dim))
|
||||
output.append(K.dot(x_flatten,
|
||||
self.kernel[i * self.output_col + j, :, :]))
|
||||
output = K.concatenate(output, axis=0)
|
||||
else:
|
||||
xs = []
|
||||
for i in range(self.output_row):
|
||||
for j in range(self.output_col):
|
||||
slice_row = slice(i * stride_row,
|
||||
i * stride_row + self.kernel_size[0])
|
||||
slice_col = slice(j * stride_col,
|
||||
j * stride_col + self.kernel_size[1])
|
||||
xs.append(K.reshape(inputs[:, :, slice_row, slice_col],
|
||||
(1, -1, feature_dim)))
|
||||
x_aggregate = K.concatenate(xs, axis=0)
|
||||
output = K.batch_dot(x_aggregate, self.kernel)
|
||||
output = K.reshape(output,
|
||||
(self.output_row, self.output_col, -1, filters))
|
||||
output = K.permute_dimensions(output, (2, 3, 0, 1))
|
||||
|
||||
elif self.data_format == 'channels_last':
|
||||
xs = []
|
||||
for i in range(self.output_row):
|
||||
for j in range(self.output_col):
|
||||
slice_row = slice(i * stride_row,
|
||||
i * stride_row + self.kernel_size[0])
|
||||
slice_col = slice(j * stride_col,
|
||||
j * stride_col + self.kernel_size[1])
|
||||
xs.append(K.reshape(inputs[:, slice_row, slice_col, :],
|
||||
(1, -1, feature_dim)))
|
||||
x_aggregate = K.concatenate(xs, axis=0)
|
||||
output = K.batch_dot(x_aggregate, self.kernel)
|
||||
output = K.reshape(output,
|
||||
(self.output_row, self.output_col, -1, filters))
|
||||
output = K.permute_dimensions(output, (2, 0, 1, 3))
|
||||
|
||||
if self.use_bias:
|
||||
if self.data_format == 'channels_first' or self.data_format == 'channels_last':
|
||||
output = K.bias_add(output, self.bias, data_format=self.data_format)
|
||||
|
||||
if self.data_format == 'channels_first':
|
||||
output += K.reshape(self.bias,
|
||||
(1, filters, self.output_row, self.output_col))
|
||||
elif self.data_format == 'channels_last':
|
||||
output += K.reshape(self.bias,
|
||||
(1, self.output_row, self.output_col, filters))
|
||||
output = self.activation(output)
|
||||
return output
|
||||
|
||||
|
||||
+20
-12
@@ -1,5 +1,12 @@
|
||||
from ..engine.topology import Layer
|
||||
"""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 .. import backend as K
|
||||
from ..engine.topology import Layer
|
||||
from tensorflow.python.framework import tensor_shape
|
||||
|
||||
|
||||
class _Merge(Layer):
|
||||
@@ -38,7 +45,7 @@ class _Merge(Layer):
|
||||
return None
|
||||
elif len(shape1) < len(shape2):
|
||||
return self._compute_elemwise_op_output_shape(shape2, shape1)
|
||||
elif len(shape2) == 0:
|
||||
elif not shape2:
|
||||
return shape1
|
||||
output_shape = list(shape1[:-len(shape2)])
|
||||
for i, j in zip(shape1[-len(shape2):], shape2):
|
||||
@@ -265,7 +272,7 @@ class Concatenate(_Merge):
|
||||
'on a list of inputs')
|
||||
if all([shape is None for shape in input_shape]):
|
||||
return
|
||||
reduced_inputs_shapes = [list(shape) for shape in input_shape]
|
||||
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]
|
||||
@@ -282,18 +289,19 @@ class Concatenate(_Merge):
|
||||
'on a list of inputs.')
|
||||
return K.concatenate(inputs, axis=self.axis)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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 = list(input_shapes[0])
|
||||
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 tuple(output_shape)
|
||||
return tensor_shape.TensorShape(output_shape)
|
||||
|
||||
def compute_mask(self, inputs, mask=None):
|
||||
if mask is None:
|
||||
@@ -371,8 +379,8 @@ class Dot(_Merge):
|
||||
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 = input_shape[0]
|
||||
shape2 = input_shape[1]
|
||||
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):
|
||||
@@ -409,12 +417,12 @@ class Dot(_Merge):
|
||||
output = K.batch_dot(x1, x2, axes)
|
||||
return output
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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 = list(input_shape[0])
|
||||
shape2 = list(input_shape[1])
|
||||
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)]
|
||||
@@ -428,7 +436,7 @@ class Dot(_Merge):
|
||||
output_shape = shape1 + shape2
|
||||
if len(output_shape) == 1:
|
||||
output_shape += [1]
|
||||
return tuple(output_shape)
|
||||
return tensor_shape.TensorShape(output_shape)
|
||||
|
||||
def compute_mask(self, inputs, mask=None):
|
||||
return None
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Layers for regularization models via the addition of noise.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from ..engine import Layer
|
||||
from .. import backend as K
|
||||
from ..engine import Layer
|
||||
import numpy as np
|
||||
from ..legacy import interfaces
|
||||
|
||||
|
||||
class GaussianNoise(Layer):
|
||||
@@ -29,7 +32,6 @@ class GaussianNoise(Layer):
|
||||
Same shape as input.
|
||||
"""
|
||||
|
||||
@interfaces.legacy_gaussiannoise_support
|
||||
def __init__(self, stddev, **kwargs):
|
||||
super(GaussianNoise, self).__init__(**kwargs)
|
||||
self.supports_masking = True
|
||||
@@ -70,7 +72,6 @@ class GaussianDropout(Layer):
|
||||
- [Dropout: A Simple Way to Prevent Neural Networks from Overfitting Srivastava, Hinton, et al. 2014](http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf)
|
||||
"""
|
||||
|
||||
@interfaces.legacy_gaussiandropout_support
|
||||
def __init__(self, rate, **kwargs):
|
||||
super(GaussianDropout, self).__init__(**kwargs)
|
||||
self.supports_masking = True
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Normalization layers.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from ..engine import Layer, InputSpec
|
||||
from .. import backend as K
|
||||
from .. import constraints
|
||||
from .. import initializers
|
||||
from .. import regularizers
|
||||
from .. import constraints
|
||||
from .. import backend as K
|
||||
from ..legacy import interfaces
|
||||
from ..engine import InputSpec
|
||||
from ..engine import Layer
|
||||
from tensorflow.python.framework import tensor_shape
|
||||
|
||||
|
||||
class BatchNormalization(Layer):
|
||||
@@ -52,7 +57,6 @@ class BatchNormalization(Layer):
|
||||
- [Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift](https://arxiv.org/abs/1502.03167)
|
||||
"""
|
||||
|
||||
@interfaces.legacy_batchnorm_support
|
||||
def __init__(self,
|
||||
axis=-1,
|
||||
momentum=0.99,
|
||||
@@ -85,6 +89,7 @@ class BatchNormalization(Layer):
|
||||
self.gamma_constraint = constraints.get(gamma_constraint)
|
||||
|
||||
def build(self, input_shape):
|
||||
input_shape = tensor_shape.TensorShape(input_shape).as_list()
|
||||
dim = input_shape[self.axis]
|
||||
if dim is None:
|
||||
raise ValueError('Axis ' + str(self.axis) + ' of '
|
||||
@@ -124,7 +129,7 @@ class BatchNormalization(Layer):
|
||||
self.built = True
|
||||
|
||||
def call(self, inputs, training=None):
|
||||
input_shape = K.int_shape(inputs)
|
||||
input_shape = inputs.get_shape().as_list()
|
||||
# Prepare broadcasting shape.
|
||||
ndim = len(input_shape)
|
||||
reduction_axes = list(range(len(input_shape)))
|
||||
|
||||
+40
-34
@@ -1,11 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Pooling layers.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from .. import backend as K
|
||||
from ..engine import Layer
|
||||
from ..engine import InputSpec
|
||||
from ..engine import Layer
|
||||
from tensorflow.python.framework import tensor_shape
|
||||
from ..utils import conv_utils
|
||||
from ..legacy import interfaces
|
||||
|
||||
|
||||
class _Pooling1D(Layer):
|
||||
@@ -22,12 +26,13 @@ class _Pooling1D(Layer):
|
||||
self.padding = conv_utils.normalize_padding(padding)
|
||||
self.input_spec = InputSpec(ndim=3)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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.pool_size[0],
|
||||
self.padding,
|
||||
self.strides[0])
|
||||
return (input_shape[0], length, input_shape[2])
|
||||
return tensor_shape.TensorShape([input_shape[0], length, input_shape[2]])
|
||||
|
||||
def _pooling_function(self, inputs, pool_size, strides,
|
||||
padding, data_format):
|
||||
@@ -67,7 +72,6 @@ class MaxPooling1D(_Pooling1D):
|
||||
3D tensor with shape: `(batch_size, downsampled_steps, features)`.
|
||||
"""
|
||||
|
||||
@interfaces.legacy_pooling1d_support
|
||||
def __init__(self, pool_size=2, strides=None,
|
||||
padding='valid', **kwargs):
|
||||
super(MaxPooling1D, self).__init__(pool_size, strides,
|
||||
@@ -97,7 +101,6 @@ class AveragePooling1D(_Pooling1D):
|
||||
3D tensor with shape: `(batch_size, downsampled_steps, features)`.
|
||||
"""
|
||||
|
||||
@interfaces.legacy_pooling1d_support
|
||||
def __init__(self, pool_size=2, strides=None,
|
||||
padding='valid', **kwargs):
|
||||
super(AveragePooling1D, self).__init__(pool_size, strides,
|
||||
@@ -126,11 +129,12 @@ class _Pooling2D(Layer):
|
||||
self.data_format = conv_utils.normalize_data_format(data_format)
|
||||
self.input_spec = InputSpec(ndim=4)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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':
|
||||
else:
|
||||
rows = input_shape[1]
|
||||
cols = input_shape[2]
|
||||
rows = conv_utils.conv_output_length(rows, self.pool_size[0],
|
||||
@@ -138,9 +142,9 @@ class _Pooling2D(Layer):
|
||||
cols = conv_utils.conv_output_length(cols, self.pool_size[1],
|
||||
self.padding, self.strides[1])
|
||||
if self.data_format == 'channels_first':
|
||||
return (input_shape[0], input_shape[1], rows, cols)
|
||||
elif self.data_format == 'channels_last':
|
||||
return (input_shape[0], rows, cols, input_shape[3])
|
||||
return tensor_shape.TensorShape([input_shape[0], input_shape[1], rows, cols])
|
||||
else:
|
||||
return tensor_shape.TensorShape([input_shape[0], rows, cols, input_shape[3]])
|
||||
|
||||
def _pooling_function(self, inputs, pool_size, strides,
|
||||
padding, data_format):
|
||||
@@ -204,7 +208,6 @@ class MaxPooling2D(_Pooling2D):
|
||||
`(batch_size, channels, pooled_rows, pooled_cols)`
|
||||
"""
|
||||
|
||||
@interfaces.legacy_pooling2d_support
|
||||
def __init__(self, pool_size=(2, 2), strides=None, padding='valid',
|
||||
data_format=None, **kwargs):
|
||||
super(MaxPooling2D, self).__init__(pool_size, strides, padding,
|
||||
@@ -259,7 +262,6 @@ class AveragePooling2D(_Pooling2D):
|
||||
`(batch_size, channels, pooled_rows, pooled_cols)`
|
||||
"""
|
||||
|
||||
@interfaces.legacy_pooling2d_support
|
||||
def __init__(self, pool_size=(2, 2), strides=None, padding='valid',
|
||||
data_format=None, **kwargs):
|
||||
super(AveragePooling2D, self).__init__(pool_size, strides, padding,
|
||||
@@ -287,12 +289,13 @@ class _Pooling3D(Layer):
|
||||
self.data_format = conv_utils.normalize_data_format(data_format)
|
||||
self.input_spec = InputSpec(ndim=5)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
def _compute_output_shape(self, input_shape):
|
||||
input_shape = tensor_shape.TensorShape(input_shape).as_list()
|
||||
if self.data_format == 'channels_first':
|
||||
len_dim1 = input_shape[2]
|
||||
len_dim2 = input_shape[3]
|
||||
len_dim3 = input_shape[4]
|
||||
elif self.data_format == 'channels_last':
|
||||
else:
|
||||
len_dim1 = input_shape[1]
|
||||
len_dim2 = input_shape[2]
|
||||
len_dim3 = input_shape[3]
|
||||
@@ -303,13 +306,17 @@ class _Pooling3D(Layer):
|
||||
len_dim3 = conv_utils.conv_output_length(len_dim3, self.pool_size[2],
|
||||
self.padding, self.strides[2])
|
||||
if self.data_format == 'channels_first':
|
||||
return (input_shape[0],
|
||||
input_shape[1],
|
||||
len_dim1, len_dim2, len_dim3)
|
||||
elif self.data_format == 'channels_last':
|
||||
return (input_shape[0],
|
||||
len_dim1, len_dim2, len_dim3,
|
||||
input_shape[4])
|
||||
return tensor_shape.TensorShape([input_shape[0],
|
||||
input_shape[1],
|
||||
len_dim1,
|
||||
len_dim2,
|
||||
len_dim3])
|
||||
else:
|
||||
return tensor_shape.TensorShape([input_shape[0],
|
||||
len_dim1,
|
||||
len_dim2,
|
||||
len_dim3,
|
||||
input_shape[4]])
|
||||
|
||||
def _pooling_function(self, inputs, pool_size, strides,
|
||||
padding, data_format):
|
||||
@@ -369,7 +376,6 @@ class MaxPooling3D(_Pooling3D):
|
||||
`(batch_size, channels, pooled_dim1, pooled_dim2, pooled_dim3)`
|
||||
"""
|
||||
|
||||
@interfaces.legacy_pooling3d_support
|
||||
def __init__(self, pool_size=(2, 2, 2), strides=None, padding='valid',
|
||||
data_format=None, **kwargs):
|
||||
super(MaxPooling3D, self).__init__(pool_size, strides, padding,
|
||||
@@ -419,7 +425,6 @@ class AveragePooling3D(_Pooling3D):
|
||||
`(batch_size, channels, pooled_dim1, pooled_dim2, pooled_dim3)`
|
||||
"""
|
||||
|
||||
@interfaces.legacy_pooling3d_support
|
||||
def __init__(self, pool_size=(2, 2, 2), strides=None, padding='valid',
|
||||
data_format=None, **kwargs):
|
||||
super(AveragePooling3D, self).__init__(pool_size, strides, padding,
|
||||
@@ -441,8 +446,9 @@ class _GlobalPooling1D(Layer):
|
||||
super(_GlobalPooling1D, self).__init__(**kwargs)
|
||||
self.input_spec = InputSpec(ndim=3)
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
return (input_shape[0], input_shape[2])
|
||||
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
|
||||
@@ -482,17 +488,17 @@ class _GlobalPooling2D(Layer):
|
||||
"""Abstract class for different global pooling 2D layers.
|
||||
"""
|
||||
|
||||
@interfaces.legacy_global_pooling_support
|
||||
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):
|
||||
def _compute_output_shape(self, input_shape):
|
||||
input_shape = tensor_shape.TensorShape(input_shape).as_list()
|
||||
if self.data_format == 'channels_last':
|
||||
return (input_shape[0], input_shape[3])
|
||||
return tensor_shape.TensorShape([input_shape[0], input_shape[3]])
|
||||
else:
|
||||
return (input_shape[0], input_shape[1])
|
||||
return tensor_shape.TensorShape([input_shape[0], input_shape[1]])
|
||||
|
||||
def call(self, inputs):
|
||||
raise NotImplementedError
|
||||
@@ -577,17 +583,17 @@ class _GlobalPooling3D(Layer):
|
||||
"""Abstract class for different global pooling 3D layers.
|
||||
"""
|
||||
|
||||
@interfaces.legacy_global_pooling_support
|
||||
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):
|
||||
def _compute_output_shape(self, input_shape):
|
||||
input_shape = tensor_shape.TensorShape(input_shape).as_list()
|
||||
if self.data_format == 'channels_last':
|
||||
return (input_shape[0], input_shape[4])
|
||||
return tensor_shape.TensorShape([input_shape[0], input_shape[4]])
|
||||
else:
|
||||
return (input_shape[0], input_shape[1])
|
||||
return tensor_shape.TensorShape([input_shape[0], input_shape[1]])
|
||||
|
||||
def call(self, inputs):
|
||||
raise NotImplementedError
|
||||
|
||||
+69
-130
@@ -1,16 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Recurrent layers.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
import numpy as np
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from .. import backend as K
|
||||
from .. import activations
|
||||
from .. import backend as K
|
||||
from .. import constraints
|
||||
from .. import initializers
|
||||
from .. import regularizers
|
||||
from .. import constraints
|
||||
from ..engine import Layer
|
||||
from ..engine import InputSpec
|
||||
from ..legacy import interfaces
|
||||
|
||||
from ..engine import Layer
|
||||
import numpy as np
|
||||
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,
|
||||
@@ -96,8 +100,6 @@ class Recurrent(Layer):
|
||||
`[(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.
|
||||
@@ -141,9 +143,6 @@ class Recurrent(Layer):
|
||||
(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)`.
|
||||
@@ -151,7 +150,7 @@ class Recurrent(Layer):
|
||||
# Masking
|
||||
This layer supports masking for input data with a variable number
|
||||
of timesteps. To introduce masks to your data,
|
||||
use an [Embedding](embeddings.md) layer with the `mask_zero` parameter
|
||||
use an `Embedding` layer with the `mask_zero` parameter
|
||||
set to `True`.
|
||||
|
||||
# Note on using statefulness in RNNs
|
||||
@@ -188,7 +187,6 @@ class Recurrent(Layer):
|
||||
"""
|
||||
|
||||
def __init__(self, return_sequences=False,
|
||||
return_state=False,
|
||||
go_backwards=False,
|
||||
stateful=False,
|
||||
unroll=False,
|
||||
@@ -196,11 +194,7 @@ class Recurrent(Layer):
|
||||
**kwargs):
|
||||
super(Recurrent, self).__init__(**kwargs)
|
||||
self.return_sequences = return_sequences
|
||||
self.return_state = return_state
|
||||
self.go_backwards = go_backwards
|
||||
if K.backend() == 'cntk' and stateful:
|
||||
raise ValueError('Stateful RNN is not currently supported with CNTK.')
|
||||
|
||||
self.stateful = stateful
|
||||
self.unroll = unroll
|
||||
self.implementation = implementation
|
||||
@@ -210,30 +204,22 @@ class Recurrent(Layer):
|
||||
self.dropout = 0
|
||||
self.recurrent_dropout = 0
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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)
|
||||
return tensor_shape.TensorShape([input_shape[0], input_shape[1], self.units])
|
||||
else:
|
||||
output_shape = (input_shape[0], self.units)
|
||||
|
||||
if self.return_state:
|
||||
state_shape = [(input_shape[0], self.units) for _ in self.states]
|
||||
return [output_shape] + state_shape
|
||||
else:
|
||||
return output_shape
|
||||
return tensor_shape.TensorShape([input_shape[0], self.units])
|
||||
|
||||
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
|
||||
if self.return_sequences:
|
||||
if isinstance(mask, list):
|
||||
return mask[0]
|
||||
return mask
|
||||
else:
|
||||
return output_mask
|
||||
return None
|
||||
|
||||
def step(self, inputs, states):
|
||||
raise NotImplementedError
|
||||
@@ -337,8 +323,7 @@ class Recurrent(Layer):
|
||||
go_backwards=self.go_backwards,
|
||||
mask=mask,
|
||||
constants=constants,
|
||||
unroll=self.unroll,
|
||||
input_length=input_shape[1])
|
||||
unroll=self.unroll)
|
||||
if self.stateful:
|
||||
updates = []
|
||||
for i in range(len(states)):
|
||||
@@ -351,18 +336,9 @@ class Recurrent(Layer):
|
||||
outputs._uses_learning_phase = True
|
||||
|
||||
if self.return_sequences:
|
||||
output = outputs
|
||||
return outputs
|
||||
else:
|
||||
output = last_output
|
||||
|
||||
if self.return_state:
|
||||
if not isinstance(states, (list, tuple)):
|
||||
states = [states]
|
||||
else:
|
||||
states = list(states)
|
||||
return [output] + states
|
||||
else:
|
||||
return output
|
||||
return last_output
|
||||
|
||||
def reset_states(self, states=None):
|
||||
if not self.stateful:
|
||||
@@ -406,7 +382,6 @@ class Recurrent(Layer):
|
||||
|
||||
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,
|
||||
@@ -420,39 +395,29 @@ class SimpleRNN(Recurrent):
|
||||
|
||||
# Arguments
|
||||
units: Positive integer, dimensionality of the output space.
|
||||
activation: Activation function to use
|
||||
(see [activations](../activations.md)).
|
||||
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.
|
||||
(see [initializers](../initializers.md)).
|
||||
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.
|
||||
(see [initializers](../initializers.md)).
|
||||
bias_initializer: Initializer for the bias vector
|
||||
(see [initializers](../initializers.md)).
|
||||
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
|
||||
(see [regularizer](../regularizers.md)).
|
||||
the `kernel` weights matrix.
|
||||
recurrent_regularizer: Regularizer function applied to
|
||||
the `recurrent_kernel` weights matrix
|
||||
(see [regularizer](../regularizers.md)).
|
||||
bias_regularizer: Regularizer function applied to the bias vector
|
||||
(see [regularizer](../regularizers.md)).
|
||||
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").
|
||||
(see [regularizer](../regularizers.md)).
|
||||
the output of the layer (its "activation")..
|
||||
kernel_constraint: Constraint function applied to
|
||||
the `kernel` weights matrix
|
||||
(see [constraints](../constraints.md)).
|
||||
the `kernel` weights matrix.
|
||||
recurrent_constraint: Constraint function applied to
|
||||
the `recurrent_kernel` weights matrix
|
||||
(see [constraints](../constraints.md)).
|
||||
bias_constraint: Constraint function applied to the bias vector
|
||||
(see [constraints](../constraints.md)).
|
||||
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.
|
||||
@@ -464,7 +429,6 @@ class SimpleRNN(Recurrent):
|
||||
- [A Theoretically Grounded Application of Dropout in Recurrent Neural Networks](http://arxiv.org/abs/1512.05287)
|
||||
"""
|
||||
|
||||
@interfaces.legacy_recurrent_support
|
||||
def __init__(self, units,
|
||||
activation='tanh',
|
||||
use_bias=True,
|
||||
@@ -506,6 +470,7 @@ class SimpleRNN(Recurrent):
|
||||
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]
|
||||
@@ -540,7 +505,7 @@ class SimpleRNN(Recurrent):
|
||||
if self.implementation > 0:
|
||||
return inputs
|
||||
else:
|
||||
input_shape = K.int_shape(inputs)
|
||||
input_shape = inputs.get_shape().as_list()
|
||||
input_dim = input_shape[2]
|
||||
timesteps = input_shape[1]
|
||||
return _time_distributed_dense(inputs,
|
||||
@@ -597,7 +562,7 @@ class SimpleRNN(Recurrent):
|
||||
ones = K.ones_like(K.reshape(inputs[:, 0, 0], (-1, 1)))
|
||||
ones = K.tile(ones, (1, self.units))
|
||||
|
||||
def dropped_inputs():
|
||||
def dropped_inputs(): # pylint: disable=function-redefined
|
||||
return K.dropout(ones, self.recurrent_dropout)
|
||||
rec_dp_mask = K.in_train_phase(dropped_inputs,
|
||||
ones,
|
||||
@@ -632,42 +597,30 @@ class GRU(Recurrent):
|
||||
|
||||
# Arguments
|
||||
units: Positive integer, dimensionality of the output space.
|
||||
activation: Activation function to use
|
||||
(see [activations](../activations.md)).
|
||||
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
|
||||
(see [activations](../activations.md)).
|
||||
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.
|
||||
(see [initializers](../initializers.md)).
|
||||
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.
|
||||
(see [initializers](../initializers.md)).
|
||||
bias_initializer: Initializer for the bias vector
|
||||
(see [initializers](../initializers.md)).
|
||||
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
|
||||
(see [regularizer](../regularizers.md)).
|
||||
the `kernel` weights matrix.
|
||||
recurrent_regularizer: Regularizer function applied to
|
||||
the `recurrent_kernel` weights matrix
|
||||
(see [regularizer](../regularizers.md)).
|
||||
bias_regularizer: Regularizer function applied to the bias vector
|
||||
(see [regularizer](../regularizers.md)).
|
||||
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").
|
||||
(see [regularizer](../regularizers.md)).
|
||||
the output of the layer (its "activation")..
|
||||
kernel_constraint: Constraint function applied to
|
||||
the `kernel` weights matrix
|
||||
(see [constraints](../constraints.md)).
|
||||
the `kernel` weights matrix.
|
||||
recurrent_constraint: Constraint function applied to
|
||||
the `recurrent_kernel` weights matrix
|
||||
(see [constraints](../constraints.md)).
|
||||
bias_constraint: Constraint function applied to the bias vector
|
||||
(see [constraints](../constraints.md)).
|
||||
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.
|
||||
@@ -681,7 +634,6 @@ class GRU(Recurrent):
|
||||
- [A Theoretically Grounded Application of Dropout in Recurrent Neural Networks](http://arxiv.org/abs/1512.05287)
|
||||
"""
|
||||
|
||||
@interfaces.legacy_recurrent_support
|
||||
def __init__(self, units,
|
||||
activation='tanh',
|
||||
recurrent_activation='hard_sigmoid',
|
||||
@@ -725,7 +677,7 @@ class GRU(Recurrent):
|
||||
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))
|
||||
@@ -776,7 +728,7 @@ class GRU(Recurrent):
|
||||
|
||||
def preprocess_input(self, inputs, training=None):
|
||||
if self.implementation == 0:
|
||||
input_shape = K.int_shape(inputs)
|
||||
input_shape = inputs.get_shape().as_list()
|
||||
input_dim = input_shape[2]
|
||||
timesteps = input_shape[1]
|
||||
|
||||
@@ -815,7 +767,7 @@ class GRU(Recurrent):
|
||||
ones = K.ones_like(K.reshape(inputs[:, 0, 0], (-1, 1)))
|
||||
ones = K.tile(ones, (1, self.units))
|
||||
|
||||
def dropped_inputs():
|
||||
def dropped_inputs(): # pylint: disable=function-redefined
|
||||
return K.dropout(ones, self.recurrent_dropout)
|
||||
rec_dp_mask = [K.in_train_phase(dropped_inputs,
|
||||
ones,
|
||||
@@ -905,46 +857,34 @@ class LSTM(Recurrent):
|
||||
|
||||
# Arguments
|
||||
units: Positive integer, dimensionality of the output space.
|
||||
activation: Activation function to use
|
||||
(see [activations](../activations.md)).
|
||||
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
|
||||
(see [activations](../activations.md)).
|
||||
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.
|
||||
(see [initializers](../initializers.md)).
|
||||
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.
|
||||
(see [initializers](../initializers.md)).
|
||||
bias_initializer: Initializer for the bias vector
|
||||
(see [initializers](../initializers.md)).
|
||||
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
|
||||
(see [regularizer](../regularizers.md)).
|
||||
the `kernel` weights matrix.
|
||||
recurrent_regularizer: Regularizer function applied to
|
||||
the `recurrent_kernel` weights matrix
|
||||
(see [regularizer](../regularizers.md)).
|
||||
bias_regularizer: Regularizer function applied to the bias vector
|
||||
(see [regularizer](../regularizers.md)).
|
||||
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").
|
||||
(see [regularizer](../regularizers.md)).
|
||||
the output of the layer (its "activation")..
|
||||
kernel_constraint: Constraint function applied to
|
||||
the `kernel` weights matrix
|
||||
(see [constraints](../constraints.md)).
|
||||
the `kernel` weights matrix.
|
||||
recurrent_constraint: Constraint function applied to
|
||||
the `recurrent_kernel` weights matrix
|
||||
(see [constraints](../constraints.md)).
|
||||
bias_constraint: Constraint function applied to the bias vector
|
||||
(see [constraints](../constraints.md)).
|
||||
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.
|
||||
@@ -954,11 +894,10 @@ class LSTM(Recurrent):
|
||||
|
||||
# References
|
||||
- [Long short-term memory](http://deeplearning.cs.cmu.edu/pdfs/Hochreiter97_lstm.pdf) (original 1997 paper)
|
||||
- [Learning to forget: Continual prediction with LSTM](http://www.mitpressjournals.org/doi/pdf/10.1162/089976600300015015)
|
||||
- [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)
|
||||
"""
|
||||
@interfaces.legacy_recurrent_support
|
||||
|
||||
def __init__(self, units,
|
||||
activation='tanh',
|
||||
recurrent_activation='hard_sigmoid',
|
||||
@@ -1005,7 +944,7 @@ class LSTM(Recurrent):
|
||||
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))
|
||||
@@ -1068,7 +1007,7 @@ class LSTM(Recurrent):
|
||||
|
||||
def preprocess_input(self, inputs, training=None):
|
||||
if self.implementation == 0:
|
||||
input_shape = K.int_shape(inputs)
|
||||
input_shape = inputs.get_shape().as_list()
|
||||
input_dim = input_shape[2]
|
||||
timesteps = input_shape[1]
|
||||
|
||||
@@ -1110,7 +1049,7 @@ class LSTM(Recurrent):
|
||||
ones = K.ones_like(K.reshape(inputs[:, 0, 0], (-1, 1)))
|
||||
ones = K.tile(ones, (1, self.units))
|
||||
|
||||
def dropped_inputs():
|
||||
def dropped_inputs(): # pylint: disable=function-redefined
|
||||
return K.dropout(ones, self.recurrent_dropout)
|
||||
rec_dp_mask = [K.in_train_phase(dropped_inputs,
|
||||
ones,
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
"""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 .advanced_activations import *
|
||||
from .convolutional import *
|
||||
from .convolutional_recurrent import *
|
||||
from .core import *
|
||||
from .embeddings import *
|
||||
from ..engine import Input
|
||||
from ..engine import InputLayer
|
||||
from .local import *
|
||||
from .merge import *
|
||||
from .noise import *
|
||||
from .normalization import *
|
||||
from .pooling import *
|
||||
from .recurrent import *
|
||||
from ..utils.generic_utils import deserialize_keras_object
|
||||
from .wrappers import *
|
||||
|
||||
|
||||
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 .. 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')
|
||||
+27
-15
@@ -1,11 +1,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""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
|
||||
import inspect
|
||||
from ..engine import Layer
|
||||
from ..engine import InputSpec
|
||||
from .. import backend as K
|
||||
from tensorflow.python.framework import tensor_shape
|
||||
|
||||
|
||||
class Wrapper(Layer):
|
||||
@@ -83,8 +88,9 @@ class Wrapper(Layer):
|
||||
|
||||
@classmethod
|
||||
def from_config(cls, config, custom_objects=None):
|
||||
from . import deserialize as deserialize_layer
|
||||
layer = deserialize_layer(config.pop('layer'), custom_objects=custom_objects)
|
||||
from . 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)
|
||||
|
||||
|
||||
@@ -138,19 +144,24 @@ class TimeDistributed(Wrapper):
|
||||
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:]
|
||||
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()
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
child_input_shape = (input_shape[0],) + input_shape[2:]
|
||||
child_output_shape = self.layer.compute_output_shape(child_input_shape)
|
||||
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 (child_output_shape[0], timesteps) + child_output_shape[1:]
|
||||
return tensor_shape.TensorShape(
|
||||
[child_output_shape[0], timesteps] + child_output_shape[1:])
|
||||
|
||||
def call(self, inputs, mask=None):
|
||||
input_shape = K.int_shape(inputs)
|
||||
@@ -162,7 +173,6 @@ class TimeDistributed(Wrapper):
|
||||
|
||||
_, outputs, _ = K.rnn(step, inputs,
|
||||
initial_states=[],
|
||||
input_length=input_shape[1],
|
||||
unroll=False)
|
||||
y = outputs
|
||||
else:
|
||||
@@ -176,8 +186,8 @@ class TimeDistributed(Wrapper):
|
||||
inputs = K.reshape(inputs, (-1,) + input_shape[2:])
|
||||
y = self.layer.call(inputs) # (num_samples * timesteps, ...)
|
||||
# Shape: (num_samples, timesteps, ...)
|
||||
output_shape = self.compute_output_shape(input_shape)
|
||||
y = K.reshape(y, (-1, input_length) + output_shape[2:])
|
||||
output_shape = self._compute_output_shape(input_shape).as_list() # pylint: disable=protected-access
|
||||
y = K.reshape(y, [-1, input_length] + output_shape[2:])
|
||||
|
||||
# Apply activity regularizer if any:
|
||||
if (hasattr(self.layer, 'activity_regularizer') and
|
||||
@@ -242,15 +252,17 @@ class Bidirectional(Wrapper):
|
||||
self.forward_layer.set_weights(weights[:nw // 2])
|
||||
self.backward_layer.set_weights(weights[nw // 2:])
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
def _compute_output_shape(self, input_shape):
|
||||
input_shape = tensor_shape.TensorShape(input_shape).as_list()
|
||||
if self.merge_mode in ['sum', 'ave', 'mul']:
|
||||
return self.forward_layer.compute_output_shape(input_shape)
|
||||
return self.forward_layer._compute_output_shape(input_shape) # pylint: disable=protected-access
|
||||
elif self.merge_mode == 'concat':
|
||||
shape = list(self.forward_layer.compute_output_shape(input_shape))
|
||||
shape = self.forward_layer._compute_output_shape(input_shape).as_list() # pylint: disable=protected-access
|
||||
shape[-1] *= 2
|
||||
return tuple(shape)
|
||||
return tensor_shape.TensorShape(shape)
|
||||
elif self.merge_mode is None:
|
||||
return [self.forward_layer.compute_output_shape(input_shape)] * 2
|
||||
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 = {}
|
||||
|
||||
@@ -161,7 +161,7 @@ def recurrent_args_preprocessor(args, kwargs):
|
||||
kwargs.pop('forget_bias_init')
|
||||
warnings.warn('The `forget_bias_init` argument '
|
||||
'has been ignored. Use `unit_forget_bias=True` '
|
||||
'instead to initialize with ones.', stacklevel=3)
|
||||
'instead to intialize with ones.', stacklevel=3)
|
||||
if 'input_dim' in kwargs:
|
||||
input_length = kwargs.pop('input_length', None)
|
||||
input_dim = kwargs.pop('input_dim')
|
||||
@@ -461,7 +461,7 @@ def convlstm2d_args_preprocessor(args, kwargs):
|
||||
else:
|
||||
warnings.warn('The `forget_bias_init` argument '
|
||||
'has been ignored. Use `unit_forget_bias=True` '
|
||||
'instead to initialize with ones.', stacklevel=3)
|
||||
'instead to intialize with ones.', stacklevel=3)
|
||||
args, kwargs, _converted = conv2d_args_preprocessor(args, kwargs)
|
||||
return args, kwargs, converted + _converted
|
||||
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
from .layers import Merge
|
||||
|
||||
|
||||
def needs_legacy_support(model):
|
||||
return isinstance(model.layers[0], Merge)
|
||||
|
||||
|
||||
def legacy_sequential_layers(model):
|
||||
layers = []
|
||||
if model.layers:
|
||||
if isinstance(model.layers[0], Merge):
|
||||
merge = model.layers[0]
|
||||
for layer in merge.layers:
|
||||
if hasattr(layer, 'layers'):
|
||||
for sublayer in layer.layers:
|
||||
if sublayer not in layers:
|
||||
layers.append(sublayer)
|
||||
else:
|
||||
if layer not in layers:
|
||||
layers.append(layer)
|
||||
else:
|
||||
if model.layers[0] not in layers:
|
||||
layers.append(model.layers[0])
|
||||
for layer in model.layers[1:]:
|
||||
if layer not in layers:
|
||||
layers.append(layer)
|
||||
return layers
|
||||
+9
-3
@@ -1,6 +1,11 @@
|
||||
"""Built-in Keras loss functions.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
import six
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from . import backend as K
|
||||
import six
|
||||
from .utils.generic_utils import deserialize_keras_object
|
||||
|
||||
|
||||
@@ -13,6 +18,7 @@ def mean_absolute_error(y_true, y_pred):
|
||||
|
||||
|
||||
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))
|
||||
@@ -35,8 +41,8 @@ def hinge(y_true, y_pred):
|
||||
|
||||
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(0., neg - pos + 1.)
|
||||
neg = K.max((1.0 - y_true) * y_pred, axis=-1)
|
||||
return K.mean(K.maximum(0.0, neg - pos + 1), axis=-1)
|
||||
|
||||
|
||||
def logcosh(y_true, y_pred):
|
||||
|
||||
+16
-14
@@ -1,19 +1,26 @@
|
||||
"""Built-in Keras metrics functions.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
import six
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from . import backend as K
|
||||
from .losses import mean_squared_error
|
||||
# pylint: disable=unused-import
|
||||
from .losses import binary_crossentropy
|
||||
from .losses import categorical_crossentropy
|
||||
from .losses import cosine_proximity
|
||||
from .losses import hinge
|
||||
from .losses import kullback_leibler_divergence
|
||||
from .losses import mean_absolute_error
|
||||
from .losses import mean_absolute_percentage_error
|
||||
from .losses import mean_squared_error
|
||||
from .losses import mean_squared_logarithmic_error
|
||||
from .losses import hinge
|
||||
from .losses import logcosh
|
||||
from .losses import squared_hinge
|
||||
from .losses import categorical_crossentropy
|
||||
from .losses import sparse_categorical_crossentropy
|
||||
from .losses import binary_crossentropy
|
||||
from .losses import kullback_leibler_divergence
|
||||
from .losses import poisson
|
||||
from .losses import cosine_proximity
|
||||
from .losses import sparse_categorical_crossentropy
|
||||
from .losses import squared_hinge
|
||||
# pylint: disable=unused-import
|
||||
import six
|
||||
from .utils.generic_utils import deserialize_keras_object
|
||||
|
||||
|
||||
@@ -36,11 +43,6 @@ def sparse_categorical_accuracy(y_true, y_pred):
|
||||
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
|
||||
|
||||
+83
-230
@@ -1,31 +1,37 @@
|
||||
"""Home of the Sequential model, and the `save_model`/`load_model` functions.
|
||||
"""
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import warnings
|
||||
import copy
|
||||
import json
|
||||
import os
|
||||
import yaml
|
||||
import numpy as np
|
||||
import warnings
|
||||
|
||||
from . import backend as K
|
||||
from . import optimizers
|
||||
from . import layers as layer_module
|
||||
from .utils.io_utils import ask_to_proceed_with_overwrite
|
||||
from .engine.training import Model
|
||||
from . import optimizers
|
||||
from .engine import topology
|
||||
from .engine.topology import Layer
|
||||
from .engine.topology import Input
|
||||
from .legacy import layers as legacy_layers
|
||||
from .legacy import models as legacy_models
|
||||
from .legacy import interfaces
|
||||
from .engine.topology import Layer
|
||||
from .engine.training import Model
|
||||
import numpy as np
|
||||
from .utils.io_utils import ask_to_proceed_with_overwrite
|
||||
|
||||
# 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.
|
||||
@@ -74,11 +80,7 @@ def save_model(model, filepath, overwrite=True, include_optimizer=True):
|
||||
|
||||
# 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()
|
||||
return obj.item()
|
||||
|
||||
# misc functions (e.g. loss function)
|
||||
if callable(obj):
|
||||
@@ -90,7 +92,7 @@ def save_model(model, filepath, overwrite=True, include_optimizer=True):
|
||||
|
||||
raise TypeError('Not JSON Serializable:', obj)
|
||||
|
||||
from . import __version__ as keras_version
|
||||
from . 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):
|
||||
@@ -107,10 +109,7 @@ def save_model(model, filepath, overwrite=True, include_optimizer=True):
|
||||
}, default=get_json_type).encode('utf8')
|
||||
|
||||
model_weights_group = f.create_group('model_weights')
|
||||
if legacy_models.needs_legacy_support(model):
|
||||
model_layers = legacy_models.legacy_sequential_layers(model)
|
||||
else:
|
||||
model_layers = model.layers
|
||||
model_layers = model.layers
|
||||
topology.save_weights_to_hdf5_group(model_weights_group, model_layers)
|
||||
|
||||
if include_optimizer and hasattr(model, 'optimizer'):
|
||||
@@ -144,8 +143,8 @@ def save_model(model, filepath, overwrite=True, include_optimizer=True):
|
||||
weight_values = K.batch_get_value(symbolic_weights)
|
||||
weight_names = []
|
||||
for i, (w, val) in enumerate(zip(symbolic_weights, weight_values)):
|
||||
# Default values of symbolic_weights is /variable for theano and cntk
|
||||
if K.backend() == 'theano' or K.backend() == 'cntk':
|
||||
# Default values of symbolic_weights is /variable for theano
|
||||
if K.backend() == 'theano':
|
||||
if hasattr(w, 'name') and w.name != "/variable":
|
||||
name = str(w.name)
|
||||
else:
|
||||
@@ -237,58 +236,61 @@ def load_model(filepath, custom_objects=None, compile=True):
|
||||
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)
|
||||
f = h5py.File(filepath, mode='r')
|
||||
|
||||
# Early return if compilation is not required.
|
||||
if not compile:
|
||||
return model
|
||||
# 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)
|
||||
|
||||
# instantiate optimizer
|
||||
training_config = f.attrs.get('training_config')
|
||||
if training_config is None:
|
||||
warnings.warn('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)
|
||||
# set weights
|
||||
topology.load_weights_from_hdf5_group(f['model_weights'], model.layers)
|
||||
|
||||
# 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']
|
||||
# Early return if compilation is not required.
|
||||
if not compile:
|
||||
f.close()
|
||||
return model
|
||||
|
||||
# Compile model.
|
||||
model.compile(optimizer=optimizer,
|
||||
loss=loss,
|
||||
metrics=metrics,
|
||||
loss_weights=loss_weights,
|
||||
sample_weight_mode=sample_weight_mode)
|
||||
# instantiate optimizer
|
||||
training_config = f.attrs.get('training_config')
|
||||
if training_config is None:
|
||||
warnings.warn('No training configuration found in save file: '
|
||||
'the model was *not* compiled. Compile it manually.')
|
||||
f.close()
|
||||
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)
|
||||
|
||||
# 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]
|
||||
model.optimizer.set_weights(optimizer_weight_values)
|
||||
# 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]
|
||||
model.optimizer.set_weights(optimizer_weight_values)
|
||||
f.close()
|
||||
return model
|
||||
|
||||
|
||||
@@ -305,7 +307,7 @@ def model_from_config(config, custom_objects=None):
|
||||
A Keras model instance (uncompiled).
|
||||
|
||||
# Raises
|
||||
TypeError: if `config` is not a dictionary.
|
||||
TypeError if `config` is not a dictionary
|
||||
"""
|
||||
if isinstance(config, list):
|
||||
raise TypeError('`model_from_config` expects a dictionary, not a list. '
|
||||
@@ -325,7 +327,12 @@ def model_from_yaml(yaml_string, custom_objects=None):
|
||||
|
||||
# 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)
|
||||
|
||||
@@ -469,9 +476,7 @@ class Sequential(Model):
|
||||
output_tensors=self.outputs,
|
||||
# no model-level masking for now
|
||||
input_masks=[None for _ in self.inputs],
|
||||
output_masks=[None],
|
||||
input_shapes=[x._keras_shape for x in self.inputs],
|
||||
output_shapes=[self.outputs[0]._keras_shape])
|
||||
output_masks=[None])
|
||||
else:
|
||||
output_tensor = layer(self.outputs[0])
|
||||
if isinstance(output_tensor, list):
|
||||
@@ -482,7 +487,7 @@ class Sequential(Model):
|
||||
self.outputs = [output_tensor]
|
||||
# update self.inbound_nodes
|
||||
self.inbound_nodes[0].output_tensors = self.outputs
|
||||
self.inbound_nodes[0].output_shapes = [self.outputs[0]._keras_shape]
|
||||
self.inbound_nodes[0].output_shapes = [K.int_shape(self.outputs[0])]
|
||||
|
||||
self.layers.append(layer)
|
||||
self.built = False
|
||||
@@ -506,7 +511,7 @@ class Sequential(Model):
|
||||
self.outputs = [self.layers[-1].output]
|
||||
# update self.inbound_nodes
|
||||
self.inbound_nodes[0].output_tensors = self.outputs
|
||||
self.inbound_nodes[0].output_shapes = [self.outputs[0]._keras_shape]
|
||||
self.inbound_nodes[0].output_shapes = [K.int_shape(self.outputs[0])]
|
||||
self.built = False
|
||||
|
||||
def get_layer(self, name=None, index=None):
|
||||
@@ -571,36 +576,9 @@ class Sequential(Model):
|
||||
self.build()
|
||||
return self.model.uses_learning_phase
|
||||
|
||||
@property
|
||||
def _flattened_layers(self):
|
||||
layers = []
|
||||
if self.layers:
|
||||
# Support for legacy models
|
||||
if isinstance(self.layers[0], legacy_layers.Merge):
|
||||
merge = self.layers[0]
|
||||
for layer in merge.layers:
|
||||
if hasattr(layer, '_flattened_layers'):
|
||||
for sublayer in layer._flattened_layers:
|
||||
if sublayer not in layers:
|
||||
layers.append(sublayer)
|
||||
elif hasattr(layer, 'layers'):
|
||||
for sublayer in layer.layers:
|
||||
if sublayer not in layers:
|
||||
layers.append(sublayer)
|
||||
else:
|
||||
if layer not in layers:
|
||||
layers.append(layer)
|
||||
else:
|
||||
if self.layers[0] not in layers:
|
||||
layers.append(self.layers[0])
|
||||
for layer in self.layers[1:]:
|
||||
if layer not in layers:
|
||||
layers.append(layer)
|
||||
return layers
|
||||
|
||||
def _gather_list_attr(self, attr):
|
||||
all_attrs = []
|
||||
for layer in self._flattened_layers:
|
||||
for layer in self.layers:
|
||||
all_attrs += getattr(layer, attr, [])
|
||||
return all_attrs
|
||||
|
||||
@@ -618,12 +596,10 @@ class Sequential(Model):
|
||||
def trainable_weights(self):
|
||||
if not self.trainable:
|
||||
return []
|
||||
# Support for legacy behavior
|
||||
return self._gather_list_attr('trainable_weights')
|
||||
|
||||
@property
|
||||
def non_trainable_weights(self):
|
||||
# Support for legacy behavior
|
||||
weights = self._gather_list_attr('non_trainable_weights')
|
||||
if not self.trainable:
|
||||
trainable_weights = self._gather_list_attr('trainable_weights')
|
||||
@@ -677,14 +653,6 @@ class Sequential(Model):
|
||||
A flat list of Numpy arrays
|
||||
(one array per model weight).
|
||||
"""
|
||||
# Legacy support
|
||||
if legacy_models.needs_legacy_support(self):
|
||||
layers = legacy_models.legacy_sequential_layers(self)
|
||||
weights = []
|
||||
for layer in layers:
|
||||
weights.append(layer.get_weights())
|
||||
return weights
|
||||
|
||||
if self.model is None:
|
||||
self.build()
|
||||
return self.model.get_weights()
|
||||
@@ -697,14 +665,6 @@ class Sequential(Model):
|
||||
of Numpy arrays with shapes and types matching
|
||||
the output of `model.get_weights()`.
|
||||
"""
|
||||
# Legacy support
|
||||
if legacy_models.needs_legacy_support(self):
|
||||
layers = legacy_models.legacy_sequential_layers(self)
|
||||
for layer in layers:
|
||||
nb_param = len(layer.weights)
|
||||
layer.set_weights(weights[:nb_param])
|
||||
weights = weights[nb_param:]
|
||||
|
||||
if self.model is None:
|
||||
self.build()
|
||||
self.model.set_weights(weights)
|
||||
@@ -715,12 +675,7 @@ class Sequential(Model):
|
||||
f = h5py.File(filepath, mode='r')
|
||||
if 'layer_names' not in f.attrs and 'model_weights' in f:
|
||||
f = f['model_weights']
|
||||
|
||||
# Legacy support
|
||||
if legacy_models.needs_legacy_support(self):
|
||||
layers = legacy_models.legacy_sequential_layers(self)
|
||||
else:
|
||||
layers = self.layers
|
||||
layers = self.layers
|
||||
if by_name:
|
||||
topology.load_weights_from_hdf5_group_by_name(f, layers)
|
||||
else:
|
||||
@@ -736,12 +691,7 @@ class Sequential(Model):
|
||||
proceed = ask_to_proceed_with_overwrite(filepath)
|
||||
if not proceed:
|
||||
return
|
||||
# Legacy support
|
||||
if legacy_models.needs_legacy_support(self):
|
||||
layers = legacy_models.legacy_sequential_layers(self)
|
||||
else:
|
||||
layers = self.layers
|
||||
|
||||
layers = self.layers
|
||||
f = h5py.File(filepath, 'w')
|
||||
topology.save_weights_to_hdf5_group(f, layers)
|
||||
f.flush()
|
||||
@@ -799,7 +749,7 @@ class Sequential(Model):
|
||||
|
||||
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, **kwargs):
|
||||
class_weight=None, sample_weight=None, initial_epoch=0):
|
||||
"""Trains the model for a fixed number of epochs.
|
||||
|
||||
# Arguments
|
||||
@@ -846,14 +796,6 @@ class Sequential(Model):
|
||||
# Raises
|
||||
RuntimeError: if the model was never compiled.
|
||||
"""
|
||||
# Legacy support
|
||||
if 'nb_epoch' in kwargs:
|
||||
warnings.warn('The `nb_epoch` argument in `fit` '
|
||||
'has been renamed `epochs`.')
|
||||
epochs = kwargs.pop('nb_epoch')
|
||||
if kwargs:
|
||||
raise TypeError('Unrecognized keyword arguments: ' + str(kwargs))
|
||||
|
||||
if self.model is None:
|
||||
raise RuntimeError('The model needs to be compiled '
|
||||
'before being used.')
|
||||
@@ -1024,7 +966,6 @@ class Sequential(Model):
|
||||
else:
|
||||
return (proba > 0.5).astype('int32')
|
||||
|
||||
@interfaces.legacy_generator_methods_support
|
||||
def fit_generator(self, generator,
|
||||
steps_per_epoch,
|
||||
epochs=1,
|
||||
@@ -1123,7 +1064,6 @@ class Sequential(Model):
|
||||
pickle_safe=pickle_safe,
|
||||
initial_epoch=initial_epoch)
|
||||
|
||||
@interfaces.legacy_generator_methods_support
|
||||
def evaluate_generator(self, generator, steps,
|
||||
max_q_size=10, workers=1,
|
||||
pickle_safe=False):
|
||||
@@ -1163,7 +1103,6 @@ class Sequential(Model):
|
||||
workers=workers,
|
||||
pickle_safe=pickle_safe)
|
||||
|
||||
@interfaces.legacy_generator_methods_support
|
||||
def predict_generator(self, generator, steps,
|
||||
max_q_size=10, workers=1,
|
||||
pickle_safe=False, verbose=0):
|
||||
@@ -1197,9 +1136,6 @@ class Sequential(Model):
|
||||
verbose=verbose)
|
||||
|
||||
def get_config(self):
|
||||
if isinstance(self.layers[0], legacy_layers.Merge):
|
||||
return self.legacy_get_config()
|
||||
|
||||
config = []
|
||||
for layer in self.layers:
|
||||
config.append({'class_name': layer.__class__.__name__,
|
||||
@@ -1208,91 +1144,8 @@ class Sequential(Model):
|
||||
|
||||
@classmethod
|
||||
def from_config(cls, config, custom_objects=None):
|
||||
if 'class_name' not in config[0] or config[0]['class_name'] == 'Merge':
|
||||
return cls.legacy_from_config(config)
|
||||
|
||||
model = cls()
|
||||
for conf in config:
|
||||
layer = layer_module.deserialize(conf, custom_objects=custom_objects)
|
||||
model.add(layer)
|
||||
return model
|
||||
|
||||
def legacy_get_config(self):
|
||||
"""Retrieves the model configuration as a Python list.
|
||||
|
||||
# Returns
|
||||
A list of dicts (each dict is a layer config).
|
||||
"""
|
||||
config = []
|
||||
if isinstance(self.layers[0], legacy_layers.Merge):
|
||||
assert hasattr(self.layers[0], 'layers')
|
||||
layers = []
|
||||
for layer in self.layers[0].layers:
|
||||
layer_config = {'class_name': layer.__class__.__name__,
|
||||
'config': layer.get_config()}
|
||||
layers.append(layer_config)
|
||||
merge_config = self.layers[0].get_config()
|
||||
merge_config['layers'] = layers
|
||||
config.append({'class_name': 'Merge', 'config': merge_config})
|
||||
else:
|
||||
config.append({'class_name': self.layers[0].__class__.__name__,
|
||||
'config': self.layers[0].get_config()})
|
||||
for layer in self.layers[1:]:
|
||||
config.append({'class_name': layer.__class__.__name__,
|
||||
'config': layer.get_config()})
|
||||
return copy.deepcopy(config)
|
||||
|
||||
@classmethod
|
||||
def legacy_from_config(cls, config, layer_cache=None):
|
||||
"""Load a model from a legacy configuration.
|
||||
|
||||
# Arguments
|
||||
config: dictionary with configuration.
|
||||
layer_cache: cache to draw pre-existing layer.
|
||||
|
||||
# Returns
|
||||
The loaded Model.
|
||||
"""
|
||||
if not layer_cache:
|
||||
layer_cache = {}
|
||||
|
||||
def normalize_legacy_config(conf):
|
||||
if 'class_name' not in conf:
|
||||
class_name = conf['name']
|
||||
name = conf.get('custom_name')
|
||||
conf['name'] = name
|
||||
return {'class_name': class_name,
|
||||
'config': conf}
|
||||
return conf
|
||||
|
||||
# the model we will return
|
||||
model = cls()
|
||||
|
||||
def get_or_create_layer(layer_data):
|
||||
name = layer_data['config'].get('name')
|
||||
if name in layer_cache:
|
||||
return layer_cache[name]
|
||||
layer = layer_module.deserialize(layer_data)
|
||||
layer_cache[name] = layer
|
||||
return layer
|
||||
|
||||
first_layer = config[0]
|
||||
first_layer = normalize_legacy_config(first_layer)
|
||||
if first_layer['class_name'] == 'Merge':
|
||||
merge_inputs = []
|
||||
first_layer_config = first_layer['config']
|
||||
for merge_input_config in first_layer_config.pop('layers'):
|
||||
merge_input = layer_module.deserialize(merge_input_config)
|
||||
merge_inputs.append(merge_input)
|
||||
first_layer_config['layers'] = merge_inputs
|
||||
merge = legacy_layers.Merge.from_config(first_layer_config)
|
||||
model.add(merge)
|
||||
else:
|
||||
layer = get_or_create_layer(first_layer)
|
||||
model.add(layer)
|
||||
|
||||
for conf in config[1:]:
|
||||
conf = normalize_legacy_config(conf)
|
||||
layer = get_or_create_layer(conf)
|
||||
model.add(layer)
|
||||
return model
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
"""Legacy objectives module.
|
||||
|
||||
Only kept for backwards API compatibility.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from .losses import *
|
||||
+35
-44
@@ -1,42 +1,20 @@
|
||||
"""Keras optimizer classes (will eventually be replaced with core optimizers).
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
import six
|
||||
import copy
|
||||
from six.moves import zip
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from . import backend as K
|
||||
from .utils.generic_utils import serialize_keras_object
|
||||
import six
|
||||
from six.moves import zip
|
||||
from tensorflow.python.training import optimizer as tf_optimizer_module
|
||||
from .utils.generic_utils import deserialize_keras_object
|
||||
|
||||
if K.backend() == 'tensorflow':
|
||||
import tensorflow as tf
|
||||
from .utils.generic_utils import serialize_keras_object
|
||||
|
||||
|
||||
def clip_norm(g, c, n):
|
||||
if c <= 0: # if clipnorm == 0 no need to add ops to the graph
|
||||
return g
|
||||
|
||||
# tf require using a special op to multiply IndexedSliced by scalar
|
||||
if K.backend() == 'tensorflow':
|
||||
condition = n >= c
|
||||
then_expression = tf.scalar_mul(c / n, g)
|
||||
else_expression = g
|
||||
|
||||
# saving the shape to avoid converting sparse tensor to dense
|
||||
if isinstance(then_expression, tf.Tensor):
|
||||
g_shape = copy.copy(then_expression.get_shape())
|
||||
elif isinstance(then_expression, tf.IndexedSlices):
|
||||
g_shape = copy.copy(then_expression.dense_shape)
|
||||
if condition.dtype != tf.bool:
|
||||
condition = tf.cast(condition, 'bool')
|
||||
g = tf.cond(condition,
|
||||
lambda: then_expression,
|
||||
lambda: else_expression)
|
||||
if isinstance(then_expression, tf.Tensor):
|
||||
g.set_shape(g_shape)
|
||||
elif isinstance(then_expression, tf.IndexedSlices):
|
||||
g._dense_shape = g_shape
|
||||
else:
|
||||
g = K.switch(K.greater_equal(n, c), g * c / n, g)
|
||||
if c > 0:
|
||||
g = K.switch(n >= c, g * c / n, g)
|
||||
return g
|
||||
|
||||
|
||||
@@ -158,7 +136,7 @@ class SGD(Optimizer):
|
||||
self.updates .append(K.update_add(self.iterations, 1))
|
||||
|
||||
# momentum
|
||||
shapes = [K.get_variable_shape(p) for p in params]
|
||||
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):
|
||||
@@ -188,6 +166,7 @@ class SGD(Optimizer):
|
||||
|
||||
|
||||
class RMSprop(Optimizer):
|
||||
# pylint: disable=line-too-long
|
||||
"""RMSProp optimizer.
|
||||
|
||||
It is recommended to leave the parameters of this optimizer
|
||||
@@ -206,6 +185,7 @@ class RMSprop(Optimizer):
|
||||
# References
|
||||
- [rmsprop: Divide the gradient by a running average of its recent magnitude](http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf)
|
||||
"""
|
||||
# pylint: enable=line-too-long
|
||||
|
||||
def __init__(self, lr=0.001, rho=0.9, epsilon=1e-8, decay=0.,
|
||||
**kwargs):
|
||||
@@ -219,7 +199,7 @@ class RMSprop(Optimizer):
|
||||
|
||||
def get_updates(self, params, constraints, loss):
|
||||
grads = self.get_gradients(loss, params)
|
||||
shapes = [K.get_variable_shape(p) for p in params]
|
||||
shapes = [K.int_shape(p) for p in params]
|
||||
accumulators = [K.zeros(shape) for shape in shapes]
|
||||
self.weights = accumulators
|
||||
self.updates = []
|
||||
@@ -252,6 +232,7 @@ class RMSprop(Optimizer):
|
||||
|
||||
|
||||
class Adagrad(Optimizer):
|
||||
# pylint: disable=line-too-long
|
||||
"""Adagrad optimizer.
|
||||
|
||||
It is recommended to leave the parameters of this optimizer
|
||||
@@ -265,6 +246,7 @@ class Adagrad(Optimizer):
|
||||
# References
|
||||
- [Adaptive Subgradient Methods for Online Learning and Stochastic Optimization](http://www.jmlr.org/papers/volume12/duchi11a/duchi11a.pdf)
|
||||
"""
|
||||
# pylint: enable=line-too-long
|
||||
|
||||
def __init__(self, lr=0.01, epsilon=1e-8, decay=0., **kwargs):
|
||||
super(Adagrad, self).__init__(**kwargs)
|
||||
@@ -276,7 +258,7 @@ class Adagrad(Optimizer):
|
||||
|
||||
def get_updates(self, params, constraints, loss):
|
||||
grads = self.get_gradients(loss, params)
|
||||
shapes = [K.get_variable_shape(p) for p in params]
|
||||
shapes = [K.int_shape(p) for p in params]
|
||||
accumulators = [K.zeros(shape) for shape in shapes]
|
||||
self.weights = accumulators
|
||||
self.updates = []
|
||||
@@ -306,6 +288,7 @@ class Adagrad(Optimizer):
|
||||
|
||||
|
||||
class Adadelta(Optimizer):
|
||||
# pylint: disable=line-too-long
|
||||
"""Adadelta optimizer.
|
||||
|
||||
It is recommended to leave the parameters of this optimizer
|
||||
@@ -321,6 +304,7 @@ class Adadelta(Optimizer):
|
||||
# References
|
||||
- [Adadelta - an adaptive learning rate method](http://arxiv.org/abs/1212.5701)
|
||||
"""
|
||||
# pylint: enable=line-too-long
|
||||
|
||||
def __init__(self, lr=1.0, rho=0.95, epsilon=1e-8, decay=0.,
|
||||
**kwargs):
|
||||
@@ -334,7 +318,7 @@ class Adadelta(Optimizer):
|
||||
|
||||
def get_updates(self, params, constraints, loss):
|
||||
grads = self.get_gradients(loss, params)
|
||||
shapes = [K.get_variable_shape(p) for p in 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
|
||||
@@ -375,6 +359,7 @@ class Adadelta(Optimizer):
|
||||
|
||||
|
||||
class Adam(Optimizer):
|
||||
# pylint: disable=line-too-long
|
||||
"""Adam optimizer.
|
||||
|
||||
Default parameters follow those provided in the original paper.
|
||||
@@ -389,6 +374,7 @@ class Adam(Optimizer):
|
||||
# References
|
||||
- [Adam - A Method for Stochastic Optimization](http://arxiv.org/abs/1412.6980v8)
|
||||
"""
|
||||
# pylint: enable=line-too-long
|
||||
|
||||
def __init__(self, lr=0.001, beta_1=0.9, beta_2=0.999,
|
||||
epsilon=1e-8, decay=0., **kwargs):
|
||||
@@ -413,7 +399,7 @@ class Adam(Optimizer):
|
||||
lr_t = lr * (K.sqrt(1. - K.pow(self.beta_2, t)) /
|
||||
(1. - K.pow(self.beta_1, t)))
|
||||
|
||||
shapes = [K.get_variable_shape(p) for p in params]
|
||||
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
|
||||
@@ -445,6 +431,7 @@ class Adam(Optimizer):
|
||||
|
||||
|
||||
class Adamax(Optimizer):
|
||||
# pylint: disable=line-too-long
|
||||
"""Adamax optimizer from Adam paper's Section 7.
|
||||
|
||||
It is a variant of Adam based on the infinity norm.
|
||||
@@ -459,6 +446,7 @@ class Adamax(Optimizer):
|
||||
# References
|
||||
- [Adam - A Method for Stochastic Optimization](http://arxiv.org/abs/1412.6980v8)
|
||||
"""
|
||||
# pylint: enable=line-too-long
|
||||
|
||||
def __init__(self, lr=0.002, beta_1=0.9, beta_2=0.999,
|
||||
epsilon=1e-8, decay=0., **kwargs):
|
||||
@@ -482,7 +470,7 @@ class Adamax(Optimizer):
|
||||
t = self.iterations + 1
|
||||
lr_t = lr / (1. - K.pow(self.beta_1, t))
|
||||
|
||||
shapes = [K.get_variable_shape(p) for p in params]
|
||||
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
|
||||
@@ -517,6 +505,7 @@ class Adamax(Optimizer):
|
||||
|
||||
|
||||
class Nadam(Optimizer):
|
||||
# pylint: disable=line-too-long
|
||||
"""Nesterov Adam optimizer.
|
||||
|
||||
Much like Adam is essentially RMSprop with momentum,
|
||||
@@ -535,6 +524,7 @@ class Nadam(Optimizer):
|
||||
- [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)
|
||||
"""
|
||||
# pylint: enable=line-too-long
|
||||
|
||||
def __init__(self, lr=0.002, beta_1=0.9, beta_2=0.999,
|
||||
epsilon=1e-8, schedule_decay=0.004, **kwargs):
|
||||
@@ -560,7 +550,7 @@ class Nadam(Optimizer):
|
||||
m_schedule_next = self.m_schedule * momentum_cache_t * momentum_cache_t_1
|
||||
self.updates.append((self.m_schedule, m_schedule_new))
|
||||
|
||||
shapes = [K.get_variable_shape(p) for p in params]
|
||||
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]
|
||||
|
||||
@@ -602,7 +592,7 @@ class TFOptimizer(Optimizer):
|
||||
"""Wrapper class for native TensorFlow optimizers.
|
||||
"""
|
||||
|
||||
def __init__(self, optimizer):
|
||||
def __init__(self, optimizer): # pylint: disable=super-init-not-called
|
||||
self.optimizer = optimizer
|
||||
self.iterations = K.variable(0., name='iterations')
|
||||
self.updates = []
|
||||
@@ -632,6 +622,7 @@ class TFOptimizer(Optimizer):
|
||||
|
||||
# Aliases.
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
sgd = SGD
|
||||
rmsprop = RMSprop
|
||||
adagrad = Adagrad
|
||||
@@ -639,6 +630,7 @@ adadelta = Adadelta
|
||||
adam = Adam
|
||||
adamax = Adamax
|
||||
nadam = Nadam
|
||||
# pylint: enable=invalid-name
|
||||
|
||||
|
||||
def serialize(optimizer):
|
||||
@@ -694,10 +686,9 @@ def get(identifier):
|
||||
# Raises
|
||||
ValueError: If `identifier` cannot be interpreted.
|
||||
"""
|
||||
if K.backend() == 'tensorflow':
|
||||
# Wrap TF optimizer instances
|
||||
if isinstance(identifier, tf.train.Optimizer):
|
||||
return TFOptimizer(identifier)
|
||||
# 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):
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
"""Data preprocessing module.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from . import image
|
||||
from . import sequence
|
||||
from . import text
|
||||
|
||||
@@ -1,27 +1,33 @@
|
||||
"""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
|
||||
|
||||
import numpy as np
|
||||
import re
|
||||
from scipy import linalg
|
||||
import scipy.ndimage as ndi
|
||||
from six.moves import range
|
||||
import os
|
||||
import re
|
||||
import threading
|
||||
import warnings
|
||||
import multiprocessing.pool
|
||||
from functools import partial
|
||||
|
||||
from .. import backend as K
|
||||
import numpy as np
|
||||
from six.moves import range
|
||||
|
||||
# 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,
|
||||
@@ -252,7 +258,7 @@ def array_to_img(x, data_format=None, scale=True):
|
||||
if data_format == 'channels_first':
|
||||
x = x.transpose(1, 2, 0)
|
||||
if scale:
|
||||
x = x + max(-np.min(x), 0)
|
||||
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
|
||||
@@ -534,7 +540,13 @@ class ImageDataGenerator(object):
|
||||
|
||||
# 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
|
||||
@@ -633,13 +645,14 @@ class ImageDataGenerator(object):
|
||||
|
||||
# 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}:
|
||||
warnings.warn(
|
||||
if x.shape[self.channel_axis] not in {1, 3, 4}:
|
||||
raise ValueError(
|
||||
'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 '
|
||||
@@ -673,6 +686,9 @@ class ImageDataGenerator(object):
|
||||
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)
|
||||
@@ -723,7 +739,7 @@ class Iterator(object):
|
||||
yield (index_array[current_index: current_index + current_batch_size],
|
||||
current_index, current_batch_size)
|
||||
|
||||
def __iter__(self):
|
||||
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
|
||||
@@ -823,73 +839,6 @@ class NumpyArrayIterator(Iterator):
|
||||
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` contained 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.
|
||||
|
||||
# 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 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:
|
||||
samples += 1
|
||||
return samples
|
||||
|
||||
|
||||
def _list_valid_filenames_in_directory(directory, white_list_formats,
|
||||
class_indices, follow_links):
|
||||
"""List paths of files in `subdir` relative from `directory` whose extensions are 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.
|
||||
|
||||
# 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.
|
||||
|
||||
@@ -982,33 +931,38 @@ class DirectoryIterator(Iterator):
|
||||
def _recursive_list(subpath):
|
||||
return sorted(os.walk(subpath, followlinks=follow_links), key=lambda tpl: tpl[0])
|
||||
|
||||
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)))
|
||||
|
||||
for subdir in classes:
|
||||
subpath = os.path.join(directory, subdir)
|
||||
for root, _, files in _recursive_list(subpath):
|
||||
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:
|
||||
self.samples += 1
|
||||
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()
|
||||
for subdir in classes:
|
||||
subpath = os.path.join(directory, subdir)
|
||||
for root, _, files in _recursive_list(subpath):
|
||||
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:
|
||||
self.classes[i] = self.class_indices[subdir]
|
||||
i += 1
|
||||
# add filename relative to directory
|
||||
absolute_path = os.path.join(root, fname)
|
||||
self.filenames.append(os.path.relpath(absolute_path, directory))
|
||||
super(DirectoryIterator, self).__init__(self.samples, batch_size, shuffle, seed)
|
||||
|
||||
def next(self):
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""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
|
||||
import random
|
||||
from six.moves import range
|
||||
|
||||
|
||||
@@ -50,16 +55,16 @@ def pad_sequences(sequences, maxlen=None, dtype='int32',
|
||||
# checking for consistency in the main loop below.
|
||||
sample_shape = tuple()
|
||||
for s in sequences:
|
||||
if len(s) > 0:
|
||||
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):
|
||||
if not len(s): # pylint: disable=g-explicit-length-test
|
||||
continue # empty list/array was found
|
||||
if truncating == 'pre':
|
||||
trunc = s[-maxlen:]
|
||||
trunc = s[-maxlen:] # pylint: disable=invalid-unary-operand-type
|
||||
elif truncating == 'post':
|
||||
trunc = s[:maxlen]
|
||||
else:
|
||||
|
||||
@@ -5,6 +5,7 @@ May benefit from a fast Cython rewrite.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import string
|
||||
import sys
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""Keras built-in regularizers.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
import six
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from . import backend as K
|
||||
from .utils.generic_utils import serialize_keras_object
|
||||
import six
|
||||
from .utils.generic_utils import deserialize_keras_object
|
||||
from .utils.generic_utils import serialize_keras_object
|
||||
|
||||
|
||||
class Regularizer(object):
|
||||
@@ -25,7 +30,7 @@ class L1L2(Regularizer):
|
||||
l2: Float; L2 regularization factor.
|
||||
"""
|
||||
|
||||
def __init__(self, l1=0., l2=0.):
|
||||
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)
|
||||
|
||||
@@ -53,7 +58,7 @@ def l2(l=0.01):
|
||||
return L1L2(l2=l)
|
||||
|
||||
|
||||
def l1_l2(l1=0.01, l2=0.01):
|
||||
def l1_l2(l1=0.01, l2=0.01): # pylint: disable=redefined-outer-name
|
||||
return L1L2(l1=l1, l2=l2)
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
"""Keras utilities.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from . import np_utils
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from . import conv_utils
|
||||
from . import data_utils
|
||||
from . import generic_utils
|
||||
from . import io_utils
|
||||
from . import np_utils
|
||||
|
||||
# Globally-importable utils.
|
||||
from .io_utils import HDF5Matrix
|
||||
|
||||
+16
-13
@@ -1,6 +1,12 @@
|
||||
from six.moves import range
|
||||
import numpy as np
|
||||
"""Utilities used by convolution layers.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from .. import backend as K
|
||||
import numpy as np
|
||||
from six.moves import range
|
||||
|
||||
|
||||
def normalize_tuple(value, n, name):
|
||||
@@ -55,11 +61,9 @@ def normalize_data_format(value):
|
||||
|
||||
def normalize_padding(value):
|
||||
padding = value.lower()
|
||||
allowed = {'valid', 'same', 'causal'}
|
||||
if K.backend() == 'theano':
|
||||
allowed.add('full')
|
||||
if padding not in allowed:
|
||||
raise ValueError('The `padding` argument must be one of "valid", "same" (or "causal" for Conv1D). '
|
||||
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
|
||||
|
||||
@@ -109,10 +113,10 @@ def conv_output_length(input_length, filter_size,
|
||||
output_length = input_length
|
||||
elif padding == 'valid':
|
||||
output_length = input_length - dilated_filter_size + 1
|
||||
elif padding == 'causal':
|
||||
output_length = input_length
|
||||
elif padding == 'full':
|
||||
output_length = input_length + dilated_filter_size - 1
|
||||
elif padding == 'causal':
|
||||
output_length = input_length
|
||||
return (output_length + stride - 1) // stride
|
||||
|
||||
|
||||
@@ -143,10 +147,9 @@ def conv_input_length(output_length, filter_size, padding, stride):
|
||||
def deconv_length(dim_size, stride_size, kernel_size, padding):
|
||||
if dim_size is None:
|
||||
return None
|
||||
dim_size *= stride_size
|
||||
if padding == 'valid':
|
||||
dim_size = dim_size * stride_size + max(kernel_size - stride_size, 0)
|
||||
dim_size += max(kernel_size - stride_size, 0)
|
||||
elif padding == 'full':
|
||||
dim_size = dim_size * stride_size - (stride_size + kernel_size - 2)
|
||||
elif padding == 'same':
|
||||
dim_size = dim_size * stride_size
|
||||
dim_size -= (stride_size + kernel_size - 2)
|
||||
return dim_size
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
"""Utilities for file download and caching."""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import hashlib
|
||||
import tarfile
|
||||
import zipfile
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import hashlib
|
||||
import six
|
||||
from six.moves.urllib.request import urlopen
|
||||
from six.moves.urllib.error import URLError
|
||||
from six.moves.urllib.error import HTTPError
|
||||
import sys
|
||||
|
||||
from six.moves.urllib.error import HTTPError
|
||||
from six.moves.urllib.error import URLError
|
||||
from six.moves.urllib.request import urlopen
|
||||
from ..utils.generic_utils import Progbar
|
||||
|
||||
|
||||
@@ -55,7 +56,7 @@ if sys.version_info[0] == 2:
|
||||
for chunk in chunk_read(response, reporthook=reporthook):
|
||||
fd.write(chunk)
|
||||
else:
|
||||
from six.moves.urllib.request import urlretrieve
|
||||
from six.moves.urllib.request import urlretrieve # pylint: disable=g-import-not-at-top
|
||||
|
||||
|
||||
def _extract_archive(file_path, path='.', archive_format='auto'):
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
"""Python utilities required by Keras."""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import inspect
|
||||
import marshal
|
||||
import sys
|
||||
import time
|
||||
import types as python_types
|
||||
|
||||
import numpy as np
|
||||
|
||||
import time
|
||||
import sys
|
||||
import six
|
||||
import marshal
|
||||
import types as python_types
|
||||
import inspect
|
||||
|
||||
_GLOBAL_CUSTOM_OBJECTS = {}
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
"""Utilities related to disk I/O."""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
import sys
|
||||
|
||||
import numpy as np
|
||||
|
||||
try:
|
||||
import h5py
|
||||
import h5py # pylint:disable=g-import-not-at-top
|
||||
except ImportError:
|
||||
h5py = None
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
"""Utilities related to Keras layers.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from .conv_utils import convert_kernel
|
||||
from .. import backend as K
|
||||
from .conv_utils import convert_kernel
|
||||
import numpy as np
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Numpy-related utilities."""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
"""Utilities related to Keras unit tests."""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import assert_allclose
|
||||
import inspect
|
||||
@@ -6,7 +10,6 @@ import six
|
||||
|
||||
from ..engine import Model, Input
|
||||
from ..models import Sequential
|
||||
from ..models import model_from_json
|
||||
from .. import backend as K
|
||||
|
||||
|
||||
@@ -85,7 +88,7 @@ def layer_test(layer_cls, kwargs={}, input_shape=None, input_dtype=None,
|
||||
|
||||
# check shape inference
|
||||
model = Model(x, y)
|
||||
expected_output_shape = layer.compute_output_shape(input_shape)
|
||||
expected_output_shape = tuple(layer._compute_output_shape(input_shape).as_list())
|
||||
actual_output = model.predict(input_data)
|
||||
actual_output_shape = actual_output.shape
|
||||
for expected_dim, actual_dim in zip(expected_output_shape,
|
||||
@@ -142,7 +145,7 @@ def layer_test(layer_cls, kwargs={}, input_shape=None, input_dtype=None,
|
||||
|
||||
|
||||
def keras_test(func):
|
||||
"""Function wrapper to clean up after TensorFlow tests.
|
||||
"""Function wrapper to clean up after tests.
|
||||
|
||||
# Arguments
|
||||
func: test function to clean up after.
|
||||
@@ -153,7 +156,6 @@ def keras_test(func):
|
||||
@six.wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
output = func(*args, **kwargs)
|
||||
if K.backend() == 'tensorflow':
|
||||
K.clear_session()
|
||||
K.clear_session()
|
||||
return output
|
||||
return wrapper
|
||||
|
||||
+10
-10
@@ -1,19 +1,19 @@
|
||||
"""Utilities related to model visualization."""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
|
||||
try:
|
||||
# pydot-ng is a fork of pydot that is better maintained.
|
||||
import pydot_ng as pydot
|
||||
import pydot_ng as pydot # pylint: disable=g-import-not-at-top
|
||||
except ImportError:
|
||||
# pydotplus is an improved version of pydot
|
||||
# Fall back on pydot if necessary.
|
||||
try:
|
||||
import pydotplus as pydot
|
||||
import pydot # pylint: disable=g-import-not-at-top
|
||||
except ImportError:
|
||||
# Fall back on pydot if necessary.
|
||||
try:
|
||||
import pydot
|
||||
except ImportError:
|
||||
pydot = None
|
||||
pydot = None
|
||||
|
||||
|
||||
def _check_pydot():
|
||||
@@ -46,8 +46,8 @@ def model_to_dot(model,
|
||||
# Returns
|
||||
A `pydot.Dot` instance representing the Keras model.
|
||||
"""
|
||||
from ..layers.wrappers import Wrapper
|
||||
from ..models import Sequential
|
||||
from ..layers.wrappers import Wrapper # pylint: disable=g-import-not-at-top
|
||||
from ..models import Sequential # pylint: disable=g-import-not-at-top
|
||||
|
||||
_check_pydot()
|
||||
dot = pydot.Dot()
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
"""Keras API wrappers.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from . import scikit_learn
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
"""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 inspect
|
||||
import types
|
||||
|
||||
import numpy as np
|
||||
|
||||
from ..utils.np_utils import to_categorical
|
||||
from ..models import Sequential
|
||||
import numpy as np
|
||||
from ..utils.np_utils import to_categorical
|
||||
|
||||
|
||||
class BaseWrapper(object):
|
||||
@@ -86,11 +89,11 @@ class BaseWrapper(object):
|
||||
raise ValueError(
|
||||
'{} is not a legal parameter'.format(params_name))
|
||||
|
||||
def get_params(self, **params):
|
||||
def get_params(self, **params): # pylint: disable=unused-argument
|
||||
"""Gets parameters for this estimator.
|
||||
|
||||
# Arguments
|
||||
**params: ignored (exists for API compatibility).
|
||||
**params: ignored (exists for API compatiblity).
|
||||
|
||||
# Returns
|
||||
Dictionary of parameter names mapped to their values.
|
||||
|
||||
+2
-2
@@ -3,12 +3,12 @@ from setuptools import find_packages
|
||||
|
||||
|
||||
setup(name='Keras',
|
||||
version='2.0.5',
|
||||
version='2.0.4-tf',
|
||||
description='Deep Learning for Python',
|
||||
author='Francois Chollet',
|
||||
author_email='francois.chollet@gmail.com',
|
||||
url='https://github.com/fchollet/keras',
|
||||
download_url='https://github.com/fchollet/keras/tarball/2.0.5',
|
||||
download_url='https://github.com/fchollet/keras/tarball/2.0.4',
|
||||
license='MIT',
|
||||
install_requires=['theano', 'pyyaml', 'six'],
|
||||
extras_require={
|
||||
|
||||
@@ -6,8 +6,7 @@ import string
|
||||
from keras.utils.test_utils import get_test_data, keras_test
|
||||
from keras.utils.np_utils import to_categorical
|
||||
from keras.models import Sequential
|
||||
from keras import layers, optimizers
|
||||
import keras.backend as K
|
||||
from keras import layers
|
||||
import keras
|
||||
|
||||
|
||||
@@ -205,14 +204,5 @@ def test_masked_temporal():
|
||||
ground_truth = -np.log(0.5)
|
||||
assert(np.abs(history.history['loss'][-1] - ground_truth) < 0.06)
|
||||
|
||||
|
||||
@pytest.mark.skipif(K.backend() != 'tensorflow', reason='Requires TF backend')
|
||||
@keras_test
|
||||
def test_embedding_with_clipnorm():
|
||||
model = Sequential()
|
||||
model.add(layers.Embedding(input_dim=1, output_dim=1))
|
||||
model.compile(optimizer=optimizers.SGD(clipnorm=0.1), loss='mse')
|
||||
model.fit(np.array([[0]]), np.array([[[0.5]]]), epochs=1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__])
|
||||
|
||||
@@ -136,10 +136,6 @@ def test_elu():
|
||||
assert_allclose(result, test_values, rtol=1e-05)
|
||||
|
||||
negative_values = np.array([[-1, -2]], dtype=K.floatx())
|
||||
# cntk can't rebind the input shape, so create the model again to test different batch size
|
||||
if (K.backend() == 'cntk'):
|
||||
x2 = K.placeholder(ndim=2)
|
||||
f = K.function([x2], [activations.elu(x2, 0.5)])
|
||||
result = f([negative_values])[0]
|
||||
true_result = (np.exp(negative_values) - 1) / 2
|
||||
|
||||
|
||||
@@ -11,24 +11,12 @@ def test_resnet50():
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support padding with non-concrete dimension")
|
||||
def test_resnet50_notop():
|
||||
model = applications.ResNet50(weights=None, include_top=False)
|
||||
assert model.output_shape == (None, None, None, 2048)
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_resnet50_notop_specified_input_shape():
|
||||
input_shape = (3, 300, 300) if K.image_data_format() == 'channels_first' else (300, 300, 3)
|
||||
model = applications.ResNet50(weights=None, include_top=False, input_shape=input_shape)
|
||||
output_shape = (None, 2048, 1, 1) if K.image_data_format() == 'channels_first' else (None, 1, 1, 2048)
|
||||
assert model.output_shape == output_shape
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support padding with non-concrete dimension")
|
||||
def test_resnet50_pooling():
|
||||
model = applications.ResNet50(weights=None,
|
||||
include_top=False,
|
||||
@@ -36,16 +24,6 @@ def test_resnet50_pooling():
|
||||
assert model.output_shape == (None, 2048)
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_resnet50_pooling_specified_input_shape():
|
||||
input_shape = (3, 300, 300) if K.image_data_format() == 'channels_first' else (300, 300, 3)
|
||||
model = applications.ResNet50(weights=None,
|
||||
include_top=False,
|
||||
pooling='avg',
|
||||
input_shape=input_shape)
|
||||
assert model.output_shape == (None, 2048)
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_vgg16():
|
||||
model = applications.VGG16(weights=None)
|
||||
@@ -53,36 +31,17 @@ def test_vgg16():
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support padding with non-concrete dimension")
|
||||
def test_vgg16_notop():
|
||||
model = applications.VGG16(weights=None, include_top=False)
|
||||
assert model.output_shape == (None, None, None, 512)
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_vgg16_notop_specified_input_shape():
|
||||
input_shape = (3, 300, 300) if K.image_data_format() == 'channels_first' else (300, 300, 3)
|
||||
model = applications.VGG16(weights=None, include_top=False, input_shape=input_shape)
|
||||
output_shape = (None, 512, 9, 9) if K.image_data_format() == 'channels_first' else (None, 9, 9, 512)
|
||||
assert model.output_shape == output_shape
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support padding with non-concrete dimension")
|
||||
def test_vgg16_pooling():
|
||||
model = applications.VGG16(weights=None, include_top=False, pooling='avg')
|
||||
assert model.output_shape == (None, 512)
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_vgg16_pooling_specified_input_shape():
|
||||
input_shape = (3, 300, 300) if K.image_data_format() == 'channels_first' else (300, 300, 3)
|
||||
model = applications.VGG16(weights=None, include_top=False, pooling='avg', input_shape=input_shape)
|
||||
assert model.output_shape == (None, 512)
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_vgg19():
|
||||
model = applications.VGG19(weights=None)
|
||||
@@ -90,36 +49,17 @@ def test_vgg19():
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support padding with non-concrete dimension")
|
||||
def test_vgg19_notop():
|
||||
model = applications.VGG19(weights=None, include_top=False)
|
||||
model = applications.VGG16(weights=None, include_top=False)
|
||||
assert model.output_shape == (None, None, None, 512)
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_vgg19_notop_specified_input_shape():
|
||||
input_shape = (3, 300, 300) if K.image_data_format() == 'channels_first' else (300, 300, 3)
|
||||
model = applications.VGG19(weights=None, include_top=False, input_shape=input_shape)
|
||||
output_shape = (None, 512, 9, 9) if K.image_data_format() == 'channels_first' else (None, 9, 9, 512)
|
||||
assert model.output_shape == output_shape
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support padding with non-concrete dimension")
|
||||
def test_vgg19_pooling():
|
||||
model = applications.VGG16(weights=None, include_top=False, pooling='avg')
|
||||
assert model.output_shape == (None, 512)
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_vgg19_pooling_specified_input_shape():
|
||||
input_shape = (3, 300, 300) if K.image_data_format() == 'channels_first' else (300, 300, 3)
|
||||
model = applications.VGG16(weights=None, include_top=False, pooling='avg', input_shape=input_shape)
|
||||
assert model.output_shape == (None, 512)
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() != 'tensorflow'),
|
||||
reason='Requires tensorflow backend')
|
||||
@@ -151,20 +91,17 @@ def test_inceptionv3():
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support padding with non-concrete dimension")
|
||||
def test_inceptionv3_notop():
|
||||
model = applications.InceptionV3(weights=None, include_top=False)
|
||||
assert model.output_shape == (None, None, None, 2048)
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support padding with non-concrete dimension")
|
||||
def test_inceptionv3_pooling():
|
||||
model = applications.InceptionV3(weights=None, include_top=False, pooling='avg')
|
||||
assert model.output_shape == (None, 2048)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__])
|
||||
# pytest.main([__file__])
|
||||
test_vgg16()
|
||||
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -1,6 +1,7 @@
|
||||
import pytest
|
||||
import json
|
||||
import numpy as np
|
||||
import tensorflow as tf
|
||||
|
||||
from keras.layers import Dense, Dropout, InputLayer
|
||||
from keras import layers
|
||||
@@ -77,8 +78,6 @@ def test_trainable_weights():
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support add learning_phase() as input")
|
||||
def test_learning_phase():
|
||||
a = Input(shape=(32,), name='input_a')
|
||||
b = Input(shape=(32,), name='input_b')
|
||||
@@ -146,7 +145,7 @@ def test_node_construction():
|
||||
a = Input(shape=(32,), name='input_a')
|
||||
b = Input(shape=(32,), name='input_b')
|
||||
|
||||
assert a._keras_shape == (None, 32)
|
||||
assert a.get_shape().as_list() == [None, 32]
|
||||
a_layer, a_node_index, a_tensor_index = a._keras_history
|
||||
b_layer, b_node_index, b_tensor_index = b._keras_history
|
||||
assert len(a_layer.inbound_nodes) == 1
|
||||
@@ -187,7 +186,7 @@ def test_node_construction():
|
||||
# test layer properties
|
||||
test_layer = Dense(16, name='test_layer')
|
||||
a_test = test_layer(a)
|
||||
assert K.int_shape(test_layer.kernel) == (32, 16)
|
||||
assert test_layer.kernel.get_shape().as_list() == [32, 16]
|
||||
assert test_layer.input == a
|
||||
assert test_layer.output == a_test
|
||||
assert test_layer.input_mask is None
|
||||
@@ -230,7 +229,7 @@ def test_multi_input_layer():
|
||||
b_2 = dense(b)
|
||||
|
||||
merged = layers.concatenate([a_2, b_2], name='merge')
|
||||
assert merged._keras_shape == (None, 16 * 2)
|
||||
assert merged.get_shape().as_list() == [None, 16 * 2]
|
||||
merge_layer, merge_node_index, merge_tensor_index = merged._keras_history
|
||||
|
||||
assert merge_node_index == 0
|
||||
@@ -252,15 +251,14 @@ def test_multi_input_layer():
|
||||
print('model.input_layers_tensor_indices:', model.input_layers_tensor_indices)
|
||||
print('model.output_layers', model.output_layers)
|
||||
|
||||
print('output_shape:', model.compute_output_shape([(None, 32), (None, 32)]))
|
||||
assert model.compute_output_shape([(None, 32), (None, 32)]) == [(None, 64), (None, 5)]
|
||||
print('output_shape:', model._compute_output_shape([(None, 32), (None, 32)]))
|
||||
output_shapes = model._compute_output_shape([(None, 32), (None, 32)])
|
||||
assert output_shapes[0].as_list() == [None, 64]
|
||||
assert output_shapes[1].as_list() == [None, 5]
|
||||
|
||||
print('mask:', model.compute_mask([a, b], [None, None]))
|
||||
assert model.compute_mask([a, b], [None, None]) == [None, None]
|
||||
|
||||
print('output_shape:', model.compute_output_shape([(None, 32), (None, 32)]))
|
||||
assert model.compute_output_shape([(None, 32), (None, 32)]) == [(None, 64), (None, 5)]
|
||||
|
||||
# we don't check names of first 2 layers (inputs) because
|
||||
# ordering of same-level layers is not fixed
|
||||
print('layers:', [layer.name for layer in model.layers])
|
||||
@@ -322,10 +320,8 @@ def test_recursion():
|
||||
f = Input(shape=(32,), name='input_f')
|
||||
g, h = model([e, f])
|
||||
|
||||
# g2, h2 = model([e, f])
|
||||
|
||||
assert g._keras_shape == c._keras_shape
|
||||
assert h._keras_shape == d._keras_shape
|
||||
assert g.get_shape().as_list() == c.get_shape().as_list()
|
||||
assert h.get_shape().as_list() == d.get_shape().as_list()
|
||||
|
||||
# test separate manipulation of different layer outputs
|
||||
i = Dense(7, name='dense_4')(h)
|
||||
@@ -343,8 +339,8 @@ def test_recursion():
|
||||
print(model.compute_mask([e, f], [None, None]))
|
||||
assert model.compute_mask([e, f], [None, None]) == [None, None]
|
||||
|
||||
print(final_model.compute_output_shape([(10, 32), (10, 32)]))
|
||||
assert final_model.compute_output_shape([(10, 32), (10, 32)]) == [(10, 7), (10, 64)]
|
||||
print(final_model._compute_output_shape([(10, 32), (10, 32)]))
|
||||
assert final_model._compute_output_shape([(10, 32), (10, 32)]) == [(10, 7), (10, 64)]
|
||||
|
||||
# run recursive model
|
||||
fn = K.function(final_model.inputs, final_model.outputs)
|
||||
@@ -375,10 +371,10 @@ def test_recursion():
|
||||
p = Input(shape=(32,), name='input_p')
|
||||
q, r = model([o, p])
|
||||
|
||||
assert n._keras_shape == (None, 5)
|
||||
assert q._keras_shape == (None, 64)
|
||||
assert n.get_shape().as_list() == [None, 5]
|
||||
assert q.get_shape().as_list() == [None, 64]
|
||||
s = layers.concatenate([n, q], name='merge_nq')
|
||||
assert s._keras_shape == (None, 64 + 5)
|
||||
assert s.get_shape().as_list() == [None, 64 + 5]
|
||||
|
||||
# test with single output as 1-elem list
|
||||
multi_io_model = Model([j, k, o, p], [s])
|
||||
@@ -441,11 +437,12 @@ def test_recursion():
|
||||
with pytest.raises(Exception) as e:
|
||||
Model([j], [m, n])
|
||||
|
||||
# redundant outputs
|
||||
# redudant outputs
|
||||
j = Input(shape=(32,), name='input_j')
|
||||
k = Input(shape=(32,), name='input_k')
|
||||
m, n = model([j, k])
|
||||
# this should work with a warning
|
||||
# this should work lol
|
||||
# TODO: raise a warning
|
||||
Model([j, k], [m, n, n])
|
||||
|
||||
# redundant inputs
|
||||
@@ -465,29 +462,27 @@ def test_recursion():
|
||||
####################################################
|
||||
# test calling layers/models on TF tensors
|
||||
|
||||
if K._BACKEND == 'tensorflow':
|
||||
import tensorflow as tf
|
||||
j = Input(shape=(32,), name='input_j')
|
||||
k = Input(shape=(32,), name='input_k')
|
||||
m, n = model([j, k])
|
||||
tf_model = Model([j, k], [m, n])
|
||||
j = Input(shape=(32,), name='input_j')
|
||||
k = Input(shape=(32,), name='input_k')
|
||||
m, n = model([j, k])
|
||||
tf_model = Model([j, k], [m, n])
|
||||
|
||||
j_tf = tf.placeholder(dtype=K.floatx())
|
||||
k_tf = tf.placeholder(dtype=K.floatx())
|
||||
m_tf, n_tf = tf_model([j_tf, k_tf])
|
||||
assert m_tf.get_shape().as_list() == [None, 64]
|
||||
assert n_tf.get_shape().as_list() == [None, 5]
|
||||
j_tf = tf.placeholder(dtype=K.floatx())
|
||||
k_tf = tf.placeholder(dtype=K.floatx())
|
||||
m_tf, n_tf = tf_model([j_tf, k_tf])
|
||||
assert m_tf.get_shape().as_list() == [None, 64]
|
||||
assert n_tf.get_shape().as_list() == [None, 5]
|
||||
|
||||
# test merge
|
||||
layers.concatenate([j_tf, k_tf], axis=1)
|
||||
layers.add([j_tf, k_tf])
|
||||
# test merge
|
||||
layers.concatenate([j_tf, k_tf], axis=1)
|
||||
layers.add([j_tf, k_tf])
|
||||
|
||||
# test tensor input
|
||||
x = tf.placeholder(shape=(None, 2), dtype=K.floatx())
|
||||
InputLayer(input_tensor=x)
|
||||
# test tensor input
|
||||
x = tf.placeholder(shape=(None, 2), dtype=K.floatx())
|
||||
InputLayer(input_tensor=x)
|
||||
|
||||
x = Input(tensor=x)
|
||||
Dense(2)(x)
|
||||
x = Input(tensor=x)
|
||||
Dense(2)(x)
|
||||
|
||||
|
||||
@keras_test
|
||||
@@ -496,7 +491,7 @@ def test_load_layers():
|
||||
from keras.models import Model
|
||||
from keras.engine.topology import preprocess_weights_for_loading
|
||||
|
||||
if K.backend() == 'tensorflow' or K.backend() == 'cntk':
|
||||
if K.backend() == 'tensorflow':
|
||||
inputs = Input(shape=(10, 20, 20, 1))
|
||||
else:
|
||||
inputs = Input(shape=(10, 1, 20, 20))
|
||||
@@ -552,7 +547,6 @@ def test_load_layers():
|
||||
assert np.all(K.eval(model.layers[2].weights[5]) == weight_tensor_bi_convlstm_new[5])
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_recursion_with_bn_and_loss():
|
||||
model1 = Sequential([
|
||||
layers.Dense(5, input_dim=5, activity_regularizer='l1'),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import pytest
|
||||
import numpy as np
|
||||
from numpy.testing import assert_allclose
|
||||
import scipy.sparse as sparse
|
||||
|
||||
from keras.layers import Dense, Dropout
|
||||
from keras.engine.topology import Input
|
||||
@@ -199,18 +198,6 @@ def test_model_methods():
|
||||
out = model.predict([input_a_np, input_b_np], batch_size=4)
|
||||
|
||||
|
||||
@pytest.mark.skipif(K.backend() != 'tensorflow', reason='sparse operations supported only by TF')
|
||||
@keras_test
|
||||
def test_sparse_input_validation_split():
|
||||
test_input = sparse.random(6, 3, density=0.25).tocsr()
|
||||
in1 = Input(shape=(3,), sparse=True)
|
||||
out1 = Dense(4)(in1)
|
||||
test_output = np.random.random((6, 4))
|
||||
model = Model(in1, out1)
|
||||
model.compile('rmsprop', 'mse')
|
||||
model.fit(test_input, test_output, epochs=1, batch_size=2, validation_split=0.2)
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_trainable_argument():
|
||||
x = np.random.random((5, 3))
|
||||
@@ -446,8 +433,6 @@ def test_model_with_partial_loss():
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support external loss yet")
|
||||
def test_model_with_external_loss():
|
||||
# None loss, only regularization loss.
|
||||
a = Input(shape=(3,), name='input_a')
|
||||
|
||||
@@ -43,69 +43,67 @@ def test_convolutional_recurrent():
|
||||
if data_format == 'channels_first' or return_sequences:
|
||||
continue
|
||||
|
||||
# cntk doesn't support statefulness on LSTM yet, will enable it on cntk later
|
||||
if K.backend() != 'cntk':
|
||||
# Tests for statefulness
|
||||
model = Sequential()
|
||||
kwargs = {'data_format': data_format,
|
||||
'return_sequences': return_sequences,
|
||||
'filters': filters,
|
||||
'kernel_size': (num_row, num_col),
|
||||
'stateful': True,
|
||||
'batch_input_shape': inputs.shape,
|
||||
'padding': 'same'}
|
||||
layer = convolutional_recurrent.ConvLSTM2D(**kwargs)
|
||||
# Tests for statefulness
|
||||
model = Sequential()
|
||||
kwargs = {'data_format': data_format,
|
||||
'return_sequences': return_sequences,
|
||||
'filters': filters,
|
||||
'kernel_size': (num_row, num_col),
|
||||
'stateful': True,
|
||||
'batch_input_shape': inputs.shape,
|
||||
'padding': 'same'}
|
||||
layer = convolutional_recurrent.ConvLSTM2D(**kwargs)
|
||||
|
||||
model.add(layer)
|
||||
model.compile(optimizer='sgd', loss='mse')
|
||||
out1 = model.predict(np.ones_like(inputs))
|
||||
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))
|
||||
# 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
|
||||
assert(out1.max() != out2.max())
|
||||
# if the state is not reset, output should be different
|
||||
assert(out1.max() != out2.max())
|
||||
|
||||
# check that output changes after states are reset
|
||||
# (even though the model itself didn't change)
|
||||
layer.reset_states()
|
||||
out3 = model.predict(np.ones_like(inputs))
|
||||
assert(out2.max() != out3.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))
|
||||
assert(out2.max() != out3.max())
|
||||
|
||||
# check that container-level reset_states() works
|
||||
model.reset_states()
|
||||
out4 = model.predict(np.ones_like(inputs))
|
||||
assert_allclose(out3, out4, atol=1e-5)
|
||||
# check that container-level reset_states() works
|
||||
model.reset_states()
|
||||
out4 = model.predict(np.ones_like(inputs))
|
||||
assert_allclose(out3, out4, atol=1e-5)
|
||||
|
||||
# check that the call to `predict` updated the states
|
||||
out5 = model.predict(np.ones_like(inputs))
|
||||
assert(out4.max() != out5.max())
|
||||
# check that the call to `predict` updated the states
|
||||
out5 = model.predict(np.ones_like(inputs))
|
||||
assert(out4.max() != out5.max())
|
||||
|
||||
# check regularizers
|
||||
kwargs = {'data_format': data_format,
|
||||
'return_sequences': return_sequences,
|
||||
'kernel_size': (num_row, num_col),
|
||||
'stateful': True,
|
||||
'filters': filters,
|
||||
'batch_input_shape': inputs.shape,
|
||||
'kernel_regularizer': regularizers.L1L2(l1=0.01),
|
||||
'recurrent_regularizer': regularizers.L1L2(l1=0.01),
|
||||
'bias_regularizer': 'l2',
|
||||
'activity_regularizer': 'l2',
|
||||
'kernel_constraint': 'max_norm',
|
||||
'recurrent_constraint': 'max_norm',
|
||||
'bias_constraint': 'max_norm',
|
||||
'padding': 'same'}
|
||||
# check regularizers
|
||||
kwargs = {'data_format': data_format,
|
||||
'return_sequences': return_sequences,
|
||||
'kernel_size': (num_row, num_col),
|
||||
'stateful': True,
|
||||
'filters': filters,
|
||||
'batch_input_shape': inputs.shape,
|
||||
'kernel_regularizer': regularizers.L1L2(l1=0.01),
|
||||
'recurrent_regularizer': regularizers.L1L2(l1=0.01),
|
||||
'bias_regularizer': 'l2',
|
||||
'activity_regularizer': 'l2',
|
||||
'kernel_constraint': 'max_norm',
|
||||
'recurrent_constraint': 'max_norm',
|
||||
'bias_constraint': 'max_norm',
|
||||
'padding': 'same'}
|
||||
|
||||
layer = convolutional_recurrent.ConvLSTM2D(**kwargs)
|
||||
layer.build(inputs.shape)
|
||||
assert len(layer.losses) == 3
|
||||
assert layer.activity_regularizer
|
||||
output = layer(K.variable(np.ones(inputs.shape)))
|
||||
assert len(layer.losses) == 4
|
||||
K.eval(output)
|
||||
layer = convolutional_recurrent.ConvLSTM2D(**kwargs)
|
||||
layer.build(inputs.shape)
|
||||
assert len(layer.losses) == 3
|
||||
assert layer.activity_regularizer
|
||||
output = layer(K.variable(np.ones(inputs.shape)))
|
||||
assert len(layer.losses) == 4
|
||||
K.eval(output)
|
||||
|
||||
# check dropout
|
||||
layer_test(convolutional_recurrent.ConvLSTM2D,
|
||||
@@ -128,7 +126,7 @@ def test_convolutional_recurrent():
|
||||
initial_state = layer.get_initial_state(x)
|
||||
y = layer(x, initial_state=initial_state)
|
||||
model = Model(x, y)
|
||||
assert model.predict(inputs).shape == layer.compute_output_shape(inputs.shape)
|
||||
assert model.predict(inputs).shape == layer._compute_output_shape(inputs.shape)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -17,8 +17,6 @@ else:
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support dilated conv")
|
||||
def test_causal_dilated_conv():
|
||||
# Causal:
|
||||
layer_test(convolutional.Conv1D,
|
||||
@@ -124,8 +122,6 @@ def test_averagepooling_1d():
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support dilated conv")
|
||||
def test_convolution_2d():
|
||||
num_samples = 2
|
||||
filters = 2
|
||||
@@ -601,8 +597,6 @@ def test_upsampling_2d():
|
||||
assert_allclose(np_output, expected_out)
|
||||
|
||||
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support it yet")
|
||||
def test_upsampling_3d():
|
||||
num_samples = 2
|
||||
stack_size = 2
|
||||
@@ -657,8 +651,6 @@ def test_upsampling_3d():
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support slice to 0 dimension")
|
||||
def test_cropping_1d():
|
||||
num_samples = 2
|
||||
time_length = 4
|
||||
|
||||
@@ -106,23 +106,10 @@ def test_lambda():
|
||||
ld = deserialize_layer({'class_name': 'Lambda', 'config': config})
|
||||
|
||||
# test with lambda
|
||||
ld = layers.Lambda(
|
||||
lambda x: K.concatenate([K.square(x), x]),
|
||||
output_shape=lambda s: tuple(list(s)[:-1] + [2 * s[-1]]))
|
||||
ld = layers.Lambda(lambda x: K.concatenate([K.square(x), x]))
|
||||
config = ld.get_config()
|
||||
ld = layers.Lambda.from_config(config)
|
||||
|
||||
# test serialization with output_shape function
|
||||
def f(x):
|
||||
return K.concatenate([K.square(x), x])
|
||||
|
||||
def f_shape(s):
|
||||
return tuple(list(s)[:-1] + [2 * s[-1]])
|
||||
|
||||
ld = layers.Lambda(f, output_shape=f_shape)
|
||||
config = ld.get_config()
|
||||
ld = deserialize_layer({'class_name': 'Lambda', 'config': config})
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_dense():
|
||||
|
||||
@@ -16,16 +16,6 @@ def test_embedding():
|
||||
input_shape=(3, 2),
|
||||
input_dtype='int32',
|
||||
expected_output_dtype=K.floatx())
|
||||
layer_test(Embedding,
|
||||
kwargs={'output_dim': 4, 'input_dim': 10, 'mask_zero': True},
|
||||
input_shape=(3, 2, 5),
|
||||
input_dtype='int32',
|
||||
expected_output_dtype=K.floatx())
|
||||
layer_test(Embedding,
|
||||
kwargs={'output_dim': 4, 'input_dim': 10, 'mask_zero': True, 'input_length': (None, 5)},
|
||||
input_shape=(3, 2, 5),
|
||||
input_dtype='int32',
|
||||
expected_output_dtype=K.floatx())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -4,9 +4,7 @@ from numpy.testing import assert_allclose
|
||||
from keras import layers
|
||||
from keras import models
|
||||
from keras import backend as K
|
||||
from keras.utils.test_utils import layer_test
|
||||
from keras.utils.test_utils import keras_test
|
||||
from keras.layers import merge
|
||||
|
||||
|
||||
@keras_test
|
||||
@@ -14,8 +12,9 @@ def test_merge_add():
|
||||
i1 = layers.Input(shape=(4, 5))
|
||||
i2 = layers.Input(shape=(4, 5))
|
||||
i3 = layers.Input(shape=(4, 5))
|
||||
|
||||
o = layers.add([i1, i2, i3])
|
||||
assert o._keras_shape == (None, 4, 5)
|
||||
assert o.get_shape().as_list() == [None, 4, 5]
|
||||
model = models.Model([i1, i2, i3], o)
|
||||
|
||||
add_layer = layers.Add()
|
||||
@@ -36,7 +35,7 @@ def test_merge_multiply():
|
||||
i2 = layers.Input(shape=(4, 5))
|
||||
i3 = layers.Input(shape=(4, 5))
|
||||
o = layers.multiply([i1, i2, i3])
|
||||
assert o._keras_shape == (None, 4, 5)
|
||||
assert o.get_shape().as_list() == [None, 4, 5]
|
||||
model = models.Model([i1, i2, i3], o)
|
||||
|
||||
mul_layer = layers.Multiply()
|
||||
@@ -56,7 +55,7 @@ def test_merge_average():
|
||||
i1 = layers.Input(shape=(4, 5))
|
||||
i2 = layers.Input(shape=(4, 5))
|
||||
o = layers.average([i1, i2])
|
||||
assert o._keras_shape == (None, 4, 5)
|
||||
assert o.get_shape().as_list() == [None, 4, 5]
|
||||
model = models.Model([i1, i2], o)
|
||||
|
||||
avg_layer = layers.Average()
|
||||
@@ -75,7 +74,7 @@ def test_merge_maximum():
|
||||
i1 = layers.Input(shape=(4, 5))
|
||||
i2 = layers.Input(shape=(4, 5))
|
||||
o = layers.maximum([i1, i2])
|
||||
assert o._keras_shape == (None, 4, 5)
|
||||
assert o.get_shape().as_list() == [None, 4, 5]
|
||||
model = models.Model([i1, i2], o)
|
||||
|
||||
max_layer = layers.Maximum()
|
||||
@@ -94,7 +93,7 @@ def test_merge_concatenate():
|
||||
i1 = layers.Input(shape=(4, 5))
|
||||
i2 = layers.Input(shape=(4, 5))
|
||||
o = layers.concatenate([i1, i2], axis=1)
|
||||
assert o._keras_shape == (None, 8, 5)
|
||||
assert o.get_shape().as_list() == [None, 8, 5]
|
||||
model = models.Model([i1, i2], o)
|
||||
|
||||
concat_layer = layers.Concatenate(axis=1)
|
||||
@@ -127,7 +126,7 @@ def test_merge_dot():
|
||||
i1 = layers.Input(shape=(4,))
|
||||
i2 = layers.Input(shape=(4,))
|
||||
o = layers.dot([i1, i2], axes=1)
|
||||
assert o._keras_shape == (None, 1)
|
||||
assert o.get_shape().as_list() == [None, 1]
|
||||
model = models.Model([i1, i2], o)
|
||||
|
||||
dot_layer = layers.Dot(axes=1)
|
||||
@@ -145,7 +144,7 @@ def test_merge_dot():
|
||||
|
||||
# Test with negative tuple of axes.
|
||||
o = layers.dot([i1, i2], axes=(-1, -1))
|
||||
assert o._keras_shape == (None, 1)
|
||||
assert o.get_shape().as_list() == [None, 1]
|
||||
model = models.Model([i1, i2], o)
|
||||
out = model.predict([x1, x2])
|
||||
assert out.shape == (2, 1)
|
||||
@@ -160,7 +159,7 @@ def test_merge_broadcast():
|
||||
ops = [layers.add, layers.maximum]
|
||||
for op in ops:
|
||||
o = op([i1, i2])
|
||||
assert o._keras_shape == (None, 4, 5)
|
||||
assert K.int_shape(o) == (None, 4, 5)
|
||||
model = models.Model([i1, i2], o)
|
||||
|
||||
x1 = np.random.random((2, 4, 5))
|
||||
@@ -174,7 +173,7 @@ def test_merge_broadcast():
|
||||
ops = [layers.add, layers.maximum]
|
||||
for op in ops:
|
||||
o = op([i1, i2])
|
||||
assert o._keras_shape == (None, None, None)
|
||||
assert K.int_shape(o) == (None, None, None)
|
||||
model = models.Model([i1, i2], o)
|
||||
|
||||
x1 = np.random.random((2, 4, 5))
|
||||
@@ -192,7 +191,6 @@ def test_merge_broadcast():
|
||||
ops = [layers.add, layers.maximum]
|
||||
for op in ops:
|
||||
o = op([i1, i2])
|
||||
assert o._keras_shape == (None, None, None)
|
||||
model = models.Model([i1, i2], o)
|
||||
|
||||
x1 = np.random.random((2, 4, 5))
|
||||
|
||||
@@ -2,12 +2,9 @@ import pytest
|
||||
from keras.utils.test_utils import layer_test
|
||||
from keras.utils.test_utils import keras_test
|
||||
from keras.layers import noise
|
||||
from keras import backend as K
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support it yet")
|
||||
def test_GaussianNoise():
|
||||
layer_test(noise.GaussianNoise,
|
||||
kwargs={'stddev': 1.},
|
||||
@@ -15,8 +12,6 @@ def test_GaussianNoise():
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support it yet")
|
||||
def test_GaussianDropout():
|
||||
layer_test(noise.GaussianDropout,
|
||||
kwargs={'rate': 0.5},
|
||||
|
||||
@@ -77,8 +77,6 @@ def test_implementation_mode(layer_class):
|
||||
|
||||
|
||||
@rnn_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support stateful RNN yet")
|
||||
def test_statefulness(layer_class):
|
||||
model = Sequential()
|
||||
model.add(embeddings.Embedding(embedding_num, embedding_dim,
|
||||
@@ -149,8 +147,6 @@ def test_regularizer(layer_class):
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support mask on RNN yet")
|
||||
def test_masking_layer():
|
||||
''' This test based on a previously failing issue here:
|
||||
https://github.com/fchollet/keras/issues/1567
|
||||
@@ -174,9 +170,7 @@ def test_masking_layer():
|
||||
|
||||
@rnn_test
|
||||
def test_from_config(layer_class):
|
||||
# cntk does not support stateful yet.
|
||||
stateful_flags = (False, True) if K.backend() != 'cntk' else (False,)
|
||||
for stateful in stateful_flags:
|
||||
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()
|
||||
@@ -226,8 +220,6 @@ def test_specify_initial_state_non_keras_tensor(layer_class):
|
||||
|
||||
|
||||
@rnn_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support stateful RNN yet")
|
||||
def test_reset_states_with_values(layer_class):
|
||||
num_states = 2 if layer_class is recurrent.LSTM else 1
|
||||
|
||||
@@ -261,7 +253,7 @@ def test_specify_state_with_masking(layer_class):
|
||||
num_states = 2 if layer_class is recurrent.LSTM else 1
|
||||
|
||||
inputs = Input((timesteps, embedding_dim))
|
||||
_ = Masking()(inputs)
|
||||
masked_inputs = Masking()(inputs)
|
||||
initial_state = [Input((units,)) for _ in range(num_states)]
|
||||
output = layer_class(units)(inputs, initial_state=initial_state)
|
||||
|
||||
@@ -274,37 +266,5 @@ def test_specify_state_with_masking(layer_class):
|
||||
targets = np.random.random((num_samples, units))
|
||||
model.fit([inputs] + initial_state, targets)
|
||||
|
||||
|
||||
@rnn_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support stateful RNN yet")
|
||||
def test_return_state(layer_class):
|
||||
num_states = 2 if layer_class is recurrent.LSTM else 1
|
||||
|
||||
inputs = Input(batch_shape=(num_samples, timesteps, embedding_dim))
|
||||
layer = layer_class(units, return_state=True, stateful=True)
|
||||
outputs = layer(inputs)
|
||||
output, state = outputs[0], outputs[1:]
|
||||
assert len(state) == num_states
|
||||
model = Model(inputs, state[0])
|
||||
|
||||
inputs = np.random.random((num_samples, timesteps, embedding_dim))
|
||||
state = model.predict(inputs)
|
||||
np.testing.assert_allclose(K.eval(layer.states[0]), state, atol=1e-4)
|
||||
|
||||
|
||||
@rnn_test
|
||||
def test_state_reuse(layer_class):
|
||||
inputs = Input(batch_shape=(num_samples, timesteps, embedding_dim))
|
||||
layer = layer_class(units, return_state=True, return_sequences=True)
|
||||
outputs = layer(inputs)
|
||||
output, state = outputs[0], outputs[1:]
|
||||
output = layer_class(units)(output, initial_state=state)
|
||||
model = Model(inputs, output)
|
||||
|
||||
inputs = np.random.random((num_samples, timesteps, embedding_dim))
|
||||
outputs = model.predict(inputs)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__])
|
||||
|
||||
@@ -5,7 +5,6 @@ from keras.utils.test_utils import keras_test
|
||||
from keras.layers import wrappers, Input
|
||||
from keras.layers import core, convolutional, recurrent, embeddings
|
||||
from keras.models import Sequential, Model, model_from_json
|
||||
from keras import backend as K
|
||||
|
||||
|
||||
@keras_test
|
||||
@@ -109,8 +108,6 @@ def test_regularizers():
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support reverse yet")
|
||||
def test_Bidirectional():
|
||||
rnn = recurrent.SimpleRNN
|
||||
samples = 2
|
||||
|
||||
@@ -1,849 +0,0 @@
|
||||
import pytest
|
||||
import json
|
||||
from keras.utils.test_utils import keras_test
|
||||
import keras
|
||||
import numpy as np
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_dense_legacy_interface():
|
||||
old_layer = keras.layers.Dense(input_dim=3, output_dim=2, name='d')
|
||||
new_layer = keras.layers.Dense(2, input_shape=(3,), name='d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Dense(2, bias=False, init='normal',
|
||||
W_regularizer='l1',
|
||||
W_constraint='maxnorm', name='d')
|
||||
new_layer = keras.layers.Dense(2, use_bias=False,
|
||||
kernel_initializer='normal',
|
||||
kernel_regularizer='l1',
|
||||
kernel_constraint='max_norm', name='d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Dense(2, bias=True,
|
||||
b_regularizer='l1',
|
||||
b_constraint='maxnorm', name='d')
|
||||
new_layer = keras.layers.Dense(2, use_bias=True,
|
||||
bias_regularizer='l1',
|
||||
bias_constraint='max_norm', name='d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_dropout_legacy_interface():
|
||||
old_layer = keras.layers.Dropout(p=3, name='drop')
|
||||
new_layer_1 = keras.layers.Dropout(rate=3, name='drop')
|
||||
new_layer_2 = keras.layers.Dropout(3, name='drop')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer_1.get_config())
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer_2.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_embedding_legacy_interface():
|
||||
old_layer = keras.layers.Embedding(4, 2, name='d')
|
||||
new_layer = keras.layers.Embedding(output_dim=2, input_dim=4, name='d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Embedding(input_dim=4, output_dim=2, name='d',
|
||||
init='normal',
|
||||
W_regularizer='l1',
|
||||
W_constraint='maxnorm')
|
||||
new_layer = keras.layers.Embedding(input_dim=4, output_dim=2, name='d',
|
||||
embeddings_initializer='normal',
|
||||
embeddings_regularizer='l1',
|
||||
embeddings_constraint='max_norm')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Embedding(1, 1, dropout=0.0, name='d')
|
||||
new_layer = keras.layers.Embedding(1, 1, name='d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_maxpooling1d_legacy_interface():
|
||||
old_layer = keras.layers.MaxPool1D(pool_length=2,
|
||||
border_mode='valid',
|
||||
name='maxpool1d')
|
||||
new_layer = keras.layers.MaxPool1D(pool_size=2,
|
||||
padding='valid',
|
||||
name='maxpool1d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.MaxPool1D(2, padding='valid', name='maxpool1d')
|
||||
new_layer = keras.layers.MaxPool1D(pool_size=2,
|
||||
padding='valid',
|
||||
name='maxpool1d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_avgpooling1d_legacy_interface():
|
||||
old_layer = keras.layers.AvgPool1D(pool_length=2,
|
||||
border_mode='valid',
|
||||
name='d')
|
||||
new_layer = keras.layers.AvgPool1D(pool_size=2, padding='valid', name='d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.AvgPool1D(2, padding='valid', name='d')
|
||||
new_layer = keras.layers.AvgPool1D(pool_size=2, padding='valid', name='d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_prelu_legacy_interface():
|
||||
old_layer = keras.layers.PReLU(init='zero', name='p')
|
||||
new_layer = keras.layers.PReLU('zero', name='p')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_gaussiannoise_legacy_interface():
|
||||
old_layer = keras.layers.GaussianNoise(sigma=0.5, name='gn')
|
||||
new_layer = keras.layers.GaussianNoise(stddev=0.5, name='gn')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_lstm_legacy_interface():
|
||||
old_layer = keras.layers.LSTM(input_shape=[3, 5], output_dim=2, name='d')
|
||||
new_layer = keras.layers.LSTM(2, input_shape=[3, 5], name='d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.LSTM(input_shape=[3, 5], output_dim=2, name='d', consume_less='mem')
|
||||
new_layer = keras.layers.LSTM(2, input_shape=[3, 5], name='d', implementation=1)
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.LSTM(input_dim=5, input_length=3,
|
||||
output_dim=2, name='d', consume_less='mem')
|
||||
new_layer = keras.layers.LSTM(2, input_shape=[3, 5], name='d', implementation=1)
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.LSTM(input_dim=5,
|
||||
output_dim=2, name='d', consume_less='mem')
|
||||
new_layer = keras.layers.LSTM(2, input_shape=[None, 5], name='d', implementation=1)
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.LSTM(input_shape=[3, 5], output_dim=2, name='d', consume_less='gpu')
|
||||
new_layer = keras.layers.LSTM(2, input_shape=[3, 5], name='d', implementation=2)
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.LSTM(2, init='normal',
|
||||
inner_init='glorot_uniform',
|
||||
forget_bias_init='one',
|
||||
inner_activation='hard_sigmoid',
|
||||
W_regularizer='l1',
|
||||
U_regularizer='l1',
|
||||
b_regularizer='l1',
|
||||
dropout_W=0.1,
|
||||
dropout_U=0.1,
|
||||
name='LSTM')
|
||||
|
||||
new_layer = keras.layers.LSTM(2, kernel_initializer='normal',
|
||||
recurrent_initializer='glorot_uniform',
|
||||
unit_forget_bias=True,
|
||||
recurrent_activation='hard_sigmoid',
|
||||
kernel_regularizer='l1',
|
||||
recurrent_regularizer='l1',
|
||||
bias_regularizer='l1',
|
||||
dropout=0.1,
|
||||
recurrent_dropout=0.1,
|
||||
name='LSTM')
|
||||
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.LSTM(2, init='normal',
|
||||
inner_init='glorot_uniform',
|
||||
forget_bias_init='zero',
|
||||
inner_activation='hard_sigmoid',
|
||||
W_regularizer='l1',
|
||||
U_regularizer='l1',
|
||||
b_regularizer='l1',
|
||||
dropout_W=0.1,
|
||||
dropout_U=0.1,
|
||||
name='LSTM')
|
||||
|
||||
new_layer = keras.layers.LSTM(2, kernel_initializer='normal',
|
||||
recurrent_initializer='glorot_uniform',
|
||||
unit_forget_bias=True,
|
||||
recurrent_activation='hard_sigmoid',
|
||||
kernel_regularizer='l1',
|
||||
recurrent_regularizer='l1',
|
||||
bias_regularizer='l1',
|
||||
dropout=0.1,
|
||||
recurrent_dropout=0.1,
|
||||
name='LSTM')
|
||||
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_simplernn_legacy_interface():
|
||||
old_layer = keras.layers.SimpleRNN(input_shape=[3, 5], output_dim=2, name='d')
|
||||
new_layer = keras.layers.SimpleRNN(2, input_shape=[3, 5], name='d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.SimpleRNN(2, init='normal',
|
||||
inner_init='glorot_uniform',
|
||||
W_regularizer='l1',
|
||||
U_regularizer='l1',
|
||||
b_regularizer='l1',
|
||||
dropout_W=0.1,
|
||||
dropout_U=0.1,
|
||||
name='SimpleRNN')
|
||||
new_layer = keras.layers.SimpleRNN(2, kernel_initializer='normal',
|
||||
recurrent_initializer='glorot_uniform',
|
||||
kernel_regularizer='l1',
|
||||
recurrent_regularizer='l1',
|
||||
bias_regularizer='l1',
|
||||
dropout=0.1,
|
||||
recurrent_dropout=0.1,
|
||||
name='SimpleRNN')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_gru_legacy_interface():
|
||||
old_layer = keras.layers.GRU(input_shape=[3, 5], output_dim=2, name='d')
|
||||
new_layer = keras.layers.GRU(2, input_shape=[3, 5], name='d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.GRU(2, init='normal',
|
||||
inner_init='glorot_uniform',
|
||||
inner_activation='hard_sigmoid',
|
||||
W_regularizer='l1',
|
||||
U_regularizer='l1',
|
||||
b_regularizer='l1',
|
||||
dropout_W=0.1,
|
||||
dropout_U=0.1,
|
||||
name='GRU')
|
||||
new_layer = keras.layers.GRU(2, kernel_initializer='normal',
|
||||
recurrent_initializer='glorot_uniform',
|
||||
recurrent_activation='hard_sigmoid',
|
||||
kernel_regularizer='l1',
|
||||
recurrent_regularizer='l1',
|
||||
bias_regularizer='l1',
|
||||
dropout=0.1,
|
||||
recurrent_dropout=0.1,
|
||||
name='GRU')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_gaussiandropout_legacy_interface():
|
||||
old_layer = keras.layers.GaussianDropout(p=0.6, name='drop')
|
||||
new_layer_1 = keras.layers.GaussianDropout(rate=0.6, name='drop')
|
||||
new_layer_2 = keras.layers.GaussianDropout(0.6, name='drop')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer_1.get_config())
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer_2.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_maxpooling2d_legacy_interface():
|
||||
old_layer = keras.layers.MaxPooling2D(pool_size=(2, 2), border_mode='valid', name='maxpool2d')
|
||||
new_layer = keras.layers.MaxPool2D(pool_size=2, padding='valid', name='maxpool2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.MaxPooling2D((2, 2), 2, 'valid', name='maxpool2d')
|
||||
new_layer = keras.layers.MaxPool2D(pool_size=2, strides=2, padding='valid', name='maxpool2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.MaxPooling2D((2, 2), padding='valid', dim_ordering='tf', name='maxpool2d')
|
||||
new_layer = keras.layers.MaxPool2D(pool_size=2, padding='valid', data_format='channels_last', name='maxpool2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.MaxPooling2D((2, 2), padding='valid', dim_ordering='th', name='maxpool2d')
|
||||
new_layer = keras.layers.MaxPool2D(pool_size=2, padding='valid', data_format='channels_first', name='maxpool2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.MaxPooling2D((2, 2), padding='valid', dim_ordering='default', name='maxpool2d')
|
||||
new_layer = keras.layers.MaxPool2D(pool_size=2, padding='valid', name='maxpool2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_avgpooling2d_legacy_interface():
|
||||
old_layer = keras.layers.AveragePooling2D(pool_size=(2, 2), border_mode='valid', name='avgpooling2d')
|
||||
new_layer = keras.layers.AvgPool2D(pool_size=(2, 2), padding='valid', name='avgpooling2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.AveragePooling2D((2, 2), (2, 2), 'valid', name='avgpooling2d')
|
||||
new_layer = keras.layers.AvgPool2D(pool_size=(2, 2), strides=(2, 2), padding='valid', name='avgpooling2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.AveragePooling2D((2, 2), padding='valid', dim_ordering='tf', name='avgpooling2d')
|
||||
new_layer = keras.layers.AvgPool2D(pool_size=2, padding='valid', data_format='channels_last', name='avgpooling2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.AveragePooling2D((2, 2), padding='valid', dim_ordering='th', name='avgpooling2d')
|
||||
new_layer = keras.layers.AvgPool2D(pool_size=2, padding='valid', data_format='channels_first', name='avgpooling2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.AveragePooling2D((2, 2), padding='valid', dim_ordering='default', name='avgpooling2d')
|
||||
new_layer = keras.layers.AvgPool2D(pool_size=2, padding='valid', name='avgpooling2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_maxpooling3d_legacy_interface():
|
||||
old_layer = keras.layers.MaxPooling3D(pool_size=(2, 2, 2), border_mode='valid', name='maxpool3d')
|
||||
new_layer = keras.layers.MaxPool3D(pool_size=(2, 2, 2), padding='valid', name='maxpool3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.MaxPooling3D((2, 2, 2), (2, 2, 2), 'valid', name='maxpool3d')
|
||||
new_layer = keras.layers.MaxPool3D(pool_size=(2, 2, 2), strides=(2, 2, 2), padding='valid', name='maxpool3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.MaxPooling3D((2, 2, 2), padding='valid', dim_ordering='tf', name='maxpool3d')
|
||||
new_layer = keras.layers.MaxPool3D(pool_size=(2, 2, 2), padding='valid', data_format='channels_last', name='maxpool3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.MaxPooling3D((2, 2, 2), padding='valid', dim_ordering='th', name='maxpool3d')
|
||||
new_layer = keras.layers.MaxPool3D(pool_size=(2, 2, 2), padding='valid', data_format='channels_first', name='maxpool3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.MaxPooling3D((2, 2, 2), padding='valid', dim_ordering='default', name='maxpool3d')
|
||||
new_layer = keras.layers.MaxPool3D(pool_size=(2, 2, 2), padding='valid', name='maxpool3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_avgpooling3d_legacy_interface():
|
||||
old_layer = keras.layers.AveragePooling3D(pool_size=(2, 2, 2), border_mode='valid', name='avgpooling3d')
|
||||
new_layer = keras.layers.AvgPool3D(pool_size=(2, 2, 2), padding='valid', name='avgpooling3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.AveragePooling3D((2, 2, 2), (2, 2, 2), 'valid', name='avgpooling3d')
|
||||
new_layer = keras.layers.AvgPool3D(pool_size=(2, 2, 2), strides=(2, 2, 2), padding='valid', name='avgpooling3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.AveragePooling3D((2, 2, 2), padding='valid', dim_ordering='tf', name='avgpooling3d')
|
||||
new_layer = keras.layers.AvgPool3D(pool_size=(2, 2, 2), padding='valid', data_format='channels_last', name='avgpooling3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.AveragePooling3D((2, 2, 2), padding='valid', dim_ordering='th', name='avgpooling3d')
|
||||
new_layer = keras.layers.AvgPool3D(pool_size=(2, 2, 2), padding='valid', data_format='channels_first', name='avgpooling3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.AveragePooling3D((2, 2, 2), padding='valid', dim_ordering='default', name='avgpooling3d')
|
||||
new_layer = keras.layers.AvgPool3D(pool_size=(2, 2, 2), padding='valid', name='avgpooling3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_global_maxpooling2d_legacy_interface():
|
||||
old_layer = keras.layers.GlobalMaxPooling2D(dim_ordering='tf', name='global_maxpool2d')
|
||||
new_layer = keras.layers.GlobalMaxPool2D(data_format='channels_last', name='global_maxpool2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.GlobalMaxPooling2D(dim_ordering='th', name='global_maxpool2d')
|
||||
new_layer = keras.layers.GlobalMaxPool2D(data_format='channels_first', name='global_maxpool2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.GlobalMaxPooling2D(dim_ordering='default', name='global_maxpool2d')
|
||||
new_layer = keras.layers.GlobalMaxPool2D(name='global_maxpool2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_global_avgpooling2d_legacy_interface():
|
||||
old_layer = keras.layers.GlobalAveragePooling2D(dim_ordering='tf', name='global_avgpool2d')
|
||||
new_layer = keras.layers.GlobalAvgPool2D(data_format='channels_last', name='global_avgpool2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.GlobalAveragePooling2D(dim_ordering='th', name='global_avgpool2d')
|
||||
new_layer = keras.layers.GlobalAvgPool2D(data_format='channels_first', name='global_avgpool2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.GlobalAveragePooling2D(dim_ordering='default', name='global_avgpool2d')
|
||||
new_layer = keras.layers.GlobalAvgPool2D(name='global_avgpool2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_global_maxpooling3d_legacy_interface():
|
||||
old_layer = keras.layers.GlobalMaxPooling3D(dim_ordering='tf', name='global_maxpool3d')
|
||||
new_layer = keras.layers.GlobalMaxPool3D(data_format='channels_last', name='global_maxpool3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.GlobalMaxPooling3D(dim_ordering='th', name='global_maxpool3d')
|
||||
new_layer = keras.layers.GlobalMaxPool3D(data_format='channels_first', name='global_maxpool3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.GlobalMaxPooling3D(dim_ordering='default', name='global_maxpool3d')
|
||||
new_layer = keras.layers.GlobalMaxPool3D(name='global_maxpool3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_global_avgpooling3d_legacy_interface():
|
||||
old_layer = keras.layers.GlobalAveragePooling3D(dim_ordering='tf', name='global_avgpool3d')
|
||||
new_layer = keras.layers.GlobalAvgPool3D(data_format='channels_last', name='global_avgpool3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.GlobalAveragePooling3D(dim_ordering='th', name='global_avgpool3d')
|
||||
new_layer = keras.layers.GlobalAvgPool3D(data_format='channels_first', name='global_avgpool3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.GlobalAveragePooling3D(dim_ordering='default', name='global_avgpool3d')
|
||||
new_layer = keras.layers.GlobalAvgPool3D(name='global_avgpool3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_upsampling1d_legacy_interface():
|
||||
old_layer = keras.layers.UpSampling1D(length=3, name='us1d')
|
||||
new_layer_1 = keras.layers.UpSampling1D(size=3, name='us1d')
|
||||
new_layer_2 = keras.layers.UpSampling1D(3, name='us1d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer_1.get_config())
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer_2.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_upsampling2d_legacy_interface():
|
||||
old_layer = keras.layers.UpSampling2D((2, 2), dim_ordering='tf', name='us2d')
|
||||
new_layer = keras.layers.UpSampling2D((2, 2), data_format='channels_last', name='us2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_upsampling3d_legacy_interface():
|
||||
old_layer = keras.layers.UpSampling3D((2, 2, 2),
|
||||
dim_ordering='tf',
|
||||
name='us3d')
|
||||
new_layer = keras.layers.UpSampling3D((2, 2, 2),
|
||||
data_format='channels_last',
|
||||
name='us3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_conv2d_legacy_interface():
|
||||
old_layer = keras.layers.Convolution2D(5, 3, 3, name='conv')
|
||||
new_layer = keras.layers.Conv2D(5, (3, 3), name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Convolution2D(5, 3, nb_col=3, name='conv')
|
||||
new_layer = keras.layers.Conv2D(5, (3, 3), name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Convolution2D(5, nb_row=3, nb_col=3, name='conv')
|
||||
new_layer = keras.layers.Conv2D(5, (3, 3), name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Convolution2D(5, 3, 3,
|
||||
init='normal',
|
||||
subsample=(2, 2),
|
||||
border_mode='valid',
|
||||
dim_ordering='th',
|
||||
W_regularizer='l1',
|
||||
b_regularizer='l2',
|
||||
W_constraint='maxnorm',
|
||||
b_constraint='unitnorm',
|
||||
name='conv')
|
||||
new_layer = keras.layers.Conv2D(5, (3, 3),
|
||||
kernel_initializer='normal',
|
||||
strides=(2, 2),
|
||||
padding='valid',
|
||||
kernel_regularizer='l1',
|
||||
bias_regularizer='l2',
|
||||
kernel_constraint='max_norm',
|
||||
bias_constraint='unit_norm',
|
||||
data_format='channels_first',
|
||||
name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_deconv2d_legacy_interface():
|
||||
old_layer = keras.layers.Deconvolution2D(5, 3, 3, (6, 7, 5), name='deconv')
|
||||
new_layer = keras.layers.Conv2DTranspose(5, (3, 3), name='deconv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Deconvolution2D(5, 3, 3, output_shape=(6, 7, 5), name='deconv')
|
||||
new_layer = keras.layers.Conv2DTranspose(5, (3, 3), name='deconv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Deconvolution2D(5, 3, nb_col=3, output_shape=(6, 7, 5), name='deconv')
|
||||
new_layer = keras.layers.Conv2DTranspose(5, (3, 3), name='deconv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Deconvolution2D(5, nb_row=3, nb_col=3, output_shape=(6, 7, 5), name='deconv')
|
||||
new_layer = keras.layers.Conv2DTranspose(5, (3, 3), name='deconv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Deconvolution2D(5, 3, 3,
|
||||
output_shape=(6, 7, 5),
|
||||
init='normal',
|
||||
subsample=(2, 2),
|
||||
border_mode='valid',
|
||||
dim_ordering='th',
|
||||
W_regularizer='l1',
|
||||
b_regularizer='l2',
|
||||
W_constraint='maxnorm',
|
||||
b_constraint='unitnorm',
|
||||
name='conv')
|
||||
new_layer = keras.layers.Conv2DTranspose(
|
||||
5, (3, 3),
|
||||
kernel_initializer='normal',
|
||||
strides=(2, 2),
|
||||
padding='valid',
|
||||
kernel_regularizer='l1',
|
||||
bias_regularizer='l2',
|
||||
kernel_constraint='max_norm',
|
||||
bias_constraint='unit_norm',
|
||||
data_format='channels_first',
|
||||
name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_conv1d_legacy_interface():
|
||||
old_layer = keras.layers.Convolution1D(5,
|
||||
filter_length=3,
|
||||
input_dim=3,
|
||||
input_length=4,
|
||||
name='conv')
|
||||
new_layer = keras.layers.Conv1D(5, 3, name='conv', input_shape=(4, 3))
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Convolution1D(5, 3,
|
||||
init='normal',
|
||||
subsample_length=2,
|
||||
border_mode='valid',
|
||||
W_regularizer='l1',
|
||||
b_regularizer='l2',
|
||||
W_constraint='maxnorm',
|
||||
b_constraint='unitnorm',
|
||||
name='conv')
|
||||
new_layer = keras.layers.Conv1D(5, 3,
|
||||
kernel_initializer='normal',
|
||||
strides=2,
|
||||
padding='valid',
|
||||
kernel_regularizer='l1',
|
||||
bias_regularizer='l2',
|
||||
kernel_constraint='max_norm',
|
||||
bias_constraint='unit_norm',
|
||||
name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_separable_conv2d_legacy_interface():
|
||||
old_layer = keras.layers.SeparableConv2D(5, 3, 3, name='conv')
|
||||
new_layer = keras.layers.SeparableConv2D(5, (3, 3), name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.SeparableConv2D(5, 3, nb_col=3, name='conv')
|
||||
new_layer = keras.layers.SeparableConv2D(5, (3, 3), name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.SeparableConv2D(5, nb_row=3, nb_col=3, name='conv')
|
||||
new_layer = keras.layers.SeparableConv2D(5, (3, 3), name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.SeparableConv2D(5, 3, 3,
|
||||
init='normal',
|
||||
subsample=(2, 2),
|
||||
border_mode='valid',
|
||||
dim_ordering='th',
|
||||
depthwise_regularizer='l1',
|
||||
b_regularizer='l2',
|
||||
depthwise_constraint='maxnorm',
|
||||
b_constraint='unitnorm',
|
||||
name='conv')
|
||||
new_layer = keras.layers.SeparableConv2D(5, (3, 3),
|
||||
depthwise_initializer='normal',
|
||||
pointwise_initializer='normal',
|
||||
strides=(2, 2),
|
||||
padding='valid',
|
||||
depthwise_regularizer='l1',
|
||||
bias_regularizer='l2',
|
||||
depthwise_constraint='max_norm',
|
||||
bias_constraint='unit_norm',
|
||||
data_format='channels_first',
|
||||
name='conv')
|
||||
old_config = json.dumps(old_layer.get_config())
|
||||
new_config = json.dumps(new_layer.get_config())
|
||||
assert old_config == new_config
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_conv3d_legacy_interface():
|
||||
old_layer = keras.layers.Convolution3D(5, 3, 3, 4, name='conv')
|
||||
new_layer = keras.layers.Conv3D(5, (3, 3, 4), name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Convolution3D(5, 3, 3, kernel_dim3=4, name='conv')
|
||||
new_layer = keras.layers.Conv3D(5, (3, 3, 4), name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Convolution3D(5, 3,
|
||||
kernel_dim2=3,
|
||||
kernel_dim3=4,
|
||||
name='conv')
|
||||
new_layer = keras.layers.Conv3D(5, (3, 3, 4), name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Convolution3D(5,
|
||||
kernel_dim1=3,
|
||||
kernel_dim2=3,
|
||||
kernel_dim3=4,
|
||||
name='conv')
|
||||
new_layer = keras.layers.Conv3D(5, (3, 3, 4), name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.Convolution3D(5, 3, 3, 4,
|
||||
init='normal',
|
||||
subsample=(2, 2, 2),
|
||||
border_mode='valid',
|
||||
dim_ordering='th',
|
||||
W_regularizer='l1',
|
||||
b_regularizer='l2',
|
||||
W_constraint='maxnorm',
|
||||
b_constraint='unitnorm',
|
||||
name='conv')
|
||||
new_layer = keras.layers.Conv3D(5, (3, 3, 4),
|
||||
kernel_initializer='normal',
|
||||
strides=(2, 2, 2),
|
||||
padding='valid',
|
||||
kernel_regularizer='l1',
|
||||
bias_regularizer='l2',
|
||||
kernel_constraint='max_norm',
|
||||
bias_constraint='unit_norm',
|
||||
data_format='channels_first',
|
||||
name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_convlstm2d_legacy_interface():
|
||||
old_layer = keras.layers.ConvLSTM2D(5, 3, 3, name='conv')
|
||||
new_layer = keras.layers.ConvLSTM2D(5, (3, 3), name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.ConvLSTM2D(5, 3, nb_col=3, name='conv')
|
||||
new_layer = keras.layers.ConvLSTM2D(5, (3, 3), name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.ConvLSTM2D(5, nb_row=3, nb_col=3, name='conv')
|
||||
new_layer = keras.layers.ConvLSTM2D(5, (3, 3), name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.ConvLSTM2D(5, 3, 3,
|
||||
init='normal',
|
||||
inner_init='uniform',
|
||||
forget_bias_init='one',
|
||||
inner_activation='relu',
|
||||
subsample=(2, 2),
|
||||
border_mode='valid',
|
||||
dim_ordering='th',
|
||||
W_regularizer='l1',
|
||||
U_regularizer='l2',
|
||||
b_regularizer='l2',
|
||||
dropout_W=0.2,
|
||||
dropout_U=0.1,
|
||||
name='conv')
|
||||
new_layer = keras.layers.ConvLSTM2D(5, (3, 3),
|
||||
kernel_initializer='normal',
|
||||
recurrent_initializer='uniform',
|
||||
unit_forget_bias=True,
|
||||
recurrent_activation='relu',
|
||||
strides=(2, 2),
|
||||
padding='valid',
|
||||
kernel_regularizer='l1',
|
||||
recurrent_regularizer='l2',
|
||||
bias_regularizer='l2',
|
||||
data_format='channels_first',
|
||||
dropout=0.2,
|
||||
recurrent_dropout=0.1,
|
||||
name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_batchnorm_legacy_interface():
|
||||
old_layer = keras.layers.BatchNormalization(mode=0, name='bn')
|
||||
new_layer = keras.layers.BatchNormalization(name='bn')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
old_layer = keras.layers.BatchNormalization(mode=0,
|
||||
beta_init='one',
|
||||
gamma_init='uniform',
|
||||
name='bn')
|
||||
new_layer = keras.layers.BatchNormalization(beta_initializer='ones',
|
||||
gamma_initializer='uniform',
|
||||
name='bn')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_atrousconv1d_legacy_interface():
|
||||
old_layer = keras.layers.AtrousConvolution1D(5, 3,
|
||||
init='normal',
|
||||
subsample_length=2,
|
||||
border_mode='valid',
|
||||
W_regularizer='l1',
|
||||
b_regularizer='l2',
|
||||
W_constraint='maxnorm',
|
||||
b_constraint='unitnorm',
|
||||
atrous_rate=2,
|
||||
name='conv')
|
||||
new_layer = keras.layers.Conv1D(5, 3,
|
||||
kernel_initializer='normal',
|
||||
strides=2,
|
||||
padding='valid',
|
||||
kernel_regularizer='l1',
|
||||
bias_regularizer='l2',
|
||||
kernel_constraint='max_norm',
|
||||
bias_constraint='unit_norm',
|
||||
dilation_rate=2,
|
||||
name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_atrousconv2d_legacy_interface():
|
||||
old_layer = keras.layers.AtrousConvolution2D(
|
||||
5, 3, 3,
|
||||
atrous_rate=(2, 2),
|
||||
init='normal',
|
||||
subsample=(2, 2),
|
||||
border_mode='valid',
|
||||
dim_ordering='th',
|
||||
W_regularizer='l1',
|
||||
b_regularizer='l2',
|
||||
W_constraint='maxnorm',
|
||||
b_constraint='unitnorm',
|
||||
name='conv')
|
||||
new_layer = keras.layers.Conv2D(5, (3, 3),
|
||||
kernel_initializer='normal',
|
||||
strides=(2, 2),
|
||||
padding='valid',
|
||||
kernel_regularizer='l1',
|
||||
bias_regularizer='l2',
|
||||
kernel_constraint='max_norm',
|
||||
bias_constraint='unit_norm',
|
||||
data_format='channels_first',
|
||||
dilation_rate=(2, 2),
|
||||
name='conv')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_zeropadding2d_legacy_interface():
|
||||
old_layer = keras.layers.ZeroPadding2D(padding={'right_pad': 4,
|
||||
'bottom_pad': 2,
|
||||
'top_pad': 1,
|
||||
'left_pad': 3},
|
||||
dim_ordering='tf',
|
||||
name='zp2d')
|
||||
new_layer = keras.layers.ZeroPadding2D(((1, 2), (3, 4)),
|
||||
data_format='channels_last',
|
||||
name='zp2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_zeropadding3d_legacy_interface():
|
||||
old_layer = keras.layers.ZeroPadding3D((2, 2, 2),
|
||||
dim_ordering='tf',
|
||||
name='zp3d')
|
||||
new_layer = keras.layers.ZeroPadding3D((2, 2, 2),
|
||||
data_format='channels_last',
|
||||
name='zp3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_cropping2d_legacy_interface():
|
||||
old_layer = keras.layers.Cropping2D(dim_ordering='tf', name='c2d')
|
||||
new_layer = keras.layers.Cropping2D(data_format='channels_last', name='c2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_cropping3d_legacy_interface():
|
||||
old_layer = keras.layers.Cropping3D(dim_ordering='tf', name='c3d')
|
||||
new_layer = keras.layers.Cropping3D(data_format='channels_last', name='c3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_generator_methods_interface():
|
||||
def train_generator():
|
||||
x = np.random.randn(2, 2)
|
||||
y = np.random.randint(0, 2, size=[2, 1])
|
||||
while True:
|
||||
yield (x, y)
|
||||
|
||||
def val_generator():
|
||||
x = np.random.randn(2, 2)
|
||||
y = np.random.randint(0, 2, size=[2, 1])
|
||||
while True:
|
||||
yield (x, y)
|
||||
|
||||
def pred_generator():
|
||||
x = np.random.randn(1, 2)
|
||||
while True:
|
||||
yield x
|
||||
|
||||
x = keras.layers.Input(shape=(2, ))
|
||||
y = keras.layers.Dense(2)(x)
|
||||
|
||||
model = keras.models.Model(inputs=x, outputs=y)
|
||||
model.compile(optimizer='rmsprop',
|
||||
loss='sparse_categorical_crossentropy',
|
||||
metrics=['accuracy'])
|
||||
model.fit_generator(generator=train_generator(),
|
||||
samples_per_epoch=1,
|
||||
validation_data=val_generator(),
|
||||
nb_val_samples=1,
|
||||
nb_worker=1)
|
||||
model.evaluate_generator(generator=train_generator(),
|
||||
val_samples=2,
|
||||
nb_worker=1)
|
||||
model.predict_generator(generator=pred_generator(),
|
||||
val_samples=2,
|
||||
nb_worker=1)
|
||||
|
||||
|
||||
def test_spatialdropout1d_legacy_interface():
|
||||
old_layer = keras.layers.SpatialDropout1D(p=0.6, name='sd1d')
|
||||
new_layer_1 = keras.layers.SpatialDropout1D(rate=0.6, name='sd1d')
|
||||
new_layer_2 = keras.layers.SpatialDropout1D(0.6, name='sd1d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer_1.get_config())
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer_2.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_spatialdropout2d_legacy_interface():
|
||||
old_layer = keras.layers.SpatialDropout2D(p=0.5,
|
||||
dim_ordering='tf',
|
||||
name='sd2d')
|
||||
new_layer_1 = keras.layers.SpatialDropout2D(rate=0.5,
|
||||
data_format='channels_last',
|
||||
name='sd2d')
|
||||
new_layer_2 = keras.layers.SpatialDropout2D(0.5,
|
||||
data_format='channels_last',
|
||||
name='sd2d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer_1.get_config())
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer_2.get_config())
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_spatialdropout3d_legacy_interface():
|
||||
old_layer = keras.layers.SpatialDropout3D(p=0.5,
|
||||
dim_ordering='tf',
|
||||
name='sd3d')
|
||||
new_layer_1 = keras.layers.SpatialDropout3D(rate=0.5,
|
||||
data_format='channels_last',
|
||||
name='sd3d')
|
||||
new_layer_2 = keras.layers.SpatialDropout3D(0.5,
|
||||
data_format='channels_last',
|
||||
name='sd3d')
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer_1.get_config())
|
||||
assert json.dumps(old_layer.get_config()) == json.dumps(new_layer_2.get_config())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__])
|
||||
@@ -1,321 +0,0 @@
|
||||
import pytest
|
||||
|
||||
from keras.utils.test_utils import keras_test
|
||||
from keras.utils.test_utils import layer_test
|
||||
from keras.legacy import layers as legacy_layers
|
||||
from keras import layers
|
||||
from keras import models
|
||||
from keras import regularizers
|
||||
from keras import constraints
|
||||
from keras import backend as K
|
||||
import numpy as np
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_highway():
|
||||
layer_test(legacy_layers.Highway,
|
||||
kwargs={},
|
||||
input_shape=(3, 2))
|
||||
|
||||
layer_test(legacy_layers.Highway,
|
||||
kwargs={'W_regularizer': regularizers.l2(0.01),
|
||||
'b_regularizer': regularizers.l1(0.01),
|
||||
'activity_regularizer': regularizers.l2(0.01),
|
||||
'W_constraint': constraints.MaxNorm(1),
|
||||
'b_constraint': constraints.MaxNorm(1)},
|
||||
input_shape=(3, 2))
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_maxout_dense():
|
||||
layer_test(legacy_layers.MaxoutDense,
|
||||
kwargs={'output_dim': 3},
|
||||
input_shape=(3, 2))
|
||||
|
||||
layer_test(legacy_layers.MaxoutDense,
|
||||
kwargs={'output_dim': 3,
|
||||
'W_regularizer': regularizers.l2(0.01),
|
||||
'b_regularizer': regularizers.l1(0.01),
|
||||
'activity_regularizer': regularizers.l2(0.01),
|
||||
'W_constraint': constraints.MaxNorm(1),
|
||||
'b_constraint': constraints.MaxNorm(1)},
|
||||
input_shape=(3, 2))
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_merge():
|
||||
# test modes: 'sum', 'mul', 'concat', 'ave', 'cos', 'dot'.
|
||||
input_shapes = [(3, 2), (3, 2)]
|
||||
inputs = [np.random.random(shape) for shape in input_shapes]
|
||||
|
||||
# test functional API
|
||||
for mode in ['sum', 'mul', 'concat', 'ave', 'max']:
|
||||
print(mode)
|
||||
input_a = layers.Input(shape=input_shapes[0][1:])
|
||||
input_b = layers.Input(shape=input_shapes[1][1:])
|
||||
merged = legacy_layers.merge([input_a, input_b], mode=mode)
|
||||
model = models.Model([input_a, input_b], merged)
|
||||
model.compile('rmsprop', 'mse')
|
||||
|
||||
expected_output_shape = model.compute_output_shape(input_shapes)
|
||||
actual_output_shape = model.predict(inputs).shape
|
||||
assert expected_output_shape == actual_output_shape
|
||||
|
||||
config = model.get_config()
|
||||
model = models.Model.from_config(config)
|
||||
model.compile('rmsprop', 'mse')
|
||||
|
||||
# test Merge (#2460)
|
||||
merged = legacy_layers.Merge(mode=mode)([input_a, input_b])
|
||||
model = models.Model([input_a, input_b], merged)
|
||||
model.compile('rmsprop', 'mse')
|
||||
|
||||
expected_output_shape = model.compute_output_shape(input_shapes)
|
||||
actual_output_shape = model.predict(inputs).shape
|
||||
assert expected_output_shape == actual_output_shape
|
||||
|
||||
# test lambda with output_shape lambda
|
||||
input_a = layers.Input(shape=input_shapes[0][1:])
|
||||
input_b = layers.Input(shape=input_shapes[1][1:])
|
||||
merged = legacy_layers.merge(
|
||||
[input_a, input_b],
|
||||
mode=lambda tup: K.concatenate([tup[0], tup[1]]),
|
||||
output_shape=lambda tup: tup[0][:-1] + (tup[0][-1] + tup[1][-1],))
|
||||
model = models.Model([input_a, input_b], merged)
|
||||
expected_output_shape = model.compute_output_shape(input_shapes)
|
||||
actual_output_shape = model.predict(inputs).shape
|
||||
assert expected_output_shape == actual_output_shape
|
||||
|
||||
config = model.get_config()
|
||||
model = models.Model.from_config(config)
|
||||
model.compile('rmsprop', 'mse')
|
||||
|
||||
# test function with output_shape function
|
||||
def fn_mode(tup):
|
||||
x, y = tup
|
||||
return K.concatenate([x, y], axis=1)
|
||||
|
||||
def fn_output_shape(tup):
|
||||
s1, s2 = tup
|
||||
return (s1[0], s1[1] + s2[1]) + s1[2:]
|
||||
|
||||
input_a = layers.Input(shape=input_shapes[0][1:])
|
||||
input_b = layers.Input(shape=input_shapes[1][1:])
|
||||
merged = legacy_layers.merge([input_a, input_b],
|
||||
mode=fn_mode,
|
||||
output_shape=fn_output_shape)
|
||||
model = models.Model([input_a, input_b], merged)
|
||||
expected_output_shape = model.compute_output_shape(input_shapes)
|
||||
actual_output_shape = model.predict(inputs).shape
|
||||
assert expected_output_shape == actual_output_shape
|
||||
|
||||
config = model.get_config()
|
||||
model = models.Model.from_config(config)
|
||||
model.compile('rmsprop', 'mse')
|
||||
|
||||
# test function with output_mask function
|
||||
# time dimension is required for masking
|
||||
input_shapes = [(4, 3, 2), (4, 3, 2)]
|
||||
inputs = [np.random.random(shape) for shape in input_shapes]
|
||||
|
||||
def fn_output_mask(tup):
|
||||
x_mask, y_mask = tup
|
||||
return K.concatenate([x_mask, y_mask])
|
||||
|
||||
input_a = layers.Input(shape=input_shapes[0][1:])
|
||||
input_b = layers.Input(shape=input_shapes[1][1:])
|
||||
a = layers.Masking()(input_a)
|
||||
b = layers.Masking()(input_b)
|
||||
merged = legacy_layers.merge([a, b], mode=fn_mode, output_shape=fn_output_shape, output_mask=fn_output_mask)
|
||||
model = models.Model([input_a, input_b], merged)
|
||||
expected_output_shape = model.compute_output_shape(input_shapes)
|
||||
actual_output_shape = model.predict(inputs).shape
|
||||
assert expected_output_shape == actual_output_shape
|
||||
|
||||
config = model.get_config()
|
||||
model = models.Model.from_config(config)
|
||||
model.compile('rmsprop', 'mse')
|
||||
|
||||
mask_inputs = (np.zeros(input_shapes[0][:-1]), np.ones(input_shapes[1][:-1]))
|
||||
expected_mask_output = np.concatenate(mask_inputs, axis=-1)
|
||||
mask_input_placeholders = [K.placeholder(shape=input_shape[:-1]) for input_shape in input_shapes]
|
||||
mask_output = model.layers[-1]._output_mask(mask_input_placeholders)
|
||||
assert np.all(K.function(mask_input_placeholders, [mask_output])(mask_inputs)[0] == expected_mask_output)
|
||||
|
||||
# test lambda with output_mask lambda
|
||||
input_a = layers.Input(shape=input_shapes[0][1:])
|
||||
input_b = layers.Input(shape=input_shapes[1][1:])
|
||||
a = layers.Masking()(input_a)
|
||||
b = layers.Masking()(input_b)
|
||||
merged = legacy_layers.merge(
|
||||
[a, b], mode=lambda tup: K.concatenate([tup[0], tup[1]], axis=1),
|
||||
output_shape=lambda tup: (tup[0][0], tup[0][1] + tup[1][1]) + tup[0][2:],
|
||||
output_mask=lambda tup: K.concatenate([tup[0], tup[1]]))
|
||||
model = models.Model([input_a, input_b], merged)
|
||||
expected_output_shape = model.compute_output_shape(input_shapes)
|
||||
actual_output_shape = model.predict(inputs).shape
|
||||
assert expected_output_shape == actual_output_shape
|
||||
|
||||
config = model.get_config()
|
||||
model = models.Model.from_config(config)
|
||||
model.compile('rmsprop', 'mse')
|
||||
|
||||
mask_output = model.layers[-1]._output_mask(mask_input_placeholders)
|
||||
assert np.all(K.function(mask_input_placeholders, [mask_output])(mask_inputs)[0] == expected_mask_output)
|
||||
|
||||
# test with arguments
|
||||
input_shapes = [(3, 2), (3, 2)]
|
||||
inputs = [np.random.random(shape) for shape in input_shapes]
|
||||
|
||||
def fn_mode(tup, a, b):
|
||||
x, y = tup
|
||||
return x * a + y * b
|
||||
|
||||
input_a = layers.Input(shape=input_shapes[0][1:])
|
||||
input_b = layers.Input(shape=input_shapes[1][1:])
|
||||
merged = legacy_layers.merge([input_a, input_b], mode=fn_mode, output_shape=lambda s: s[0], arguments={'a': 0.7, 'b': 0.3})
|
||||
model = models.Model([input_a, input_b], merged)
|
||||
output = model.predict(inputs)
|
||||
|
||||
config = model.get_config()
|
||||
model = models.Model.from_config(config)
|
||||
|
||||
assert np.all(model.predict(inputs) == output)
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support stateful RNN yet")
|
||||
def test_merge_mask_2d():
|
||||
rand = lambda *shape: np.asarray(np.random.random(shape) > 0.5, dtype='int32')
|
||||
|
||||
# inputs
|
||||
input_a = layers.Input(shape=(3,))
|
||||
input_b = layers.Input(shape=(3,))
|
||||
|
||||
# masks
|
||||
masked_a = layers.Masking(mask_value=0)(input_a)
|
||||
masked_b = layers.Masking(mask_value=0)(input_b)
|
||||
|
||||
# three different types of merging
|
||||
merged_sum = legacy_layers.merge([masked_a, masked_b], mode='sum')
|
||||
merged_concat = legacy_layers.merge([masked_a, masked_b], mode='concat', concat_axis=1)
|
||||
merged_concat_mixed = legacy_layers.merge([masked_a, input_b], mode='concat', concat_axis=1)
|
||||
|
||||
# test sum
|
||||
model_sum = models.Model([input_a, input_b], [merged_sum])
|
||||
model_sum.compile(loss='mse', optimizer='sgd')
|
||||
model_sum.fit([rand(2, 3), rand(2, 3)], [rand(2, 3)], epochs=1)
|
||||
|
||||
# test concatenation
|
||||
model_concat = models.Model([input_a, input_b], [merged_concat])
|
||||
model_concat.compile(loss='mse', optimizer='sgd')
|
||||
model_concat.fit([rand(2, 3), rand(2, 3)], [rand(2, 6)], epochs=1)
|
||||
|
||||
# test concatenation with masked and non-masked inputs
|
||||
model_concat = models.Model([input_a, input_b], [merged_concat_mixed])
|
||||
model_concat.compile(loss='mse', optimizer='sgd')
|
||||
model_concat.fit([rand(2, 3), rand(2, 3)], [rand(2, 6)], epochs=1)
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="cntk does not support stateful RNN yet")
|
||||
def test_merge_mask_3d():
|
||||
rand = lambda *shape: np.asarray(np.random.random(shape) > 0.5, dtype='int32')
|
||||
|
||||
# embeddings
|
||||
input_a = layers.Input(shape=(3,), dtype='int32')
|
||||
input_b = layers.Input(shape=(3,), dtype='int32')
|
||||
embedding = layers.Embedding(3, 4, mask_zero=True)
|
||||
embedding_a = embedding(input_a)
|
||||
embedding_b = embedding(input_b)
|
||||
|
||||
# rnn
|
||||
rnn = layers.SimpleRNN(3, return_sequences=True)
|
||||
rnn_a = rnn(embedding_a)
|
||||
rnn_b = rnn(embedding_b)
|
||||
|
||||
# concatenation
|
||||
merged_concat = legacy_layers.merge([rnn_a, rnn_b], mode='concat', concat_axis=-1)
|
||||
model = models.Model([input_a, input_b], [merged_concat])
|
||||
model.compile(loss='mse', optimizer='sgd')
|
||||
model.fit([rand(2, 3), rand(2, 3)], [rand(2, 3, 6)])
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_sequential_regression():
|
||||
# start with a basic example of using a Sequential model
|
||||
# inside the functional API
|
||||
seq = models.Sequential()
|
||||
seq.add(layers.Dense(10, input_shape=(10,)))
|
||||
|
||||
x = layers.Input(shape=(10,))
|
||||
y = seq(x)
|
||||
model = models.Model(x, y)
|
||||
model.compile('rmsprop', 'mse')
|
||||
weights = model.get_weights()
|
||||
|
||||
# test serialization
|
||||
config = model.get_config()
|
||||
model = models.Model.from_config(config)
|
||||
model.compile('rmsprop', 'mse')
|
||||
model.set_weights(weights)
|
||||
|
||||
# more advanced model with multiple branches
|
||||
|
||||
branch_1 = models.Sequential(name='branch_1')
|
||||
branch_1.add(layers.Embedding(input_dim=100,
|
||||
output_dim=10,
|
||||
input_length=2,
|
||||
name='embed_1'))
|
||||
branch_1.add(layers.LSTM(32, name='lstm_1'))
|
||||
|
||||
branch_2 = models.Sequential(name='branch_2')
|
||||
branch_2.add(layers.Dense(32, input_shape=(8,), name='dense_2'))
|
||||
|
||||
branch_3 = models.Sequential(name='branch_3')
|
||||
branch_3.add(layers.Dense(32, input_shape=(6,), name='dense_3'))
|
||||
|
||||
branch_1_2 = models.Sequential([legacy_layers.Merge([branch_1, branch_2], mode='concat')], name='branch_1_2')
|
||||
branch_1_2.add(layers.Dense(16, name='dense_1_2-0'))
|
||||
# test whether impromtu input_shape breaks the model
|
||||
branch_1_2.add(layers.Dense(16, input_shape=(16,), name='dense_1_2-1'))
|
||||
|
||||
model = models.Sequential([legacy_layers.Merge([branch_1_2, branch_3], mode='concat')], name='final')
|
||||
model.add(layers.Dense(16, name='dense_final'))
|
||||
model.compile(optimizer='rmsprop',
|
||||
loss='categorical_crossentropy',
|
||||
metrics=['accuracy'])
|
||||
model.summary()
|
||||
|
||||
x = (100 * np.random.random((100, 2))).astype('int32')
|
||||
y = np.random.random((100, 8))
|
||||
z = np.random.random((100, 6))
|
||||
labels = np.random.random((100, 16))
|
||||
model.fit([x, y, z], labels, epochs=1)
|
||||
|
||||
# test if Sequential can be called in the functional API
|
||||
|
||||
a = layers.Input(shape=(2,), dtype='int32')
|
||||
b = layers.Input(shape=(8,))
|
||||
c = layers.Input(shape=(6,))
|
||||
o = model([a, b, c])
|
||||
|
||||
outer_model = models.Model([a, b, c], o)
|
||||
outer_model.compile(optimizer='rmsprop',
|
||||
loss='categorical_crossentropy',
|
||||
metrics=['accuracy'])
|
||||
outer_model.fit([x, y, z], labels, epochs=1)
|
||||
|
||||
# test serialization
|
||||
config = outer_model.get_config()
|
||||
outer_model = models.Model.from_config(config)
|
||||
outer_model.compile(optimizer='rmsprop',
|
||||
loss='categorical_crossentropy',
|
||||
metrics=['accuracy'])
|
||||
outer_model.fit([x, y, z], labels, epochs=1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__])
|
||||
@@ -1,279 +0,0 @@
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
import pytest
|
||||
import os
|
||||
import numpy as np
|
||||
|
||||
from keras.models import Sequential
|
||||
from keras.layers import Dense, Activation
|
||||
from keras.legacy.layers import Merge
|
||||
from keras.utils import np_utils
|
||||
from keras.utils.test_utils import get_test_data, keras_test
|
||||
from keras.models import model_from_json, model_from_yaml
|
||||
|
||||
|
||||
input_dim = 16
|
||||
num_hidden = 8
|
||||
num_class = 4
|
||||
batch_size = 32
|
||||
epochs = 1
|
||||
|
||||
|
||||
def _get_test_data():
|
||||
np.random.seed(1234)
|
||||
|
||||
train_samples = 100
|
||||
test_samples = 50
|
||||
|
||||
(x_train, y_train), (x_test, y_test) = get_test_data(num_train=train_samples,
|
||||
num_test=test_samples,
|
||||
input_shape=(input_dim,),
|
||||
classification=True,
|
||||
num_classes=4)
|
||||
y_test = np_utils.to_categorical(y_test)
|
||||
y_train = np_utils.to_categorical(y_train)
|
||||
return (x_train, y_train), (x_test, y_test)
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_merge_sum():
|
||||
(x_train, y_train), (x_test, y_test) = _get_test_data()
|
||||
left = Sequential()
|
||||
left.add(Dense(num_hidden, input_shape=(input_dim,)))
|
||||
left.add(Activation('relu'))
|
||||
|
||||
right = Sequential()
|
||||
right.add(Dense(num_hidden, input_shape=(input_dim,)))
|
||||
right.add(Activation('relu'))
|
||||
|
||||
model = Sequential()
|
||||
model.add(Merge([left, right], mode='sum'))
|
||||
model.add(Dense(num_class))
|
||||
model.add(Activation('softmax'))
|
||||
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
|
||||
|
||||
model.fit([x_train, x_train], y_train, batch_size=batch_size, epochs=epochs, verbose=0, validation_data=([x_test, x_test], y_test))
|
||||
model.fit([x_train, x_train], y_train, batch_size=batch_size, epochs=epochs, verbose=0, validation_split=0.1)
|
||||
model.fit([x_train, x_train], y_train, batch_size=batch_size, epochs=epochs, verbose=0)
|
||||
model.fit([x_train, x_train], y_train, batch_size=batch_size, epochs=epochs, verbose=0, shuffle=False)
|
||||
|
||||
loss = model.evaluate([x_test, x_test], y_test, verbose=0)
|
||||
|
||||
model.predict([x_test, x_test], verbose=0)
|
||||
model.predict_classes([x_test, x_test], verbose=0)
|
||||
model.predict_proba([x_test, x_test], verbose=0)
|
||||
|
||||
# test weight saving
|
||||
fname = 'test_merge_sum_temp.h5'
|
||||
model.save_weights(fname, overwrite=True)
|
||||
left = Sequential()
|
||||
left.add(Dense(num_hidden, input_shape=(input_dim,)))
|
||||
left.add(Activation('relu'))
|
||||
right = Sequential()
|
||||
right.add(Dense(num_hidden, input_shape=(input_dim,)))
|
||||
right.add(Activation('relu'))
|
||||
model = Sequential()
|
||||
model.add(Merge([left, right], mode='sum'))
|
||||
model.add(Dense(num_class))
|
||||
model.add(Activation('softmax'))
|
||||
model.load_weights(fname)
|
||||
os.remove(fname)
|
||||
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
|
||||
|
||||
nloss = model.evaluate([x_test, x_test], y_test, verbose=0)
|
||||
assert(loss == nloss)
|
||||
|
||||
# test serialization
|
||||
config = model.get_config()
|
||||
Sequential.from_config(config)
|
||||
|
||||
model.summary()
|
||||
json_str = model.to_json()
|
||||
model_from_json(json_str)
|
||||
|
||||
yaml_str = model.to_yaml()
|
||||
model_from_yaml(yaml_str)
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_merge_dot():
|
||||
(x_train, y_train), (x_test, y_test) = _get_test_data()
|
||||
|
||||
left = Sequential()
|
||||
left.add(Dense(num_hidden, input_shape=(input_dim,)))
|
||||
left.add(Activation('relu'))
|
||||
|
||||
right = Sequential()
|
||||
right.add(Dense(num_hidden, input_shape=(input_dim,)))
|
||||
right.add(Activation('relu'))
|
||||
|
||||
model = Sequential()
|
||||
model.add(Merge([left, right], mode='dot', dot_axes=1))
|
||||
model.add(Dense(num_class))
|
||||
model.add(Activation('softmax'))
|
||||
|
||||
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
|
||||
|
||||
left = Sequential()
|
||||
left.add(Dense(num_hidden, input_shape=(input_dim,)))
|
||||
left.add(Activation('relu'))
|
||||
|
||||
right = Sequential()
|
||||
right.add(Dense(num_hidden, input_shape=(input_dim,)))
|
||||
right.add(Activation('relu'))
|
||||
|
||||
model = Sequential()
|
||||
model.add(Merge([left, right], mode='dot', dot_axes=[1, 1]))
|
||||
model.add(Dense(num_class))
|
||||
model.add(Activation('softmax'))
|
||||
|
||||
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_merge_concat():
|
||||
(x_train, y_train), (x_test, y_test) = _get_test_data()
|
||||
|
||||
left = Sequential(name='branch_1')
|
||||
left.add(Dense(num_hidden, input_shape=(input_dim,), name='dense_1'))
|
||||
left.add(Activation('relu', name='relu_1'))
|
||||
|
||||
right = Sequential(name='branch_2')
|
||||
right.add(Dense(num_hidden, input_shape=(input_dim,), name='dense_2'))
|
||||
right.add(Activation('relu', name='relu_2'))
|
||||
|
||||
model = Sequential(name='merged_branches')
|
||||
model.add(Merge([left, right], mode='concat', name='merge'))
|
||||
model.add(Dense(num_class, name='final_dense'))
|
||||
model.add(Activation('softmax', name='softmax'))
|
||||
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
|
||||
|
||||
model.fit([x_train, x_train], y_train, batch_size=batch_size, epochs=epochs, verbose=0, validation_data=([x_test, x_test], y_test))
|
||||
model.fit([x_train, x_train], y_train, batch_size=batch_size, epochs=epochs, verbose=0, validation_split=0.1)
|
||||
model.fit([x_train, x_train], y_train, batch_size=batch_size, epochs=epochs, verbose=0)
|
||||
model.fit([x_train, x_train], y_train, batch_size=batch_size, epochs=epochs, verbose=0, shuffle=False)
|
||||
|
||||
loss = model.evaluate([x_test, x_test], y_test, verbose=0)
|
||||
|
||||
model.predict([x_test, x_test], verbose=0)
|
||||
model.predict_classes([x_test, x_test], verbose=0)
|
||||
model.predict_proba([x_test, x_test], verbose=0)
|
||||
model.get_config()
|
||||
|
||||
fname = 'test_merge_concat_temp.h5'
|
||||
model.save_weights(fname, overwrite=True)
|
||||
model.fit([x_train, x_train], y_train, batch_size=batch_size, epochs=epochs, verbose=0)
|
||||
model.load_weights(fname)
|
||||
os.remove(fname)
|
||||
|
||||
nloss = model.evaluate([x_test, x_test], y_test, verbose=0)
|
||||
assert(loss == nloss)
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_merge_recursivity():
|
||||
(x_train, y_train), (x_test, y_test) = _get_test_data()
|
||||
left = Sequential()
|
||||
left.add(Dense(num_hidden, input_shape=(input_dim,)))
|
||||
left.add(Activation('relu'))
|
||||
|
||||
right = Sequential()
|
||||
right.add(Dense(num_hidden, input_shape=(input_dim,)))
|
||||
right.add(Activation('relu'))
|
||||
|
||||
righter = Sequential()
|
||||
righter.add(Dense(num_hidden, input_shape=(input_dim,)))
|
||||
righter.add(Activation('relu'))
|
||||
|
||||
intermediate = Sequential()
|
||||
intermediate.add(Merge([left, right], mode='sum'))
|
||||
intermediate.add(Dense(num_hidden))
|
||||
intermediate.add(Activation('relu'))
|
||||
|
||||
model = Sequential()
|
||||
model.add(Merge([intermediate, righter], mode='sum'))
|
||||
model.add(Dense(num_class))
|
||||
model.add(Activation('softmax'))
|
||||
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
|
||||
|
||||
model.fit([x_train, x_train, x_train], y_train, batch_size=batch_size, epochs=epochs, verbose=0, validation_data=([x_test, x_test, x_test], y_test))
|
||||
model.fit([x_train, x_train, x_train], y_train, batch_size=batch_size, epochs=epochs, verbose=0, validation_split=0.1)
|
||||
model.fit([x_train, x_train, x_train], y_train, batch_size=batch_size, epochs=epochs, verbose=0)
|
||||
model.fit([x_train, x_train, x_train], y_train, batch_size=batch_size, epochs=epochs, verbose=0, shuffle=False)
|
||||
|
||||
loss = model.evaluate([x_test, x_test, x_test], y_test, verbose=0)
|
||||
|
||||
model.predict([x_test, x_test, x_test], verbose=0)
|
||||
model.predict_classes([x_test, x_test, x_test], verbose=0)
|
||||
model.predict_proba([x_test, x_test, x_test], verbose=0)
|
||||
|
||||
fname = 'test_merge_recursivity_temp.h5'
|
||||
model.save_weights(fname, overwrite=True)
|
||||
model.load_weights(fname)
|
||||
os.remove(fname)
|
||||
|
||||
nloss = model.evaluate([x_test, x_test, x_test], y_test, verbose=0)
|
||||
assert(loss == nloss)
|
||||
|
||||
# test serialization
|
||||
config = model.get_config()
|
||||
Sequential.from_config(config)
|
||||
|
||||
model.summary()
|
||||
json_str = model.to_json()
|
||||
model_from_json(json_str)
|
||||
|
||||
yaml_str = model.to_yaml()
|
||||
model_from_yaml(yaml_str)
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_merge_overlap():
|
||||
(x_train, y_train), (x_test, y_test) = _get_test_data()
|
||||
left = Sequential()
|
||||
left.add(Dense(num_hidden, input_shape=(input_dim,)))
|
||||
left.add(Activation('relu'))
|
||||
|
||||
model = Sequential()
|
||||
model.add(Merge([left, left], mode='sum'))
|
||||
model.add(Dense(num_class))
|
||||
model.add(Activation('softmax'))
|
||||
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
|
||||
|
||||
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(x_test, y_test))
|
||||
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=2, validation_split=0.1)
|
||||
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=0)
|
||||
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, shuffle=False)
|
||||
|
||||
model.train_on_batch(x_train[:32], y_train[:32])
|
||||
|
||||
loss = model.evaluate(x_test, y_test, verbose=0)
|
||||
model.predict(x_test, verbose=0)
|
||||
model.predict_classes(x_test, verbose=0)
|
||||
model.predict_proba(x_test, verbose=0)
|
||||
|
||||
fname = 'test_merge_overlap_temp.h5'
|
||||
print(model.layers)
|
||||
model.save_weights(fname, overwrite=True)
|
||||
print(model.trainable_weights)
|
||||
|
||||
model.load_weights(fname)
|
||||
os.remove(fname)
|
||||
|
||||
nloss = model.evaluate(x_test, y_test, verbose=0)
|
||||
assert(loss == nloss)
|
||||
|
||||
# test serialization
|
||||
config = model.get_config()
|
||||
Sequential.from_config(config)
|
||||
|
||||
model.summary()
|
||||
json_str = model.to_json()
|
||||
model_from_json(json_str)
|
||||
|
||||
yaml_str = model.to_yaml()
|
||||
model_from_yaml(yaml_str)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__])
|
||||
@@ -16,8 +16,7 @@ allobj = [losses.mean_squared_error,
|
||||
losses.kullback_leibler_divergence,
|
||||
losses.poisson,
|
||||
losses.cosine_proximity,
|
||||
losses.logcosh,
|
||||
losses.categorical_hinge]
|
||||
losses.logcosh]
|
||||
|
||||
|
||||
def test_objective_shapes_3d():
|
||||
@@ -48,13 +47,11 @@ def test_cce_one_hot():
|
||||
|
||||
|
||||
def test_categorical_hinge():
|
||||
y_pred = K.variable(np.array([[0.3, 0.2, 0.1],
|
||||
[0.1, 0.2, 0.7]]))
|
||||
y_true = K.variable(np.array([[0, 1, 0],
|
||||
[1, 0, 0]]))
|
||||
y_pred = K.variable(np.array([[0.3, 0.2, 0.1], [0.1, 0.2, 0.7]]))
|
||||
y_true = K.variable(np.array([[0, 1, 0], [1, 0, 0]]))
|
||||
expected_loss = ((0.3 - 0.2 + 1) + (0.7 - 0.1 + 1)) / 2.0
|
||||
loss = K.eval(losses.categorical_hinge(y_true, y_pred))
|
||||
assert np.isclose(expected_loss, np.mean(loss))
|
||||
assert np.isclose(expected_loss, loss)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -42,8 +42,6 @@ def test_sparse_metrics():
|
||||
assert K.eval(metric(y_a, y_b)).shape == (6,)
|
||||
|
||||
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="keras cntk backend does not support top_k yet")
|
||||
def test_top_k_categorical_accuracy():
|
||||
y_pred = K.variable(np.array([[0.3, 0.2, 0.1], [0.1, 0.2, 0.7]]))
|
||||
y_true = K.variable(np.array([[0, 1, 0], [1, 0, 0]]))
|
||||
@@ -58,21 +56,5 @@ def test_top_k_categorical_accuracy():
|
||||
assert failure_result == 0
|
||||
|
||||
|
||||
@pytest.mark.skipif((K.backend() == 'cntk'),
|
||||
reason="keras cntk backend does not support top_k yet")
|
||||
def test_sparse_top_k_categorical_accuracy():
|
||||
y_pred = K.variable(np.array([[0.3, 0.2, 0.1], [0.1, 0.2, 0.7]]))
|
||||
y_true = K.variable(np.array([[1], [0]]))
|
||||
success_result = K.eval(metrics.sparse_top_k_categorical_accuracy(y_true, y_pred,
|
||||
k=3))
|
||||
assert success_result == 1
|
||||
partial_result = K.eval(metrics.sparse_top_k_categorical_accuracy(y_true, y_pred,
|
||||
k=2))
|
||||
assert partial_result == 0.5
|
||||
failure_result = K.eval(metrics.sparse_top_k_categorical_accuracy(y_true, y_pred,
|
||||
k=1))
|
||||
assert failure_result == 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__])
|
||||
|
||||
@@ -73,11 +73,22 @@ class TestImage:
|
||||
with pytest.raises(ValueError):
|
||||
x = np.random.random((3, 10, 10))
|
||||
generator.fit(x)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
x = np.random.random((32, 3, 10, 10))
|
||||
generator.fit(x)
|
||||
with pytest.raises(ValueError):
|
||||
x = np.random.random((32, 10, 10, 5))
|
||||
generator.fit(x)
|
||||
# Test flow with invalid data
|
||||
with pytest.raises(ValueError):
|
||||
x = np.random.random((32, 10, 10, 5))
|
||||
generator.flow(np.arange(x.shape[0]))
|
||||
with pytest.raises(ValueError):
|
||||
x = np.random.random((32, 10, 10))
|
||||
generator.flow(np.arange(x.shape[0]))
|
||||
with pytest.raises(ValueError):
|
||||
x = np.random.random((32, 3, 10, 10))
|
||||
generator.flow(np.arange(x.shape[0]))
|
||||
|
||||
def test_image_data_generator_fit(self):
|
||||
generator = image.ImageDataGenerator(
|
||||
|
||||
@@ -302,9 +302,9 @@ def test_CSVLogger():
|
||||
@pytest.mark.skipif((K.backend() != 'tensorflow'),
|
||||
reason='Requires tensorflow backend')
|
||||
def test_TensorBoard():
|
||||
np.random.seed(np.random.randint(1, 1e7))
|
||||
filepath = './logs_' + str(np.random.randint(1, 1e4))
|
||||
np.random.seed(1337)
|
||||
|
||||
filepath = './logs'
|
||||
(X_train, y_train), (X_test, y_test) = get_test_data(
|
||||
num_train=train_samples,
|
||||
num_test=test_samples,
|
||||
@@ -387,9 +387,9 @@ def test_TensorBoard():
|
||||
@pytest.mark.skipif((K.backend() != 'tensorflow'),
|
||||
reason='Requires tensorflow backend')
|
||||
def test_TensorBoard_convnet():
|
||||
np.random.seed(np.random.randint(1, 1e7))
|
||||
filepath = './logs_' + str(np.random.randint(1, 1e4))
|
||||
np.random.seed(1337)
|
||||
|
||||
filepath = './logs'
|
||||
input_shape = (16, 16, 3)
|
||||
(x_train, y_train), (x_test, y_test) = get_test_data(num_train=500,
|
||||
num_test=200,
|
||||
@@ -512,9 +512,7 @@ def test_LambdaCallback():
|
||||
reason="Requires tensorflow backend")
|
||||
def test_TensorBoard_with_ReduceLROnPlateau():
|
||||
import shutil
|
||||
np.random.seed(np.random.randint(1, 1e7))
|
||||
filepath = './logs_' + str(np.random.randint(1, 1e4))
|
||||
|
||||
filepath = './logs'
|
||||
(X_train, y_train), (X_test, y_test) = get_test_data(num_train=train_samples,
|
||||
num_test=test_samples,
|
||||
input_shape=(input_dim,),
|
||||
|
||||
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário