Comparar commits

...

156 Commits

Autor SHA1 Mensagem Data
Francois Chollet afbd5d34a3 merge 2017-05-24 14:57:32 -07:00
Francois Chollet 07e0fbc963 Style fixes. 2017-05-24 14:46:15 -07:00
nzw 7ef13165b7 Improve documents (#6727)
* Improve documents

* Fix style
2017-05-23 17:13:09 -07:00
Andrew Hundt d939f14843 stale bot specifies 30 days when it posts (#6735)
Got notified about some stale threads, but realized I forgot to put the number of days in the post's string.
2017-05-23 14:13:32 -07:00
Taehoon Lee ce0f97dbe3 Fix ImageNet weight loading for ResNet50 with channels_first (#6658)
Fix ImageNet weight loading for InceptionV3
2017-05-23 14:12:07 -07:00
cocuh 7e870a97ec Fix edge cases of custom object deserialization 2017-05-23 11:30:45 -07:00
Daniel Høyer Iversen a2c3fa2b96 Small clean ups (#6724)
* Remove unused variables

* progbar
2017-05-23 11:22:34 -07:00
nameless-Chatoyant 7f09d45efb Fix typo in docstring
Corrected a small annotation in Input()
2017-05-23 11:11:29 -07:00
meberstein 85fe6427a5 Added hinge loss for categorical classification (#6687)
* Fix bug in EarlyStopping to reset stopped_epoch in on_train_begin to allow it to be re-used

* Added hinge loss for categorical classification
2017-05-23 10:49:23 -07:00
Andrew Hundt b205ba1270 Automatically close stale issues (#6701)
@fchollet Merge this pull request plus follow https://github.com/integration/probot-stale to automatically mark the many 3 month old issues as stale, then close them after an additional 30 days.

I chose 30 additional days for closing because sometimes people go on vacation for a few weeks, this way they'll have time after being notified.
2017-05-23 10:34:31 -07:00
Francois Chollet 99e4e481c5 merge master 2017-05-22 15:30:24 -07:00
Arun Lobo e74a37438b Add Chrome timeline support in Tensorflow (#6693)
Fixes #6606
2017-05-22 13:55:03 -07:00
Francois Chollet 2061f41987 style fixes 2017-05-22 13:25:04 -07:00
Rusty c8d35caa7f Updated filters in text processing documentation (#6696) 2017-05-22 13:10:27 -07:00
Andrew Hundt cf57d28452 get_file() progbar fix (#6670)
* Fix get_file download progress bar

* Added a comment to clarify the purpose of the "enclosed" dictionary

* pep8

* Fix get_file download progress bar, including no Content-Length header.

* Progbar accepts target None in addition to -1.

* #6670 Remove Progbar implementation details from docstring
Only None should be supported on the Progbar target parameter,
target values of -1 are an unsupported implementation detail
that may be removed in the future.
2017-05-22 12:04:33 -07:00
Indy M c1a1c33ef9 updated fit on texts description (#6699)
fit_on_texts returns a list of words not integer indices as stated. I've corrected this.
2017-05-21 10:52:03 -07:00
Taehoon Lee bac16379a2 Fix typos (#6702) 2017-05-21 10:51:19 -07:00
Matt Gardner b5490b20d2 Fix depth calculation for shared layers (#6668)
* Fixed depth calculation for shared layers

* Added a failing test

* Update the node's depth too
2017-05-19 16:54:03 -07:00
Jun Kim 3061fcce60 Fix a typo in expand_dims() (#6671)
In comment: expended -> expanded
2017-05-18 16:12:48 -07:00
Daniel Høyer Iversen 7a3190de3b Typo in documentation (#6672) 2017-05-18 16:12:37 -07:00
Stefano ed9e8d2ff0 Update image.py (#6618)
Fixes https://github.com/fchollet/keras/issues/6612
2017-05-16 13:40:01 -07:00
Stefano 13303663ff Change save_format from jpg top png, because jpg is a loss format. (#6638)
* Change save_format from jpg top png, because jpg is a loss format.

* Change default format to png, because jpeg is a loss format.
2017-05-16 07:57:50 -07:00
Fariz Rahman 0d27d903c2 Bug fix in convolutional recurrent state setting
* Bug fix: convolutional recurrent (again)

* pep8

* Update convolutional_recurrent.py

* pep8
2017-05-14 10:42:44 -07:00
Kevin Mader 6220e35ccd adding io_utils test for hdf5matrix (#6610)
* adding io_utils test for hdf5matrix

* incorporating pep8 and feedback from @fchollet
2017-05-14 10:40:28 -07:00
Francois Chollet bc9dbc5de0 Style fix in error message 2017-05-12 11:08:46 -07:00
Kyle Dorman d67cf89759 Better error message for invalid functional api inputs (#6589) (#6593)
* Better error message for invalid funcational api inputs (#6589)

* raise ValueError if `inputs` is not a Keras tensor

* Move  to respective backends

* raise error if is_keras_tensor is called on a non-tensor object

* Fix failing tests

* responding to comments

* Update docstring comments to better explain expected behavior
2017-05-12 11:04:27 -07:00
Gökçen Eraslan a2dde60a2f TensorBoard: Embed only given layers (#6565)
* TensorBoard: Embed only given layers.

* TensorBoard: Fix pep8
2017-05-11 14:34:33 -07:00
rejunity e177397427 Small fixes for Neural_Doodle example (#6577)
* Fixed type conversion in neural_doodle example. Shape returns number of channels as int32 however further calculations require it to be float

* Updated neural doodle example to follow Keras2 API. Renamed ‘border_mode’ argument to ‘padding’.

* Fixed apostrophe for consistency.
2017-05-11 14:33:39 -07:00
meberstein 5f4f234f9b In EarlyStopping, reset stopped_epoch in on_train_begin to allow it to be re-used (#6591) 2017-05-11 14:32:49 -07:00
Daniel Høyer Iversen 24db6bfaaf Fix in ZeroPadding3D (#6574)
* Buf fix in ZeroPadding3D

* test_zero_padding_3d
2017-05-11 08:53:15 -07:00
Clara Eng 504bded884 Add callback to terminate training if NaN loss encountered. (Update to #4849) (#6456)
* Added callback TerminateOnNaN.

* Added fixes.
2017-05-10 13:44:57 -07:00
catta202000 08aa6ae555 Added batch histogram computation (#6065)
* Added batch histogram computation

* batch_size_histogram renamed to batch_size, default set to 32, added spaces around operators

* PEP8 fix

* Added batch_size in tests/keras/test_callbacks.py::test_TensorBoard_convnet

* PEP8 fix

* Batch size reduced in tests, targets and sample_weights sliced
2017-05-10 08:16:55 -07:00
popyy0101 737ae88a02 Use OrderedDict instead of normal dict to produce reliable iteration for dict.items() (#6573) 2017-05-10 08:13:53 -07:00
Fariz Rahman 6642d496e5 Recurrent : InputSpec fixes (#6568)
* Recurrent : InputSpec fixes

* Update convolutional_recurrent.py

* pep8 fix

* Update convolutional_recurrent.py
2017-05-09 23:40:57 -07:00
Fariz Rahman 2766074d19 Bug fix + test : Initializing states for ConvLSTM2D (#6564)
* Bug fix

* Update convolutional_recurrent_test.py

* Update convolutional_recurrent.py
2017-05-09 17:32:37 -07:00
Gökçen Eraslan 672028a5f2 Fix hyperlink misrendering in documentation (#6558)
Two hyperlinks (namely `[here]` and `[details]`) are misrendered in TensorBoard documentation, see https://keras.io/callbacks/#tensorboard. Fix exclude `(` in argument names, because otherwise `[link](http://` is rendered as a function/class argument.
2017-05-09 12:13:24 -07:00
Francois Chollet 1a89b13cb4 Try reverting previously merged PR. 2017-05-08 09:33:42 -07:00
Han Lin 268672df65 Don't rate limit final update (#6536) 2017-05-07 17:34:44 -07:00
iddober bfae0a6191 remove unused import in tests folder (#6534) 2017-05-07 14:46:26 -07:00
Moussa Taifi a2a0f66276 Add exception handling when attempting to write keras config file (#6453)
* add exception handling when attempting to write keras config file to disk to match tf.contrib.keras implementation

* Add reliance on exceptions rather than testing write access to the target directory.
2017-05-06 20:02:08 -07:00
Kosuke Kusano ea8e2edf17 fix tuple error message (#6530) 2017-05-06 19:18:29 -07:00
Murat Ambarkutuk d223cc0ff7 Add an option to create dot model in different directions (#5472)
* Add an option to create dot model in different directions

This commit adds an optional argument to functions plot() and model_to_dot() specifying the direction of the dot object

* Rename visualize_util.py to vis_utils.py and and model plot direction

* Format the code in the PEP8 style guide

* Add docstring for plot_model method, format code according to PEP8

pycodestyle and pydocstyle raises no info, warning, or error with this pr.

* Docstring style

* Docstring fixes.
2017-05-05 13:35:09 -07:00
Grégory Châtel 8ac1b1fdc9 Add a directory iterator option to allow to work easily with autoencoders (issue #4260) (#6510)
* identical class_mode code.

* New directory iterator testing function

* class_mode keyword changed to input + clearer doc.
2017-05-05 09:07:31 -07:00
Dr. Kashif Rasul 23833417cf fixed typo (#6523) 2017-05-05 09:05:15 -07:00
Eric Xihui Lin 61c9cdc53c Use axis instead of reduction_indices in logsumexp 2017-05-04 19:47:41 -07:00
Francois Chollet 1c7e63e42c Update docs autogen script. 2017-05-04 17:02:32 -07:00
Francois Chollet 6582043276 Update CONTRIBUTING.md 2017-05-04 17:02:17 -07:00
Parag S. Chandakkar 85221ccd13 Changed l2_normalization in theano_backend.py (#6513) 2017-05-04 15:18:26 -07:00
Gökçen Eraslan cf550db5a5 Visualize grad distributions in TensorBoard (#6313)
* Visualize weight grad distributions in TensorBoard

* TensorBoard: Add learning_phase if needed and fix fit_generator target dimensions.

* TensorBoard: Fix pep8

* TensorBoard: Add a flag to make grad visualization optional.

* TensorBoard: Test grad visualizations as well.

* TensorBoard: Documentation and further pep8 changes.

* TensorBoard: Add dropout layer to test K.learning_phase()

* Add learning_phase check in fit() to fit_generator().

* Tensorboard: Add test for comparing cbk.validation_data for fit() and fit_generator()

* Tensorboard: Fix cbk.val_data test.

* Tensorboard: Enable grad vis in tb convnet test.

* Tensorboard: No linebreak for more readability
2017-05-04 15:17:10 -07:00
SimonMarkWarren 75519651bb Fix error in test_saving_without_compilation (#6504)
* Fix error in test_saving_without_compilation

* Update test_model_saving.py
2017-05-04 13:52:15 -07:00
Stephan Heijl b93d3b23f5 Moved start/end (#6502) 2017-05-04 13:07:26 -07:00
Abhai Kollara Dilip dc3d164c6b Tokenizer docs patch (#6506)
* Tokenizer docs patch

* Minor change
2017-05-04 13:06:26 -07:00
Taehoon Lee 47dddaa7fd Fix valid condition for TF <-> TH conversion of Conv1D (#6497) 2017-05-04 11:49:37 -07:00
Gökçen Eraslan fdd822c03e Tensorboard: Check weight dimensions better in write_images (#6505)
* Tensorboard: Add a convnet test for tensorboard

* Tensorboard: Check weight dimensions better in write_images and make the code more explicit

* Tensorboard: 2 epochs is enough for tb convnet test

* Tensorboard: Fix pep8
2017-05-04 11:48:13 -07:00
Frédéric Bastien a736c2632b Add function names to help profiling/printing of function. (#6463)
* Add function names to help profiling/printing of function.

* Docstring and pass to Theano the new parameter
2017-05-02 08:43:17 -07:00
Daniel Julius Lasiman 1a707ea11e Handle properly values with str type in CSVLogger #6459 (#6460) 2017-05-01 16:56:00 -07:00
Shaofan Lai c430b6c492 Add skip_compile option to keras.models.load_model() (#6436)
* add skip_compile option to keras.models.load_model()

* update document

* change name from skip_compile to compile
2017-04-30 12:20:55 -07:00
Francois Chollet 457b0c1d3e Merge branch 'master' into tf-keras 2017-04-07 14:15:00 -07:00
Francois Chollet bf5735b577 Merge branch 'master' into tf-keras 2017-04-07 14:03:45 -07:00
Francois Chollet 1f82b19349 add changes to inception_v3 2017-04-07 13:46:10 -07:00
Francois Chollet b8b2fc4e6c merge. 2017-04-07 13:43:32 -07:00
Francois Chollet b5411f10a1 Merge branch 'master' into tf-keras 2017-04-05 11:57:42 -07:00
Francois Chollet fce18b245c merge 2017-04-05 10:46:20 -07:00
Francois Chollet e872da85e4 exception json decoding error 2017-04-04 11:46:23 -07:00
Francois Chollet a2a2e49457 merge 2017-04-03 17:18:56 -07:00
Francois Chollet 032abdb666 Merge branch 'tf-keras' of github.com:fchollet/keras into tf-keras 2017-04-03 15:29:06 -07:00
Francois Chollet 8100ac79c1 Make config file saving conditional on permissions. 2017-04-03 15:28:51 -07:00
Francois Chollet 16db6db6ae style fix 2017-04-02 13:23:13 -07:00
Francois Chollet 4026f89bd1 merge master. 2017-04-02 13:22:06 -07:00
Francois Chollet 5436b4fb00 Merge branch 'master' into tf-keras 2017-04-02 12:56:20 -07:00
Francois Chollet 6c199c41dd Style fix. 2017-04-02 12:54:50 -07:00
Francois Chollet 1a7e51cfc8 Backend fixes. 2017-04-02 12:50:18 -07:00
Francois Chollet df14349c2a Merge branch 'tf-keras' of github.com:fchollet/keras into tf-keras 2017-04-02 12:46:57 -07:00
Francois Chollet 855e8dccde backport py3 fix in backend 2017-04-02 12:46:37 -07:00
Francois Chollet 850d92516c Merge branch 'master' into tf-keras 2017-04-02 12:45:16 -07:00
Francois Chollet 96909acd1e Merge branch 'tf-keras' of github.com:fchollet/keras into tf-keras 2017-04-02 11:49:55 -07:00
Francois Chollet 9479666083 Adapt merge tests. 2017-04-02 11:49:41 -07:00
Francois Chollet c0e972f3b4 Merge branch 'master' into tf-keras 2017-04-02 11:42:28 -07:00
Francois Chollet a517bc69fb rm legacy interface tests 2017-04-02 11:39:32 -07:00
Francois Chollet 57d7fce61d Remove backend tests 2017-04-02 11:29:43 -07:00
Francois Chollet 4a5a3dd685 merge master. 2017-04-02 11:21:03 -07:00
Francois Chollet 819f3e2ba5 style fix 2017-03-15 15:55:09 -07:00
Francois Chollet 6ef5bb2ddc style fixes 2017-03-15 12:47:08 -07:00
Francois Chollet 01081d4899 Merge branch 'tf-keras' of https://github.com/fchollet/keras into tf-keras 2017-03-15 12:46:22 -07:00
Francois Chollet f37c7d4fd9 rm objectives 2017-03-15 12:46:00 -07:00
Francois Chollet 4a2ff8d019 Remove common.py 2017-03-15 12:45:23 -07:00
Francois Chollet 59b1e2a25c Merge branch 'master' into tf-keras
# Conflicts:
#	keras/backend/__init__.py
#	keras/backend/common.py
#	keras/backend/theano_backend.py
2017-03-15 12:44:24 -07:00
Francois Chollet 240eda535d Merge branch 'tf-keras' of https://github.com/fchollet/keras into tf-keras 2017-03-14 09:11:09 -07:00
Francois Chollet 9d62df3f21 Merge branch 'master' into tf-keras 2017-03-14 09:10:19 -07:00
Francois Chollet 776a15aad9 Merge branch 'tf-keras' of https://github.com/fchollet/keras into tf-keras 2017-03-13 17:44:26 -07:00
Francois Chollet 4b79df99b9 Make Keras dir creation safer in multithreaded envs. 2017-03-13 17:44:15 -07:00
Francois Chollet 3acd5b2e86 Merge branch 'tf-keras' of https://github.com/fchollet/keras into tf-keras 2017-03-13 14:16:37 -07:00
Francois Chollet 5952ea52aa Merge branch 'keras-2' into tf-keras 2017-03-13 14:16:06 -07:00
Francois Chollet 50eb3bfa1b Merge branch 'tf-keras' of https://github.com/fchollet/keras into tf-keras 2017-03-13 12:18:53 -07:00
Francois Chollet b6b5343af3 Fixes. 2017-03-13 12:18:43 -07:00
Francois Chollet ff7209cc16 Merge branch 'tf-keras' of https://github.com/fchollet/keras into tf-keras 2017-03-13 12:08:14 -07:00
Francois Chollet 4736730e22 Add docstring. 2017-03-13 12:07:52 -07:00
Francois Chollet 38cdc03cc4 Merge branch 'tf-keras' of https://github.com/fchollet/keras into tf-keras 2017-03-13 12:02:07 -07:00
Francois Chollet c00a73a65e Merge 2017-03-13 12:01:54 -07:00
Francois Chollet 6a835faf79 Merge branch 'tf-keras' of https://github.com/fchollet/keras into tf-keras 2017-03-13 11:59:16 -07:00
Francois Chollet 3f9379ec3e Add mandatory imports 2017-03-13 11:59:12 -07:00
Francois Chollet c11bbd807c merge. 2017-03-13 11:58:27 -07:00
Francois Chollet ba3ea75307 Merge branch 'tf-keras' of github.com:fchollet/keras into tf-keras 2017-03-10 20:40:27 -08:00
Francois Chollet 4b975c113c merge. 2017-03-10 20:40:14 -08:00
Francois Chollet 50ee2f9602 merge. 2017-03-10 10:22:03 -08:00
Francois Chollet 565d1d5116 Fix TF imports 2017-03-10 10:21:02 -08:00
Francois Chollet 4794363fae merge 2017-03-10 10:19:13 -08:00
Francois Chollet c2cc739938 Merge branch 'tf-keras' of https://github.com/fchollet/keras into tf-keras 2017-03-10 09:51:37 -08:00
Francois Chollet 6790c0d247 add mandatory imports 2017-03-10 09:51:30 -08:00
Francois Chollet a92026d719 Remove internal docs links from docstrings. 2017-03-10 09:47:23 -08:00
Francois Chollet d14df154e5 merge 2017-03-10 09:39:28 -08:00
Francois Chollet 1b6e14e944 Use int_shape where appropriate. 2017-03-06 19:02:10 -08:00
Francois Chollet 27329b8400 merge 2017-03-06 18:47:56 -08:00
Francois Chollet 28f3eaedd1 Merge. 2017-03-05 17:44:00 -08:00
Francois Chollet 2abdcdfb8e Update. 2017-03-05 17:42:59 -08:00
Francois Chollet 4b7122ef9c Add module level imports 2017-03-05 16:11:10 -08:00
Francois Chollet 9840b5ad24 fix backend imports. 2017-03-05 14:02:11 -08:00
Francois Chollet 4adb619518 merge 2017-03-05 13:57:49 -08:00
Francois Chollet cff822c9df Merge branch 'keras-2' into tf-keras 2017-03-04 17:59:19 -08:00
Francois Chollet f9ede2ba1b Merge branch 'keras-2' into tf-keras 2017-03-03 11:52:09 -08:00
Francois Chollet 71b5c2d05b Add comment. 2017-03-03 11:51:11 -08:00
Francois Chollet d69432cd0a Add short aliases for global pooling layers. 2017-03-03 10:44:15 -08:00
Francois Chollet 8a99aaf604 Merge. 2017-03-01 18:23:31 -08:00
Francois Chollet aabe81e82b Merge. 2017-03-01 18:22:44 -08:00
Francois Chollet 94545cea9b Linter fixes. 2017-03-01 18:21:28 -08:00
Francois Chollet c25a319463 Fix circular imports issue. 2017-02-28 15:27:26 -08:00
Francois Chollet 1847036cfd Reallow causal padding. 2017-02-28 15:27:17 -08:00
Francois Chollet 3865b589e1 merge. 2017-02-28 14:46:38 -08:00
Francois Chollet 2832c740aa Reallow causal padding. 2017-02-26 16:45:27 -08:00
Francois Chollet 9ee8425072 Linter fixes. 2017-02-26 16:32:01 -08:00
Francois Chollet 1db4438ac9 merge. 2017-02-26 15:21:58 -08:00
Francois Chollet 1bd4fac1a7 merge 2017-02-26 15:02:04 -08:00
Francois Chollet a58fb1d917 merge. 2017-02-26 14:34:43 -08:00
Francois Chollet 5ae17cd983 Linter fixes. 2017-02-26 14:31:41 -08:00
Francois Chollet 9b0ff98ead merge. 2017-02-26 13:53:12 -08:00
Francois Chollet 27e943eda2 Linter fixes. 2017-02-26 13:51:27 -08:00
Francois Chollet 71b74d6b89 Merge branch 'tf-keras' of https://github.com/fchollet/keras into tf-keras 2017-02-26 13:22:38 -08:00
Francois Chollet afd9d8087d Linter fixes. 2017-02-26 13:22:30 -08:00
Francois Chollet dc66ca402a Merge branch 'keras-2' into tf-keras 2017-02-26 13:20:52 -08:00
Francois Chollet 7b231e2819 Merge branch 'tf-keras' of https://github.com/fchollet/keras into tf-keras 2017-02-26 12:47:57 -08:00
Francois Chollet 369bfcb1bf lint fixes 2017-02-26 12:47:53 -08:00
Francois Chollet 2ca7908f59 merge 2017-02-26 12:46:35 -08:00
Francois Chollet d684124d89 Fixes. 2017-02-26 12:44:02 -08:00
Francois Chollet d2a609e459 Add names in optimizer variables. 2017-02-26 11:17:57 -08:00
Francois Chollet bd4d40e514 Fix typo. 2017-02-25 15:13:53 -08:00
Francois Chollet 5abbd05245 Docstring fixes. 2017-02-25 14:24:15 -08:00
Francois Chollet 265464141e Style fixes. 2017-02-25 14:21:07 -08:00
Francois Chollet 6feb1d9e27 Update setup.py. 2017-02-25 13:55:49 -08:00
Francois Chollet 7936401a87 Remove backend tests. 2017-02-25 13:54:18 -08:00
Francois Chollet 672fe90dd9 Atomize TF imports in backend. 2017-02-25 13:50:38 -08:00
Francois Chollet d5a384ed61 Atomize TF imports (except for backend). 2017-02-25 13:50:28 -08:00
Francois Chollet 22b943e935 Merge branch 'keras-2' into tf-keras 2017-02-25 11:29:28 -08:00
Francois Chollet 94268267c4 Make compute_output_shape private. 2017-02-25 11:06:08 -08:00
Francois Chollet 350da1a3c3 Merge keras-2. 2017-02-25 10:54:48 -08:00
Francois Chollet 3fc74cfc0b Second pass over TF conversion (nearly done). 2017-02-24 16:45:35 -08:00
Francois Chollet c6e6acdebf First pass over TF conversion. 2017-02-24 13:35:00 -08:00
92 arquivos alterados com 2603 adições e 6069 exclusões
+19
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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)
+3 -3
Ver Arquivo
@@ -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.
+4 -6
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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__:
+3 -2
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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'
+6 -1
Ver Arquivo
@@ -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
+8 -2
Ver Arquivo
@@ -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
+7 -1
Ver Arquivo
@@ -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'
+13 -17
Ver Arquivo
@@ -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
+27 -29
Ver Arquivo
@@ -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
+15 -16
Ver Arquivo
@@ -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)
+15 -16
Ver Arquivo
@@ -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)
+13 -15
Ver Arquivo
@@ -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
-91
Ver Arquivo
@@ -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
-217
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
+9 -8
Ver Arquivo
@@ -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):
+9 -4
Ver Arquivo
@@ -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
+7 -1
Ver Arquivo
@@ -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):
+5
Ver Arquivo
@@ -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
+10 -4
Ver Arquivo
@@ -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.
+10 -4
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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)
+7 -1
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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']
+9 -3
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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')
+10 -14
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
+60 -45
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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 = {
+17 -13
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
+5 -4
Ver Arquivo
@@ -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
+11 -6
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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,
+49
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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 = {}
Ver Arquivo
-27
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
-6
Ver Arquivo
@@ -1,6 +0,0 @@
"""Legacy objectives module.
Only kept for backwards API compatibility.
"""
from __future__ import absolute_import
from .losses import *
+33 -18
Ver Arquivo
@@ -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):
+9
Ver Arquivo
@@ -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
+42 -15
Ver Arquivo
@@ -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())
+9 -4
Ver Arquivo
@@ -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:
+6 -4
Ver Arquivo
@@ -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
+9 -4
Ver Arquivo
@@ -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)
+6 -1
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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):
+35 -27
Ver Arquivo
@@ -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)
+6 -4
Ver Arquivo
@@ -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:
+6 -2
Ver Arquivo
@@ -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'}
+2
Ver Arquivo
@@ -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
+7 -5
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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'
+7
Ver Arquivo
@@ -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
+7 -4
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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',
+2 -1
Ver Arquivo
@@ -103,4 +103,5 @@ def test_inceptionv3_pooling():
if __name__ == '__main__':
pytest.main([__file__])
# pytest.main([__file__])
test_vgg16()
+15
Ver Arquivo
@@ -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))
+59 -36
Ver Arquivo
@@ -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__])
+47 -13
Ver Arquivo
@@ -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
+1 -14
Ver Arquivo
@@ -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():
+10 -12
Ver Arquivo
@@ -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))
+1 -1
Ver Arquivo
@@ -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
-849
Ver Arquivo
@@ -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__])
-317
Ver Arquivo
@@ -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__])
-279
Ver Arquivo
@@ -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 -1
Ver Arquivo
@@ -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__])
+26
Ver Arquivo
@@ -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
+128 -2
Ver Arquivo
@@ -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)
-2
Ver Arquivo
@@ -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():
+65
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
+28 -3
Ver Arquivo
@@ -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__])