Comparar commits
156 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| afbd5d34a3 | |||
| 07e0fbc963 | |||
| 7ef13165b7 | |||
| d939f14843 | |||
| ce0f97dbe3 | |||
| 7e870a97ec | |||
| a2c3fa2b96 | |||
| 7f09d45efb | |||
| 85fe6427a5 | |||
| b205ba1270 | |||
| 99e4e481c5 | |||
| e74a37438b | |||
| 2061f41987 | |||
| c8d35caa7f | |||
| cf57d28452 | |||
| c1a1c33ef9 | |||
| bac16379a2 | |||
| b5490b20d2 | |||
| 3061fcce60 | |||
| 7a3190de3b | |||
| ed9e8d2ff0 | |||
| 13303663ff | |||
| 0d27d903c2 | |||
| 6220e35ccd | |||
| bc9dbc5de0 | |||
| d67cf89759 | |||
| a2dde60a2f | |||
| e177397427 | |||
| 5f4f234f9b | |||
| 24db6bfaaf | |||
| 504bded884 | |||
| 08aa6ae555 | |||
| 737ae88a02 | |||
| 6642d496e5 | |||
| 2766074d19 | |||
| 672028a5f2 | |||
| 1a89b13cb4 | |||
| 268672df65 | |||
| bfae0a6191 | |||
| a2a0f66276 | |||
| ea8e2edf17 | |||
| d223cc0ff7 | |||
| 8ac1b1fdc9 | |||
| 23833417cf | |||
| 61c9cdc53c | |||
| 1c7e63e42c | |||
| 6582043276 | |||
| 85221ccd13 | |||
| cf550db5a5 | |||
| 75519651bb | |||
| b93d3b23f5 | |||
| dc3d164c6b | |||
| 47dddaa7fd | |||
| fdd822c03e | |||
| a736c2632b | |||
| 1a707ea11e | |||
| c430b6c492 | |||
| 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 |
@@ -0,0 +1,19 @@
|
||||
# Configuration for probot-stale - https://github.com/probot/stale
|
||||
|
||||
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
||||
daysUntilStale: 90
|
||||
# Number of days of inactivity before a stale Issue or Pull Request is closed
|
||||
daysUntilClose: 30
|
||||
# Issues or Pull Requests with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- bug
|
||||
- Announcement
|
||||
- help wanted
|
||||
- To investigate
|
||||
# Label to use when marking as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed after 30 days if no further activity
|
||||
occurs, but feel free to re-open a closed issue if needed.
|
||||
+6
-5
@@ -49,7 +49,7 @@ Here's a quick guide to submitting your improvements:
|
||||
|
||||
2. Write the code. This is the hard part!
|
||||
|
||||
3. Make sure any new function or class you introduce has proper docstrings. Make sure any code you touch still has up-to-date docstrings and documentation.
|
||||
3. Make sure any new function or class you introduce has proper docstrings. Make sure any code you touch still has up-to-date docstrings and documentation. **Docstring style should be respected.** In particular, they should be formatted in MarkDown, and there should be sections for `Arguments`, `Returns`, `Raises` (if applicable). Look at other docstrings in the codebase for examples.
|
||||
|
||||
4. Write tests. Your code should have full unit test coverage. If you want to see your PR merged promptly, this is crucial.
|
||||
|
||||
@@ -57,19 +57,20 @@ Here's a quick guide to submitting your improvements:
|
||||
- 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
|
||||
- with the TensorFlow backend, on Python 2.7
|
||||
- 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`
|
||||
|
||||
8. When committing, use appropriate, descriptive commit messages. Make sure that your branch history is not a string of "bug fix", "fix", "oops", etc. When submitting your PR, squash your commits into a single commit with an appropriate commit message, to make sure the project history stays clean and readable. See ['rebase and squash'](http://rebaseandsqua.sh/) for technical help on how to squash your commits.
|
||||
8. When committing, use appropriate, descriptive commit messages.
|
||||
|
||||
9. Update the documentation. If introducing new functionality, make sure you include code snippets demonstrating the usage of your new feature.
|
||||
|
||||
10. Submit your PR. If your changes have been approved in a previous discussion, and if you have complete (and passing) unit tests, your PR is likely to be merged promptly. Otherwise, well...
|
||||
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
|
||||
|
||||
|
||||
+3
-4
@@ -120,14 +120,13 @@ PAGES = [
|
||||
models.Sequential.fit,
|
||||
models.Sequential.evaluate,
|
||||
models.Sequential.predict,
|
||||
models.Sequential.predict_classes,
|
||||
models.Sequential.predict_proba,
|
||||
models.Sequential.train_on_batch,
|
||||
models.Sequential.test_on_batch,
|
||||
models.Sequential.predict_on_batch,
|
||||
models.Sequential.fit_generator,
|
||||
models.Sequential.evaluate_generator,
|
||||
models.Sequential.predict_generator,
|
||||
models.Sequential.get_layer,
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -388,7 +387,7 @@ def process_class_docstring(docstring):
|
||||
r'\n __\1__\n\n',
|
||||
docstring)
|
||||
|
||||
docstring = re.sub(r' ([^\s\\]+):(.*)\n',
|
||||
docstring = re.sub(r' ([^\s\\\(]+):(.*)\n',
|
||||
r' - __\1__:\2\n',
|
||||
docstring)
|
||||
|
||||
@@ -406,7 +405,7 @@ def process_function_docstring(docstring):
|
||||
r'\n __\1__\n\n',
|
||||
docstring)
|
||||
|
||||
docstring = re.sub(r' ([^\s\\]+):(.*)\n',
|
||||
docstring = re.sub(r' ([^\s\\\(]+):(.*)\n',
|
||||
r' - __\1__:\2\n',
|
||||
docstring)
|
||||
|
||||
|
||||
externo
+3
-3
@@ -253,7 +253,7 @@ The default input size for this model is 224x224.
|
||||
- input_shape: optional shape tuple, only to be specified
|
||||
if `include_top` is False (otherwise the input shape
|
||||
has to be `(224, 224, 3)` (with `channels_last` data format)
|
||||
or `(3, 224, 244)` (with `channels_first` data format).
|
||||
or `(3, 224, 224)` (with `channels_first` data format).
|
||||
It should have exactly 3 inputs channels,
|
||||
and width and height should be no smaller than 48.
|
||||
E.g. `(200, 200, 3)` would be one valid value.
|
||||
@@ -309,7 +309,7 @@ The default input size for this model is 224x224.
|
||||
- input_shape: optional shape tuple, only to be specified
|
||||
if `include_top` is False (otherwise the input shape
|
||||
has to be `(224, 224, 3)` (with `channels_last` data format)
|
||||
or `(3, 224, 244)` (with `channels_first` data format).
|
||||
or `(3, 224, 224)` (with `channels_first` data format).
|
||||
It should have exactly 3 inputs channels,
|
||||
and width and height should be no smaller than 48.
|
||||
E.g. `(200, 200, 3)` would be one valid value.
|
||||
@@ -367,7 +367,7 @@ The default input size for this model is 224x224.
|
||||
- input_shape: optional shape tuple, only to be specified
|
||||
if `include_top` is False (otherwise the input shape
|
||||
has to be `(224, 224, 3)` (with `channels_last` data format)
|
||||
or `(3, 224, 244)` (with `channels_first` data format).
|
||||
or `(3, 224, 224)` (with `channels_first` data format).
|
||||
It should have exactly 3 inputs channels,
|
||||
and width and height should be no smaller than 197.
|
||||
E.g. `(200, 200, 3)` would be one valid value.
|
||||
|
||||
externo
+4
-6
@@ -41,9 +41,9 @@ model.add(Activation('softmax'))
|
||||
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
|
||||
|
||||
history = LossHistory()
|
||||
model.fit(X_train, Y_train, batch_size=128, epochs=20, verbose=0, callbacks=[history])
|
||||
model.fit(x_train, y_train, batch_size=128, epochs=20, verbose=0, callbacks=[history])
|
||||
|
||||
print history.losses
|
||||
print(history.losses)
|
||||
# outputs
|
||||
'''
|
||||
[0.66047596406559383, 0.3547245744908703, ..., 0.25953155204159617, 0.25901699725311789]
|
||||
@@ -65,8 +65,6 @@ model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
|
||||
'''
|
||||
saves the model weights after each epoch if the validation loss decreased
|
||||
'''
|
||||
checkpointer = ModelCheckpoint(filepath="/tmp/weights.hdf5", verbose=1, save_best_only=True)
|
||||
model.fit(X_train, Y_train, batch_size=128, epochs=20, verbose=0, validation_data=(X_test, Y_test), callbacks=[checkpointer])
|
||||
|
||||
checkpointer = ModelCheckpoint(filepath='/tmp/weights.hdf5', verbose=1, save_best_only=True)
|
||||
model.fit(x_train, y_train, batch_size=128, epochs=20, verbose=0, validation_data=(X_test, Y_test), callbacks=[checkpointer])
|
||||
```
|
||||
|
||||
|
||||
+16
-16
@@ -153,16 +153,16 @@ For example:
|
||||
"""
|
||||
Assume original model looks like this:
|
||||
model = Sequential()
|
||||
model.add(Dense(2, input_dim=3, name="dense_1"))
|
||||
model.add(Dense(3, name="dense_2"))
|
||||
model.add(Dense(2, input_dim=3, name='dense_1'))
|
||||
model.add(Dense(3, name='dense_2'))
|
||||
...
|
||||
model.save_weights(fname)
|
||||
"""
|
||||
|
||||
# new model
|
||||
model = Sequential()
|
||||
model.add(Dense(2, input_dim=3, name="dense_1")) # will be loaded
|
||||
model.add(Dense(10, name="new_dense")) # will not be loaded
|
||||
model.add(Dense(2, input_dim=3, name='dense_1')) # will be loaded
|
||||
model.add(Dense(10, name='new_dense')) # will not be loaded
|
||||
|
||||
# load weights from first model; will only affect the first layer, dense_1.
|
||||
model.load_weights(fname, by_name=True)
|
||||
@@ -201,7 +201,7 @@ from keras import backend as K
|
||||
# with a Sequential model
|
||||
get_3rd_layer_output = K.function([model.layers[0].input],
|
||||
[model.layers[3].output])
|
||||
layer_output = get_3rd_layer_output([X])[0]
|
||||
layer_output = get_3rd_layer_output([x])[0]
|
||||
```
|
||||
|
||||
Similarly, you could build a Theano and TensorFlow function directly.
|
||||
@@ -214,17 +214,17 @@ get_3rd_layer_output = K.function([model.layers[0].input, K.learning_phase()],
|
||||
[model.layers[3].output])
|
||||
|
||||
# output in test mode = 0
|
||||
layer_output = get_3rd_layer_output([X, 0])[0]
|
||||
layer_output = get_3rd_layer_output([x, 0])[0]
|
||||
|
||||
# output in train mode = 1
|
||||
layer_output = get_3rd_layer_output([X, 1])[0]
|
||||
layer_output = get_3rd_layer_output([x, 1])[0]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### How can I use Keras with datasets that don't fit in memory?
|
||||
|
||||
You can do batch training using `model.train_on_batch(X, y)` and `model.test_on_batch(X, y)`. See the [models documentation](/models/sequential).
|
||||
You can do batch training using `model.train_on_batch(x, y)` and `model.test_on_batch(x, y)`. See the [models documentation](/models/sequential).
|
||||
|
||||
Alternatively, you can write a generator that yields batches of training data and use the method `model.fit_generator(data_generator, steps_per_epoch, epochs)`.
|
||||
|
||||
@@ -239,7 +239,7 @@ You can use an `EarlyStopping` callback:
|
||||
```python
|
||||
from keras.callbacks import EarlyStopping
|
||||
early_stopping = EarlyStopping(monitor='val_loss', patience=2)
|
||||
model.fit(X, y, validation_split=0.2, callbacks=[early_stopping])
|
||||
model.fit(x, y, validation_split=0.2, callbacks=[early_stopping])
|
||||
```
|
||||
|
||||
Find out more in the [callbacks documentation](/callbacks).
|
||||
@@ -268,7 +268,7 @@ Validation data is never shuffled.
|
||||
The `model.fit` method returns an `History` callback, which has a `history` attribute containing the lists of successive losses and other metrics.
|
||||
|
||||
```python
|
||||
hist = model.fit(X, y, validation_split=0.2)
|
||||
hist = model.fit(x, y, validation_split=0.2)
|
||||
print(hist.history)
|
||||
```
|
||||
|
||||
@@ -315,7 +315,7 @@ Making a RNN stateful means that the states for the samples of each batch will b
|
||||
When using stateful RNNs, it is therefore assumed that:
|
||||
|
||||
- all batches have the same number of samples
|
||||
- If `X1` and `X2` are successive batches of samples, then `X2[i]` is the follow-up sequence to `X1[i]`, for every `i`.
|
||||
- If `x1` and `x2` are successive batches of samples, then `x2[i]` is the follow-up sequence to `x1[i]`, for every `i`.
|
||||
|
||||
To use statefulness in RNNs, you need to:
|
||||
|
||||
@@ -332,7 +332,7 @@ Example:
|
||||
|
||||
```python
|
||||
|
||||
X # this is our input data, of shape (32, 21, 16)
|
||||
x # this is our input data, of shape (32, 21, 16)
|
||||
# we will feed it to our model in sequences of length 10
|
||||
|
||||
model = Sequential()
|
||||
@@ -342,10 +342,10 @@ model.add(Dense(16, activation='softmax'))
|
||||
model.compile(optimizer='rmsprop', loss='categorical_crossentropy')
|
||||
|
||||
# we train the network to predict the 11th timestep given the first 10:
|
||||
model.train_on_batch(X[:, :10, :], np.reshape(X[:, 10, :], (32, 16)))
|
||||
model.train_on_batch(x[:, :10, :], np.reshape(x[:, 10, :], (32, 16)))
|
||||
|
||||
# the state of the network has changed. We can feed the follow-up sequences:
|
||||
model.train_on_batch(X[:, 10:20, :], np.reshape(X[:, 20, :], (32, 16)))
|
||||
model.train_on_batch(x[:, 10:20, :], np.reshape(x[:, 20, :], (32, 16)))
|
||||
|
||||
# let's reset the states of the LSTM layer:
|
||||
model.reset_states()
|
||||
@@ -418,8 +418,8 @@ You can also directly use a HDF5 dataset:
|
||||
```python
|
||||
import h5py
|
||||
with h5py.File('input/file.hdf5', 'r') as f:
|
||||
X_data = f['X_data']
|
||||
model.predict(X_data)
|
||||
x_data = f['x_data']
|
||||
model.predict(x_data)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
+5
-3
@@ -7,6 +7,7 @@ keras.preprocessing.image.ImageDataGenerator(featurewise_center=False,
|
||||
featurewise_std_normalization=False,
|
||||
samplewise_std_normalization=False,
|
||||
zca_whitening=False,
|
||||
zca_epsilon=1e-6,
|
||||
rotation_range=0.,
|
||||
width_shift_range=0.,
|
||||
height_shift_range=0.,
|
||||
@@ -29,6 +30,7 @@ Generate batches of tensor image data with real-time data augmentation. The data
|
||||
- __samplewise_center__: Boolean. Set each sample mean to 0.
|
||||
- __featurewise_std_normalization__: Boolean. Divide inputs by std of the dataset, feature-wise.
|
||||
- __samplewise_std_normalization__: Boolean. Divide each input by its std.
|
||||
- __zca_epsilon__: epsilon for ZCA whitening. Default is 1e-6.
|
||||
- __zca_whitening__: Boolean. Apply ZCA whitening.
|
||||
- __rotation_range__: Int. Degree range for random rotations.
|
||||
- __width_shift_range__: Float (fraction of total width). Range for random horizontal shifts.
|
||||
@@ -66,7 +68,7 @@ Generate batches of tensor image data with real-time data augmentation. The data
|
||||
- __augment__: Boolean (default: False). Whether to fit on randomly augmented samples.
|
||||
- __rounds__: int (default: 1). If augment, how many augmentation passes over the data to use.
|
||||
- __seed__: int (default: None). Random seed.
|
||||
- __flow(X, y)__: Takes numpy data & label arrays, and generates batches of augmented/normalized data. Yields batches indefinitely, in an infinite loop.
|
||||
- __flow(x, y)__: Takes numpy data & label arrays, and generates batches of augmented/normalized data. Yields batches indefinitely, in an infinite loop.
|
||||
- __Arguments__:
|
||||
- __x__: data. Should have rank 4.
|
||||
In case of grayscale data,
|
||||
@@ -78,7 +80,7 @@ Generate batches of tensor image data with real-time data augmentation. The data
|
||||
- __seed__: int (default: None).
|
||||
- __save_to_dir__: None or str (default: None). This allows you to optimally specify a directory to which to save the augmented pictures being generated (useful for visualizing what you are doing).
|
||||
- __save_prefix__: str (default: `''`). Prefix to use for filenames of saved pictures (only relevant if `save_to_dir` is set).
|
||||
- __save_format__: one of "png", "jpeg" (only relevant if `save_to_dir` is set). Default: "jpeg".
|
||||
- __save_format__: one of "png", "jpeg" (only relevant if `save_to_dir` is set). Default: "png".
|
||||
- __yields__: Tuples of `(x, y)` where `x` is a numpy array of image data and `y` is a numpy array of corresponding labels.
|
||||
The generator loops indefinitely.
|
||||
- __flow_from_directory(directory)__: Takes the path to a directory, and generates batches of augmented/normalized data. Yields batches indefinitely, in an infinite loop.
|
||||
@@ -95,7 +97,7 @@ Generate batches of tensor image data with real-time data augmentation. The data
|
||||
- __seed__: optional random seed for shuffling and transformations.
|
||||
- __save_to_dir__: None or str (default: None). This allows you to optimally specify a directory to which to save the augmented pictures being generated (useful for visualizing what you are doing).
|
||||
- __save_prefix__: str. Prefix to use for filenames of saved pictures (only relevant if `save_to_dir` is set).
|
||||
- __save_format__: one of "png", "jpeg" (only relevant if `save_to_dir` is set). Default: "jpeg".
|
||||
- __save_format__: one of "png", "jpeg" (only relevant if `save_to_dir` is set). Default: "png".
|
||||
- __follow_links__: whether to follow symlinks inside class subdirectories (default: False).
|
||||
|
||||
|
||||
|
||||
+6
-5
@@ -3,7 +3,7 @@
|
||||
|
||||
```python
|
||||
keras.preprocessing.text.text_to_word_sequence(text,
|
||||
filters=base_filter(), lower=True, split=" ")
|
||||
filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n', lower=True, split=" ")
|
||||
```
|
||||
|
||||
Split a sentence into a list of words.
|
||||
@@ -12,7 +12,7 @@ Split a sentence into a list of words.
|
||||
|
||||
- __Arguments__:
|
||||
- __text__: str.
|
||||
- __filters__: list (or concatenation) of characters to filter out, such as punctuation. Default: base_filter(), includes basic punctuation, tabs, and newlines.
|
||||
- __filters__: list (or concatenation) of characters to filter out, such as punctuation. Default: '!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n' , includes basic punctuation, tabs, and newlines.
|
||||
- __lower__: boolean. Whether to set the text to lowercase.
|
||||
- __split__: str. Separator for word splitting.
|
||||
|
||||
@@ -20,7 +20,7 @@ Split a sentence into a list of words.
|
||||
|
||||
```python
|
||||
keras.preprocessing.text.one_hot(text, n,
|
||||
filters=base_filter(), lower=True, split=" ")
|
||||
filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n', lower=True, split=" ")
|
||||
```
|
||||
|
||||
One-hot encode a text into a list of word indexes in a vocabulary of size n.
|
||||
@@ -33,14 +33,15 @@ One-hot encode a text into a list of word indexes in a vocabulary of size n.
|
||||
## Tokenizer
|
||||
|
||||
```python
|
||||
keras.preprocessing.text.Tokenizer(num_words=None, filters=base_filter(),
|
||||
lower=True, split=" ")
|
||||
keras.preprocessing.text.Tokenizer(num_words=None, filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n',
|
||||
lower=True, split=" ", char_level=False)
|
||||
```
|
||||
|
||||
Class for vectorizing texts, or/and turning texts into sequences (=list of word indexes, where the word of rank i in the dataset (starting at 1) has index i).
|
||||
|
||||
- __Arguments__: Same as `text_to_word_sequence` above.
|
||||
- __num_words__: None or int. Maximum number of words to work with (if set, tokenization will be restricted to the top num_words most common words in the dataset).
|
||||
- __char_level__: if True, every character will be treated as a token.
|
||||
|
||||
- __Methods__:
|
||||
|
||||
|
||||
@@ -196,8 +196,8 @@ x = mask_input
|
||||
for layer in image_model.layers[1:]:
|
||||
name = 'mask_%s' % layer.name
|
||||
if 'conv' in layer.name:
|
||||
x = AveragePooling2D((3, 3), strides=(
|
||||
1, 1), name=name, border_mode='same')(x)
|
||||
x = AveragePooling2D((3, 3), padding='same', strides=(
|
||||
1, 1), name=name)(x)
|
||||
elif 'pool' in layer.name:
|
||||
x = AveragePooling2D((2, 2), name=name)(x)
|
||||
mask_model = Model(mask_input, x)
|
||||
@@ -238,6 +238,7 @@ def region_style_loss(style_image, target_image, style_mask, target_mask):
|
||||
masked_target = K.permute_dimensions(
|
||||
target_image, (2, 0, 1)) * target_mask
|
||||
num_channels = K.shape(style_image)[-1]
|
||||
num_channels = K.cast(num_channels, dtype='float32')
|
||||
s = gram_matrix(masked_style) / K.mean(style_mask) / num_channels
|
||||
c = gram_matrix(masked_target) / K.mean(target_mask) / num_channels
|
||||
return K.mean(K.square(s - c))
|
||||
|
||||
+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.4'
|
||||
__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,28 +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 ..utils.layer_utils import convert_all_kernels_in_model
|
||||
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'
|
||||
@@ -157,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
|
||||
@@ -384,8 +382,6 @@ def InceptionV3(include_top=True,
|
||||
cache_subdir='models',
|
||||
md5_hash='bcbd6486424b2319ff4ef7d526e38f63')
|
||||
model.load_weights(weights_path)
|
||||
if K.backend() == 'theano':
|
||||
convert_all_kernels_in_model(model)
|
||||
return model
|
||||
|
||||
|
||||
|
||||
@@ -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'
|
||||
@@ -77,7 +78,7 @@ 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
|
||||
@@ -85,6 +86,7 @@ def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2))
|
||||
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:
|
||||
@@ -264,21 +264,19 @@ def ResNet50(include_top=True, weights='imagenet',
|
||||
model.load_weights(weights_path)
|
||||
if K.backend() == 'theano':
|
||||
layer_utils.convert_all_kernels_in_model(model)
|
||||
|
||||
if K.image_data_format() == 'channels_first':
|
||||
if include_top:
|
||||
maxpool = model.get_layer(name='avg_pool')
|
||||
shape = maxpool.output_shape[1:]
|
||||
dense = model.get_layer(name='fc1000')
|
||||
layer_utils.convert_dense_weights_data_format(dense, shape, 'channels_first')
|
||||
|
||||
if K.backend() == 'tensorflow':
|
||||
warnings.warn('You are using the TensorFlow backend, yet you '
|
||||
'are using the Theano '
|
||||
'image data format convention '
|
||||
'(`image_data_format="channels_first"`). '
|
||||
'For best performance, set '
|
||||
'`image_data_format="channels_last"` in '
|
||||
'your Keras config '
|
||||
'at ~/.keras/keras.json.')
|
||||
if K.image_data_format() == 'channels_first' and K.backend() == 'tensorflow':
|
||||
warnings.warn('You are using the TensorFlow backend, yet you '
|
||||
'are using the Theano '
|
||||
'image data format convention '
|
||||
'(`image_data_format="channels_first"`). '
|
||||
'For best performance, set '
|
||||
'`image_data_format="channels_last"` in '
|
||||
'your Keras config '
|
||||
'at ~/.keras/keras.json.')
|
||||
return model
|
||||
|
||||
@@ -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'
|
||||
@@ -59,7 +60,7 @@ def VGG16(include_top=True, weights='imagenet',
|
||||
input_shape: optional shape tuple, only to be specified
|
||||
if `include_top` is False (otherwise the input shape
|
||||
has to be `(224, 224, 3)` (with `channels_last` data format)
|
||||
or `(3, 224, 244)` (with `channels_first` data format).
|
||||
or `(3, 224, 224)` (with `channels_first` data format).
|
||||
It should have exactly 3 inputs channels,
|
||||
and width and height should be no smaller than 48.
|
||||
E.g. `(200, 200, 3)` would be one valid value.
|
||||
@@ -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'
|
||||
@@ -59,7 +60,7 @@ def VGG19(include_top=True, weights='imagenet',
|
||||
input_shape: optional shape tuple, only to be specified
|
||||
if `include_top` is False (otherwise the input shape
|
||||
has to be `(224, 224, 3)` (with `channels_last` data format)
|
||||
or `(3, 224, 244)` (with `channels_first` data format).
|
||||
or `(3, 224, 224)` (with `channels_first` data format).
|
||||
It should have exactly 3 inputs channels,
|
||||
and width and height should be no smaller than 48.
|
||||
E.g. `(200, 200, 3)` would be one valid value.
|
||||
@@ -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,91 +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
|
||||
from .common import is_keras_tensor
|
||||
|
||||
# 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'}
|
||||
_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 os.access(_keras_base_dir, os.W_OK):
|
||||
if not os.path.exists(_keras_dir):
|
||||
try:
|
||||
os.makedirs(_keras_dir)
|
||||
except OSError:
|
||||
pass
|
||||
if not os.path.exists(_config_path):
|
||||
_config = {'floatx': floatx(),
|
||||
'epsilon': epsilon(),
|
||||
'backend': _BACKEND,
|
||||
'image_data_format': image_data_format()}
|
||||
with open(_config_path, 'w') as f:
|
||||
f.write(json.dumps(_config, indent=4))
|
||||
|
||||
# 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'}
|
||||
_BACKEND = _backend
|
||||
|
||||
# Import backend functions.
|
||||
if _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
|
||||
@@ -1,217 +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)
|
||||
|
||||
|
||||
def is_keras_tensor(x):
|
||||
"""Returns whether `x` is a Keras tensor.
|
||||
|
||||
# Arguments
|
||||
x: a potential tensor.
|
||||
|
||||
# Returns
|
||||
A boolean: whether the argument is a Keras tensor.
|
||||
|
||||
# Examples
|
||||
```python
|
||||
>>> from keras import backend as K
|
||||
>>> np_var = numpy.array([1, 2])
|
||||
>>> K.is_keras_tensor(np_var)
|
||||
False
|
||||
>>> keras_var = K.variable(np_var)
|
||||
>>> K.is_keras_tensor(keras_var) # A variable is not a Tensor.
|
||||
False
|
||||
>>> keras_placeholder = K.placeholder(shape=(2, 4, 5))
|
||||
>>> K.is_keras_tensor(keras_placeholder) # A placeholder is a Tensor.
|
||||
True
|
||||
```
|
||||
"""
|
||||
if hasattr(x, '_keras_shape'):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
# 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 invalid `dim_ordering`
|
||||
"""
|
||||
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
+124
-59
@@ -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):
|
||||
@@ -227,6 +231,21 @@ class BaseLogger(Callback):
|
||||
logs[k] = self.totals[k] / self.seen
|
||||
|
||||
|
||||
class TerminateOnNaN(Callback):
|
||||
"""Callback that terminates training when a NaN loss is encountered."""
|
||||
|
||||
def __init__(self):
|
||||
super(TerminateOnNaN, self).__init__()
|
||||
|
||||
def on_batch_end(self, batch, logs=None):
|
||||
logs = logs or {}
|
||||
loss = logs.get('loss')
|
||||
if loss is not None:
|
||||
if np.isnan(loss) or np.isinf(loss):
|
||||
print('Batch %d: Invalid loss, terminating training' % (batch))
|
||||
self.model.stop_training = True
|
||||
|
||||
|
||||
class ProgbarLogger(Callback):
|
||||
"""Callback that prints metrics to stdout.
|
||||
|
||||
@@ -467,7 +486,9 @@ class EarlyStopping(Callback):
|
||||
self.min_delta *= -1
|
||||
|
||||
def on_train_begin(self, logs=None):
|
||||
self.wait = 0 # Allow instances to be re-used
|
||||
# Allow instances to be re-used
|
||||
self.wait = 0
|
||||
self.stopped_epoch = 0
|
||||
self.best = np.Inf if self.monitor_op == np.less else -np.Inf
|
||||
|
||||
def on_epoch_end(self, epoch, logs=None):
|
||||
@@ -563,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
|
||||
@@ -582,15 +604,20 @@ class TensorBoard(Callback):
|
||||
|
||||
# Arguments
|
||||
log_dir: the path of the directory where to save the log
|
||||
files to be parsed by Tensorboard.
|
||||
files to be parsed by TensorBoard.
|
||||
histogram_freq: frequency (in epochs) at which to compute activation
|
||||
histograms for the layers of the model. If set to 0,
|
||||
histograms won't be computed.
|
||||
write_graph: whether to visualize the graph in Tensorboard.
|
||||
and weight histograms for the layers of the model. If set to 0,
|
||||
histograms won't be computed. Validation data (or split) must be
|
||||
specified for histogram visualizations.
|
||||
write_graph: whether to visualize the graph in TensorBoard.
|
||||
The log file can become quite large when
|
||||
write_graph is set to True.
|
||||
write_grads: whether to visualize gradient histograms in TensorBoard.
|
||||
`histogram_freq` must be greater than 0.
|
||||
batch_size: size of batch of inputs to feed to the network
|
||||
for histograms computation.
|
||||
write_images: whether to write model weights to visualize as
|
||||
image in Tensorboard.
|
||||
image in TensorBoard.
|
||||
embeddings_freq: frequency (in epochs) at which selected embedding
|
||||
layers will be saved.
|
||||
embeddings_layer_names: a list of names of layers to keep eye on. If
|
||||
@@ -601,59 +628,82 @@ 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,
|
||||
batch_size=32,
|
||||
write_graph=True,
|
||||
write_grads=False,
|
||||
write_images=False,
|
||||
embeddings_freq=0,
|
||||
embeddings_layer_names=None,
|
||||
embeddings_metadata=None):
|
||||
super(TensorBoard, self).__init__()
|
||||
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
|
||||
self.write_graph = write_graph
|
||||
self.write_grads = write_grads
|
||||
self.write_images = write_images
|
||||
self.embeddings_freq = embeddings_freq
|
||||
self.embeddings_layer_names = embeddings_layer_names
|
||||
self.embeddings_metadata = embeddings_metadata or {}
|
||||
self.batch_size = batch_size
|
||||
|
||||
def set_model(self, model):
|
||||
self.model = model
|
||||
self.sess = K.get_session()
|
||||
if self.histogram_freq and self.merged is None:
|
||||
for layer in self.model.layers:
|
||||
|
||||
for weight in layer.weights:
|
||||
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)
|
||||
if self.write_images:
|
||||
w_img = tf.squeeze(weight)
|
||||
shape = w_img.get_shape()
|
||||
if len(shape) > 1 and shape[0] > shape[1]:
|
||||
w_img = tf.transpose(w_img)
|
||||
if len(shape) == 1:
|
||||
w_img = tf.expand_dims(w_img, 0)
|
||||
w_img = tf.expand_dims(tf.expand_dims(w_img, 0), -1)
|
||||
tf.summary.image(weight.name, w_img)
|
||||
w_img = array_ops.squeeze(weight)
|
||||
shape = K.int_shape(w_img)
|
||||
if len(shape) == 2: # dense layer kernel case
|
||||
if shape[0] > shape[1]:
|
||||
w_img = array_ops.transpose(w_img)
|
||||
shape = K.int_shape(w_img)
|
||||
w_img = array_ops.reshape(w_img, [1,
|
||||
shape[0],
|
||||
shape[1],
|
||||
1])
|
||||
elif len(shape) == 3: # convnet case
|
||||
if K.image_data_format() == 'channels_last':
|
||||
# switch to channels_first to display
|
||||
# every kernel as a separate image
|
||||
w_img = array_ops.transpose(w_img, perm=[2, 0, 1])
|
||||
shape = K.int_shape(w_img)
|
||||
w_img = array_ops.reshape(
|
||||
w_img, [shape[0], shape[1], shape[2], 1])
|
||||
elif len(shape) == 1: # bias case
|
||||
w_img = array_ops.reshape(
|
||||
w_img, [1, shape[0], 1, 1])
|
||||
else:
|
||||
# not possible to handle 3D convnets etc.
|
||||
continue
|
||||
|
||||
shape = K.int_shape(w_img)
|
||||
assert len(shape) == 4 and shape[-1] in [1, 3, 4]
|
||||
tf_summary.image(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:
|
||||
self.saver = tf.train.Saver()
|
||||
|
||||
embeddings_layer_names = self.embeddings_layer_names
|
||||
|
||||
if not embeddings_layer_names:
|
||||
@@ -664,6 +714,8 @@ class TensorBoard(Callback):
|
||||
for layer in self.model.layers
|
||||
if layer.name in embeddings_layer_names}
|
||||
|
||||
self.saver = saver_lib.Saver(list(embeddings.values()))
|
||||
|
||||
embeddings_metadata = {}
|
||||
|
||||
if not isinstance(self.embeddings_metadata, str):
|
||||
@@ -673,15 +725,13 @@ class TensorBoard(Callback):
|
||||
for layer_name in embeddings.keys()}
|
||||
|
||||
config = projector.ProjectorConfig()
|
||||
self.embeddings_logs = []
|
||||
self.embeddings_ckpt_path = os.path.join(self.log_dir,
|
||||
'keras_embedding.ckpt')
|
||||
|
||||
for layer_name, tensor in embeddings.items():
|
||||
embedding = config.embeddings.add()
|
||||
embedding.tensor_name = tensor.name
|
||||
|
||||
self.embeddings_logs.append(os.path.join(self.log_dir,
|
||||
layer_name + '.ckpt'))
|
||||
|
||||
if layer_name in embeddings_metadata:
|
||||
embedding.metadata_path = embeddings_metadata[layer_name]
|
||||
|
||||
@@ -692,29 +742,42 @@ class TensorBoard(Callback):
|
||||
|
||||
if self.validation_data and self.histogram_freq:
|
||||
if epoch % self.histogram_freq == 0:
|
||||
# TODO: implement batched calls to sess.run
|
||||
# (current call will likely go OOM on GPU)
|
||||
if self.model.uses_learning_phase:
|
||||
cut_v_data = len(self.model.inputs)
|
||||
val_data = self.validation_data[:cut_v_data] + [0]
|
||||
tensors = self.model.inputs + [K.learning_phase()]
|
||||
else:
|
||||
val_data = self.validation_data
|
||||
tensors = self.model.inputs
|
||||
feed_dict = dict(zip(tensors, val_data))
|
||||
result = self.sess.run([self.merged], feed_dict=feed_dict)
|
||||
summary_str = result[0]
|
||||
self.writer.add_summary(summary_str, epoch)
|
||||
|
||||
if self.embeddings_freq and self.embeddings_logs:
|
||||
val_data = self.validation_data
|
||||
tensors = (self.model.inputs +
|
||||
self.model.targets +
|
||||
self.model.sample_weights)
|
||||
|
||||
if self.model.uses_learning_phase:
|
||||
tensors += [K.learning_phase()]
|
||||
|
||||
assert len(val_data) == len(tensors)
|
||||
val_size = val_data[0].shape[0]
|
||||
i = 0
|
||||
while i < val_size:
|
||||
step = min(self.batch_size, val_size - i)
|
||||
batch_val = []
|
||||
batch_val.append(val_data[0][i:i + step])
|
||||
batch_val.append(val_data[1][i:i + step])
|
||||
batch_val.append(val_data[2][i:i + step])
|
||||
if self.model.uses_learning_phase:
|
||||
batch_val.append(val_data[3])
|
||||
feed_dict = dict(zip(tensors, batch_val))
|
||||
result = self.sess.run([self.merged], feed_dict=feed_dict)
|
||||
summary_str = result[0]
|
||||
self.writer.add_summary(summary_str, epoch)
|
||||
i += self.batch_size
|
||||
|
||||
if self.embeddings_freq and self.embeddings_ckpt_path:
|
||||
if epoch % self.embeddings_freq == 0:
|
||||
for log in self.embeddings_logs:
|
||||
self.saver.save(self.sess, log, epoch)
|
||||
self.saver.save(self.sess,
|
||||
self.embeddings_ckpt_path,
|
||||
epoch)
|
||||
|
||||
for name, value in logs.items():
|
||||
if name in ['batch', 'size']:
|
||||
continue
|
||||
summary = tf.Summary()
|
||||
summary = tf_summary.Summary()
|
||||
summary_value = summary.value.add()
|
||||
summary_value.simple_value = value.item()
|
||||
summary_value.tag = name
|
||||
@@ -879,7 +942,9 @@ class CSVLogger(Callback):
|
||||
|
||||
def handle_value(k):
|
||||
is_zero_dim_ndarray = isinstance(k, np.ndarray) and k.ndim == 0
|
||||
if isinstance(k, Iterable) and not is_zero_dim_ndarray:
|
||||
if isinstance(k, six.string_types):
|
||||
return k
|
||||
elif isinstance(k, Iterable) and not is_zero_dim_ndarray:
|
||||
return '"[%s]"' % (', '.join(map(str, k)))
|
||||
else:
|
||||
return k
|
||||
|
||||
@@ -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):
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
+149
-146
@@ -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()
|
||||
@@ -413,13 +416,22 @@ class Layer(object):
|
||||
ValueError: in case of mismatch between
|
||||
the provided inputs and the expectations of the layer.
|
||||
"""
|
||||
inputs = _to_list(inputs)
|
||||
for x in inputs:
|
||||
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: ' +
|
||||
str(type(x)) + '. Full input: ' +
|
||||
str(inputs) + '. All inputs to the layer '
|
||||
'should be tensors.')
|
||||
|
||||
if not self.input_spec:
|
||||
return
|
||||
if not isinstance(self.input_spec, (list, tuple)):
|
||||
input_spec = _to_list(self.input_spec)
|
||||
else:
|
||||
input_spec = self.input_spec
|
||||
inputs = _to_list(inputs)
|
||||
if len(inputs) != len(input_spec):
|
||||
raise ValueError('Layer ' + self.name + ' expects ' +
|
||||
str(len(input_spec)) + ' inputs, '
|
||||
@@ -470,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 ' +
|
||||
@@ -485,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(
|
||||
@@ -494,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
|
||||
@@ -512,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().
|
||||
@@ -543,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:
|
||||
@@ -578,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)
|
||||
@@ -599,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).
|
||||
@@ -615,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:
|
||||
@@ -626,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
|
||||
@@ -634,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.
|
||||
"""
|
||||
@@ -643,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 = []
|
||||
@@ -671,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
|
||||
@@ -686,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
|
||||
@@ -701,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
|
||||
@@ -737,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.
|
||||
@@ -1009,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, '
|
||||
@@ -1043,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, '
|
||||
@@ -1070,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 inputs == []:
|
||||
if inputs == []: # pylint: disable=g-explicit-bool-comparison
|
||||
inputs = None
|
||||
if inputs is not None:
|
||||
inputs_hash = _object_list_uid(inputs)
|
||||
@@ -1102,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 inputs == []:
|
||||
if inputs == []: # pylint: disable=g-explicit-bool-comparison
|
||||
inputs = None
|
||||
if inputs is not None:
|
||||
inputs_hash = _object_list_uid(inputs)
|
||||
@@ -1242,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. '
|
||||
@@ -1270,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):
|
||||
@@ -1325,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
|
||||
@@ -1337,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,
|
||||
@@ -1349,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
|
||||
@@ -1359,14 +1342,12 @@ def Input(shape=None, batch_shape=None,
|
||||
attributes that allow us to build a Keras model
|
||||
just by knowing the inputs and outputs of the model.
|
||||
|
||||
For instance, if a, b and c and Keras tensors,
|
||||
For instance, if a, b and c are Keras tensors,
|
||||
it becomes possible to do:
|
||||
`model = Model(input=[a, b], output=c)`
|
||||
|
||||
The added Keras 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.
|
||||
|
||||
@@ -1412,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:
|
||||
@@ -1458,8 +1439,7 @@ class Container(Layer):
|
||||
from_config
|
||||
"""
|
||||
|
||||
@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()
|
||||
@@ -1594,12 +1574,12 @@ class Container(Layer):
|
||||
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
|
||||
@@ -1661,7 +1641,6 @@ class Container(Layer):
|
||||
layer = node.inbound_layers[i]
|
||||
node_index = node.node_indices[i]
|
||||
tensor_index = node.tensor_indices[i]
|
||||
next_node = layer.inbound_nodes[node_index]
|
||||
build_map_of_graph(x, finished_nodes, nodes_in_progress,
|
||||
layer, node_index, tensor_index)
|
||||
|
||||
@@ -1679,6 +1658,15 @@ class Container(Layer):
|
||||
# If the depth is not set, the node has no outbound nodes (depth 0).
|
||||
depth = nodes_depths.setdefault(node, 0)
|
||||
|
||||
# Update the depth of the corresponding layer
|
||||
previous_depth = layers_depths.get(node.outbound_layer, 0)
|
||||
# If we've seen this layer before at a higher depth, we should use that depth instead
|
||||
# of the node depth. This is necessary for shared layers that have inputs at different
|
||||
# depth levels in the graph.
|
||||
depth = max(depth, previous_depth)
|
||||
layers_depths[node.outbound_layer] = depth
|
||||
nodes_depths[node] = depth
|
||||
|
||||
# Update the depth of inbound nodes.
|
||||
for i in range(len(node.inbound_layers)):
|
||||
inbound_layer = node.inbound_layers[i]
|
||||
@@ -1687,10 +1675,6 @@ class Container(Layer):
|
||||
previous_depth = nodes_depths.get(inbound_node, 0)
|
||||
nodes_depths[inbound_node] = max(depth + 1, previous_depth)
|
||||
|
||||
# Update the depth of the corresponding layer
|
||||
previous_depth = layers_depths.get(node.outbound_layer, 0)
|
||||
layers_depths[node.outbound_layer] = max(depth, previous_depth)
|
||||
|
||||
# Build a dict {depth: list of nodes with this depth}
|
||||
nodes_by_depth = {}
|
||||
for node, depth in nodes_depths.items():
|
||||
@@ -1778,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:
|
||||
@@ -2041,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 ' +
|
||||
@@ -2051,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 = {}
|
||||
@@ -2090,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)
|
||||
@@ -2115,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.
|
||||
@@ -2208,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):
|
||||
@@ -2230,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)
|
||||
|
||||
@@ -2256,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]
|
||||
@@ -2380,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
|
||||
@@ -2468,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):
|
||||
@@ -2546,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 = {
|
||||
@@ -2600,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):
|
||||
@@ -2731,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')
|
||||
@@ -2889,16 +2888,20 @@ def preprocess_weights_for_loading(layer, weights,
|
||||
(2, 3, 1, 0))
|
||||
weights = [kernel, recurrent_kernel, bias]
|
||||
|
||||
if original_backend and K.backend() != original_backend:
|
||||
conv_layers = ['Conv1D',
|
||||
'Conv2D',
|
||||
'Conv3D',
|
||||
'Conv2DTranspose']
|
||||
if layer.__class__.__name__ in conv_layers:
|
||||
conv_layers = ['Conv1D',
|
||||
'Conv2D',
|
||||
'Conv3D',
|
||||
'Conv2DTranspose',
|
||||
'ConvLSTM2D']
|
||||
if layer.__class__.__name__ in conv_layers:
|
||||
if original_backend and K.backend() != original_backend:
|
||||
weights[0] = conv_utils.convert_kernel(weights[0])
|
||||
if layer.__class__.__name__ == 'ConvLSTM2D':
|
||||
weights[0] = conv_utils.convert_kernel(weights[0])
|
||||
weights[1] = conv_utils.convert_kernel(weights[1])
|
||||
if layer.__class__.__name__ == 'ConvLSTM2D':
|
||||
weights[1] = conv_utils.convert_kernel(weights[1])
|
||||
if K.int_shape(layer.weights[0]) != weights[0].shape:
|
||||
weights[0] = np.transpose(weights[0], (3, 2, 0, 1))
|
||||
if layer.__class__.__name__ == 'ConvLSTM2D':
|
||||
weights[1] = np.transpose(weights[1], (3, 2, 0, 1))
|
||||
return weights
|
||||
|
||||
|
||||
|
||||
+51
-53
@@ -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:
|
||||
@@ -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,12 +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. Ignored for Tensorflow backend.
|
||||
**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)
|
||||
@@ -983,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()]
|
||||
|
||||
@@ -1016,13 +1016,16 @@ class Model(Container):
|
||||
self.train_function = K.function(inputs,
|
||||
[self.total_loss] + self.metrics_tensors,
|
||||
updates=updates,
|
||||
name='train_function',
|
||||
**self._function_kwargs)
|
||||
|
||||
def _make_test_function(self):
|
||||
if not hasattr(self, 'test_function'):
|
||||
raise RuntimeError('You must compile your model before using it.')
|
||||
if self.test_function is None:
|
||||
inputs = self._feed_inputs + self._feed_targets + self._feed_sample_weights
|
||||
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.
|
||||
@@ -1030,11 +1033,13 @@ class Model(Container):
|
||||
self.test_function = K.function(inputs,
|
||||
[self.total_loss] + self.metrics_tensors,
|
||||
updates=self.state_updates,
|
||||
name='test_function',
|
||||
**self._function_kwargs)
|
||||
|
||||
def _make_predict_function(self):
|
||||
if not hasattr(self, 'predict_function'):
|
||||
self.predict_function = None
|
||||
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()]
|
||||
@@ -1042,11 +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,
|
||||
**kwargs)
|
||||
name='predict_function',
|
||||
**self._function_kwargs)
|
||||
|
||||
def _fit_loop(self, f, ins, out_labels=None, batch_size=32,
|
||||
epochs=100, verbose=1, callbacks=None,
|
||||
@@ -1156,6 +1161,8 @@ class Model(Container):
|
||||
batch_logs[l] = o
|
||||
|
||||
callbacks.on_batch_end(batch_index, batch_logs)
|
||||
if callback_model.stop_training:
|
||||
break
|
||||
|
||||
if batch_index == len(batches) - 1: # Last batch.
|
||||
if do_validation:
|
||||
@@ -1352,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
|
||||
@@ -1412,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,
|
||||
@@ -1431,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) '
|
||||
@@ -1698,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,
|
||||
@@ -1825,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)` '
|
||||
@@ -1836,8 +1833,11 @@ class Model(Container):
|
||||
str(validation_data))
|
||||
val_x, val_y, val_sample_weights = self._standardize_user_data(
|
||||
val_x, val_y, val_sample_weight)
|
||||
val_data = val_x + val_y + val_sample_weights
|
||||
if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
|
||||
val_data += [0.]
|
||||
for cbk in callbacks:
|
||||
cbk.validation_data = val_x + [val_y, val_sample_weights]
|
||||
cbk.validation_data = val_data
|
||||
enqueuer = None
|
||||
|
||||
try:
|
||||
@@ -1864,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)` '
|
||||
@@ -1936,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.
|
||||
@@ -1997,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) '
|
||||
@@ -2033,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):
|
||||
@@ -2092,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):
|
||||
|
||||
+247
-309
@@ -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 = {
|
||||
@@ -264,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)`
|
||||
@@ -294,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,
|
||||
@@ -382,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:
|
||||
@@ -418,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),
|
||||
@@ -507,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:
|
||||
@@ -543,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),
|
||||
@@ -632,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:
|
||||
@@ -672,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),
|
||||
@@ -707,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) +
|
||||
@@ -780,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
|
||||
@@ -795,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()
|
||||
@@ -845,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:
|
||||
@@ -890,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),
|
||||
@@ -931,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))
|
||||
@@ -995,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]
|
||||
|
||||
@@ -1010,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()
|
||||
@@ -1044,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)
|
||||
@@ -1099,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],
|
||||
@@ -1168,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,
|
||||
@@ -1231,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)
|
||||
@@ -1292,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,
|
||||
@@ -1319,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]
|
||||
@@ -1329,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]
|
||||
@@ -1342,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,
|
||||
@@ -1399,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)
|
||||
@@ -1427,43 +1380,44 @@ 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] + 2 * self.padding[0][0]
|
||||
dim1 = input_shape[2] + self.padding[0][0] + self.padding[0][1]
|
||||
else:
|
||||
dim1 = None
|
||||
if input_shape[3] is not None:
|
||||
dim2 = input_shape[3] + 2 * self.padding[1][0]
|
||||
dim2 = input_shape[3] + self.padding[1][0] + self.padding[1][1]
|
||||
else:
|
||||
dim2 = None
|
||||
if input_shape[4] is not None:
|
||||
dim3 = input_shape[4] + 2 * self.padding[2][0]
|
||||
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] + 2 * self.padding[0][1]
|
||||
dim1 = input_shape[1] + self.padding[0][0] + self.padding[0][1]
|
||||
else:
|
||||
dim1 = None
|
||||
if input_shape[2] is not None:
|
||||
dim2 = input_shape[2] + 2 * self.padding[1][1]
|
||||
dim2 = input_shape[2] + self.padding[1][0] + self.padding[1][1]
|
||||
else:
|
||||
dim2 = None
|
||||
if input_shape[3] is not None:
|
||||
dim3 = input_shape[3] + 2 * self.padding[2][1]
|
||||
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,
|
||||
@@ -1501,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:
|
||||
@@ -1577,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)
|
||||
@@ -1604,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[:,
|
||||
@@ -1637,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]:,
|
||||
@@ -1657,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,
|
||||
@@ -1705,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)
|
||||
@@ -1736,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]
|
||||
@@ -1750,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]
|
||||
@@ -1768,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,
|
||||
@@ -1888,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.
|
||||
|
||||
@@ -105,9 +108,13 @@ class ConvRecurrent2D(Recurrent):
|
||||
self.return_sequences = return_sequences
|
||||
self.go_backwards = go_backwards
|
||||
self.stateful = stateful
|
||||
self.input_spec = InputSpec(ndim=5)
|
||||
self.input_spec = [InputSpec(ndim=5)]
|
||||
self.state_spec = None
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
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]
|
||||
@@ -126,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,
|
||||
@@ -181,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).
|
||||
@@ -271,7 +278,6 @@ class ConvLSTM2D(ConvRecurrent2D):
|
||||
cells output
|
||||
"""
|
||||
|
||||
@interfaces.legacy_convlstm2d_support
|
||||
def __init__(self, filters,
|
||||
kernel_size,
|
||||
strides=(1, 1),
|
||||
@@ -328,10 +334,14 @@ class ConvLSTM2D(ConvRecurrent2D):
|
||||
|
||||
self.dropout = min(1., max(0., dropout))
|
||||
self.recurrent_dropout = min(1., max(0., recurrent_dropout))
|
||||
self.state_spec = [InputSpec(ndim=4), InputSpec(ndim=4)]
|
||||
|
||||
def build(self, input_shape):
|
||||
# TODO: better handling of input spec
|
||||
self.input_spec = InputSpec(shape=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()
|
||||
@@ -347,6 +357,10 @@ class ConvLSTM2D(ConvRecurrent2D):
|
||||
raise ValueError('The channel dimension of the inputs '
|
||||
'should be defined. Found `None`.')
|
||||
input_dim = input_shape[channel_axis]
|
||||
state_shape = [None] * 4
|
||||
state_shape[channel_axis] = input_dim
|
||||
state_shape = tuple(state_shape)
|
||||
self.state_spec = [InputSpec(shape=state_shape), InputSpec(shape=state_shape)]
|
||||
kernel_shape = self.kernel_size + (input_dim, self.filters * 4)
|
||||
self.kernel_shape = kernel_shape
|
||||
recurrent_kernel_shape = self.kernel_size + (self.filters, self.filters * 4)
|
||||
@@ -413,8 +427,9 @@ class ConvLSTM2D(ConvRecurrent2D):
|
||||
def reset_states(self):
|
||||
if not self.stateful:
|
||||
raise RuntimeError('Layer must be stateful.')
|
||||
input_shape = self.input_spec.shape
|
||||
output_shape = self.compute_output_shape(input_shape)
|
||||
input_shape = self.input_spec[0].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 '
|
||||
@@ -465,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,
|
||||
|
||||
+47
-152
@@ -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
|
||||
@@ -377,30 +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 x.
|
||||
# solution:
|
||||
# 1) rely on x._keras_shape
|
||||
# 2) fallback: K.int_shape
|
||||
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 = 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}
|
||||
@@ -443,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)
|
||||
@@ -481,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 '
|
||||
@@ -489,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):
|
||||
@@ -525,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)
|
||||
@@ -558,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.
|
||||
|
||||
@@ -595,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 {}
|
||||
@@ -605,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)
|
||||
@@ -671,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()))
|
||||
@@ -707,21 +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']
|
||||
|
||||
config['function'] = function
|
||||
config['output_shape'] = output_shape
|
||||
return cls(**config)
|
||||
|
||||
|
||||
@@ -754,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)`.
|
||||
@@ -788,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,
|
||||
@@ -844,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,12 +108,15 @@ class Embedding(Layer):
|
||||
else:
|
||||
return K.not_equal(inputs, 0)
|
||||
|
||||
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 self.input_length:
|
||||
input_length = input_shape[1]
|
||||
else:
|
||||
input_length = self.input_length
|
||||
return (input_shape[0], input_length, self.output_dim)
|
||||
return tensor_shape.TensorShape([input_shape[0],
|
||||
input_length,
|
||||
self.output_dim])
|
||||
|
||||
def call(self, inputs):
|
||||
if K.dtype(inputs) != 'int32':
|
||||
|
||||
+34
-44
@@ -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,12 +135,13 @@ 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):
|
||||
stride = self.strides[0]
|
||||
@@ -232,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:
|
||||
@@ -268,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),
|
||||
@@ -305,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]
|
||||
@@ -316,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],
|
||||
@@ -344,23 +334,23 @@ 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):
|
||||
stride_row, stride_col = self.strides
|
||||
|
||||
+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
|
||||
|
||||
+64
-94
@@ -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,
|
||||
@@ -146,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
|
||||
@@ -200,13 +204,14 @@ 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:
|
||||
return (input_shape[0], input_shape[1], self.units)
|
||||
return tensor_shape.TensorShape([input_shape[0], input_shape[1], self.units])
|
||||
else:
|
||||
return (input_shape[0], self.units)
|
||||
return tensor_shape.TensorShape([input_shape[0], self.units])
|
||||
|
||||
def compute_mask(self, inputs, mask):
|
||||
if self.return_sequences:
|
||||
@@ -256,6 +261,8 @@ class Recurrent(Layer):
|
||||
# Compute the full input spec, including state
|
||||
input_spec = self.input_spec
|
||||
state_spec = self.state_spec
|
||||
if not isinstance(input_spec, list):
|
||||
input_spec = [input_spec]
|
||||
if not isinstance(state_spec, list):
|
||||
state_spec = [state_spec]
|
||||
self.input_spec = input_spec + state_spec
|
||||
@@ -316,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)):
|
||||
@@ -389,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.
|
||||
@@ -433,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,
|
||||
@@ -475,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]
|
||||
@@ -509,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,
|
||||
@@ -566,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,
|
||||
@@ -601,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.
|
||||
@@ -650,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',
|
||||
@@ -694,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))
|
||||
@@ -745,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]
|
||||
|
||||
@@ -784,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,
|
||||
@@ -874,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.
|
||||
@@ -923,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',
|
||||
@@ -974,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))
|
||||
@@ -1037,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]
|
||||
|
||||
@@ -1079,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 = {}
|
||||
|
||||
@@ -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
|
||||
+13
-1
@@ -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))
|
||||
@@ -33,6 +39,12 @@ def hinge(y_true, y_pred):
|
||||
return K.mean(K.maximum(1. - y_true * y_pred, 0.), axis=-1)
|
||||
|
||||
|
||||
def categorical_hinge(y_true, y_pred):
|
||||
pos = K.sum(y_true * y_pred, axis=-1)
|
||||
neg = K.max((1.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):
|
||||
def cosh(x):
|
||||
return (K.exp(x) + K.exp(-x)) / 2
|
||||
|
||||
+16
-9
@@ -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
|
||||
|
||||
|
||||
|
||||
+46
-179
@@ -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.
|
||||
@@ -86,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):
|
||||
@@ -103,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'):
|
||||
@@ -167,7 +170,7 @@ def save_model(model, filepath, overwrite=True, include_optimizer=True):
|
||||
f.close()
|
||||
|
||||
|
||||
def load_model(filepath, custom_objects=None):
|
||||
def load_model(filepath, custom_objects=None, compile=True):
|
||||
"""Loads a model saved via `save_model`.
|
||||
|
||||
# Arguments
|
||||
@@ -175,12 +178,16 @@ def load_model(filepath, custom_objects=None):
|
||||
custom_objects: Optional dictionary mapping names
|
||||
(strings) to custom classes or functions to be
|
||||
considered during deserialization.
|
||||
compile: Boolean, whether to compile the model
|
||||
after loading.
|
||||
|
||||
# Returns
|
||||
A Keras model instance. If an optimizer was found
|
||||
as part of the saved model, the model is already
|
||||
compiled. Otherwise, the model is uncompiled and
|
||||
a warning will be displayed.
|
||||
a warning will be displayed. When `compile` is set
|
||||
to False, the compilation is omitted without any
|
||||
warning.
|
||||
|
||||
# Raises
|
||||
ImportError: if h5py is not available.
|
||||
@@ -242,6 +249,11 @@ def load_model(filepath, custom_objects=None):
|
||||
# set weights
|
||||
topology.load_weights_from_hdf5_group(f['model_weights'], model.layers)
|
||||
|
||||
# Early return if compilation is not required.
|
||||
if not compile:
|
||||
f.close()
|
||||
return model
|
||||
|
||||
# instantiate optimizer
|
||||
training_config = f.attrs.get('training_config')
|
||||
if training_config is None:
|
||||
@@ -315,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)
|
||||
|
||||
@@ -459,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):
|
||||
@@ -472,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
|
||||
@@ -496,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):
|
||||
@@ -561,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
|
||||
|
||||
@@ -608,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')
|
||||
@@ -667,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()
|
||||
@@ -687,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)
|
||||
@@ -705,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:
|
||||
@@ -726,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()
|
||||
@@ -756,7 +716,8 @@ class Sequential(Model):
|
||||
sample weighting (2D weights), set this to "temporal".
|
||||
"None" defaults to sample-wise weights (1D).
|
||||
**kwargs: for Theano backend, these are passed into K.function.
|
||||
Ignored for Tensorflow backend.
|
||||
When using the Tensorflow backend, these are passed into
|
||||
`tf.Session.run`.
|
||||
|
||||
# Example
|
||||
```python
|
||||
@@ -777,15 +738,18 @@ class Sequential(Model):
|
||||
**kwargs)
|
||||
self.optimizer = self.model.optimizer
|
||||
self.loss = self.model.loss
|
||||
self.total_loss = self.model.total_loss
|
||||
self.loss_weights = self.model.loss_weights
|
||||
self.metrics = self.model.metrics
|
||||
self.metrics_tensors = self.model.metrics_tensors
|
||||
self.metrics_names = self.model.metrics_names
|
||||
self.sample_weight_mode = self.model.sample_weight_mode
|
||||
self.sample_weights = self.model.sample_weights
|
||||
self.targets = self.model.targets
|
||||
|
||||
def fit(self, x, y, batch_size=32, epochs=10, verbose=1, callbacks=None,
|
||||
validation_split=0., validation_data=None, shuffle=True,
|
||||
class_weight=None, sample_weight=None, initial_epoch=0, **kwargs):
|
||||
class_weight=None, sample_weight=None, initial_epoch=0):
|
||||
"""Trains the model for a fixed number of epochs.
|
||||
|
||||
# Arguments
|
||||
@@ -832,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.')
|
||||
@@ -1010,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,
|
||||
@@ -1109,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):
|
||||
@@ -1149,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):
|
||||
@@ -1183,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__,
|
||||
@@ -1194,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 *
|
||||
+33
-18
@@ -1,13 +1,15 @@
|
||||
"""Keras optimizer classes (will eventually be replaced with core optimizers).
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
import six
|
||||
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):
|
||||
@@ -134,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):
|
||||
@@ -164,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
|
||||
@@ -182,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):
|
||||
@@ -195,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 = []
|
||||
@@ -228,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
|
||||
@@ -241,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)
|
||||
@@ -252,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 = []
|
||||
@@ -282,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
|
||||
@@ -297,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):
|
||||
@@ -310,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
|
||||
@@ -351,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.
|
||||
@@ -365,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):
|
||||
@@ -389,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
|
||||
@@ -421,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.
|
||||
@@ -435,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):
|
||||
@@ -458,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
|
||||
@@ -493,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,
|
||||
@@ -511,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):
|
||||
@@ -536,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]
|
||||
|
||||
@@ -578,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 = []
|
||||
@@ -608,6 +622,7 @@ class TFOptimizer(Optimizer):
|
||||
|
||||
# Aliases.
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
sgd = SGD
|
||||
rmsprop = RMSprop
|
||||
adagrad = Adagrad
|
||||
@@ -615,6 +630,7 @@ adadelta = Adadelta
|
||||
adam = Adam
|
||||
adamax = Adamax
|
||||
nadam = Nadam
|
||||
# pylint: enable=invalid-name
|
||||
|
||||
|
||||
def serialize(optimizer):
|
||||
@@ -670,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,25 +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
|
||||
|
||||
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,
|
||||
@@ -250,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
|
||||
@@ -346,6 +354,7 @@ class ImageDataGenerator(object):
|
||||
featurewise_std_normalization: divide inputs by std of the dataset.
|
||||
samplewise_std_normalization: divide each input by its std.
|
||||
zca_whitening: apply ZCA whitening.
|
||||
zca_epsilon: epsilon for ZCA whitening. Default is 1e-6.
|
||||
rotation_range: degrees (0 to 180).
|
||||
width_shift_range: fraction of total width.
|
||||
height_shift_range: fraction of total height.
|
||||
@@ -382,6 +391,7 @@ class ImageDataGenerator(object):
|
||||
featurewise_std_normalization=False,
|
||||
samplewise_std_normalization=False,
|
||||
zca_whitening=False,
|
||||
zca_epsilon=1e-6,
|
||||
rotation_range=0.,
|
||||
width_shift_range=0.,
|
||||
height_shift_range=0.,
|
||||
@@ -402,6 +412,7 @@ class ImageDataGenerator(object):
|
||||
self.featurewise_std_normalization = featurewise_std_normalization
|
||||
self.samplewise_std_normalization = samplewise_std_normalization
|
||||
self.zca_whitening = zca_whitening
|
||||
self.zca_epsilon = zca_epsilon
|
||||
self.rotation_range = rotation_range
|
||||
self.width_shift_range = width_shift_range
|
||||
self.height_shift_range = height_shift_range
|
||||
@@ -443,7 +454,7 @@ class ImageDataGenerator(object):
|
||||
'Received arg: ', zoom_range)
|
||||
|
||||
def flow(self, x, y=None, batch_size=32, shuffle=True, seed=None,
|
||||
save_to_dir=None, save_prefix='', save_format='jpeg'):
|
||||
save_to_dir=None, save_prefix='', save_format='png'):
|
||||
return NumpyArrayIterator(
|
||||
x, y, self,
|
||||
batch_size=batch_size,
|
||||
@@ -460,7 +471,7 @@ class ImageDataGenerator(object):
|
||||
batch_size=32, shuffle=True, seed=None,
|
||||
save_to_dir=None,
|
||||
save_prefix='',
|
||||
save_format='jpeg',
|
||||
save_format='png',
|
||||
follow_links=False):
|
||||
return DirectoryIterator(
|
||||
directory, self,
|
||||
@@ -529,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
|
||||
@@ -628,6 +645,7 @@ 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:
|
||||
@@ -668,10 +686,13 @@ 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)
|
||||
self.principal_components = np.dot(np.dot(u, np.diag(1. / np.sqrt(s + 10e-7))), u.T)
|
||||
self.principal_components = np.dot(np.dot(u, np.diag(1. / np.sqrt(s + self.zca_epsilon))), u.T)
|
||||
|
||||
|
||||
class Iterator(object):
|
||||
@@ -718,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
|
||||
@@ -752,7 +773,7 @@ class NumpyArrayIterator(Iterator):
|
||||
def __init__(self, x, y, image_data_generator,
|
||||
batch_size=32, shuffle=False, seed=None,
|
||||
data_format=None,
|
||||
save_to_dir=None, save_prefix='', save_format='jpeg'):
|
||||
save_to_dir=None, save_prefix='', save_format='png'):
|
||||
if y is not None and len(x) != len(y):
|
||||
raise ValueError('X (images tensor) and y (labels) '
|
||||
'should have the same length. '
|
||||
@@ -838,6 +859,8 @@ class DirectoryIterator(Iterator):
|
||||
`"binary"`: binary targets (if there are only two classes),
|
||||
`"categorical"`: categorical targets,
|
||||
`"sparse"`: integer targets,
|
||||
`"input"`: targets are images identical to input images (mainly
|
||||
used to work with autoencoders),
|
||||
`None`: no targets get yielded (only input images are yielded).
|
||||
batch_size: Integer, size of a batch.
|
||||
shuffle: Boolean, whether to shuffle the data between epochs.
|
||||
@@ -858,7 +881,7 @@ class DirectoryIterator(Iterator):
|
||||
classes=None, class_mode='categorical',
|
||||
batch_size=32, shuffle=True, seed=None,
|
||||
data_format=None,
|
||||
save_to_dir=None, save_prefix='', save_format='jpeg',
|
||||
save_to_dir=None, save_prefix='', save_format='png',
|
||||
follow_links=False):
|
||||
if data_format is None:
|
||||
data_format = K.image_data_format()
|
||||
@@ -881,10 +904,12 @@ class DirectoryIterator(Iterator):
|
||||
else:
|
||||
self.image_shape = (1,) + self.target_size
|
||||
self.classes = classes
|
||||
if class_mode not in {'categorical', 'binary', 'sparse', None}:
|
||||
if class_mode not in {'categorical', 'binary', 'sparse',
|
||||
'input', None}:
|
||||
raise ValueError('Invalid class_mode:', class_mode,
|
||||
'; expected one of "categorical", '
|
||||
'"binary", "sparse", or None.')
|
||||
'"binary", "sparse", "input"'
|
||||
' or None.')
|
||||
self.class_mode = class_mode
|
||||
self.save_to_dir = save_to_dir
|
||||
self.save_prefix = save_prefix
|
||||
@@ -972,7 +997,9 @@ class DirectoryIterator(Iterator):
|
||||
format=self.save_format)
|
||||
img.save(os.path.join(self.save_to_dir, fname))
|
||||
# build batch of labels
|
||||
if self.class_mode == 'sparse':
|
||||
if self.class_mode == 'input':
|
||||
batch_y = batch_x.copy()
|
||||
elif self.class_mode == 'sparse':
|
||||
batch_y = self.classes[index_array]
|
||||
elif self.class_mode == 'binary':
|
||||
batch_y = self.classes[index_array].astype(K.floatx())
|
||||
|
||||
@@ -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,12 +5,14 @@ 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
|
||||
import numpy as np
|
||||
from six.moves import range
|
||||
from six.moves import zip
|
||||
from collections import OrderedDict
|
||||
import warnings
|
||||
|
||||
if sys.version_info < (3,):
|
||||
@@ -22,7 +24,7 @@ else:
|
||||
def text_to_word_sequence(text,
|
||||
filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n',
|
||||
lower=True, split=" "):
|
||||
"""Converts a text to a sequence of word indices.
|
||||
"""Converts a text to a sequence of words (or tokens).
|
||||
|
||||
# Arguments
|
||||
text: Input text (string).
|
||||
@@ -31,7 +33,7 @@ def text_to_word_sequence(text,
|
||||
split: Sentence split marker (string).
|
||||
|
||||
# Returns
|
||||
A list of integer word indices.
|
||||
A list of words (or tokens).
|
||||
"""
|
||||
if lower:
|
||||
text = text.lower()
|
||||
@@ -68,7 +70,7 @@ class Tokenizer(object):
|
||||
tabs and line breaks, minus the `'` character.
|
||||
lower: boolean. Whether to convert the texts to lowercase.
|
||||
split: character or string to use for token splitting.
|
||||
char_level: if True, every character will be treated as a word.
|
||||
char_level: if True, every character will be treated as a token.
|
||||
|
||||
By default, all punctuation is removed, turning the texts into
|
||||
space-separated sequences of words
|
||||
@@ -92,7 +94,7 @@ class Tokenizer(object):
|
||||
if kwargs:
|
||||
raise TypeError('Unrecognized keyword arguments: ' + str(kwargs))
|
||||
|
||||
self.word_counts = {}
|
||||
self.word_counts = OrderedDict()
|
||||
self.word_docs = {}
|
||||
self.filters = filters
|
||||
self.split = split
|
||||
|
||||
@@ -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
|
||||
|
||||
+18
-15
@@ -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
|
||||
|
||||
@@ -70,7 +74,7 @@ def convert_kernel(kernel):
|
||||
Also works reciprocally, since the transformation is its own inverse.
|
||||
|
||||
# Arguments
|
||||
kernel: Numpy array (4D or 5D).
|
||||
kernel: Numpy array (3D, 4D or 5D).
|
||||
|
||||
# Returns
|
||||
The converted kernel.
|
||||
@@ -79,7 +83,7 @@ def convert_kernel(kernel):
|
||||
ValueError: in case of invalid kernel shape or invalid data_format.
|
||||
"""
|
||||
kernel = np.asarray(kernel)
|
||||
if not 4 <= kernel.ndim <= 5:
|
||||
if not 3 <= kernel.ndim <= 5:
|
||||
raise ValueError('Invalid kernel shape:', kernel.shape)
|
||||
slices = [slice(None, None, -1) for _ in range(kernel.ndim)]
|
||||
no_flip = (slice(None, None), slice(None, None))
|
||||
@@ -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
|
||||
|
||||
+24
-17
@@ -1,19 +1,19 @@
|
||||
"""Utilities for file download and caching."""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import functools
|
||||
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
|
||||
|
||||
|
||||
@@ -36,8 +36,10 @@ if sys.version_info[0] == 2:
|
||||
data: `data` argument passed to `urlopen`.
|
||||
"""
|
||||
def chunk_read(response, chunk_size=8192, reporthook=None):
|
||||
total_size = response.info().get('Content-Length').strip()
|
||||
total_size = int(total_size)
|
||||
content_type = response.info().get('Content-Length')
|
||||
total_size = -1
|
||||
if content_type is not None:
|
||||
total_size = int(content_type.strip())
|
||||
count = 0
|
||||
while 1:
|
||||
chunk = response.read(chunk_size)
|
||||
@@ -54,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'):
|
||||
@@ -186,19 +188,24 @@ def get_file(fname,
|
||||
|
||||
if download:
|
||||
print('Downloading data from', origin)
|
||||
progbar = None
|
||||
|
||||
def dl_progress(count, block_size, total_size, progbar=None):
|
||||
if progbar is None:
|
||||
progbar = Progbar(total_size)
|
||||
class ProgressTracker(object):
|
||||
# Maintain progbar for the lifetime of download.
|
||||
# This design was chosen for Python 2.7 compatibility.
|
||||
progbar = None
|
||||
|
||||
def dl_progress(count, block_size, total_size):
|
||||
if ProgressTracker.progbar is None:
|
||||
if total_size is -1:
|
||||
total_size = None
|
||||
ProgressTracker.progbar = Progbar(total_size)
|
||||
else:
|
||||
progbar.update(count * block_size)
|
||||
ProgressTracker.progbar.update(count * block_size)
|
||||
|
||||
error_msg = 'URL fetch failure on {}: {} -- {}'
|
||||
try:
|
||||
try:
|
||||
urlretrieve(origin, fpath,
|
||||
functools.partial(dl_progress, progbar=progbar))
|
||||
urlretrieve(origin, fpath, dl_progress)
|
||||
except URLError as e:
|
||||
raise Exception(error_msg.format(origin, e.errno, e.reason))
|
||||
except HTTPError as e:
|
||||
@@ -207,7 +214,7 @@ def get_file(fname,
|
||||
if os.path.exists(fpath):
|
||||
os.remove(fpath)
|
||||
raise
|
||||
progbar = None
|
||||
ProgressTracker.progbar = None
|
||||
|
||||
if untar:
|
||||
if not os.path.exists(untar_fpath):
|
||||
|
||||
@@ -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 = {}
|
||||
|
||||
@@ -133,17 +135,20 @@ def deserialize_keras_object(identifier, module_objects=None,
|
||||
': ' + class_name)
|
||||
if hasattr(cls, 'from_config'):
|
||||
arg_spec = inspect.getargspec(cls.from_config)
|
||||
custom_objects = custom_objects or {}
|
||||
if 'custom_objects' in arg_spec.args:
|
||||
custom_objects = custom_objects or {}
|
||||
return cls.from_config(config['config'],
|
||||
custom_objects=dict(list(_GLOBAL_CUSTOM_OBJECTS.items()) +
|
||||
list(custom_objects.items())))
|
||||
return cls.from_config(config['config'])
|
||||
with CustomObjectScope(custom_objects):
|
||||
return cls.from_config(config['config'])
|
||||
else:
|
||||
# Then `cls` may be a function returning a class.
|
||||
# in this case by convention `config` holds
|
||||
# the kwargs of the function.
|
||||
return cls(**config['config'])
|
||||
custom_objects = custom_objects or {}
|
||||
with CustomObjectScope(custom_objects):
|
||||
return cls(**config['config'])
|
||||
elif isinstance(identifier, six.string_types):
|
||||
function_name = identifier
|
||||
if custom_objects and function_name in custom_objects:
|
||||
@@ -153,7 +158,7 @@ def deserialize_keras_object(identifier, module_objects=None,
|
||||
else:
|
||||
fn = module_objects.get(function_name)
|
||||
if fn is None:
|
||||
raise ValueError('Unknown ' + printable_module_name,
|
||||
raise ValueError('Unknown ' + printable_module_name +
|
||||
':' + function_name)
|
||||
return fn
|
||||
else:
|
||||
@@ -208,12 +213,14 @@ class Progbar(object):
|
||||
"""Displays a progress bar.
|
||||
|
||||
# Arguments
|
||||
target: Total number of steps expected.
|
||||
target: Total number of steps expected, None if unknown.
|
||||
interval: Minimum visual progress update interval (in seconds).
|
||||
"""
|
||||
|
||||
def __init__(self, target, width=30, verbose=1, interval=0.05):
|
||||
self.width = width
|
||||
if target is None:
|
||||
target = -1
|
||||
self.target = target
|
||||
self.sum_values = {}
|
||||
self.unique_values = []
|
||||
@@ -253,21 +260,22 @@ class Progbar(object):
|
||||
sys.stdout.write('\b' * prev_total_width)
|
||||
sys.stdout.write('\r')
|
||||
|
||||
numdigits = int(np.floor(np.log10(self.target))) + 1
|
||||
barstr = '%%%dd/%%%dd [' % (numdigits, numdigits)
|
||||
bar = barstr % (current, self.target)
|
||||
prog = float(current) / self.target
|
||||
prog_width = int(self.width * prog)
|
||||
if prog_width > 0:
|
||||
bar += ('=' * (prog_width - 1))
|
||||
if current < self.target:
|
||||
bar += '>'
|
||||
else:
|
||||
bar += '='
|
||||
bar += ('.' * (self.width - prog_width))
|
||||
bar += ']'
|
||||
sys.stdout.write(bar)
|
||||
self.total_width = len(bar)
|
||||
if self.target is not -1:
|
||||
numdigits = int(np.floor(np.log10(self.target))) + 1
|
||||
barstr = '%%%dd/%%%dd [' % (numdigits, numdigits)
|
||||
bar = barstr % (current, self.target)
|
||||
prog = float(current) / self.target
|
||||
prog_width = int(self.width * prog)
|
||||
if prog_width > 0:
|
||||
bar += ('=' * (prog_width - 1))
|
||||
if current < self.target:
|
||||
bar += '>'
|
||||
else:
|
||||
bar += '='
|
||||
bar += ('.' * (self.width - prog_width))
|
||||
bar += ']'
|
||||
sys.stdout.write(bar)
|
||||
self.total_width = len(bar)
|
||||
|
||||
if current:
|
||||
time_per_unit = (now - self.start) / current
|
||||
@@ -275,7 +283,7 @@ class Progbar(object):
|
||||
time_per_unit = 0
|
||||
eta = time_per_unit * (self.target - current)
|
||||
info = ''
|
||||
if current < self.target:
|
||||
if current < self.target and self.target is not -1:
|
||||
info += ' - ETA: %ds' % eta
|
||||
else:
|
||||
info += ' - %ds' % (now - self.start)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -62,8 +64,8 @@ class HDF5Matrix(object):
|
||||
return self.end - self.start
|
||||
|
||||
def __getitem__(self, key):
|
||||
start, stop = key.start, key.stop
|
||||
if isinstance(key, slice):
|
||||
start, stop = key.start, key.stop
|
||||
if start is None:
|
||||
start = 0
|
||||
if stop is 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
|
||||
|
||||
|
||||
@@ -167,7 +171,7 @@ def convert_dense_weights_data_format(dense,
|
||||
came before the target `Dense` layer.
|
||||
target_data_format: One of "channels_last", "channels_first".
|
||||
Set it "channels_last"
|
||||
if converting a "chnnels_first" model to "channels_last",
|
||||
if converting a "channels_first" model to "channels_last",
|
||||
or reciprocally.
|
||||
"""
|
||||
assert target_data_format in {'channels_last', 'channels_first'}
|
||||
|
||||
@@ -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
|
||||
|
||||
+41
-13
@@ -1,43 +1,57 @@
|
||||
"""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:
|
||||
# Fall back on pydot if necessary.
|
||||
try:
|
||||
import pydot
|
||||
import pydot # pylint: disable=g-import-not-at-top
|
||||
except ImportError:
|
||||
pydot = None
|
||||
|
||||
|
||||
def _check_pydot():
|
||||
try:
|
||||
# Attempt to create an image of a blank graph to check the pydot/graphviz installation.
|
||||
# Attempt to create an image of a blank graph
|
||||
# to check the pydot/graphviz installation.
|
||||
pydot.Dot.create(pydot.Dot())
|
||||
except Exception: # pydot raises a generic Exception here, so no specific class can be caught.
|
||||
except Exception:
|
||||
# pydot raises a generic Exception here,
|
||||
# so no specific class can be caught.
|
||||
raise ImportError('Failed to import pydot. You must install pydot'
|
||||
' and graphviz for `pydotprint` to work.')
|
||||
|
||||
|
||||
def model_to_dot(model, show_shapes=False, show_layer_names=True):
|
||||
"""Converts a Keras model to dot format.
|
||||
def model_to_dot(model,
|
||||
show_shapes=False,
|
||||
show_layer_names=True,
|
||||
rankdir='TB'):
|
||||
"""Convert a Keras model to dot format.
|
||||
|
||||
# Arguments
|
||||
model: A Keras model instance.
|
||||
show_shapes: whether to display shape information.
|
||||
show_layer_names: whether to display layer names.
|
||||
rankdir: `rankdir` argument passed to PyDot,
|
||||
a string specifying the format of the plot:
|
||||
'TB' creates a vertical plot;
|
||||
'LR' creates a horizontal plot.
|
||||
|
||||
# Returns
|
||||
A `pydot.Dot` instance representing the Keras model.
|
||||
"""
|
||||
from ..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()
|
||||
dot.set('rankdir', 'TB')
|
||||
dot.set('rankdir', rankdir)
|
||||
dot.set('concentrate', True)
|
||||
dot.set_node_defaults(shape='record')
|
||||
|
||||
@@ -78,8 +92,9 @@ def model_to_dot(model, show_shapes=False, show_layer_names=True):
|
||||
[str(ishape) for ishape in layer.input_shapes])
|
||||
else:
|
||||
inputlabels = 'multiple'
|
||||
label = '%s\n|{input:|output:}|{{%s}|{%s}}' % (label, inputlabels, outputlabels)
|
||||
|
||||
label = '%s\n|{input:|output:}|{{%s}|{%s}}' % (label,
|
||||
inputlabels,
|
||||
outputlabels)
|
||||
node = pydot.Node(layer_id, label=label)
|
||||
dot.add_node(node)
|
||||
|
||||
@@ -99,8 +114,21 @@ def model_to_dot(model, show_shapes=False, show_layer_names=True):
|
||||
def plot_model(model,
|
||||
to_file='model.png',
|
||||
show_shapes=False,
|
||||
show_layer_names=True):
|
||||
dot = model_to_dot(model, show_shapes, show_layer_names)
|
||||
show_layer_names=True,
|
||||
rankdir='TB'):
|
||||
"""Converts a Keras model to dot format and save to a file.
|
||||
|
||||
# Arguments
|
||||
model: A Keras model instance
|
||||
to_file: File name of the plot image.
|
||||
show_shapes: whether to display shape information.
|
||||
show_layer_names: whether to display layer names.
|
||||
rankdir: `rankdir` argument passed to PyDot,
|
||||
a string specifying the format of the plot:
|
||||
'TB' creates a vertical plot;
|
||||
'LR' creates a horizontal plot.
|
||||
"""
|
||||
dot = model_to_dot(model, show_shapes, show_layer_names, rankdir)
|
||||
_, extension = os.path.splitext(to_file)
|
||||
if not extension:
|
||||
extension = 'png'
|
||||
|
||||
@@ -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,7 +89,7 @@ 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
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ from setuptools import find_packages
|
||||
|
||||
|
||||
setup(name='Keras',
|
||||
version='2.0.4',
|
||||
version='2.0.4-tf',
|
||||
description='Deep Learning for Python',
|
||||
author='Francois Chollet',
|
||||
author_email='francois.chollet@gmail.com',
|
||||
|
||||
@@ -103,4 +103,5 @@ def test_inceptionv3_pooling():
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__])
|
||||
# pytest.main([__file__])
|
||||
test_vgg16()
|
||||
|
||||
@@ -77,6 +77,21 @@ def check_composed_tensor_operations(first_function_name, first_function_args,
|
||||
|
||||
class TestBackend(object):
|
||||
|
||||
def test_is_keras_tensor(self):
|
||||
for K in [KTH, KTF]:
|
||||
np_var = np.array([1, 2])
|
||||
try:
|
||||
K.is_keras_tensor(np_var)
|
||||
assert True is False
|
||||
except ValueError:
|
||||
# This is the expected behavior
|
||||
continue
|
||||
|
||||
keras_var = K.variable(np_var)
|
||||
assert K.is_keras_tensor(keras_var) is True
|
||||
keras_placeholder = K.placeholder(shape=(2, 4, 5))
|
||||
assert K.is_keras_tensor(keras_placeholder) is True
|
||||
|
||||
def test_linear_operations(self):
|
||||
check_two_tensor_operation('dot', (4, 2), (2, 4))
|
||||
check_two_tensor_operation('dot', (4, 2), (5, 2, 3))
|
||||
|
||||
@@ -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
|
||||
@@ -144,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
|
||||
@@ -185,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
|
||||
@@ -228,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
|
||||
@@ -250,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])
|
||||
@@ -320,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)
|
||||
@@ -341,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)
|
||||
@@ -373,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])
|
||||
@@ -464,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
|
||||
@@ -577,5 +573,32 @@ def test_recursion_with_bn_and_loss():
|
||||
model2.fit(x, y, verbose=0, epochs=1)
|
||||
|
||||
|
||||
def test_shared_layer_depth_is_correct():
|
||||
# Basic outline here: we have a shared embedding layer, and two inputs that go through
|
||||
# different depths of computation in the graph before the final output. We need the computed
|
||||
# depth of the input layers to be the same, because they both pass through the embedding layer
|
||||
# before anything else happens. That's what we're testing.
|
||||
from keras.layers import Embedding, Input, Dense, Concatenate
|
||||
from keras.models import Model
|
||||
input1 = Input(shape=(10,), name="input1")
|
||||
input2 = Input(shape=(10,), name="input2")
|
||||
embedding_layer = Embedding(name="embedding", input_dim=5, output_dim=10)
|
||||
embedded_input1 = embedding_layer(input1)
|
||||
embedded_input2 = embedding_layer(input2)
|
||||
transformed_input2 = Dense(6)(Dense(5)(Dense(3)(embedded_input2)))
|
||||
final_output = Dense(2)(Concatenate()([embedded_input1, transformed_input2]))
|
||||
model = Model(inputs=[input1, input2], outputs=final_output)
|
||||
input1_depth = -1
|
||||
input2_depth = -1
|
||||
for depth, layers in model.layers_by_depth.items():
|
||||
for layer in layers:
|
||||
if layer.name == 'input1':
|
||||
input1_depth = depth
|
||||
if layer.name == 'input2':
|
||||
input2_depth = depth
|
||||
assert input1_depth != -1
|
||||
assert input1_depth == input2_depth
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__])
|
||||
|
||||
@@ -3,8 +3,8 @@ import numpy as np
|
||||
from numpy.testing import assert_allclose
|
||||
|
||||
from keras import backend as K
|
||||
from keras.models import Sequential
|
||||
from keras.layers import convolutional_recurrent
|
||||
from keras.models import Sequential, Model
|
||||
from keras.layers import convolutional_recurrent, Input
|
||||
from keras.utils.test_utils import layer_test
|
||||
from keras import regularizers
|
||||
|
||||
@@ -116,5 +116,18 @@ def test_convolutional_recurrent():
|
||||
'recurrent_dropout': 0.1},
|
||||
input_shape=inputs.shape)
|
||||
|
||||
# check state initialization
|
||||
layer = convolutional_recurrent.ConvLSTM2D(filters=filters,
|
||||
kernel_size=(num_row, num_col),
|
||||
data_format=data_format,
|
||||
return_sequences=return_sequences)
|
||||
layer.build(inputs.shape)
|
||||
x = Input(batch_shape=inputs.shape)
|
||||
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)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__])
|
||||
|
||||
@@ -494,20 +494,54 @@ def test_zero_padding_3d():
|
||||
stack_size))
|
||||
|
||||
# basic test
|
||||
layer_test(convolutional.ZeroPadding3D,
|
||||
kwargs={'padding': (2, 2, 2)},
|
||||
input_shape=inputs.shape)
|
||||
for data_format in ['channels_first', 'channels_last']:
|
||||
layer_test(convolutional.ZeroPadding3D,
|
||||
kwargs={'padding': (2, 2, 2), 'data_format': data_format},
|
||||
input_shape=inputs.shape)
|
||||
layer_test(convolutional.ZeroPadding3D,
|
||||
kwargs={'padding': ((1, 2), (3, 4), (0, 2)), 'data_format': data_format},
|
||||
input_shape=inputs.shape)
|
||||
|
||||
# correctness test
|
||||
layer = convolutional.ZeroPadding3D(padding=(2, 2, 2))
|
||||
layer.build(inputs.shape)
|
||||
output = layer(K.variable(inputs))
|
||||
np_output = K.eval(output)
|
||||
for offset in [0, 1, -1, -2]:
|
||||
assert_allclose(np_output[:, offset, :, :, :], 0.)
|
||||
assert_allclose(np_output[:, :, offset, :, :], 0.)
|
||||
assert_allclose(np_output[:, :, :, offset, :], 0.)
|
||||
assert_allclose(np_output[:, 2:-2, 2:-2, 2:-2, :], 1.)
|
||||
# correctness test
|
||||
layer = convolutional.ZeroPadding3D(padding=(2, 2, 2),
|
||||
data_format=data_format)
|
||||
layer.build(inputs.shape)
|
||||
output = layer(K.variable(inputs))
|
||||
np_output = K.eval(output)
|
||||
if data_format == 'channels_last':
|
||||
for offset in [0, 1, -1, -2]:
|
||||
assert_allclose(np_output[:, offset, :, :, :], 0.)
|
||||
assert_allclose(np_output[:, :, offset, :, :], 0.)
|
||||
assert_allclose(np_output[:, :, :, offset, :], 0.)
|
||||
assert_allclose(np_output[:, 2:-2, 2:-2, 2:-2, :], 1.)
|
||||
elif data_format == 'channels_first':
|
||||
for offset in [0, 1, -1, -2]:
|
||||
assert_allclose(np_output[:, :, offset, :, :], 0.)
|
||||
assert_allclose(np_output[:, :, :, offset, :], 0.)
|
||||
assert_allclose(np_output[:, :, :, :, offset], 0.)
|
||||
assert_allclose(np_output[:, :, 2:-2, 2:-2, 2:-2], 1.)
|
||||
|
||||
layer = convolutional.ZeroPadding3D(padding=((1, 2), (3, 4), (0, 2)),
|
||||
data_format=data_format)
|
||||
layer.build(inputs.shape)
|
||||
output = layer(K.variable(inputs))
|
||||
np_output = K.eval(output)
|
||||
if data_format == 'channels_last':
|
||||
for dim1_offset in [0, -1, -2]:
|
||||
assert_allclose(np_output[:, dim1_offset, :, :, :], 0.)
|
||||
for dim2_offset in [0, 1, 2, -1, -2, -3, -4]:
|
||||
assert_allclose(np_output[:, :, dim2_offset, :, :], 0.)
|
||||
for dim3_offset in [-1, -2]:
|
||||
assert_allclose(np_output[:, :, :, dim3_offset, :], 0.)
|
||||
assert_allclose(np_output[:, 1:-2, 3:-4, 0:-2, :], 1.)
|
||||
elif data_format == 'channels_first':
|
||||
for dim1_offset in [0, -1, -2]:
|
||||
assert_allclose(np_output[:, :, dim1_offset, :, :], 0.)
|
||||
for dim2_offset in [0, 1, 2, -1, -2, -3, -4]:
|
||||
assert_allclose(np_output[:, :, :, dim2_offset, :], 0.)
|
||||
for dim3_offset in [-1, -2]:
|
||||
assert_allclose(np_output[:, :, :, :, dim3_offset], 0.)
|
||||
assert_allclose(np_output[:, :, 1:-2, 3:-4, 0:-2], 1.)
|
||||
|
||||
|
||||
@keras_test
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -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,7 +2,7 @@ import pytest
|
||||
import numpy as np
|
||||
from numpy.testing import assert_allclose
|
||||
|
||||
from keras.layers import Dense, Activation, Input
|
||||
from keras.layers import Input
|
||||
from keras.utils.test_utils import layer_test, keras_test
|
||||
from keras.layers import normalization
|
||||
from keras.models import Sequential, Model
|
||||
|
||||
@@ -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,317 +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
|
||||
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
|
||||
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__])
|
||||
@@ -10,7 +10,8 @@ allobj = [losses.mean_squared_error,
|
||||
losses.mean_absolute_percentage_error,
|
||||
losses.mean_squared_logarithmic_error,
|
||||
losses.squared_hinge,
|
||||
losses.hinge, losses.categorical_crossentropy,
|
||||
losses.hinge,
|
||||
losses.categorical_crossentropy,
|
||||
losses.binary_crossentropy,
|
||||
losses.kullback_leibler_divergence,
|
||||
losses.poisson,
|
||||
@@ -45,5 +46,13 @@ def test_cce_one_hot():
|
||||
assert K.eval(losses.sparse_categorical_crossentropy(y_a, y_b)).shape == (6,)
|
||||
|
||||
|
||||
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]]))
|
||||
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, loss)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__])
|
||||
|
||||
@@ -160,6 +160,32 @@ class TestImage:
|
||||
assert(sorted(dir_iterator.filenames) == sorted(filenames))
|
||||
shutil.rmtree(tmp_folder)
|
||||
|
||||
def test_directory_iterator_class_mode_input(self):
|
||||
tmp_folder = tempfile.mkdtemp(prefix='test_images')
|
||||
os.mkdir(os.path.join(tmp_folder, 'class-1'))
|
||||
|
||||
# save the images in the paths
|
||||
count = 0
|
||||
for test_images in self.all_test_images:
|
||||
for im in test_images:
|
||||
filename = os.path.join(tmp_folder, 'class-1', 'image-{}.jpg'.format(count))
|
||||
im.save(os.path.join(tmp_folder, filename))
|
||||
count += 1
|
||||
|
||||
# create iterator
|
||||
generator = image.ImageDataGenerator()
|
||||
dir_iterator = generator.flow_from_directory(tmp_folder, class_mode='input')
|
||||
batch = next(dir_iterator)
|
||||
|
||||
# check if input and output have the same shape
|
||||
assert(batch[0].shape == batch[1].shape)
|
||||
# check if the input and output images are not the same numpy array
|
||||
input_img = batch[0][0]
|
||||
output_img = batch[1][0]
|
||||
output_img[0][0][0] += 1
|
||||
assert(input_img[0][0][0] != output_img[0][0][0])
|
||||
shutil.rmtree(tmp_folder)
|
||||
|
||||
def test_img_utils(self):
|
||||
height, width = 10, 8
|
||||
|
||||
|
||||
@@ -6,9 +6,12 @@ import pytest
|
||||
from csv import Sniffer
|
||||
import shutil
|
||||
from keras import optimizers
|
||||
from keras import initializers
|
||||
from keras import callbacks
|
||||
from keras.models import Sequential
|
||||
from keras.layers.core import Dense
|
||||
from keras.layers.core import Dense, Dropout
|
||||
from keras.layers.convolutional import Conv2D
|
||||
from keras.layers.pooling import MaxPooling2D, GlobalAveragePooling2D
|
||||
from keras.utils.test_utils import get_test_data
|
||||
from keras.utils.test_utils import keras_test
|
||||
from keras import backend as K
|
||||
@@ -22,6 +25,34 @@ train_samples = 20
|
||||
test_samples = 20
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_TerminateOnNaN():
|
||||
np.random.seed(1337)
|
||||
(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=num_class)
|
||||
|
||||
y_test = np_utils.to_categorical(y_test)
|
||||
y_train = np_utils.to_categorical(y_train)
|
||||
cbks = [callbacks.TerminateOnNaN()]
|
||||
model = Sequential()
|
||||
initializer = initializers.Constant(value=1e5)
|
||||
for _ in range(5):
|
||||
model.add(Dense(num_hidden, input_dim=input_dim, activation='relu',
|
||||
kernel_initializer=initializer))
|
||||
model.add(Dense(num_class, activation='linear'))
|
||||
model.compile(loss='mean_squared_error',
|
||||
optimizer='rmsprop')
|
||||
|
||||
history = model.fit(X_train, y_train, batch_size=batch_size,
|
||||
validation_data=(X_test, y_test), callbacks=cbks, epochs=20)
|
||||
loss = history.history['loss']
|
||||
assert len(loss) == 1
|
||||
assert loss[0] == np.inf
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_ModelCheckpoint():
|
||||
np.random.seed(1337)
|
||||
@@ -309,13 +340,17 @@ def test_TensorBoard():
|
||||
# case 1 Sequential
|
||||
model = Sequential()
|
||||
model.add(Dense(num_hidden, input_dim=input_dim, activation='relu'))
|
||||
model.add(Dropout(0.1))
|
||||
model.add(Dense(num_class, activation='softmax'))
|
||||
model.compile(loss='categorical_crossentropy',
|
||||
optimizer='sgd',
|
||||
metrics=['accuracy'])
|
||||
|
||||
tsb = callbacks.TensorBoard(log_dir=filepath, histogram_freq=1,
|
||||
write_images=True)
|
||||
write_images=True, write_grads=True,
|
||||
embeddings_freq=1,
|
||||
embeddings_layer_names=['dense_1'],
|
||||
batch_size=5)
|
||||
cbks = [tsb]
|
||||
|
||||
# fit with validation data
|
||||
@@ -348,6 +383,97 @@ def test_TensorBoard():
|
||||
shutil.rmtree(filepath)
|
||||
|
||||
|
||||
@keras_test
|
||||
@pytest.mark.skipif((K.backend() != 'tensorflow'),
|
||||
reason='Requires tensorflow backend')
|
||||
def test_TensorBoard_convnet():
|
||||
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,
|
||||
input_shape=input_shape,
|
||||
classification=True,
|
||||
num_classes=4)
|
||||
y_train = np_utils.to_categorical(y_train)
|
||||
y_test = np_utils.to_categorical(y_test)
|
||||
|
||||
model = Sequential([
|
||||
Conv2D(filters=8, kernel_size=3,
|
||||
activation='relu',
|
||||
input_shape=input_shape),
|
||||
MaxPooling2D(pool_size=2),
|
||||
Conv2D(filters=4, kernel_size=(3, 3),
|
||||
activation='relu', padding='same'),
|
||||
GlobalAveragePooling2D(),
|
||||
Dense(y_test.shape[-1], activation='softmax')
|
||||
])
|
||||
model.compile(loss='categorical_crossentropy',
|
||||
optimizer='rmsprop',
|
||||
metrics=['accuracy'])
|
||||
tsb = callbacks.TensorBoard(log_dir=filepath, histogram_freq=1,
|
||||
write_images=True, write_grads=True,
|
||||
batch_size=16)
|
||||
cbks = [tsb]
|
||||
model.summary()
|
||||
history = model.fit(x_train, y_train, epochs=2, batch_size=16,
|
||||
validation_data=(x_test, y_test),
|
||||
callbacks=cbks,
|
||||
verbose=0)
|
||||
assert os.path.exists(filepath)
|
||||
shutil.rmtree(filepath)
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_CallbackValData():
|
||||
np.random.seed(1337)
|
||||
(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=num_class)
|
||||
y_test = np_utils.to_categorical(y_test)
|
||||
y_train = np_utils.to_categorical(y_train)
|
||||
model = Sequential()
|
||||
model.add(Dense(num_hidden, input_dim=input_dim, activation='relu'))
|
||||
model.add(Dense(num_class, activation='softmax'))
|
||||
model.compile(loss='categorical_crossentropy',
|
||||
optimizer='sgd',
|
||||
metrics=['accuracy'])
|
||||
|
||||
cbk = callbacks.LambdaCallback(on_train_end=lambda x: 1)
|
||||
model.fit(X_train, y_train, batch_size=batch_size,
|
||||
validation_data=(X_test, y_test), callbacks=[cbk], epochs=1)
|
||||
|
||||
def data_generator(train):
|
||||
if train:
|
||||
max_batch_index = len(X_train) // batch_size
|
||||
else:
|
||||
max_batch_index = len(X_test) // batch_size
|
||||
i = 0
|
||||
while 1:
|
||||
if train:
|
||||
yield (X_train[i * batch_size: (i + 1) * batch_size],
|
||||
y_train[i * batch_size: (i + 1) * batch_size])
|
||||
else:
|
||||
yield (X_test[i * batch_size: (i + 1) * batch_size],
|
||||
y_test[i * batch_size: (i + 1) * batch_size])
|
||||
i += 1
|
||||
i = i % max_batch_index
|
||||
|
||||
cbk2 = callbacks.LambdaCallback(on_train_end=lambda x: 1)
|
||||
model.fit_generator(data_generator(True), len(X_train), epochs=1,
|
||||
validation_data=(X_test, y_test),
|
||||
callbacks=[cbk2])
|
||||
|
||||
# callback validation data should always have x, y, and sample weights
|
||||
assert len(cbk.validation_data) == len(cbk2.validation_data) == 3
|
||||
assert cbk.validation_data[0] is cbk2.validation_data[0]
|
||||
assert cbk.validation_data[1] is cbk2.validation_data[1]
|
||||
assert cbk.validation_data[2].shape == cbk2.validation_data[2].shape
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_LambdaCallback():
|
||||
np.random.seed(1337)
|
||||
|
||||
@@ -9,8 +9,6 @@ from six.moves.urllib.parse import urljoin
|
||||
from keras.utils.data_utils import get_file
|
||||
from keras.utils.data_utils import validate_file
|
||||
from keras.utils.data_utils import _hash_file
|
||||
from keras import activations
|
||||
from keras import regularizers
|
||||
|
||||
|
||||
def test_data_utils():
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
'''Tests for functions in io_utils.py.
|
||||
'''
|
||||
import os
|
||||
import pytest
|
||||
from keras.models import Sequential
|
||||
from keras.layers import Dense
|
||||
from keras.utils.io_utils import HDF5Matrix
|
||||
import numpy as np
|
||||
import warnings
|
||||
import h5py
|
||||
|
||||
|
||||
def create_dataset(h5_path='test.h5'):
|
||||
X = np.random.randn(200, 10).astype('float32')
|
||||
y = np.random.randint(0, 2, size=(200, 1))
|
||||
f = h5py.File(h5_path, 'w')
|
||||
# Creating dataset to store features
|
||||
X_dset = f.create_dataset('my_data', (200, 10), dtype='f')
|
||||
X_dset[:] = X
|
||||
# Creating dataset to store labels
|
||||
y_dset = f.create_dataset('my_labels', (200, 1), dtype='i')
|
||||
y_dset[:] = y
|
||||
f.close()
|
||||
|
||||
|
||||
def test_io_utils():
|
||||
'''Tests the HDF5Matrix code using the sample from @jfsantos at
|
||||
https://gist.github.com/jfsantos/e2ef822c744357a4ed16ec0c885100a3
|
||||
'''
|
||||
h5_path = 'test.h5'
|
||||
create_dataset(h5_path)
|
||||
|
||||
# Instantiating HDF5Matrix for the training set, which is a slice of the first 150 elements
|
||||
X_train = HDF5Matrix(h5_path, 'my_data', start=0, end=150)
|
||||
y_train = HDF5Matrix(h5_path, 'my_labels', start=0, end=150)
|
||||
|
||||
# Likewise for the test set
|
||||
X_test = HDF5Matrix(h5_path, 'my_data', start=150, end=200)
|
||||
y_test = HDF5Matrix(h5_path, 'my_labels', start=150, end=200)
|
||||
|
||||
# HDF5Matrix behave more or less like Numpy matrices with regards to indexing
|
||||
assert y_train.shape == (150, 1), 'HDF5Matrix shape should match input array'
|
||||
# But they do not support negative indices, so don't try print(X_train[-1])
|
||||
|
||||
model = Sequential()
|
||||
model.add(Dense(64, input_shape=(10,), activation='relu'))
|
||||
model.add(Dense(1, activation='sigmoid'))
|
||||
|
||||
model.compile(loss='binary_crossentropy', optimizer='sgd')
|
||||
|
||||
# Note: you have to use shuffle='batch' or False with HDF5Matrix
|
||||
model.fit(X_train, y_train, batch_size=32, shuffle='batch', verbose=False)
|
||||
# test that evalutation and prediction don't crash and return reasonable results
|
||||
out_pred = model.predict(X_test, batch_size=32, verbose=False)
|
||||
out_eval = model.evaluate(X_test, y_test, batch_size=32, verbose=False)
|
||||
|
||||
assert out_pred.shape == (50, 1), 'Prediction shape does not match'
|
||||
assert out_eval.shape == (), 'Shape of evaluation does not match'
|
||||
assert out_eval > 0, 'Evaluation value does not meet criteria: {}'.format(out_eval)
|
||||
|
||||
os.remove(h5_path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__])
|
||||
@@ -2,8 +2,6 @@ import pytest
|
||||
import numpy as np
|
||||
|
||||
from keras.utils.test_utils import get_test_data
|
||||
from keras.utils import np_utils
|
||||
from keras import backend as K
|
||||
|
||||
from keras.models import Sequential
|
||||
from keras.layers.core import Dense, Activation
|
||||
|
||||
@@ -4,6 +4,7 @@ import tempfile
|
||||
import numpy as np
|
||||
from numpy.testing import assert_allclose
|
||||
|
||||
from keras import backend as K
|
||||
from keras.models import Model, Sequential
|
||||
from keras.layers import Dense, Lambda, RepeatVector, TimeDistributed
|
||||
from keras.layers import Input
|
||||
@@ -76,7 +77,7 @@ def test_sequential_model_saving_2():
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_fuctional_model_saving():
|
||||
def test_functional_model_saving():
|
||||
input = Input(shape=(3,))
|
||||
x = Dense(2)(input)
|
||||
output = Dense(3)(x)
|
||||
@@ -131,10 +132,11 @@ def test_saving_multiple_metrics_outputs():
|
||||
|
||||
@keras_test
|
||||
def test_saving_without_compilation():
|
||||
"""Test saving model without compiling.
|
||||
"""
|
||||
model = Sequential()
|
||||
model.add(Dense(2, input_shape=(3,)))
|
||||
model.add(Dense(3))
|
||||
model.compile(loss='mse', optimizer='sgd', metrics=['acc'])
|
||||
|
||||
_, fname = tempfile.mkstemp('.h5')
|
||||
save_model(model, fname)
|
||||
@@ -269,7 +271,7 @@ def square_fn(x):
|
||||
@keras_test
|
||||
def test_saving_lambda_custom_objects():
|
||||
input = Input(shape=(3,))
|
||||
x = Lambda(lambda x: square_fn(x), output_shape=(3,))(input)
|
||||
x = Lambda(lambda x: square_fn(x))(input)
|
||||
output = Dense(3)(x)
|
||||
|
||||
model = Model(input, output)
|
||||
@@ -291,5 +293,28 @@ def test_saving_lambda_custom_objects():
|
||||
assert_allclose(out, out2, atol=1e-05)
|
||||
|
||||
|
||||
@keras_test
|
||||
def test_saving_custom_activation_function():
|
||||
x = Input(shape=(3,))
|
||||
output = Dense(3, activation=K.cos)(x)
|
||||
|
||||
model = Model(x, output)
|
||||
model.compile(loss=losses.MSE,
|
||||
optimizer=optimizers.RMSprop(lr=0.0001),
|
||||
metrics=[metrics.categorical_accuracy])
|
||||
x = np.random.random((1, 3))
|
||||
y = np.random.random((1, 3))
|
||||
model.train_on_batch(x, y)
|
||||
|
||||
out = model.predict(x)
|
||||
_, fname = tempfile.mkstemp('.h5')
|
||||
save_model(model, fname)
|
||||
|
||||
model = load_model(fname, custom_objects={'cos': K.cos})
|
||||
os.remove(fname)
|
||||
|
||||
out2 = model.predict(x)
|
||||
assert_allclose(out, out2, atol=1e-05)
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__])
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário