Comparar commits

..

960 Commits

Autor SHA1 Mensagem Data
Francois Chollet df860fdb94 Update IRNN example 2015-11-29 13:08:45 -08:00
Francois Chollet 361a7cfe41 Update addition example 2015-11-29 12:54:45 -08:00
Francois Chollet 8f2d6d2714 Add support for time-distributed softmax. 2015-11-29 12:54:26 -08:00
Francois Chollet cbee000b66 Fix TF RNN issues 2015-11-29 12:22:41 -08:00
Francois Chollet 7ecd6c3c5f Fix backend tests 2015-11-29 10:38:48 -08:00
Francois Chollet 060ef32ce0 Merge branch 'backend' of https://github.com/fchollet/keras into backend 2015-11-29 10:15:45 -08:00
Francois Chollet 36392c75d7 Fix backend tests 2015-11-29 10:15:37 -08:00
François Chollet 2f01f29995 Merge pull request #1105 from transcranial/backend
fix tensorflow travis config
2015-11-28 21:13:41 -08:00
Leon Chen 0ab3a6c00c use ubuntu 14.04 on travis 2015-11-28 23:42:54 -05:00
Leon Chen 475fa79ec4 fix tensorflow travis config 2015-11-28 23:18:07 -05:00
Francois Chollet e600b0d947 Attempt to fix Travis config 2015-11-28 17:51:35 -08:00
Francois Chollet 677e15cd02 Attempt to fix Travis config 2015-11-28 17:50:23 -08:00
Francois Chollet ea2fd6526b Attempt to fix TF on Travis 2015-11-28 17:43:48 -08:00
Francois Chollet 26b040effe Attempt to fix TF in Travis config 2015-11-28 17:36:52 -08:00
Francois Chollet ef3ef71ee6 Add exception for TF + NTM 2015-11-28 17:19:13 -08:00
Francois Chollet 5c3aea2202 Fix backend init 2015-11-28 17:05:49 -08:00
Francois Chollet b6ea543a46 Fix Travis config. 2015-11-28 16:59:48 -08:00
Francois Chollet e32436144b Add tests 2015-11-28 16:39:42 -08:00
Francois Chollet 2bc900c3d2 Upate Travis config. 2015-11-28 16:36:09 -08:00
Francois Chollet 6c458ff281 Update layers. 2015-11-28 16:35:55 -08:00
Francois Chollet 69a8acc05a Update backend functionality. 2015-11-28 16:35:20 -08:00
Francois Chollet 71c6c83e30 Update examples. 2015-11-28 16:34:52 -08:00
Francois Chollet 634aedca1a Update documentation. 2015-11-28 16:34:35 -08:00
Francois Chollet 4b39b5f36b Remove deprecated code. 2015-11-28 16:34:06 -08:00
Francois Chollet 25e85b616f Merge master 2015-11-26 12:28:38 -08:00
Francois Chollet 47ed18a3af Update backends with rnn support 2015-11-26 10:42:52 -08:00
François Chollet febc604fc4 Merge pull request #1081 from farizrahman4u/patch-17
Bug fix - Siamese layer
2015-11-25 13:28:59 -08:00
François Chollet 8612da30a9 Merge pull request #1082 from PFischbeck/patch-1
Fix typo in index.md
2015-11-25 13:27:04 -08:00
Fariz Rahman 9c1afbb667 Update containers.py 2015-11-26 02:38:25 +05:30
Philipp Fischbeck 8c9c8ae5ad Fix typo in index.md 2015-11-25 22:06:56 +01:00
Fariz Rahman b92cec3d48 Fix for nested models 2015-11-26 02:21:42 +05:30
Fariz Rahman cbb9d00106 Update core.py 2015-11-26 02:09:43 +05:30
Fariz Rahman aca4a7735e Bug fix 2015-11-26 02:07:51 +05:30
Francois Chollet 6afce5862a Merge branch 'farizrahman4u-patch-16' 2015-11-25 11:53:57 -08:00
Francois Chollet f2a14a9b57 Update doc for add_shared_node in Graph model. 2015-11-25 11:53:28 -08:00
Francois Chollet 4429547354 Merge branch 'patch-16' of https://github.com/farizrahman4u/keras into farizrahman4u-patch-16 2015-11-25 11:45:06 -08:00
François Chollet b733951a19 Merge pull request #1079 from transcranial/elu
add exponential linear units activation layer
2015-11-25 10:30:12 -08:00
Fariz Rahman 78c61c65c2 Update containers.py 2015-11-25 23:38:18 +05:30
Fariz Rahman 242793a223 Update Graph doc 2015-11-25 23:36:16 +05:30
Fariz Rahman 5c1e5d5e40 Update core.py 2015-11-25 23:25:16 +05:30
Fariz Rahman e34022bf12 Docstrings 2015-11-25 23:13:49 +05:30
Fariz Rahman dac1e8ec65 Add add_shared_node() 2015-11-25 23:12:52 +05:30
Fariz Rahman 7867abdd69 Docstrings 2015-11-25 22:53:03 +05:30
Fariz Rahman 2685134832 Add add_shared_layer() 2015-11-25 22:52:29 +05:30
Fariz Rahman 138e77d0d6 Add Siamese layer 2015-11-25 22:50:53 +05:30
François Chollet 59a30e99a3 Merge pull request #1073 from pse1202/master
Typo fix
2015-11-25 09:03:38 -08:00
Leon Chen 71ee360c20 add exponential linear units activation layer 2015-11-25 11:20:49 -05:00
Sangeon Park 88cc300103 Typo fix
tran and test sets -> train and test sets
2015-11-25 07:42:15 +09:00
François Chollet b059945195 Merge pull request #1059 from farizrahman4u/patch-15
Fix misleading comment in babi_memnn.py
2015-11-22 14:57:29 -08:00
Fariz Rahman 819f569ca8 Update babi_memnn.py 2015-11-23 04:16:32 +05:30
Fariz Rahman d322785543 Fix misleading comment in babi_memnn.py
Output of question_encoder is 3D : sequence of vectors, not single vector.
2015-11-23 03:54:32 +05:30
Francois Chollet 05aecbc0bc Fix README, docs captioning example 2015-11-22 12:05:26 -08:00
Francois Chollet 37ebbc3a1c Remove outdated comment 2015-11-22 12:03:53 -08:00
François Chollet 252db48746 Merge pull request #1052 from EderSantana/patch-4
Fix typos and even more informative docs.
2015-11-21 14:39:15 -08:00
Eder Santana 2d3880dc35 Fix typos and even more informative docs.
Even more informative docs. Sorry for not doing all the work at once.
2015-11-20 21:25:24 -05:00
François Chollet 50467e32a2 Merge pull request #990 from EderSantana/ntm
Neural Turing Machines
2015-11-20 17:56:38 -08:00
François Chollet e1cc291a25 Merge pull request #1046 from julienr/visutil_to_graph
Add visualize_util.to_graph and docs
2015-11-20 08:55:34 -08:00
Julien Rebetez 71b258d21e Add visualization section to docs 2015-11-20 11:03:31 +01:00
Julien Rebetez c1b54159b8 Add a new to_graph function in visualize_util that allow one to get the pydot.Graph object directly. This can be used to display the graph inline in a notebook. 2015-11-20 11:03:04 +01:00
François Chollet 6a231f1a24 Merge pull request #1041 from neggert/lambda_enhancements
Lambda layer enhancements
2015-11-19 22:39:28 -08:00
François Chollet b82223b2f2 Merge pull request #1037 from farizrahman4u/patch-9
Fix load_from_json for models with Lambda layer
2015-11-19 22:38:47 -08:00
François Chollet 0e69226546 Merge pull request #1039 from phreeza/patch-3
Update visualize_util.py to fix #1036
2015-11-19 22:38:33 -08:00
EderSantana 89132a6986 Fix typos and update docs 2015-11-19 23:46:55 -05:00
Francois Chollet 8b75182a17 Update backend 2015-11-19 20:14:48 -08:00
Francois Chollet bc5e993ae3 Update tests 2015-11-19 20:14:38 -08:00
Francois Chollet 8f2b5f0458 Continue Keras conversion to dual-backend version 2015-11-19 20:14:29 -08:00
Francois Chollet 34838cd369 Update examples 2015-11-19 20:13:49 -08:00
z001qdp 71b00324d8 Allow Lambda layer to pass arguments to Layer constructor.
Most importantly, the `input_shape` argument. This allows a Lambda
layer to be the first layer in a net, which was previously
impossible.
2015-11-19 16:35:26 -06:00
Nic Eggert 16590ccce5 Fix typo in Lambda layer 2015-11-19 16:17:48 -06:00
Thomas McColgan 2431764fed Update visualize_util.py to fix #1036 2015-11-19 14:53:51 +01:00
Fariz Rahman d444b9190f Update layer_utils.py 2015-11-19 16:15:26 +05:30
Francois Chollet 8ad18ce8f5 Update a number of tests. 2015-11-18 17:46:37 -08:00
Francois Chollet a744b600e9 Convert a number of layers. 2015-11-18 17:46:25 -08:00
Francois Chollet 52dac5e4b3 Update backends. 2015-11-18 17:45:29 -08:00
Francois Chollet e94f29cac4 Fix bug with validation data in Graph model 2015-11-18 13:32:06 -08:00
Francois Chollet 4e519f7aa7 Convert activations, constraints, noise, embedding 2015-11-17 21:39:15 -08:00
Francois Chollet fd05964135 Update TH / TF backends 2015-11-17 21:38:39 -08:00
Eder Santana 747d4a30b1 Update ntm.py
remove commented code
2015-11-17 21:03:06 -05:00
Eder Santana ab19cf7b07 Update ntm.py
clean up documentation
2015-11-17 21:00:51 -05:00
Eder Santana 6b8970abd3 Update neural_turing_machine_copy.py
Fix wrong import and train both models
2015-11-17 20:53:11 -05:00
Francois Chollet 5ed913da11 Convert constraints, initialization, activations 2015-11-15 15:01:58 -08:00
Francois Chollet 6ffa18e390 Convert objectives to Keras backend. 2015-11-15 14:33:20 -08:00
Francois Chollet 33ed943ad5 Convert optimizers to Keras backend. 2015-11-15 14:33:08 -08:00
Francois Chollet 368df8ef04 Convert regularizers to Keras backend. 2015-11-15 14:32:58 -08:00
Francois Chollet 24b5e80667 Fix axis specification in TF. 2015-11-15 11:30:07 -08:00
Francois Chollet 15fea0488a Style fixes 2015-11-14 22:17:13 -08:00
Francois Chollet cda6a998ef Add initial version of Theano/TensorFlow backends 2015-11-14 22:08:21 -08:00
François Chollet 653ee91d35 Merge pull request #999 from dbonadiman/patch-4
Update docs with go_backwards option
2015-11-14 11:04:50 -08:00
François Chollet eb8b37604c Merge pull request #1001 from dbonadiman/patch-5
Fixed error go_backward and return sequences.
2015-11-12 20:44:31 -08:00
Daniele Bonadiman e1bd779463 fixed an error in backward computation of recurrent layers on return sequences. 2015-11-12 13:25:47 +01:00
Daniele Bonadiman 62154fd6c6 Merge pull request #2 from fchollet/master
Up do date 2
2015-11-12 12:17:57 +01:00
Daniele Bonadiman f8b0c7e2e3 Update doc with go_backwards option 2015-11-12 11:48:32 +01:00
François Chollet 7df515b607 Merge pull request #995 from farizrahman4u/patch-9
Include samples dim in output_shape's argument
2015-11-11 10:33:24 -08:00
Fariz Rahman b65c665d2a Include samples dim in output_shape's argument 2015-11-11 23:58:12 +05:30
Francois Chollet dfa6b3a4c3 Merge branch 'farizrahman4u-patch-9' 2015-11-11 08:58:16 -08:00
Francois Chollet 2e6025d7cc Fix coding style in documentation for Lambda 2015-11-11 08:58:04 -08:00
Francois Chollet 1a721b42c7 Merge branch 'patch-9' of https://github.com/farizrahman4u/keras into farizrahman4u-patch-9 2015-11-11 08:47:08 -08:00
François Chollet d0677a1e1f Merge pull request #992 from tzachar/patch.02
Fix containers.graph sav/get_weights
2015-11-11 08:44:13 -08:00
Fariz Rahman f6f8bf643e Update core.md 2015-11-11 21:08:30 +05:30
Fariz Rahman d6aebff5b2 Added documentation for LambdaMerge layer 2015-11-11 21:07:36 +05:30
Fariz Rahman e60b7de064 Update core.md 2015-11-11 20:44:34 +05:30
Fariz Rahman cbd8eb7a55 Added documentation for Lambda layer with example 2015-11-11 20:39:53 +05:30
nir tzachar 20dc637cd6 Fix containers.graph sav/get_weights
As the graph container was not using each individual layer's get/set
weights, but rather the super class layer.get_weights, which works on
self.params(), it was missing some weights in the process, i.e., the
BatchNormalizationLayer has custom get_weights which allows to save the
running mean/std. However, these running computations are not added to
BatchNormalizationLayer.params(), resulting in losing these weights
after serializing a graph model utilizing a BatchNormalizationLayer.

Fixed to use each node's get/set weights.
2015-11-11 11:40:43 +02:00
François Chollet e037e17557 Merge pull request #950 from rushter/autoencoder-fix
Fix AutoEncoder's input_shape
2015-11-10 18:08:38 -08:00
François Chollet 9ad5bf3a7b Merge pull request #986 from tzachar/patch
Fix TimeDistributedMerge
2015-11-10 18:07:54 -08:00
EderSantana 9e4e317bcb Neural Turing Machines 2015-11-10 19:16:26 -05:00
nir tzachar db60707cb8 Fix TimeDistributedMerge
When mode='ave', and the dtype of the input is float32, dividing the sum
by shape[1], which is of dtype int64, results in an output of dtype
float64, which is wrong.

fixed to use theano.tensor.mean instead.
2015-11-10 09:40:37 +02:00
Francois Chollet 91ea495b56 MemNN Python3 compatibility 2015-11-09 18:47:29 -08:00
Francois Chollet d9596ae68d Add memory network example. 2015-11-09 18:47:29 -08:00
Francois Chollet 1dc1d25a58 Add memory network example. 2015-11-09 16:37:44 -08:00
François Chollet 527b1ed0dc Merge pull request #978 from dbonadiman/patch-3
Fix imdb bidirectional
2015-11-09 08:03:07 -08:00
Fariz Rahman 17d2f5f960 del instead of setting to None 2015-11-09 18:54:54 +05:30
Fariz Rahman 2ef4d698ef Whitespace fix 2015-11-09 18:50:52 +05:30
Fariz Rahman bde97055c0 Update core.py 2015-11-09 18:40:01 +05:30
Fariz Rahman 3b0e2b0c79 Del ndim arg,exclude samples dim from output shape 2015-11-09 18:37:32 +05:30
Daniele Bonadiman 3e3c43d3ee fix TypeError: fit() got an unexpected keyword argument 'show_accuracy' 2015-11-09 12:06:18 +01:00
Daniele Bonadiman cb60477548 Merge pull request #1 from fchollet/master
Up to date
2015-11-09 09:25:42 +00:00
Francois Chollet 3d25fae014 Merge branch 'dbonadiman-add-1' 2015-11-08 18:16:33 -08:00
Francois Chollet 4884595e4d Style fixes in bidirectional LSTM example. 2015-11-08 18:16:10 -08:00
Francois Chollet 1760ed6cd7 Merge branch 'add-1' of https://github.com/dbonadiman/keras into dbonadiman-add-1 2015-11-08 18:07:20 -08:00
François Chollet b1bbedfb46 Merge pull request #972 from dbonadiman/patch-1
[Patch] Fixing issue with dot output shape
2015-11-08 18:05:35 -08:00
Francois Chollet 227c300a0a Remove sudo from Travis CI config 2015-11-08 17:04:14 -08:00
Francois Chollet f5819a0d4e Update Travis CI config 2015-11-08 16:59:14 -08:00
Daniele Bonadiman 28882a868d fix https://github.com/fchollet/keras/pull/970#issuecomment-154886091 2015-11-09 00:29:14 +01:00
Daniele Bonadiman b32e60cfa0 fixing issues with dot output shape 2015-11-08 23:26:33 +01:00
Daniele Bonadiman ca360b0d15 bidirectional lstm example added. 2015-11-08 23:19:14 +01:00
Daniele Bonadiman 10852b2529 go_backwards added to recurrent layers. 2015-11-08 22:56:42 +01:00
rushter cc0108097c Fix AutoEncoder's input_shape 2015-11-04 10:12:39 +03:00
François Chollet fe14a845ab Merge pull request #942 from matsuyamax/master
Fixes and input checks for dot mode in merge.
2015-11-02 20:45:51 -08:00
Makoto Matsuyama 5964848bdf Fix Python3 compatibility 2015-11-02 20:14:33 -08:00
Makoto Matsuyama 002a9d5d2b Fixes and input checks for dot mode in merge. 2015-11-02 19:37:00 -08:00
François Chollet eba8530e7b Merge pull request #941 from stephenroller/master
imported TimeDistributedMerge
2015-11-02 14:47:42 -08:00
Stephen Roller 7432034ada TimeDistributedMerge needed to be imported into layer_utils, so it could be serialized to to_json 2015-11-02 16:36:05 -06:00
François Chollet 99331b83f9 Merge pull request #938 from farizrahman4u/patch-12
Avoid recalculation of output in join merge.
2015-11-02 12:37:31 -08:00
François Chollet 0b326d9688 Merge pull request #939 from stephenroller/master
Fix merge concat mode
2015-11-02 11:58:22 -08:00
Stephen Roller 57612707c1 Fix merge concat mode; the assertion checked the opposite of what was desired. 2015-11-02 13:51:10 -06:00
Fariz Rahman 5352e46e09 Avoid recalculation of output in join merge. 2015-11-03 00:10:43 +05:30
François Chollet a5d93bfdc1 Merge pull request #935 from liormagen/patch-1
Handle an empty document
2015-11-02 08:18:05 -08:00
Lior Magen 742ccaa2cf Handle an empty document
In case of an empty sequence (as a result of clearing stop words for example), don't raise an error but continue to the next sequence.
2015-11-02 16:39:18 +02:00
François Chollet 284ef7b495 Merge pull request #927 from LeavesBreathe/patch-2
Update Docs for RMSE in objectives
2015-11-01 10:59:42 -08:00
LeavesBreathe 02180e881d Update Docs for RMSE in objectives 2015-10-31 13:13:21 -04:00
Francois Chollet 4a6b03403b Fix ParametricSoftplus 2015-10-31 10:12:27 -07:00
François Chollet ccdd5d147d Merge pull request #926 from rushter/small-fixes
Small fixes
2015-10-31 10:11:16 -07:00
François Chollet 3c95896415 Merge pull request #922 from LeavesBreathe/patch-2
Added Root Mean Square Error
2015-10-31 09:57:05 -07:00
rushter 66edb6aea0 Fix python 3 compatibility 2015-10-31 18:16:48 +03:00
rushter 5590dc7b0d FIx read-only property can't be changed 2015-10-31 18:11:51 +03:00
rushter 8f2810bfee Remove useless declaration 2015-10-31 17:32:01 +03:00
rushter 42e582b1ba FIx typos 2015-10-31 17:30:00 +03:00
LeavesBreathe 43bf884b5f Added Root Mean Square Error 2015-10-31 08:59:04 -04:00
François Chollet 234408e82e Merge pull request #920 from farizrahman4u/patch-2
Fix dot_axis API
2015-10-30 13:47:51 -07:00
François Chollet 41db741881 Merge pull request #917 from contextvision/dropout
Dropout: rescale data at training time (breaks bw compat.)
2015-10-30 13:47:21 -07:00
François Chollet 46bfa18a57 Merge pull request #911 from jpeg729/custom_objects
Change the custom_layer api to support custom_objects
2015-10-30 13:41:54 -07:00
Francois Chollet 7e85390d8e Merge branch 'master' of https://github.com/fchollet/keras 2015-10-30 13:14:03 -07:00
Francois Chollet a2d01238af Fix flaky Travis test 2015-10-30 13:13:50 -07:00
Fariz Rahman ba982e7ee0 Whitespace fix 2015-10-30 23:28:15 +05:30
Fariz Rahman 18f122e1d9 Fix dot_axis API
Make the default value of dot_axes more useful.
2015-10-30 23:26:52 +05:30
Mikael Rousson bae645b65e rescale data at training time (breaks bw compat.) 2015-10-30 09:38:10 +01:00
jpeg729 66ad0bf736 Change the custom_layer api to support custom_objects
A small change permitting the use of custom loss functions, custom
optimizers, custom activation functions, and so on.
2015-10-29 16:31:17 +01:00
Fariz Rahman 469640bd45 Fix serialization recursion problem 2015-10-29 08:57:05 +05:30
Fariz Rahman 2f8b351c95 Update core.py 2015-10-29 08:23:18 +05:30
Fariz Rahman 8ee2ffd7e1 Update core.py 2015-10-29 08:22:09 +05:30
Fariz Rahman fb24dc1904 Update core.py 2015-10-29 00:02:00 +05:30
Fariz Rahman 79e702ec53 Added test for Lambda layer 2015-10-28 23:42:43 +05:30
François Chollet bd005d66af Merge pull request #906 from farizrahman4u/patch-2
Add dot_axes argument to Graph
2015-10-28 10:57:26 -07:00
Fariz Rahman 0354e64521 Update test_sequential_model.py 2015-10-28 12:39:02 +05:30
Fariz Rahman a4552fb004 Use input shape instead of input layer 2015-10-28 12:38:09 +05:30
Fariz Rahman 455d7d10db Add dot_axes argument to Graph
Add dot_axes argument, used by the recently added dot merge mode.
2015-10-28 12:07:53 +05:30
Francois Chollet 1c7585a563 Fix failing test 2015-10-27 22:08:41 -07:00
Francois Chollet 22566c37ce Fix dot_axes API in Merge 2015-10-27 22:08:25 -07:00
Fariz Rahman 1f0178e793 Whitespace fix 2015-10-28 10:32:51 +05:30
Fariz Rahman fbe2ea6537 Update core.py 2015-10-28 10:31:16 +05:30
Fariz Rahman 7b0be64757 White space/style/comment fix 2015-10-28 10:28:54 +05:30
François Chollet 0edbdcc998 Merge pull request #905 from farizrahman4u/patch-10
Dot and cos merge modes
2015-10-27 21:50:11 -07:00
Fariz Rahman 21dcabb6e8 Update test_sequential_model.py 2015-10-28 09:55:34 +05:30
Fariz Rahman c34578aece Added test for dot merge with tuple and int axes 2015-10-28 09:48:42 +05:30
Fariz Rahman 01a3e298fb Dot and cos merge modes
Cleaner version of #891
2015-10-28 09:44:18 +05:30
Fariz Rahman 42a65d4b83 Update core.py 2015-10-28 08:43:48 +05:30
Fariz Rahman cb836091ec Update core.py 2015-10-28 08:28:16 +05:30
Fariz Rahman 6a05247711 Update core.py 2015-10-28 04:10:43 +05:30
Fariz Rahman c015acb413 Update core.py 2015-10-28 03:43:48 +05:30
Fariz Rahman feac8dba01 Update test_sequential_model.py 2015-10-28 03:38:01 +05:30
Fariz Rahman ba389ffb11 Added LambdaMerge 2015-10-28 03:30:32 +05:30
Fariz Rahman c6c3a0247c Add auto_name to config 2015-10-28 02:48:43 +05:30
Fariz Rahman c140939c5a Update core.py 2015-10-28 02:39:18 +05:30
François Chollet a9cecbbe43 Merge pull request #897 from amitbeka/load-name-consume
utils.layer_utils: don't consume 'name' when loading
2015-10-27 13:48:10 -07:00
François Chollet 0f0d264e55 Merge pull request #903 from EderSantana/patch-2
property input_shape for Sequential
2015-10-27 13:35:36 -07:00
Eder Santana a9d0905897 property input_shape for Sequential
Fix #902
2015-10-27 16:23:59 -04:00
Fariz Rahman c90d2dfc0c Update core.py 2015-10-28 01:36:47 +05:30
Fariz Rahman 315a12ac58 Pass value for auto_name argument 2015-10-28 01:19:11 +05:30
Fariz Rahman f5896236fa Added auto_name argument for merge layer 2015-10-28 01:16:36 +05:30
Fariz Rahman 29e788dc2e Update test_sequential_model.py 2015-10-27 21:49:58 +05:30
Fariz Rahman 07f8cef29c Update core.py 2015-10-27 19:59:35 +05:30
Fariz Rahman a069161d0f Update test_sequential_model.py 2015-10-27 19:58:16 +05:30
François Chollet 26b57a6cdd Merge pull request #860 from jeanpijon/monitor_directions
Monitor directions #2
2015-10-26 10:12:53 -07:00
Fariz Rahman 45577f7959 Added type checking for output_shape return value 2015-10-26 21:54:07 +05:30
Fariz Rahman 25aab5d405 Indentation fix 2015-10-26 21:16:48 +05:30
Fariz Rahman a58e037715 Added doc string 2015-10-26 21:02:34 +05:30
Fariz Rahman eb62075078 Roll back 2015-10-26 20:43:17 +05:30
Pesan Jan 3663f64bb4 Modification of ModelCheckpoint to allow monitoring of increasing
metrics
2015-10-26 11:58:08 +01:00
Amit Beka fcd54ac85b utils.layer_utils: don't consume 'name' when loading
When loading regularizers/constraints from config, and the object isn't
found, don't consume the 'name' key.

This enables expansions to keras to be saved/loaded with dictionaries as
some of their parameters.

Signed-off-by: Amit Beka <amit.beka@gmail.com>
2015-10-26 12:11:07 +02:00
Fariz Rahman fb8e80daf4 Consider the case where Lambda is input layer 2015-10-26 14:52:54 +05:30
Fariz Rahman ac3d135b84 Only allow named inputs to be merged by join mode 2015-10-26 14:46:51 +05:30
Fariz Rahman d876dae965 Named layers before join merging 2015-10-26 14:45:06 +05:30
Fariz Rahman 345d78e27d Added default value for output shape 2015-10-26 08:41:34 +05:30
Fariz Rahman d5827c8917 Whitespace fix 2015-10-26 07:51:27 +05:30
Fariz Rahman 779bf2a8d2 Made compatible with Python 3 2015-10-26 07:50:55 +05:30
Fariz Rahman 0fab8ac373 Update test_sequential_model.py 2015-10-26 07:26:47 +05:30
Fariz Rahman b3594ccd5e Added test for serializing model with Lambda layer 2015-10-26 07:18:20 +05:30
Fariz Rahman 15b84d375f Update core.py 2015-10-26 07:00:02 +05:30
Fariz Rahman 312120272f Add Python3 support 2015-10-26 06:54:46 +05:30
Fariz Rahman 97b27bfd1e Update test_sequential_model.py 2015-10-26 06:24:59 +05:30
Fariz Rahman a0c5f5743c Update core.py 2015-10-26 06:19:18 +05:30
Fariz Rahman 688b898dc8 Update test_sequential_model.py 2015-10-26 05:50:19 +05:30
Fariz Rahman 7def993fe2 Update test_sequential_model.py 2015-10-26 05:40:56 +05:30
Fariz Rahman c33a551f97 Update test_sequential_model.py 2015-10-26 05:20:23 +05:30
Fariz Rahman 3f8bfd2b1c Added test for Lambda layer 2015-10-26 05:04:34 +05:30
Fariz Rahman c6cf4425d3 Update core.py 2015-10-26 04:21:56 +05:30
Fariz Rahman aa6cf91a18 White space/ style fix 2015-10-26 04:00:44 +05:30
Fariz Rahman 5faef2fc56 Changed order of inheritance 2015-10-26 03:58:41 +05:30
Fariz Rahman ad254f99eb Bug fix 2015-10-26 03:47:56 +05:30
Fariz Rahman e6cecb5d12 Separate Lambda and MaskedLambda layers 2015-10-26 03:29:57 +05:30
Fariz Rahman 6106d1fa30 Indentation fix 2015-10-26 02:30:00 +05:30
Fariz Rahman ab6b11d86e Lambda Layer
Lambda layer can be used to implement any arbitrary function when stacked on top of a join merge layer.
2015-10-26 02:20:24 +05:30
François Chollet 6e2e6eff89 Merge pull request #892 from amitbeka/fix-requirements
fix setup.py: add six as a requirement
2015-10-25 10:25:46 -07:00
Amit Beka e60680b12c fix setup.py: add six as a requirement
Signed-off-by: Amit Beka <amit.beka@gmail.com>
2015-10-25 18:06:41 +02:00
Francois Chollet 47071f9303 Merge branch 'farizrahman4u-patch-8' 2015-10-24 21:08:12 -07:00
Francois Chollet 14486397c5 Whitespace / style fixes 2015-10-24 21:07:47 -07:00
Francois Chollet 0cd30480fb Merge branch 'patch-8' of https://github.com/farizrahman4u/keras into farizrahman4u-patch-8 2015-10-24 20:46:10 -07:00
Francois Chollet 74b590eff8 Whitespace / style fixes only 2015-10-24 20:39:06 -07:00
Francois Chollet 25a2a972b1 Merge branch 'patch-1' of https://github.com/farizrahman4u/keras into farizrahman4u-patch-1 2015-10-24 20:28:51 -07:00
François Chollet 01bb88513d Merge pull request #889 from trungnt13/master
fixed error in reading hdf5 dataset
2015-10-24 14:22:30 -07:00
farizrahman4u 0d233b2512 Update imdb_cnn_lstm.py 2015-10-25 02:43:02 +05:30
farizrahman4u e704e1578e Update imdb_cnn_lstm.py
Style fix
2015-10-25 02:37:47 +05:30
nick_artin 0c0d91df2e Fixed error in reading hdf5 dataset 2015-10-24 23:00:17 +02:00
François Chollet 52fd68f4c5 Merge pull request #886 from alvations/master
Added version information and docstring to __init__
2015-10-24 13:05:34 -07:00
alvations 7b0b324041 Merge pull request #2 from alvations/alvations-patch-1
Removed the unused import
2015-10-24 20:23:11 +02:00
alvations 8b24b3343f Removed the unused import 2015-10-24 20:20:32 +02:00
alvations 084b235c62 Merge pull request #1 from alvations/alvations-patch-1
Added version information and docstring to __init__
2015-10-24 15:29:40 +02:00
alvations 9a384888d7 Added version information and docstring to __init__ 2015-10-24 15:21:34 +02:00
farizrahman4u 6cc827ca55 Bug fix 2015-10-24 15:11:20 +05:30
farizrahman4u d2051a5df1 Added shape checking for concat merge 2015-10-24 14:53:36 +05:30
François Chollet e7c6d598a9 Merge pull request #839 from mmmikael/trainable
added possibility to freeze layers during training
2015-10-23 16:40:38 -07:00
farizrahman4u 1526d81ab3 Faster and better Sentiment Analysis example.
Faster and more accurate sentiment analysis using combination of convolutional and recurrent layers. Better and faster results when compared to using either convnet or rnn alone.

Comparison with other sentiment analysis examples (run on a slow machine so that the time differences are visible):

imdb_lstm.py

Train...
Train on 20000 samples, validate on 5000 samples
Epoch 1/4
20000/20000 [==============================] - 784s - loss: 0.4773 - acc: 0.7769 - val_loss: 0.3613 - val_acc: 0.8396
Epoch 2/4
20000/20000 [==============================] - 788s - loss: 0.2691 - acc: 0.8946 - val_loss: 0.3644 - val_acc: 0.8376
Epoch 3/4
20000/20000 [==============================] - 791s - loss: 0.1770 - acc: 0.9351 - val_loss: 0.3913 - val_acc: 0.8370
Epoch 4/4
20000/20000 [==============================] - 800s - loss: 0.1137 - acc: 0.9612 - val_loss: 0.4621 - val_acc: 0.8308
5000/5000 [==============================] - 48s
Test score: 0.46212145137
Test accuracy: 0.8308

imdb_cnn.py

Train on 20000 samples, validate on 5000 samples
Epoch 1/3
20000/20000 [==============================] - 1414s - loss: 0.6401 - acc: 0.5930 - val_loss: 0.5144 - val_acc: 0.7442
Epoch 2/3
20000/20000 [==============================] - 1411s - loss: 0.3908 - acc: 0.8255 - val_loss: 0.3615 - val_acc: 0.8344
Epoch 3/3
20000/20000 [==============================] - 1416s - loss: 0.3173 - acc: 0.8636 - val_loss: 0.3788 - val_acc: 0.8256



imdb_cnn_lstm.py

Train...
Train on 20000 samples, validate on 5000 samples
Epoch 1/2
20000/20000 [==============================] - 575s - loss: 0.4312 - acc: 0.7900 - val_loss: 0.3457 - val_acc: 0.8456
Epoch 2/2
20000/20000 [==============================] - 580s - loss: 0.2302 - acc: 0.9094 - val_loss: 0.3546 - val_acc: 0.8498
5000/5000 [==============================] - 26s
Test score: 0.354624111649
Test accuracy: 0.8498
2015-10-24 01:49:27 +05:30
farizrahman4u 73c0045815 Bug fix
The base Layer was not returning an output shape.
2015-10-24 01:08:40 +05:30
farizrahman4u 3981a87b31 Assert input shapes of Merge layer are equal
Make sure that only layers with same output_shape are merged using sum, ave and mul modes.
2015-10-23 20:52:43 +05:30
Mikael Rousson a78c43033e added possibility to freeze layers during training 2015-10-23 13:53:26 +02:00
François Chollet 80e85836c1 Merge pull request #876 from farizrahman4u/patch-2
Update comment to include new join merge mode
2015-10-22 15:35:04 -07:00
farizrahman4u 569bb74a08 Update comment to include new join merge mode 2015-10-23 00:04:22 +05:30
François Chollet a8eda69f3e Merge pull request #869 from EderSantana/join
add join to valid merge modes
2015-10-22 09:16:16 -07:00
EderSantana 6f620712b5 add join to valid merge modes 2015-10-21 21:41:34 -04:00
François Chollet a19c9ecfbd Merge pull request #865 from suixudongi8/patch-1
Update optimizers.py
2015-10-21 18:33:14 -07:00
Xsh Disney 11e4c4b90f Update optimizers.py
Bug:
float() argument must be a string or a number, not 'TensorSharedVariable'
fixed!
2015-10-21 21:30:44 +08:00
François Chollet 025cd16854 Merge pull request #859 from r9y9/patch-1
FIx `Exception: Invalid layer: LRN2D`
2015-10-20 10:24:48 -07:00
Ryuichi YAMAMOTO 68f619b9f9 import LRN2D
This should fix the problem`Exception: Invalid layer: LRN2D` while loading a model that includes LRN2D.

```py
model = Sequential()
model.add(Convolution2D(30, 3, 3, input_shape=(1, 28, 28)))
model.add(LRN2D())

model_def = model.to_yaml()

# this line raises Exception: Invalid layer: LRN2D
model_from_yaml(model_def)
```

The code above could reproduce the problem.
2015-10-20 19:28:41 +09:00
Francois Chollet f1ef9895f5 Update README w/ warning about using latest Theano 2015-10-14 11:26:23 -07:00
Francois Chollet a86b381424 Update LICENSE with copyright information. 2015-10-14 09:02:22 -07:00
Francois Chollet 5691912701 Update RNN docs 2015-10-13 17:56:06 -07:00
François Chollet cc26bc24a9 Merge pull request #826 from jfsantos/patch-5
Fix #821
2015-10-13 11:41:15 -07:00
João Felipe Santos f62c03bdea Fix #821
`decay` in `SGD` is not a shared value, so it does not have a `get_value` method.
2015-10-13 14:19:50 -04:00
François Chollet 40a9bd7c2f Merge pull request #819 from xingdi-eric-yuan/master
Bug fixes:
2015-10-12 20:15:13 -07:00
Xingdi (Eric) Yuan 38a3228999 Bug fixes:
“TypeError: Cannot cast ufunc subtract output from dtype('float64') to
dtype('uint8') with casting rule 'same_kind'” in
keras/preprocessing/image.py, line 239, when using data augmentation.
2015-10-12 15:09:25 +08:00
Francois Chollet d2189fef32 Update version number: now 0.2.0 2015-10-10 17:51:59 -07:00
François Chollet 0a35173b33 Merge pull request #814 from matsuyamax/shapeinfer
Fix variable sharing issue with NonNeg constraint.
2015-10-10 17:17:41 -07:00
Makoto Matsuyama 5d2f3101ae Fix variable sharing issue with NonNeg constraint. 2015-10-10 16:50:33 -07:00
François Chollet 73aac1c7c9 Merge pull request #813 from hedeon/keras_hq
Fix: added "Permute" into imports of line 8: keras/keras/utils/layer_utils.py
2015-10-10 13:09:37 -07:00
Haizhou Qu 815f7064a2 Fix: added "Permute" into imports 2015-10-10 20:50:26 +01:00
François Chollet 63f81cafbd Merge pull request #808 from transcranial/typo-fixes
fixes for new API: Embedding layer, additional examples
2015-10-09 22:47:43 -07:00
Leon Chen 4c1a6fc27e fix Embedding config property to include new input_length property, add input_length to all examples with Embedding layer 2015-10-09 16:35:48 -04:00
Leon Chen 9dbf04b699 poolsize -> pool_size 2015-10-09 16:32:34 -04:00
François Chollet 856a99de6c Merge pull request #804 from transcranial/conv2d-bugfix
correct image_shape and filter_shape parameters in Convolution2D
2015-10-08 16:11:44 -07:00
Leon Chen f463d23b38 correct image_shape and filter_shape parameters in Convolution2D 2015-10-08 16:54:15 -04:00
François Chollet 775719983f Merge pull request #791 from matsuyamax/shapeinfer
Add automatic shape inference.
2015-10-06 20:26:20 -07:00
Makoto Matsuyama e839a4bdac Py3 compatibility 2015-10-05 17:42:35 -07:00
Makoto Matsuyama cfd2763514 Simplify test_tasks 2015-10-05 17:04:50 -07:00
Makoto Matsuyama 0b8a52e463 Update documentation to new API. 2015-10-05 16:28:17 -07:00
Makoto Matsuyama cb77f7d7e2 Incorporate image_shape and filter_shape in convs 2015-10-05 13:02:31 -07:00
Makoto Matsuyama e8e56d9013 Add shape inference to Graph containers 2015-10-05 12:01:24 -07:00
Makoto Matsuyama c60e2dfbdb Update (most) automated tests. 2015-10-05 07:09:44 -07:00
François Chollet 9807dcd69b Merge pull request #775 from stephenbalaban/feature/customlayers
First crack at threading `custom_layers` through.
2015-10-05 05:55:27 -07:00
Makoto Matsuyama 2bd4c295d6 Update all examples with new API 2015-10-04 18:44:49 -07:00
Makoto Matsuyama 35d66d672b Add shape inference to existing layers 2015-10-04 16:45:01 -07:00
Stephen A. Balaban 11eaaeb695 Rm custom_layers argument from get_from_module
Removed tailind whitespace in generic_utils.
Shoved variables from `custom_layers` into globals().
2015-10-04 15:57:43 -07:00
Stephen A. Balaban cc1251b307 Merge branch 'master' of github.com:fchollet/keras 2015-10-04 15:44:36 -07:00
Makoto Matsuyama 4564dab62a Allow any layer to accept a 'input_shape' kwarg. 2015-10-04 14:26:12 -07:00
Makoto Matsuyama 0e62ae4eaa fix merge conflict 2015-10-04 13:41:45 -07:00
François Chollet 876bca046f Merge pull request #780 from matsuyamax/master
Fix compatibility with old MaxPooling interface
2015-10-04 13:00:01 -07:00
Makoto Matsuyama d7e0ba1c39 Fix 2015-10-04 12:49:50 -07:00
Makoto Matsuyama e0bcee4963 Revert default stride in MaxPooling to None 2015-10-04 12:28:22 -07:00
Makoto Matsuyama ca4fc2e72f Fix compatibility with old MaxPooling interface 2015-10-04 12:26:48 -07:00
François Chollet 83544cdb41 Merge pull request #777 from matsuyamax/shapeinfer
Add .output_shape attribute in all layers (+tests)
2015-10-04 10:46:56 -07:00
Makoto Matsuyama 37978fcda6 fix merge conflict 2015-10-04 06:57:52 -07:00
Makoto Matsuyama 61d76d4a07 fix merge conflict 2015-10-04 06:39:40 -07:00
Makoto Matsuyama cc6280f34d Fix tests 2015-10-04 06:30:45 -07:00
François Chollet 5bab11eec7 Merge pull request #778 from transcranial/conv1d-cudnn
Use cuDNN in Convolution1D layer if available
2015-10-04 06:29:44 -07:00
Leon Chen 65b048455b use cuDNN in Convolution1D layer if available 2015-10-04 01:52:39 -04:00
Makoto Matsuyama 9be4480eab Add ZeroPadding1D, refactor ZeroPadding2D 2015-10-03 22:16:14 -07:00
Makoto Matsuyama 7219bb4b96 Change API of Reshape layer 2015-10-03 22:15:53 -07:00
Makoto Matsuyama fd2c6dbafd in MaxPooling layers: poolsize -> pool_size 2015-10-03 21:52:35 -07:00
Makoto Matsuyama 19c736a4ca Remove print statement, py3 compatibility. 2015-10-03 19:54:46 -07:00
François Chollet b9bf954f24 Merge pull request #732 from matsuyamax/master
Update relu to use Theano's implementation
2015-10-03 19:27:18 -07:00
Makoto Matsuyama 0bc7b25f59 Upgrade Theano in Travis config 2015-10-03 18:20:00 -07:00
Makoto Matsuyama 9f47903daf Merge remote-tracking branch 'upstream/master' 2015-10-03 18:18:18 -07:00
Makoto Matsuyama 7f1eb97000 Remove whitespace, useless comment 2015-10-03 18:15:46 -07:00
Makoto Matsuyama c506fbda4a Add .output_shape attribute in all layers (+tests) 2015-10-03 17:08:28 -07:00
Stephen A. Balaban aa05c44145 Merge branch 'master' of github.com:fchollet/keras 2015-10-03 12:58:09 -07:00
Stephen A. Balaban 2e0d96d1a2 Merge branch 'bugfix/reshape' 2015-10-03 12:56:26 -07:00
François Chollet 6b62678e90 Merge pull request #619 from amitbeka/non-overwrite-checkpoint
support for multiple files in ModelCheckpoint
2015-10-03 12:10:55 -07:00
François Chollet cc8a901c31 Merge pull request #706 from nehz/nehz-subsample
Should subsample Convolution1D on correct axis
2015-10-03 12:07:06 -07:00
François Chollet 7c44d16a77 Merge pull request #771 from stephenbalaban/bugfix/reshape
Bugfix/reshape
2015-10-03 10:10:03 -07:00
Stephen A. Balaban ee07e6ef74 Added kwargs to Reshape. 2015-10-02 17:00:23 -07:00
Stephen A. Balaban 88a0ab5e93 First crack at threading custom_layers through.
A bit surprised that keras was using globals() to access layers (doesn't work
across modules.) Hacky solution was to pass a dict mapping name -> class.
I called this dict `custom_layers`.

Is there a better way of doing this that I'm not seeing?
2015-10-02 13:31:19 -07:00
Stephen A. Balaban 57bb9e2613 Added **kwargs to to_json and to_yaml.
This allows you to do nice things like save JSON models so that they're human
readable & editable. For example:

>>> with open('output.json', 'w') as f:
...     f.write(model.to_json(indent=4, sort_keys=True))
...
2015-10-02 10:59:13 -07:00
François Chollet c1857cfa66 Merge pull request #757 from matsuyamax/cnn_fix
Fix Reshape and Permute deserialization
2015-09-30 22:18:31 -07:00
Makoto Matsuyama 2d8307622d Fix Reshape and Permute deserialization 2015-09-30 21:16:59 -07:00
François Chollet af932d3480 Merge pull request #752 from jfsantos/patch-4
Fix typo in docstring
2015-09-30 09:07:18 -07:00
João Felipe Santos 4ed53ae5a4 Fix typo in docstring
longuest -> longest
2015-09-30 11:47:38 -04:00
François Chollet 0d798c662b Merge pull request #749 from nebw/fix-sample-weight-doc
add class_weight/sample_weight parameters to doc #736
2015-09-29 20:56:29 -07:00
Benjamin Wild 5f4675bd7f add class_weight/sample_weight parameters to doc #736 2015-09-29 16:51:32 +02:00
François Chollet 14b175c9b0 Merge pull request #745 from blackyang/doc_sample_weight
change sample_weight doc
2015-09-28 22:19:04 -07:00
Xiao Yang 8d4e75894a change sample_weight doc 2015-09-29 00:53:13 -04:00
François Chollet 3d888cbf7e Merge pull request #739 from matsuyamax/cnn_fix
Fix bug in deserialization of convolutional layers
2015-09-28 08:22:14 -07:00
Makoto Matsuyama 3b76158c49 Fix bug in deserialization of convolutional layers 2015-09-27 21:49:20 -07:00
François Chollet 788d838160 Merge pull request #738 from matsuyamax/graph_fix
Fix bug with Graph sample_weights
2015-09-27 21:39:16 -07:00
Makoto Matsuyama 56ae624f12 Fix bug with Graph sample_weights 2015-09-27 20:50:32 -07:00
François Chollet ef43a271ee Merge pull request #714 from eulerreich/patch-1
fixed incorrect comment
2015-09-27 10:48:18 -07:00
François Chollet 0b1a1e9761 Merge pull request #734 from EderSantana/master
Fix order of sings of clipvalue
2015-09-26 14:48:49 -07:00
EderSantana 52e3e2623a Merge branch 'master' of https://github.com/fchollet/keras 2015-09-26 17:43:26 -04:00
EderSantana 46a2fb6fd8 Fix sign order for clipvalue 2015-09-26 17:42:56 -04:00
Makoto Matsuyama b0f2446370 Fix relu 2015-09-25 23:55:25 -07:00
Makoto Matsuyama 7a2e8ce8a2 Update relu to use Theano's implementation 2015-09-25 23:21:35 -07:00
François Chollet 200948c3be Merge pull request #730 from eulerreich/patch-2
minor typo
2015-09-25 20:45:32 -07:00
François Chollet 35612d698a Merge pull request #731 from eulerreich/patch-3
minor typos
2015-09-25 20:45:15 -07:00
eulerreich 8a5767a53e minor typos 2015-09-25 22:18:53 -05:00
eulerreich f4ca4026a3 minor typo 2015-09-25 22:11:57 -05:00
François Chollet e4d0ed5992 Merge pull request #719 from farizrahman4u/patch-1
Update skipgram_word_embeddings.py
2015-09-25 19:52:26 -07:00
François Chollet 1325e73a59 Merge pull request #729 from EderSantana/master
Clip value as in Neural Turing Machines paper
2015-09-25 19:49:23 -07:00
EderSantana b6d8e9dd4e Fix clip value logic 2015-09-25 22:12:15 -04:00
EderSantana 69afdd7ec4 Add clip value as in Neural Turing Machines
Instead of norm clipping they do an elementwise clip. I believe others may want
to try that out too.
2015-09-25 22:10:27 -04:00
farizrahman4u d5cd2687ed Update skipgram_word_embeddings.py
Redundant code line 159 and 161
2015-09-25 11:14:53 +05:30
François Chollet ca60201fe5 Merge pull request #690 from EderSantana/master
Add merge_mode join
2015-09-24 21:16:22 -07:00
EderSantana dd6697738b Raise error if using merge_mode= with unnamed input 2015-09-24 18:14:04 -04:00
EderSantana cccc118225 Raise error if using merge_mode= with unnamed input 2015-09-24 18:12:21 -04:00
eulerreich 36578f8569 fixed incorrect comment 2015-09-23 12:30:48 -05:00
François Chollet c18a9cd405 Merge pull request #684 from jmhessel/mergefixes
Added averaging support in merge and a TimeDistributedMerge layer
2015-09-22 20:12:26 -07:00
Jack Hessel cba5cfa597 Added a very quick config unit test 2015-09-22 16:50:02 -04:00
EderSantana b2048d1d88 Merge branch 'master' of https://github.com/fchollet/keras 2015-09-22 11:43:42 -04:00
EderSantana 8bfafd6d7f Merge join returns OrderedDict instead of list
This makes merge_mode='join' complaint with keras API. Also, the OrderedDict
allows the user to simple .values() and use it as a list if he knows in which
order the inputs were merged.
2015-09-22 11:37:49 -04:00
Zhen Wang a6521de3e3 Should subsample Convolution1D on correct axis 2015-09-21 11:59:40 +08:00
Zhen Wang 02ddc11858 Merge pull request #1 from fchollet/master
Update
2015-09-21 11:58:23 +08:00
François Chollet 588261acfc Merge pull request #704 from rodrigob/patch-4
Add a bit of flexibility in Progbar.update
2015-09-20 12:33:31 -07:00
François Chollet 61a48d487f Merge pull request #696 from rodrigob/patch-3
"Epoch %d out of %d"
2015-09-20 12:26:49 -07:00
Rodrigo Benenson eee20b4614 Update callbacks.py
fixed +1
2015-09-20 21:23:43 +02:00
Rodrigo Benenson 9827db2c85 Update callbacks.py
following suggestions
2015-09-20 21:18:42 +02:00
Rodrigo Benenson b9403cb262 Add a bit of flexibility in Progbar.update
By allowing sum_values[k] to be other things than lists, it makes it easier for children classes to print "any value" (in my case, a timedelta object).
2015-09-20 15:26:27 +02:00
François Chollet e379fff425 Merge pull request #697 from ndronen/count-params
Parameter counting method for models.
2015-09-18 07:45:44 -07:00
Nicholas Dronen 80c0c762fd Add count_params method to keras.layers.core.Layer and the Sequential and Graph container classes. 2015-09-17 09:19:21 -06:00
Rodrigo Benenson 51818e5b7b "Epoch %d out of %d"
Print "Epoch %d out of %d" instead of just "Epoch %d"
2015-09-17 15:39:56 +02:00
François Chollet 393642df55 Merge pull request #691 from grahamannett/master
added visualization tools to view Sequential and Graph models
2015-09-16 20:52:41 -07:00
graham 6bb9eecd0c added functioning vizualization 2015-09-16 00:58:44 -07:00
graham f026bb2f5a added functioning vizualization 2015-09-16 00:10:38 -07:00
EderSantana 5c3db2fea6 Add merge_mode join 2015-09-15 21:52:54 -04:00
Jack Hessel 1a953feaf7 added averaging support in merge and a TimeDistributedMerge layer 2015-09-14 13:27:59 -04:00
François Chollet 0733a80297 Merge pull request #677 from jnphilipp/master
Fixed Python 3 Image loading. Closed #676
2015-09-11 19:23:45 -07:00
jnphilipp a5653c245a Fixed Python 3 Image loading. Closed #676 2015-09-11 22:39:07 +02:00
François Chollet 1724fe5882 Merge pull request #662 from gw0/feat-optional-h5py
Remove h5py requirement and made it optional.
2015-09-09 07:58:50 -07:00
gw0 [http://gw.tnode.com/] a582b184c9 Remove h5py requirement and made it optional. 2015-09-08 17:56:44 +02:00
François Chollet 36ef1ca7b4 Merge pull request #661 from jfsantos/patch-3
Updated documentation of Merge layer
2015-09-08 08:42:38 -07:00
João Felipe Santos 27edefe48c Updated documentation of Merge layer
Added 'mul' mode documentation to Merge.
2015-09-08 10:50:11 -04:00
François Chollet 4b1b86783f Merge pull request #659 from amitbeka/support-saving-masking
add Masking layer to utils.layer_utils for saving/loading
2015-09-08 07:46:45 -07:00
François Chollet 7009e80b74 Merge pull request #660 from amitbeka/fix-saving-sgd
fix SGD get_config
2015-09-08 07:46:22 -07:00
Amit Beka cd82deb152 fix SGD get_config
Signed-off-by: Amit Beka <amit.beka@gmail.com>
2015-09-08 17:04:24 +03:00
Amit Beka 65b794957f add Masking layer to utils.layer_utils for saving/loading
Signed-off-by: Amit Beka <amit.beka@gmail.com>
2015-09-08 16:39:06 +03:00
Francois Chollet 7b4e6ef50c Fix typo in FAQ 2015-09-07 20:50:40 -07:00
Francois Chollet f804b19fdc Fix typos in FAQ 2015-09-07 20:48:37 -07:00
Francois Chollet eff8731db4 Fixes in doc FAQ 2015-09-07 18:20:39 -07:00
Francois Chollet 43ddbf4a4f Add Keras FAQ 2015-09-07 17:11:38 -07:00
Francois Chollet c5b3959b42 Fix test_tasks 2015-09-07 15:36:38 -07:00
Francois Chollet 289804c67c Fix theano.tensor.signal import issue 2015-09-07 15:16:06 -07:00
Francois Chollet c6825eb343 Style fixes 2015-09-07 15:06:37 -07:00
Francois Chollet 92b8ad9d02 Merge branch 'master' of https://github.com/Mofef/keras into Mofef-master 2015-09-07 15:02:30 -07:00
Francois Chollet 3dfba0504b Merge branch 'master' of https://github.com/fchollet/keras 2015-09-07 13:59:56 -07:00
François Chollet 4bdb43f244 Merge pull request #639 from rodrigob/patch-1
Added reference for orthogonal initialization
2015-09-07 13:12:46 -07:00
Francois Chollet 83e285fd00 Add on_gpu() check 2015-09-07 13:05:45 -07:00
Francois Chollet 4e1ec93c2f Fix weight saving in BatchNormalization 2015-09-07 12:50:34 -07:00
François Chollet 2224c4cc1e Merge pull request #654 from phreeza/travis-coveralls-support
add travis CI and coveralls support
2015-09-07 10:40:55 -07:00
François Chollet 9f6f206ccd Merge pull request #647 from phreeza/test_convolutional
Add tests for convolutional layers
2015-09-07 10:40:35 -07:00
Francois Chollet f3eeb982d0 Avoid dnn import when not running on GPU 2015-09-07 10:32:13 -07:00
Moritz Münst 2be651dc39 concatenation axis as param for Merge() and Graph.add_output/node() 2015-09-07 19:36:51 +03:00
Thomas McColgan c77ded2eb6 add travis CI and coveralls support 2015-09-07 16:28:03 +02:00
François Chollet 06ab8dbd34 Merge pull request #650 from rodrigob/patch-2
Fix cPickle import for python3 support
2015-09-06 17:27:33 -07:00
François Chollet 8e293db9b5 Merge pull request #644 from anjishnu/issue_643
Fixed import errors with six.moves.cPickle and model.train typo in th…
2015-09-06 12:42:11 -07:00
Rodrigo Benenson 5040aa386d Fix cPickle import for python3 support 2015-09-06 15:58:30 +02:00
Thomas McColgan 8e67b040e8 add tests for border_mode == same 2015-09-06 13:03:18 +02:00
Thomas McColgan 84909a49c2 add upsampling layer tests 2015-09-06 12:55:50 +02:00
Thomas McColgan 0969c569a6 add convolutional layer tests 2015-09-06 12:17:24 +02:00
Francois Chollet cb8f0a83e6 Merge branch 'jfsantos-merge_mul' 2015-09-05 17:49:55 -07:00
Francois Chollet 5648119b66 Remove outdated Merge exception 2015-09-05 17:49:27 -07:00
Francois Chollet 25e9b90550 Merge branch 'merge_mul' of https://github.com/jfsantos/keras into jfsantos-merge_mul 2015-09-05 17:45:13 -07:00
Anjishnu Kumar e98b24a767 changed 'fit' to 'train_on_batch' 2015-09-05 14:19:40 -07:00
Anjishnu Kumar 034822359d Fixed import errors with six.moves.cPickle and model.train typo in the skipgram embeddings example 2015-09-05 13:36:52 -07:00
François Chollet 2e60c99924 Merge pull request #642 from wuaalb/lr-scheduler
Fix typo LearningRateScheduler
2015-09-05 04:38:26 -07:00
wuaalb 4bb6ac0b04 Fix typo LearningRateScheduler 2015-09-05 11:59:29 +02:00
François Chollet c368b86d11 Merge pull request #640 from Smerity/master
Removing magic numbers from MNIST and CIFAR10
2015-09-04 17:30:57 -07:00
Stephen Merity 49335d4345 Remove magic numbers from cifar10_cnn.py (fixes #469) 2015-09-04 16:34:00 -07:00
Stephen Merity 93c1a8c675 Remove magic numbers from mnist_cnn.py (re: #469) 2015-09-04 16:24:47 -07:00
Rodrigo Benenson 5f3bdeb0a3 Added reference for orthogonal initialization 2015-09-05 00:54:24 +02:00
François Chollet ddf908359c Merge pull request #637 from jnphilipp/master
Fix for issue #636
2015-09-04 10:28:41 -07:00
jnphilipp 37f4d11ea9 Merge branch 'master' of github.com:jnphilipp/keras 2015-09-04 13:49:52 +02:00
jnphilipp 94fbbd1c7e Fixed missing import. Closed #636 2015-09-04 13:44:26 +02:00
Francois Chollet 332d43e023 Make Pmat a param of JSZ1-2 2015-09-02 20:18:28 -07:00
Francois Chollet f84fe7ce17 Change cPickle import pattern in datasets 2015-09-02 20:15:14 -07:00
Joao Felipe Santos 16d0e40560 Updated 'mul' mode to support multiple layers 2015-08-31 21:17:09 -04:00
Amit Beka da24be79ab support for multiple files in ModelCheckpoint
enable string formatted filenames (e.g. weights.{epoch:02d}.hdf5), so
every epoch will be saved to a different file without overwriting.

Signed-off-by: Amit Beka <amit.beka@gmail.com>
2015-08-31 11:25:06 +03:00
Joao Felipe Santos ab8642e0ff Added element-wise multiplication as merge mode 2015-08-29 13:24:54 -04:00
fchollet 2c30d503ea Fix sample weights generation for validation data 2015-08-27 15:52:10 -07:00
fchollet 7a86ff7f5b Fixes in loss weighting with validation data 2015-08-27 15:38:26 -07:00
François Chollet 1eb2e6e3f2 Merge pull request #606 from entron/fix_multi_gpu
Multiple GPU works
2015-08-27 13:54:00 -07:00
Cheng Guo a9d437198e Multiple GPU works 2015-08-27 16:25:10 +02:00
fchollet 3c4f0ac609 Revert "Fix sample_weight and class_weight in validation"
This reverts commit 9773e810a5.
2015-08-26 16:50:24 -07:00
fchollet 9773e810a5 Fix sample_weight and class_weight in validation 2015-08-26 15:37:06 -07:00
fchollet 484039d2ce Merge branch 'conv_same_with_cudnn' of https://github.com/entron/keras into entron-conv_same_with_cudnn 2015-08-25 11:58:27 -07:00
Cheng Guo 5a3d2fe204 added check of running device 2015-08-25 10:42:42 +02:00
François Chollet 14e4a2391a Merge pull request #381 from osh/thresh_activ
adding thresholded linear and rectified activation functions
2015-08-24 23:17:07 -07:00
fchollet a701435049 Merge branch 'time-distributed-class-weights' 2015-08-24 15:08:59 -07:00
fchollet 24bf848851 Merge branch 'time-distributed-class-weights' of https://github.com/wxs/keras into time-distributed-class-weights 2015-08-24 15:00:52 -07:00
fchollet bad60eedda Merge branch 'wxs-fix-weight-mask-interaction' 2015-08-24 13:41:42 -07:00
fchollet 21f0bfa239 Fix loss masking test 2015-08-24 13:41:05 -07:00
fchollet 6ef6128bb1 Merge branch 'fix-weight-mask-interaction' of https://github.com/wxs/keras into wxs-fix-weight-mask-interaction 2015-08-24 13:23:15 -07:00
Xavier Snelgrove 9e001ee70c Make the logic more understandable via DRY 2015-08-24 15:27:52 -04:00
Xavier Snelgrove fc6c42e3df I believe this is the correct combination of masks and weights 2015-08-24 15:25:14 -04:00
Xavier Snelgrove 1ee8efde56 Remove a no-op reshape
This reshape happens implicitly via the nonzero() call now.
2015-08-24 15:20:10 -04:00
Xavier Snelgrove 25508e0771 Fix interaction issues with mask and weights in weighted_objective
We used nonzero() on the weights in order to ensure that if there
happened to be a NaN or an Inf in the output that was going to be masked
about by the weights anyway, it wouldn't propagate (because 0*inf = NaN)
however this was causing interaction issues if you also used a mask,
because that wasn't using nonzero() properly.

This fixes that, and also fixes what I believe was an issue where I was
calling mean() instead of dividing by the sum of the sample weights.
2015-08-24 15:13:24 -04:00
fchollet 34999c8658 Fix Poisson loss when target = 0 2015-08-24 11:10:27 -07:00
fchollet f66b58bb6c Merge branch 'master' of https://github.com/fchollet/keras 2015-08-24 06:06:34 -07:00
fchollet 6cd8d3c37a Fix optimizer serialization 2015-08-24 06:06:03 -07:00
François Chollet 0daf02a96d Merge pull request #586 from jerheff/patch-1
Fix documented form of parametric softplus
2015-08-23 18:42:23 -07:00
Jeremy Heffner b498218d0b Fix documented form of parametric softplus 2015-08-23 17:45:50 -04:00
fchollet aa21a15bd3 Merge branch 'EderSantana-master' 2015-08-21 14:52:30 -07:00
fchollet 93624e10e8 Fix graph container 2015-08-21 14:52:03 -07:00
fchollet d9579e1c08 Learning rate scheduling touch-ups 2015-08-21 14:51:24 -07:00
fchollet 5af36525c5 Merge branch 'master' of https://github.com/EderSantana/keras into EderSantana-master 2015-08-21 14:46:10 -07:00
fchollet eb11ad776e Merge branch 'master' of https://github.com/fchollet/keras 2015-08-21 14:24:25 -07:00
fchollet ff197781b3 Multi-io get_input / get_ouput in graph container 2015-08-21 14:24:13 -07:00
fchollet af84a6879d Remove irrelevant code in convolutional 2015-08-21 14:23:17 -07:00
EderSantana f4a2323d5e - pep8 + better callback name 2015-08-21 14:56:26 -04:00
EderSantana 6a5a317848 I mean on_epoch_begin 2015-08-20 17:43:03 -04:00
EderSantana cdbbdce934 Make lr and momemtum shared_scalars
With lr and momentum being scalars we can change their values without
needing to recompile the model. This PR also includes a Callback called
LrSetter that gets a dict with epoch x lr pairs and set the values of
the later at the begging of the associated epoch.
2015-08-20 17:42:15 -04:00
François Chollet effe128bde Merge pull request #561 from JasonTam/sklearn-init-params
Moved fit/predict params to init. Changed test accordingly.
2015-08-20 14:13:46 -07:00
JasonTam dcbe14cd9a Moved fit/predict params to init. Changed test accordingly. This addresses #558 . 2015-08-19 15:35:28 -04:00
François Chollet 103a3da614 Merge pull request #559 from danielforsyth/docs
Add SciPy Link to Conv Layer Docs
2015-08-19 09:46:19 -07:00
forsythd ec450f429e Add SciPy Link to Conv Layer Docs 2015-08-19 12:37:07 -04:00
Cheng Guo a3f3a020a2 added cudnn availability check 2015-08-19 11:10:11 +02:00
François Chollet b958978dde Merge pull request #555 from jdwittenauer/master
Finished scikit-learn wrapper
2015-08-18 20:15:55 -07:00
fchollet a478930d25 Add weight loading to PReLU, ParametricSoftPlus 2015-08-18 18:19:58 -07:00
John Wittenauer 4afb5b60d6 Resolved a few minor issues found during testing. 2015-08-18 21:05:45 -04:00
fchollet 78feed7fa9 Fix autoencoder serialization 2015-08-18 16:49:31 -07:00
François Chollet 5e9579aeac Merge pull request #547 from awentzonline/conn-map-dict
Fix Graph.set_previous with dict connection_map
2015-08-18 07:09:15 -07:00
Adam Wentz c515dc90d4 Fix Graph.set_previous with dict connection_map 2015-08-17 20:41:20 -05:00
John Wittenauer 7c966439fa Updated wrapper test script. 2015-08-17 21:03:00 -04:00
fchollet 818f5d7dc4 Merge branch 'master' of https://github.com/fchollet/keras 2015-08-17 17:57:48 -07:00
fchollet 23b1d7929f Merge branch 'Smerity-master' 2015-08-17 17:57:41 -07:00
fchollet d5455154f2 Touch-ups to addition RNN example 2015-08-17 17:57:20 -07:00
François Chollet d473216a8b Merge pull request #546 from awentzonline/typo
Fixed typo in containers.Graph
2015-08-17 17:22:19 -07:00
Adam Wentz ca0ebcc627 Fixed typo in containers.Graph 2015-08-17 19:01:42 -05:00
Stephen Merity 588ce7a7e2 Example: Sequence to sequence learning for addition using RNNs 2015-08-17 04:42:54 -07:00
fchollet 97174dd298 Fix batch normalization as first layer 2015-08-16 18:09:48 -07:00
fchollet 3dd6dbe5d4 Merge branch 'master' of https://github.com/fchollet/keras 2015-08-16 17:53:53 -07:00
fchollet 4de2b58842 Fix graph model 2015-08-16 17:53:37 -07:00
François Chollet 88ba02ae32 Merge pull request #538 from jfsantos/patch-2
Recent update broke HDF5Matrix
2015-08-16 17:02:40 -07:00
João Felipe Santos af6b50b64c Recent update broke HDF5Matrix
`refs` is a class attribute, not an instance attribute. If you make `refs` an instance attribute, this will cause `HDF5Matrix` to open the same HDF5 file more than once (which should never happen).
2015-08-16 16:51:20 -04:00
fchollet a02ccc2a78 Change API of ZeroPadding2D 2015-08-16 12:02:07 -07:00
fchollet f494757860 Merge branch 'anayebi-master' 2015-08-16 10:39:58 -07:00
fchollet 965a8cae03 Convolution layers: style cleanup, code re-org 2015-08-16 10:39:27 -07:00
fchollet c61616abf4 Merge branch 'master' of https://github.com/anayebi/keras into anayebi-master 2015-08-16 10:29:20 -07:00
fchollet ca758bef0b Fix RepeatVector in captioning example 2015-08-16 10:27:13 -07:00
anayebi 024a88f986 Removed negative axis indices from UpSample2D 2015-08-16 09:23:13 -07:00
fchollet a1161885d5 Fix text preprocessing 2015-08-17 00:28:46 +09:00
François Chollet 9c58adfe4b Merge pull request #515 from bshickel/patch-1
Fixes IndexError when converting sequences to matrix with nb_words = None
2015-08-16 08:22:11 -07:00
John Wittenauer c9461d7148 Added regressor class. 2015-08-15 20:59:06 -04:00
John Wittenauer dbe948ec97 Added base class for classifer to inherit from. 2015-08-15 20:46:41 -04:00
fchollet f7d4a1e443 Merge branch 'master' of https://github.com/fchollet/keras 2015-08-16 05:29:06 +09:00
fchollet 7115efc37b Remove optional loss masking (now automatic) 2015-08-16 05:28:33 +09:00
François Chollet 2079807ac2 Merge pull request #528 from stephenroller/ndim_tensor
ndim_tensor should support one dimensional tensors.
2015-08-16 05:21:30 +09:00
François Chollet aa2f866083 Merge pull request #533 from lukedeo/fix
fix: json dump to string
2015-08-16 05:21:18 +09:00
lukedeo 9b4fe767ae fix: json dump to string 2015-08-15 13:10:24 +02:00
anayebi fe45d2f002 Added UpSample1D and UpSample2D 2015-08-14 17:06:14 -07:00
EderSantana 9d76926eba Added cost masking to Graph model 2015-08-14 12:29:19 -04:00
Stephen Roller dec67bdb4e ndim_tensor should support one dimensional tensors. 2015-08-14 08:00:56 -05:00
fchollet a6aa7940bf Fix history in graph model. 2015-08-13 23:33:39 +09:00
Cheng Guo ab75f215b6 Use cudnn in Convolution2D to speedup 2015-08-13 11:45:28 +02:00
bshickel 3bc4b5249a Fixes IndexError when converting sequence to matrix
Calling sequences_to_matrix results in an IndexError when nb_words = None. This is caused by a 1-indexed word_index, since sequences_to_matrix expects 0-indexing. Converts word_index to 0-based indexing.
2015-08-10 13:46:39 -04:00
fchollet ae4219e6b1 Fix loss masking tests 2015-08-10 13:34:40 +09:00
fchollet b3cb7f4ef7 Merge branch 'master' of https://github.com/EderSantana/keras into EderSantana-master 2015-08-10 13:14:11 +09:00
fchollet eac3bf8b58 Extend layer API to multi inputs / ouputs 2015-08-10 13:13:29 +09:00
fchollet 425f29038a Add create_output option in Graph model 2015-08-10 12:36:41 +09:00
fchollet 1b66e36e25 Merge branch 'master' of https://github.com/fchollet/keras 2015-08-10 12:19:20 +09:00
fchollet b057624707 Add border_mode = same to Convolution1D 2015-08-10 12:16:52 +09:00
François Chollet 69628bb28d Merge pull request #512 from averybigant/fix_conv_layers_yaml_load
Fix conv layers loading for model_from_config
2015-08-10 11:41:36 +09:00
Renbi.YU ed4acfae40 Fix conv layers loading for model_from_config 2015-08-09 23:49:04 +08:00
fchollet 9e7f67b6f9 Fix typo 2015-08-09 15:29:14 +09:00
fchollet c81d6ec93f Fix batch normalization 2015-08-09 15:26:34 +09:00
fchollet 0eea5055c9 Use readthedocs theme in dev doc version 2015-08-09 12:14:51 +09:00
fchollet e1d8b1ba09 Update MaxPooling1D documentation. 2015-08-09 12:12:50 +09:00
fchollet 616fcbaa20 Merge branch 'nehz-MaxPooling1D-fix' of https://github.com/nehz/keras into nehz-nehz-MaxPooling1D-fix 2015-08-09 12:07:23 +09:00
François Chollet 921cf41d24 Merge pull request #494 from wxs/document-sampleweight
Add documentation for time distributed sample weighting
2015-08-07 15:36:48 +09:00
François Chollet f8afa92bbb Merge pull request #489 from dribnet/url_check
data_utils: add error handling on url fetches
2015-08-07 14:26:09 +09:00
François Chollet 1a572b10e8 Merge pull request #501 from Smerity/master
Fixes and full results for bAbi RNN example
2015-08-07 14:18:40 +09:00
Stephen Merity 342f2bc271 babi_rnn: Adding results for all tasks in bAbi tasks dataset 2015-08-06 21:43:05 -07:00
Stephen Merity dbc0c27729 babi_rnn bugfix: Fixing missing Python 3 support
+ reduce function disappeared (requires import from functools)
+ tarfiles and encodings - decoding bytes to ASCII at line level
2015-08-06 21:36:06 -07:00
Stephen Merity 63284a47ff babi_rnn bugfix: QA19 requires vocab from the answer
For all other questions, the full vocab is in the stories and the queries
2015-08-06 12:58:34 -07:00
Zhen Wang 6d17e9994e Fix MaxPooling1D.
Should downsample on `steps`.
2015-08-07 00:46:31 +08:00
Xavier Snelgrove 1d6b60c1ad Allow class_weight's use with time distributed data
As far as I can tell there is no reason not to support class_weight with
time distributed data, rewriting the standardize_weights function with
that in mind.
2015-08-06 11:22:43 -04:00
Xavier Snelgrove 73fdaf6d6f Add documentation for time distributed sample weighting
There was some confusion around whether you could mask individual
timesteps.
2015-08-06 09:59:35 -04:00
Tom White 6fddf15f1f data_utils: add error handling on url fetches
urlretrieve will blindly swallow any 4xx and 5xx responses
and then save the html error response in the local file. This
is probably exactly what we don't want, because not only will
the program crash if there is a network hiccup when the error
file cannot be opened, but it will continue to do so when rerun
until the corrupt cached file is found and manually removed.

Luckily, urlretrieve is just a thin wrapper around
FancyURLopener, so we can make our own thin wrapper
that throws an exception instead of caching the
wrong file.

Tested to be working as before when running cached and
uncached datasets, and also verified to fail loudly
when asked to fetch http://httpstat.us/500
2015-08-06 01:34:18 -07:00
François Chollet e42f738d0d Merge pull request #479 from anayebi/poisson-loss
Added Poisson Loss as an objective
2015-08-05 13:33:04 +09:00
anayebi 149d0e8d18 Added Poisson loss to Objectives 2015-08-04 21:06:51 -07:00
fchollet 37965cae6b Style touch-ups in babi example 2015-08-04 22:49:05 +09:00
Stephen Merity de78ddff9c Example: Use RNNs to answer questions from bAbi 2015-08-04 03:16:26 -07:00
fchollet 4ecb5bdd14 Fix Hualos callback 2015-08-02 16:58:04 +09:00
fchollet 1e3d9f7be1 Fix Hualos callback 2015-08-01 21:36:05 +09:00
François Chollet 54dc64736e Merge pull request #457 from kashif/adam
Updated adam solver to v8 of paper
2015-07-31 23:12:44 +09:00
François Chollet 3bf5340f18 Merge pull request #449 from tkipf/master
Proper handling of output values in Masking layer
2015-07-31 19:14:21 +09:00
fchollet 15a3a1f1ce Randomness seeding, small fixes 2015-07-31 10:38:46 +09:00
Kashif Rasul 9c7c52d908 further optimisation 2015-07-29 14:57:18 +02:00
Kashif Rasul 10b767d17e more efficient implementation as per paper 2015-07-29 12:07:46 +02:00
Kashif Rasul c68aaa21af fixed t variable 2015-07-28 20:36:41 +02:00
Kashif Rasul eeb56b9e22 updated adam solver
Updated adam solver to v8 of paper. The kappa (lambda) parameter has no
practical use and has been removed.

Fixed the calculations for beta_1_t and beta_2_t where also wrong.
2015-07-28 20:06:21 +02:00
EderSantana f25f894bd9 Correntions in the cost functions masking
We can average the vector and batch dimensions with mean, only the time
dimensions needs special love.
2015-07-28 10:01:14 -04:00
EderSantana a79343f5b0 Test previous commit 2015-07-27 12:39:48 -04:00
EderSantana 53aaa66994 Added masking to cost function
When dealing with sequences of different lenghts, this OPTIONALLY
fixes cost function bias to the largest sequences.
2015-07-27 12:27:13 -04:00
Thomas Kipf cb763aa26b Proper handling of output values in Masking layer 2015-07-27 14:24:00 +02:00
fchollet 48381f8af5 Masking layer touch-ups 2015-07-27 14:39:51 +09:00
fchollet 3212cd4ccd Merge branch 'masking-layer' of https://github.com/amitbeka/keras into amitbeka-masking-layer 2015-07-27 14:26:38 +09:00
fchollet 6a1ede1aa3 Merge branch 'master' of https://github.com/fchollet/keras 2015-07-27 14:26:07 +09:00
François Chollet b1631bd836 Merge pull request #447 from amitbeka/gitignore-tags
git-ignore tags file
2015-07-27 12:52:09 +09:00
Tim O'Shea a06e193679 adding thresholded linear and rectified activation functions 2015-07-26 15:06:42 -04:00
Amit Beka 38f7fb1efb git-ignore tags file
Signed-off-by: Amit Beka <amit.beka@gmail.com>
2015-07-26 13:01:46 +00:00
Amit Beka cb1d25fddb layers.core: add Masking layer
Signed-off-by: Amit Beka <amit.beka@gmail.com>
2015-07-26 12:57:57 +00:00
fchollet b64217cdef Small style fixes 2015-07-26 17:00:18 +09:00
François Chollet 59a634d558 Merge pull request #444 from erfannoury/patch-1
Fix LossHistory callback argument in doc
2015-07-26 16:48:59 +09:00
Erfan Noury dd833de568 Fix LossHistory callback argument in doc 2015-07-26 10:34:07 +04:30
fchollet 275f4166e4 Merge branch 'master' of https://github.com/fchollet/keras 2015-07-25 10:37:17 +09:00
fchollet 8675fc5213 Update core layers documentation 2015-07-25 10:34:51 +09:00
François Chollet 68f0677476 Merge pull request #441 from kenterao/master
Fix optimizer get/set state
2015-07-25 09:23:40 +09:00
Ken Terao 3a62cad7f5 fix model_from_json 2015-07-24 17:38:24 -05:00
Ken Terao 1e18983cfb Fix optimizer 2015-07-24 17:34:11 -05:00
fchollet a4def20848 Fix serialization 2015-07-24 22:08:27 +09:00
fchollet f1d60121ed Fix optimizers test 2015-07-24 18:34:57 +09:00
fchollet 0661032509 Merge branch 'master' of https://github.com/kenterao/keras into kenterao-master 2015-07-24 17:53:22 +09:00
fchollet 4f6b1a4dae Add optimizers tests 2015-07-24 17:50:44 +09:00
fchollet 0e295dbda1 Merge branch 'master' of https://github.com/fchollet/keras 2015-07-24 16:38:33 +09:00
fchollet 7c3bf9d02f Add dataset tests 2015-07-24 16:26:49 +09:00
fchollet e06f9df878 Refactor model serialization 2015-07-24 16:26:27 +09:00
fchollet b6aaeb35ee Fix embedding test 2015-07-24 16:26:16 +09:00
fchollet d1387c1e87 Move model_utils to layer_utils 2015-07-24 16:05:39 +09:00
fchollet 3a28da9e54 Cleanup/fix model_utils 2015-07-24 16:02:46 +09:00
fchollet 32fd202805 Merge branch 'print_layer_shapes' of https://github.com/julienr/keras into julienr-print_layer_shapes 2015-07-24 15:32:44 +09:00
fchollet e975f8a691 Remove deprecated methods 2015-07-24 09:32:41 +09:00
François Chollet d2defcae18 Merge pull request #433 from mynameisfiber/master
Fixed parameter passing for preprocessing.text.one_hot
2015-07-24 09:15:53 +09:00
Ken Terao 347e6d01ff Added get_state and set_state method to Optimizer base class. 2015-07-23 19:10:38 -05:00
François Chollet 540a1ceb45 Merge pull request #436 from kenterao/master
typo
2015-07-24 08:56:06 +09:00
Ken Terao 4c83fccced typo 2015-07-23 18:51:29 -05:00
Ken Terao 0974e07a4a typo 2015-07-23 18:49:33 -05:00
Micha Gorelick 570c377623 Fixed parameter passing for preprocessing.text.one_hot 2015-07-23 16:07:24 -04:00
Julien Rebetez 896880f84d Add a test script for model_utils 2015-07-23 18:22:13 +02:00
Julien Rebetez d635a60140 Add model_utils.print_graph_layer_shapes to handle Graph models.
Also handle Merge layers
2015-07-23 18:22:06 +02:00
Julien Rebetez e1df8ca2b1 Merge branch 'master' into print_layer_shapes 2015-07-23 16:48:27 +02:00
Julien Rebetez 1ad453f6d0 Add check to print_layer_shapes to fail explicitely on model used connected to other models. 2015-07-23 16:46:35 +02:00
fchollet a08bf38ec6 Extend loss weighting tests 2015-07-23 20:31:35 +09:00
fchollet 6289de3717 Fix & extend loss weighting 2015-07-23 20:14:34 +09:00
fchollet 8a99d6e404 Merge branch 'master' of https://github.com/kenterao/keras into kenterao-master 2015-07-23 19:44:05 +09:00
fchollet 6ed288b11c Merge branch 'the-moliver-Psoftplus' 2015-07-23 18:08:37 +09:00
fchollet 940377302b merge 2015-07-23 18:06:59 +09:00
Ken Terao 9cf5f6f982 adding sample_weights to Graph 2015-07-22 23:50:03 -05:00
Michael Oliver 84a3b5aecb Make initializations flexible 2015-07-22 12:30:51 -07:00
Michael Oliver 0174f21ea5 Change name, change to maskedlayer, add docs 2015-07-22 11:20:55 -07:00
François Chollet 2e204479ad Merge pull request #425 from tleeuwenburg/test_layers
More testing, esp core layers
2015-07-22 23:01:18 +09:00
fchollet 1ebec1e515 merge 2015-07-22 22:47:07 +09:00
François Chollet 828d1876ef Merge pull request #407 from tleeuwenburg/travis_upgrade
Travis upgrade
2015-07-22 22:36:20 +09:00
Tennessee Leeuwenburg 66247a8261 Added h5py to the conda install
Test with some travis steps removes

Testing

Tweaking

Tweaking

Tweaking

Final tweaking
2015-07-22 12:09:47 +02:00
Thomas McColgan 67426a6fa3 Test the constructor, config and params functions of all core layers. 2015-07-22 09:08:39 +02:00
Thomas McColgan 571448f5cd test connecting base layers 2015-07-22 09:08:39 +02:00
Thomas McColgan 319412a62d test elementary input and output of base layer 2015-07-22 09:08:39 +02:00
Thomas McColgan 20921b7b13 add some inline documentation 2015-07-22 09:08:39 +02:00
Thomas McColgan f08f590752 add a test on the output dimensions 2015-07-22 09:08:39 +02:00
Thomas McColgan b5dac6bd64 put dimensions into variables
and

make things a bit more concise
2015-07-22 09:08:39 +02:00
Thomas McColgan 130e5cd8cd run get_config and get_output_mask
typo
2015-07-22 09:08:39 +02:00
Thomas McColgan 529306f9f9 simple test of all recurrent layers 2015-07-22 09:08:38 +02:00
fchollet ed9834c62a Remove dot utils doc 2015-07-22 10:33:39 +09:00
fchollet 3037183c1b Remove dot_utils 2015-07-22 10:32:00 +09:00
fchollet ec8f7f0017 Codebase cleanup 2015-07-22 10:31:49 +09:00
fchollet f392a7800d Merge branch 'master' of https://github.com/fchollet/keras 2015-07-21 15:41:11 +09:00
fchollet 72e73b0a30 Merge branch 'cmyr-batch-shuffle' 2015-07-21 15:40:48 +09:00
fchollet 2fbfbdddf6 Cleanup error msg 2015-07-21 15:40:38 +09:00
fchollet e98b1c2352 Merge branch 'batch-shuffle' of https://github.com/cmyr/keras into cmyr-batch-shuffle 2015-07-21 15:37:16 +09:00
François Chollet 80f04d7b56 Merge pull request #420 from the-moliver/the-moliver-samplingfix
Update lstm_text_generation.py with proper multinomial sampling
2015-07-21 14:12:32 +09:00
Michael Oliver 2ada7d16cb change Psoftplus defaults to be nearer relu 2015-07-20 18:14:41 -07:00
Michael Oliver dc50928c18 add theano import 2015-07-20 17:44:19 -07:00
Michael Oliver 36a9a39473 Add parametric softplus 2015-07-20 17:09:09 -07:00
Michael Oliver 98d49754ed Update lstm_text_generation.py
Modify to use proper multinomial sampling, with temperature to control diversity. This seems to generate qualitatively better results and is technically more correct.
2015-07-20 15:42:14 -07:00
cmyr 3b4b5a654b added documentation + a hint if hdf5/shuffle conflict suspected 2015-07-20 13:44:56 -04:00
Julien Rebetez 62a4f29a71 Add print_layer_shapes function 2015-07-20 17:01:59 +02:00
fchollet d2b5849784 Merge branch 'anayebi-master' 2015-07-19 11:05:19 +09:00
fchollet 4b6bf1dbfe Fix Permute layer 2015-07-19 11:04:58 +09:00
fchollet 84d9171ac2 Merge branch 'master' of https://github.com/anayebi/keras into anayebi-master 2015-07-19 10:53:29 +09:00
fchollet c777cdf812 Update README 2015-07-18 20:01:23 +09:00
fchollet 91a15fdf43 Doc, README touch-ups 2015-07-18 19:49:10 +09:00
anayebi fea95703f4 Added Permute layer as suggested by loyeamen on #401 2015-07-17 13:20:12 -07:00
François Chollet efbf7a27f1 Merge pull request #404 from tleeuwenburg/test_norm
Squashed commit of the following:
2015-07-17 13:26:01 +09:00
François Chollet 0e87f4070e Merge pull request #403 from phreeza/typo
fix a typo in several places (ouput -> output)
2015-07-17 08:46:24 +09:00
Tennessee Leeuwenburg a3052e708a Updated to use new container infrastructure 2015-07-17 09:05:57 +10:00
Tennessee Leeuwenburg e6582c1892 Squashed commit of the following:
Author: Thomas McColgan <thomas.mccolgan@gmail.com>

    test config and weight init in batch normalization
    add tests for batch normalization
2015-07-17 08:42:52 +10:00
Thomas McColgan 71ac4bffd3 fix a typo in several places (ouput -> output) 2015-07-16 22:48:38 +02:00
fchollet 6a4aab453f Fix border mode = same in Conv2D 2015-07-16 23:30:29 +09:00
fchollet 46e19b95d8 Cleanup 2015-07-16 16:31:47 +09:00
fchollet 8824f1b469 Fix yaml serialization support 2015-07-16 16:31:14 +09:00
fchollet 43d84368c6 Fixes in yaml serialization 2015-07-16 15:18:34 +09:00
fchollet 08abc317f2 Merge branch 'yaml' of https://github.com/maxpumperla/keras into maxpumperla-yaml 2015-07-16 14:21:30 +09:00
fchollet 036d968ad6 Merge branch 'master' of https://github.com/fchollet/keras 2015-07-16 14:19:24 +09:00
fchollet 510068b83e Merge branch 'pjadzinsky-master' 2015-07-16 14:18:48 +09:00
fchollet 43736166a4 Touch-ups to 'same' border mode 2015-07-16 14:18:05 +09:00
fchollet 9e25669843 Merge branch 'master' of https://github.com/pjadzinsky/keras into pjadzinsky-master 2015-07-16 14:08:38 +09:00
François Chollet 12eba1333a Merge pull request #398 from kenterao/master
Match get_updates signature
2015-07-16 14:07:07 +09:00
Pablo Jadzinsky 6336567c84 Added border_mode='same' to Convolution2D 2015-07-15 21:36:36 -07:00
Ken Terao a3ebda96c3 Uninitialized progbar when verbose==0 2015-07-15 23:29:43 -04:00
Ken Terao 37fe48b744 Match get_updates signature 2015-07-15 23:24:42 -04:00
fchollet fd1d5908c6 Fix graph tests 2015-07-16 10:37:36 +09:00
fchollet 08b1964b77 Fix doc 2015-07-16 10:37:27 +09:00
Pablo Jadzinsky 6a0bf4833b Merge branch 'master' of github.com:pjadzinsky/keras 2015-07-15 12:48:38 -07:00
Pablo Jadzinsky 7af168d81a Added CropImage layer. Shrinks images in a convolution layer. When
applying a Convolution2D with border_mode='Full', images will grow in
size, this Layer allows to shrink them back to its original size (or any
other size)
2015-07-15 12:45:21 -07:00
Max Pumperla 5998b5dcff Extended yaml tests, includes merged sequentials and graphs 2015-07-15 17:07:42 +02:00
Max Pumperla af845d55a4 layer utils, has getter for layers by name and arguments and from_yaml function 2015-07-15 17:06:19 +02:00
Max Pumperla 200a006262 get_from_module available with additional dictionary arguments to initialize objects 2015-07-15 17:05:09 +02:00
Max Pumperla 705694a870 Allow getter of regularizers to take dict args 2015-07-15 17:03:41 +02:00
Max Pumperla 7da91d94ef Allow optimizer getter to take dict args 2015-07-15 17:00:07 +02:00
Max Pumperla 2b7a3cbaa9 to_yaml for Sequential and Graph, as well as model_from_yaml in model agnostic fashion 2015-07-15 16:59:28 +02:00
Max Pumperla c90f98eaec Merge layer to_yaml and None default for reg and constr 2015-07-15 16:58:18 +02:00
Max Pumperla 6c695493c9 Roll back to None as default for reg and constr 2015-07-15 16:56:30 +02:00
Max Pumperla eef82c486a Containers have a layer_to_yaml method | plus fixed a minor typo, inputs were mistakenly added to output_config, not input_config 2015-07-15 16:55:14 +02:00
Max Pumperla 53331e43c2 Allow constraint getter to take parameter dict 2015-07-15 16:52:40 +02:00
fchollet 94c930e99e Remove weight tying in autoencoder 2015-07-15 13:01:48 +09:00
fchollet 2d0e84a857 Merge branch 'mikekestemont-master' 2015-07-15 12:36:20 +09:00
fchollet c8a2f46f79 Rename IMDB CNN example 2015-07-15 12:35:56 +09:00
fchollet 6899a9db16 Revise IMDB conv1d example 2015-07-15 12:35:28 +09:00
fchollet 238d390932 Merge branch 'master' of https://github.com/mikekestemont/keras into mikekestemont-master 2015-07-15 12:18:15 +09:00
fchollet 22bd7cfab6 Update reuters dataset 2015-07-15 10:18:08 +09:00
Mike Kestemont 2603fa37d2 added conv1D example 2015-07-14 22:34:05 +02:00
cmyr 48ea8dfb47 implement batch shuffle 2015-07-14 15:04:23 -04:00
Max Pumperla 319e18ad8f Removed camel case in to_yaml 2015-07-14 16:51:31 +02:00
Max Pumperla 848e1fb5c5 Removed camel case 2015-07-14 16:49:55 +02:00
Max Pumperla 38c4cb2ac2 Manual test for yaml (de-)serialisation 2015-07-14 10:09:05 +02:00
Max Pumperla 493e6d2852 Changed output format of from/to yaml to string, instead of file path 2015-07-14 10:03:19 +02:00
fchollet 03e512a3f4 Batch validation in fit 2015-07-14 13:06:37 +09:00
fchollet a3dadff38f Update documentation 2015-07-12 08:10:13 +09:00
fchollet 65ebd8aa6a Merge branch 'master' of https://github.com/fchollet/keras 2015-07-11 10:20:03 +09:00
fchollet 9f71949d6d Dynamic epsilon in objectives 2015-07-11 10:19:46 +09:00
François Chollet 0bf62784cb Merge pull request #372 from KyotoSunshine/master
Fix uniform initializations equations
2015-07-10 11:21:54 +09:00
KyotoSunshine afc5adbfe1 Fix mistakes in uniform initializations equations
Standard deviation values were being passed as scale values for uniform distributions. 
But the relationship is: scale = standard deviation * sqrt(3).
So, the s values in glorot_uniform, lecun_uniform, and he_uniform should have been multiplied by sqrt(3) before being passed into uniform() function. Now it is fixed.
2015-07-10 02:51:57 +09:00
Max Pumperla 94d857f3cb Changed layers to use get_config for regularizers and constraints for (de-)serialization 2015-07-09 11:50:08 +02:00
Max Pumperla d77175fb2e GaussianNoise has to be MaskedLayer instead of Layer 2015-07-09 11:48:20 +02:00
Max Pumperla f142d34ffc serialize sequential models as yaml 2015-07-09 11:47:19 +02:00
Max Pumperla ca22bb7db5 Getter for regularizers 2015-07-09 10:42:38 +02:00
Max Pumperla 3909e783b9 Stored loss function as self.unweighted_loss, before passing it to weighted_objective 2015-07-09 10:41:54 +02:00
Max Pumperla 46f591d4bb Getter for constraints 2015-07-09 10:40:34 +02:00
François Chollet 472f8ba94b Merge pull request #346 from wxs/document-masking
Add some documentation of the masking feature
2015-07-09 06:57:28 +09:00
fchollet 5bf2718580 Fix binary_crossentropy 2015-07-08 14:03:07 -07:00
fchollet 9a649d2b27 Fix GaussianNoise imports 2015-07-08 13:32:54 -07:00
fchollet c06b746704 Merge branch 'patch-1' of https://github.com/the-moliver/keras into the-moliver-patch-1 2015-07-08 13:29:58 -07:00
Max Pumperla b4c62ffbab Constraints, optimizers and regularizers have a get_config() as preliminary to serialisation 2015-07-08 14:31:43 +02:00
Max Pumperla 5cbe62c248 Made theano_mode field of Sequential 2015-07-08 14:30:32 +02:00
Michael Oliver f0aedaf4e8 correct sqrt call 2015-07-07 18:29:52 -07:00
Michael Oliver 1bfbb33c0d change Layer to MaskedLayer bugfix 2015-07-07 18:22:19 -07:00
fchollet bc05a25b1b Fix tests, increase coverage 2015-07-07 11:07:10 -07:00
fchollet 1e73e1bc54 Fix History callback 2015-07-07 11:07:00 -07:00
fchollet 07f2253ff2 Add test for sequential model 2015-07-07 10:11:48 -07:00
fchollet f817e2e71c merge 2015-07-07 07:40:40 -07:00
François Chollet 4b07e77828 Merge pull request #353 from mthrok/master
Modified comment and fixed batch_size
2015-07-07 07:38:06 -07:00
François Chollet c0a44daabc Merge pull request #349 from floydsoft/patch-1
fix doc
2015-07-07 07:37:29 -07:00
Moto H 7ff158de41 Modified comment and fixed batch_size 2015-07-07 14:22:25 +09:00
Michael Oliver 8213e515d3 Update noise.py
Add link
2015-07-06 20:27:19 -07:00
Michael Oliver c353dfc5f9 Update noise.md
Add link
2015-07-06 20:26:34 -07:00
Michael Oliver 0cae63accb Update noise.py
fix code style
2015-07-06 20:08:24 -07:00
Michael Oliver 5ed7f78b42 update docs 2015-07-06 15:03:14 -07:00
Michael Oliver c354b9be5c Add GaussianDropout 2015-07-06 14:13:01 -07:00
floydsoft df331cc5e0 fix doc 2015-07-07 04:59:00 +08:00
François Chollet 14b014883a Merge pull request #348 from floydsoft/master
fix add_node from inputs
2015-07-06 12:51:18 -07:00
fchollet 7094be1b44 Add y standardization to graph model 2015-07-06 12:47:36 -07:00
floydsoft d4f39c8f53 fix add_node from inputs 2015-07-07 03:45:34 +08:00
Xavier Snelgrove 337f39bd02 Add some documentation of the masking feature 2015-07-06 15:28:16 -04:00
fchollet 7c8d9aaf6b Fix gaussian noise doc 2015-07-06 10:16:37 -07:00
fchollet 6c55dbd6d5 Fix callbacks doc 2015-07-06 10:09:32 -07:00
fchollet ab8f7da83f Put GaussianNoise in its own module. 2015-07-06 10:05:55 -07:00
fchollet 1f21e61a40 Merge branch 'master' of https://github.com/Reddine/keras into Reddine-master 2015-07-06 09:58:33 -07:00
fchollet 16f737ffc2 Fix AE example in doc 2015-07-06 09:57:00 -07:00
fchollet 1fe6556ab8 Fix graph doc 2015-07-05 21:05:56 -07:00
fchollet aeb954dd49 Add dtype to graph inputs 2015-07-05 21:03:29 -07:00
fchollet 35bcd5a45a Touch-ups in examples and doc 2015-07-05 15:04:20 -07:00
fchollet b1d9448908 Refactor merge layer 2015-07-05 14:51:25 -07:00
fchollet fe3c4d73eb Update graph tests 2015-07-05 14:28:35 -07:00
Kheir Eddine FARFAR c315b0d7a9 fix GaussianNoise 2015-07-05 22:22:16 +01:00
fchollet ddd5f47640 Fix container merging issue 2015-07-05 14:13:02 -07:00
fchollet 63f9a7955d Fix ModelCheckpoint callback 2015-07-05 11:19:58 -07:00
fchollet 8995b50a96 Remove DenoisingAutoEncoder 2015-07-05 11:09:22 -07:00
Kheir Eddine FARFAR e014b9435f Create Gaussian Noise layer 2015-07-05 17:46:32 +01:00
fchollet b22e547e98 Merge branch 'Reddine-master' 2015-07-04 15:39:54 -07:00
fchollet 8bd8ae1daa Correct MAPE loss 2015-07-04 15:39:37 -07:00
fchollet 1530f31c1d Merge branch 'master' of https://github.com/Reddine/keras into Reddine-master 2015-07-04 15:35:13 -07:00
fchollet f2c97d817b Add Graph model to doc 2015-07-04 15:08:53 -07:00
fchollet 53a05b6e4c Fix metrics issue in evaluate 2015-07-04 14:37:58 -07:00
fchollet dab55518ba Update cifar10 example 2015-07-04 14:28:24 -07:00
fchollet be75548ca3 Add graph config management 2015-07-04 14:27:01 -07:00
Kheir Eddine FARFAR 32f483fe33 Fix mape objective 2015-07-04 21:02:47 +01:00
fchollet 553a7c0265 Graph bugfix, improve tests 2015-07-04 12:02:26 -07:00
Kheir Eddine FARFAR 60daee5674 Add mape and msle objectives to the documentation 2015-07-04 15:24:24 +01:00
Kheir Eddine FARFAR 47fd945cf1 Add MAPE objective 2015-07-04 15:16:52 +01:00
fchollet 66b8f37175 Complete working version of graphs. API needs work 2015-07-04 00:50:24 -07:00
fchollet f1cd436574 Fixes in models, callbacks 2015-07-03 23:43:19 -07:00
fchollet f30223096e merge 2015-07-03 22:43:34 -07:00
fchollet 76b9877ccb Add MSLE objective 2015-07-03 18:04:15 -07:00
fchollet 243d4737d1 Better API for Convolution1D and MaxPooling1D 2015-07-03 15:59:25 -07:00
fchollet 9e4e432822 Merge branch 'pranv-master' 2015-07-03 11:31:27 -07:00
fchollet c7c5372509 Style fixes 2015-07-03 11:31:03 -07:00
fchollet 2baa9a8e57 Merge branch 'master' of https://github.com/pranv/keras into pranv-master 2015-07-03 11:12:21 -07:00
fchollet e63644cf82 Fix denoising autoencoder issue 2015-07-03 11:08:29 -07:00
Pranav Shyam af0899ded7 Added LRN, Convolution with Strides and ZeroPadding2D 2015-07-03 11:53:47 +05:30
fchollet a5f4bd33c9 Merge branch 'master' of https://github.com/fchollet/keras 2015-07-02 22:54:41 -07:00
fchollet 522201ec9e Add test utils 2015-07-02 22:54:27 -07:00
François Chollet 506aaf1721 Merge pull request #328 from samuela/patch-1
Fix parenthesis typo in examples.md
2015-07-02 22:12:21 -07:00
fchollet 8e1e32a906 Fix tests 2015-07-02 22:11:46 -07:00
fchollet 0332b95cdf Remove check in binary_crossentropy 2015-07-02 21:53:12 -07:00
fchollet f53c3195e7 Merge branch 'master' of https://github.com/fchollet/keras 2015-07-02 21:47:25 -07:00
fchollet 940bd47bc9 Add test_loss_weighting 2015-07-02 21:47:10 -07:00
fchollet ee730496ee Add test_tasks 2015-07-02 21:45:31 -07:00
fchollet 06d7c7dab2 Strict handling of incorrect dims in binary_xent 2015-07-02 21:44:57 -07:00
samuela 91d86c355b Fix parenthesis typo in examples.md 2015-07-02 21:17:19 -04:00
François Chollet 98f055074c Merge pull request #327 from tleeuwenburg/master
New pull request -- much cleaner
2015-07-02 17:48:27 -07:00
fchollet bba5379305 Fix constraint tests 2015-07-02 17:47:12 -07:00
Thomas McColgan acef252703 change constraints tests to new constraint api 2015-07-03 10:01:44 +10:00
Thomas McColgan 514ac06c2e missing axis parameter 2015-07-03 10:01:44 +10:00
Thomas McColgan f184db8c53 add exotic inputs to identity test 2015-07-03 10:01:43 +10:00
Thomas McColgan d59f2519fa make some texts a bit more explicit 2015-07-03 10:01:43 +10:00
Thomas McColgan 4956ed9e97 small PEP-8 changes 2015-07-03 10:01:43 +10:00
Thomas McColgan b48e39aafd Add a test for the identity, non-negative, and unit-norm constraints 2015-07-03 10:01:43 +10:00
Thomas McColgan a808ae6ff8 Add a test for the max-norm constraint 2015-07-03 10:01:43 +10:00
fchollet 2805413653 Merge branch 'master' of https://github.com/fchollet/keras 2015-07-02 15:22:18 -07:00
fchollet 2d5b86d7a8 Merge branch 'mthrok-master' 2015-07-02 15:21:57 -07:00
fchollet 12a5c6fe46 Touch-ups in IRNN example 2015-07-02 15:21:37 -07:00
fchollet e50462e71f Merge branch 'master' of https://github.com/mthrok/keras into mthrok-master 2015-07-02 13:50:00 -07:00
François Chollet 2f98bed389 Merge pull request #325 from phreeza/patch-2
Fix unitnorm to be a class, like other constraints
2015-07-02 13:02:29 -07:00
Thomas McColgan 24be9eb88b Fix unitnorm to be a class, like other constraints
brought to you by unittests
2015-07-02 21:29:50 +02:00
François Chollet e15f722558 Merge pull request #323 from wxs/None-on-embedding
Return None when not masking Embedding.
2015-07-02 10:13:20 -07:00
Xavier Snelgrove c9fd2c8a8c Add some clarification comments. 2015-07-02 12:55:58 -04:00
Xavier Snelgrove 42497d9fda Return None when not masking Embedding.
Embedding is supposed to return None for its mask when it's not in
masking mode.
2015-07-02 12:44:55 -04:00
fchollet 278618281c Fix masking issue 2015-07-01 21:32:57 -07:00
Moto H 4ae4c9c8df Corrected execution time 2015-07-02 09:24:09 +09:00
Moto H 89ad3c726c Changed #epochs 2015-07-02 09:02:27 +09:00
Moto H 3af4d2fd33 Added IRNN example. 2015-07-02 08:55:06 +09:00
fchollet a4329aa4b0 Merge branch 'master' of https://github.com/fchollet/keras 2015-06-30 20:03:23 -07:00
fchollet 24df6a9f9b Fix weights in model.test 2015-06-30 20:03:11 -07:00
fchollet 560cb94519 Callback refactor 2015-06-30 17:59:34 -07:00
fchollet 2ab9f0ef61 Add working Graph container 2015-06-30 17:59:19 -07:00
fchollet d148ff11c2 Initial draft of Graph container 2015-06-29 22:26:57 -07:00
François Chollet 256a908250 Merge pull request #301 from ameasure/patch-1
Update convolutional.md
2015-06-29 16:26:59 -07:00
Alexander Measure 11d3335dcc Update convolutional.md
Changed documentation of subsample parameter to match implementation.
2015-06-29 19:10:21 -04:00
François Chollet 1b7ce160e2 Merge pull request #297 from wxs/pre-truncation
Support truncation off beginning of sequence
2015-06-29 14:17:22 -07:00
fchollet c7aac3ce39 ones as default init for LSTM forget gate bias 2015-06-29 14:14:05 -07:00
Xavier Snelgrove 7e06995678 Support truncation off beginning of sequence 2015-06-29 11:57:40 -04:00
fchollet ce659e568b Fix check for mask 2015-06-29 06:02:02 -07:00
fchollet e8a6ae298d Fix regularization in Embedding 2015-06-29 05:07:37 -07:00
fchollet e3d3d62218 Update doc with sample_weight and class_weight 2015-06-28 18:01:30 -07:00
fchollet 877d44740c Merge branch 'master' of https://github.com/fchollet/keras 2015-06-28 17:54:29 -07:00
fchollet cc9edcf472 Fix merge conflicts, add class_weight support 2015-06-28 17:50:42 -07:00
fchollet 5e5bff0510 Simplify IMDB example 2015-06-28 17:09:54 -07:00
François Chollet bc4e47e689 Merge pull request #290 from stonebig/master
create .keras/models dir if needed
2015-06-28 10:53:28 -07:00
stonebig d9357646e2 create keras directories if needed
solves #289
2015-06-28 10:53:36 +02:00
fchollet c4735f59c4 Doc touch-ups 2015-06-27 23:52:03 -07:00
fchollet 3af40ba584 Fix typo in doc 2015-06-27 20:35:16 -07:00
fchollet 36e5a17b29 Update docs 2015-06-27 20:31:09 -07:00
fchollet cbde35fdf5 Improve API of ActivityRegularization 2015-06-27 20:31:03 -07:00
fchollet 76b28524d1 Remove image_shape in conv layers 2015-06-27 20:29:27 -07:00
fchollet 090ada4e77 Fix mkdocs.yml 2015-06-27 20:29:07 -07:00
fchollet 8ef90a03b3 Switch convolutional layers to new regularization 2015-06-27 15:43:49 -07:00
fchollet f04fdec9e6 Incorporate regularization into loss function 2015-06-27 15:39:32 -07:00
fchollet 0d6575c7f9 Merge branch 'master' of https://github.com/fchollet/keras 2015-06-27 13:42:51 -07:00
fchollet cc750adf60 Merge branch 'phreeza-activity_reg' 2015-06-27 13:42:21 -07:00
fchollet 752037c140 Remove loss_update system 2015-06-27 13:42:00 -07:00
fchollet ba11d9ca75 Restore callbacks in fit 2015-06-27 13:30:48 -07:00
fchollet 499a05003b Fix regularisers/constraints tests 2015-06-27 13:30:21 -07:00
fchollet c9addefa28 Simplify regularizers 2015-06-27 13:30:01 -07:00
fchollet 0f12e0119b Switch constraints to OO model 2015-06-27 13:29:48 -07:00
fchollet 4d267f5ba3 Remove manual check for regularizers (use auto) 2015-06-27 13:29:29 -07:00
fchollet 5719322573 Merge branch 'activity_reg' of https://github.com/phreeza/keras into phreeza-activity_reg 2015-06-27 13:02:13 -07:00
fchollet 5b6f56a040 Add mask support to new recurrent layers 2015-06-27 13:01:27 -07:00
François Chollet 3e08814118 Merge pull request #280 from tleeuwenburg/master
Added unit test, travis file
2015-06-26 18:13:59 -07:00
fchollet 9c8e0d43f3 Add support for custom padding value in sequence 2015-06-26 17:44:56 -07:00
fchollet ea0b7d263c Add text dataset support for OOV, start chars 2015-06-26 17:44:21 -07:00
fchollet 99c20e25c9 Make sure key examples are deterministic 2015-06-26 17:41:13 -07:00
fchollet 2abb4b2316 Merge branch 'the-moliver-patch-1' 2015-06-26 15:25:44 -07:00
fchollet 0d6c55d5f0 Style touch-ups 2015-06-26 15:25:30 -07:00
fchollet 45e444cc63 Code style fixes 2015-06-26 15:21:45 -07:00
fchollet 5d1976c46d Update IMDB example 2015-06-26 15:21:10 -07:00
Michael Oliver 3ff19e2a62 Fix memory leak
The scan in get_output TimeDistributedDense leaked memory like crazy. Changing it to match get_output in Dense seems to have fixed the problem and behaves identically.
2015-06-26 14:53:52 -07:00
Thomas McColgan 95a363f3d8 Revert "Make merge layer work with a single model, turning it into a container layer."
This reverts commit f4df2240c1.
2015-06-26 23:16:54 +02:00
fchollet 3995b18f43 Merge branch 'mask_value' of https://github.com/wxs/keras into wxs-mask_value 2015-06-26 14:13:06 -07:00
Xavier Snelgrove d57206dfd9 Disregard objective output dimensions when weighting
Binary cross-entropy and categorical cross-entropy give differently
shaped results, which used to not matter since mean() ignored the shape
2015-06-26 17:09:25 -04:00
Thomas McColgan 71787762db Revert "Add an Autoencoder model and a test to go with it."
This reverts commit 12f7f374c3.

Conflicts:
	keras/models.py
2015-06-26 22:59:15 +02:00
Thomas McColgan da20a4ccd2 remove a remaining instance of old naming 2015-06-26 22:57:37 +02:00
fchollet 90c4edefd3 Merge branch 'mask_value' of https://github.com/wxs/keras into wxs-mask_value 2015-06-26 12:32:36 -07:00
Xavier Snelgrove ad99af7be7 Force mask type to int8 for GPU 2015-06-26 12:00:21 -04:00
Thomas McColgan aaceb11b9e change custom regularizer in autoencoder to 2015-06-26 09:24:51 +02:00
Thomas McColgan 7d7085d523 Further simplification of Regularizer code (dropped flags entirely) 2015-06-26 09:23:26 +02:00
Thomas McColgan 33ca877821 Merge branch 'master' into activity_reg
Conflicts:
	keras/models.py
2015-06-26 09:18:37 +02:00
Tennessee Leeuwenburg 15055483ff Added a docstring to the linear activation function about input checking.
Added some more unit tests
2015-06-26 17:01:09 +10:00
Thomas McColgan c3d90020fc change semantics of Regularizer class to reduce external control flow 2015-06-26 08:50:11 +02:00
Thomas McColgan ed8448df7b Merge branch 'master' of https://github.com/phreeza/keras
Conflicts:
	keras/models.py
2015-06-26 08:30:55 +02:00
Tennessee Leeuwenburg 81822d3e52 Updated test to reflect new return type (list rather than list-of-list)
Added a test for the linear function
2015-06-26 12:37:00 +10:00
Tennessee Leeuwenburg 7a6cec902e Merge branch 'master' of https://github.com/fchollet/keras 2015-06-26 12:25:53 +10:00
Tennessee Leeuwenburg 37e3ffed85 Deleted superfluous test file
Added basic softmax activation test
2015-06-26 12:12:29 +10:00
fchollet 7fafc8ec9d Merge branch 'master' of https://github.com/fchollet/keras 2015-06-25 16:37:07 -07:00
fchollet 91aa190ceb Merge branch 'transcranial-RNN-MUT' 2015-06-25 16:35:57 -07:00
Xavier Snelgrove 4eb8346df5 Handle previous properly, rename things for clarity 2015-06-25 16:27:15 -04:00
Thomas McColgan 9083dd088d add execution lines to unit test 2015-06-25 21:30:29 +02:00
Leon Chen 4e78c9e758 add theano floatX dtype 2015-06-25 15:19:34 -04:00
Leon Chen 93ff2240f3 use sparse random projections for dimensionality changes 2015-06-25 15:03:43 -04:00
Thomas McColgan 867253e5d8 rename cost to loss 2015-06-25 20:53:50 +02:00
Xavier Snelgrove 31a303c38f Remove unused import 2015-06-25 14:10:25 -04:00
Xavier Snelgrove e1a39b80a9 Some code linting 2015-06-25 14:09:27 -04:00
Xavier Snelgrove 1564343c6e Didn't always initialize weight_val 2015-06-25 13:50:47 -04:00
Xavier Snelgrove 62392a4b5e Switch to better masking scheme.
Layers now have get_input_mask() and get_output_mask() functions
which you can use to get an int8 array representing which data
is masked.
2015-06-25 13:44:45 -04:00
Leon Chen 11685f68d5 relax input_dim == output_dim constraint with matrix multiplication, and rename MutatedRNN to JZS 2015-06-25 10:21:39 -04:00
Thomas McColgan b4c7aded69 fix file format 2015-06-25 14:07:12 +02:00
Thomas McColgan 182c827433 move manual text/check to appropriate location 2015-06-25 14:03:07 +02:00
Thomas McColgan 59e345501e refactored regularizers to be objects of a given class 2015-06-25 13:25:03 +02:00
Thomas McColgan 56e09ad736 add tests for regularizers 2015-06-25 11:39:47 +02:00
François Chollet 4d39c08c42 Merge pull request #277 from pdermyer/mergefix
Fixed Merge handling of overlapping Models.
2015-06-24 13:16:27 -07:00
Xavier Snelgrove 4962f18857 Move the objective-weighting decorator out of get() 2015-06-24 15:09:26 -04:00
Xavier Snelgrove 11e961fdf8 Introduce weighting of labels.
This changes objective functions to no longer return scalars, but
rather tensors of dimension one less than y, representing the loss for
each datapoint in y, on which it is expected you will calculate a weighted mean.
2015-06-24 14:58:58 -04:00
pdermyer 413663f03f Fixed Merge handling of overlapping Models. 2015-06-24 11:18:32 -07:00
Xavier Snelgrove 433f56f35d Merge remote-tracking branch 'origin/master' into mask_value 2015-06-24 11:37:58 -04:00
Leon Chen 6420c59f1b update docs 2015-06-24 11:29:47 -04:00
Leon Chen c35780557e implement MUT1, MUT2, MUT3 recurrent NN architectures from Jozefowicz et al 2015 2015-06-24 11:29:28 -04:00
François Chollet 4ba83caef2 Merge pull request #275 from transcranial/init-identity-mat
add identity matrix initialization
2015-06-23 17:24:52 -07:00
Leon Chen 13715c49c3 add identity matrix initialization 2015-06-23 19:16:16 -04:00
Xavier Snelgrove 7ef71ec944 Add mask_val to get_config() 2015-06-23 18:13:18 -04:00
fchollet 4e19cd29c9 Merge branch 'amitbeka-get_from_module_unicode_fix' 2015-06-23 10:51:28 -07:00
fchollet 1d02231a49 Merge branch 'get_from_module_unicode_fix' of https://github.com/amitbeka/keras into amitbeka-get_from_module_unicode_fix 2015-06-23 10:48:16 -07:00
François Chollet 333e85f6b1 Merge pull request #266 from d0ugal/master
Updated the MkDocs config from the deprecated format
2015-06-23 10:35:05 -07:00
fchollet 6d82ba75c9 Merge branch 'wxs-remove-time-distributed-softmax' 2015-06-23 10:22:15 -07:00
fchollet 135dccfeea Coding style 2015-06-23 10:22:03 -07:00
fchollet 4c5f8e364c merge 2015-06-23 10:16:50 -07:00
fchollet 515c430f43 Merge autoencoder fix 2015-06-23 10:07:46 -07:00
fchollet 8a2ae93ba7 Improve autoencoder check 2015-06-23 10:01:50 -07:00
Xavier Snelgrove 4c3495896e Remove time_distributed_softmax in favour of softmax
There is no reason to have two different functions for this! The softmax
function can just be configured to always perform the softmax across the
trailing dimension (i.e. nb_dimensions)
2015-06-23 12:24:08 -04:00
Xavier Snelgrove 86a9445ffd Remove mask_val from time_distributed_softmax 2015-06-23 12:04:03 -04:00
Xavier Snelgrove 271e2b7f84 Add masking support to the activation layer 2015-06-23 12:00:03 -04:00
Julien Rebetez ce6728d9ce Make Autoencoder.connect call encoder.connect(). This fixes
a DisconnectedInputError if the encoder is a containers.Sequential
instance.
2015-06-23 14:33:06 +02:00
Thomas McColgan 85c915bd7e Merge branch 'master' of https://github.com/fchollet/keras into activity_reg
Conflicts:
	keras/models.py
2015-06-23 13:08:15 +02:00
Dougal Matthews 2603b95c8c Updated the MkDocs config from the deprecated format 2015-06-23 09:14:21 +01:00
Amit Beka d9e76bdeca fix to support python3
Signed-off-by: Amit Beka <amit.beka@gmail.com>
2015-06-23 05:53:53 +00:00
Tennessee Leeuwenburg 28285ceda7 Merge branch 'master' of https://github.com/fchollet/keras 2015-06-23 14:15:47 +10:00
Stephen Merity be22591e32 Decrease memory usage of LSTM text gen example
Both the training features and labels can be represented as numpy
booleans instead of float32 / float64. This enables standard low RAM
machines to scale up to large datasets. Especially important if you
either have many characters (ASCII), long sequences, or a large dataset.
2015-06-23 14:03:32 +10:00
fchollet a9f94c94a7 Revert loss weighting 2015-06-23 14:03:32 +10:00
fchollet 155369711c Update gitignore 2015-06-23 14:03:31 +10:00
fchollet 3dd4b2e8ab Rename test folder 2015-06-23 14:03:31 +10:00
fchollet a1912b0774 Rename lossweights test 2015-06-23 14:03:31 +10:00
François Chollet 99cdd12bf7 Merge pull request #264 from Smerity/master
Decrease memory usage of LSTM text gen example
2015-06-22 17:32:28 -07:00
Xavier Snelgrove 2384aa4c97 Add masking to time_distributed_softmax 2015-06-22 17:33:44 -04:00
Stephen Merity b9fbc458ed Decrease memory usage of LSTM text gen example
Both the training features and labels can be represented as numpy
booleans instead of float32 / float64. This enables standard low RAM
machines to scale up to large datasets. Especially important if you
either have many characters (ASCII), long sequences, or a large dataset.
2015-06-22 14:24:46 -07:00
Xavier Snelgrove e3519221b4 Add masking to GRU and LSTM 2015-06-22 16:44:01 -04:00
Xavier Snelgrove 3f3a1f0e9b Remove redundant masking in _step 2015-06-22 15:49:53 -04:00
Xavier Snelgrove 852f5d977f TimeDistributedDense masking 2015-06-22 15:41:45 -04:00
Xavier Snelgrove a1ab9769ec Rename test to check as per new convention 2015-06-22 15:12:02 -04:00
Xavier Snelgrove ef4250fc05 Move recurrent mask tests into new directory layout 2015-06-22 15:05:01 -04:00
Xavier Snelgrove 76328bedd1 Merge remote-tracking branch 'origin/master' into mask_value 2015-06-22 14:45:48 -04:00
fchollet f8ee81d89e Revert loss weighting 2015-06-22 11:39:22 -07:00
Xavier Snelgrove 83419e644f Dropout masking 2015-06-22 14:16:48 -04:00
Amit Beka c274cb990b utils/generic_utils: fix unicode strings problem
in get_from_module(), a unicode identifier should be treated as a str
type.

Signed-off-by: Amit Beka <amit.beka@gmail.com>
2015-06-22 13:31:03 +00:00
Thomas McColgan b0b3ff13b0 Update models.py 2015-06-22 09:38:45 +02:00
fchollet 384634d321 Update gitignore 2015-06-21 16:05:55 -07:00
Tennessee Leeuwenburg 3e0b09e819 Updated script name 2015-06-22 07:53:32 +10:00
Tennessee Leeuwenburg e0f58c976b Try anaconda with travis 2015-06-22 07:45:23 +10:00
fchollet dd82a3944e Rename test folder 2015-06-21 12:00:57 -07:00
fchollet 9763f81185 Rename lossweights test 2015-06-21 11:54:25 -07:00
François Chollet ae13539a88 Merge pull request #256 from tleeuwenburg/master
Simple refactor of directories to support auto testing
2015-06-21 11:10:10 -07:00
Tennessee Leeuwenburg cbcb3b96ef Added travis file 2015-06-21 20:40:51 +10:00
Tennessee Leeuwenburg 0a21abc810 Rename a manual test to a check 2015-06-21 20:08:54 +10:00
Tennessee Leeuwenburg 1fc3c4b22e Renamed non-automatable tests as "checks"
Moved tests into either manual or auto subdirectories.
2015-06-21 20:06:36 +10:00
fchollet 5a1a00e69e Add RemoteMonitor callback 2015-06-20 19:32:28 -07:00
fchollet 97f23268c2 Refactor test_lossweights into unit test 2015-06-20 17:09:08 -07:00
fchollet fd5b68dbe3 Fix Python3 issue with class_weight 2015-06-20 16:53:57 -07:00
fchollet ac0a9db039 Merge 2015-06-20 15:32:45 -07:00
fchollet 1d586440a8 Rewrite class_weight and sample_weight tests 2015-06-20 15:30:18 -07:00
fchollet b44ecab225 Make RNG deterministic when seeded through numpy 2015-06-20 15:29:40 -07:00
fchollet 34cbc1d401 Merge branch 'instance_weight' of https://github.com/tdhd/keras into tdhd-instance_weight 2015-06-20 14:46:40 -07:00
fchollet 0e6fd3d306 Update callbacks documentation 2015-06-19 16:36:00 -07:00
fchollet ccbe381dcd Add early stopping 2015-06-19 16:31:06 -07:00
fchollet 1f224de9b1 Fix callbacks doc 2015-06-19 15:38:53 -07:00
fchollet e23e86ae7a Improve examples, add new MNIST CNN example 2015-06-19 15:38:33 -07:00
fchollet 06f22db69a Up the batch size in MNIST example 2015-06-19 12:52:43 -07:00
Philipp 824f9f5e80 refactored weighting in models.py 2015-06-19 21:30:23 +02:00
Xavier Snelgrove a12510ba97 Remove mask_value application from _step
I realized that it makes more sense to have _step *apply* a mask, but
then to set the masked entries to mask_value outside of step. This
should be more efficient, but more importantly should make
implementations easier to understand.

Another nice effect: an alternative masking scheme can be introduced
without changing _step at all.
2015-06-19 15:06:57 -04:00
Xavier Snelgrove c13154933e Remove some outdated comments from test 2015-06-19 13:45:56 -04:00
Xavier Snelgrove 981d23a66e Introduce masking to SimpleDeepRNN 2015-06-19 13:41:27 -04:00
Xavier Snelgrove 7278db105d Pass historical masks using the taps of scan
I did not previously know about Theano's "taps" concept.
2015-06-19 11:32:22 -04:00
Philipp 1b9f35f535 added tests for sample weight 2015-06-19 09:40:50 +02:00
Philipp c4f0f8b394 renamed instance weight to sample weight 2015-06-19 09:40:38 +02:00
Xavier Snelgrove d7a612bb8c Was incorrectly fixing the masked weights in Embedding
This led me to realize that I also was not properly passing masks out of
recurrent layers, nor were my tests properly checking for this. I've
resolved this here.
2015-06-19 01:07:35 -04:00
Xavier Snelgrove a8f1a6a11b Was not properly setting the mask row. 2015-06-18 22:08:17 -04:00
Xavier Snelgrove bde9ff8232 By default Embeddings don't have a mask 2015-06-18 21:58:51 -04:00
Xavier Snelgrove 32c507eaf8 Fix for the GPU again 2015-06-18 17:55:21 -04:00
Xavier Snelgrove 36676451c9 Was calculating the mask on transformed x, not X. 2015-06-18 17:41:49 -04:00
Xavier Snelgrove e369559170 Mis-set first value of mask at t-1 2015-06-18 17:34:00 -04:00
Xavier Snelgrove 7f445d9a21 Properly mask inputs from t-1 in recurrent net 2015-06-18 17:28:29 -04:00
Xavier Snelgrove 4cc03dd4ef Missed a bit of whitespace 2015-06-18 17:07:51 -04:00
Xavier Snelgrove 2727198f94 Whitespace changes for readability 2015-06-18 16:59:58 -04:00
Xavier Snelgrove 88b0c8e067 Added .swp files to the gitignore for Vim users 2015-06-18 16:58:34 -04:00
Xavier Snelgrove a75a31381e Added a concept of masking by value to the SimpleRNN 2015-06-18 16:27:30 -04:00
fchollet d550232458 Merge branch 'master' of https://github.com/fchollet/keras 2015-06-18 11:26:24 -07:00
fchollet 6329378ca3 Make pre-padding the default in sequence tensors 2015-06-18 11:26:11 -07:00
Philipp b3402f5011 renamed test file for class weights 2015-06-18 17:09:59 +02:00
Philipp 4cfb5d7971 added instance weight implementation 2015-06-18 17:04:28 +02:00
Thomas McColgan a51d7ae145 typo 2015-06-18 17:01:05 +02:00
Thomas McColgan bd361595be make l1 norm actually be an l1 norm. doh! 2015-06-18 16:43:28 +02:00
Thomas McColgan 668eeebdda Merge branch 'master' of https://github.com/fchollet/keras into activity_reg
Conflicts:
	keras/models.py
2015-06-18 14:47:23 +02:00
Thomas McColgan cf49d59aff add a test for activity regulrisation 2015-06-18 14:41:10 +02:00
Thomas McColgan 31a6ee342b make cost updates propagate all the way, even if layer input is unknown at instantiation 2015-06-18 14:40:46 +02:00
Thomas McColgan fecedb02cf add cost update member to layer 2015-06-18 10:58:38 +02:00
François Chollet 8e5cdd1689 Merge pull request #238 from jfsantos/patch-1
Fix typo
2015-06-17 11:13:11 -07:00
João Felipe Santos 45775e36b1 Fix typo 2015-06-17 14:11:13 -04:00
François Chollet 4830b4be27 Merge pull request #188 from tdhd/classweights
Add support for class_weight in fit
2015-06-17 10:25:34 -07:00
fchollet 702e9d3bec Merge branch 'master' of https://github.com/fchollet/keras 2015-06-16 22:53:13 -07:00
fchollet 1857a6af5e Improve LSTM text generation example 2015-06-16 22:52:06 -07:00
François Chollet 4b065a28a0 Merge pull request #234 from iskandr/master
Added Convolution1D and MaxPooling1D to layers documentation
2015-06-16 13:28:52 -07:00
Alex Rubinsteyn 33334883fa Added Convolution1D and MaxPooling1D to layers documentation 2015-06-16 12:58:52 -04:00
Philipp 2165fd03dc updated testcase for class weights 2015-06-16 11:03:30 +02:00
fchollet 872a9faf18 Fix printing for Python2 in LSTM example 2015-06-15 17:54:59 -07:00
fchollet d2b229df2e Add LSTM text generation example 2015-06-15 17:43:25 -07:00
Philipp 35c2f36759 moved weight multiplication outside of T.max 2015-06-15 15:20:33 +02:00
Philipp 24d735ecb1 merge master 2015-06-15 11:49:09 +02:00
Philipp 8c93ba860a objectives now reshape weight vector to match dims 2015-06-15 11:48:30 +02:00
fchollet bf4822f675 Fix autoencoder issue 2015-06-14 20:58:53 -07:00
Philipp ed6e351953 merge master 2015-06-14 23:10:34 +02:00
Philipp 368ad61236 removed unnecessary check in fit/train 2015-06-14 23:09:06 +02:00
Philipp 829b7ab289 fixed error in binary crossentropy obj 2015-06-14 23:04:37 +02:00
fchollet ce20955379 Update setup.py 2015-06-13 17:54:33 -07:00
fchollet fabfdb868e Remove long_description from setup.py 2015-06-13 17:51:51 -07:00
fchollet b82ab804da Update setup.py and setup.cfg for pypi release 2015-06-13 17:26:18 -07:00
Philipp 0a10e20959 merge master 2015-06-13 00:52:41 +02:00
Philipp ffeefb2a1b update test verbosity 2015-06-09 11:02:42 +02:00
Philipp eb33c9a18c updated branch 2015-06-09 10:53:31 +02:00
Philipp 39f05c3436 check for incompatible combination of parameters in fit/train 2015-06-08 09:52:58 +02:00
Philipp c0b7044ce6 add weight to (squared) hinge 2015-06-08 09:36:36 +02:00
Philipp bde147ce3a revert objective changes 2015-06-08 09:33:31 +02:00
Philipp d6eb8a47d7 add weight to all objective functions 2015-06-08 09:30:53 +02:00
Philipp 206f29ea6e fixed calculate_class_weights where it would yield an np-array with shape[1] == 1 which is not mappable. binary crossentropy adapted with weights. 2015-06-06 00:49:00 +02:00
Philipp a6824931e4 moved calculate_class_weights outside of model class 2015-06-05 21:47:32 +02:00
Philipp 7bcc4cb257 added documentation for classweights and a test 2015-06-03 17:39:34 +02:00
Philipp a4af21d588 added class weights to the Model class and one of the objective functions as an optional parameter 2015-06-03 17:39:11 +02:00
Thomas McColgan 12f7f374c3 Add an Autoencoder model and a test to go with it. 2015-05-25 17:17:58 +02:00
Thomas McColgan f4df2240c1 Make merge layer work with a single model, turning it into a container layer. 2015-05-25 17:16:05 +02:00
112 arquivos alterados com 11103 adições e 3177 exclusões
+6 -1
Ver Arquivo
@@ -1,6 +1,11 @@
*.DS_Store
*.pyc
*.swp
temp/*
dist/*
build/*
keras/datasets/data/*
keras/datasets/temp/*
keras/datasets/temp/*
docs/site/*
docs/theme/*
tags
+42
Ver Arquivo
@@ -0,0 +1,42 @@
sudo: required
dist: trusty
language: python
python:
- "2.7"
- "3.4"
install:
# code below is taken from http://conda.pydata.org/docs/travis.html
# We do this conditionally because it saves us some downloading if the
# version is the same.
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
wget https://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh;
else
wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
fi
- bash miniconda.sh -b -p $HOME/miniconda
- export PATH="$HOME/miniconda/bin:$PATH"
- hash -r
- conda config --set always_yes yes --set changeps1 no
- conda update -q conda
# Useful for debugging any issues with conda
- conda info -a
- conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION numpy scipy matplotlib pandas pytest h5py
- source activate test-environment
- pip install pytest-cov python-coveralls
- pip install git+git://github.com/Theano/Theano.git
- python setup.py install
# install TensorFlow
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
pip install https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.5.0-cp27-none-linux_x86_64.whl;
fi
# command to run tests
script:
- PYTHONPATH=$PWD:$PYTHONPATH py.test -v --cov-report term-missing --cov keras tests/
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
sed -i -e 's/theano/tensorflow/g' ~/.keras/keras.json;
PYTHONPATH=$PWD:$PYTHONPATH py.test -v --cov-report term-missing --cov keras tests/;
fi
after_success:
- coveralls
+19 -2
Ver Arquivo
@@ -1,6 +1,23 @@
The MIT License (MIT)
COPYRIGHT
Copyright (c) 2015
All contributions by François Chollet:
Copyright (c) 2015, François Chollet.
All rights reserved.
All contributions by Google:
Copyright (c) 2015, Google, Inc.
All rights reserved.
All other contributions:
Copyright (c) 2015, the respective contributors.
All rights reserved.
Each contributor holds copyright over their respective contributions.
The project versioning (Git) records all such contribution source information.
LICENSE
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+118 -152
Ver Arquivo
@@ -1,209 +1,175 @@
# Keras: Theano-based Deep Learning library
# Keras: Deep Learning library for Theano and TensorFlow
## You have just found Keras.
Keras is a minimalist, highly modular neural network library in the spirit of Torch, written in Python / Theano so as not to have to deal with the dearth of ecosystem in Lua. It was developed with a focus on enabling fast experimentation. Being able to go from idea to result with the least possible delay is key to doing good research.
Keras is a minimalist, highly modular neural networks library, written in Python and capable of running either on top of either [TensorFlow](https://github.com/tensorflow/tensorflow) or [Theano](https://github.com/Theano/Theano). It was developed with a focus on enabling fast experimentation. Being able to go from idea to result with the least possible delay is key to doing good research.
Use Keras if you need a deep learning library that:
- allows for easy and fast prototyping (through total modularity, minimalism, and extensibility).
- supports both convolutional networks (for vision) and recurrent networks (for sequence data). As well as combinations of the two.
- runs seamlessly on the CPU and the GPU.
- supports both convolutional networks and recurrent networks, as well as combinations of the two.
- supports arbitrary connectivity schemes (including multi-input and multi-output training).
- runs seamlessly on CPU and GPU.
Read the documentation at [Keras.io](http://keras.io).
Keras is compatible with __Python 2.7-3.4__.
Keras is compatible with:
- __Python 2.7-3.5__ with the Theano backend
- __Python 2.7__ with the TensorFlow backend
------------------
## Guiding principles
- __Modularity.__ A model is understood as a sequence of standalone, fully-configurable modules that can be plugged together with as little restrictions as possible. In particular, neural layers, cost functions, optimizers, initialization schemes, activation functions and dropout are all standalone modules that you can combine to create new models.
- __Modularity.__ A model is understood as a sequence or a graph of standalone, fully-configurable modules that can be plugged together with as little restrictions as possible. In particular, neural layers, cost functions, optimizers, initialization schemes, activation functions, regularization schemes are all standalone modules that you can combine to create new models.
- __Minimalism.__ Each module should be kept short and simple (<100 lines of code). Every piece of code should be transparent upon first reading. No black magic: it hurts iteration speed and ability to innovate.
- __Minimalism.__ Each module should be kept short and simple. Every piece of code should be transparent upon first reading. No black magic: it hurts iteration speed and ability to innovate.
- __Easy extensibility.__ New features (a new module, per the above definition, or a new way to combine modules together) are dead simple to add (as new classes/functions), and existing modules provide ample examples.
- __Easy extensibility.__ New modules are dead simple to add (as new classes and functions), and existing modules provide ample examples. To be able to easily create new modules allows for total expressiveness, making Keras suitable for advanced research.
- __Work with Python__. No separate models configuration files in a declarative format (like in Caffe or PyLearn2). Models are described in Python code, which is compact, easier to debug, benefits from syntax highlighting, and most of all, allows for ease of extensibility. See for yourself with the examples below.
- __Work with Python__. No separate models configuration files in a declarative format. Models are described in Python code, which is compact, easier to debug, and allows for ease of extensibility.
## Examples
### Multilayer Perceptron (MLP):
------------------
## Getting started: 30 seconds to Keras
The core datastructure of Keras is a __model__, a way to organize layers. There are two types of models: [`Sequential`](/models/#sequential) and [`Graph`](/models/#graph).
Here's the `Sequential` model (a linear pile of layers):
```python
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
model = Sequential()
```
Stacking layers is as easy as `.add()`:
```python
from keras.layers.core import Dense, Activation
model.add(Dense(output_dim=64, input_dim=100, init="glorot_uniform"))
model.add(Activation("relu"))
model.add(Dense(output_dim=10, init="glorot_uniform"))
model.add(Activation("softmax"))
```
Once your model looks good, configure its learning process with `.compile()`:
```python
model.compile(loss='categorical_crossentropy', optimizer='sgd')
```
If you need to, you can further configure your optimizer. A core principle of Keras is to make things reasonably simple, while allowing the user to be fully in control when they need to (the ultimate control being the easy extensibility of the source code).
```python
from keras.optimizers import SGD
model = Sequential()
model.add(Dense(20, 64, init='uniform'))
model.add(Activation('tanh'))
model.add(Dropout(0.5))
model.add(Dense(64, 64, init='uniform'))
model.add(Activation('tanh'))
model.add(Dropout(0.5))
model.add(Dense(64, 2, init='uniform'))
model.add(Activation('softmax'))
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='mean_squared_error', optimizer=sgd)
model.fit(X_train, y_train, nb_epoch=20, batch_size=16)
score = model.evaluate(X_test, y_test, batch_size=16)
model.compile(loss='categorical_crossentropy', optimizer=SGD(lr=0.01, momentum=0.9, nesterov=True))
```
### Alternative implementation of MLP:
You can now iterate on your training data in batches:
```python
model = Sequential()
model.add(Dense(20, 64, init='uniform', activation='tanh'))
model.add(Dropout(0.5))
model.add(Dense(64, 64, init='uniform', activation='tanh'))
model.add(Dropout(0.5))
model.add(Dense(64, 2, init='uniform', activation='softmax'))
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='mean_squared_error', optimizer=sgd)
model.fit(X_train, Y_train, nb_epoch=5, batch_size=32)
```
### VGG-like convnet:
Alternatively, you can feed batches to your model manually:
```python
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.optimizers import SGD
model = Sequential()
model.add(Convolution2D(32, 3, 3, 3, border_mode='full'))
model.add(Activation('relu'))
model.add(Convolution2D(32, 32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
model.add(Dropout(0.25))
model.add(Convolution2D(64, 32, 3, 3, border_mode='full'))
model.add(Activation('relu'))
model.add(Convolution2D(64, 64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(64*8*8, 256))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(256, 10))
model.add(Activation('softmax'))
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)
model.fit(X_train, Y_train, batch_size=32, nb_epoch=1)
model.train_on_batch(X_batch, Y_batch)
```
### Sequence classification with LSTM:
Evaluate your performance in one line:
```python
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.layers.embeddings import Embedding
from keras.layers.recurrent import LSTM
model = Sequential()
model.add(Embedding(max_features, 256))
model.add(LSTM(256, 128, activation='sigmoid', inner_activation='hard_sigmoid'))
model.add(Dropout(0.5))
model.add(Dense(128, 1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='rmsprop')
model.fit(X_train, Y_train, batch_size=16, nb_epoch=10)
score = model.evaluate(X_test, Y_test, batch_size=16)
objective_score = model.evaluate(X_test, Y_test, batch_size=32)
```
### Architecture for learning image captions with a convnet and a Gated Recurrent Unit:
(word-level embedding, caption of maximum length 16 words).
Note that getting this to actually "work" will require using a bigger convnet, initialized with pre-trained weights.
Displaying readable results will also require an embedding decoder.
Or generate predictions on new data:
```python
max_caption_len = 16
model = Sequential()
model.add(Convolution2D(32, 3, 3, 3, border_mode='full'))
model.add(Activation('relu'))
model.add(Convolution2D(32, 32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
model.add(Convolution2D(64, 32, 3, 3, border_mode='full'))
model.add(Activation('relu'))
model.add(Convolution2D(64, 64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
model.add(Convolution2D(128, 64, 3, 3, border_mode='full'))
model.add(Activation('relu'))
model.add(Convolution2D(128, 128, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
model.add(Flatten())
model.add(Dense(128*4*4, 256))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Repeat(max_caption_len))
# the GRU below returns sequences of max_caption_len vectors of size 256 (our word embedding size)
model.add(GRU(256, 256, return_sequences=True))
model.compile(loss='mean_squared_error', optimizer='rmsprop')
# "images" is a numpy array of shape (nb_samples, nb_channels=3, width, height)
# "captions" is a numpy array of shape (nb_samples, max_caption_len=16, embedding_dim=256)
# captions are supposed already embedded (dense vectors).
model.fit(images, captions, batch_size=16, nb_epoch=100)
classes = model.predict_classes(X_test, batch_size=32)
proba = model.predict_proba(X_test, batch_size=32)
```
In the examples folder, you will find example models for real datasets:
- CIFAR10 small images classification: Convnet with realtime data augmentation
- IMDB movie review sentiment classification: LSTM over sequences of words
- Reuters newswires topic classification: Multilayer Perceptron
- MNIST handwritten digits classification: Multilayer Perceptron
Building a network of LSTMs, a deep CNN, a Neural Turing Machine, a word2vec embedder or any other model is just as fast. The ideas behind deep learning are simple, so why should their implementation be painful?
Have a look at these [starter examples](http://keras.io/examples/).
In the [examples folder](https://github.com/fchollet/keras/tree/master/examples) of the repo, you will find more advanced models: question-answering with memory networks, text generation with stacked LSTMs, neural turing machines, etc.
## Current capabilities
------------------
For complete coverage of the API, check out [the Keras documentation](http://keras.io).
A few highlights: convnets, LSTM, GRU, word2vec-style embeddings, PReLU, batch normalization...
## Installation
Keras uses the following dependencies:
- numpy, scipy
- Theano
- See installation instructions: http://deeplearning.net/software/theano/install.html#install
- pyyaml
- HDF5 and h5py (optional, required if you use model saving/loading functions)
- Optional but recommended if you use CNNs: cuDNN.
Once you have the dependencies installed, cd to the Keras folder and run the install command:
When using the Theano backend:
- Theano
- [See installation instructions](http://deeplearning.net/software/theano/install.html#install).
**Note**: You should use the latest version of Theano, not the PyPI version. Install it with:
```
sudo pip install git+git://github.com/Theano/Theano.git
```
When using the TensorFlow backend:
- TensorFlow
- [See installation instructions](https://github.com/tensorflow/tensorflow#download-and-setup).
To install, `cd` to the Keras folder and run the install command:
```
sudo python setup.py install
```
You can also install Keras from PyPI:
```
sudo pip install keras
```
------------------
## Switching from Theano to TensorFlow
By default, Keras will use Theano as its tensor manipulation library. [Follow these instructions](http://keras.io/backend/) to configure the Keras backend.
------------------
## Support
You can ask questions and join the development discussion on the [Keras Google group](https://groups.google.com/forum/#!forum/keras-users).
------------------
## Contribution Guidelines
Keras welcomes all contributions from the community.
- Keep a pragmatic mindset and avoid bloat. Only add to the source if that is the only path forward.
- New features should be documented. Make sure you update the documentation along with your Pull Request.
- Any new function or class should have a proper docstring.
- The documentation for every new feature should include a usage example in the form of a code snippet.
- All changes should be tested. Make sure any new feature you add has a corresponding unit test.
- Please no Pull Requests about coding style.
- Even if you don't contribute to the Keras source code, if you have an application of Keras that is concise and powerful, please consider adding it to our collection of [examples](https://github.com/fchollet/keras/tree/master/examples).
------------------
## Why this name, Keras?
Keras (κέρας) means _horn_ in Greek. It is a reference to a literary image from ancient Greek and Latin literature, first found in the _Odyssey_, where dream spirits (_Oneiroi_, singular _Oneiros_) are divided between those who deceive men with false visions, who arrive to Earth through a gate of ivory, and those who announce a future that will come to pass, who arrive through a gate of horn. It's a play on the words κέρας (horn) / κραίνω (fulfill), and ἐλέφας (ivory) / ἐλεφαίρομαι (deceive).
Keras was developed as part of the research effort of project ONEIROS (Open-ended Neuro-Electronic Intelligent Robot Operating System).
Keras was initially developed as part of the research effort of project ONEIROS (Open-ended Neuro-Electronic Intelligent Robot Operating System).
_"Oneiroi are beyond our unravelling --who can be sure what tale they tell? Not all that men look for comes to pass. Two gates there are that give passage to fleeting Oneiroi; one is made of horn, one of ivory. The Oneiroi that pass through sawn ivory are deceitful, bearing a message that will not be fulfilled; those that come out through polished horn have truth behind them, to be accomplished for men who see them."_ Homer, Odyssey 19. 562 ff (Shewring translation).
>_"Oneiroi are beyond our unravelling --who can be sure what tale they tell? Not all that men look for comes to pass. Two gates there are that give passage to fleeting Oneiroi; one is made of horn, one of ivory. The Oneiroi that pass through sawn ivory are deceitful, bearing a message that will not be fulfilled; those that come out through polished horn have truth behind them, to be accomplished for men who see them."_ Homer, Odyssey 19. 562 ff (Shewring translation).
------------------
+28 -30
Ver Arquivo
@@ -2,42 +2,40 @@ site_name: Keras Documentation
theme: readthedocs
docs_dir: sources
repo_url: http://github.com/fchollet/keras
site_url: /
site_url: http://keras.io/
#theme_dir: theme
site_description: Documentation for fast and lightweight Keras Deep Learning library.
include_404: true
include_search: true
dev_addr: '0.0.0.0:8000'
google_analytics: ['UA-61785484-1', 'keras.io']
pages:
- [index.md, Home]
- [documentation.md, Index]
- Home: index.md
- Index: documentation.md
- Examples: examples.md
- FAQ: faq.md
- Optimizers: optimizers.md
- Objectives: objectives.md
- Models: models.md
- Activations: activations.md
- Initializations: initializations.md
- Regularizers: regularizers.md
- Constraints: constraints.md
- Callbacks: callbacks.md
- Datasets: datasets.md
- Visualization: visualization.md
- Layers:
- Core Layers: layers/core.md
- Convolutional Layers: layers/convolutional.md
- Recurrent Layers: layers/recurrent.md
- Advanced Activations Layers: layers/advanced_activations.md
- Normalization Layers: layers/normalization.md
- Embedding Layers: layers/embeddings.md
- Noise layers: layers/noise.md
- Containers: layers/containers.md
- Preprocessing:
- Sequence Preprocessing: preprocessing/sequence.md
- Text Preprocessing: preprocessing/text.md
- Image Preprocessing: preprocessing/image.md
- [examples.md, Examples]
- [optimizers.md, Optimizers]
- [objectives.md, Objectives]
- [models.md, Models]
- [activations.md, Activations]
- [initializations.md, Initializations]
- [regularizers.md, Regularizers]
- [constraints.md, Constraints]
- [callbacks.md, Callbacks]
- [datasets.md, Datasets]
- [layers/core.md, Layers, Core Layers]
- [layers/convolutional.md, Layers, Convolutional Layers]
- [layers/recurrent.md, Layers, Recurrent Layers]
- [layers/advanced_activations.md, Layers, Advanced Activations Layers]
- [layers/normalization.md, Layers, Normalization Layers]
- [layers/embeddings.md, Layers, Embedding Layers]
- [layers/containers.md, Layers, Containers]
- [preprocessing/sequence.md, Preprocessing, Sequence Preprocessing]
- [preprocessing/text.md, Preprocessing, Text Preprocessing]
- [preprocessing/image.md, Preprocessing, Image Preprocessing]
- [utils/visualization.md, Utils, Visualization Utilities]
+5 -6
Ver Arquivo
@@ -6,12 +6,12 @@ Activations can either be used through an `Activation` layer, or through the `ac
```python
from keras.layers.core import Activation, Dense
model.add(Dense(64, 64, init='uniform'))
model.add(Dense(64))
model.add(Activation('tanh'))
```
is equivalent to:
```python
model.add(Dense(20, 64, init='uniform', activation='tanh'))
model.add(Dense(64, activation='tanh'))
```
You can also pass an element-wise Theano function as an activation:
@@ -20,14 +20,13 @@ You can also pass an element-wise Theano function as an activation:
def tanh(x):
return theano.tensor.tanh(x)
model.add(Dense(20, 64, init='uniform', activation=tanh))
model.add(Dense(64, activation=tanh))
model.add(Activation(tanh))
```
## Available activations
- __softmax__: Should only be applied to 2D layers (expected shape: `(nb_samples, nb_dims)`).
- __time_distributed_softmax__: Softmax applied to every sample at every timestep of a layer of shape `(nb_samples, nb_timesteps, nb_dims)`.
- __softmax__: Softmax applied across inputs last dimension. Expects shape either `(nb_samples, nb_timesteps, nb_dims)` or `(nb_samples, nb_dims)`.
- __softplus__
- __relu__
- __tanh__
@@ -37,4 +36,4 @@ model.add(Activation(tanh))
## On Advanced Activations
Activations that are more complex than a simple Theano function (eg. learnable activations, configurable activations, etc.) are available as [Advanced Activation layers](layers/advanced_activations.md), and can be found in the module `keras.layers.advanced_activations`. These include PReLU and LeakyReLU.
Activations that are more complex than a simple Theano function (eg. learnable activations, configurable activations, etc.) are available as [Advanced Activation layers](layers/advanced_activations.md), and can be found in the module `keras.layers.advanced_activations`. These include PReLU and LeakyReLU.
+74
Ver Arquivo
@@ -0,0 +1,74 @@
# Keras backends
## What is a "backend"?
Keras is a model-level library, providing high-level building blocks for developing deep learning models. It does not handle itself low-level operations such as tensor products, convolutions and so on. Instead, it relies on a specialized, well-optimized tensor manipulation library to do so, serving as the "backend engine" of Keras. Rather than picking one single tensor library and making the implementation of Keras tied to that library, Keras handles the problem in a modular way, and several different backend engines can be plugged seamlessly into Keras.
At this time, Keras has two backend implementations available: the **Theano** backend and the **TensorFlow** backend.
- [Theano](http://deeplearning.net/software/theano/) is an open-source symbolic tensor manipulation framework developed by LISA/MILA Lab at Université de Montréal.
- [TensorFlow](http://www.tensorflow.org/) is an open-source symbolic tensor manipulation framework developed by Google, Inc.
## Switching from one backend to another
If you have run Keras at least once, you will find the Keras configuration file at:
`~/.keras/keras.json`
If it isn't there, you can create it.
It probably looks like this:
`{"epsilon": 1e-07, "floatx": "float32", "backend": "theano"}`
Simply change the field `backend` to either `"theano"` or `"tensorflow"`, and Keras will use the new configuration next time you run any Keras code.
## Using the abstract Keras backend to write new code
If you want the Keras modules you write to be compatible with both Theano and TensorFlow, you have to write them via the abstract Keras backend API. Here's an intro.
You can import the backend module via:
```python
from keras import backend as K
```
This instantiates an input placeholder. It's equivalent to `tf.placeholder()` or `T.matrix()`, `T.tensor3()`, etc.
```python
input = K.placeholder(shape=(2, 4, 5))
# also works:
input = K.placeholder(shape=(None, 4, 5))
# also works:
input = K.placeholder(ndim=3)
```
This instantiates a shared variable. It's equivalent to `tf.variable()` or `theano.shared()`.
```python
val = np.random.random((3, 4, 5))
var = K.variable(value=val)
# all-zeros variable:
var = K.ones(shape=(3, 4, 5))
# all-ones:
var = K.zeros(shape=(3, 4, 5))
```
Most tensor operations you will need can be done as you would in TensorFlow or Theano:
```python
a = b + c * K.abs(d)
c = K.dot(a, K.transpose(b))
a = K.sum(b, axis=2)
a = K.softmax(b)
a = concatenate([b, c], axis=-1)
# etc...
```
For more information, see the code at `keras/backend/theano_backend.py` and `keras/backend/tensorflow_backend.py`.
+27 -7
Ver Arquivo
@@ -1,6 +1,6 @@
## Usage of callbacks
A callback is a set of functions to be applied at given stages of the training procedure. You can use callbacks to get a view on internal states and statistics of the model during training. You can pass a list of callback (as the keyword argument `callbacks`) to the `.fit()` method of the `Sequential` model. The relevant methods of the callbacks will then be called at each stage of the training.
A callback is a set of functions to be applied at given stages of the training procedure. You can use callbacks to get a view on internal states and statistics of the model during training. You can pass a list of callbacks (as the keyword argument `callbacks`) to the `.fit()` method of the `Sequential` model. The relevant methods of the callbacks will then be called at each stage of the training.
---
@@ -27,6 +27,26 @@ The `logs` dictionary will contain keys for quantities relevant to the current b
---
## Available callbacks
```python
keras.callbacks.ModelCheckpoint(filepath, verbose=0, save_best_only=False)
```
Save the model after every epoch. If `save_best_only=True`, the latest best model according to the validation loss will not be overwritten.
`filepath` can contain named formatting options, which will be filled the value of `epoch` and keys in `logs` (passed in `on_epoch_end`).
For example: if `filepath` is `weights.{epoch:02d}-{val_loss:.2f}.hdf5`, then multiple files will be save with the epoch number and the validation loss.
```python
keras.callbacks.EarlyStopping(monitor='val_loss', patience=0, verbose=0)
```
Stop training after no improvement of the metric `monitor` is seen for `patience` epochs.
---
## Create a callback
@@ -35,7 +55,7 @@ You can create a custom callback by extending the base class `keras.callbacks.Ca
Here's a simple example saving a list of losses over each batch during training:
```python
class LossHistory(keras.callbacks.Callback):
def on_train_begin(self):
def on_train_begin(self, logs={}):
self.losses = []
def on_batch_end(self, batch, logs={}):
@@ -44,18 +64,18 @@ class LossHistory(keras.callbacks.Callback):
---
### Example to record the loss history
### Example: recording loss history
```python
class LossHistory(keras.callbacks.Callback):
def on_train_begin(self):
def on_train_begin(self, logs={}):
self.losses = []
def on_batch_end(self, batch, logs={}):
self.losses.append(logs.get('loss'))
model = Sequential()
model.add(Dense(784, 10, init='uniform'))
model.add(Dense(10, input_dim=784, init='uniform'))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
@@ -71,13 +91,13 @@ print history.losses
---
### Example to checkpoint models
### Example: model checkpoints
```python
from keras.callbacks import ModelCheckpoint
model = Sequential()
model.add(Dense(784, 10, init='uniform'))
model.add(Dense(10, input_dim=784, init='uniform'))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
+6 -3
Ver Arquivo
@@ -2,14 +2,17 @@
Functions from the `constraints` module allow setting constraints (eg. non-negativity) on network parameters during optimization.
The keyword arguments used for passing constraints to parameters in a layer will depend on the layer.
The penalties are applied on a per-layer basis. The exact API will depend on the layer, but the layers `Dense`, `TimeDistributedDense`, `MaxoutDense`, `Convolution1D` and `Convolution2D` have a unified API.
In the `Dense` layer it is simply `W_constraint` for the main weights matrix, and `b_constraint` for the bias.
These layers expose 2 keyword arguments:
- `W_constraint` for the main weights matrix
- `b_constraint` for the bias.
```python
from keras.constraints import maxnorm
model.add(Dense(64, 64, W_constraint = maxnorm(2)))
model.add(Dense(64, W_constraint = maxnorm(2)))
```
## Available constraints
+5
Ver Arquivo
@@ -5,6 +5,8 @@
- [Home](index.md)
- [Index](documentation.md)
- [Examples](examples.md)
- [FAQ](faq.md)
- [Backend](backend.md)
---
@@ -15,6 +17,9 @@
- [Models](models.md)
- [Activations](activations.md)
- [Initializations](initializations.md)
- [Regularizers](regularizers.md)
- [Constraints](constraints.md)
- [Callbacks](callbacks.md)
- [Datasets](datasets.md)
---
+82 -67
Ver Arquivo
@@ -1,7 +1,7 @@
Here are a few examples to get you started!
### Multilayer Perceptron (MLP)
### Multilayer Perceptron (MLP):
```python
from keras.models import Sequential
@@ -9,13 +9,16 @@ from keras.layers.core import Dense, Dropout, Activation
from keras.optimizers import SGD
model = Sequential()
model.add(Dense(20, 64, init='uniform'))
# Dense(64) is a fully-connected layer with 64 hidden units.
# in the first layer, you must specify the expected input data shape:
# here, 20-dimensional vectors.
model.add(Dense(64, input_dim=20, init='uniform'))
model.add(Activation('tanh'))
model.add(Dropout(0.5))
model.add(Dense(64, 64, init='uniform'))
model.add(Dense(64, init='uniform'))
model.add(Activation('tanh'))
model.add(Dropout(0.5))
model.add(Dense(64, 2, init='uniform'))
model.add(Dense(2, init='uniform'))
model.add(Activation('softmax'))
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
@@ -25,25 +28,21 @@ model.fit(X_train, y_train, nb_epoch=20, batch_size=16)
score = model.evaluate(X_test, y_test, batch_size=16)
```
---
### Alternative implementation of MLP
### Alternative implementation of MLP:
```python
model = Sequential()
model.add(Dense(20, 64, init='uniform', activation='tanh'))
model.add(Dense(64, input_dim=20, init='uniform', activation='tanh'))
model.add(Dropout(0.5))
model.add(Dense(64, 64, init='uniform', activation='tanh'))
model.add(Dense(64, init='uniform', activation='tanh'))
model.add(Dropout(0.5))
model.add(Dense(64, 2, init='uniform', activation='softmax')
model.add(Dense(2, init='uniform', activation='softmax'))
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='mean_squared_error', optimizer=sgd)
```
---
### VGG-like convnet
### VGG-like convnet:
```python
from keras.models import Sequential
@@ -52,26 +51,29 @@ from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.optimizers import SGD
model = Sequential()
model.add(Convolution2D(32, 3, 3, 3, border_mode='full'))
# input: 100x100 images with 3 channels -> (3, 100, 100) tensors.
# this applies 32 convolution filters of size 3x3 each.
model.add(Convolution2D(32, 3, 3, border_mode='full', input_shape=(3, 100, 100)))
model.add(Activation('relu'))
model.add(Convolution2D(32, 32, 3, 3))
model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Convolution2D(64, 32, 3, 3, border_mode='full'))
model.add(Convolution2D(64, 3, 3, border_mode='valid'))
model.add(Activation('relu'))
model.add(Convolution2D(64, 64, 3, 3))
model.add(Convolution2D(64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(64*8*8, 256))
# Note: Keras does automatic shape inference.
model.add(Dense(256))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(256, 10))
model.add(Dense(10))
model.add(Activation('softmax'))
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
@@ -81,9 +83,7 @@ model.fit(X_train, Y_train, batch_size=32, nb_epoch=1)
```
---
### Sequence classification with LSTM
### Sequence classification with LSTM:
```python
from keras.models import Sequential
@@ -92,10 +92,10 @@ from keras.layers.embeddings import Embedding
from keras.layers.recurrent import LSTM
model = Sequential()
model.add(Embedding(max_features, 256))
model.add(LSTM(256, 128, activation='sigmoid', inner_activation='hard_sigmoid'))
model.add(Embedding(max_features, 256, input_length=maxlen))
model.add(LSTM(output_dim=128, activation='sigmoid', inner_activation='hard_sigmoid'))
model.add(Dropout(0.5))
model.add(Dense(128, 1))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='rmsprop')
@@ -104,58 +104,73 @@ model.fit(X_train, Y_train, batch_size=16, nb_epoch=10)
score = model.evaluate(X_test, Y_test, batch_size=16)
```
---
### Architecture for learning image captions with a convnet and a Gated Recurrent Unit
### Architecture for learning image captions with a convnet and a Gated Recurrent Unit:
(word-level embedding, caption of maximum length 16 words).
Note that getting this to actually "work" will require using a bigger convnet, initialized with pre-trained weights.
Displaying readable results will also require an embedding decoder.
Note that getting this to work well will require using a bigger convnet, initialized with pre-trained weights.
```python
max_caption_len = 16
vocab_size = 10000
model = Sequential()
model.add(Convolution2D(32, 3, 3, 3, border_mode='full'))
model.add(Activation('relu'))
model.add(Convolution2D(32, 32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
# first, let's define an image model that
# will encode pictures into 128-dimensional vectors.
# it should be initialized with pre-trained weights.
image_model = Sequential()
image_model.add(Convolution2D(32, 3, 3, border_mode='full', input_shape=(3, 100, 100)))
image_model.add(Activation('relu'))
image_model.add(Convolution2D(32, 3, 3))
image_model.add(Activation('relu'))
image_model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(64, 32, 3, 3, border_mode='full'))
model.add(Activation('relu'))
model.add(Convolution2D(64, 64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
image_model.add(Convolution2D(64, 3, 3, border_mode='full'))
image_model.add(Activation('relu'))
image_model.add(Convolution2D(64, 3, 3))
image_model.add(Activation('relu'))
image_model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(128, 64, 3, 3, border_mode='full'))
model.add(Activation('relu'))
model.add(Convolution2D(128, 128, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
image_model.add(Flatten())
image_model.add(Dense(128))
model.add(Flatten())
model.add(Dense(128*4*4, 256))
model.add(Activation('relu'))
model.add(Dropout(0.5))
# let's load the weights from a save file.
image_model.load_weights('weight_file.h5')
model.add(Repeat(max_caption_len))
# the GRU below returns sequences of max_caption_len vectors of size 256 (our word embedding size)
model.add(GRU(256, 256, return_sequences=True))
# next, let's define a RNN model that encodes sequences of words
# into sequences of 128-dimensional word vectors.
language_model = Sequential()
language_model.add(Embedding(vocab_size, 256, input_length=max_caption_len))
language_model.add(GRU(output_dim=128, return_sequences=True))
language_model.add(TimeDistributedDense(128))
model.compile(loss='mean_squared_error', optimizer='rmsprop')
# let's repeat the image vector to turn it into a sequence.
image_model.add(RepeatVector(max_caption_len))
# "images" is a numpy array of shape (nb_samples, nb_channels=3, width, height)
# "captions" is a numpy array of shape (nb_samples, max_caption_len=16, embedding_dim=256)
# captions are supposed already embedded (dense vectors).
model.fit(images, captions, batch_size=16, nb_epoch=100)
# the output of both models will be tensors of shape (samples, max_caption_len, 128).
# let's concatenate these 2 vector sequences.
model = Merge([image_model, language_model], mode='concat', concat_axis=-1)
# let's encode this vector sequence into a single vector
model.add(GRU(256, 256, return_sequences=False))
# which will be used to compute a probability
# distribution over what the next word in the caption should be!
model.add(Dense(vocab_size))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
# "images" is a numpy float array of shape (nb_samples, nb_channels=3, width, height).
# "captions" is a numpy integer array of shape (nb_samples, max_caption_len)
# containing word index sequences representing partial captions.
# "next_words" is a numpy float array of shape (nb_samples, vocab_size)
# containing a categorical encoding (0s and 1s) of the next word in the corresponding
# partial caption.
model.fit([images, partial_captions], next_words, batch_size=16, nb_epoch=100)
```
---
In the [examples folder](https://github.com/fchollet/keras/tree/master/examples), you will find example models for real datasets:
- CIFAR10 small images classification: Convnet with realtime data augmentation
In the examples folder, you will find example models for real datasets:
- CIFAR10 small images classification: Convolutional Neural Network (CNN) with realtime data augmentation
- IMDB movie review sentiment classification: LSTM over sequences of words
- Reuters newswires topic classification: Multilayer Perceptron
- Reuters newswires topic classification: Multilayer Perceptron (MLP)
- MNIST handwritten digits classification: MLP & CNN
- Character-level text generation with LSTM
...and more.
+179
Ver Arquivo
@@ -0,0 +1,179 @@
# Keras FAQ: Frequently Asked Keras Questions
[How can I run Keras on GPU?](#how-can-i-run-keras-on-gpu)
[How can I save a Keras model?](#how-can-i-save-a-keras-model)
[Why is the training loss much higher than the testing loss?](#why-is-the-training-loss-much-higher-than-the-testing-loss)
[How can I visualize the output of an intermediate layer?](#how-can-i-visualize-the-output-of-an-intermediate-layer)
[Isn't there a bug with Merge or Graph related to input concatenation?](#isnt-there-a-bug-with-merge-or-graph-related-to-input-concatenation)
[How can I use Keras with datasets that don't fit in memory?](#how-can-i-use-keras-with-datasets-that-dont-fit-in-memory)
[How can I interrupt training when the validation loss isn't decreasing anymore?](#how-can-i-interrupt-training-when-the-validation-loss-isnt-decreasing-anymore)
[How is the validation split computed?](#how-is-the-validation-split-computed)
[Is the data shuffled during training?](#is-the-data-shuffled-during-training)
[How can I record the training / validation loss / accuracy at each epoch?](#how-can-i-record-the-training-validation-loss-accuracy-at-each-epoch)
---
### How can I run Keras on GPU?
Method 1: use Theano flags.
```bash
THEANO_FLAGS=device=gpu,floatX=float32 python my_keras_script.py
```
The name 'gpu' might have to be changed depending on your device's identifier (e.g. `gpu0`, `gpu1`, etc).
Method 2: set up your `.theanorc`: [Instructions](http://deeplearning.net/software/theano/library/config.html)
Method 3: manually set `theano.config.device`, `theano.config.floatX` at the beginning of your code:
```python
import theano
theano.config.device = 'gpu'
theano.config.floatX = 'float32'
```
---
### How can I save a Keras model?
*It is not recommended to use pickle or cPickle to save a Keras model.*
If you only need to save the architecture of a model, and not its weights, you can do:
```python
# save as JSON
json_string = model.to_json()
# save as YAML
yaml_string = model.to_yaml()
```
You can then build a fresh model from this data:
```python
# model reconstruction from JSON:
from keras.models import model_from_json
model = model_from_json(json_string)
# model reconstruction from YAML
model = model_from_yaml(yaml_string)
```
If you need to save the weights of a model, you can do so in HDF5:
```python
model.save_weights('my_model_weights.h5')
```
Assuming you have code for instantiating your model, you can then load the weights you saved into a model with the same architecture:
```python
model.load_weights('my_model_weights.h5')
```
This leads us to a way to save and reconstruct models from only serialized data:
```python
json_string = model.to_json()
open('my_model_architecture.json', 'w').write(json_string)
model.save_weights('my_model_weights.h5')
# elsewhere...
model = model_from_json(open('my_model_architecture.json').read())
model.load_weights('my_model_weights.h5')
```
---
### Why is the training loss much higher than the testing loss?
A Keras model has two modes: training and testing. Regularization mechanisms, such as Dropout and L1/L2 weight regularization, are turned off at testing time.
Besides, the training loss is the average of the losses over each batch of training data. Because your model is changing over time, the loss over the first batches of an epoch is generally higher than over the last batches. On the other hand, the testing loss for an epoch is computed using the model as it is at the end of the epoch, resulting in a lower loss.
---
### How can I visualize the output of an intermediate layer?
You can build a Theano function that will return the output of a certain layer given a certain input, for example:
```python
# with a Sequential model
get_3rd_layer_output = theano.function([model.layers[0].input],
model.layers[3].get_output(train=False))
layer_output = get_3rd_layer_output(X)
# with a Graph model
get_conv_layer_output = theano.function([model.inputs[i].input for i in model.input_order],
model.outputs['conv'].get_output(train=False),
on_unused_input='ignore')
conv_output = get_conv_output(input_data_dict)
```
---
### Isn't there a bug with Merge or Graph related to input concatenation?
Yes, there was a known bug with tensor concatenation in Thenao that was fixed early 2015.
Please upgrade to the latest version of Theano:
```bash
sudo pip install git+git://github.com/Theano/Theano.git
```
---
### 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.md).
You can also see batch training in action in our [CIFAR10 example](https://github.com/fchollet/keras/blob/master/examples/cifar10_cnn.py).
---
### How can I interrupt training when the validation loss isn't decreasing anymore?
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])
```
Find out more in the [callbacks documentation](callbacks.md).
---
### How is the validation split computed?
If you set the `validation_split` arugment in `model.fit` to e.g. 0.1, then the validation data used will be the *last 10%* of the data. If you set it to 0.25, it will be the last 25% of the data, etc.
---
### Is the data shuffled during training?
Yes, if the `shuffle` argument in `model.fit` is set to `True` (which is the default), the training data will be randomly shuffled at each epoch.
Validation data isn't shuffled.
---
### How can I record the training / validation loss / accuracy at each epoch?
The `model.fit` method returns an `History` callback, which has a `history` attribute containing the lists of successive losses / accuracies.
```python
hist = model.fit(X, y, validation_split=0.2)
print(hist.history)
```
---
+78 -34
Ver Arquivo
@@ -1,36 +1,44 @@
# Keras: Theano-based Deep Learning library
# Keras: Deep Learning library for Theano and TensorFlow
## Overview
## You have just found Keras.
Keras is a minimalist, highly modular neural network library in the spirit of Torch, written in Python, that uses [Theano](http://deeplearning.net/software/theano/) under the hood for fast tensor manipulation on GPU and CPU. It was developed with a focus on enabling fast experimentation.
Keras is a minimalist, highly modular neural networks library, written in Python and capable of running either on top of either [TensorFlow](https://github.com/tensorflow/tensorflow) or [Theano](https://github.com/Theano/Theano). It was developed with a focus on enabling fast experimentation. Being able to go from idea to result with the least possible delay is key to doing good research.
Use Keras if you need a deep learning library that:
- allows for easy and fast prototyping (through total modularity, minimalism, and extensibility).
- supports both __convolutional networks__ and __recurrent networks__ (LSTM, GRU, etc). As well as combinations of the two.
- runs seamlessly on the CPU and the GPU.
- supports both convolutional networks and recurrent networks, as well as combinations of the two.
- supports arbitrary connectivity schemes (including multi-input and multi-output training).
- runs seamlessly on CPU and GPU.
Read the documentation at [Keras.io](http://keras.io).
Keras is compatible with:
- __Python 2.7-3.5__ with the Theano backend
- __Python 2.7__ with the TensorFlow backend
------------------
## Guiding principles
- __Modularity.__ A model is understood as a sequence of standalone, fully-configurable modules that can be plugged together with as little restrictions as possible. In particular, neural layers, cost functions, optimizers, initialization schemes, activation functions and dropout are all standalone modules that you can combine to create new models.
- __Modularity.__ A model is understood as a sequence or a graph of standalone, fully-configurable modules that can be plugged together with as little restrictions as possible. In particular, neural layers, cost functions, optimizers, initialization schemes, activation functions, regularization schemes are all standalone modules that you can combine to create new models.
- __Minimalism.__ Each module should be kept short and simple (<100 lines of code). Every piece of code should be transparent upon first reading. No black magic: it hurts iteration speed and ability to innovate.
- __Minimalism.__ Each module should be kept short and simple. Every piece of code should be transparent upon first reading. No black magic: it hurts iteration speed and ability to innovate.
- __Easy extensibility.__ A new feature (a new module, per the above definition, or a new way to combine modules together) are dead simple to add (as new classes/functions), and existing modules provide ample examples.
- __Easy extensibility.__ New modules are dead simple to add (as new classes and functions), and existing modules provide ample examples. To be able to easily create new modules allows for total expressiveness, making Keras suitable for advanced research.
- __Work with Python__. No separate models configuration files in a declarative format (like in Caffe or PyLearn2). Models are described in Python code, which is compact, easier to debug, benefits from syntax highlighting, and most of all, allows for ease of extensibility.
- __Work with Python__. No separate models configuration files in a declarative format. Models are described in Python code, which is compact, easier to debug, and allows for ease of extensibility.
## Code
Find the code on Github: [fchollet/keras](https://github.com/fchollet/keras).
------------------
## License
Keras is licensed under the [MIT license](http://opensource.org/licenses/MIT).
## Getting started: 30 seconds to Keras
The core datastructure of Keras is a __model__, a way to organize layers. Here's a sequential model (a linear pile of layers).
The core datastructure of Keras is a __model__, a way to organize layers. There are two types of models: [`Sequential`](/models/#sequential) and [`Graph`](/models/#graph).
Here's the `Sequential` model (a linear pile of layers):
```python
from keras.models import Sequential
@@ -43,9 +51,9 @@ Stacking layers is as easy as `.add()`:
```python
from keras.layers.core import Dense, Activation
model.add(Dense(input_dim=100, output_dim=64, init="uniform"))
model.add(Dense(output_dim=64, input_dim=100, init="glorot_uniform"))
model.add(Activation("relu"))
model.add(Dense(input_dim=64, output_dim=10, init="uniform"))
model.add(Dense(output_dim=10, init="glorot_uniform"))
model.add(Activation("softmax"))
```
@@ -54,7 +62,7 @@ Once your model looks good, configure its learning process with `.compile()`:
model.compile(loss='categorical_crossentropy', optimizer='sgd')
```
If you need to, you can further configure your optimizer. A core principle of Keras is make things things reasonably simple, while allowing the user to be fully in control when they need to (the ultimate control being the easy extensibility of the source code).
If you need to, you can further configure your optimizer. A core principle of Keras is to make things reasonably simple, while allowing the user to be fully in control when they need to (the ultimate control being the easy extensibility of the source code).
```python
from keras.optimizers import SGD
model.compile(loss='categorical_crossentropy', optimizer=SGD(lr=0.01, momentum=0.9, nesterov=True))
@@ -67,7 +75,7 @@ model.fit(X_train, Y_train, nb_epoch=5, batch_size=32)
Alternatively, you can feed batches to your model manually:
```python
model.train(X_batch, Y_batch)
model.train_on_batch(X_batch, Y_batch)
```
Evaluate your performance in one line:
@@ -81,51 +89,87 @@ classes = model.predict_classes(X_test, batch_size=32)
proba = model.predict_proba(X_test, batch_size=32)
```
Building a network of LSTMs, a deep CNN, a word2vec embedder or any other model is just as fast. The ideas behind deep learning are simple, so why should their implementation be painful?
Building a network of LSTMs, a deep CNN, a Neural Turing Machine, a word2vec embedder or any other model is just as fast. The ideas behind deep learning are simple, so why should their implementation be painful?
Have a look at these [starter examples](http://keras.io/examples/).
In the [examples folder](https://github.com/fchollet/keras/tree/master/examples) of the repo, you will find more advanced models: question-answering with memory networks, text generation with stacked LSTMs, neural turing machines, etc.
------------------
Have a look at the [examples](examples.md).
## Installation
Keras uses the following dependencies:
- numpy, scipy
- Theano
- See [installation instructions](http://deeplearning.net/software/theano/install.html#install).
- pyyaml
- HDF5 and h5py (optional, required if you use model saving/loading functions)
- Optional but recommended if you use CNNs: cuDNN.
Once you have the dependencies installed, clone the repo:
```bash
git clone https://github.com/fchollet/keras.git
When using the Theano backend:
- Theano
- [See installation instructions](http://deeplearning.net/software/theano/install.html#install).
**Note**: You should use the latest version of Theano, not the PyPI version. Install it with:
```
sudo pip install git+git://github.com/Theano/Theano.git
```
When using the TensorFlow backend:
- TensorFlow
- [See installation instructions](https://github.com/tensorflow/tensorflow#download-and-setup).
To install, `cd` to the Keras folder and run the install command:
```
Go to the Keras folder and run the install command:
```bash
cd keras
sudo python setup.py install
```
You can also install Keras from PyPI:
```
sudo pip install keras
```
------------------
## Switching from Theano to TensorFlow
By default, Keras will use Theano as its tensor manipulation library. [Follow these instructions](http://keras.io/backend/) to configure the Keras backend.
------------------
## Support
You can ask questions and join the development discussion on the [Keras Google group](https://groups.google.com/forum/#!forum/keras-users).
------------------
## Contribution Guidelines
Keras welcomes all contributions from the community.
- Keep a pragmatic mindset and avoid bloat. Only add to the source if that is the only path forward.
- New features should be documented. Make sure you update the documentation along with your Pull Request.
- Any new function or class should have a proper docstring.
- The documentation for every new feature should include a usage example in the form of a code snippet.
- All changes should be tested. A formal test process will be introduced very soon.
- All changes should be tested. Make sure any new feature you add has a corresponding unit test.
- Please no Pull Requests about coding style.
- Even if you don't contribute to the Keras source code, if you have an application of Keras that is concise and powerful, please consider adding it to our collection of [examples](https://github.com/fchollet/keras/tree/master/examples).
------------------
## Why this name, Keras?
Keras (κέρας) means _horn_ in Greek. It is a reference to a literary image from ancient Greek and Latin literature, first found in the _Odyssey_, where dream spirits (_Oneiroi_, singular _Oneiros_) are divided between those who deceive men with false visions, who arrive to Earth through a gate of ivory, and those who announce a future that will come to pass, who arrive through a gate of horn. It's a play on the words κέρας (horn) / κραίνω (fulfill), and ἐλέφας (ivory) / ἐλεφαίρομαι (deceive).
Keras was developed as part of the research effort of project ONEIROS (Open-ended Neuro-Electronic Intelligent Robot Operating System).
Keras was initially developed as part of the research effort of project ONEIROS (Open-ended Neuro-Electronic Intelligent Robot Operating System).
> _"Oneiroi are beyond our unravelling --who can be sure what tale they tell? Not all that men look for comes to pass. Two gates there are that give passage to fleeting Oneiroi; one is made of horn, one of ivory. The Oneiroi that pass through sawn ivory are deceitful, bearing a message that will not be fulfilled; those that come out through polished horn have truth behind them, to be accomplished for men who see them."_
>_"Oneiroi are beyond our unravelling --who can be sure what tale they tell? Not all that men look for comes to pass. Two gates there are that give passage to fleeting Oneiroi; one is made of horn, one of ivory. The Oneiroi that pass through sawn ivory are deceitful, bearing a message that will not be fulfilled; those that come out through polished horn have truth behind them, to be accomplished for men who see them."_ Homer, Odyssey 19. 562 ff (Shewring translation).
> -- Homer, Odyssey 19. 562 ff (Shewring translation).
------------------
+2 -2
Ver Arquivo
@@ -1,4 +1,3 @@
# Initializations
## Usage of initializations
@@ -7,7 +6,7 @@ Initializations define the probability distribution used to set the initial rand
The keyword arguments used for passing initializations to layers will depend on the layer. Usually it is simply `init`:
```python
model.add(Dense(64, 64, init='uniform'))
model.add(Dense(64, init='uniform'))
```
## Available initializations
@@ -15,6 +14,7 @@ model.add(Dense(64, 64, init='uniform'))
- __uniform__
- __lecun_uniform__: Uniform initialization scaled by the square root of the number of inputs (LeCun 98).
- __normal__
- __identity__: Use with square 2D layers (`shape[0] == shape[1]`).
- __orthogonal__: Use with square 2D layers (`shape[0] == shape[1]`).
- __zero__
- __glorot_normal__: Gaussian initialization scaled by fan_in + fan_out (Glorot 2010)
+76 -5
Ver Arquivo
@@ -7,7 +7,8 @@ keras.layers.advanced_activations.LeakyReLU(alpha=0.3)
Special version of a Rectified Linear Unit that allows a small gradient when the unit is not active (`f(x) = alpha*x for x < 0`).
- __Input shape__: This layer does not assume a specific input shape. As a result, it cannot be used as the first layer in a model.
- __Input shape__: Arbitrary. Use the keyword argument `input_shape` (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.
- __Output shape__: Same as input.
@@ -19,17 +20,87 @@ Special version of a Rectified Linear Unit that allows a small gradient when the
## PReLU
```python
keras.layers.advanced_activations.PReLU(input_shape)
keras.layers.advanced_activations.PReLU()
```
Parametrized linear unit. Similar to a LeakyReLU, where each input unit has its alpha coefficient, and where these coefficients are learned during training.
- __Input shape__: Same as `input_shape`. This layer cannot be used as first layer in a model.
- __Input shape__: Arbitrary. Use the keyword argument `input_shape` (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.
- __Output shape__: Same as input.
- __References__:
- [Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification](http://arxiv.org/pdf/1502.01852v1.pdf)
---
## ELU
```python
keras.layers.advanced_activations.ELU()
```
Exponential linear unit. Negative values pushes mean unit activations closer to zero, with the advantage of having a noise-robust deactivation state.
- __Input shape__: Arbitrary. Use the keyword argument `input_shape` (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.
- __Output shape__: Same as input.
- __References__:
- [Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs)](http://arxiv.org/pdf/1511.07289v1.pdf)
---
## ParametricSoftplus
```python
keras.layers.advanced_activations.ParametricSoftplus()
```
Parametric Softplus of the form: (`f(x) = alpha * (1 + exp(beta * x))`). This is essentially a smooth version of ReLU where the parameters control the sharpness of the rectification. The parameters are initialized to more closely approximate a ReLU than the standard `softplus`: `alpha` initialized to `0.2` and `beta` initialized to `5.0`. The parameters are fit separately for each hidden unit.
- __Input shape__: Arbitrary. Use the keyword argument `input_shape=...` when using this layer as the first layer in a model.
- __Output shape__: Same as input.
- __References__:
- [Inferring Nonlinear Neuronal Computation Based on Physiologically Plausible Inputs](http://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1003143)
## Thresholded Linear
```python
keras.layers.advanced_activations.ThresholdedLinear(theta)
```
Parametrized linear unit. provides a threshold near zero where values are zeroed.
- __Input shape__: Arbitrary. Use the keyword argument `input_shape` (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.
- __Output shape__: Same as input.
- __Arguments__:
- __input_shape__: tuple.
- __theta__: float >= 0. Threshold location of activation
- __References__:
- [Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification](http://arxiv.org/pdf/1502.01852v1.pdf)
- [Zero-Bias Autoencoders and the Benefits of Co-Adapting Features](http://arxiv.org/pdf/1402.3337.pdf)
## Thresholded ReLu
```python
keras.layers.advanced_activations.ThresholdedReLu(theta)
```
Parametrized rectified linear unit. provides a threshold near zero where values are zeroed.
- __Input shape__: Arbitrary. Use the keyword argument `input_shape=...` when using this layer as the first layer in a model.
- __Output shape__: Same as input.
- __Arguments__:
- __theta__: float >= 0. Threshold location of activation
- __References__:
- [Zero-Bias Autoencoders and the Benefits of Co-Adapting Features](http://arxiv.org/pdf/1402.3337.pdf)
-2
Ver Arquivo
@@ -1,5 +1,3 @@
# Containers
Containers are ensembles of layers that can be interacted with through the same API as `Layer` objects.
## Sequential
+188 -6
Ver Arquivo
@@ -1,20 +1,202 @@
## Convolution1D
```python
keras.layers.convolutional.Convolution1D(nb_filter, filter_length,
init='uniform',
activation='linear',
weights=None,
border_mode='valid',
subsample_length=1,
W_regularizer=None, b_regularizer=None,
W_constraint=None, b_constraint=None,
input_dim=None, input_length=None)
```
Convolution operator for filtering neighborhoods of one-dimensional inputs. When using this layer as the first layer in a model, either provide the keyword argument `input_dim` (int, e.g. 128 for sequences of 128-dimensional vectors), or `input_shape` (tuple of integers, e.g. (10, 128) for sequences of 10 vectors of 128-dimensional vectors).
- __Input shape__: 3D tensor with shape: `(samples, steps, input_dim)`.
- __Output shape__: 3D tensor with shape: `(samples, new_steps, nb_filter)`. `steps` value might have changed due to padding.
- __Arguments__:
- __nb_filter__: Number of convolution kernels to use (dimensionality of the output).
- __filter_length__: The extension (spatial or temporal) of each filter.
- __init__: name of initialization function for the weights of the layer (see: [initializations](../initializations.md)), or alternatively, Theano function to use for weights initialization. This parameter is only relevant if you don't pass a `weights` argument.
- __activation__: name of activation function to use (see: [activations](../activations.md)), or alternatively, elementwise Theano function. If you don't specify anything, no activation is applied (ie. "linear" activation: a(x) = x).
- __weights__: list of numpy arrays to set as initial weights.
- __border_mode__: 'valid' or 'same'.
- __subsample_length__: factor by which to subsample output.
- __W_regularizer__: instance of [WeightRegularizer](../regularizers.md) (eg. L1 or L2 regularization), applied to the main weights matrix.
- __b_regularizer__: instance of [WeightRegularizer](../regularizers.md), applied to the bias.
- __activity_regularizer__: instance of [ActivityRegularizer](../regularizers.md), applied to the network output.
- __W_constraint__: instance of the [constraints](../constraints.md) module (eg. maxnorm, nonneg), applied to the main weights matrix.
- __b_constraint__: instance of the [constraints](../constraints.md) module, applied to the bias.
- __input_dim__: Number of channels/dimensions in the input. Either this argument or the keyword argument `input_shape` must be provided when using this layer as the first layer in a model.
- __input_length__: Length of input sequences, when it is constant. This argument is required if you are going to connect `Flatten` then `Dense` layers upstream (without it, the shape of the dense outputs cannot be computed).
---
## Convolution2D
```python
keras.layers.convolutional.Convolution2D(nb_filter, stack_size, nb_row, nb_col,
init='glorot_uniform', activation='linear', weights=None,
image_shape=None, border_mode='valid', subsample=(1,1))
keras.layers.convolutional.Convolution2D(nb_filter, nb_row, nb_col,
init='glorot_uniform',
activation='linear',
weights=None,
border_mode='valid',
subsample=(1, 1),
W_regularizer=None, b_regularizer=None,
W_constraint=None,
dim_ordering='th')
```
This is a wrapper for Theano's [conv2d](http://deeplearning.net/software/theano/library/tensor/nnet/conv.html#theano.tensor.nnet.conv.conv2d).
Convolution operator for filtering windows of two-dimensional inputs. When using this layer as the first layer in a model, provide the keyword argument `input_shape` (tuple of integers, does not include the sample axis), e.g. `input_shape=(3, 128, 128)` for 128x128 RGB pictures.
- __Input shape__: 4D tensor with shape: `(samples, channels, rows, cols)` if dim_ordering='th'
or 4D tensor with shape: `(samples, rows, cols, channels)` if dim_ordering='tf'.
- __Output shape__: 4D tensor with shape: `(samples, nb_filter, nb_row, nb_col)` if dim_ordering='th'
or 4D tensor with shape: `(samples, nb_row, nb_col, nb_filter)` if dim_ordering='tf'.
- __Arguments__:
- __nb_filter__: Number of convolution filters to use.
- __nb_row__: Number of rows in the convolution kernel.
- __nb_col__: Number of columns in the convolution kernel.
- __init__: name of initialization function for the weights of the layer (see: [initializations](../initializations.md)), or alternatively, Theano function to use for weights initialization. This parameter is only relevant if you don't pass a `weights` argument.
- __activation__: name of activation function to use (see: [activations](../activations.md)), or alternatively, elementwise Theano function. If you don't specify anything, no activation is applied (ie. "linear" activation: a(x) = x).
- __weights__: list of numpy arrays to set as initial weights.
- __border_mode__: 'valid' or 'same'.
- __subsample__: tuple of length 2. Factor by which to subsample output. Also called strides elsewhere.
- __W_regularizer__: instance of [WeightRegularizer](../regularizers.md) (eg. L1 or L2 regularization), applied to the main weights matrix.
- __b_regularizer__: instance of [WeightRegularizer](../regularizers.md), applied to the bias.
- __activity_regularizer__: instance of [ActivityRegularizer](../regularizers.md), applied to the network output.
- __W_constraint__: instance of the [constraints](../constraints.md) module (eg. maxnorm, nonneg), applied to the main weights matrix.
- __b_constraint__: instance of the [constraints](../constraints.md) module, applied to the bias.
- __dim_ordering__: 'th' or 'tf'. In 'th' mode, the channels dimension (the depth) is at index 1, in 'tf' mode is it at index 3.
---
## MaxPooling1D
```python
keras.layers.convolutional.MaxPooling1D(pool_length=2, stride=None, border_mode='valid')
```
Max pooling operation for temporal data.
- __Input shape__: 3D tensor with shape: `(samples, steps, features)`.
- __Output shape__: 3D tensor with shape: `(samples, downsampled_steps, features)`.
- __Arguments__:
- __pool_length__: factor by which to downscale. 2 will halve the input.
- __stride__: integer or None. Stride value.
- __border_mode__: 'valid' or 'same'. **Note:** 'same' will only work with TensorFlow for the time being.
---
## MaxPooling2D
```python
keras.layers.convolutional.MaxPooling2D(poolsize=(2, 2), ignore_border=True)
keras.layers.convolutional.MaxPooling2D(pool_size=(2, 2), border_mode='valid', dim_ordering='th')
```
This is a wrapper for Theano's [max_pool_2d](http://deeplearning.net/software/theano/library/tensor/signal/downsample.html).
Max pooling operation for spatial data.
- __Input shape__: 4D tensor with shape: `(samples, channels, rows, cols)` if dim_ordering='th'
or 4D tensor with shape: `(samples, rows, cols, channels)` if dim_ordering='tf'.
- __Output shape__: 4D tensor with shape: `(nb_samples, channels, pooled_rows, pooled_cols)` if dim_ordering='th'
or 4D tensor with shape: `(samples, pooled_rows, pooled_cols, channels)` if dim_ordering='tf'.
- __Arguments__:
- __pool_size__: tuple of 2 integers, factors by which to downscale (vertical, horizontal). (2, 2) will halve the image in each dimension.
- __strides__: tuple of 2 integers, or None. Strides values.
- __border_mode__: 'valid' or 'same'. **Note:** 'same' will only work with TensorFlow for the time being.
- __dim_ordering__: 'th' or 'tf'. In 'th' mode, the channels dimension (the depth) is at index 1, in 'tf' mode is it at index 3.
---
## UpSampling1D
```python
keras.layers.convolutional.UpSampling1D(length=2)
```
Repeats each temporal step `length` times along the time axis.
- __Input shape__: 3D tensor with shape: `(samples, steps, features)`.
- __Output shape__: 3D tensor with shape: `(samples, upsampled_steps, features)`.
- __Arguments__:
- __length__: integer. Upsampling factor.
---
## UpSampling2D
```python
keras.layers.convolutional.UpSampling2D(size=(2, 2), dim_ordering='th')
```
Repeats the rows and columns of the data by size[0] and size[1] respectively.
- __Input shape__: 4D tensor with shape: `(samples, channels, rows, cols)` if dim_ordering='th'
or 4D tensor with shape: `(samples, rows, cols, channels)` if dim_ordering='tf'.
- __Output shape__: 4D tensor with shape: `(samples, channels, upsampled_rows, upsampled_cols)` if dim_ordering='th'
or 4D tensor with shape: `(samples, upsampled_rows, upsampled_cols, channels)` if dim_ordering='tf'.
- __Arguments__:
- __size__: tuple of 2 integers. The upsampling factors for rows and columns.
- __dim_ordering__: 'th' or 'tf'. In 'th' mode, the channels dimension (the depth) is at index 1, in 'tf' mode is it at index 3.
---
## ZeroPadding1D
```python
keras.layers.convolutional.ZeroPaddding1D(padding=1)
```
Pads the input with zeros left and right along the time axis.
- __Input shape__: 3D tensor with shape: `(nb_samples, steps, dim)`.
- __Output shape__: 3D tensor with shape: `(nb_samples, padded_steps, dim)`.
- __Arguments__:
- __padding__: integer, the size of the padding.
---
## ZeroPadding2D
```python
keras.layers.convolutional.ZeroPaddding2D(padding=(1, 1), dim_ordering='th')
```
Pads the rows and columns of the input with zeros, left and right.
- __Input shape__: 4D tensor with shape: `(samples, channels, rows, cols)` if dim_ordering='th'
or 4D tensor with shape: `(samples, rows, cols, channels)` if dim_ordering='tf'.
- __Output shape__: 4D tensor with shape: `(samples, channels, padded_rows, padded_cols)` if dim_ordering='th'
or 4D tensor with shape: `(samples, padded_rows, padded_cols, channels)` if dim_ordering='tf'.
- __Arguments__:
- __padding__: tuple of 2 integers, the size of the padding for rows and columns respectively.
- __dim_ordering__: 'th' or 'tf'. In 'th' mode, the channels dimension (the depth) is at index 1, in 'tf' mode is it at index 3.
---
+209 -87
Ver Arquivo
@@ -7,7 +7,7 @@ keras.layers.core.Layer()
__Methods__:
```python
connect(previous_layer)
set_previous(previous_layer)
```
Connect the input of the current layer to the output of the argument layer.
@@ -20,7 +20,7 @@ Connect the input of the current layer to the output of the argument layer.
```python
output(train)
get_output(train)
```
Get the output of the layer.
@@ -65,13 +65,24 @@ Set the weights of the parameters of the layer.
- __weights__: List of numpy arrays (one per layer parameter). Should be in the same order as what `get_weights(self)` returns.
```python
get_config()
```
- __Return__: Configuration dictionary describing the layer.
---
## Dense
```python
keras.layers.core.Dense(input_dim, output_dim, init='glorot_uniform', activation='linear', weights=None \
W_regularizer=None, b_regularizer=None, W_constraint=None, b_constraint=None)
keras.layers.core.Dense(output_dim,
init='glorot_uniform',
activation='linear',
weights=None,
W_regularizer=None, b_regularizer=None, activity_regularizer=None,
W_constraint=None, b_constraint=None,
input_dim=None)
```
Standard 1D fully-connect layer.
@@ -82,44 +93,52 @@ Standard 1D fully-connect layer.
- __Arguments__:
- __input_dim__: int >= 0.
- __output_dim__: int >= 0.
- __init__: name of initialization function for the weights of the layer (see: [initializations](../initializations.md)), or alternatively, Theano function to use for weights initialization. This parameter is only relevant if you don't pass a `weights` argument.
- __activation__: name of activation function to use (see: [activations](../activations.md)), or alternatively, elementwise Theano function. If you don't specify anything, no activation is applied (ie. "linear" activation: a(x) = x).
- __weights__: list of numpy arrays to set as initial weights. The list should have 1 element, of shape `(input_dim, output_dim)`.
- __W_regularizer__: instance of the [regularizers](../regularizers.md) module (eg. L1 or L2 regularization), applied to the main weights matrix.
- __b_regularizer__: instance of the [regularizers](../regularizers.md) module, applied to the bias.
- __W_regularizer__: instance of [WeightRegularizer](../regularizers.md) (eg. L1 or L2 regularization), applied to the main weights matrix.
- __b_regularizer__: instance of [WeightRegularizer](../regularizers.md), applied to the bias.
- __activity_regularizer__: instance of [ActivityRegularizer](../regularizers.md), applied to the network output.
- __W_constraint__: instance of the [constraints](../constraints.md) module (eg. maxnorm, nonneg), applied to the main weights matrix.
- __b_constraint__: instance of the [constraints](../constraints.md) module, applied to the bias.
- __input_dim__: dimensionality of the input (integer). This argument (or alternatively, the keyword argument `input_shape`) is required when using this layer as the first layer in a model.
---
## TimeDistributedDense
```python
keras.layers.core.TimeDistributedDense(input_dim, output_dim, init='glorot_uniform', activation='linear', weights=None \
W_regularizer=None, b_regularizer=None, W_constraint=None, b_constraint=None)
keras.layers.core.TimeDistributedDense(output_dim,
init='glorot_uniform',
activation='linear',
weights=None
W_regularizer=None, b_regularizer=None, activity_regularizer=None,
W_constraint=None, b_constraint=None,
input_dim=None, input_length=None)
```
Fully-connected layer distributed over the time dimension. Useful after a recurrent network set to `return_sequences=True`.
- __Input shape__: 3D tensor with shape: `(nb_samples, nb_timesteps, input_dim)`.
- __Input shape__: 3D tensor with shape: `(nb_samples, timesteps, input_dim)`.
- __Arguments__:
- __input_dim__: int >= 0.
- __output_dim__: int >= 0.
- __init__: name of initialization function for the weights of the layer (see: [initializations](../initializations.md)), or alternatively, Theano function to use for weights initialization. This parameter is only relevant if you don't pass a `weights` argument.
- __activation__: name of activation function to use (see: [activations](../activations.md)), or alternatively, elementwise Theano function. If you don't specify anything, no activation is applied (ie. "linear" activation: a(x) = x).
- __weights__: list of numpy arrays to set as initial weights. The list should have 1 element, of shape `(input_dim, output_dim)`.
- __W_regularizer__: instance of the [regularizers](../regularizers.md) module (eg. L1 or L2 regularization), applied to the main weights matrix.
- __b_regularizer__: instance of the [regularizers](../regularizers.md) module, applied to the bias.
- __W_regularizer__: instance of [WeightRegularizer](../regularizers.md) (eg. L1 or L2 regularization), applied to the main weights matrix.
- __b_regularizer__: instance of [WeightRegularizer](../regularizers.md), applied to the bias.
- __activity_regularizer__: instance of [ActivityRegularizer](../regularizers.md), applied to the network output.
- __W_constraint__: instance of the [constraints](../constraints.md) module (eg. maxnorm, nonneg), applied to the main weights matrix.
- __b_constraint__: instance of the [constraints](../constraints.md) module, applied to the bias.
- __input_dim__: dimensionality of the input (integer). This argument (or alternatively, the keyword argument `input_shape`) is required when using this layer as the first layer in a model.
- __input_length__: Length of input sequences, when it is constant. This argument is required if you are going to connect `Flatten` then `Dense` layers upstream (without it, the shape of the dense outputs cannot be computed).
- __Example__:
```python
# input shape: (nb_samples, nb_timesteps, 10)
model.add(LSTM(10, 5, return_sequences=True)) # output shape: (nb_samples, nb_timesteps, 5)
model.add(TimeDistributedDense(5, 10)) # output shape: (nb_samples, nb_timesteps, 10)
# input shape: (nb_samples, timesteps, 10)
model.add(LSTM(5, return_sequences=True, input_dim=10)) # output shape: (nb_samples, timesteps, 5)
model.add(TimeDistributedDense(15)) # output shape: (nb_samples, timesteps, 15)
```
@@ -127,7 +146,7 @@ model.add(TimeDistributedDense(5, 10)) # output shape: (nb_samples, nb_timesteps
## AutoEncoder
```python
keras.layers.core.AutoEncoder(encoder, decoder, output_reconstruction=True, tie_weights=False, weights=None):
keras.layers.core.AutoEncoder(encoder, decoder, output_reconstruction=True, weights=None):
```
A customizable autoencoder model. If `output_reconstruction = True` then dim(input) = dim(output) else dim(output) = dim(hidden)
@@ -143,9 +162,7 @@ A customizable autoencoder model. If `output_reconstruction = True` then dim(inp
- __decoder__: A [layer](./) or [layer container](./containers.md).
- __output_reconstruction__: If this is False the when .predict() is called the output is the deepest hidden layer's activation. Otherwise the output of the final decoder layer is presented. Be sure your validation data confirms to this logic if you decide to use any.
- __tie_weights__: If True then the encoder bias is tied to the decoder bias. **Note**: This required the encoder layer corresponding to this decoder layer to be of the same time, eg: Dense:Dense
- __output_reconstruction__: If this is False, then when .predict() is called, the output is the deepest hidden layer's activation. Otherwise, the output of the final decoder layer is presented. Be sure your validation data conforms to this logic if you decide to use any.
- __weights__: list of numpy arrays to set as initial weights. The list should have 1 element, of shape `(input_dim, output_dim)`.
@@ -154,47 +171,11 @@ A customizable autoencoder model. If `output_reconstruction = True` then dim(inp
from keras.layers import containers
# input shape: (nb_samples, 32)
encoder = containers.Sequential([Dense(32, 16), Dense(16, 8)])
decoder = containers.Sequential([Dense(8, 16), Dense(16, 32)])
autoencoder.add(AutoEncoder(encoder=encoder, decoder=decoder, output_reconstruction=False, tie_weights=True))
```
encoder = containers.Sequential([Dense(16, input_dim=32), Dense(8)])
decoder = containers.Sequential([Dense(16, input_dim=8), Dense(32)])
---
## DenoisingAutoEncoder
```python
keras.layers.core.AutoEncoder(encoder, decoder, output_reconstruction=True, tie_weights=False, weights=None, corruption_level=0.3):
```
A denoising autoencoder model that inherits the base features from autoencoder.
Since this layer uses similar logic to Dropout it cannot be the first layer in a pipeline.
- __Input shape__: The layer shape is defined by the encoder definitions
- __Output shape__: The layer shape is defined by the decoder definitions
- __Arguments__:
- __encoder__: A [layer](./) or [layer container](./containers.md).
- __decoder__: A [layer](./) or [layer container](./containers.md).
- __output_reconstruction__: If this is False the when .predict() is called the output is the deepest hidden layer's activation. Otherwise the output of the final decoder layer is presented. Be sure your validation data confirms to this logic if you decide to use any.
- __tie_weights__: If True then the encoder bias is tied to the decoder bias. **Note**: This required the encoder layer corresponding to this decoder layer to be of the same time, eg: Dense:Dense
- __weights__: list of numpy arrays to set as initial weights. The list should have 1 element, of shape `(input_dim, output_dim)`.
- __corruption_level__: the amount of binomial noise added to the input layer of the model.
- __Example__:
```python
# input shape: (nb_samples, 32)
autoencoder.add(Dense(32, 32))
autoencoder.add(DenoisingAutoEncoder(encoder=Dense(32, 16),
decoder=Dense(16, 32),
output_reconstruction=False, tie_weights=True,
corruption_level=0.3))
autoencoder = Sequential()
autoencoder.add(AutoEncoder(encoder=encoder, decoder=decoder, output_reconstruction=False))
```
@@ -206,7 +187,8 @@ keras.layers.core.Activation(activation)
```
Apply an activation function to the input.
- __Input shape__: This layer does not assume a specific input shape. As a result, it cannot be used as the first layer in a model.
- __Input shape__: Arbitrary. Use the keyword argument `input_shape` (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.
- __Output shape__: Same as input.
@@ -223,7 +205,8 @@ keras.layers.core.Dropout(p)
```
Apply dropout to the input. Dropout consists in randomly setting a fraction `p` of input units to 0 at each update during training time, which helps prevent overfitting. Reference: [Dropout: A Simple Way to Prevent Neural Networks from Overfitting](http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf)
- __Input shape__: This layer does not assume a specific input shape.
- __Input shape__: Arbitrary. Use the keyword argument `input_shape` (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.
- __Output shape__: Same as input.
@@ -231,29 +214,30 @@ Apply dropout to the input. Dropout consists in randomly setting a fraction `p`
- __p__: float (0 <= p < 1). Fraction of the input that gets dropped out at training time.
---
## Reshape
```python
keras.layers.core.Reshape(*dims)
keras.layers.core.Reshape(dims)
```
Reshape the input to a new shape containing the same number of units.
- __Input shape__: This layer does not assume a specific input shape.
- __Output shape__: `(nb_samples, *dims)`.
- __Input shape__: Arbitrary. Use the keyword argument `input_shape` (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.
- __Output shape__: `(nb_samples, dims)`.
- __Arguments__:
- *dims: integers. Dimensions of the new shape.
- dims: tuple of integers. Dimensions of the new shape.
- __Example__:
```python
# input shape: (nb_samples, 10)
model.add(Dense(10, 100)) # output shape: (nb_samples, 100)
model.add(Reshape(10, 10)) # output shape: (nb_samples, 10, 10)
model.add(Dense(100, input_dim=10)) # output shape: (nb_samples, 100)
model.add(Reshape(dims=(10, 10))) # output shape: (nb_samples, 10, 10)
```
---
@@ -265,7 +249,7 @@ keras.layers.core.Flatten()
Convert a nD input to 1D.
- __Input shape__: (nb_samples, *). This layer cannot be used as the first layer in a model.
- __Input shape__: Arbitrary. Use the keyword argument `input_shape` (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.
- __Output shape__: `(nb_samples, nb_input_units)`.
@@ -276,23 +260,60 @@ Convert a nD input to 1D.
keras.layers.core.RepeatVector(n)
```
Repeat the 1D input n times. Dimensions of input are assumed to be (nb_samples, dim). Output will have the shape (nb_samples, n, dim).
Repeat the 1D input n times. Dimensions of input are assumed to be `(nb_samples, dim)`. Output will have the shape `(nb_samples, n, dim)`.
- __Input shape__: This layer does not assume a specific input shape. This layer cannot be used as the first layer in a model.
Note that the output is still a single tensor; `RepeatVector` does not split the data flow.
- __Input shape__: Arbitrary. Use the keyword argument `input_shape` (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.
- __Output shape__: `(nb_samples, n, input_dims)`.
- __Arguments__:
- __n__: int.
---
## Permute
```python
keras.layers.core.Permute(dims)
```
Permute the dimensions of the input data according to the given tuple. Sometimes useful for connecting RNNs and convnets together.
- __Input shape__: Arbitrary. Use the keyword argument `input_shape` (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.
- __Output shape__: Same as the input shape, but with the dimensions re-ordered according to the ordering specified by the tuple.
- __Argument__: tuple specifying the permutation scheme (e.g. `(2, 1)` permutes the first and second dimension of the input).
- __Example__:
```python
# input shape: (nb_samples, 10)
model.add(Dense(50, input_dim=10)) # output shape: (nb_samples, 50)
model.add(Reshape(dims=(10, 5))) # output shape: (nb_samples, 10, 5)
model.add(Permute(dims=(2, 1))) #output shape: (nb_samples, 5, 10)
```
---
## ActivityRegularization
```python
keras.layers.core.ActivityRegularization(l1=0., l2=0.)
```
Leaves the input unchanged, but adds a term to the loss function based on the input activity. L1 and L2 regularization supported.
This layer can be used, for instance, to induce activation sparsity in the previous layer.
---
## MaxoutDense
```python
keras.layers.core.MaxoutDense(input_dim, output_dim, nb_feature=4, init='glorot_uniform', weights=None, \
W_regularizer=None, b_regularizer=None, W_constraint=None, b_constraint=None)
keras.layers.core.MaxoutDense(output_dim, nb_feature=4,
init='glorot_uniform',
weights=None,
W_regularizer=None, b_regularizer=None, activity_regularizer=None,
W_constraint=None, b_constraint=None,
input_dim=None)
```
A dense maxout layer. A `MaxoutDense` layer takes the element-wise maximum of `nb_feature` `Dense(input_dim, output_dim)` linear layers. This allows the layer to learn a convex, piecewise linear activation function over the inputs. See [this paper](http://arxiv.org/pdf/1302.4389.pdf) for more details. Note that this is a *linear* layer -- if you wish to apply activation function (you shouldn't need to -- they are universal function approximators), an `Activation` layer must be added after.
@@ -303,49 +324,55 @@ A dense maxout layer. A `MaxoutDense` layer takes the element-wise maximum of `n
- __Arguments__:
- __input_dim__: int >= 0.
- __output_dim__: int >= 0.
- __nb_feature__: int >= 0. the number of features to create for the maxout. This is equivalent to the number of piecewise elements to be allowed for the activation function.
- __init__: name of initialization function for the weights of the layer (see: [initializations](../initializations.md)), or alternatively, Theano function to use for weights initialization. This parameter is only relevant if you don't pass a `weights` argument.
- __weights__: list of numpy arrays to set as initial weights. The list should have 1 element, of shape `(input_dim, output_dim)`.
- __W_regularizer__: instance of the [regularizers](../regularizers.md) module (eg. L1 or L2 regularization), applied to the main weights matrix.
- __b_regularizer__: instance of the [regularizers](../regularizers.md) module, applied to the bias.
- __W_regularizer__: instance of [WeightRegularizer](../regularizers.md) (eg. L1 or L2 regularization), applied to the main weights matrix.
- __b_regularizer__: instance of [WeightRegularizer](../regularizers.md), applied to the bias.
- __activity_regularizer__: instance of [ActivityRegularizer](../regularizers.md), applied to the network output.
- __W_constraint__: instance of the [constraints](../constraints.md) module (eg. maxnorm, nonneg), applied to the main weights matrix.
- __b_constraint__: instance of the [constraints](../constraints.md) module, applied to the bias.
- __input_dim__: dimensionality of the input (integer). This argument (or alternatively, the keyword argument `input_shape`) is required when using this layer as the first layer in a model.
```python
# input shape: (nb_samples, 10)
model.add(Dense(10, 100)) # output shape: (nb_samples, 100)
model.add(MaxoutDense(100, 100, nb_feature=10)) # output shape: (nb_samples, 100)
model.add(RepeatVector(2)) # output shape: (nb_samples, 2, 10)
model.add(Dense(100, input_dim=10)) # output shape: (nb_samples, 100)
model.add(MaxoutDense(50, nb_feature=10)) # output shape: (nb_samples, 50)
```
## Merge
```python
keras.layers.core.Merge(models, mode='sum')
keras.layers.core.Merge(layers, mode='sum', concat_axis=-1, dot_axes=-1)
```
Merge the output of a list of models into a single tensor, following one of two modes: `sum` or `concat`.
Merge the output of a list of layers (or containers) into a single tensor.
- __Arguments__:
- __models__: List of `Sequential` models.
- __mode__: String, one of `{'sum', 'concat'}`. `sum` will simply sum the outputs of the models (therefore all models should have an output with the same shape). `concat` will concatenate the outputs along the last dimension (therefore all models should have an output that only differ along the last dimension).
- __layers__: List of layers or [containers](/layers/containers/).
- __mode__: String, one of `{'sum', 'mul', 'concat', 'ave', 'dot'}`. `sum`, `mul` and `ave` will simply sum/multiply/average the outputs of the layers (therefore all layers should have an output with the same shape). `concat` will concatenate the outputs along the dimension specified by `concate_axis` (therefore all layers should have an output that only differ along this dimension). `dot` will dot tensor contraction on the axes specified by `dot_axes` (see [the Numpy documentation](http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.tensordot.html) for more details).
- __concat_axis__: axis to use in `concat` mode.
- __dot_axes__: axis or axes to use in `dot` mode (see [the Numpy documentation](http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.tensordot.html) for more details).
- __Notes__:
- `dot` mode only works with Theano for the time being.
- __Example__:
```python
left = Sequential()
left.add(Dense(784, 50))
left.add(Dense(50, input_shape=(784,)))
left.add(Activation('relu'))
right = Sequential()
right.add(Dense(784, 50))
right.add(Dense(50, input_shape=(784,)))
right.add(Activation('relu'))
model = Sequential()
model.add(Merge([left, right], mode='sum'))
model.add(Dense(50, 10))
model.add(Dense(10))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
@@ -353,3 +380,98 @@ model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
model.fit([X_train, X_train], Y_train, batch_size=128, nb_epoch=20, validation_data=([X_test, X_test], Y_test))
```
## Masking
```python
keras.layers.core.Masking(mask_value=0.)
```
Create a mask for the input data by using `mask_value` as the sentinel value which should be masked out.
Given an input of dimensions `(nb_samples, timesteps, input_dim)`, return the input untouched as output, and supply a mask of shape `(nb_samples, timesteps)` where all timesteps which had *all* their values equal to `mask_value` are masked out.
- __Input shape__: 3D tensor with shape: `(nb_samples, timesteps, features)`.
- __Output shape__: 3D tensor with shape: `(nb_samples, timesteps, features)`.
- __Notes__: Masking only works in Theano for the time being.
## Lambda
```python
keras.layers.core.Lambda(function, output_shape=None)
```
Used for evaluating an arbitrary Theano expression on the output of the previous layer.
- __Input shape__: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.
- __Output shape__: Specified by the `output_shape` argument.
- __Arguments__:
- __function__: The expression to be evaluated. Takes one argument: the output of the previous layer.
- __output_shape__: Shape of the tensor returned by `function`. Should be a shape tuple (not including the samples dimension) or a function of the full input shape tuple (including samples dimension).
- __Example__:
```python
# custom softmax function
def sharp_softmax(X, beta=1.5):
return theano.tensor.nnet.softmax(X * beta)
def output_shape(input_shape):
# here input_shape includes the samples dimension
return input_shape # shape is unchanged
model = Sequential()
model.add(Dense(input_dim=10, output_dim=10))
model.add(Lambda(sharp_softmax, output_shape))
model.add(Dense(1))
model.add(Activation('sigmoid'))
```
## LambdaMerge
```python
keras.layers.core.LambdaMerge(layers, function, output_shape=None)
```
Merge the output of a list of layers (or containers) into a single tensor, using an arbitrary Theano expression.
- __Arguments__:
- __layers__: List of layers or [containers](/layers/containers/).
- __function__: The expression to be evaluated. Takes one argument: the list of input tensors.
- __output_shape__: Shape of the tensor returned by `function`. Should be a shape tuple (not including samples dimension) or a function of the list of input shape tuples (including samples dimension).
- __Example__:
```python
# root mean square function
def rms(inputs):
# inputs is a list of tensors
s = inputs[0] ** 2
for i in range(1, len(inputs)):
s += inputs[i] ** 2
s /= len(inputs)
s = theano.tensor.sqrt(s)
# return a single tensor
return s
def output_shape(input_shapes):
# return the shape of the first tensor
return input_shapes[0]
left = Sequential()
left.add(Dense(input_dim=10, output_dim=10))
left.add(Activation('sigmoid'))
right = Sequential()
right.add(Dense(input_dim=10, output_dim=10))
right.add(Activation('sigmoid'))
model = Sequential()
model.add(LambdaMerge([left, right], rms, output_shape))
model.add(Dense(1))
model.add(Activation('sigmoid'))
```
---
+12 -29
Ver Arquivo
@@ -2,47 +2,30 @@
## Embedding
```python
keras.layers.embeddings.Embedding(input_dim, output_dim, init='uniform', weights=None, W_regularizer=None, W_constraint=None)
keras.layers.embeddings.Embedding(input_dim, output_dim,
init='uniform',
weights=None,
W_regularizer=None, W_constraint=None,
mask_zero=False,
input_length=None)
```
Turn positive integers (indexes) into denses vectors of fixed size,
eg. `[[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]]`
- __Input shape__: 2D tensor with shape: `(nb_samples, maxlen)`.
- __Input shape__: 2D tensor with shape: `(nb_samples, sequence_length)`.
- __Output shape__: 3D tensor with shape: `(nb_samples, maxlen, output_dim)`.
- __Output shape__: 3D tensor with shape: `(nb_samples, sequence_length, output_dim)`.
- __Arguments__:
- __input_dim__: int >= 0. Size of the vocabulary, ie. 1+maximum integer index occuring in the input data.
- __input_dim__: int >= 0. Size of the vocabulary, ie. 1+maximum integer index occurring in the input data.
- __output_dim__: int >= 0. Dimension of the dense embedding.
- __init__: name of initialization function for the weights of the layer (see: [initializations](../initializations.md)), or alternatively, Theano function to use for weights initialization. This parameter is only relevant if you don't pass a `weights` argument.
- __weights__: list of numpy arrays to set as initial weights. The list should have 1 element, of shape `(input_dim, output_dim)`.
- __W_regularizer__: instance of the [regularizers](../regularizers.md) module (eg. L1 or L2 regularization), applied to the embedding matrix.
- __W_constraint__: instance of the [constraints](../constraints.md) module (eg. maxnorm, nonneg), applied to the embedding matrix.
- __mask_zero__: Whether or not the input value 0 is a special "padding" value that should be masked out. This is useful for [recurrent layers](recurrent.md) which may take variable length input. If this is `True` then all subsequent layers in the model need to support masking or an exception will be raised.
- __input_length__: Length of input sequences, when it is constant. This argument is required if you are going to connect `Flatten` then `Dense` layers upstream (without it, the shape of the dense outputs cannot be computed).
## WordContextProduct
```python
keras.layers.embeddings.WordContextProduct(input_dim, proj_dim=128,
init='uniform', activation='sigmoid', weights=None)
```
This layer turns a pair of words (a pivot word + a context word, ie. a word from the same context as a pivot, or a random, out-of-context word), indentified by their indices in a vocabulary, into two dense reprensentations (word representation and context representation).
Then it returns `activation(dot(pivot_embedding, context_embedding))`, which can be trained to encode the probability of finding the context word in the context of the pivot word (or reciprocally depending on your training procedure).
For more context, see Mikolov et al.: [Efficient Estimation of Word reprensentations in Vector Space](http://arxiv.org/pdf/1301.3781v3.pdf)
- __Input shape__: 2D tensor with shape: `(nb_samples, 2)`.
- __Output shape__: 2D tensor with shape: `(nb_samples, 1)`.
- __Arguments__:
- __input_dim__: int >= 0. Size of the vocabulary, ie. 1+maximum integer index occuring in the input data.
- __proj_dim__: int >= 0. Dimension of the dense embedding used internally.
- __init__: name of initialization function for the embeddings (see: [initializations](../initializations.md)), or alternatively, Theano function to use for weights initialization. This parameter is only relevant if you don't pass a `weights` argument.
- __activation__: name of activation function to use (see: [activations](../activations.md)), or alternatively, elementwise Theano function.
- __weights__: list of numpy arrays to set as initial weights. The list should have 2 element, both of shape `(input_dim, proj_dim)`. The first element is the word embedding weights, the second one is the context embedding weights.
---
+37
Ver Arquivo
@@ -0,0 +1,37 @@
## GaussianNoise
```python
keras.layers.noise.GaussianNoise(sigma)
```
Apply to the input an additive zero-centred gaussian noise with standard deviation `sigma`. This is useful to mitigate overfitting (you could see it as a kind of random data augmentation). Gaussian Noise (GS) is a natural choice as corruption process for real valued inputs.
Only active at training time.
- __Input shape__: Arbitrary. Use the keyword argument `input_shape` (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.
- __Output shape__: Same as input.
- __Arguments__:
- __sigma__: float, standard deviation of the noise distribution.
---
## GaussianDropout
```python
keras.layers.noise.GaussianDropout(p)
```
Apply to the input an multiplicative one-centred gaussian noise with standard deviation `sqrt(p/(1-p))`. p refers to drop probability to match Dropout layer syntax.
Only active at training time.
- __Input shape__: Arbitrary. Use the keyword argument `input_shape` (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.
- __Output shape__: Same as input.
- __Arguments__:
- __p__: float, drop probability as with Dropout.
+3 -4
Ver Arquivo
@@ -2,17 +2,16 @@
## BatchNormalization
```python
keras.layers.normalization.BatchNormalization(input_shape, epsilon=1e-6, weights=None)
keras.layers.normalization.BatchNormalization(epsilon=1e-6, weights=None)
```
Normalize the activations of the previous layer at each batch.
- __Input shape__: Same as `input_shape`. This layer cannot be used as first layer in a model.
- __Input shape__: Arbitrary. Use the keyword argument `input_shape` (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.
- __Output shape__: Same as input.
- __Arguments__:
- __input_shape__: tuple.
- __Arguments__:
- __epsilon__: small float > 0. Fuzz parameter.
- __weights__: Initialization weights. List of 2 numpy arrays, with shapes: `[(input_shape,), (input_shape,)]`
+54 -57
Ver Arquivo
@@ -2,62 +2,38 @@
## SimpleRNN
```python
keras.layers.recurrent.SimpleRNN(input_dim, output_dim,
init='glorot_uniform', inner_init='orthogonal', activation='sigmoid', weights=None,
truncate_gradient=-1, return_sequences=False)
keras.layers.recurrent.SimpleRNN(output_dim,
init='glorot_uniform', inner_init='orthogonal',
activation='sigmoid',
weights=None,
return_sequences=False,
go_backwards=False,
stateful=False,
input_dim=None, input_length=None)
```
Fully connected RNN where output is to fed back to input. Not a particularly useful model, included for demonstration purposes.
Fully connected RNN where output is to fed back to input.
- __Input shape__: 3D tensor with shape: `(nb_samples, timesteps, input_dim)`.
- __Output shape__:
- if `return_sequences`: 3D tensor with shape: `(nb_samples, timesteps, ouput_dim)`.
- if `return_sequences`: 3D tensor with shape: `(nb_samples, timesteps, output_dim)`.
- else: 2D tensor with shape: `(nb_samples, output_dim)`.
- __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 set to `True`. **Note:** for the time being, masking in only supported with Theano.
- __Notes__: When using the TensorFlow backend, the number of timesteps used must be fixed. Make sure to pass an `input_length` int argument or a complete `input_shape` tuple argument.
- __Arguments__:
- __input_dim__: dimension of the input.
- __output_dim__: dimension of the internal projections and the final output.
- __init__: weight initialization function. Can be the name of an existing function (str), or a Theano function (see: [initializations](../initializations.md)).
- __activation__: activation function. Can be the name of an existing function (str), or a Theano function (see: [activations](../activations.md)).
- __weights__: list of numpy arrays to set as initial weights. The list should have 3 elements, of shapes: `[(input_dim, output_dim), (output_dim, output_dim), (output_dim,)]`.
- __truncate_gradient__: Number of steps to use in truncated BPTT. See: [Theano "scan"](http://deeplearning.net/software/theano/library/scan.html).
- __return_sequences__: Boolean. Whether to return the last output in the output sequence, or the full sequence.
---
## SimpleDeepRNN
```python
keras.layers.recurrent.SimpleDeepRNN(input_dim, output_dim, depth=3,
init='glorot_uniform', inner_init='orthogonal',
activation='sigmoid', inner_activation='hard_sigmoid',
weights=None, truncate_gradient=-1, return_sequences=False)
```
Fully connected RNN where the output of multiple timesteps (up to "depth" steps in the past) is fed back to the input:
```
output = activation( W.x_t + b + inner_activation(U_1.h_tm1) + inner_activation(U_2.h_tm2) + ... )
```
Not a particularly useful model, included for demonstration purposes.
- __Input shape__: 3D tensor with shape: `(nb_samples, timesteps, input_dim)`.
- __Output shape__:
- if `return_sequences`: 3D tensor with shape: `(nb_samples, timesteps, ouput_dim)`.
- else: 2D tensor with shape: `(nb_samples, output_dim)`.
- __Arguments__:
- __input_dim__: dimension of the input.
- __output_dim__: dimension of the internal projections and the final output.
- __depth__: int >= 1. Lookback depth (eg. depth=1 is equivalent to SimpleRNN).
- __init__: weight initialization function for the output cell. Can be the name of an existing function (str), or a Theano function (see: [initializations](../initializations.md)).
- __inner_init__: weight initialization function for the inner cells.
- __activation__: activation function for the output. Can be the name of an existing function (str), or a Theano function (see: [activations](../activations.md)).
- __inner_activation__: activation function for the inner cells.
- __weights__: list of numpy arrays to set as initial weights. The list should have depth+2 elements.
- __truncate_gradient__: Number of steps to use in truncated BPTT. See: [Theano "scan"](http://deeplearning.net/software/theano/library/scan.html).
- __return_sequences__: Boolean. Whether to return the last output in the output sequence, or the full sequence.
- __go_backwards__: Boolean (default False). If True, rocess the input sequence backwards.
- __stateful__: Boolean (default False). If True, the last state for each sample at index i in a batch will be used as initial state for the sample of index i in the following batch.
- __input_dim__: dimensionality of the input (integer). This argument (or alternatively, the keyword argument `input_shape`) is required when using this layer as the first layer in a model.
- __input_length__: Length of input sequences, when it is constant. This argument is required if you are going to connect `Flatten` then `Dense` layers upstream (without it, the shape of the dense outputs cannot be computed).
---
@@ -65,10 +41,13 @@ Not a particularly useful model, included for demonstration purposes.
## GRU
```python
keras.layers.recurrent.GRU(input_dim, output_dim=128,
keras.layers.recurrent.GRU(output_dim,
init='glorot_uniform', inner_init='orthogonal',
activation='sigmoid', inner_activation='hard_sigmoid',
weights=None, truncate_gradient=-1, return_sequences=False)
return_sequences=False,
go_backwards=False,
stateful=False,
input_dim=None, input_length=None)
```
Gated Recurrent Unit - Cho et al. 2014.
@@ -76,19 +55,26 @@ Gated Recurrent Unit - Cho et al. 2014.
- __Input shape__: 3D tensor with shape: `(nb_samples, timesteps, input_dim)`.
- __Output shape__:
- if `return_sequences`: 3D tensor with shape: `(nb_samples, timesteps, ouput_dim)`.
- if `return_sequences`: 3D tensor with shape: `(nb_samples, timesteps, output_dim)`.
- else: 2D tensor with shape: `(nb_samples, output_dim)`.
- __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 set to true. **Note:** for the time being, masking in only supported with Theano.
- __Notes__: When using the TensorFlow backend, the number of timesteps used must be fixed. Make sure to pass an `input_length` int argument or a complete `input_shape` tuple argument.
- __Arguments__:
- __input_dim__: dimension of the input.
- __output_dim__: dimension of the internal projections and the final output.
- __init__: weight initialization function for the output cell. Can be the name of an existing function (str), or a Theano function (see: [initializations](../initializations.md)).
- __inner_init__: weight initialization function for the inner cells.
- __activation__: activation function for the output. Can be the name of an existing function (str), or a Theano function (see: [activations](../activations.md)).
- __inner_activation__: activation function for the inner cells.
- __weights__: list of numpy arrays to set as initial weights. The list should have 9 elements.
- __truncate_gradient__: Number of steps to use in truncated BPTT. See: [Theano "scan"](http://deeplearning.net/software/theano/library/scan.html).
- __return_sequences__: Boolean. Whether to return the last output in the output sequence, or the full sequence.
- __go_backwards__: Boolean (default False). If True, rocess the input sequence backwards.
- __stateful__: Boolean (default False). If True, the last state for each sample at index i in a batch will be used as initial state for the sample of index i in the following batch.
- __input_dim__: dimensionality of the input (integer). This argument (or alternatively, the keyword argument `input_shape`) is required when using this layer as the first layer in a model.
- __input_length__: Length of input sequences, when it is constant. This argument is required if you are going to connect `Flatten` then `Dense` layers upstream (without it, the shape of the dense outputs cannot be computed).
- __References__:
- [On the Properties of Neural Machine Translation: Encoder–Decoder Approaches](http://www.aclweb.org/anthology/W14-4012)
@@ -99,10 +85,14 @@ Gated Recurrent Unit - Cho et al. 2014.
## LSTM
```python
keras.layers.recurrent.LSTM(input_dim, output_dim=128,
init='glorot_uniform', inner_init='orthogonal',
keras.layers.recurrent.LSTM(output_dim,
init='glorot_uniform', inner_init='orthogonal', forget_bias_init='one',
activation='tanh', inner_activation='hard_sigmoid',
weights=None, truncate_gradient=-1, return_sequences=False)
weights=None,
return_sequences=False,
go_backwards=False,
stateful=False,
input_dim=None, input_length=None)
```
Long-Short Term Memory unit - Hochreiter 1997.
@@ -110,24 +100,31 @@ Long-Short Term Memory unit - Hochreiter 1997.
- __Input shape__: 3D tensor with shape: `(nb_samples, timesteps, input_dim)`.
- __Output shape__:
- if `return_sequences`: 3D tensor with shape: `(nb_samples, timesteps, ouput_dim)`.
- if `return_sequences`: 3D tensor with shape: `(nb_samples, timesteps, output_dim)`.
- else: 2D tensor with shape: `(nb_samples, output_dim)`.
- __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 set to true. **Note:** for the time being, masking in only supported with Theano.
- __Notes__: When using the TensorFlow backend, the number of timesteps used must be fixed. Make sure to pass an `input_length` int argument or a complete `input_shape` tuple argument.
- __Arguments__:
- __input_dim__: dimension of the input.
- __output_dim__: dimension of the internal projections and the final output.
- __init__: weight initialization function for the output cell. Can be the name of an existing function (str), or a Theano function (see: [initializations](../initializations.md)).
- __inner_init__: weight initialization function for the inner cells.
- __forget_bias_init__: initialization function for the bias of the forget gate. [Jozefowicz et al.](http://www.jmlr.org/proceedings/papers/v37/jozefowicz15.pdf) recommend initializing with ones.
- __activation__: activation function for the output. Can be the name of an existing function (str), or a Theano function (see: [activations](../activations.md)).
- __inner_activation__: activation function for the inner cells.
- __weights__: list of numpy arrays to set as initial weights. The list should have 12 elements.
- __truncate_gradient__: Number of steps to use in truncated BPTT. See: [Theano "scan"](http://deeplearning.net/software/theano/library/scan.html).
- __return_sequences__: Boolean. Whether to return the last output in the output sequence, or the full sequence.
- __go_backwards__: Boolean (default False). If True, rocess the input sequence backwards.
- __stateful__: Boolean (default False). If True, the last state for each sample at index i in a batch will be used as initial state for the sample of index i in the following batch.
- __input_dim__: dimensionality of the input (integer). This argument (or alternatively, the keyword argument `input_shape`) is required when using this layer as the first layer in a model.
- __input_length__: Length of input sequences, when it is constant. This argument is required if you are going to connect `Flatten` then `Dense` layers upstream (without it, the shape of the dense outputs cannot be computed).
- __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 labelling with recurrent neural networks](http://www.cs.toronto.edu/~graves/preprint.pdf)
---
+114 -17
Ver Arquivo
@@ -7,40 +7,41 @@ model = keras.models.Sequential()
```
- __Methods__:
- __add__(layer): Add a layer to the model.
- __compile__(optimizer, loss, class_mode="categorical"):
- __Arguments__:
- __compile__(optimizer, loss, class_mode="categorical"):
- __Arguments__:
- __optimizer__: str (name of optimizer) or optimizer object. See [optimizers](optimizers.md).
- __loss__: str (name of objective function) or objective function. See [objectives](objectives.md).
- __class_mode__: one of "categorical", "binary". This is only used for computing classification accuracy or using the predict_classes method.
- __theano_mode__: A `theano.compile.mode.Mode` ([reference](http://deeplearning.net/software/theano/library/compile/mode.html)) instance controlling specifying compilation options.
- __fit__(X, y, batch_size=128, nb_epoch=100, verbose=1, validation_split=0., validation_data=None, shuffle=True, show_accuracy=False, callbacks=[]): Train a model for a fixed number of epochs.
- __Return__: a history dictionary with a record of training loss values at successive epochs, as well as validation loss values (if applicable), accuracy (if applicable), etc.
- __Arguments__:
- __class_mode__: one of "categorical", "binary". This is only used for computing classification accuracy or using the predict_classes method.
- __fit__(X, y, batch_size=128, nb_epoch=100, verbose=1, validation_split=0., validation_data=None, shuffle=True, show_accuracy=False, callbacks=[], class_weight=None, sample_weight=None): Train a model for a fixed number of epochs.
- __Return__: a history object. It `history` attribute is a record of training loss values at successive epochs, as well as validation loss values (if applicable).
- __Arguments__:
- __X__: data.
- __y__: labels.
- __batch_size__: int. Number of samples per gradient update.
- __nb_epoch__: int.
- __nb_epoch__: int.
- __verbose__: 0 for no logging to stdout, 1 for progress bar logging, 2 for one log line per epoch.
- __callbacks__: `keras.callbacks.Callback` list. List of callbacks to apply during training. See [callbacks](callbacks.md).
- __validation_split__: float (0. < x < 1). Fraction of the data to use as held-out validation data.
- __validation_data__: tuple (X, y) to be used as held-out validation data. Will override validation_split.
- __shuffle__: boolean. Whether to shuffle the samples at each epoch.
- __shuffle__: boolean or str (for 'batch'). Whether to shuffle the samples at each epoch. 'batch' is a special option for dealing with the limitations of HDF5 data; it shuffles in batch-sized chunks.
- __show_accuracy__: boolean. Whether to display class accuracy in the logs to stdout at each epoch.
- __callbacks__: `keras.callbacks.Callback` list. List of callbacks to apply during training. See [callbacks](callbacks.md).
- __evaluate__(X, y, batch_size=128, show_accuracy=False, verbose=1): Show performance of the model over some validation data.
- __Return__: The loss score over the data.
- __class_weight__: dictionary mapping classes to a weight value, used for scaling the loss function (during training only).
- __sample_weight__: list or numpy array with 1:1 mapping to the training samples, used for scaling the loss function (during training only). For time-distributed data, there is one weight per sample *per timestep*, i.e. if your output data is shaped `(nb_samples, timesteps, output_dim)`, your mask should be of shape `(nb_samples, timesteps, 1)`. This allows you to mask out or reweight individual output timesteps, which is useful in sequence to sequence learning.
- __evaluate__(X, y, batch_size=128, show_accuracy=False, verbose=1, sample_weight=None): Show performance of the model over some validation data.
- __Return__: The loss score over the data, or a `(loss, accuracy)` tuple if `show_accuracy=True`.
- __Arguments__: Same meaning as fit method above. verbose is used as a binary flag (progress bar or nothing).
- __predict__(X, batch_size=128, verbose=1):
- __predict__(X, batch_size=128, verbose=1):
- __Return__: An array of predictions for some test data.
- __Arguments__: Same meaning as fit method above.
- __predict_classes__(X, batch_size=128, verbose=1): Return an array of class predictions for some test data.
- __Return__: An array of labels for some test data.
- __Arguments__: Same meaning as fit method above. verbose is used as a binary flag (progress bar or nothing).
- __train__(X, y, accuracy=False): Single gradient update on one batch. if accuracy==False, return tuple (loss_on_batch, accuracy_on_batch). Else, return loss_on_batch.
- __train_on_batch__(X, y, accuracy=False, class_weight=None, sample_weight=None): Single gradient update on one batch.
- __Return__: loss over the data, or tuple `(loss, accuracy)` if `accuracy=True`.
- __test__(X, y, accuracy=False): Single performance evaluation on one batch. if accuracy==False, return tuple (loss_on_batch, accuracy_on_batch). Else, return loss_on_batch.
- __test_on_batch__(X, y, accuracy=False, sample_weight=None): Single performance evaluation on one batch.
- __Return__: loss over the data, or tuple `(loss, accuracy)` if `accuracy=True`.
- __save_weights__(fname, overwrite=False): Store the weights of all layers to a HDF5 file. If overwrite==False and the file already exists, an exception will be thrown.
- __load_weights__(fname): Sets the weights of a model, based to weights stored by __save__weights__. You can only __load__weights__ on a savefile from a model with an identical architecture. __load_weights__ can be called either before or after the __compile__ step.
- __load_weights__(fname): Sets the weights of a model, based to weights stored by __save_weights__. You can only __load_weights__ on a savefile from a model with an identical architecture. __load_weights__ can be called either before or after the __compile__ step.
__Examples__:
@@ -50,7 +51,7 @@ from keras.layers.core import Dense, Dropout, Activation
from keras.optimizers import SGD
model = Sequential()
model.add(Dense(64, 2, init='uniform'))
model.add(Dense(2, init='uniform', input_dim=64))
model.add(Activation('softmax'))
model.compile(loss='mse', optimizer='sgd')
@@ -112,3 +113,99 @@ Epoch 2
10960/37800 [=======>......................] - ETA: 4s - loss: 0.0109 - acc.: 0.9420
'''
```
---
## Graph
Arbitrary connection graph. It can have any number of inputs and outputs, with each output trained with its own loss function. The quantity being optimized by a Graph model is the sum of all loss functions over the different outputs.
```python
model = keras.models.Graph()
```
- __Methods__:
- __add_input__(name, input_shape, dtype='float'): Add an input with shape dimensionality `ndim`.
- __Arguments__:
- __input_shape__: Integer tuple, shape of the expected input (not including the samples axis). E.g. (10,) for 10-dimensional vectors, (None, 128) for sequences (of variable length) of 128-dimensional vectors, (3, 32, 32) for 32x32 images with RGB channels.
- __dtype__: `float` or `int`. Type of the expected input data.
- __add_output__(name, input=None, inputs=[], merge_mode='concat'): Add an output connect to `input` or `inputs`.
- __Arguments__:
- __name__: str. unique identifier of the output.
- __input__: str name of the node that the output is connected to. Only specify *one* of either `input` or `inputs`.
- __inputs__: list of str names of the node that the output is connected to.
- __merge_mode__: "sum" or "concat". Only applicable if `inputs` list is specified. Merge mode for the different inputs.
- __add_node__(layer, name, input=None, inputs=[], merge_mode='concat'): Add an output connect to `input` or `inputs`.
- __Arguments__:
- __layer__: Layer instance.
- __name__: str. unique identifier of the node.
- __input__: str name of the node/input that the node is connected to. Only specify *one* of either `input` or `inputs`.
- __inputs__: list of str names of the node that the node is connected to.
- __merge_mode__: "sum" or "concat". Only applicable if `inputs` list is specified. Merge mode for the different inputs.
- __add_shared_node__(layer, name, inputs=[], merge_mode=None, outputs=[]): Add a shared node connected to `inputs`. A shared node is a layer that will be applied separately to every incoming input, and that uses only one set of weights. The merging operation occurs on the outputs of the layer.
- __Arguments__:
- __layer__: Layer instance.
- __name__: str. unique identifier of the node.
- __inputs__: list of str names of the node that the node is connected to.
- __merge_mode__: Merge mode for the different inputs.
- __outputs__: Optional. List of names for outputs, when merge_mode = None.
- __compile__(optimizer, loss):
- __Arguments__:
- __optimizer__: str (name of optimizer) or optimizer object. See [optimizers](optimizers.md).
- __loss__: dictionary mapping the name(s) of the output(s) to a loss function (string name of objective function or objective function. See [objectives](objectives.md)).
- __fit__(data, batch_size=128, nb_epoch=100, verbose=1, validation_split=0., validation_data=None, shuffle=True, callbacks=[]): Train a model for a fixed number of epochs.
- __Return__: a history object. It `history` attribute is a record of training loss values at successive epochs, as well as validation loss values (if applicable).
- __Arguments__:
- __data__:dictionary mapping input names out outputs names to appropriate numpy arrays. All arrays should contain the same number of samples.
- __batch_size__: int. Number of samples per gradient update.
- __nb_epoch__: int.
- __verbose__: 0 for no logging to stdout, 1 for progress bar logging, 2 for one log line per epoch.
- __callbacks__: `keras.callbacks.Callback` list. List of callbacks to apply during training. See [callbacks](callbacks.md).
- __validation_split__: float (0. < x < 1). Fraction of the data to use as held-out validation data.
- __validation_data__: tuple (X, y) to be used as held-out validation data. Will override validation_split.
- __shuffle__: boolean. Whether to shuffle the samples at each epoch.
- __evaluate__(data, batch_size=128, verbose=1): Show performance of the model over some validation data.
- __Return__: The loss score over the data.
- __Arguments__: Same meaning as fit method above. verbose is used as a binary flag (progress bar or nothing).
- __predict__(data, batch_size=128, verbose=1):
- __Return__: A dictionary mapping output names to arrays of predictions over the data.
- __Arguments__: Same meaning as fit method above. Only inputs need to be specified in `data`.
- __train_on_batch__(data): Single gradient update on one batch.
- __Return__: loss over the data.
- __test_on_batch__(data): Single performance evaluation on one batch.
- __Return__: loss over the data.
- __save_weights__(fname, overwrite=False): Store the weights of all layers to a HDF5 file. If `overwrite==False` and the file already exists, an exception will be thrown.
- __load_weights__(fname): Sets the weights of a model, based to weights stored by __save_weights__. You can only __load_weights__ on a savefile from a model with an identical architecture. __load_weights__ can be called either before or after the __compile__ step.
__Examples__:
```python
# graph model with one input and two outputs
graph = Graph()
graph.add_input(name='input', input_shape=(32,))
graph.add_node(Dense(16), name='dense1', input='input')
graph.add_node(Dense(4), name='dense2', input='input')
graph.add_node(Dense(4), name='dense3', input='dense1')
graph.add_output(name='output1', input='dense2')
graph.add_output(name='output2', input='dense3')
graph.compile('rmsprop', {'output1':'mse', 'output2':'mse'})
history = graph.fit({'input':X_train, 'output1':y_train, 'output2':y2_train}, nb_epoch=10)
```
```python
# graph model with two inputs and one output
graph = Graph()
graph.add_input(name='input1', input_shape=(32,))
graph.add_input(name='input2', input_shape=(32,))
graph.add_node(Dense(16), name='dense1', input='input1')
graph.add_node(Dense(4), name='dense2', input='input2')
graph.add_node(Dense(4), name='dense3', input='dense1')
graph.add_output(name='output', inputs=['dense2', 'dense3'], merge_mode='sum')
graph.compile('rmsprop', {'output':'mse'})
history = graph.fit({'input1':X_train, 'input2':X2_train, 'output':y_train}, nb_epoch=10)
predictions = graph.predict({'input1':X_test, 'input2':X2_test}) # {'output':...}
```
+7 -2
Ver Arquivo
@@ -7,18 +7,23 @@ An objective function (or loss function, or optimization score function) is one
model.compile(loss='mean_squared_error', optimizer='sgd')
```
You can either pass the name of an existing objective, or pass a Theano symbolic function that returns a scalar and takes the following two arguments:
You can either pass the name of an existing objective, or pass a Theano symbolic function that returns a scalar for each data-point and takes the following two arguments:
- __y_true__: True labels. Theano tensor.
- __y_pred__: Predictions. Theano tensor of the same shape as y_true.
The actual optimized objective is the mean of the output array across all datapoints.
For a few examples of such functions, check out the [objectives source](https://github.com/fchollet/keras/blob/master/keras/objectives.py).
## Available objectives
- __mean_squared_error__ / __mse__
- __root_mean_squared_error__ / __rmse__
- __mean_absolute_error__ / __mae__
- __mean_absolute_percentage_error__ / __mape__
- __mean_squared_logarithmic_error__ / __msle__
- __squared_hinge__
- __hinge__
- __binary_crossentropy__: Also known as logloss.
- __categorical_crossentropy__: Also known as multiclass logloss. __Note__: using this objective requires that your labels are binary arrays of shape `(nb_samples, nb_classes)`.
- __categorical_crossentropy__: Also known as multiclass logloss. __Note__: using this objective requires that your labels are binary arrays of shape `(nb_samples, nb_classes)`.
+5 -6
Ver Arquivo
@@ -5,7 +5,7 @@ An optimizer is one of the two arguments required for compiling a Keras model:
```python
model = Sequential()
model.add(Dense(20, 64, init='uniform'))
model.add(Dense(64, init='uniform', input_dim=10))
model.add(Activation('tanh'))
model.add(Activation('softmax'))
@@ -103,16 +103,15 @@ __Arguments__:
## Adam
```python
keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-8, kappa=1-1e-8)
keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-8)
```
Adam optimizer, proposed by Kingma and Lei Ba in [Adam: A Method For Stochastic Optimization](http://arxiv.org/pdf/1412.6980v4.pdf). Default parameters are those suggested in the paper. The parameter "lambda" from the paper has been renamed kappa, for syntactic reasons.
Adam optimizer, proposed by Kingma and Lei Ba in [Adam: A Method For Stochastic Optimization](http://arxiv.org/pdf/1412.6980v8.pdf). Default parameters are those suggested in the paper.
__Arguments__:
- __lr__: float >= 0. Learning rate.
- __lr__: float >= 0. Learning rate.
- __beta_1__, __beta_2__: floats, 0 < beta < 1. Generally close to 1.
- __epsilon__: float >= 0. Fuzz factor.
- __kappa__: float 0 < kappa < 1. Lambda parameter in the original paper.
---
---
+30 -8
Ver Arquivo
@@ -1,18 +1,40 @@
## Usage of regularizers
Regularizers allow to apply penalties on network parameters during optimization.
Regularizers allow to apply penalties on layer parameters or layer activity during optimization. These penalties are incorporated in the loss function that the network optimizes.
The keyword arguments used for passing penalties to parameters in a layer will depend on the layer.
The penalties are applied on a per-layer basis. The exact API will depend on the layer, but the layers `Dense`, `TimeDistributedDense`, `MaxoutDense`, `Convolution1D` and `Convolution2D` have a unified API.
In the `Dense` layer it is simply `W_regularizer` for the main weights matrix, and `b_regularizer` for the bias.
These layers expose 3 keyword arguments:
- `W_regularizer`: instance of `keras.regularizers.WeightRegularizer`
- `b_regularizer`: instance of `keras.regularizers.WeightRegularizer`
- `activity_regularizer`: instance of `keras.regularizers.ActivityRegularizer`
## Example
```python
from keras.regularizers import l2
model.add(Dense(64, 64, W_regularizer = l2(.01)))
from keras.regularizers import l2, activity_l2
model.add(Dense(64, input_dim=64, W_regularizer=l2(0.01), activity_regularizer=activity_l2(0.01)))
```
## Available penalties
- __l1__(l=0.01): L1 regularization penalty, also known as LASSO
- __l2__(l=0.01): L2 regularization penalty, also known as weight decay, or Ridge
- __l1l2__(l1=0.01, l2=0.01): L1-L2 regularization penalty, also known as ElasticNet
```python
keras.regularizers.WeightRegularizer(l1=0., l2=0.)
```
```python
keras.regularizers.ActivityRegularizer(l1=0., l2=0.)
```
## Shortcuts
These are shortcut functions available in `keras.regularizers`.
- __l1__(l=0.01): L1 weight regularization penalty, also known as LASSO
- __l2__(l=0.01): L2 weight regularization penalty, also known as weight decay, or Ridge
- __l1l2__(l1=0.01, l2=0.01): L1-L2 weight regularization penalty, also known as ElasticNet
- __activity_l1__(l=0.01): L1 activity regularization
- __activity_l2__(l=0.01): L2 activity regularization
- __activity_l1l2__(l1=0.01, l2=0.01): L1+L2 activity regularization
-28
Ver Arquivo
@@ -1,28 +0,0 @@
## Grapher
Creates a visualization of the model structure using `pydot`.
```python
grapher = keras.utils.dot_utils.Grapher()
```
- __Methods__:
- __plot__(model, to_file): creates a graph visualizing the structure of `model` and writes it to `to_file`.
- __Arguments__:
- __model__: an instance of a Keras model (e.g. `Sequential`)
- __to_file__: the filename to save the visualization png to.
__Examples__:
```python
from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.utils.dot_utils import Grapher
grapher = Grapher()
model = Sequential()
model.add(Dense(64, 2, init='uniform'))
model.add(Activation('softmax'))
grapher.plot(model, 'model.png')
```
+20
Ver Arquivo
@@ -0,0 +1,20 @@
## Model visualization
The `keras.utils.visualize_util` module provides utility functions to plot
a Keras model (using graphviz).
This will plot a graph of the model and save it to a file:
```python
from keras.utils.visualize_util import plot
plot(model, to_file='model.png')
```
You can also directly obtain the `pydot.Graph` object and render it yourself,
for example to show it in an ipython notebook :
```python
from IPython.display import SVG
from keras.utils.visualize_util import to_graph
SVG(to_graph(model).create(prog='dot', format='svg'))
```
+166
Ver Arquivo
@@ -0,0 +1,166 @@
# -*- coding: utf-8 -*-
from __future__ import print_function
from keras.models import Sequential, slice_X
from keras.layers.core import Activation, TimeDistributedDense, RepeatVector
from keras.layers import recurrent
import numpy as np
from six.moves import range
"""
An implementation of sequence to sequence learning for performing addition
Input: "535+61"
Output: "596"
Padding is handled by using a repeated sentinel character (space)
Input may optionally be inverted, shown to increase performance in many tasks in:
"Learning to Execute"
http://arxiv.org/abs/1410.4615
and
"Sequence to Sequence Learning with Neural Networks"
http://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf
Theoretically it introduces shorter term dependencies between source and target.
Two digits inverted:
+ One layer LSTM (128 HN), 5k training examples = 99% train/test accuracy in 55 epochs
Three digits inverted:
+ One layer LSTM (128 HN), 50k training examples = 99% train/test accuracy in 100 epochs
Four digits inverted:
+ One layer LSTM (128 HN), 400k training examples = 99% train/test accuracy in 20 epochs
Five digits inverted:
+ One layer LSTM (128 HN), 550k training examples = 99% train/test accuracy in 30 epochs
"""
class CharacterTable(object):
"""
Given a set of characters:
+ Encode them to a one hot integer representation
+ Decode the one hot integer representation to their character output
+ Decode a vector of probabilties to their character output
"""
def __init__(self, chars, maxlen):
self.chars = sorted(set(chars))
self.char_indices = dict((c, i) for i, c in enumerate(self.chars))
self.indices_char = dict((i, c) for i, c in enumerate(self.chars))
self.maxlen = maxlen
def encode(self, C, maxlen=None):
maxlen = maxlen if maxlen else self.maxlen
X = np.zeros((maxlen, len(self.chars)))
for i, c in enumerate(C):
X[i, self.char_indices[c]] = 1
return X
def decode(self, X, calc_argmax=True):
if calc_argmax:
X = X.argmax(axis=-1)
return ''.join(self.indices_char[x] for x in X)
class colors:
ok = '\033[92m'
fail = '\033[91m'
close = '\033[0m'
# Parameters for the model and dataset
TRAINING_SIZE = 50000
DIGITS = 3
INVERT = True
# Try replacing GRU, or SimpleRNN
RNN = recurrent.LSTM
HIDDEN_SIZE = 128
BATCH_SIZE = 128
LAYERS = 1
MAXLEN = DIGITS + 1 + DIGITS
chars = '0123456789+ '
ctable = CharacterTable(chars, MAXLEN)
questions = []
expected = []
seen = set()
print('Generating data...')
while len(questions) < TRAINING_SIZE:
f = lambda: int(''.join(np.random.choice(list('0123456789')) for i in range(np.random.randint(1, DIGITS + 1))))
a, b = f(), f()
# Skip any addition questions we've already seen
# Also skip any such that X+Y == Y+X (hence the sorting)
key = tuple(sorted((a, b)))
if key in seen:
continue
seen.add(key)
# Pad the data with spaces such that it is always MAXLEN
q = '{}+{}'.format(a, b)
query = q + ' ' * (MAXLEN - len(q))
ans = str(a + b)
# Answers can be of maximum size DIGITS + 1
ans += ' ' * (DIGITS + 1 - len(ans))
if INVERT:
query = query[::-1]
questions.append(query)
expected.append(ans)
print('Total addition questions:', len(questions))
print('Vectorization...')
X = np.zeros((len(questions), MAXLEN, len(chars)), dtype=np.bool)
y = np.zeros((len(questions), DIGITS + 1, len(chars)), dtype=np.bool)
for i, sentence in enumerate(questions):
X[i] = ctable.encode(sentence, maxlen=MAXLEN)
for i, sentence in enumerate(expected):
y[i] = ctable.encode(sentence, maxlen=DIGITS + 1)
# Shuffle (X, y) in unison as the later parts of X will almost all be larger digits
indices = np.arange(len(y))
np.random.shuffle(indices)
X = X[indices]
y = y[indices]
# Explicitly set apart 10% for validation data that we never train over
split_at = len(X) - len(X) / 10
(X_train, X_val) = (slice_X(X, 0, split_at), slice_X(X, split_at))
(y_train, y_val) = (y[:split_at], y[split_at:])
print(X_train.shape)
print(y_train.shape)
print('Build model...')
model = Sequential()
# "Encode" the input sequence using an RNN, producing an output of HIDDEN_SIZE
# note: in a situation where your input sequences have a variable length,
# use input_shape=(None, nb_feature).
model.add(RNN(HIDDEN_SIZE, input_shape=(MAXLEN, len(chars))))
# For the decoder's input, we repeat the encoded input for each time step
model.add(RepeatVector(DIGITS + 1))
# The decoder RNN could be multiple layers stacked or a single layer
for _ in range(LAYERS):
model.add(RNN(HIDDEN_SIZE, return_sequences=True))
# For each of step of the output sequence, decide which character should be chosen
model.add(TimeDistributedDense(len(chars)))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam')
# Train the model each generation and show predictions against the validation dataset
for iteration in range(1, 200):
print()
print('-' * 50)
print('Iteration', iteration)
model.fit(X_train, y_train, batch_size=BATCH_SIZE, nb_epoch=1, validation_data=(X_val, y_val), show_accuracy=True)
###
# Select 10 samples from the validation set at random so we can visualize errors
for i in range(10):
ind = np.random.randint(0, len(X_val))
rowX, rowy = X_val[np.array([ind])], y_val[np.array([ind])]
preds = model.predict_classes(rowX, verbose=0)
q = ctable.decode(rowX[0])
correct = ctable.decode(rowy[0])
guess = ctable.decode(preds[0], calc_argmax=False)
print('Q', q[::-1] if INVERT else q)
print('T', correct)
print(colors.ok + '' + colors.close if correct == guess else colors.fail + '' + colors.close, guess)
print('---')
+203
Ver Arquivo
@@ -0,0 +1,203 @@
from __future__ import print_function
from keras.models import Sequential
from keras.layers.embeddings import Embedding
from keras.layers.core import Activation, Dense, Merge, Permute, Dropout
from keras.layers.recurrent import LSTM
from keras.datasets.data_utils import get_file
from keras.preprocessing.sequence import pad_sequences
from functools import reduce
import tarfile
import numpy as np
import re
"""
Train a memory network on the bAbI dataset.
References:
- Jason Weston, Antoine Bordes, Sumit Chopra, Tomas Mikolov, Alexander M. Rush,
"Towards AI-Complete Question Answering: A Set of Prerequisite Toy Tasks",
http://arxiv.org/abs/1503.08895
- Sainbayar Sukhbaatar, Arthur Szlam, Jason Weston, Rob Fergus,
"End-To-End Memory Networks",
http://arxiv.org/abs/1503.08895
Reaches 93% accuracy on task 'single_supporting_fact_10k' after 70 epochs.
Time per epoch: 3s on CPU (core i7).
"""
def tokenize(sent):
'''Return the tokens of a sentence including punctuation.
>>> tokenize('Bob dropped the apple. Where is the apple?')
['Bob', 'dropped', 'the', 'apple', '.', 'Where', 'is', 'the', 'apple', '?']
'''
return [x.strip() for x in re.split('(\W+)?', sent) if x.strip()]
def parse_stories(lines, only_supporting=False):
'''Parse stories provided in the bAbi tasks format
If only_supporting is true, only the sentences that support the answer are kept.
'''
data = []
story = []
for line in lines:
line = line.decode('utf-8').strip()
nid, line = line.split(' ', 1)
nid = int(nid)
if nid == 1:
story = []
if '\t' in line:
q, a, supporting = line.split('\t')
q = tokenize(q)
substory = None
if only_supporting:
# Only select the related substory
supporting = map(int, supporting.split())
substory = [story[i - 1] for i in supporting]
else:
# Provide all the substories
substory = [x for x in story if x]
data.append((substory, q, a))
story.append('')
else:
sent = tokenize(line)
story.append(sent)
return data
def get_stories(f, only_supporting=False, max_length=None):
'''Given a file name, read the file, retrieve the stories, and then convert the sentences into a single story.
If max_length is supplied, any stories longer than max_length tokens will be discarded.
'''
data = parse_stories(f.readlines(), only_supporting=only_supporting)
flatten = lambda data: reduce(lambda x, y: x + y, data)
data = [(flatten(story), q, answer) for story, q, answer in data if not max_length or len(flatten(story)) < max_length]
return data
def vectorize_stories(data, word_idx, story_maxlen, query_maxlen):
X = []
Xq = []
Y = []
for story, query, answer in data:
x = [word_idx[w] for w in story]
xq = [word_idx[w] for w in query]
y = np.zeros(len(word_idx) + 1) # let's not forget that index 0 is reserved
y[word_idx[answer]] = 1
X.append(x)
Xq.append(xq)
Y.append(y)
return (pad_sequences(X, maxlen=story_maxlen),
pad_sequences(Xq, maxlen=query_maxlen), np.array(Y))
path = get_file('babi-tasks-v1-2.tar.gz',
origin='http://www.thespermwhale.com/jaseweston/babi/tasks_1-20_v1-2.tar.gz')
tar = tarfile.open(path)
challenges = {
# QA1 with 10,000 samples
'single_supporting_fact_10k': 'tasks_1-20_v1-2/en-10k/qa1_single-supporting-fact_{}.txt',
# QA2 with 10,000 samples
'two_supporting_facts_10k': 'tasks_1-20_v1-2/en-10k/qa2_two-supporting-facts_{}.txt',
}
challenge_type = 'single_supporting_fact_10k'
challenge = challenges[challenge_type]
print('Extracting stories for the challenge:', challenge_type)
train_stories = get_stories(tar.extractfile(challenge.format('train')))
test_stories = get_stories(tar.extractfile(challenge.format('test')))
vocab = sorted(reduce(lambda x, y: x | y, (set(story + q + [answer]) for story, q, answer in train_stories + test_stories)))
# Reserve 0 for masking via pad_sequences
vocab_size = len(vocab) + 1
story_maxlen = max(map(len, (x for x, _, _ in train_stories + test_stories)))
query_maxlen = max(map(len, (x for _, x, _ in train_stories + test_stories)))
print('-')
print('Vocab size:', vocab_size, 'unique words')
print('Story max length:', story_maxlen, 'words')
print('Query max length:', query_maxlen, 'words')
print('Number of training stories:', len(train_stories))
print('Number of test stories:', len(test_stories))
print('-')
print('Here\'s what a "story" tuple looks like (input, query, answer):')
print(train_stories[0])
print('-')
print('Vectorizing the word sequences...')
word_idx = dict((c, i + 1) for i, c in enumerate(vocab))
inputs_train, queries_train, answers_train = vectorize_stories(train_stories, word_idx, story_maxlen, query_maxlen)
inputs_test, queries_test, answers_test = vectorize_stories(test_stories, word_idx, story_maxlen, query_maxlen)
print('-')
print('inputs: integer tensor of shape (samples, max_length)')
print('inputs_train shape:', inputs_train.shape)
print('inputs_test shape:', inputs_test.shape)
print('-')
print('queries: integer tensor of shape (samples, max_length)')
print('queries_train shape:', queries_train.shape)
print('queries_test shape:', queries_test.shape)
print('-')
print('answers: binary (1 or 0) tensor of shape (samples, vocab_size)')
print('answers_train shape:', answers_train.shape)
print('answers_test shape:', answers_test.shape)
print('-')
print('Compiling...')
# embed the input sequence into a sequence of vectors
input_encoder_m = Sequential()
input_encoder_m.add(Embedding(input_dim=vocab_size,
output_dim=64,
input_length=story_maxlen))
# output: (samples, story_maxlen, embedding_dim)
# embed the question into a sequence of vectors
question_encoder = Sequential()
question_encoder.add(Embedding(input_dim=vocab_size,
output_dim=64,
input_length=query_maxlen))
# output: (samples, query_maxlen, embedding_dim)
# compute a 'match' between input sequence elements (which are vectors)
# and the question vector sequence
match = Sequential()
match.add(Merge([input_encoder_m, question_encoder],
mode='dot',
dot_axes=[(2,), (2,)]))
# output: (samples, story_maxlen, query_maxlen)
# embed the input into a single vector with size = story_maxlen:
input_encoder_c = Sequential()
input_encoder_c.add(Embedding(input_dim=vocab_size,
output_dim=query_maxlen,
input_length=story_maxlen))
# output: (samples, story_maxlen, query_maxlen)
# sum the match vector with the input vector:
response = Sequential()
response.add(Merge([match, input_encoder_c], mode='sum'))
# output: (samples, story_maxlen, query_maxlen)
response.add(Permute((2, 1))) # output: (samples, query_maxlen, story_maxlen)
# concatenate the match vector with the question vector,
# and do logistic regression on top
answer = Sequential()
answer.add(Merge([response, question_encoder], mode='concat', concat_axis=-1))
# the original paper uses a matrix multiplication for this reduction step.
# we choose to use a RNN instead.
answer.add(LSTM(64))
# one regularization layer -- more would probably be needed.
answer.add(Dropout(0.25))
answer.add(Dense(vocab_size))
# we output a probability distribution over the vocabulary
answer.add(Activation('softmax'))
answer.compile(optimizer='rmsprop', loss='categorical_crossentropy')
# Note: you could use a Graph model to avoid repeat the input twice
answer.fit([inputs_train, queries_train, inputs_train], answers_train,
batch_size=32,
nb_epoch=70,
show_accuracy=True,
validation_data=([inputs_test, queries_test, inputs_test], answers_test))
+199
Ver Arquivo
@@ -0,0 +1,199 @@
from __future__ import absolute_import
from __future__ import print_function
from functools import reduce
import re
import tarfile
import numpy as np
np.random.seed(1337) # for reproducibility
from keras.datasets.data_utils import get_file
from keras.layers.embeddings import Embedding
from keras.layers.core import Dense, Merge
from keras.layers import recurrent
from keras.models import Sequential
from keras.preprocessing.sequence import pad_sequences
'''
Trains two recurrent neural networks based upon a story and a question.
The resulting merged vector is then queried to answer a range of bAbI tasks.
The results are comparable to those for an LSTM model provided in Weston et al.:
"Towards AI-Complete Question Answering: A Set of Prerequisite Toy Tasks"
http://arxiv.org/abs/1502.05698
Task Number | FB LSTM Baseline | Keras QA
--- | --- | ---
QA1 - Single Supporting Fact | 50 | 52.1
QA2 - Two Supporting Facts | 20 | 37.0
QA3 - Three Supporting Facts | 20 | 20.5
QA4 - Two Arg. Relations | 61 | 62.9
QA5 - Three Arg. Relations | 70 | 61.9
QA6 - Yes/No Questions | 48 | 50.7
QA7 - Counting | 49 | 78.9
QA8 - Lists/Sets | 45 | 77.2
QA9 - Simple Negation | 64 | 64.0
QA10 - Indefinite Knowledge | 44 | 47.7
QA11 - Basic Coreference | 72 | 74.9
QA12 - Conjunction | 74 | 76.4
QA13 - Compound Coreference | 94 | 94.4
QA14 - Time Reasoning | 27 | 34.8
QA15 - Basic Deduction | 21 | 32.4
QA16 - Basic Induction | 23 | 50.6
QA17 - Positional Reasoning | 51 | 49.1
QA18 - Size Reasoning | 52 | 90.8
QA19 - Path Finding | 8 | 9.0
QA20 - Agent's Motivations | 91 | 90.7
For the resources related to the bAbI project, refer to:
https://research.facebook.com/researchers/1543934539189348
Notes:
- With default word, sentence, and query vector sizes, the GRU model achieves:
- 52.1% test accuracy on QA1 in 20 epochs (2 seconds per epoch on CPU)
- 37.0% test accuracy on QA2 in 20 epochs (16 seconds per epoch on CPU)
In comparison, the Facebook paper achieves 50% and 20% for the LSTM baseline.
- The task does not traditionally parse the question separately. This likely
improves accuracy and is a good example of merging two RNNs.
- The word vector embeddings are not shared between the story and question RNNs.
- See how the accuracy changes given 10,000 training samples (en-10k) instead
of only 1000. 1000 was used in order to be comparable to the original paper.
- Experiment with GRU, LSTM, and JZS1-3 as they give subtly different results.
- The length and noise (i.e. 'useless' story components) impact the ability for
LSTMs / GRUs to provide the correct answer. Given only the supporting facts,
these RNNs can achieve 100% accuracy on many tasks. Memory networks and neural
networks that use attentional processes can efficiently search through this
noise to find the relevant statements, improving performance substantially.
This becomes especially obvious on QA2 and QA3, both far longer than QA1.
'''
def tokenize(sent):
'''Return the tokens of a sentence including punctuation.
>>> tokenize('Bob dropped the apple. Where is the apple?')
['Bob', 'dropped', 'the', 'apple', '.', 'Where', 'is', 'the', 'apple', '?']
'''
return [x.strip() for x in re.split('(\W+)?', sent) if x.strip()]
def parse_stories(lines, only_supporting=False):
'''Parse stories provided in the bAbi tasks format
If only_supporting is true, only the sentences that support the answer are kept.
'''
data = []
story = []
for line in lines:
line = line.decode('utf-8').strip()
nid, line = line.split(' ', 1)
nid = int(nid)
if nid == 1:
story = []
if '\t' in line:
q, a, supporting = line.split('\t')
q = tokenize(q)
substory = None
if only_supporting:
# Only select the related substory
supporting = map(int, supporting.split())
substory = [story[i - 1] for i in supporting]
else:
# Provide all the substories
substory = [x for x in story if x]
data.append((substory, q, a))
story.append('')
else:
sent = tokenize(line)
story.append(sent)
return data
def get_stories(f, only_supporting=False, max_length=None):
'''Given a file name, read the file, retrieve the stories, and then convert the sentences into a single story.
If max_length is supplied, any stories longer than max_length tokens will be discarded.
'''
data = parse_stories(f.readlines(), only_supporting=only_supporting)
flatten = lambda data: reduce(lambda x, y: x + y, data)
data = [(flatten(story), q, answer) for story, q, answer in data if not max_length or len(flatten(story)) < max_length]
return data
def vectorize_stories(data, word_idx, story_maxlen, query_maxlen):
X = []
Xq = []
Y = []
for story, query, answer in data:
x = [word_idx[w] for w in story]
xq = [word_idx[w] for w in query]
y = np.zeros(len(word_idx) + 1) # let's not forget that index 0 is reserved
y[word_idx[answer]] = 1
X.append(x)
Xq.append(xq)
Y.append(y)
return pad_sequences(X, maxlen=story_maxlen), pad_sequences(Xq, maxlen=query_maxlen), np.array(Y)
RNN = recurrent.GRU
EMBED_HIDDEN_SIZE = 50
SENT_HIDDEN_SIZE = 100
QUERY_HIDDEN_SIZE = 100
BATCH_SIZE = 32
EPOCHS = 20
print('RNN / Embed / Sent / Query = {}, {}, {}, {}'.format(RNN, EMBED_HIDDEN_SIZE, SENT_HIDDEN_SIZE, QUERY_HIDDEN_SIZE))
path = get_file('babi-tasks-v1-2.tar.gz', origin='http://www.thespermwhale.com/jaseweston/babi/tasks_1-20_v1-2.tar.gz')
tar = tarfile.open(path)
# Default QA1 with 1000 samples
# challenge = 'tasks_1-20_v1-2/en/qa1_single-supporting-fact_{}.txt'
# QA1 with 10,000 samples
# challenge = 'tasks_1-20_v1-2/en-10k/qa1_single-supporting-fact_{}.txt'
# QA2 with 1000 samples
challenge = 'tasks_1-20_v1-2/en/qa2_two-supporting-facts_{}.txt'
# QA2 with 10,000 samples
# challenge = 'tasks_1-20_v1-2/en-10k/qa2_two-supporting-facts_{}.txt'
train = get_stories(tar.extractfile(challenge.format('train')))
test = get_stories(tar.extractfile(challenge.format('test')))
vocab = sorted(reduce(lambda x, y: x | y, (set(story + q + [answer]) for story, q, answer in train + test)))
# Reserve 0 for masking via pad_sequences
vocab_size = len(vocab) + 1
word_idx = dict((c, i + 1) for i, c in enumerate(vocab))
story_maxlen = max(map(len, (x for x, _, _ in train + test)))
query_maxlen = max(map(len, (x for _, x, _ in train + test)))
X, Xq, Y = vectorize_stories(train, word_idx, story_maxlen, query_maxlen)
tX, tXq, tY = vectorize_stories(test, word_idx, story_maxlen, query_maxlen)
print('vocab = {}'.format(vocab))
print('X.shape = {}'.format(X.shape))
print('Xq.shape = {}'.format(Xq.shape))
print('Y.shape = {}'.format(Y.shape))
print('story_maxlen, query_maxlen = {}, {}'.format(story_maxlen, query_maxlen))
print('Build model...')
sentrnn = Sequential()
sentrnn.add(Embedding(vocab_size, EMBED_HIDDEN_SIZE, mask_zero=True))
sentrnn.add(RNN(SENT_HIDDEN_SIZE, return_sequences=False))
qrnn = Sequential()
qrnn.add(Embedding(vocab_size, EMBED_HIDDEN_SIZE))
qrnn.add(RNN(QUERY_HIDDEN_SIZE, return_sequences=False))
model = Sequential()
model.add(Merge([sentrnn, qrnn], mode='concat'))
model.add(Dense(vocab_size, activation='softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy', class_mode='categorical')
print('Training')
model.fit([X, Xq], Y, batch_size=BATCH_SIZE, nb_epoch=EPOCHS, validation_split=0.05, show_accuracy=True)
loss, acc = model.evaluate([tX, tXq], tY, batch_size=BATCH_SIZE, show_accuracy=True)
print('Test loss / test accuracy = {:.4f} / {:.4f}'.format(loss, acc))
+36 -38
Ver Arquivo
@@ -19,7 +19,7 @@ from six.moves import range
(it's still underfitting at that point, though).
Note: the data was pickled with Python 2, and some encoding issues might prevent you
from loading it in Python 3. You might have to load it in Python 2,
from loading it in Python 3. You might have to load it in Python 2,
save it in a different format, load it in Python 3 and repickle it.
'''
@@ -28,8 +28,14 @@ nb_classes = 10
nb_epoch = 200
data_augmentation = True
# the data, shuffled and split between tran and test sets
# input image dimensions
img_rows, img_cols = 32, 32
# the CIFAR10 images are RGB
img_channels = 3
# the data, shuffled and split between train and test sets
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
print('X_train shape:', X_train.shape)
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')
@@ -39,40 +45,40 @@ Y_test = np_utils.to_categorical(y_test, nb_classes)
model = Sequential()
model.add(Convolution2D(32, 3, 3, 3, border_mode='full'))
model.add(Convolution2D(32, 3, 3, border_mode='same',
input_shape=(img_channels, img_rows, img_cols)))
model.add(Activation('relu'))
model.add(Convolution2D(32, 32, 3, 3))
model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Convolution2D(64, 32, 3, 3, border_mode='full'))
model.add(Convolution2D(64, 3, 3, border_mode='same'))
model.add(Activation('relu'))
model.add(Convolution2D(64, 64, 3, 3))
model.add(Convolution2D(64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(64*8*8, 512, init='normal'))
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(512, nb_classes, init='normal'))
model.add(Dense(nb_classes))
model.add(Activation('softmax'))
# let's train the model using SGD + momentum (how original).
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)
X_train = X_train.astype("float32")
X_test = X_test.astype("float32")
X_train /= 255
X_test /= 255
if not data_augmentation:
print("Not using data augmentation or normalization")
X_train = X_train.astype("float32")
X_test = X_test.astype("float32")
X_train /= 255
X_test /= 255
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=10)
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch)
score = model.evaluate(X_test, Y_test, batch_size=batch_size)
print('Test score:', score)
@@ -81,18 +87,18 @@ else:
# this will do preprocessing and realtime data augmentation
datagen = ImageDataGenerator(
featurewise_center=True, # set input mean to 0 over the dataset
samplewise_center=False, # set each sample mean to 0
featurewise_std_normalization=True, # divide inputs by std of the dataset
samplewise_std_normalization=False, # divide each input by its std
zca_whitening=False, # apply ZCA whitening
rotation_range=20, # randomly rotate images in the range (degrees, 0 to 180)
width_shift_range=0.2, # randomly shift images horizontally (fraction of total width)
height_shift_range=0.2, # randomly shift images vertically (fraction of total height)
horizontal_flip=True, # randomly flip images
vertical_flip=False) # randomly flip images
featurewise_center=True, # set input mean to 0 over the dataset
samplewise_center=False, # set each sample mean to 0
featurewise_std_normalization=True, # divide inputs by std of the dataset
samplewise_std_normalization=False, # divide each input by its std
zca_whitening=False, # apply ZCA whitening
rotation_range=20, # randomly rotate images in the range (degrees, 0 to 180)
width_shift_range=0.2, # randomly shift images horizontally (fraction of total width)
height_shift_range=0.2, # randomly shift images vertically (fraction of total height)
horizontal_flip=True, # randomly flip images
vertical_flip=False) # randomly flip images
# compute quantities required for featurewise normalization
# compute quantities required for featurewise normalization
# (std, mean, and principal components if ZCA whitening is applied)
datagen.fit(X_train)
@@ -104,20 +110,12 @@ else:
# batch train with realtime data augmentation
progbar = generic_utils.Progbar(X_train.shape[0])
for X_batch, Y_batch in datagen.flow(X_train, Y_train):
loss = model.train(X_batch, Y_batch)
loss = model.train_on_batch(X_batch, Y_batch)
progbar.add(X_batch.shape[0], values=[("train loss", loss)])
print("Testing...")
# test time!
progbar = generic_utils.Progbar(X_test.shape[0])
for X_batch, Y_batch in datagen.flow(X_test, Y_test):
score = model.test(X_batch, Y_batch)
score = model.test_on_batch(X_batch, Y_batch)
progbar.add(X_batch.shape[0], values=[("test loss", score)])
+63
Ver Arquivo
@@ -0,0 +1,63 @@
from __future__ import absolute_import
from __future__ import print_function
import numpy as np
np.random.seed(1337) # for reproducibility
from keras.preprocessing import sequence
from keras.utils.np_utils import accuracy
from keras.models import Graph
from keras.layers.core import Dense, Dropout
from keras.layers.embeddings import Embedding
from keras.layers.recurrent import LSTM
from keras.datasets import imdb
'''
Train a Bidirectional LSTM on the IMDB sentiment classification task.
GPU command:
THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python imdb_bidirectional_lstm.py
Output after 4 epochs on CPU: ~0.8146
Time per epoch on CPU (Core i7): ~150s.
'''
max_features = 20000
maxlen = 100 # cut texts after this number of words (among top max_features most common words)
batch_size = 32
print("Loading data...")
(X_train, y_train), (X_test, y_test) = imdb.load_data(nb_words=max_features,
test_split=0.2)
print(len(X_train), 'train sequences')
print(len(X_test), 'test sequences')
print("Pad sequences (samples x time)")
X_train = sequence.pad_sequences(X_train, maxlen=maxlen)
X_test = sequence.pad_sequences(X_test, maxlen=maxlen)
print('X_train shape:', X_train.shape)
print('X_test shape:', X_test.shape)
y_train = np.array(y_train)
y_test = np.array(y_test)
print('Build model...')
model = Graph()
model.add_input(name='input', input_shape=(maxlen,), dtype=int)
model.add_node(Embedding(max_features, 128, input_length=maxlen),
name='embedding', input='input')
model.add_node(LSTM(64), name='forward', input='embedding')
model.add_node(LSTM(64, go_backwards=True), name='backward', input='embedding')
model.add_node(Dropout(0.5), name='dropout', inputs=['forward', 'backward'])
model.add_node(Dense(1, activation='sigmoid'), name='sigmoid', input='dropout')
model.add_output(name='output', input='sigmoid')
# try using different optimizers and different optimizer configs
model.compile('adam', {'output': 'binary_crossentropy'})
print("Train...")
model.fit({'input': X_train, 'output': y_train},
batch_size=batch_size,
nb_epoch=4)
acc = accuracy(y_test,
np.round(np.array(model.predict({'input': X_test},
batch_size=batch_size)['output'])))
print('Test accuracy:', acc)
+80
Ver Arquivo
@@ -0,0 +1,80 @@
from __future__ import absolute_import
from __future__ import print_function
import numpy as np
np.random.seed(1337) # for reproducibility
from keras.preprocessing import sequence
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.embeddings import Embedding
from keras.layers.convolutional import Convolution1D, MaxPooling1D
from keras.datasets import imdb
'''
This example demonstrates the use of Convolution1D
for text classification.
Run on GPU: THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python imdb_cnn.py
Get to 0.835 test accuracy after 2 epochs. 100s/epoch on K520 GPU.
'''
# set parameters:
max_features = 5000
maxlen = 100
batch_size = 32
embedding_dims = 100
nb_filter = 250
filter_length = 3
hidden_dims = 250
nb_epoch = 2
print("Loading data...")
(X_train, y_train), (X_test, y_test) = imdb.load_data(nb_words=max_features,
test_split=0.2)
print(len(X_train), 'train sequences')
print(len(X_test), 'test sequences')
print("Pad sequences (samples x time)")
X_train = sequence.pad_sequences(X_train, maxlen=maxlen)
X_test = sequence.pad_sequences(X_test, maxlen=maxlen)
print('X_train shape:', X_train.shape)
print('X_test shape:', X_test.shape)
print('Build model...')
model = Sequential()
# we start off with an efficient embedding layer which maps
# our vocab indices into embedding_dims dimensions
model.add(Embedding(max_features, embedding_dims, input_length=maxlen))
model.add(Dropout(0.25))
# we add a Convolution1D, which will learn nb_filter
# word group filters of size filter_length:
model.add(Convolution1D(nb_filter=nb_filter,
filter_length=filter_length,
border_mode="valid",
activation="relu",
subsample_length=1))
# we use standard max pooling (halving the output of the previous layer):
model.add(MaxPooling1D(pool_length=2))
# We flatten the output of the conv layer,
# so that we can add a vanilla dense layer:
model.add(Flatten())
# We add a vanilla hidden layer:
model.add(Dense(hidden_dims))
model.add(Dropout(0.25))
model.add(Activation('relu'))
# We project onto a single unit output layer, and squash it with a sigmoid:
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
class_mode="binary")
model.fit(X_train, y_train, batch_size=batch_size,
nb_epoch=nb_epoch, show_accuracy=True,
validation_data=(X_test, y_test))
+84
Ver Arquivo
@@ -0,0 +1,84 @@
from __future__ import absolute_import
from __future__ import print_function
import numpy as np
np.random.seed(1337) # for reproducibility
from keras.preprocessing import sequence
from keras.optimizers import SGD, RMSprop, Adagrad
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.layers.embeddings import Embedding
from keras.layers.recurrent import LSTM, GRU, SimpleRNN
from keras.layers.convolutional import Convolution1D, MaxPooling1D
from keras.datasets import imdb
'''
Train a recurrent convolutional network on the IMDB sentiment classification task.
GPU command:
THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python imdb_lstm.py
Get to 0.8498 test accuracy after 2 epochs. 41s/epoch on K520 GPU.
'''
# Embedding
max_features = 20000
maxlen = 100
embedding_size = 128
# Convolution
filter_length = 3
nb_filter = 64
pool_length = 2
# LSTM
lstm_output_size = 70
# Training
batch_size = 30
nb_epoch = 2
'''
Note:
batch_size is highly sensitive.
Only 2 epochs are needed as the dataset is very small.
'''
print("Loading data...")
(X_train, y_train), (X_test, y_test) = imdb.load_data(nb_words=max_features, test_split=0.2)
print(len(X_train), 'train sequences')
print(len(X_test), 'test sequences')
print("Pad sequences (samples x time)")
X_train = sequence.pad_sequences(X_train, maxlen=maxlen)
X_test = sequence.pad_sequences(X_test, maxlen=maxlen)
print('X_train shape:', X_train.shape)
print('X_test shape:', X_test.shape)
print('Build model...')
model = Sequential()
model.add(Embedding(max_features, embedding_size, input_length=maxlen))
model.add(Dropout(0.25))
model.add(Convolution1D(nb_filter=nb_filter,
filter_length=filter_length,
border_mode="valid",
activation="relu",
subsample_length=1))
model.add(MaxPooling1D(pool_length=pool_length))
model.add(LSTM(lstm_output_size))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='adam',
class_mode="binary")
print("Train...")
model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=nb_epoch,
validation_data=(X_test, y_test), show_accuracy=True)
score, acc = model.evaluate(X_test, y_test, batch_size=batch_size,
show_accuracy=True)
print('Test score:', score)
print('Test accuracy:', acc)
+25 -26
Ver Arquivo
@@ -1,44 +1,42 @@
from __future__ import absolute_import
from __future__ import print_function
import numpy as np
np.random.seed(1337) # for reproducibility
from keras.preprocessing import sequence
from keras.optimizers import SGD, RMSprop, Adagrad
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.layers.embeddings import Embedding
from keras.layers.recurrent import LSTM, GRU
from keras.layers.recurrent import LSTM
from keras.datasets import imdb
'''
Train a LSTM on the IMDB sentiment classification task.
The dataset is actually too small for LSTM to be of any advantage
The dataset is actually too small for LSTM to be of any advantage
compared to simpler, much faster methods such as TF-IDF+LogReg.
Notes:
Notes:
- RNNs are tricky. Choice of batch size is important,
choice of loss and optimizer is critical, etc.
Most configurations won't converge.
- RNNs are tricky. Choice of batch size is important,
choice of loss and optimizer is critical, etc.
Some configurations won't converge.
- LSTM loss decrease during training can be quite different
from what you see with CNNs/MLPs/etc. It's more or less a sigmoid
instead of an inverse exponential.
- LSTM loss decrease patterns during training can be quite different
from what you see with CNNs/MLPs/etc.
GPU command:
THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python imdb_lstm.py
250s/epoch on GPU (GT 650M), vs. 400s/epoch on CPU (2.4Ghz Core i7).
'''
max_features=20000
maxlen = 100 # cut texts after this number of words (among top max_features most common words)
batch_size = 16
max_features = 20000
maxlen = 100 # cut texts after this number of words (among top max_features most common words)
batch_size = 32
print("Loading data...")
(X_train, y_train), (X_test, y_test) = imdb.load_data(nb_words=max_features, test_split=0.2)
(X_train, y_train), (X_test, y_test) = imdb.load_data(nb_words=max_features,
test_split=0.2)
print(len(X_train), 'train sequences')
print(len(X_test), 'test sequences')
@@ -50,21 +48,22 @@ print('X_test shape:', X_test.shape)
print('Build model...')
model = Sequential()
model.add(Embedding(max_features, 256))
model.add(LSTM(256, 128)) # try using a GRU instead, for fun
model.add(Embedding(max_features, 128, input_length=maxlen))
model.add(LSTM(128)) # try using a GRU instead, for fun
model.add(Dropout(0.5))
model.add(Dense(128, 1))
model.add(Dense(1))
model.add(Activation('sigmoid'))
# try using different optimizers and different optimizer configs
model.compile(loss='binary_crossentropy', optimizer='adam', class_mode="binary")
model.compile(loss='binary_crossentropy',
optimizer='adam',
class_mode="binary")
print("Train...")
model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=5, validation_split=0.1, show_accuracy=True)
score = model.evaluate(X_test, y_test, batch_size=batch_size)
model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=3,
validation_data=(X_test, y_test), show_accuracy=True)
score, acc = model.evaluate(X_test, y_test,
batch_size=batch_size,
show_accuracy=True)
print('Test score:', score)
classes = model.predict_classes(X_test, batch_size=batch_size)
acc = np_utils.accuracy(classes, y_test)
print('Test accuracy:', acc)
+18 -19
Ver Arquivo
@@ -3,6 +3,7 @@ from __future__ import print_function
import numpy as np
import pandas as pd
np.random.seed(1337) # for reproducibility
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
@@ -17,13 +18,13 @@ from sklearn.preprocessing import StandardScaler
This demonstrates how to reach a score of 0.4890 (local validation)
on the Kaggle Otto challenge, with a deep net using Keras.
Compatible Python 2.7-3.4
Compatible Python 2.7-3.4. Requires Scikit-Learn and Pandas.
Recommended to run on GPU:
Recommended to run on GPU:
Command: THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python kaggle_otto_nn.py
On EC2 g2.2xlarge instance: 19s/epoch. 6-7 minutes total training time.
Best validation score at epoch 21: 0.4881
Best validation score at epoch 21: 0.4881
Try it at home:
- with/without BatchNormalization (BatchNormalization helps!)
@@ -35,19 +36,19 @@ from sklearn.preprocessing import StandardScaler
Get the data from Kaggle: https://www.kaggle.com/c/otto-group-product-classification-challenge/data
'''
np.random.seed(1337) # for reproducibility
def load_data(path, train=True):
df = pd.read_csv(path)
X = df.values.copy()
if train:
np.random.shuffle(X) # https://youtu.be/uyUXoap67N8
np.random.shuffle(X) # https://youtu.be/uyUXoap67N8
X, labels = X[:, 1:-1].astype(np.float32), X[:, -1]
return X, labels
else:
X, ids = X[:, 1:].astype(np.float32), X[:, 0].astype(str)
return X, ids
def preprocess_data(X, scaler=None):
if not scaler:
scaler = StandardScaler()
@@ -55,6 +56,7 @@ def preprocess_data(X, scaler=None):
X = scaler.transform(X)
return X, scaler
def preprocess_labels(labels, encoder=None, categorical=True):
if not encoder:
encoder = LabelEncoder()
@@ -64,6 +66,7 @@ def preprocess_labels(labels, encoder=None, categorical=True):
y = np_utils.to_categorical(y)
return y, encoder
def make_submission(y_prob, ids, encoder, fname):
with open(fname, 'w') as f:
f.write('id,')
@@ -75,7 +78,6 @@ def make_submission(y_prob, ids, encoder, fname):
f.write('\n')
print("Wrote submission to file {}.".format(fname))
print("Loading data...")
X, labels = load_data('train.csv', train=True)
X, scaler = preprocess_data(X)
@@ -93,32 +95,29 @@ print(dims, 'dims')
print("Building model...")
model = Sequential()
model.add(Dense(dims, 512, init='glorot_uniform'))
model.add(PReLU((512,)))
model.add(BatchNormalization((512,)))
model.add(Dense(512, input_shape=(dims,)))
model.add(PReLU())
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(Dense(512, 512, init='glorot_uniform'))
model.add(PReLU((512,)))
model.add(BatchNormalization((512,)))
model.add(Dense(512))
model.add(PReLU())
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(Dense(512, 512, init='glorot_uniform'))
model.add(PReLU((512,)))
model.add(BatchNormalization((512,)))
model.add(Dense(512))
model.add(PReLU())
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(Dense(512, nb_classes, init='glorot_uniform'))
model.add(Dense(nb_classes))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer="adam")
print("Training model...")
model.fit(X, y, nb_epoch=20, batch_size=128, validation_split=0.15)
print("Generating submission...")
proba = model.predict_proba(X_test)
make_submission(proba, ids, encoder, fname='keras-otto.csv')
+103
Ver Arquivo
@@ -0,0 +1,103 @@
from __future__ import print_function
from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM
from keras.datasets.data_utils import get_file
import numpy as np
import random
import sys
'''
Example script to generate text from Nietzsche's writings.
At least 20 epochs are required before the generated text
starts sounding coherent.
It is recommended to run this script on GPU, as recurrent
networks are quite computationally intensive.
If you try this script on new data, make sure your corpus
has at least ~100k characters. ~1M is better.
'''
path = get_file('nietzsche.txt', origin="https://s3.amazonaws.com/text-datasets/nietzsche.txt")
text = open(path).read().lower()
print('corpus length:', len(text))
chars = set(text)
print('total chars:', len(chars))
char_indices = dict((c, i) for i, c in enumerate(chars))
indices_char = dict((i, c) for i, c in enumerate(chars))
# cut the text in semi-redundant sequences of maxlen characters
maxlen = 20
step = 3
sentences = []
next_chars = []
for i in range(0, len(text) - maxlen, step):
sentences.append(text[i: i + maxlen])
next_chars.append(text[i + maxlen])
print('nb sequences:', len(sentences))
print('Vectorization...')
X = np.zeros((len(sentences), maxlen, len(chars)), dtype=np.bool)
y = np.zeros((len(sentences), len(chars)), dtype=np.bool)
for i, sentence in enumerate(sentences):
for t, char in enumerate(sentence):
X[i, t, char_indices[char]] = 1
y[i, char_indices[next_chars[i]]] = 1
# build the model: 2 stacked LSTM
print('Build model...')
model = Sequential()
model.add(LSTM(512, return_sequences=True, input_shape=(maxlen, len(chars))))
model.add(Dropout(0.2))
model.add(LSTM(512, return_sequences=False))
model.add(Dropout(0.2))
model.add(Dense(len(chars)))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
def sample(a, temperature=1.0):
# helper function to sample an index from a probability array
a = np.log(a) / temperature
a = np.exp(a) / np.sum(np.exp(a))
return np.argmax(np.random.multinomial(1, a, 1))
# train the model, output generated text after each iteration
for iteration in range(1, 60):
print()
print('-' * 50)
print('Iteration', iteration)
model.fit(X, y, batch_size=128, nb_epoch=1)
start_index = random.randint(0, len(text) - maxlen - 1)
for diversity in [0.2, 0.5, 1.0, 1.2]:
print()
print('----- diversity:', diversity)
generated = ''
sentence = text[start_index: start_index + maxlen]
generated += sentence
print('----- Generating with seed: "' + sentence + '"')
sys.stdout.write(generated)
for iteration in range(400):
x = np.zeros((1, maxlen, len(chars)))
for t, char in enumerate(sentence):
x[0, t, char_indices[char]] = 1.
preds = model.predict(x, verbose=0)[0]
next_index = sample(preds, diversity)
next_char = indices_char[next_index]
generated += next_char
sentence = sentence[1:] + next_char
sys.stdout.write(next_char)
sys.stdout.flush()
print()
+74
Ver Arquivo
@@ -0,0 +1,74 @@
from __future__ import absolute_import
from __future__ import print_function
import numpy as np
np.random.seed(1337) # for reproducibility
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.utils import np_utils
'''
Train a simple convnet on the MNIST dataset.
Run on GPU: THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python mnist_cnn.py
Get to 99.25% test accuracy after 12 epochs (there is still a lot of margin for parameter tuning).
16 seconds per epoch on a GRID K520 GPU.
'''
batch_size = 128
nb_classes = 10
nb_epoch = 12
# input image dimensions
img_rows, img_cols = 28, 28
# number of convolutional filters to use
nb_filters = 32
# size of pooling area for max pooling
nb_pool = 2
# convolution kernel size
nb_conv = 3
# the data, shuffled and split between tran and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(X_train.shape[0], 1, img_rows, img_cols)
X_test = X_test.reshape(X_test.shape[0], 1, img_rows, img_cols)
X_train = X_train.astype("float32")
X_test = X_test.astype("float32")
X_train /= 255
X_test /= 255
print('X_train shape:', X_train.shape)
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')
# convert class vectors to binary class matrices
Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)
model = Sequential()
model.add(Convolution2D(nb_filters, nb_conv, nb_conv,
border_mode='same',
input_shape=(1, img_rows, img_cols)))
model.add(Activation('relu'))
model.add(Convolution2D(nb_filters, nb_conv, nb_conv))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adadelta')
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=True, verbose=1, validation_data=(X_test, Y_test))
score = model.evaluate(X_test, Y_test, show_accuracy=True, verbose=0)
print('Test score:', score[0])
print('Test accuracy:', score[1])
+86
Ver Arquivo
@@ -0,0 +1,86 @@
from __future__ import absolute_import
from __future__ import print_function
import numpy as np
np.random.seed(1337) # for reproducibility
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.initializations import normal, identity
from keras.layers.recurrent import SimpleRNN, LSTM
from keras.optimizers import RMSprop
from keras.utils import np_utils
'''
This is a reproduction of the IRNN experiment
with pixel-by-pixel sequential MNIST in
"A Simple Way to Initialize Recurrent Networks of Rectified Linear Units "
by Quoc V. Le, Navdeep Jaitly, Geoffrey E. Hinton
arXiv:1504.00941v2 [cs.NE] 7 Apr 201
http://arxiv.org/pdf/1504.00941v2.pdf
Optimizer is replaced with RMSprop which yields more stable and steady
improvement.
Reaches 0.93 train/test accuracy after 900 epochs
(which roughly corresponds to 1687500 steps in the original paper.)
'''
batch_size = 32
nb_classes = 10
nb_epochs = 200
hidden_units = 100
learning_rate = 1e-6
clip_norm = 1.0
# the data, shuffled and split between train and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(X_train.shape[0], -1, 1)
X_test = X_test.reshape(X_test.shape[0], -1, 1)
X_train = X_train.astype("float32")
X_test = X_test.astype("float32")
X_train /= 255
X_test /= 255
print('X_train shape:', X_train.shape)
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')
# convert class vectors to binary class matrices
Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)
print('Evaluate IRNN...')
model = Sequential()
model.add(SimpleRNN(output_dim=hidden_units,
init=lambda shape: normal(shape, scale=0.001),
inner_init=lambda shape: identity(shape, scale=1.0),
activation='relu', input_shape=X_train.shape[1:]))
model.add(Dense(nb_classes))
model.add(Activation('softmax'))
rmsprop = RMSprop(lr=learning_rate)
model.compile(loss='categorical_crossentropy', optimizer=rmsprop)
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epochs,
show_accuracy=True, verbose=1, validation_data=(X_test, Y_test))
scores = model.evaluate(X_test, Y_test, show_accuracy=True, verbose=0)
print('IRNN test score:', scores[0])
print('IRNN test accuracy:', scores[1])
print('Compare to LSTM...')
model = Sequential()
model.add(LSTM(hidden_units, input_shape=X_train.shape[1:]))
model.add(Dense(nb_classes))
model.add(Activation('softmax'))
rmsprop = RMSprop(lr=learning_rate)
model.compile(loss='categorical_crossentropy', optimizer=rmsprop)
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epochs,
show_accuracy=True, verbose=1, validation_data=(X_test, Y_test))
scores = model.evaluate(X_test, Y_test, show_accuracy=True, verbose=0)
print('LSTM test score:', scores[0])
print('LSTM test accuracy:', scores[1])
+19 -13
Ver Arquivo
@@ -1,29 +1,31 @@
from __future__ import absolute_import
from __future__ import print_function
import numpy as np
np.random.seed(1337) # for reproducibility
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.regularizers import l2, l1
from keras.constraints import maxnorm
from keras.optimizers import SGD, Adam, RMSprop
from keras.utils import np_utils
import numpy as np
'''
Train a simple deep NN on the MNIST dataset.
Get to 98.40% test accuracy after 20 epochs
(there is *a lot* of margin for parameter tuning).
2 seconds per epoch on a K520 GPU.
'''
batch_size = 64
batch_size = 128
nb_classes = 10
nb_epoch = 20
np.random.seed(1337) # for reproducibility
# the data, shuffled and split between tran and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(60000,784)
X_test = X_test.reshape(10000,784)
X_train = X_train.reshape(60000, 784)
X_test = X_test.reshape(10000, 784)
X_train = X_train.astype("float32")
X_test = X_test.astype("float32")
X_train /= 255
@@ -36,19 +38,23 @@ Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)
model = Sequential()
model.add(Dense(784, 128))
model.add(Dense(512, input_shape=(784,)))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Dense(128, 128))
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Dense(128, 10))
model.add(Dense(10))
model.add(Activation('softmax'))
rms = RMSprop()
model.compile(loss='categorical_crossentropy', optimizer=rms)
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=True, verbose=2, validation_data=(X_test, Y_test))
score = model.evaluate(X_test, Y_test, show_accuracy=True, verbose=0)
model.fit(X_train, Y_train,
batch_size=batch_size, nb_epoch=nb_epoch,
show_accuracy=True, verbose=2,
validation_data=(X_test, Y_test))
score = model.evaluate(X_test, Y_test,
show_accuracy=True, verbose=0)
print('Test score:', score[0])
print('Test accuracy:', score[1])
+122
Ver Arquivo
@@ -0,0 +1,122 @@
from __future__ import absolute_import
from __future__ import print_function
import numpy as np
import datetime
np.random.seed(1337) # for reproducibility
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.utils import np_utils
'''
Transfer learning toy example:
1- Train a simple convnet on the MNIST dataset the first 5 digits [0..4].
2- Freeze convolutional layers and fine-tune dense layers
for the classification of digits [5..9].
Run on GPU: THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python mnist_cnn.py
Get to 99.8% test accuracy after 5 epochs
for the first five digits classifier
and 99.2% for the last five digits after transfer + fine-tuning.
'''
now = datetime.datetime.now
batch_size = 128
nb_classes = 5
nb_epoch = 5
# input image dimensions
img_rows, img_cols = 28, 28
# number of convolutional filters to use
nb_filters = 32
# size of pooling area for max pooling
nb_pool = 2
# convolution kernel size
nb_conv = 3
def train_model(model, train, test, nb_classes):
X_train = train[0].reshape(train[0].shape[0], 1, img_rows, img_cols)
X_test = test[0].reshape(test[0].shape[0], 1, img_rows, img_cols)
X_train = X_train.astype("float32")
X_test = X_test.astype("float32")
X_train /= 255
X_test /= 255
print('X_train shape:', X_train.shape)
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')
# convert class vectors to binary class matrices
Y_train = np_utils.to_categorical(train[1], nb_classes)
Y_test = np_utils.to_categorical(test[1], nb_classes)
model.compile(loss='categorical_crossentropy', optimizer='adadelta')
t = now()
model.fit(X_train, Y_train,
batch_size=batch_size, nb_epoch=nb_epoch,
show_accuracy=True, verbose=1,
validation_data=(X_test, Y_test))
print('Training time: %s' % (now() - t))
score = model.evaluate(X_test, Y_test, show_accuracy=True, verbose=0)
print('Test score:', score[0])
print('Test accuracy:', score[1])
# the data, shuffled and split between train and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()
# create two datasets one with digits below 5 and one with 5 and above
X_train_lt5 = X_train[y_train < 5]
y_train_lt5 = y_train[y_train < 5]
X_test_lt5 = X_test[y_test < 5]
y_test_lt5 = y_test[y_test < 5]
X_train_gte5 = X_train[y_train >= 5]
y_train_gte5 = y_train[y_train >= 5] - 5 # make classes start at 0 for
X_test_gte5 = X_test[y_test >= 5] # np_utils.to_categorical
y_test_gte5 = y_test[y_test >= 5] - 5
# define two groups of layers: feature (convolutions) and classification (dense)
feature_layers = [
Convolution2D(nb_filters, nb_conv, nb_conv,
border_mode='valid',
input_shape=(1, img_rows, img_cols)),
Activation('relu'),
Convolution2D(nb_filters, nb_conv, nb_conv),
Activation('relu'),
MaxPooling2D(pool_size=(nb_pool, nb_pool)),
Dropout(0.25),
Flatten(),
]
classification_layers = [
Dense(128),
Activation('relu'),
Dropout(0.5),
Dense(nb_classes),
Activation('softmax')
]
# create complete model
model = Sequential()
for l in feature_layers + classification_layers:
model.add(l)
# train model for 5-digit classification [0..4]
train_model(model,
(X_train_lt5, y_train_lt5),
(X_test_lt5, y_test_lt5), nb_classes)
# freeze feature layers and rebuild model
for l in feature_layers:
l.trainable = False
# transfer: train dense layers for new classification task [5..9]
train_model(model,
(X_train_gte5, y_train_gte5),
(X_test_gte5, y_test_gte5), nb_classes)
+168
Ver Arquivo
@@ -0,0 +1,168 @@
from __future__ import absolute_import
from __future__ import print_function
import numpy as np
np.random.seed(123)
import matplotlib.pyplot as plt
from theano import function
from keras.models import Sequential
from keras.layers.core import TimeDistributedDense, Activation
from keras.layers.recurrent import LSTM
from keras.optimizers import Adam
from keras.utils import generic_utils
from keras.layers.ntm import NeuralTuringMachine as NTM
"""
Copy Problem defined in Graves et. al [0]
Training data is made of sequences with length 1 to 20.
Test data are sequences of length 100.
The model is tested every 500 weight updates.
After about 3500 updates, the accuracy jumps from around 50% to >90%.
Estimated compile time: 12 min
Estimated time to train Neural Turing Machine and 3 layer LSTM on an NVidia GTX 680: 2h
[0]: http://arxiv.org/pdf/1410.5401v2.pdf
"""
batch_size = 100
h_dim = 128
n_slots = 128
m_length = 20
input_dim = 8
lr = 1e-3
clipvalue = 10
##### Neural Turing Machine ######
ntm = NTM(h_dim, n_slots=n_slots, m_length=m_length, shift_range=3,
inner_rnn='lstm', return_sequences=True, input_dim=input_dim)
model = Sequential()
model.add(ntm)
model.add(TimeDistributedDense(input_dim))
model.add(Activation('sigmoid'))
sgd = Adam(lr=lr, clipvalue=clipvalue)
model.compile(loss='binary_crossentropy', optimizer=sgd)
# LSTM - Run this for comparison
sgd2 = Adam(lr=lr, clipvalue=clipvalue)
lstm = Sequential()
lstm.add(LSTM(input_dim=input_dim, output_dim=h_dim*2, return_sequences=True))
lstm.add(LSTM(output_dim=h_dim*2, return_sequences=True))
lstm.add(LSTM(output_dim=h_dim*2, return_sequences=True))
lstm.add(TimeDistributedDense(input_dim))
lstm.add(Activation('sigmoid'))
lstm.compile(loss='binary_crossentropy', optimizer=sgd)
###### DATASET ########
def get_sample(batch_size=128, n_bits=8, max_size=20, min_size=1):
# generate samples with random length
inp = np.zeros((batch_size, 2*max_size-1, n_bits))
out = np.zeros((batch_size, 2*max_size-1, n_bits))
sw = np.zeros((batch_size, 2*max_size-1, 1))
for i in range(batch_size):
t = np.random.randint(low=min_size, high=max_size)
x = np.random.uniform(size=(t, n_bits)) > .5
for j,f in enumerate(x.sum(axis=-1)): # remove fake flags
if f>=n_bits:
x[j, :] = 0.
del_flag = np.ones((1, n_bits))
inp[i, :t+1] = np.concatenate([x, del_flag], axis=0)
out[i, t+1:(2*t+1)] = x
sw[i, t+1:(2*t+1)] = 1
return inp, out, sw
def show_pattern(inp, out, sw, file_name='ntm_output.png'):
''' Helper function to visualize results '''
plt.figure(figsize=(10, 10))
plt.subplot(131)
plt.imshow(inp>.5)
plt.subplot(132)
plt.imshow(out>.5)
plt.subplot(133)
plt.imshow(sw>.5)
plt.savefig(file_name)
plt.close()
# Show data example:
inp, out, sw = get_sample(1, 8, 20)
plt.subplot(131)
plt.title('input')
plt.imshow(inp[0], cmap='gray')
plt.subplot(132)
plt.title('desired')
plt.imshow(out[0], cmap='gray')
plt.subplot(133)
plt.title('sample_weight')
plt.imshow(sw[0], cmap='gray')
# training uses sequences of length 1 to 20. Test uses series of length 100.
def test_model(model, file_name, min_size=100):
I, V, sw = get_sample(batch_size=500, n_bits=input_dim, max_size=min_size+1, min_size=min_size)
Y = np.asarray(model.predict(I, batch_size=100) > .5).astype('float64')
acc = (V[:, -min_size:, :] == Y[:, -min_size:, :]).mean() * 100
show_pattern(Y[0], V[0], sw[0], file_name)
return acc
##### TRAIN ######
nb_epoch = 4000
progbar = generic_utils.Progbar(nb_epoch)
for e in range(nb_epoch):
I, V, sw = get_sample(n_bits=input_dim, max_size=20, min_size=1, batch_size=100)
loss1 = model.train_on_batch(I, V, sample_weight=sw)
loss2 = lstm.train_on_batch(I, V, sample_weight=sw)
progbar.add(1, values=[("NTM", loss1), ("LSTM", loss2)])
if e % 500 == 0:
print("")
acc1 = test_model(model, 'ntm.png')
acc2 = test_model(lstm, 'lstm.png')
print("NTM test acc: {}".format(acc1))
print("LSTM test acc: {}".format(acc2))
##### VISUALIZATION #####
X = model.get_input()
Y = ntm.get_full_output()[0:3] # (memory over time, read_vectors, write_vectors)
F = function([X], Y, allow_input_downcast=True)
inp, out, sw = get_sample(1, 8, 21, 20)
mem, read, write = F(inp.astype('float32'))
Y = model.predict(inp)
plt.figure(figsize=(15, 12))
plt.subplot(221)
plt.imshow(write[0])
plt.xlabel('memory location')
plt.ylabel('time')
plt.title('write')
plt.subplot(222)
plt.imshow(read[0])
plt.title('read')
plt.subplot(223)
plt.title('desired')
plt.imshow(out[0])
plt.subplot(224)
plt.imshow(Y[0]>.5)
plt.title('output')
plt.figure(figsize=(15, 10))
plt.subplot(325)
plt.ylabel('time')
plt.xlabel('location')
plt.title('memory evolving in time (avg value per location)')
plt.imshow(mem[0].mean(axis=-1))
+5 -3
Ver Arquivo
@@ -1,6 +1,7 @@
from __future__ import absolute_import
from __future__ import print_function
import numpy as np
np.random.seed(1337) # for reproducibility
from keras.datasets import reuters
from keras.models import Sequential
@@ -19,6 +20,7 @@ from keras.preprocessing.text import Tokenizer
max_words = 1000
batch_size = 32
nb_epoch = 5
print("Loading data...")
(X_train, y_train), (X_test, y_test) = reuters.load_data(nb_words=max_words, test_split=0.2)
@@ -43,15 +45,15 @@ print('Y_test shape:', Y_test.shape)
print("Building model...")
model = Sequential()
model.add(Dense(max_words, 256, init='normal'))
model.add(Dense(512, input_shape=(max_words,)))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(256, nb_classes, init='normal'))
model.add(Dense(nb_classes))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam')
history = model.fit(X_train, Y_train, nb_epoch=4, batch_size=batch_size, verbose=1, show_accuracy=True, validation_split=0.1)
history = model.fit(X_train, Y_train, nb_epoch=nb_epoch, batch_size=batch_size, verbose=1, show_accuracy=True, validation_split=0.1)
score = model.evaluate(X_test, Y_test, batch_size=batch_size, verbose=1, show_accuracy=True)
print('Test score:', score[0])
print('Test accuracy:', score[1])
-215
Ver Arquivo
@@ -1,215 +0,0 @@
'''
We loop over words in a dataset, and for each word, we look at a context window around the word.
We generate pairs of (pivot_word, other_word_from_same_context) with label 1,
and pairs of (pivot_word, random_word) with label 0 (skip-gram method).
We use the layer WordContextProduct to learn embeddings for the word couples,
and compute a proximity score between the embeddings (= p(context|word)),
trained with our positive and negative labels.
We then use the weights computed by WordContextProduct to encode words
and demonstrate that the geometry of the embedding space
captures certain useful semantic properties.
Read more about skip-gram in this particularly gnomic paper by Mikolov et al.:
http://arxiv.org/pdf/1301.3781v3.pdf
Note: you should run this on GPU, otherwise training will be quite slow.
On a EC2 GPU instance, expect 3 hours per 10e6 comments (~10e8 words) per epoch with dim_proj=256.
Should be much faster on a modern GPU.
GPU command:
THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python skipgram_word_embeddings.py
Dataset: 5,845,908 Hacker News comments.
Obtain the dataset at:
https://mega.co.nz/#F!YohlwD7R!wec0yNO86SeaNGIYQBOR0A
(HNCommentsAll.1perline.json.bz2)
'''
from __future__ import absolute_import
from __future__ import print_function
import numpy as np
import theano
import six.moves.cPickle
import os, re, json
from keras.preprocessing import sequence, text
from keras.optimizers import SGD, RMSprop, Adagrad
from keras.utils import np_utils, generic_utils
from keras.models import Sequential
from keras.layers.embeddings import WordContextProduct, Embedding
from six.moves import range
from six.moves import zip
max_features = 50000 # vocabulary size: top 50,000 most common words in data
skip_top = 100 # ignore top 100 most common words
nb_epoch = 1
dim_proj = 256 # embedding space dimension
save = True
load_model = False
load_tokenizer = False
train_model = True
save_dir = os.path.expanduser("~/.keras/models")
model_load_fname = "HN_skipgram_model.pkl"
model_save_fname = "HN_skipgram_model.pkl"
tokenizer_fname = "HN_tokenizer.pkl"
data_path = os.path.expanduser("~/")+"HNCommentsAll.1perline.json"
# text preprocessing utils
html_tags = re.compile(r'<.*?>')
to_replace = [('&#x27;', "'")]
hex_tags = re.compile(r'&.*?;')
def clean_comment(comment):
c = str(comment.encode("utf-8"))
c = html_tags.sub(' ', c)
for tag, char in to_replace:
c = c.replace(tag, char)
c = hex_tags.sub(' ', c)
return c
def text_generator(path=data_path):
f = open(path)
for i, l in enumerate(f):
comment_data = json.loads(l)
comment_text = comment_data["comment_text"]
comment_text = clean_comment(comment_text)
if i % 10000 == 0:
print(i)
yield comment_text
f.close()
# model management
if load_tokenizer:
print('Load tokenizer...')
tokenizer = six.moves.cPickle.load(open(os.path.join(save_dir, tokenizer_fname), 'rb'))
else:
print("Fit tokenizer...")
tokenizer = text.Tokenizer(nb_words=max_features)
tokenizer.fit_on_texts(text_generator())
if save:
print("Save tokenizer...")
if not os.path.exists(save_dir):
os.makedirs(save_dir)
six.moves.cPickle.dump(tokenizer, open(os.path.join(save_dir, tokenizer_fname), "wb"))
# training process
if train_model:
if load_model:
print('Load model...')
model = six.moves.cPickle.load(open(os.path.join(save_dir, model_load_fname), 'rb'))
else:
print('Build model...')
model = Sequential()
model.add(WordContextProduct(max_features, proj_dim=dim_proj, init="uniform"))
model.compile(loss='mse', optimizer='rmsprop')
sampling_table = sequence.make_sampling_table(max_features)
for e in range(nb_epoch):
print('-'*40)
print('Epoch', e)
print('-'*40)
progbar = generic_utils.Progbar(tokenizer.document_count)
samples_seen = 0
losses = []
for i, seq in enumerate(tokenizer.texts_to_sequences_generator(text_generator())):
# get skipgram couples for one text in the dataset
couples, labels = sequence.skipgrams(seq, max_features, window_size=4, negative_samples=1., sampling_table=sampling_table)
if couples:
# one gradient update per sentence (one sentence = a few 1000s of word couples)
X = np.array(couples, dtype="int32")
loss = model.train(X, labels)
losses.append(loss)
if len(losses) % 100 == 0:
progbar.update(i, values=[("loss", np.mean(losses))])
losses = []
samples_seen += len(labels)
print('Samples seen:', samples_seen)
print("Training completed!")
if save:
print("Saving model...")
if not os.path.exists(save_dir):
os.makedirs(save_dir)
six.moves.cPickle.dump(model, open(os.path.join(save_dir, model_save_fname), "wb"))
print("It's test time!")
# recover the embedding weights trained with skipgram:
weights = model.layers[0].get_weights()[0]
# we no longer need this
del model
weights[:skip_top] = np.zeros((skip_top, dim_proj))
norm_weights = np_utils.normalize(weights)
word_index = tokenizer.word_index
reverse_word_index = dict([(v, k) for k, v in list(word_index.items())])
word_index = tokenizer.word_index
def embed_word(w):
i = word_index.get(w)
if (not i) or (i<skip_top) or (i>=max_features):
return None
return norm_weights[i]
def closest_to_point(point, nb_closest=10):
proximities = np.dot(norm_weights, point)
tups = list(zip(list(range(len(proximities))), proximities))
tups.sort(key=lambda x: x[1], reverse=True)
return [(reverse_word_index.get(t[0]), t[1]) for t in tups[:nb_closest]]
def closest_to_word(w, nb_closest=10):
i = word_index.get(w)
if (not i) or (i<skip_top) or (i>=max_features):
return []
return closest_to_point(norm_weights[i].T, nb_closest)
''' the resuls in comments below were for:
5.8M HN comments
dim_proj = 256
nb_epoch = 2
optimizer = rmsprop
loss = mse
max_features = 50000
skip_top = 100
negative_samples = 1.
window_size = 4
and frequency subsampling of factor 10e-5.
'''
words = ["article", # post, story, hn, read, comments
"3", # 6, 4, 5, 2
"two", # three, few, several, each
"great", # love, nice, working, looking
"data", # information, memory, database
"money", # company, pay, customers, spend
"years", # ago, year, months, hours, week, days
"android", # ios, release, os, mobile, beta
"javascript", # js, css, compiler, library, jquery, ruby
"look", # looks, looking
"business", # industry, professional, customers
"company", # companies, startup, founders, startups
"after", # before, once, until
"own", # personal, our, having
"us", # united, country, american, tech, diversity, usa, china, sv
"using", # javascript, js, tools (lol)
"here", # hn, post, comments
]
for w in words:
res = closest_to_word(w)
print('====', w)
for r in res:
print(r)
+15
Ver Arquivo
@@ -0,0 +1,15 @@
"""
Keras: Theano-based Deep Learning library
==================================
Keras is a minimalist, highly modular neural network library in
the spirit of Torch, written in Python / Theano so as not to have
to deal with the dearth of ecosystem in Lua. It was developed with
a focus on enabling fast experimentation. Being able to go from
idea to result with the least possible delay is key to doing
good research.
See http://keras.io/
"""
__version__ = '0.2.0'
+30 -15
Ver Arquivo
@@ -1,34 +1,49 @@
from __future__ import absolute_import
import theano
import theano.tensor as T
import types
from . import backend as K
def softmax(x):
return T.nnet.softmax(x)
ndim = K.ndim(x)
if ndim == 2:
return K.softmax(x)
elif ndim == 3:
# apply softmax to each timestep
def step(x, states):
return K.softmax(x), []
last_output, outputs, states = K.rnn(step, x, [], masking=False)
return outputs
else:
raise Exception('Cannot apply softmax to a tensor that is not 2D or 3D. ' +
'Here, ndim=' + str(ndim))
def time_distributed_softmax(x):
xshape = x.shape
X = x.reshape((xshape[0] * xshape[1], xshape[2]))
return T.nnet.softmax(X).reshape(xshape)
def softplus(x):
return T.nnet.softplus(x)
return K.softplus(x)
def relu(x, alpha=0., max_value=None):
return K.relu(x, alpha=alpha, max_value=max_value)
def relu(x):
return (x + abs(x)) / 2.0
def tanh(x):
return T.tanh(x)
return K.tanh(x)
def sigmoid(x):
return T.nnet.sigmoid(x)
return K.sigmoid(x)
def hard_sigmoid(x):
return T.nnet.hard_sigmoid(x)
return K.hard_sigmoid(x)
def linear(x):
'''
The function returns the variable that is passed in, so all types work
'''
return x
from .utils.generic_utils import get_from_module
def get(identifier):
return get_from_module(identifier, globals(), 'activation function')
return get_from_module(identifier, globals(), 'activation function')
+39
Ver Arquivo
@@ -0,0 +1,39 @@
from __future__ import absolute_import
from __future__ import print_function
import os
import json
from .common import epsilon, floatx, set_epsilon, set_floatx
_keras_dir = os.path.expanduser(os.path.join('~', '.keras'))
if not os.path.exists(_keras_dir):
os.makedirs(_keras_dir)
_BACKEND = 'theano'
_config_path = os.path.expanduser(os.path.join('~', '.keras', 'keras.json'))
if os.path.exists(_config_path):
_config = json.load(open(_config_path))
_floatx = _config.get('floatx', floatx())
assert _floatx in {'float32', 'float64'}
_epsilon = _config.get('epsilon', epsilon())
assert type(_epsilon) == float
_backend = _config.get('backend', _BACKEND)
assert _backend in {'theano', 'tensorflow'}
set_floatx(_floatx)
set_epsilon(_epsilon)
_BACKEND = _backend
else:
# save config file, for easy edition
_config = {'floatx': floatx(),
'epsilon': epsilon(),
'backend': _BACKEND}
json.dump(_config, open(_config_path, 'w'))
if _BACKEND == 'theano':
print('Using Theano backend.')
from .theano_backend import *
elif _BACKEND == 'tensorflow':
print('Using TensorFlow backend.')
from .tensorflow_backend import *
else:
raise Exception('Unknown backend: ' + str(backend))
+31
Ver Arquivo
@@ -0,0 +1,31 @@
import numpy as np
# the type of float to use throughout the session.
_FLOATX = 'float32'
_EPSILON = 10e-8
def epsilon():
return _EPSILON
def set_epsilon(e):
global _EPSILON
_EPSILON = e
def floatx():
return _FLOATX
def set_floatx(floatx):
global _FLOATX
if floatx not in {'float32', 'float64'}:
raise Exception('Unknown floatx type: ' + str(floatx))
_FLOATX = floatx
def cast_to_floatx(x):
'''Cast a Numpy array to floatx.
'''
return np.asarray(x, dtype=_FLOATX)
+602
Ver Arquivo
@@ -0,0 +1,602 @@
import tensorflow as tf
import numpy as np
from .common import _FLOATX, _EPSILON
# INTERNAL UTILS
_SESSION = None
def _get_session():
global _SESSION
if _SESSION is None:
_SESSION = tf.Session('')
return _SESSION
def _set_session(session):
global _SESSION
_SESSION = session
# VARIABLE MANIPULATION
def variable(value, dtype=_FLOATX, name=None):
v = tf.Variable(np.asarray(value, dtype=dtype), name=name)
_get_session().run(v.initializer)
return v
def placeholder(shape=None, ndim=None, dtype=_FLOATX, name=None):
if not shape:
if ndim:
shape = [None for _ in range(ndim)]
return tf.placeholder(dtype, shape=shape, name=name)
def shape(x):
return x.get_shape()
def ndim(x):
return len(x.get_shape())
def eval(x):
'''Run a graph.
'''
return x.eval(session=_get_session())
def zeros(shape, dtype=_FLOATX, name=None):
return variable(np.zeros(shape), dtype, name)
def ones(shape, dtype=_FLOATX, name=None):
return variable(np.ones(shape), dtype, name)
def ones_like(x, name=None):
return tf.ones_like(x)
def zeros_like(x, name=None):
return tf.zeros_like(x)
def count_params(x):
'''Return number of scalars in a tensor.
'''
shape = x.get_shape()
return np.prod([shape[i]._value for i in range(len(shape))])
def cast(x, dtype):
return tf.cast(x, dtype)
# LINEAR ALGEBRA
def dot(x, y):
return tf.matmul(x, y)
def transpose(x):
return tf.transpose(x)
def gather(reference, indices):
'''reference: a tensor.
indices: an int tensor of indices.
Return: a tensor of same type as reference.
'''
return tf.gather(reference, indices)
# ELEMENT-WISE OPERATIONS
def max(x, axis=None, keepdims=False):
if axis is not None and axis < 0:
axis = axis % len(x.get_shape())
return tf.reduce_max(x, reduction_indices=axis, keep_dims=keepdims)
def min(x, axis=None, keepdims=False):
if axis is not None and axis < 0:
axis = axis % len(x.get_shape())
return tf.reduce_min(x, reduction_indices=axis, keep_dims=keepdims)
def sum(x, axis=None, keepdims=False):
'''Sum of the values in a tensor, alongside the specified axis.
'''
if axis is not None and axis < 0:
axis = axis % len(x.get_shape())
return tf.reduce_sum(x, reduction_indices=axis, keep_dims=keepdims)
def prod(x, axis=None, keepdims=False):
'''Multiply the values in a tensor, alongside the specified axis.
'''
return tf.reduce_prod(x, reduction_indices=axis, keep_dims=keepdims)
def std(x, axis=None, keepdims=False):
if axis is not None and axis < 0:
axis = axis % len(x.get_shape())
if x.dtype.base_dtype == tf.bool:
x = tf.cast(x, _FLOATX)
m = tf.reduce_mean(x, reduction_indices=axis, keep_dims=keepdims)
devs_squared = tf.square(x - m)
return tf.sqrt(tf.reduce_mean(devs_squared,
reduction_indices=axis,
keep_dims=keepdims))
def mean(x, axis=None, keepdims=False):
if axis is not None and axis < 0:
axis = axis % len(x.get_shape())
if x.dtype.base_dtype == tf.bool:
x = tf.cast(x, _FLOATX)
return tf.reduce_mean(x, reduction_indices=axis, keep_dims=keepdims)
def any(x, axis=None, keepdims=False):
'''Bitwise reduction (logical OR).
Return array of int8 (0s and 1s).
'''
if axis is not None and axis < 0:
axis = axis % len(x.get_shape())
x = tf.cast(x, tf.bool)
x = tf.reduce_any(x, reduction_indices=axis, keep_dims=keepdims)
return tf.cast(x, tf.int8)
def argmax(x, axis=-1):
if axis < 0:
axis = axis % len(x.get_shape())
return tf.argmax(x, axis)
def argmin(x, axis=-1):
if axis < 0:
axis = axis % len(x.get_shape())
return tf.argmin(x, axis)
def square(x):
return tf.square(x)
def abs(x):
return tf.abs(x)
def sqrt(x):
x = tf.clip_by_value(x, tf.cast(0., dtype=_FLOATX),
tf.cast(np.inf, dtype=_FLOATX))
return tf.sqrt(x)
def exp(x):
return tf.exp(x)
def log(x):
return tf.log(x)
def round(x):
return tf.round(x)
def pow(x, a):
return tf.pow(x, a)
def clip(x, min_value, max_value):
if max_value < min_value:
max_value = min_value
return tf.clip_by_value(x, tf.cast(min_value, dtype=_FLOATX),
tf.cast(max_value, dtype=_FLOATX))
def equal(x, y):
return tf.equal(x, y)
def maximum(x, y):
return tf.maximum(x, y)
def minimum(x, y):
return tf.minimum(x, y)
# SHAPE OPERATIONS
def concatenate(tensors, axis=-1):
if axis < 0:
axis = axis % len(tensors[0].get_shape())
return tf.concat(axis, tensors)
def reshape(x, shape):
return tf.reshape(x, shape)
def permute_dimensions(x, pattern):
'''Transpose dimensions.
pattern should be a tuple or list of
dimension indices, e.g. [0, 2, 1].
'''
return tf.transpose(x, perm=pattern)
def repeat(x, n):
'''Repeat a 2D tensor:
if x has shape (samples, dim) and n=2,
the output will have shape (samples, 2, dim)
'''
tensors = [x] * n
stacked = tf.pack(tensors)
return tf.transpose(stacked, (1, 0, 2))
def tile(x, n):
return tf.tile(x, n)
def flatten(x):
'''Turn a n-D tensor into a 2D tensor where
the first dimension is conserved.
'''
x = tf.reshape(x, [-1, np.prod(x.get_shape()[1:].as_list())])
return x
def expand_dims(x, dim=-1):
'''Add a 1-sized dimension at index "dim".
'''
return tf.expand_dims(x, dim)
def squeeze(x, axis):
'''Remove a 1-dimension from the tensor at index "axis".
'''
return tf.squeeze(x, [axis])
def temporal_padding(x, padding=1):
'''Pad the middle dimension of a 3D tensor
with "padding" zeros left and right.
Appologies for the inane API, but Theano makes this
really hard.
'''
pattern = [[0, 0], [padding, padding], [0, 0]]
return tf.pad(x, pattern)
def spatial_2d_padding(x, padding=(1, 1), dim_ordering='th'):
'''Pad the 2nd and 3rd dimensions of a 4D tensor
with "padding[0]" and "padding[1]" (resp.) zeros left and right.
'''
if dim_ordering == 'th':
pattern = [[0, 0], [0, 0],
[padding[0], padding[0]], [padding[1], padding[1]]]
else:
pattern = [[0, 0],
[padding[0], padding[0]], [padding[1], padding[1]],
[0, 0]]
return tf.pad(x, pattern)
# VALUE MANIPULATION
def get_value(x):
'''Technically the same as eval() for TF.
'''
return x.eval(session=_get_session())
def set_value(x, value):
tf.assign(x, np.asarray(value)).op.run(session=_get_session())
# GRAPH MANIPULATION
class Function(object):
def __init__(self, inputs, outputs, updates=[]):
self.inputs = list(inputs)
self.outputs = list(outputs)
with tf.control_dependencies(self.outputs):
self.updates = [tf.assign(p, new_p) for (p, new_p) in updates]
def __call__(self, inputs):
names = [v.name for v in self.inputs]
feed_dict = dict(zip(names, inputs))
session = _get_session()
updated = session.run(self.outputs + self.updates, feed_dict=feed_dict)
return updated[:len(self.outputs)]
def function(inputs, outputs, updates=[]):
return Function(inputs, outputs, updates=updates)
def gradients(loss, variables):
return tf.gradients(loss, variables)
# CONTROL FLOW
def rnn(step_function, inputs, initial_states,
go_backwards=False, masking=True):
'''Iterates over the time dimension of a tensor.
Parameters
----------
inputs: tensor of temporal data of shape (samples, time, ...)
(at least 3D).
step_function:
Parameters:
input: tensor with shape (samples, ...) (no time dimension),
representing input for the batch of samples at a certain
time step.
states: list of tensors.
Returns:
output: tensor with shape (samples, ...) (no time dimension),
new_states: list of tensors, same length and shapes
as 'states'.
initial_states: tensor with shape (samples, ...) (no time dimension),
containing the initial values for the states used in
the step function.
go_backwards: boolean. If True, do the iteration over
the time dimension in reverse order.
masking: boolean. If true, any input timestep inputs[s, i]
that is all-zeros will be skipped (states will be passed to
the next step unchanged) and the corresponding output will
be all zeros.
Returns
-------
A tuple (last_output, outputs, new_states).
last_output: the latest output of the rnn, of shape (samples, ...)
outputs: tensor with shape (samples, time, ...) where each
entry outputs[s, t] is the output of the step function
at time t for sample s.
new_states: list of tensors, latest states returned by
the step function, of shape (samples, ...).
'''
inputs = tf.transpose(inputs, (1, 0, 2))
input_list = tf.unpack(inputs)
states = initial_states
successive_states = []
successive_outputs = []
if go_backwards:
input_list.reverse()
for input in input_list:
output, new_states = step_function(input, states)
if masking:
# for now we raise an exception because tf.reduce_any will not work
raise Exception("Masking is Theano-only for the time being.")
# if all-zero input timestep, return
# all-zero output and unchanged states
switch = tf.reduce_any(input)
output = tf.control_flow_ops.cond(switch,
lambda: output,
lambda: 0. * output)
return_states = []
for state, new_state in zip(states, new_states):
return_states.append(tf.control_flow_ops.cond(switch,
lambda: new_state,
lambda: state))
states = return_states
else:
states = new_states
successive_outputs.append(output)
successive_states.append(states)
last_output = successive_outputs[-1]
outputs = tf.pack(successive_outputs)
new_states = successive_states[-1]
outputs = tf.transpose(outputs, (1, 0, 2))
return last_output, outputs, states
def switch(condition, then_expression, else_expression):
'''condition: scalar tensor.
'''
return tf.control_flow_ops.cond(condition,
lambda: then_expression,
lambda: else_expression)
# NN OPERATIONS
def relu(x, alpha=0., max_value=None):
'''ReLU.
alpha: slope of negative section.
'''
negative_part = tf.nn.relu(-x)
x = tf.nn.relu(x)
if max_value is not None:
x = tf.clip_by_value(x, tf.cast(0., dtype=_FLOATX),
tf.cast(max_value, dtype=_FLOATX))
x -= tf.constant(alpha, dtype=_FLOATX) * negative_part
return x
def softmax(x):
return tf.nn.softmax(x)
def softplus(x):
return tf.nn.softplus(x)
def categorical_crossentropy(output, target, from_logits=False):
'''Note: tf.nn.softmax_cross_entropy_with_logits
expects logits, Keras expects probabilities.
'''
if not from_logits:
# scale preds so that the class probas of each sample sum to 1
output /= tf.reduce_sum(output,
reduction_indices=len(output.get_shape())-1,
keep_dims=True)
# manual computation of crossentropy
output = tf.clip_by_value(output, tf.cast(_EPSILON, dtype=_FLOATX),
tf.cast(1.-_EPSILON, dtype=_FLOATX))
return - tf.reduce_sum(target * tf.log(output),
reduction_indices=len(output.get_shape())-1)
else:
return tf.nn.softmax_cross_entropy_with_logits(output, target)
def binary_crossentropy(output, target, from_logits=False):
'''Note: tf.nn.sigmoid_cross_entropy_with_logits
expects logits, Keras expects probabilities.
'''
if not from_logits:
# transform back to logits
output = tf.clip_by_value(output, tf.cast(_EPSILON, dtype=_FLOATX),
tf.cast(1.-_EPSILON, dtype=_FLOATX))
output = tf.log(output / (1 - output))
return tf.nn.sigmoid_cross_entropy_with_logits(output, target)
def sigmoid(x):
return tf.nn.sigmoid(x)
def hard_sigmoid(x):
x = (0.2 * x) + 0.5
x = tf.clip_by_value(x, tf.cast(0., dtype=_FLOATX),
tf.cast(1., dtype=_FLOATX))
return x
def tanh(x):
return tf.nn.tanh(x)
def dropout(x, level, seed=None):
retain_prob = 1. - level
if seed is None:
seed = np.random.randint(10e6)
# the dummy 1. works around a TF bug
# (float32_ref vs. float32 incomptability)
return tf.nn.dropout(x * 1., retain_prob, seed=seed)
# CONVOLUTIONS
def conv2d(x, kernel, strides=(1, 1), border_mode='valid', dim_ordering='th'):
'''
Run on cuDNN if available.
border_mode: string, "same" or "valid".
dim_ordering: whether to use Theano or TensorFlow dimension ordering
in inputs/kernels/ouputs.
'''
if border_mode == 'same':
padding = 'SAME'
elif border_mode == 'valid':
padding = 'VALID'
else:
raise Exception('Invalid border mode: ' + str(border_mode))
strides = (1,) + strides + (1,)
if _FLOATX == 'float64':
# tf conv2d only supports float32
x = tf.cast(x, 'float32')
kernel = tf.cast(kernel, 'float32')
if dim_ordering == 'th':
# TF uses the last dimension as channel dimension,
# instead of the 2nd one.
# TH input shape: (samples, input_depth, rows, cols)
# TF input shape: (samples, rows, cols, input_depth)
# TH kernel shape: (depth, input_depth, rows, cols)
# TF kernel shape: (rows, cols, input_depth, depth)
x = tf.transpose(x, (0, 2, 3, 1))
kernel = tf.transpose(kernel, (2, 3, 1, 0))
x = tf.nn.conv2d(x, kernel, strides, padding=padding)
x = tf.transpose(x, (0, 3, 1, 2))
elif dim_ordering == 'tf':
x = tf.nn.conv2d(x, kernel, strides, padding=padding)
else:
raise Exception('Unknown dim_ordering: ' + str(dim_ordering))
if _FLOATX == 'float64':
x = tf.cast(x, 'float64')
return x
def maxpool2d(x, pool_size, strides=(1, 1),
border_mode='valid', dim_ordering='th'):
'''
pool_size: tuple of 2 integers.
strides: tuple of 2 integers.
border_mode: one of "valid", "same".
dim_ordering: one of "th", "tf".
'''
if border_mode == 'same':
padding = 'SAME'
elif border_mode == 'valid':
padding = 'VALID'
else:
raise Exception('Invalid border mode: ' + str(border_mode))
strides = (1,) + strides + (1,)
pool_size = (1,) + pool_size + (1,)
if _FLOATX == 'float64':
# tf max_pool only supports float32
x = tf.cast(x, 'float32')
if dim_ordering == 'th':
# TF uses the last dimension as channel dimension,
# instead of the 2nd one.
# TH input shape: (samples, input_depth, rows, cols)
# TF input shape: (samples, rows, cols, input_depth)
# TH kernel shape: (depth, input_depth, rows, cols)
# TF kernel shape: (rows, cols, input_depth, depth)
x = tf.transpose(x, (0, 2, 3, 1))
x = tf.nn.max_pool(x, pool_size, strides, padding=padding)
x = tf.transpose(x, (0, 3, 1, 2))
elif dim_ordering == 'tf':
x = tf.nn.max_pool(x, pool_size, strides, padding=padding)
else:
raise Exception('Unknown dim_ordering: ' + str(dim_ordering))
if _FLOATX == 'float64':
x = tf.cast(x, 'float64')
return x
# RANDOMNESS
def random_normal(shape, mean=0.0, std=1.0, dtype=_FLOATX, seed=None):
if seed is None:
seed = np.random.randint(10e6)
return tf.random_normal(shape, mean=mean, stddev=std,
dtype=dtype, seed=seed)
def random_uniform(shape, low=0.0, high=1.0, dtype=_FLOATX, seed=None):
if seed is None:
seed = np.random.randint(10e6)
return tf.random_uniform(shape, minval=low, maxval=high,
dtype=dtype, seed=seed)
+622
Ver Arquivo
@@ -0,0 +1,622 @@
import theano
from theano import tensor as T
from theano.sandbox.rng_mrg import MRG_RandomStreams as RandomStreams
from theano.tensor.signal import downsample
import numpy as np
from .common import _FLOATX, _EPSILON
# INTERNAL UTILS
theano.config.floatX = _FLOATX
def _on_gpu():
'''Returns whether the session is set to
run on GPU or not (i.e. on CPU).
'''
return theano.config.device[:3] == 'gpu'
if _on_gpu():
'''Import cuDNN only if running on GPU:
not having Cuda install should not
prevent from running the present code.
'''
from theano.sandbox.cuda import dnn
# VARIABLE MANIPULATION
def variable(value, dtype=_FLOATX, name=None):
'''Instantiate a tensor variable.
'''
value = np.asarray(value, dtype=dtype)
return theano.shared(value=value, name=name, strict=False)
def placeholder(shape=None, ndim=None, dtype=_FLOATX, name=None):
'''Instantiate an input data placeholder variable.
'''
if shape is None and ndim is None:
raise Exception('Specify either a shape or ndim value.')
if shape is not None:
ndim = len(shape)
if ndim == 0:
return T.scalar(name=name, dtype=dtype)
elif ndim == 1:
return T.vector(name=name, dtype=dtype)
elif ndim == 2:
return T.matrix(name=name, dtype=dtype)
elif ndim == 3:
return T.tensor3(name=name, dtype=dtype)
elif ndim == 4:
return T.tensor4(name=name, dtype=dtype)
else:
raise Exception('ndim too large: ' + str(ndim))
def shape(x):
'''Return the shape of a tensor.
Warning: type returned will be different for
Theano backend (Theano tensor type) and TF backend (TF TensorShape).
'''
return x.shape
def ndim(x):
return x.ndim
def eval(x):
'''Run a graph.
'''
return x.eval()
def zeros(shape, dtype=_FLOATX, name=None):
'''Instantiate an all-zeros variable.
'''
return variable(np.zeros(shape), dtype, name)
def ones(shape, dtype=_FLOATX, name=None):
'''Instantiate an all-ones variable.
'''
return variable(np.ones(shape), dtype, name)
def ones_like(x):
return T.ones_like(x)
def zeros_like(x):
return T.zeros_like(x)
def count_params(x):
'''Return number of scalars in a tensor.
Return: numpy integer.
'''
return np.prod(x.shape.eval())
def cast(x, dtype):
return T.cast(x, dtype)
# LINEAR ALGEBRA
'''
Assumed overridden:
+, -, /, *, +=, -=, *=, /=
'''
def dot(x, y):
return T.dot(x, y)
def transpose(x):
return T.transpose(x)
def gather(reference, indices):
'''reference: a tensor.
indices: an int tensor of indices.
Return: a tensor of same type as reference.
'''
return reference[indices]
# ELEMENT-WISE OPERATIONS
def max(x, axis=None, keepdims=False):
return T.max(x, axis=axis, keepdims=keepdims)
def min(x, axis=None, keepdims=False):
return T.min(x, axis=axis, keepdims=keepdims)
def sum(x, axis=None, keepdims=False):
'''Sum of the values in a tensor, alongside the specified axis.
'''
return T.sum(x, axis=axis, keepdims=keepdims)
def prod(x, axis=None, keepdims=False):
'''Multiply the values in a tensor, alongside the specified axis.
'''
return T.prod(x, axis=axis, keepdims=keepdims)
def mean(x, axis=None, keepdims=False):
return T.mean(x, axis=axis, keepdims=keepdims)
def std(x, axis=None, keepdims=False):
return T.std(x, axis=axis, keepdims=keepdims)
def any(x, axis=None, keepdims=False):
'''Bitwise reduction (logical OR).
'''
return T.any(x, axis=axis, keepdims=keepdims)
def argmax(x, axis=-1):
return T.argmax(x, axis=axis, keepdims=False)
def argmin(x, axis=-1):
return T.argmin(x, axis=axis, keepdims=False)
def square(x):
return T.sqr(x)
def abs(x):
return T.abs_(x)
def sqrt(x):
x = T.clip(x, 0., np.inf)
return T.sqrt(x)
def exp(x):
return T.exp(x)
def log(x):
return T.log(x)
def round(x):
return T.round(x)
def pow(x, a):
return T.pow(x, a)
def clip(x, min_value, max_value):
if max_value < min_value:
max_value = min_value
return T.clip(x, min_value, max_value)
def equal(x, y):
return T.eq(x, y)
def maximum(x, y):
return T.maximum(x, y)
def minimum(x, y):
return T.minimum(x, y)
# SHAPE OPERATIONS
def concatenate(tensors, axis=-1):
return T.concatenate(tensors, axis=axis)
def reshape(x, shape):
return T.reshape(x, shape)
def permute_dimensions(x, pattern):
'''Transpose dimensions.
pattern should be a tuple or list of
dimension indices, e.g. [0, 2, 1].
'''
pattern = tuple(pattern)
return x.dimshuffle(pattern)
def repeat(x, n):
'''Repeat a 2D tensor:
if x has shape (samples, dim) and n=2,
the output will have shape (samples, 2, dim)
'''
tensors = [x] * n
stacked = T.stack(*tensors)
return stacked.dimshuffle((1, 0, 2))
def tile(x, n):
return T.tile(x, n)
def flatten(x):
'''Turn a n-D tensor into a 2D tensor where
the first dimension is conserved.
'''
x = T.reshape(x, (x.shape[0], T.prod(x.shape) // x.shape[0]))
return x
def expand_dims(x, dim=-1):
'''Add a 1-sized dimension at index "dim".
'''
pattern = [i for i in range(x.type.ndim)]
if dim < 0:
if x.type.ndim == 0:
dim = 0
else:
dim = dim % x.type.ndim + 1
pattern.insert(dim, 'x')
return x.dimshuffle(pattern)
def squeeze(x, axis):
'''Remove a 1-dimension from the tensor at index "axis".
'''
x = T.addbroadcast(x, axis)
return T.squeeze(x)
def temporal_padding(x, padding=1):
'''Pad the middle dimension of a 3D tensor
with "padding" zeros left and right.
Appologies for the inane API, but Theano makes this
really hard.
'''
input_shape = x.shape
output_shape = (input_shape[0],
input_shape[1] + 2 * padding,
input_shape[2])
output = T.zeros(output_shape)
return T.set_subtensor(output[:, padding:x.shape[1] + padding, :], x)
def spatial_2d_padding(x, padding=(1, 1), dim_ordering='th'):
'''Pad the 2nd and 3rd dimensions of a 4D tensor
with "padding[0]" and "padding[1]" (resp.) zeros left and right.
'''
input_shape = x.shape
if dim_ordering == 'th':
output_shape = (input_shape[0],
input_shape[1],
input_shape[2] + 2 * padding[0],
input_shape[3] + 2 * padding[1])
output = T.zeros(output_shape)
indices = (slice(None),
slice(None),
slice(padding[0], input_shape[2] + padding[0]),
slice(padding[1], input_shape[3] + padding[1]))
elif dim_ordering == 'tf':
output_shape = (input_shape[0],
input_shape[1] + 2 * padding[0],
input_shape[2] + 2 * padding[1],
input_shape[3])
output = T.zeros(output_shape)
indices = (slice(None),
slice(padding[0], input_shape[1] + padding[0]),
slice(padding[1], input_shape[2] + padding[1]),
slice(None))
else:
raise Exception('Invalid dim_ordering: ' + dim_ordering)
return T.set_subtensor(output[indices], x)
# VALUE MANIPULATION
def get_value(x):
if not hasattr(x, 'get_value'):
raise Exception("'get_value() can only be called on a variable. " +
"If you have an expression instead, use eval().")
return x.get_value()
def set_value(x, value):
x.set_value(np.asarray(value, dtype=x.dtype))
# GRAPH MANIPULATION
class Function(object):
def __init__(self, inputs, outputs, updates=[], **kwargs):
self.function = theano.function(inputs, outputs, updates=updates,
allow_input_downcast=True, **kwargs)
def __call__(self, inputs):
return self.function(*inputs)
def function(inputs, outputs, updates=[]):
return Function(inputs, outputs, updates=updates)
def gradients(loss, variables):
return T.grad(loss, variables)
# CONTROL FLOW
def rnn(step_function, inputs, initial_states,
go_backwards=False, masking=True):
'''Iterates over the time dimension of a tensor.
Parameters
----------
inputs: tensor of temporal data of shape (samples, time, ...)
(at least 3D).
step_function:
Parameters:
input: tensor with shape (samples, ...) (no time dimension),
representing input for the batch of samples at a certain
time step.
states: list of tensors.
Returns:
output: tensor with shape (samples, ...) (no time dimension),
new_states: list of tensors, same length and shapes
as 'states'.
initial_states: tensor with shape (samples, ...) (no time dimension),
containing the initial values for the states used in
the step function.
go_backwards: boolean. If True, do the iteration over
the time dimension in reverse order.
masking: boolean. If true, any input timestep inputs[s, i]
that is all-zeros will be skipped (states will be passed to
the next step unchanged) and the corresponding output will
be all zeros.
Returns
-------
A tuple (last_output, outputs, new_states).
last_output: the latest output of the rnn, of shape (samples, ...)
outputs: tensor with shape (samples, time, ...) where each
entry outputs[s, t] is the output of the step function
at time t for sample s.
new_states: list of tensors, latest states returned by
the step function, of shape (samples, ...).
'''
inputs = inputs.dimshuffle((1, 0, 2))
def _step(*args):
global single_result
input = args[0]
states = args[1:]
output, new_states = step_function(input, states)
if masking:
# if all-zero input timestep, return
# all-zero output and unchanged states
switch = T.any(input)
output = T.switch(switch, output, 0. * output)
return_states = []
for state, new_state in zip(states, new_states):
return_states.append(T.switch(switch, new_state, state))
return [output] + return_states
else:
return [output] + new_states
results, _ = theano.scan(
_step,
sequences=inputs,
outputs_info=[None] + initial_states,
go_backwards=go_backwards)
# deal with Theano API inconsistency
if type(results) is list:
outputs = results[0]
states = results[1:]
else:
outputs = results
states = []
outputs = T.squeeze(outputs)
last_output = outputs[-1]
outputs = outputs.dimshuffle((1, 0, 2))
states = [T.squeeze(state[-1]) for state in states]
return last_output, outputs, states
def switch(condition, then_expression, else_expression):
'''condition: scalar tensor.
'''
return T.switch(condition, then_expression, else_expression)
# NN OPERATIONS
def relu(x, alpha=0., max_value=None):
x = T.nnet.relu(x, alpha)
if max_value is not None:
x = T.minimum(x, max_value)
return x
def softmax(x):
return T.nnet.softmax(x)
def softplus(x):
return T.nnet.softplus(x)
def categorical_crossentropy(output, target, from_logits=False):
if from_logits:
output = T.nnet.softmax(output)
else:
# scale preds so that the class probas of each sample sum to 1
output /= output.sum(axis=-1, keepdims=True)
# avoid numerical instability with _EPSILON clipping
output = T.clip(output, _EPSILON, 1.0 - _EPSILON)
return T.nnet.categorical_crossentropy(output, target)
def binary_crossentropy(output, target, from_logits=False):
if from_logits:
output = T.nnet.sigmoid(output)
# avoid numerical instability with _EPSILON clipping
output = T.clip(output, _EPSILON, 1.0 - _EPSILON)
return T.nnet.binary_crossentropy(output, target)
def sigmoid(x):
return T.nnet.sigmoid(x)
def hard_sigmoid(x):
return T.nnet.hard_sigmoid(x)
def tanh(x):
return T.tanh(x)
def dropout(x, level, seed=None):
if level < 0. or level >= 1:
raise Exception('Dropout level must be in interval [0, 1[.')
if seed is None:
seed = np.random.randint(10e6)
rng = RandomStreams(seed=seed)
retain_prob = 1. - level
x *= rng.binomial(x.shape, p=retain_prob, dtype=x.dtype)
x /= retain_prob
return x
# CONVOLUTIONS
def conv2d(x, kernel, strides=(1, 1), border_mode='valid', dim_ordering='th'):
'''
Run on cuDNN if available.
border_mode: string, "same" or "valid".
'''
if dim_ordering not in {'th', 'tf'}:
raise Exception('Unknown dim_ordering ' + str(dim_ordering))
if dim_ordering == 'tf':
# TF uses the last dimension as channel dimension,
# instead of the 2nd one.
# TH input shape: (samples, input_depth, rows, cols)
# TF input shape: (samples, rows, cols, input_depth)
# TH kernel shape: (depth, input_depth, rows, cols)
# TF kernel shape: (rows, cols, input_depth, depth)
x = x.dimshuffle((0, 3, 1, 2))
kernel = kernel.dimshuffle((3, 2, 0, 1))
if _on_gpu() and dnn.dnn_available():
if border_mode == 'same':
assert(strides == (1, 1))
pad_x = (kernel.shape[2] - strides[0]) // 2
pad_y = (kernel.shape[3] - strides[1]) // 2
conv_out = dnn.dnn_conv(img=x,
kerns=kernel,
border_mode=(pad_x, pad_y))
else:
conv_out = dnn.dnn_conv(img=x,
kerns=kernel,
border_mode=border_mode,
subsample=strides)
else:
if border_mode == 'same':
th_border_mode = 'full'
assert(strides == (1, 1))
elif border_mode == 'valid':
th_border_mode = 'valid'
else:
raise Exception('Border mode not supported: ' + str(border_mode))
conv_out = T.nnet.conv.conv2d(x, kernel,
border_mode=th_border_mode,
subsample=strides)
if border_mode == 'same':
shift_x = (kernel.shape[2] - 1) // 2
shift_y = (kernel.shape[3] - 1) // 2
conv_out = conv_out[:, :,
shift_x:x.shape[2] + shift_x,
shift_y:x.shape[3] + shift_y]
if dim_ordering == 'tf':
conv_out = conv_out.dimshuffle((0, 2, 3, 1))
return conv_out
def maxpool2d(x, pool_size, strides=(1, 1), border_mode='valid',
dim_ordering='th'):
if border_mode == 'same':
# TODO: add implementation for border_mode="same"
raise Exception('border_mode="same" not supported with Theano.')
elif border_mode == 'valid':
ignore_border = True
padding = (0, 0)
else:
raise Exception('Invalid border mode: ' + str(border_mode))
if dim_ordering not in {'th', 'tf'}:
raise Exception('Unknown dim_ordering ' + str(dim_ordering))
if dim_ordering == 'tf':
x = x.dimshuffle((0, 3, 1, 2))
pool_out = downsample.max_pool_2d(x,
ds=pool_size,
st=strides,
ignore_border=ignore_border,
padding=padding,
mode='average_exc_pad')
if dim_ordering == 'tf':
pool_out = pool_out.dimshuffle((0, 2, 3, 1))
return pool_out
# RANDOMNESS
def random_normal(shape, mean=0.0, std=1.0, dtype=_FLOATX, seed=None):
if seed is None:
seed = np.random.randint(10e6)
rng = RandomStreams(seed=seed)
return rng.normal(size=shape, avg=mean, std=std, dtype=dtype)
def random_uniform(shape, low=0.0, high=1.0, dtype=_FLOATX, seed=None):
if seed is None:
seed = np.random.randint(10e6)
rng = RandomStreams(seed=seed)
return rng.uniform(shape, low=low, high=high, dtype=dtype)
'''
more TODO:
tensordot -> soon to be introduced in TF
batched_tensordot -> reimplement
'''
+164 -87
Ver Arquivo
@@ -1,16 +1,16 @@
from __future__ import absolute_import
from __future__ import print_function
import theano
import theano.tensor as T
import numpy as np
import warnings
import time
from collections import deque
import numpy as np
import time
import json
import warnings
from collections import deque
from .utils.generic_utils import Progbar
class CallbackList(object):
class CallbackList(object):
def __init__(self, callbacks=[], queue_length=10):
self.callbacks = [c for c in callbacks]
self.queue_length = queue_length
@@ -43,10 +43,9 @@ class CallbackList(object):
callback.on_batch_begin(batch, logs)
self._delta_ts_batch_begin.append(time.time() - t_before_callbacks)
delta_t_median = np.median(self._delta_ts_batch_begin)
if self._delta_t_batch > 0. and delta_t_median > 0.95 * self._delta_t_batch \
and delta_t_median > 0.1:
if self._delta_t_batch > 0. and delta_t_median > 0.95 * self._delta_t_batch and delta_t_median > 0.1:
warnings.warn('Method on_batch_begin() is slow compared '
'to the batch update (%f). Check your callbacks.' % delta_t_median)
'to the batch update (%f). Check your callbacks.' % delta_t_median)
self._t_enter_batch = time.time()
def on_batch_end(self, batch, logs={}):
@@ -56,10 +55,9 @@ class CallbackList(object):
callback.on_batch_end(batch, logs)
self._delta_ts_batch_end.append(time.time() - t_before_callbacks)
delta_t_median = np.median(self._delta_ts_batch_end)
if self._delta_t_batch > 0. and delta_t_median > 0.95 * self._delta_t_batch \
and delta_t_median > 0.1:
if self._delta_t_batch > 0. and delta_t_median > 0.95 * self._delta_t_batch and delta_t_median > 0.1:
warnings.warn('Method on_batch_end() is slow compared '
'to the batch update (%f). Check your callbacks.' % delta_t_median)
'to the batch update (%f). Check your callbacks.' % delta_t_median)
def on_train_begin(self, logs={}):
for callback in self.callbacks:
@@ -99,120 +97,199 @@ class Callback(object):
def on_train_end(self, logs={}):
pass
class BaseLogger(Callback):
class BaseLogger(Callback):
def on_train_begin(self, logs={}):
self.verbose = self.params['verbose']
self.nb_epoch = self.params['nb_epoch']
def on_epoch_begin(self, epoch, logs={}):
if self.verbose:
print('Epoch %d' % epoch)
self.progbar = Progbar(target=self.params['nb_sample'], \
verbose=self.verbose)
self.current = 0
self.tot_loss = 0.
self.tot_acc = 0.
print('Epoch %d/%d' % (epoch + 1, self.nb_epoch))
self.progbar = Progbar(target=self.params['nb_sample'],
verbose=self.verbose)
self.seen = 0
self.totals = {}
def on_batch_begin(self, batch, logs={}):
if self.current < self.params['nb_sample']:
if self.seen < self.params['nb_sample']:
self.log_values = []
def on_batch_end(self, batch, logs={}):
batch_size = logs.get('size', 0)
self.current += batch_size
self.seen += batch_size
for k, v in logs.items():
if k in self.totals:
self.totals[k] += v * batch_size
else:
self.totals[k] = v * batch_size
for k in self.params['metrics']:
if k in logs:
self.log_values.append((k, logs[k]))
loss = logs.get('loss')
self.log_values.append(('loss', loss))
self.tot_loss += loss * batch_size
if self.params['show_accuracy']:
accuracy = logs.get('accuracy')
self.log_values.append(('acc.', accuracy))
self.tot_acc += accuracy * batch_size
# skip progbar update for the last batch; will be handled by on_epoch_end
if self.verbose and self.current < self.params['nb_sample']:
self.progbar.update(self.current, self.log_values)
if self.verbose and self.seen < self.params['nb_sample']:
self.progbar.update(self.seen, self.log_values)
def on_epoch_end(self, epoch, logs={}):
self.log_values.append(('loss', self.tot_loss / self.current))
if self.params['show_accuracy']:
self.log_values.append(('acc.', self.tot_acc / self.current))
if self.params['do_validation']:
val_loss = logs.get('val_loss')
self.log_values.append(('val. loss', val_loss))
if self.params['show_accuracy']:
val_acc = logs.get('val_accuracy')
self.log_values.append(('val. acc.', val_acc))
self.progbar.update(self.current, self.log_values)
for k in self.params['metrics']:
if k in self.totals:
self.log_values.append((k, self.totals[k] / self.seen))
if k in logs:
self.log_values.append((k, logs[k]))
if self.verbose:
self.progbar.update(self.seen, self.log_values)
class History(Callback):
def on_train_begin(self, logs={}):
self.epoch = []
self.loss = []
if self.params['show_accuracy']:
self.accuracy = []
if self.params['do_validation']:
self.validation_loss = []
if self.params['show_accuracy']:
self.validation_accuracy = []
self.history = {}
def on_epoch_begin(self, epoch, logs={}):
self.seen = 0
self.tot_loss = 0.
self.tot_accuracy = 0.
self.totals = {}
def on_batch_end(self, batch, logs={}):
batch_size = logs.get('size', 0)
self.seen += batch_size
self.tot_loss += logs.get('loss', 0.) * batch_size
if self.params['show_accuracy']:
self.tot_accuracy += logs.get('accuracy', 0.) * batch_size
for k, v in logs.items():
if k in self.totals:
self.totals[k] += v * batch_size
else:
self.totals[k] = v * batch_size
def on_epoch_end(self, epoch, logs={}):
val_loss = logs.get('val_loss')
val_acc = logs.get('val_accuracy')
self.epoch.append(epoch)
self.loss.append(self.tot_loss / self.seen)
if self.params['show_accuracy']:
self.accuracy.append(self.tot_accuracy / self.seen)
if self.params['do_validation']:
self.validation_loss.append(val_loss)
if self.params['show_accuracy']:
self.validation_accuracy.append(val_acc)
for k, v in self.totals.items():
if k not in self.history:
self.history[k] = []
self.history[k].append(v / self.seen)
for k, v in logs.items():
if k not in self.history:
self.history[k] = []
self.history[k].append(v)
class ModelCheckpoint(Callback):
def __init__(self, filepath, verbose=0, save_best_only=False):
def __init__(self, filepath, monitor='val_loss', verbose=0, save_best_only=False, mode='auto'):
super(Callback, self).__init__()
self.monitor = monitor
self.verbose = verbose
self.filepath = filepath
self.save_best_only = save_best_only
self.loss = []
self.best_loss = np.Inf
self.val_loss = []
self.best_val_loss = np.Inf
if mode not in ['auto', 'min', 'max']:
warnings.warn("ModelCheckpoint mode %s is unknown, fallback to auto mode" % (self.mode), RuntimeWarning)
mode = 'auto'
if mode == "min":
self.monitor_op = np.less
self.best = np.Inf
elif mode == "max":
self.monitor_op = np.greater
self.best = -np.Inf
else:
if "acc" in self.monitor:
self.monitor_op = np.greater
self.best = -np.Inf
else:
self.monitor_op = np.less
self.best = np.Inf
def on_epoch_end(self, epoch, logs={}):
'''currently, on_epoch_end receives epoch_logs from keras.models.Sequential.fit
which does only contain, if at all, the validation loss and validation accuracy'''
if self.save_best_only and self.params['do_validation']:
cur_val_loss = logs.get('val_loss')
self.val_loss.append(cur_val_loss)
if cur_val_loss < self.best_val_loss:
if self.verbose > 0:
print("Epoch %05d: valdidation loss improved from %0.5f to %0.5f, saving model to %s"
% (epoch, self.best_val_loss, cur_val_loss, self.filepath))
self.best_val_loss = cur_val_loss
self.model.save_weights(self.filepath, overwrite=True)
filepath = self.filepath.format(epoch=epoch, **logs)
if self.save_best_only:
current = logs.get(self.monitor)
if current is None:
warnings.warn("Can save best model only with %s available, skipping." % (self.monitor), RuntimeWarning)
else:
if self.verbose > 0:
print("Epoch %05d: validation loss did not improve" % (epoch))
elif self.save_best_only and not self.params['do_validation']:
import warnings
warnings.warn("Can save best model only with validation data, skipping", RuntimeWarning)
elif not self.save_best_only:
if self.monitor_op(current, self.best):
if self.verbose > 0:
print("Epoch %05d: %s improved from %0.5f to %0.5f, saving model to %s"
% (epoch, self.monitor, self.best, current, filepath))
self.best = current
self.model.save_weights(filepath, overwrite=True)
else:
if self.verbose > 0:
print("Epoch %05d: %s did not improve" % (epoch, self.monitor))
else:
if self.verbose > 0:
print("Epoch %05d: saving model to %s" % (epoch, self.filepath))
self.model.save_weights(self.filepath, overwrite=True)
print("Epoch %05d: saving model to %s" % (epoch, filepath))
self.model.save_weights(filepath, overwrite=True)
class EarlyStopping(Callback):
def __init__(self, monitor='val_loss', patience=0, verbose=0):
super(Callback, self).__init__()
self.monitor = monitor
self.patience = patience
self.verbose = verbose
self.best = np.Inf
self.wait = 0
def on_epoch_end(self, epoch, logs={}):
current = logs.get(self.monitor)
if current is None:
warnings.warn("Early stopping requires %s available!" % (self.monitor), RuntimeWarning)
if current < self.best:
self.best = current
self.wait = 0
else:
if self.wait >= self.patience:
if self.verbose > 0:
print("Epoch %05d: early stopping" % (epoch))
self.model.stop_training = True
self.wait += 1
class RemoteMonitor(Callback):
def __init__(self, root='http://localhost:9000'):
self.root = root
def on_epoch_begin(self, epoch, logs={}):
self.seen = 0
self.totals = {}
def on_batch_end(self, batch, logs={}):
batch_size = logs.get('size', 0)
self.seen += batch_size
for k, v in logs.items():
if k in self.totals:
self.totals[k] += v * batch_size
else:
self.totals[k] = v * batch_size
def on_epoch_end(self, epoch, logs={}):
import requests
send = {}
send['epoch'] = epoch
for k, v in self.totals.items():
send[k] = v / self.seen
for k, v in logs.items():
send[k] = v
try:
r = requests.post(self.root + '/publish/epoch/end/', {'data': json.dumps(send)})
except:
print('Warning: could not reach RemoteMonitor root server at ' + str(self.root))
class LearningRateScheduler(Callback):
'''LearningRateScheduler
schedule is a function that gets an epoch number as input and returns a new
learning rate as output.
'''
def __init__(self, schedule):
super(LearningRateScheduler, self).__init__()
self.schedule = schedule
def on_epoch_begin(self, epoch, logs={}):
self.model.optimizer.lr.set_value(self.schedule(epoch))
+38 -15
Ver Arquivo
@@ -1,22 +1,45 @@
from __future__ import absolute_import
import theano
import theano.tensor as T
import numpy as np
from . import backend as K
def maxnorm(m=2):
def maxnorm_wrap(p):
norms = T.sqrt(T.sum(T.sqr(p), axis=0))
desired = T.clip(norms, 0, m)
class Constraint(object):
def __call__(self, p):
return p
def get_config(self):
return {"name": self.__class__.__name__}
class MaxNorm(Constraint):
def __init__(self, m=2):
self.m = m
def __call__(self, p):
norms = K.sqrt(K.sum(K.square(p), axis=0))
desired = K.clip(norms, 0, self.m)
p = p * (desired / (1e-7 + norms))
return p
return maxnorm_wrap
def nonneg(p):
p *= T.ge(p, 0)
return p
def get_config(self):
return {"name": self.__class__.__name__,
"m": self.m}
def identity(g):
return g
def unitnorm(e):
return e / T.sqrt(T.sum(e**2, axis=-1, keepdims=True))
class NonNeg(Constraint):
def __call__(self, p):
p *= K.cast(p >= 0., K.floatx())
return p
class UnitNorm(Constraint):
def __call__(self, p):
return p / K.sqrt(K.sum(K.square(p), axis=-1, keepdims=True))
identity = Constraint
maxnorm = MaxNorm
nonneg = NonNeg
unitnorm = UnitNorm
from .utils.generic_utils import get_from_module
def get(identifier, kwargs=None):
return get_from_module(identifier, globals(), 'constraint', instantiate=True, kwargs=kwargs)
+3 -3
Ver Arquivo
@@ -1,15 +1,15 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
import sys
import six.moves.cPickle
from six.moves import cPickle
from six.moves import range
def load_batch(fpath, label_key='labels'):
f = open(fpath, 'rb')
if sys.version_info < (3,):
d = six.moves.cPickle.load(f)
d = cPickle.load(f)
else:
d = six.moves.cPickle.load(f, encoding="bytes")
d = cPickle.load(f, encoding="bytes")
# decode utf8
for k, v in d.items():
del(d[k])
+3 -2
Ver Arquivo
@@ -4,6 +4,7 @@ from .data_utils import get_file
import numpy as np
import os
def load_data():
dirname = "cifar-10-batches-py"
origin = "http://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz"
@@ -20,11 +21,11 @@ def load_data():
data, labels = load_batch(fpath)
X_train[(i-1)*10000:i*10000, :, :, :] = data
y_train[(i-1)*10000:i*10000] = labels
fpath = os.path.join(path, 'test_batch')
X_test, y_test = load_batch(fpath)
y_train = np.reshape(y_train, (len(y_train), 1))
y_test = np.reshape(y_test, (len(y_test), 1))
return (X_train, y_train), (X_test, y_test)
return (X_train, y_train), (X_test, y_test)
+2 -1
Ver Arquivo
@@ -4,6 +4,7 @@ from .data_utils import get_file
import numpy as np
import os
def load_data(label_mode='fine'):
if label_mode not in ['fine', 'coarse']:
raise Exception('label_mode must be one of "fine" "coarse".')
@@ -24,4 +25,4 @@ def load_data(label_mode='fine'):
y_train = np.reshape(y_train, (len(y_train), 1))
y_test = np.reshape(y_test, (len(y_test), 1))
return (X_train, y_train), (X_test, y_test)
return (X_train, y_train), (X_test, y_test)
+14 -8
Ver Arquivo
@@ -1,9 +1,18 @@
from __future__ import absolute_import
from __future__ import print_function
import tarfile, inspect, os
from six.moves.urllib.request import urlretrieve
import tarfile
import os
from six.moves.urllib.request import FancyURLopener
from ..utils.generic_utils import Progbar
class ParanoidURLopener(FancyURLopener):
def http_error_default(self, url, fp, errcode, errmsg, headers):
raise Exception('URL fetch failure on {}: {} -- {}'.format(url, errcode, errmsg))
def get_file(fname, origin, untar=False):
datadir = os.path.expanduser(os.path.join('~', '.keras', 'datasets'))
if not os.path.exists(datadir):
@@ -15,13 +24,11 @@ def get_file(fname, origin, untar=False):
else:
fpath = os.path.join(datadir, fname)
try:
f = open(fpath)
except:
if not os.path.exists(fpath):
print('Downloading data from', origin)
global progbar
progbar = None
def dl_progress(count, block_size, total_size):
global progbar
if progbar is None:
@@ -29,7 +36,7 @@ def get_file(fname, origin, untar=False):
else:
progbar.update(count*block_size)
urlretrieve(origin, fpath, dl_progress)
ParanoidURLopener().retrieve(origin, fpath, dl_progress)
progbar = None
if untar:
@@ -41,4 +48,3 @@ def get_file(fname, origin, untar=False):
return untar_fpath
return fpath
+30 -9
Ver Arquivo
@@ -1,11 +1,15 @@
from __future__ import absolute_import
import six.moves.cPickle
from six.moves import cPickle
import gzip
from .data_utils import get_file
import random
from six.moves import zip
import numpy as np
def load_data(path="imdb.pkl", nb_words=None, skip_top=0, maxlen=None, test_split=0.2, seed=113,
start_char=1, oov_char=2, index_from=3):
def load_data(path="imdb.pkl", nb_words=None, skip_top=0, maxlen=None, test_split=0.2, seed=113):
path = get_file(path, origin="https://s3.amazonaws.com/text-datasets/imdb.pkl")
if path.endswith(".gz"):
@@ -13,13 +17,18 @@ def load_data(path="imdb.pkl", nb_words=None, skip_top=0, maxlen=None, test_spli
else:
f = open(path, 'rb')
X, labels = six.moves.cPickle.load(f)
X, labels = cPickle.load(f)
f.close()
random.seed(seed)
random.shuffle(X)
random.seed(seed)
random.shuffle(labels)
np.random.seed(seed)
np.random.shuffle(X)
np.random.seed(seed)
np.random.shuffle(labels)
if start_char is not None:
X = [[start_char] + [w + index_from for w in x] for x in X]
elif index_from:
X = [[w + index_from for w in x] for x in X]
if maxlen:
new_X = []
@@ -34,7 +43,20 @@ def load_data(path="imdb.pkl", nb_words=None, skip_top=0, maxlen=None, test_spli
if not nb_words:
nb_words = max([max(x) for x in X])
X = [[0 if (w >= nb_words or w < skip_top) else w for w in x] for x in X]
# by convention, use 2 as OOV word
# reserve 'index_from' (=3 by default) characters: 0 (padding), 1 (start), 2 (OOV)
if oov_char is not None:
X = [[oov_char if (w >= nb_words or w < skip_top) else w for w in x] for x in X]
else:
nX = []
for x in X:
nx = []
for w in x:
if (w >= nb_words or w < skip_top):
nx.append(w)
nX.append(nx)
X = nX
X_train = X[:int(len(X)*(1-test_split))]
y_train = labels[:int(len(X)*(1-test_split))]
@@ -42,4 +64,3 @@ def load_data(path="imdb.pkl", nb_words=None, skip_top=0, maxlen=None, test_spli
y_test = labels[int(len(X)*(1-test_split)):]
return (X_train, y_train), (X_test, y_test)
+5 -4
Ver Arquivo
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
import gzip
from .data_utils import get_file
import six.moves.cPickle
from six.moves import cPickle
import sys
def load_data(path="mnist.pkl.gz"):
path = get_file(path, origin="https://s3.amazonaws.com/img-datasets/mnist.pkl.gz")
@@ -13,10 +14,10 @@ def load_data(path="mnist.pkl.gz"):
f = open(path, 'rb')
if sys.version_info < (3,):
data = six.moves.cPickle.load(f)
data = cPickle.load(f)
else:
data = six.moves.cPickle.load(f, encoding="bytes")
data = cPickle.load(f, encoding="bytes")
f.close()
return data # (X_train, y_train), (X_test, y_test)
return data # (X_train, y_train), (X_test, y_test)
+40 -16
Ver Arquivo
@@ -5,8 +5,10 @@ from .data_utils import get_file
import string
import random
import os
import six.moves.cPickle
from six.moves import cPickle
from six.moves import zip
import numpy as np
def make_reuters_dataset(path=os.path.join('datasets', 'temp', 'reuters21578'), min_samples_per_topic=15):
import re
@@ -18,13 +20,12 @@ def make_reuters_dataset(path=os.path.join('datasets', 'temp', 'reuters21578'),
for fname in os.listdir(path):
if 'sgm' in fname:
s = open(path + fname).read()
s = open(os.path.join(path, fname)).read()
tag = '<TOPICS>'
while tag in s:
s = s[s.find(tag)+len(tag):]
topics = s[:s.find('</')]
if topics and not '</D><D>' in topics:
if topics and '</D><D>' not in topics:
topic = topics.replace('<D>', '').replace('</D>', '')
wire_topics.append(topic)
topic_counts[topic] = topic_counts.get(topic, 0) + 1
@@ -38,7 +39,7 @@ def make_reuters_dataset(path=os.path.join('datasets', 'temp', 'reuters21578'),
# only keep most common topics
items = list(topic_counts.items())
items.sort(key = lambda x: x[1])
items.sort(key=lambda x: x[1])
kept_topics = set()
for x in items:
print(x[0] + ': ' + str(x[1]))
@@ -70,25 +71,35 @@ def make_reuters_dataset(path=os.path.join('datasets', 'temp', 'reuters21578'),
print('Sanity check:')
for w in ["banana", "oil", "chocolate", "the", "dsft"]:
print('...index of', w, ':', tokenizer.word_index.get(w))
print('text reconstruction:')
reverse_word_index = dict([(v, k) for k, v in tokenizer.word_index.items()])
print(' '.join(reverse_word_index[i] for i in X[10]))
dataset = (X, labels)
dataset = (X, labels)
print('-')
print('Saving...')
six.moves.cPickle.dump(dataset, open(os.path.join('datasets', 'data', 'reuters.pkl'), 'w'))
six.moves.cPickle.dump(tokenizer.word_index, open(os.path.join('datasets','data', 'reuters_word_index.pkl'), 'w'))
cPickle.dump(dataset, open(os.path.join('datasets', 'data', 'reuters.pkl'), 'w'))
cPickle.dump(tokenizer.word_index, open(os.path.join('datasets', 'data', 'reuters_word_index.pkl'), 'w'))
def load_data(path="reuters.pkl", nb_words=None, skip_top=0, maxlen=None, test_split=0.2, seed=113,
start_char=1, oov_char=2, index_from=3):
def load_data(path="reuters.pkl", nb_words=None, skip_top=0, maxlen=None, test_split=0.2, seed=113):
path = get_file(path, origin="https://s3.amazonaws.com/text-datasets/reuters.pkl")
f = open(path, 'rb')
X, labels = six.moves.cPickle.load(f)
X, labels = cPickle.load(f)
f.close()
random.seed(seed)
random.shuffle(X)
random.seed(seed)
random.shuffle(labels)
np.random.seed(seed)
np.random.shuffle(X)
np.random.seed(seed)
np.random.shuffle(labels)
if start_char is not None:
X = [[start_char] + [w + index_from for w in x] for x in X]
elif index_from:
X = [[w + index_from for w in x] for x in X]
if maxlen:
new_X = []
@@ -103,7 +114,20 @@ def load_data(path="reuters.pkl", nb_words=None, skip_top=0, maxlen=None, test_s
if not nb_words:
nb_words = max([max(x) for x in X])
X = [[0 if (w >= nb_words or w < skip_top) else w for w in x] for x in X]
# by convention, use 2 as OOV word
# reserve 'index_from' (=3 by default) characters: 0 (padding), 1 (start), 2 (OOV)
if oov_char is not None:
X = [[oov_char if (w >= nb_words or w < skip_top) else w for w in x] for x in X]
else:
nX = []
for x in X:
nx = []
for w in x:
if (w >= nb_words or w < skip_top):
nx.append(w)
nX.append(nx)
X = nX
X_train = X[:int(len(X)*(1-test_split))]
y_train = labels[:int(len(X)*(1-test_split))]
@@ -116,7 +140,7 @@ def load_data(path="reuters.pkl", nb_words=None, skip_top=0, maxlen=None, test_s
def get_word_index(path="reuters_word_index.pkl"):
path = get_file(path, origin="https://s3.amazonaws.com/text-datasets/reuters_word_index.pkl")
f = open(path, 'rb')
return six.moves.cPickle.load(f)
return cPickle.load(f)
if __name__ == "__main__":
+31 -13
Ver Arquivo
@@ -1,9 +1,7 @@
from __future__ import absolute_import
import theano
import theano.tensor as T
import numpy as np
from . import backend as K
from .utils.theano_utils import sharedX, shared_zeros
def get_fans(shape):
fan_in = shape[0] if len(shape) == 2 else np.prod(shape[1:])
@@ -12,19 +10,22 @@ def get_fans(shape):
def uniform(shape, scale=0.05):
return sharedX(np.random.uniform(low=-scale, high=scale, size=shape))
return K.variable(np.random.uniform(low=-scale, high=scale, size=shape))
def normal(shape, scale=0.05):
return sharedX(np.random.randn(*shape) * scale)
return K.variable(np.random.randn(*shape) * scale)
def lecun_uniform(shape):
''' Reference: LeCun 98, Efficient Backprop
http://yann.lecun.com/exdb/publis/pdf/lecun-98b.pdf
'''
fan_in, fan_out = get_fans(shape)
scale = 1./np.sqrt(fan_in)
scale = np.sqrt(3. / fan_in)
return uniform(shape, scale)
def glorot_normal(shape):
''' Reference: Glorot & Bengio, AISTATS 2010
'''
@@ -32,11 +33,13 @@ def glorot_normal(shape):
s = np.sqrt(2. / (fan_in + fan_out))
return normal(shape, s)
def glorot_uniform(shape):
fan_in, fan_out = get_fans(shape)
s = np.sqrt(2. / (fan_in + fan_out))
s = np.sqrt(6. / (fan_in + fan_out))
return uniform(shape, s)
def he_normal(shape):
''' Reference: He et al., http://arxiv.org/abs/1502.01852
'''
@@ -44,23 +47,38 @@ def he_normal(shape):
s = np.sqrt(2. / fan_in)
return normal(shape, s)
def he_uniform(shape):
fan_in, fan_out = get_fans(shape)
s = np.sqrt(2. / fan_in)
s = np.sqrt(6. / fan_in)
return uniform(shape, s)
def orthogonal(shape, scale=1.1):
''' From Lasagne
''' From Lasagne. Reference: Saxe et al., http://arxiv.org/abs/1312.6120
'''
flat_shape = (shape[0], np.prod(shape[1:]))
a = np.random.normal(0.0, 1.0, flat_shape)
u, _, v = np.linalg.svd(a, full_matrices=False)
q = u if u.shape == flat_shape else v # pick the one with the correct shape
# pick the one with the correct shape
q = u if u.shape == flat_shape else v
q = q.reshape(shape)
return sharedX(scale * q[:shape[0], :shape[1]])
return K.variable(scale * q[:shape[0], :shape[1]])
def identity(shape, scale=1):
if len(shape) != 2 or shape[0] != shape[1]:
raise Exception("Identity matrix initialization can only be used for 2D square matrices")
else:
return K.variable(scale * np.identity(shape[0]))
def zero(shape):
return shared_zeros(shape)
return K.zeros(shape)
def one(shape):
return K.ones(shape)
from .utils.generic_utils import get_from_module
+137 -19
Ver Arquivo
@@ -1,38 +1,156 @@
from ..layers.core import Layer
from ..utils.theano_utils import shared_zeros
from .. import initializations
from ..layers.core import Layer, MaskedLayer
from .. import backend as K
import numpy as np
class LeakyReLU(Layer):
def __init__(self, alpha=0.3):
super(LeakyReLU,self).__init__()
class LeakyReLU(MaskedLayer):
def __init__(self, alpha=0.3, **kwargs):
super(LeakyReLU, self).__init__(**kwargs)
self.alpha = alpha
def get_output(self, train):
X = self.get_input(train)
return ((X + abs(X)) / 2.0) + self.alpha * ((X - abs(X)) / 2.0)
return K.relu(X, alpha=self.alpha)
def get_config(self):
return {"name":self.__class__.__name__,
"alpha":self.alpha}
config = {"name": self.__class__.__name__,
"alpha": self.alpha}
base_config = super(LeakyReLU, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class PReLU(Layer):
class PReLU(MaskedLayer):
'''
Reference:
Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification
Reference:
Delving Deep into Rectifiers: Surpassing Human-Level
Performance on ImageNet Classification
http://arxiv.org/pdf/1502.01852v1.pdf
'''
def __init__(self, input_shape):
super(PReLU,self).__init__()
self.alphas = shared_zeros(input_shape)
def __init__(self, init='zero', weights=None, **kwargs):
self.init = initializations.get(init)
self.initial_weights = weights
super(PReLU, self).__init__(**kwargs)
def build(self):
input_shape = self.input_shape[1:]
self.alphas = self.init(input_shape)
self.params = [self.alphas]
self.input_shape = input_shape
if self.initial_weights is not None:
self.set_weights(self.initial_weights)
del self.initial_weights
def get_output(self, train):
X = self.get_input(train)
pos = ((X + abs(X)) / 2.0)
neg = self.alphas * ((X - abs(X)) / 2.0)
pos = K.relu(X)
neg = self.alphas * (X - abs(X)) * 0.5
return pos + neg
def get_config(self):
return {"name":self.__class__.__name__,
"input_shape":self.input_shape}
config = {"name": self.__class__.__name__,
"init": self.init.__name__}
base_config = super(PReLU, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class ELU(MaskedLayer):
def __init__(self, alpha=1.0, **kwargs):
super(ELU, self).__init__(**kwargs)
self.alpha = alpha
def get_output(self, train):
X = self.get_input(train)
pos = K.relu(X)
neg = (X - abs(X)) * 0.5
return pos + self.alpha * (K.exp(neg) - 1.)
def get_config(self):
config = {"name": self.__class__.__name__,
"alpha": self.alpha}
base_config = super(ELU, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class ParametricSoftplus(MaskedLayer):
'''
Parametric Softplus of the form: alpha * log(1 + exp(beta * X))
Reference:
Inferring Nonlinear Neuronal Computation
Based on Physiologically Plausible Inputs
http://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1003143
'''
def __init__(self, alpha_init=0.2, beta_init=5.0,
weights=None, **kwargs):
self.alpha_init = alpha_init
self.beta_init = beta_init
self.initial_weights = weights
super(ParametricSoftplus, self).__init__(**kwargs)
def build(self):
input_shape = self.input_shape[1:]
self.alphas = K.variable(self.alpha_init * np.ones(input_shape))
self.betas = K.variable(self.beta_init * np.ones(input_shape))
self.params = [self.alphas, self.betas]
if self.initial_weights is not None:
self.set_weights(self.initial_weights)
del self.initial_weights
def get_output(self, train):
X = self.get_input(train)
return K.softplus(self.betas * X) * self.alphas
def get_config(self):
config = {"name": self.__class__.__name__,
"alpha_init": self.alpha_init,
"beta_init": self.beta_init}
base_config = super(ParametricSoftplus, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class ThresholdedLinear(MaskedLayer):
'''
Thresholded Linear Activation
Reference:
Zero-Bias Autoencoders and the Benefits of Co-Adapting Features
http://arxiv.org/pdf/1402.3337.pdf
'''
def __init__(self, theta=1.0, **kwargs):
super(ThresholdedLinear, self).__init__(**kwargs)
self.theta = theta
def get_output(self, train):
X = self.get_input(train)
return K.switch(K.abs(X) < self.theta, 0, X)
def get_config(self):
config = {"name": self.__class__.__name__,
"theta": self.theta}
base_config = super(ThresholdedLinear, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class ThresholdedReLU(MaskedLayer):
'''
Thresholded Rectified Activation
Reference:
Zero-Bias Autoencoders and the Benefits of Co-Adapting Features
http://arxiv.org/pdf/1402.3337.pdf
'''
def __init__(self, theta=1.0, **kwargs):
super(ThresholdedReLU, self).__init__(**kwargs)
self.theta = theta
def get_output(self, train):
X = self.get_input(train)
return K.switch(X > self.theta, X, 0)
def get_config(self):
config = {"name": self.__class__.__name__,
"theta": self.theta}
base_config = super(ThresholdedReLU, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
+363 -27
Ver Arquivo
@@ -1,53 +1,93 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import print_function
import theano.tensor as T
from ..layers.core import Layer
from collections import OrderedDict
from .. import backend as K
from ..layers.core import Layer, Merge, Siamese, SiameseHead
from six.moves import range
def ndim_tensor(ndim):
if ndim == 2:
return T.matrix()
elif ndim == 3:
return T.tensor3()
elif ndim == 4:
return T.tensor4()
return T.matrix()
class Sequential(Layer):
'''
Simple linear stack of layers.
inherited from Layer:
- get_params
- get_output_mask
- supports_masked_input
'''
def __init__(self, layers=[]):
self.layers = []
self.params = []
self.regularizers = []
self.constraints = []
for layer in layers:
self.add(layer)
def connect(self, layer):
def set_previous(self, layer):
self.layers[0].previous = layer
def add(self, layer):
self.layers.append(layer)
if len(self.layers) > 1:
self.layers[-1].connect(self.layers[-2])
params, regularizers, constraints = layer.get_params()
self.params += params
self.regularizers += regularizers
self.constraints += constraints
self.layers[-1].set_previous(self.layers[-2])
if not hasattr(self.layers[0], 'input'):
self.set_input()
@property
def params(self):
params = []
for l in self.layers:
if l.trainable:
params += l.get_params()[0]
return params
@property
def regularizers(self):
regularizers = []
for l in self.layers:
if l.trainable:
regularizers += l.get_params()[1]
return regularizers
@property
def constraints(self):
constraints = []
for l in self.layers:
if l.trainable:
constraints += l.get_params()[2]
return constraints
@property
def updates(self):
updates = []
for l in self.layers:
if l.trainable:
updates += l.get_params()[3]
return updates
@property
def output_shape(self):
return self.layers[-1].output_shape
def get_output(self, train=False):
return self.layers[-1].get_output(train)
def set_input(self):
for l in self.layers:
if hasattr(l, 'input'):
ndim = len(K.get_shape(l.input))
self.layers[0].input = K.placeholder(ndim=ndim)
break
def get_input(self, train=False):
if not hasattr(self.layers[0], 'input'):
for l in self.layers:
if hasattr(l, 'input'):
break
ndim = l.input.ndim
self.layers[0].input = ndim_tensor(ndim)
self.set_input()
return self.layers[0].get_input(train)
@property
def input_shape(self):
return self.layers[0].input_shape
@property
def input(self):
return self.get_input()
@@ -65,5 +105,301 @@ class Sequential(Layer):
weights = weights[nb_param:]
def get_config(self):
return {"name":self.__class__.__name__,
"layers":[layer.get_config() for layer in self.layers]}
return {"name": self.__class__.__name__,
"layers": [layer.get_config() for layer in self.layers]}
def count_params(self):
return sum([layer.count_params() for layer in self.layers])
class Graph(Layer):
'''
Implement a NN graph with arbitrary layer connections,
arbitrary number of inputs and arbitrary number of outputs.
Note: Graph can only be used as a layer
(connect, input, get_input, get_output)
when it has exactly one input and one output.
inherited from Layer:
- get_output_mask
- supports_masked_input
- get_weights
- set_weights
'''
def __init__(self):
self.namespace = set() # strings
self.nodes = OrderedDict() # layer-like
self.inputs = {} # layer-like
self.input_order = [] # strings
self.outputs = {} # layer-like
self.output_order = [] # strings
self.input_config = [] # dicts
self.output_config = [] # dicts
self.node_config = [] # dicts
@property
def nb_input(self):
return len(self.inputs)
@property
def nb_output(self):
return len(self.outputs)
@property
def params(self):
params = []
for l in self.nodes.values():
if l.trainable:
params += l.get_params()[0]
return params
@property
def regularizers(self):
regularizers = []
for l in self.nodes.values():
if l.trainable:
regularizers += l.get_params()[1]
return regularizers
@property
def constraints(self):
constraints = []
for l in self.nodes.values():
if l.trainable:
constraints += l.get_params()[2]
return constraints
@property
def updates(self):
updates = []
for l in self.nodes.values():
if l.trainable:
updates += l.get_params()[3]
return updates
def set_previous(self, layer, connection_map={}):
if self.nb_input != layer.nb_output:
raise Exception('Cannot connect layers: input count does not match output count.')
if self.nb_input == 1:
self.inputs[self.input_order[0]].set_previous(layer)
else:
if not connection_map:
raise Exception('Cannot attach multi-input layer: no connection_map provided.')
for k, v in connection_map.items():
if k in self.inputs and v in layer.outputs:
self.inputs[k].set_previous(layer.outputs[v])
else:
raise Exception('Invalid connection map.')
def get_input(self, train=False):
if len(self.inputs) == len(self.outputs) == 1:
return self.inputs[self.input_order[0]].get_input(train)
else:
return dict([(k, v.get_input(train)) for k, v in self.inputs.items()])
@property
def input(self):
return self.get_input()
@property
def output_shape(self):
if self.nb_output == 1:
# return tuple
return self.outputs[self.output_order[0]].output_shape
else:
# return dictionary mapping output names to shape tuples
return dict([(k, v.output_shape) for k, v in self.outputs.items()])
def get_output(self, train=False):
if len(self.inputs) == len(self.outputs) == 1:
return self.outputs[self.output_order[0]].get_output(train)
else:
return dict([(k, v.get_output(train)) for k, v in self.outputs.items()])
def add_input(self, name, input_shape, dtype='float'):
if name in self.namespace:
raise Exception('Duplicate node identifier: ' + name)
self.namespace.add(name)
self.input_order.append(name)
layer = Layer() # empty layer
layer.set_input_shape(input_shape)
if dtype == 'float':
layer.input = K.placeholder(shape=layer.input_shape, name=name)
else:
if len(input_shape) == 1:
layer.input = K.placeholder(shape=layer.input_shape,
dtype='int32',
name=name)
else:
raise Exception('Type "int" can only be used with ndim==2 (Embedding).')
self.inputs[name] = layer
self.input_config.append({'name': name,
'input_shape': input_shape,
'dtype': dtype})
def add_node(self, layer, name, input=None, inputs=[],
merge_mode='concat', concat_axis=-1, dot_axes=-1,
create_output=False):
if name in self.namespace:
raise Exception('Duplicate node identifier: ' + name)
if input:
if input not in self.namespace:
raise Exception('Unknown node/input identifier: ' + input)
if input in self.nodes:
layer.set_previous(self.nodes[input])
elif input in self.inputs:
layer.set_previous(self.inputs[input])
if inputs:
to_merge = []
for n in inputs:
if n in self.nodes:
to_merge.append(self.nodes[n])
elif n in self.inputs:
to_merge.append(self.inputs[n])
else:
raise Exception('Unknown identifier: ' + n)
merge = Merge(to_merge, mode=merge_mode,
concat_axis=concat_axis, dot_axes=dot_axes)
layer.set_previous(merge)
self.namespace.add(name)
self.nodes[name] = layer
self.node_config.append({'name': name,
'input': input,
'inputs': inputs,
'merge_mode': merge_mode,
'concat_axis': concat_axis,
'dot_axes': dot_axes,
'create_output': create_output})
if create_output:
self.add_output(name, input=name)
def add_shared_node(self, layer, name, inputs=[], merge_mode=None,
concat_axis=-1, dot_axes=-1, outputs=[],
create_output=False):
'''
Used to shared / multi input-multi output node
Arguments
------------
layer - The layer to be shared across multiple inputs
name - Name of the shared layer
inputs - List of names of input nodes
merge_mode - Similar to merge_mode argument of add_node()
concat_axis - Similar to concat_axis argument of add_node()
dot_axes - Similar to dot_axes argument of add_node()
outputs - Names for output nodes. Used when merge_mode = None
create_output - Similar to create_output argument of add_node().
Output will be created only if merge_mode is given
'''
if name in self.namespace:
raise Exception('Duplicate node identifier: ' + name)
for o in outputs:
if o in self.namespace:
raise Exception('Duplicate node identifier: ' + o)
if merge_mode:
if merge_mode not in {'sum', 'ave', 'mul', 'dot', 'cos', 'concat', 'join'}:
raise Eception("Invalid merge mode")
layers = []
for i in range(len(inputs)):
input = inputs[i]
if input in self.nodes:
n = self.nodes[input]
if n.__class__.__name__ == 'Siamese':
if n.merge_mode is None:
for j in range(len(n.inputs)):
sh = SiameseHead(j)
sh.previous = n
layers.append(sh)
else:
layers.append(n)
else:
layers.append(n)
elif input in self.inputs:
n = self.inputs[input]
layers.append(n)
else:
raise Exception('Unknown identifier: ' + input)
s = Siamese(layer, layers, merge_mode, concat_axis=concat_axis, dot_axes=dot_axes)
s.set_name(name)
self.namespace.add(name)
self.nodes[name] = s
self.node_config.append({'name': name,
'inputs': inputs,
'merge_mode': merge_mode,
'concat_axis': concat_axis,
'dot_axes': dot_axes,
'create_output': create_output if merge_mode else False})
if not merge_mode:
for i in range(len(outputs)):
sh = SiameseHead(i)
sh.previous = s
sh_name = outputs[i]
sh.set_name(sh_name)
self.namespace.add(sh_name)
self.nodes[sh_name] = sh
self.node_config.append({'name': sh_name,
'inputs': [s],
'create_output': create_output})
if create_output:
self.add_output(sh_name, input=sh_name)
if create_output and merge_mode:
if merge_mode == 'join':
raise Exception("Output can not be of type OrderedDict")
self.add_output(name, input=name)
def add_output(self, name, input=None, inputs=[],
merge_mode='concat', concat_axis=-1, dot_axes=-1):
if name in self.output_order:
raise Exception('Duplicate output identifier: ' + name)
if input:
if input not in self.namespace:
raise Exception('Unknown node/input identifier: ' + input)
if input in self.nodes:
self.outputs[name] = self.nodes[input]
elif input in self.inputs:
self.outputs[name] = self.inputs[input]
if inputs:
to_merge = []
for n in inputs:
if n not in self.nodes:
raise Exception('Unknown identifier: ' + n)
to_merge.append(self.nodes[n])
merge = Merge(to_merge, mode=merge_mode,
concat_axis=concat_axis, dot_axes=dot_axes)
self.outputs[name] = merge
self.output_order.append(name)
self.output_config.append({'name': name,
'input': input,
'inputs': inputs,
'merge_mode': merge_mode,
'concat_axis': concat_axis,
'dot_axes': dot_axes})
def get_config(self):
return {"name": self.__class__.__name__,
"input_config": self.input_config,
"node_config": self.node_config,
"output_config": self.output_config,
"input_order": self.input_order,
"output_order": self.output_order,
"nodes": dict([(c["name"], self.nodes[c["name"]].get_config()) for c in self.node_config])}
def count_params(self):
return sum([layer.count_params() for layer in self.nodes.values()])
def get_weights(self):
weights = []
for layer in self.nodes.values():
weights += layer.get_weights()
return weights
def set_weights(self, weights):
for layer in self.nodes.values():
nb_param = len(layer.get_weights())
layer.set_weights(weights[:nb_param])
weights = weights[nb_param:]
+451 -107
Ver Arquivo
@@ -1,161 +1,505 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
import theano
import theano.tensor as T
from theano.tensor.signal import downsample
from .. import activations, initializations
from ..utils.theano_utils import shared_zeros
from .. import backend as K
from .. import activations, initializations, regularizers, constraints
from ..layers.core import Layer
class Convolution1D(Layer):
def __init__(self, nb_filter, stack_size, filter_length,
init='uniform', activation='linear', weights=None,
image_shape=None, border_mode='valid', subsample_length=1,
W_regularizer=None, b_regularizer=None, W_constraint=None, b_constraint=None):
def conv_output_length(input_length, filter_size, border_mode, stride):
if input_length is None:
return None
assert border_mode in {'same', 'valid'}
if border_mode == 'same':
output_length = input_length
elif border_mode == 'valid':
output_length = input_length - filter_size + 1
return (output_length + stride - 1) // stride
nb_row = 1
nb_col = filter_length
class Convolution1D(Layer):
input_ndim = 3
def __init__(self, nb_filter, filter_length,
init='uniform', activation='linear', weights=None,
border_mode='valid', subsample_length=1,
W_regularizer=None, b_regularizer=None, activity_regularizer=None,
W_constraint=None, b_constraint=None,
input_dim=None, input_length=None, **kwargs):
if border_mode not in {'valid', 'same'}:
raise Exception('Invalid border mode for Convolution1D:', border_mode)
self.nb_filter = nb_filter
self.stack_size = stack_size
self.filter_length = filter_length
self.subsample_length = subsample_length
self.init = initializations.get(init)
self.activation = activations.get(activation)
self.subsample = (1, subsample_length)
assert border_mode in {'valid', 'same'}, 'border_mode must be in {valid, same}'
self.border_mode = border_mode
self.image_shape = image_shape
self.subsample_length = subsample_length
self.input = T.tensor4()
self.W_shape = (nb_filter, stack_size, nb_row, nb_col)
self.subsample = (subsample_length, 1)
self.W_regularizer = regularizers.get(W_regularizer)
self.b_regularizer = regularizers.get(b_regularizer)
self.activity_regularizer = regularizers.get(activity_regularizer)
self.W_constraint = constraints.get(W_constraint)
self.b_constraint = constraints.get(b_constraint)
self.constraints = [self.W_constraint, self.b_constraint]
self.initial_weights = weights
self.input_dim = input_dim
self.input_length = input_length
if self.input_dim:
kwargs['input_shape'] = (self.input_length, self.input_dim)
self.input = K.placeholder(ndim=3)
super(Convolution1D, self).__init__(**kwargs)
def build(self):
input_dim = self.input_shape[2]
self.W_shape = (self.nb_filter, input_dim, self.filter_length, 1)
self.W = self.init(self.W_shape)
self.b = shared_zeros((nb_filter,))
self.b = K.zeros((self.nb_filter,))
self.params = [self.W, self.b]
self.regularizers = []
self.regularizers = [W_regularizer, b_regularizer]
self.constraints = [W_constraint, b_constraint]
if self.W_regularizer:
self.W_regularizer.set_param(self.W)
self.regularizers.append(self.W_regularizer)
if weights is not None:
self.set_weights(weights)
if self.b_regularizer:
self.b_regularizer.set_param(self.b)
self.regularizers.append(self.b_regularizer)
def get_output(self, train):
if self.activity_regularizer:
self.activity_regularizer.set_layer(self)
self.regularizers.append(self.activity_regularizer)
if self.initial_weights is not None:
self.set_weights(self.initial_weights)
del self.initial_weights
@property
def output_shape(self):
length = conv_output_length(self.input_shape[1],
self.filter_length,
self.border_mode,
self.subsample[0])
return (self.input_shape[0], length, self.nb_filter)
def get_output(self, train=False):
X = self.get_input(train)
X = K.expand_dims(X, -1) # add a dimension of the right
X = K.permute_dimensions(X, (0, 2, 1, 3))
conv_out = K.conv2d(X, self.W, strides=self.subsample,
border_mode=self.border_mode, dim_ordering='th')
conv_out = theano.tensor.nnet.conv.conv2d(X, self.W,
border_mode=self.border_mode, subsample=self.subsample, image_shape=self.image_shape)
output = self.activation(conv_out + self.b.dimshuffle('x', 0, 'x', 'x'))
output = conv_out + K.reshape(self.b, (1, self.nb_filter, 1, 1))
output = self.activation(output)
output = K.squeeze(output, 3) # remove the dummy 3rd dimension
output = K.permute_dimensions(output, (0, 2, 1))
return output
def get_config(self):
return {"name":self.__class__.__name__,
"nb_filter":self.nb_filter,
"stack_size":self.stack_size,
"filter_length":self.filter_length,
"init":self.init.__name__,
"activation":self.activation.__name__,
"image_shape":self.image_shape,
"border_mode":self.border_mode,
"subsample_length":self.subsample_length}
class MaxPooling1D(Layer):
def __init__(self, pool_length=2, ignore_border=True):
self.pool_length = pool_length
self.poolsize = (1, pool_length)
self.ignore_border = ignore_border
self.input = T.tensor4()
self.params = []
def get_output(self, train):
X = self.get_input(train)
output = downsample.max_pool_2d(X, self.poolsize, ignore_border=self.ignore_border)
return output
def get_config(self):
return {"name":self.__class__.__name__,
"pool_length":self.pool_length,
"ignore_border":self.ignore_border}
config = {"name": self.__class__.__name__,
"nb_filter": self.nb_filter,
"filter_length": self.filter_length,
"init": self.init.__name__,
"activation": self.activation.__name__,
"border_mode": self.border_mode,
"subsample_length": self.subsample_length,
"W_regularizer": self.W_regularizer.get_config() if self.W_regularizer else None,
"b_regularizer": self.b_regularizer.get_config() if self.b_regularizer else None,
"activity_regularizer": self.activity_regularizer.get_config() if self.activity_regularizer else None,
"W_constraint": self.W_constraint.get_config() if self.W_constraint else None,
"b_constraint": self.b_constraint.get_config() if self.b_constraint else None,
"input_dim": self.input_dim,
"input_length": self.input_length}
base_config = super(Convolution1D, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class Convolution2D(Layer):
def __init__(self, nb_filter, stack_size, nb_row, nb_col,
init='glorot_uniform', activation='linear', weights=None,
image_shape=None, border_mode='valid', subsample=(1,1),
W_regularizer=None, b_regularizer=None, W_constraint=None, b_constraint=None):
super(Convolution2D,self).__init__()
input_ndim = 4
self.init = initializations.get(init)
self.activation = activations.get(activation)
self.subsample = subsample
self.border_mode = border_mode
self.image_shape = image_shape
def __init__(self, nb_filter, nb_row, nb_col,
init='glorot_uniform', activation='linear', weights=None,
border_mode='valid', subsample=(1, 1), dim_ordering='th',
W_regularizer=None, b_regularizer=None, activity_regularizer=None,
W_constraint=None, b_constraint=None, **kwargs):
if border_mode not in {'valid', 'same'}:
raise Exception('Invalid border mode for Convolution2D:', border_mode)
self.nb_filter = nb_filter
self.stack_size = stack_size
self.nb_row = nb_row
self.nb_col = nb_col
self.init = initializations.get(init)
self.activation = activations.get(activation)
assert border_mode in {'valid', 'same'}, 'border_mode must be in {valid, same}'
self.border_mode = border_mode
self.subsample = tuple(subsample)
assert dim_ordering in {'tf', 'th'}, 'dim_ordering must be in {tf, th}'
self.dim_ordering = dim_ordering
self.input = T.tensor4()
self.W_shape = (nb_filter, stack_size, nb_row, nb_col)
self.W_regularizer = regularizers.get(W_regularizer)
self.b_regularizer = regularizers.get(b_regularizer)
self.activity_regularizer = regularizers.get(activity_regularizer)
self.W_constraint = constraints.get(W_constraint)
self.b_constraint = constraints.get(b_constraint)
self.constraints = [self.W_constraint, self.b_constraint]
self.initial_weights = weights
self.input = K.placeholder(ndim=4)
super(Convolution2D, self).__init__(**kwargs)
def build(self):
if self.dim_ordering == 'th':
stack_size = self.input_shape[1]
self.W_shape = (self.nb_filter, stack_size, self.nb_row, self.nb_col)
elif self.dim_ordering == 'tf':
stack_size = self.input_shape[3]
self.W_shape = (self.nb_row, self.nb_col, stack_size, self.nb_filter)
else:
raise Exception('Invalid dim_ordering: ' + self.dim_ordering)
self.W = self.init(self.W_shape)
self.b = shared_zeros((nb_filter,))
self.b = K.zeros((self.nb_filter,))
self.params = [self.W, self.b]
self.regularizers = []
self.regularizers = [W_regularizer, b_regularizer]
self.constraints = [W_constraint, b_constraint]
if self.W_regularizer:
self.W_regularizer.set_param(self.W)
self.regularizers.append(self.W_regularizer)
if weights is not None:
self.set_weights(weights)
if self.b_regularizer:
self.b_regularizer.set_param(self.b)
self.regularizers.append(self.b_regularizer)
def get_output(self, train):
if self.activity_regularizer:
self.activity_regularizer.set_layer(self)
self.regularizers.append(self.activity_regularizer)
if self.initial_weights is not None:
self.set_weights(self.initial_weights)
del self.initial_weights
@property
def output_shape(self):
input_shape = self.input_shape
if self.dim_ordering == 'th':
rows = input_shape[2]
cols = input_shape[3]
elif self.dim_ordering == 'tf':
rows = input_shape[1]
cols = input_shape[2]
else:
raise Exception('Invalid dim_ordering: ' + self.dim_ordering)
rows = conv_output_length(rows, self.nb_row,
self.border_mode, self.subsample[0])
cols = conv_output_length(cols, self.nb_col,
self.border_mode, self.subsample[1])
if self.dim_ordering == 'th':
return (input_shape[0], self.nb_filter, rows, cols)
elif self.dim_ordering == 'tf':
return (input_shape[0], rows, cols, self.nb_filter)
else:
raise Exception('Invalid dim_ordering: ' + self.dim_ordering)
def get_output(self, train=False):
X = self.get_input(train)
conv_out = K.conv2d(X, self.W, strides=self.subsample,
border_mode=self.border_mode,
dim_ordering=self.dim_ordering)
conv_out = theano.tensor.nnet.conv.conv2d(X, self.W,
border_mode=self.border_mode, subsample=self.subsample, image_shape=self.image_shape)
output = self.activation(conv_out + self.b.dimshuffle('x', 0, 'x', 'x'))
output = conv_out + K.reshape(self.b, (1, self.nb_filter, 1, 1))
output = self.activation(output)
return output
def get_config(self):
return {"name":self.__class__.__name__,
"nb_filter":self.nb_filter,
"stack_size":self.stack_size,
"nb_row":self.nb_row,
"nb_col":self.nb_col,
"init":self.init.__name__,
"activation":self.activation.__name__,
"image_shape":self.image_shape,
"border_mode":self.border_mode,
"subsample":self.subsample}
config = {"name": self.__class__.__name__,
"nb_filter": self.nb_filter,
"nb_row": self.nb_row,
"nb_col": self.nb_col,
"init": self.init.__name__,
"activation": self.activation.__name__,
"border_mode": self.border_mode,
"subsample": self.subsample,
"dim_ordering": self.dim_ordering,
"W_regularizer": self.W_regularizer.get_config() if self.W_regularizer else None,
"b_regularizer": self.b_regularizer.get_config() if self.b_regularizer else None,
"activity_regularizer": self.activity_regularizer.get_config() if self.activity_regularizer else None,
"W_constraint": self.W_constraint.get_config() if self.W_constraint else None,
"b_constraint": self.b_constraint.get_config() if self.b_constraint else None}
base_config = super(Convolution2D, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class MaxPooling1D(Layer):
input_ndim = 3
def __init__(self, pool_length=2, stride=None,
border_mode='valid', **kwargs):
super(MaxPooling1D, self).__init__(**kwargs)
if stride is None:
stride = pool_length
self.pool_length = pool_length
self.stride = stride
self.st = (self.stride, 1)
self.input = K.placeholder(ndim=3)
self.pool_size = (pool_length, 1)
assert border_mode in {'valid', 'same'}, 'border_mode must be in {valid, same}'
self.border_mode = border_mode
@property
def output_shape(self):
input_shape = self.input_shape
length = conv_output_length(input_shape[1], self.pool_length,
self.border_mode, self.stride)
return (input_shape[0], length, input_shape[2])
def get_output(self, train=False):
X = self.get_input(train)
X = K.expand_dims(X, -1) # add dummy last dimension
X = K.permute_dimensions(X, (0, 2, 1, 3))
output = K.maxpool2d(X, pool_size=self.pool_size, strides=self.st,
border_mode=self.border_mode,
dim_ordering='th')
output = K.permute_dimensions(output, (0, 2, 1, 3))
return K.squeeze(output, 3) # remove dummy last dimension
def get_config(self):
config = {"name": self.__class__.__name__,
"stride": self.stride,
"pool_length": self.pool_length,
"border_mode": self.border_mode}
base_config = super(MaxPooling1D, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class MaxPooling2D(Layer):
def __init__(self, poolsize=(2, 2), ignore_border=True):
super(MaxPooling2D,self).__init__()
self.input = T.tensor4()
self.poolsize = poolsize
self.ignore_border = ignore_border
input_ndim = 4
def get_output(self, train):
def __init__(self, pool_size=(2, 2), strides=None, border_mode='valid',
dim_ordering='th', **kwargs):
super(MaxPooling2D, self).__init__(**kwargs)
self.input = K.placeholder(ndim=4)
self.pool_size = tuple(pool_size)
if strides is None:
strides = self.pool_size
self.strides = tuple(strides)
assert border_mode in {'valid', 'same'}, 'border_mode must be in {valid, same}'
self.border_mode = border_mode
assert dim_ordering in {'tf', 'th'}, 'dim_ordering must be in {tf, th}'
self.dim_ordering = dim_ordering
@property
def output_shape(self):
input_shape = self.input_shape
if self.dim_ordering == 'th':
rows = input_shape[2]
cols = input_shape[3]
elif self.dim_ordering == 'tf':
rows = input_shape[1]
cols = input_shape[2]
else:
raise Exception('Invalid dim_ordering: ' + self.dim_ordering)
rows = conv_output_length(rows, self.pool_size[0],
self.border_mode, self.strides[0])
cols = conv_output_length(cols, self.pool_size[1],
self.border_mode, self.strides[1])
if self.dim_ordering == 'th':
return (input_shape[0], input_shape[1], rows, cols)
elif self.dim_ordering == 'tf':
return (input_shape[0], rows, cols, input_shape[3])
else:
raise Exception('Invalid dim_ordering: ' + self.dim_ordering)
def get_output(self, train=False):
X = self.get_input(train)
output = downsample.max_pool_2d(X, self.poolsize, ignore_border=self.ignore_border)
output = K.maxpool2d(X, pool_size=self.pool_size,
strides=self.strides,
border_mode=self.border_mode,
dim_ordering=self.dim_ordering)
return output
def get_config(self):
return {"name":self.__class__.__name__,
"poolsize":self.poolsize,
"ignore_border":self.ignore_border}
config = {"name": self.__class__.__name__,
"pool_size": self.pool_size,
"border_mode": self.border_mode,
"strides": self.strides,
"dim_ordering": self.dim_ordering}
base_config = super(MaxPooling2D, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class UpSampling1D(Layer):
input_ndim = 3
# class ZeroPadding2D(Layer): TODO
def __init__(self, length=2, **kwargs):
super(UpSampling1D, self).__init__(**kwargs)
self.length = length
self.input = K.placeholder(ndim=3)
# class Convolution3D: TODO
@property
def output_shape(self):
input_shape = self.input_shape
return (input_shape[0], self.length * input_shape[1], input_shape[2])
# class MaxPooling3D: TODO
def get_output(self, train=False):
X = self.get_input(train)
output = K.concatenate([X] * self.length, axis=1)
return output
def get_config(self):
config = {"name": self.__class__.__name__,
"length": self.length}
base_config = super(UpSampling1D, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class UpSampling2D(Layer):
input_ndim = 4
def __init__(self, size=(2, 2), dim_ordering='th', **kwargs):
super(UpSampling2D, self).__init__(**kwargs)
self.input = K.placeholder(ndim=4)
self.size = tuple(size)
assert dim_ordering in {'tf', 'th'}, 'dim_ordering must be in {tf, th}'
self.dim_ordering = dim_ordering
@property
def output_shape(self):
input_shape = self.input_shape
if self.dim_ordering == 'th':
return (input_shape[0],
input_shape[1],
self.size[0] * input_shape[2],
self.size[1] * input_shape[3])
elif self.dim_ordering == 'tf':
return (input_shape[0],
self.size[0] * input_shape[1],
self.size[1] * input_shape[2],
input_shape[3])
else:
raise Exception('Invalid dim_ordering: ' + self.dim_ordering)
def get_output(self, train=False):
X = self.get_input(train)
if self.dim_ordering == 'th':
output = K.concatenate([X] * self.size[0], axis=2)
output = K.concatenate([output] * self.size[1], axis=3)
elif self.dim_ordering == 'tf':
output = K.concatenate([X] * self.size[0], axis=1)
output = K.concatenate([output] * self.size[1], axis=2)
else:
raise Exception('Invalid dim_ordering: ' + self.dim_ordering)
return output
def get_config(self):
config = {"name": self.__class__.__name__,
"size": self.size}
base_config = super(UpSampling2D, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class ZeroPadding1D(Layer):
"""Zero-padding layer for 1D input (e.g. temporal sequence).
Input shape
-----------
3D tensor with shape (samples, axis_to_pad, features)
Output shape
------------
3D tensor with shape (samples, padded_axis, features)
Arguments
---------
padding: int
How many zeros to add at the beginning and end of
the padding dimension (axis 1).
"""
input_ndim = 3
def __init__(self, padding=1, **kwargs):
super(ZeroPadding1D, self).__init__(**kwargs)
self.padding = padding
self.input = K.placeholder(ndim=3)
@property
def output_shape(self):
input_shape = self.input_shape
return (input_shape[0],
input_shape[1] + self.padding * 2,
input_shape[2])
def get_output(self, train=False):
X = self.get_input(train)
return K.temporal_padding(X, padding=self.padding)
def get_config(self):
config = {"name": self.__class__.__name__,
"padding": self.padding}
base_config = super(ZeroPadding1D, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class ZeroPadding2D(Layer):
"""Zero-padding layer for 2D input (e.g. picture).
Input shape
-----------
4D tensor with shape:
(samples, depth, first_axis_to_pad, second_axis_to_pad)
Output shape
------------
4D tensor with shape:
(samples, depth, first_padded_axis, second_padded_axis)
Arguments
---------
padding: tuple of int (length 2)
How many zeros to add at the beginning and end of
the 2 padding dimensions (axis 3 and 4).
"""
input_ndim = 4
def __init__(self, padding=(1, 1), dim_ordering='th', **kwargs):
super(ZeroPadding2D, self).__init__(**kwargs)
self.padding = tuple(padding)
self.input = K.placeholder(ndim=4)
assert dim_ordering in {'tf', 'th'}, 'dim_ordering must be in {tf, th}'
self.dim_ordering = dim_ordering
@property
def output_shape(self):
input_shape = self.input_shape
if self.dim_ordering == 'th':
return (input_shape[0],
input_shape[1],
input_shape[2] + 2 * self.padding[0],
input_shape[3] + 2 * self.padding[1])
elif self.dim_ordering == 'tf':
return (input_shape[0],
input_shape[1] + 2 * self.padding[0],
input_shape[2] + 2 * self.padding[1],
input_shape[3])
else:
raise Exception('Invalid dim_ordering: ' + self.dim_ordering)
def get_output(self, train=False):
X = self.get_input(train)
return K.spatial_2d_padding(X, padding=self.padding,
dim_ordering=self.dim_ordering)
def get_config(self):
config = {"name": self.__class__.__name__,
"padding": self.padding}
base_config = super(ZeroPadding2D, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
+1207 -246
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+64 -80
Ver Arquivo
@@ -1,104 +1,88 @@
from __future__ import absolute_import
import theano
import theano.tensor as T
from .. import backend as K
from .. import activations, initializations, regularizers, constraints
from ..layers.core import Layer, MaskedLayer
from .. import activations, initializations
from ..layers.core import Layer
from ..constraints import unitnorm
class Embedding(Layer):
'''
Turn positive integers (indexes) into denses vectors of fixed size.
Turn positive integers (indexes) into denses vectors of fixed size.
eg. [[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]]
@input_dim: size of vocabulary (highest input integer + 1)
@out_dim: size of dense representation
'''
def __init__(self, input_dim, output_dim, init='uniform', weights=None, W_regularizer=None, W_constraint=None):
super(Embedding,self).__init__()
self.init = initializations.get(init)
input_ndim = 2
def __init__(self, input_dim, output_dim,
init='uniform', input_length=None,
W_regularizer=None, activity_regularizer=None,
W_constraint=None,
mask_zero=False,
weights=None, **kwargs):
self.input_dim = input_dim
self.output_dim = output_dim
self.init = initializations.get(init)
self.input_length = input_length
self.mask_zero = mask_zero
self.input = T.imatrix()
self.W_constraint = constraints.get(W_constraint)
self.constraints = [self.W_constraint]
self.W_regularizer = regularizers.get(W_regularizer)
self.activity_regularizer = regularizers.get(activity_regularizer)
self.initial_weights = weights
kwargs['input_shape'] = (self.input_dim,)
super(Embedding, self).__init__(**kwargs)
def build(self):
self.input = K.placeholder(shape=(None, self.input_length),
dtype='int32')
self.W = self.init((self.input_dim, self.output_dim))
self.params = [self.W]
self.constraints = [W_constraint]
self.regularizers = [W_regularizer]
self.regularizers = []
if self.W_regularizer:
self.W_regularizer.set_param(self.W)
self.regularizers.append(self.W_regularizer)
if weights is not None:
self.set_weights(weights)
if self.activity_regularizer:
self.activity_regularizer.set_layer(self)
self.regularizers.append(self.activity_regularizer)
if self.initial_weights is not None:
self.set_weights(self.initial_weights)
def get_output_mask(self, train=None):
X = self.get_input(train)
if not self.mask_zero:
return None
else:
if K._BACKEND == "tensorflow":
raise Exception("Masking is Theano-only for the time being.")
return K.ones_like(X) * (1 - K.equal(X, 0))
@property
def output_shape(self):
return (self.input_shape[0], self.input_length, self.output_dim)
def get_output(self, train=False):
X = self.get_input(train)
out = self.W[X]
out = K.gather(self.W, X)
return out
def get_config(self):
return {"name":self.__class__.__name__,
"input_dim":self.input_dim,
"output_dim":self.output_dim,
"init":self.init.__name__}
class WordContextProduct(Layer):
'''
This layer turns a pair of words (a pivot word + a context word,
ie. a word from the same context, or a random, out-of-context word),
indentified by their index in a vocabulary, into two dense reprensentations
(word representation and context representation).
Then it returns activation(dot(pivot_embedding, context_embedding)),
which can be trained to encode the probability
of finding the context word in the context of the pivot word
(or reciprocally depending on your training procedure).
The layer ingests integer tensors of shape:
(nb_samples, 2)
and outputs a float tensor of shape
(nb_samples, 1)
The 2nd dimension encodes (pivot, context).
input_dim is the size of the vocabulary.
For more context, see Mikolov et al.:
Efficient Estimation of Word reprensentations in Vector Space
http://arxiv.org/pdf/1301.3781v3.pdf
'''
def __init__(self, input_dim, proj_dim=128,
init='uniform', activation='sigmoid', weights=None):
super(WordContextProduct,self).__init__()
self.input_dim = input_dim
self.proj_dim = proj_dim
self.init = initializations.get(init)
self.activation = activations.get(activation)
self.input = T.imatrix()
# two different embeddings for pivot word and its context
# because p(w|c) != p(c|w)
self.W_w = self.init((input_dim, proj_dim))
self.W_c = self.init((input_dim, proj_dim))
self.params = [self.W_w, self.W_c]
if weights is not None:
self.set_weights(weights)
def get_output(self, train=False):
X = self.get_input(train)
w = self.W_w[X[:, 0]] # nb_samples, proj_dim
c = self.W_c[X[:, 1]] # nb_samples, proj_dim
dot = T.sum(w * c, axis=1)
dot = theano.tensor.reshape(dot, (X.shape[0], 1))
return self.activation(dot)
def get_config(self):
return {"name":self.__class__.__name__,
"input_dim":self.input_dim,
"proj_dim":self.proj_dim,
"init":self.init.__name__,
"activation":self.activation.__name__}
config = {"name": self.__class__.__name__,
"input_dim": self.input_dim,
"output_dim": self.output_dim,
"init": self.init.__name__,
"input_length": self.input_length,
"mask_zero": self.mask_zero,
"activity_regularizer": self.activity_regularizer.get_config() if self.activity_regularizer else None,
"W_regularizer": self.W_regularizer.get_config() if self.W_regularizer else None,
"W_constraint": self.W_constraint.get_config() if self.W_constraint else None}
base_config = super(Embedding, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
+55
Ver Arquivo
@@ -0,0 +1,55 @@
from __future__ import absolute_import
from .core import MaskedLayer
from .. import backend as K
class GaussianNoise(MaskedLayer):
'''
Corruption process with GaussianNoise
'''
def __init__(self, sigma, **kwargs):
super(GaussianNoise, self).__init__(**kwargs)
self.sigma = sigma
def get_output(self, train=False):
X = self.get_input(train)
if not train or self.sigma == 0:
return X
else:
return X + K.random_normal(shape=K.shape(X),
mean=0.,
std=self.sigma)
def get_config(self):
config = {"name": self.__class__.__name__,
"sigma": self.sigma}
base_config = super(GaussianNoise, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class GaussianDropout(MaskedLayer):
'''
Multiplicative Gaussian Noise
Reference:
Dropout: A Simple Way to Prevent Neural Networks from Overfitting
Srivastava, Hinton, et al. 2014
http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf
'''
def __init__(self, p, **kwargs):
super(GaussianDropout, self).__init__(**kwargs)
self.p = p
def get_output(self, train):
X = self.get_input(train)
if train:
# self.p refers to drop probability rather than
# retain probability (as in paper), for consistency
X *= K.random_normal(shape=K.shape(X), mean=1.0,
std=self.p / (1.0 - self.p))
return X
def get_config(self):
config = {"name": self.__class__.__name__,
"p": self.p}
base_config = super(GaussianDropout, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
+94 -40
Ver Arquivo
@@ -1,69 +1,123 @@
from ..layers.core import Layer
from ..utils.theano_utils import shared_zeros
from .. import initializations
from .. import backend as K
import theano.tensor as T
class BatchNormalization(Layer):
'''
Reference:
Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift
Reference:
Batch Normalization: Accelerating Deep Network Training
by Reducing Internal Covariate Shift
http://arxiv.org/pdf/1502.03167v3.pdf
mode: 0 -> featurewise normalization
1 -> samplewise normalization (may sometimes outperform featurewise mode)
1 -> samplewise normalization
(may sometimes outperform featurewise mode)
momentum: momentum term in the computation of a running estimate of the mean and std of the data
momentum: momentum term in the computation
of a running estimate of the mean and std of the data
'''
def __init__(self, input_shape, epsilon=1e-6, mode=0, momentum=0.9, weights=None):
super(BatchNormalization,self).__init__()
def __init__(self, epsilon=1e-6, mode=0, momentum=0.9,
weights=None, **kwargs):
self.init = initializations.get("uniform")
self.input_shape = input_shape
self.epsilon = epsilon
self.mode = mode
self.momentum = momentum
self.initial_weights = weights
super(BatchNormalization, self).__init__(**kwargs)
self.gamma = self.init((self.input_shape))
self.beta = shared_zeros(self.input_shape)
def build(self):
input_shape = self.input_shape # starts with samples axis
input_shape = input_shape[1:]
self.running_mean = None
self.running_std = None
self.gamma = self.init((input_shape))
self.beta = K.zeros(input_shape)
self.params = [self.gamma, self.beta]
if weights is not None:
self.set_weights(weights)
self.running_mean = K.zeros(input_shape)
self.running_std = K.ones((input_shape))
# initialize self.updates: batch mean/std computation
X = self.get_input(train=True)
m = K.mean(X, axis=0)
std = K.mean(K.square(X - m) + self.epsilon, axis=0)
std = K.sqrt(std)
mean_update = self.momentum * self.running_mean + (1-self.momentum) * m
std_update = self.momentum * self.running_std + (1-self.momentum) * std
self.updates = [(self.running_mean, mean_update),
(self.running_std, std_update)]
if self.initial_weights is not None:
self.set_weights(self.initial_weights)
del self.initial_weights
def get_weights(self):
super_weights = super(BatchNormalization, self).get_weights()
return super_weights + [K.get_value(self.running_mean),
K.get_value(self.running_std)]
def set_weights(self, weights):
K.set_value(self.running_mean, weights[-2])
K.set_value(self.running_std, weights[-1])
super(BatchNormalization, self).set_weights(weights[:-2])
def get_output(self, train):
X = self.get_input(train)
if self.mode == 0:
if train:
m = X.mean(axis=0)
# manual computation of std to prevent NaNs
std = T.mean((X-m)**2 + self.epsilon, axis=0) ** 0.5
X_normed = (X - m) / (std + self.epsilon)
if self.running_mean is None:
self.running_mean = m
self.running_std = std
else:
self.running_mean *= self.momentum
self.running_mean += (1-self.momentum) * m
self.running_std *= self.momentum
self.running_std += (1-self.momentum) * std
else:
X_normed = (X - self.running_mean) / (self.running_std + self.epsilon)
X_normed = ((X - self.running_mean) /
(self.running_std + self.epsilon))
elif self.mode == 1:
m = X.mean(axis=-1, keepdims=True)
std = X.std(axis=-1, keepdims=True)
m = K.mean(X, axis=-1, keepdims=True)
std = K.std(X, axis=-1, keepdims=True)
X_normed = (X - m) / (std + self.epsilon)
out = self.gamma * X_normed + self.beta
return out
def get_config(self):
return {"name":self.__class__.__name__,
"input_shape":self.input_shape,
"epsilon":self.epsilon,
"mode":self.mode}
config = {"name": self.__class__.__name__,
"epsilon": self.epsilon,
"mode": self.mode,
"momentum": self.momentum}
base_config = super(BatchNormalization, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class LRN2D(Layer):
"""
This code is adapted from pylearn2.
License at: https://github.com/lisa-lab/pylearn2/blob/master/LICENSE.txt
"""
def __init__(self, alpha=1e-4, k=2, beta=0.75, n=5, **kwargs):
if n % 2 == 0:
raise NotImplementedError("LRN2D only works with odd n. n provided: " + str(n))
super(LRN2D, self).__init__(**kwargs)
self.alpha = alpha
self.k = k
self.beta = beta
self.n = n
def get_output(self, train):
X = self.get_input(train)
b, ch, r, c = K.shape(X)
half_n = self.n // 2
input_sqr = K.square(X)
extra_channels = K.zeros((b, ch + 2 * half_n, r, c))
input_sqr = K.concatenate([extra_channels[:, :half_n, :, :],
input_sqr,
extra_channels[:, half_n + ch:, :, :]],
axis=1)
scale = self.k
for i in range(self.n):
scale += self.alpha * input_sqr[:, i:i + ch, :, :]
scale = scale ** self.beta
return X / scale
def get_config(self):
config = {"name": self.__class__.__name__,
"alpha": self.alpha,
"k": self.k,
"beta": self.beta,
"n": self.n}
base_config = super(LRN2D, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
+326
Ver Arquivo
@@ -0,0 +1,326 @@
import numpy as np
from scipy.linalg import circulant
from .. import backend as K
import theano
import theano.tensor as T
floatX = theano.config.floatX
from keras.layers.recurrent import Recurrent, GRU, LSTM
from keras.utils.theano_utils import shared_zeros, alloc_zeros_matrix, shared_scalar
tol = 1e-4
def _update_controller(self, inp, h_tm1, M, mask):
""" Update inner RNN controler
We have to update the inner RNN inside the Neural Turing Machine, this
is an almost literal copy of keras.layers.recurrent.GRU and
keras.layers.recurrent.LSTM see these clases for further details.
"""
x = T.concatenate([inp, M], axis=-1)
# get inputs
if self.inner_rnn == 'gru':
x_z = T.dot(x, self.rnn.W_z) + self.rnn.b_z
x_r = T.dot(x, self.rnn.W_r) + self.rnn.b_r
x_h = T.dot(x, self.rnn.W_h) + self.rnn.b_h
elif self.inner_rnn == 'lstm':
xi = T.dot(x, self.rnn.W_i) + self.rnn.b_i
xf = T.dot(x, self.rnn.W_f) + self.rnn.b_f
xc = T.dot(x, self.rnn.W_c) + self.rnn.b_c
xo = T.dot(x, self.rnn.W_o) + self.rnn.b_o
elif self.inner_rnn == 'simple':
x = T.dot(x, self.rnn.W) + self.rnn.b
# update state
if self.inner_rnn == 'gru':
h = self.rnn._step(x_z, x_r, x_h, 1., h_tm1[0],
self.rnn.U_z,
self.rnn.U_r,
self.rnn.U_h)
h = mask[:, None] * h + (1-mask[:, None])*h_tm1[0]
h = (h, )
elif self.inner_rnn == 'lstm':
h = self.rnn._step(xi, xf, xo, xc, 1.,
h_tm1[1], h_tm1[0],
self.rnn.U_i, self.rnn.U_f,
self.rnn.U_o, self.rnn.U_c)
h = h[::-1]
h = tuple([mask[:, None]*h[i] +
(1-mask[:, None])*h_tm1[i] for i in range(len(h))])
elif self.inner_rnn == 'simple':
h = self.rnn._step(x, 1, h_tm1[0], self.rnn.U)
h = mask[:, None] * h + (1-mask[:, None])*h_tm1[0]
h = (h, )
return h
def _circulant(leng, n_shifts):
""" Generate circulant copies of a vector.
This will generate a tensor with `n_shifts` of rotated versions the
identity matrix. When this tensor is multiplied by a vector
the result are `n_shifts` shifted versions of that vector. Since
everything is done with inner products, this operation is differentiable.
Paramters:
----------
leng: int > 0, number of memory locations
n_shifts: int > 0, number of allowed shifts (if 1, no shift)
Returns:
--------
shift operation, a tensor with dimensions (n_shifts, leng, leng)
"""
eye = np.eye(leng)
shifts = range(n_shifts//2, -n_shifts//2, -1)
C = np.asarray([np.roll(eye, s, axis=1) for s in shifts])
return theano.shared(C.astype(theano.config.floatX))
def _renorm(x):
return x / (x.sum(axis=1, keepdims=True))
def _softmax(x):
wt = x.flatten(ndim=2)
w = T.nnet.softmax(wt)
return w.reshape(x.shape) # T.clip(s, 0, 1)
def _cosine_distance(M, k):
dot = (M * k[:, None, :]).sum(axis=-1)
nM = T.sqrt((M**2).sum(axis=-1))
nk = T.sqrt((k**2).sum(axis=-1, keepdims=True))
return dot / (nM * nk)
class NeuralTuringMachine(Recurrent):
""" Neural Turing Machines
Parameters:
-----------
shift_range: int, number of available shifts, ex. if 3, avilable shifts are
(-1, 0, 1)
n_slots: number of memory locations
m_length: memory length at each location
inner_rnn: str, supported values are 'gru' and 'lstm'
output_dim: hidden state size (RNN controller output_dim)
Known issues and TODO:
----------------------
Theano may complain when n_slots == 1.
Add multiple reading and writing heads.
"""
def __init__(self, output_dim, n_slots, m_length, shift_range=3,
inner_rnn='gru', truncate_gradient=-1, return_sequences=False,
init='glorot_uniform', inner_init='orthogonal',
input_dim=None, input_length=None, **kwargs):
if K._BACKEND != 'theano':
raise Exception('NeuralTuringMachine is only available for Theano for the time being. ' +
'It will be adapted to TensorFlow soon.')
self.output_dim = output_dim
self.n_slots = n_slots
self.m_length = m_length
self.shift_range = shift_range
self.init = init
self.inner_init = inner_init
self.inner_rnn = inner_rnn
self.return_sequences = return_sequences
self.truncate_gradient = truncate_gradient
self.input_dim = input_dim
self.input_length = input_length
if self.input_dim:
kwargs['input_shape'] = (self.input_length, self.input_dim)
super(NeuralTuringMachine, self).__init__(**kwargs)
def build(self):
input_leng, input_dim = self.input_shape[1:]
self.input = T.tensor3()
if self.inner_rnn == 'gru':
self.rnn = GRU(
input_dim=input_dim+self.m_length,
input_length=input_leng,
output_dim=self.output_dim, init=self.init,
inner_init=self.inner_init)
elif self.inner_rnn == 'lstm':
self.rnn = LSTM(
input_dim=input_dim+self.m_length,
input_length=input_leng,
output_dim=self.output_dim, init=self.init,
inner_init=self.inner_init)
else:
raise ValueError('this inner_rnn is not implemented yet.')
self.rnn.build()
# initial memory, state, read and write vecotrs
self.M = theano.shared((.001*np.ones((1,)).astype(floatX)))
self.init_h = shared_zeros((self.output_dim))
self.init_wr = self.rnn.init((self.n_slots,))
self.init_ww = self.rnn.init((self.n_slots,))
# write
self.W_e = self.rnn.init((self.output_dim, self.m_length)) # erase
self.b_e = shared_zeros((self.m_length))
self.W_a = self.rnn.init((self.output_dim, self.m_length)) # add
self.b_a = shared_zeros((self.m_length))
# get_w parameters for reading operation
self.W_k_read = self.rnn.init((self.output_dim, self.m_length))
self.b_k_read = self.rnn.init((self.m_length, ))
self.W_c_read = self.rnn.init((self.output_dim, 3)) # 3 = beta, g, gamma see eq. 5, 7, 9 in Graves et. al 2014
self.b_c_read = shared_zeros((3))
self.W_s_read = self.rnn.init((self.output_dim, self.shift_range))
self.b_s_read = shared_zeros((self.shift_range))
# get_w parameters for writing operation
self.W_k_write = self.rnn.init((self.output_dim, self.m_length))
self.b_k_write = self.rnn.init((self.m_length, ))
self.W_c_write = self.rnn.init((self.output_dim, 3)) # 3 = beta, g, gamma see eq. 5, 7, 9
self.b_c_write = shared_zeros((3))
self.W_s_write = self.rnn.init((self.output_dim, self.shift_range))
self.b_s_write = shared_zeros((self.shift_range))
self.C = _circulant(self.n_slots, self.shift_range)
self.params = self.rnn.params + [
self.W_e, self.b_e,
self.W_a, self.b_a,
self.W_k_read, self.b_k_read,
self.W_c_read, self.b_c_read,
self.W_s_read, self.b_s_read,
self.W_k_write, self.b_k_write,
self.W_s_write, self.b_s_write,
self.W_c_write, self.b_c_write,
self.M,
self.init_h, self.init_wr, self.init_ww]
if self.inner_rnn == 'lstm':
self.init_c = shared_zeros((self.output_dim))
self.params = self.params + [self.init_c, ]
def _read(self, w, M):
return (w[:, :, None]*M).sum(axis=1)
def _write(self, w, e, a, M, mask):
Mtilda = M * (1 - w[:, :, None]*e[:, None, :])
Mout = Mtilda + w[:, :, None]*a[:, None, :]
return mask[:, None, None]*Mout + (1-mask[:, None, None])*M
def _get_content_w(self, beta, k, M):
num = beta[:, None] * _cosine_distance(M, k)
return _softmax(num)
def _get_location_w(self, g, s, C, gamma, wc, w_tm1, mask):
wg = g[:, None] * wc + (1-g[:, None])*w_tm1
Cs = (C[None, :, :, :] * wg[:, None, None, :]).sum(axis=3)
wtilda = (Cs * s[:, :, None]).sum(axis=1)
wout = _renorm(wtilda ** gamma[:, None])
return mask[:, None] * wout + (1-mask[:, None])*w_tm1
def _get_controller_output(self, h, W_k, b_k, W_c, b_c, W_s, b_s):
k = T.tanh(T.dot(h, W_k) + b_k) # + 1e-6
c = T.dot(h, W_c) + b_c
beta = T.nnet.relu(c[:, 0]) + 1e-6
g = T.nnet.sigmoid(c[:, 1])
gamma = T.nnet.relu(c[:, 2]) + 1
s = T.nnet.softmax(T.dot(h, W_s) + b_s)
return k, beta, g, gamma, s
def _get_initial_states(self, batch_size):
init_M = self.M.dimshuffle(0, 'x', 'x').repeat(
batch_size, axis=0).repeat(self.n_slots, axis=1).repeat(
self.m_length, axis=2)
init_h = self.init_h.dimshuffle(('x', 0)).repeat(batch_size, axis=0)
init_wr = self.init_wr.dimshuffle(('x', 0)).repeat(batch_size, axis=0)
init_ww = self.init_ww.dimshuffle(('x', 0)).repeat(batch_size, axis=0)
if self.inner_rnn == 'lstm':
init_c = self.init_c.dimshuffle(('x', 0)).repeat(batch_size, axis=0)
return init_M, T.nnet.softmax(init_wr), T.nnet.softmax(init_ww), init_h, init_c
else:
return init_M, T.nnet.softmax(init_wr), T.nnet.softmax(init_ww), init_h
def _step(self, x, mask, M_tm1, wr_tm1, ww_tm1, *args):
# read
if self.inner_rnn == 'lstm':
h_tm1 = args[0:2][::-1] # (cell_tm1, h_tm1)
else:
h_tm1 = args[0:1] # (h_tm1, )
k_read, beta_read, g_read, gamma_read, s_read = self._get_controller_output(
h_tm1[-1], self.W_k_read, self.b_k_read, self.W_c_read, self.b_c_read,
self.W_s_read, self.b_s_read)
wc_read = self._get_content_w(beta_read, k_read, M_tm1)
wr_t = self._get_location_w(g_read, s_read, self.C, gamma_read,
wc_read, wr_tm1, mask)
M_read = self._read(wr_t, M_tm1)
# update controller
h_t = _update_controller(self, x, h_tm1, M_read, mask)
# write
k_write, beta_write, g_write, gamma_write, s_write = self._get_controller_output(
h_t[-1], self.W_k_write, self.b_k_write, self.W_c_write,
self.b_c_write, self.W_s_write, self.b_s_write)
wc_write = self._get_content_w(beta_write, k_write, M_tm1)
ww_t = self._get_location_w(g_write, s_write, self.C, gamma_write,
wc_write, ww_tm1, mask)
e = T.nnet.sigmoid(T.dot(h_t[-1], self.W_e) + self.b_e)
a = T.tanh(T.dot(h_t[-1], self.W_a) + self.b_a)
M_t = self._write(ww_t, e, a, M_tm1, mask)
return (M_t, wr_t, ww_t) + h_t
def get_output(self, train=False):
outputs = self.get_full_output(train)
if self.return_sequences:
return outputs[-1]
else:
return outputs[-1][:, -1]
@property
def output_shape(self):
input_shape = self.input_shape
if self.return_sequences:
return input_shape[0], input_shape[1], self.output_dim
else:
return input_shape[0], self.output_dim
def get_full_output(self, train=False):
"""
This method is for research and visualization purposes. Use it as:
X = model.get_input() # full model
Y = ntm.get_output() # this layer
F = theano.function([X], Y, allow_input_downcast=True)
[memory, read_address, write_address, rnn_state] = F(x)
if inner_rnn == "lstm" use it as:
[memory, read_address, write_address, rnn_cell, rnn_state] = F(x)
"""
X = self.get_input(train)
padded_mask = self.get_padded_shuffled_mask(train, X, pad=1)[:, :, 0]
X = X.dimshuffle((1, 0, 2))
init_states = self._get_initial_states(X.shape[1])
outputs, updates = theano.scan(self._step,
sequences=[X, padded_mask],
outputs_info=init_states,
non_sequences=self.params,
truncate_gradient=self.truncate_gradient)
out = [outputs[0].dimshuffle((1, 0, 2, 3)),
outputs[1].dimshuffle(1, 0, 2),
outputs[2].dimshuffle((1, 0, 2)),
outputs[3].dimshuffle((1, 0, 2))]
if self.inner_rnn == 'lstm':
out + [outputs[4].dimshuffle((1, 0, 2))]
return out
+263 -279
Ver Arquivo
@@ -1,276 +1,269 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
import theano
import theano.tensor as T
import numpy as np
from .. import backend as K
from .. import activations, initializations
from ..utils.theano_utils import shared_zeros, alloc_zeros_matrix
from ..layers.core import Layer
from six.moves import range
from ..layers.core import MaskedLayer
class SimpleRNN(Layer):
'''
Fully connected RNN where output is to fed back to input.
Not a particularly useful model,
included for demonstration purposes
(demonstrates how to use theano.scan to build a basic RNN).
class Recurrent(MaskedLayer):
input_ndim = 3
def __init__(self, weights=None,
return_sequences=False, go_backwards=False, stateful=False,
input_dim=None, input_length=None, **kwargs):
self.return_sequences = return_sequences
self.initial_weights = weights
self.go_backwards = go_backwards
self.stateful = stateful
self.input_dim = input_dim
self.input_length = input_length
if self.input_dim:
kwargs['input_shape'] = (self.input_length, self.input_dim)
super(Recurrent, self).__init__(**kwargs)
def get_output_mask(self, train=False):
if self.return_sequences:
return super(Recurrent, self).get_output_mask(train)
else:
return None
@property
def output_shape(self):
input_shape = self.input_shape
if self.return_sequences:
return (input_shape[0], input_shape[1], self.output_dim)
else:
return (input_shape[0], self.output_dim)
def step(self, x, states):
raise NotImplementedError
def get_output(self, train=False):
# input shape: (nb_samples, time (padded with zeros), input_dim)
X = self.get_input(train)
assert K.ndim(X) == 3
if K._BACKEND == 'tensorflow':
if not self.input_shape[1]:
raise Exception('When using TensorFlow, you should define ' +
'explicitely the number of timesteps of ' +
'your sequences. Make sure the first layer ' +
'has an "input_shape" argument with a defined ' +
'first dimension.')
mask = self.get_output_mask(train)
if mask:
# apply mask
X *= K.expand_dims(mask)
masking = True
else:
masking = False
if self.stateful:
initial_states = self.states
else:
# build an all-zero tensor of shape (samples, output_dim)
initial_state = K.zeros_like(X) # (samples, timesteps, input_dim)
initial_state = K.sum(initial_state, axis=1) # (samples, input_dim)
reducer = K.zeros((self.input_dim, self.output_dim))
initial_state = K.dot(initial_state, reducer) # (samples, output_dim)
initial_states = [initial_state for _ in range(len(self.states))]
last_output, outputs, states = K.rnn(self.step, X, initial_states,
go_backwards=self.go_backwards,
masking=masking)
if self.stateful:
for i in range(len(states)):
K.set_value(self.states[i], states[i])
if self.return_sequences:
return outputs
else:
return last_output
def get_config(self):
config = {"name": self.__class__.__name__,
"return_sequences": self.return_sequences,
"input_dim": self.input_dim,
"input_length": self.input_length,
"go_backwards": self.go_backwards,
"stateful": self.stateful}
base_config = super(Recurrent, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class SimpleRNN(Recurrent):
'''
def __init__(self, input_dim, output_dim,
init='glorot_uniform', inner_init='orthogonal', activation='sigmoid', weights=None,
truncate_gradient=-1, return_sequences=False):
super(SimpleRNN,self).__init__()
Fully-connected RNN where the output is to fed back to input.
Takes inputs with shape:
(nb_samples, max_sample_length, input_dim)
(samples shorter than `max_sample_length`
are padded with zeros at the end)
and returns outputs with shape:
if not return_sequences:
(nb_samples, output_dim)
if return_sequences:
(nb_samples, max_sample_length, output_dim)
'''
def __init__(self, output_dim,
init='glorot_uniform', inner_init='orthogonal',
activation='sigmoid', **kwargs):
self.output_dim = output_dim
self.init = initializations.get(init)
self.inner_init = initializations.get(inner_init)
self.input_dim = input_dim
self.output_dim = output_dim
self.truncate_gradient = truncate_gradient
self.activation = activations.get(activation)
self.return_sequences = return_sequences
self.input = T.tensor3()
super(SimpleRNN, self).__init__(**kwargs)
self.W = self.init((self.input_dim, self.output_dim))
def build(self):
input_shape = self.input_shape
if self.stateful:
if not input_shape[0]:
raise Exception('If a RNN is stateful, a complete ' +
'input_shape must be provided ' +
'(including batch size).')
self.states = [K.zeros(input_shape[0], self.output_dim)]
else:
# initial states: all-zero tensor of shape (output_dim)
self.states = [None]
input_dim = input_shape[2]
self.input_dim = input_dim
self.W = self.init((input_dim, self.output_dim))
self.U = self.inner_init((self.output_dim, self.output_dim))
self.b = shared_zeros((self.output_dim))
self.b = K.zeros((self.output_dim))
self.params = [self.W, self.U, self.b]
if weights is not None:
self.set_weights(weights)
if self.initial_weights is not None:
self.set_weights(self.initial_weights)
del self.initial_weights
def _step(self, x_t, h_tm1, u):
'''
Variable names follow the conventions from:
http://deeplearning.net/software/theano/library/scan.html
'''
return self.activation(x_t + T.dot(h_tm1, u))
def get_output(self, train):
X = self.get_input(train) # shape: (nb_samples, time (padded with zeros at the end), input_dim)
# new shape: (time, nb_samples, input_dim) -> because theano.scan iterates over main dimension
X = X.dimshuffle((1,0,2))
x = T.dot(X, self.W) + self.b
# scan = theano symbolic loop.
# See: http://deeplearning.net/software/theano/library/scan.html
# Iterate over the first dimension of the x array (=time).
outputs, updates = theano.scan(
self._step, # this will be called with arguments (sequences[i], outputs[i-1], non_sequences[i])
sequences=x, # tensors to iterate over, inputs to _step
# initialization of the output. Input to _step with default tap=-1.
outputs_info=T.unbroadcast(alloc_zeros_matrix(X.shape[1], self.output_dim), 1),
non_sequences=self.U, # static inputs to _step
truncate_gradient=self.truncate_gradient
)
if self.return_sequences:
return outputs.dimshuffle((1,0,2))
return outputs[-1]
def step(self, x, states):
# states only contains the previous output.
assert len(states) == 1
prev_output = states[0]
h = K.dot(x, self.W) + self.b
output = self.activation(h * K.dot(prev_output, self.U))
return output, [output]
def get_config(self):
return {"name":self.__class__.__name__,
"input_dim":self.input_dim,
"output_dim":self.output_dim,
"init":self.init.__name__,
"inner_init":self.inner_init.__name__,
"activation":self.activation.__name__,
"truncate_gradient":self.truncate_gradient,
"return_sequences":self.return_sequences}
config = {"output_dim": self.output_dim,
"init": self.init.__name__,
"inner_init": self.inner_init.__name__,
"activation": self.activation.__name__}
base_config = super(SimpleRNN, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class SimpleDeepRNN(Layer):
'''
Fully connected RNN where the output of multiple timesteps
(up to "depth" steps in the past) is fed back to the input:
output = activation( W.x_t + b + inner_activation(U_1.h_tm1) + inner_activation(U_2.h_tm2) + ... )
This demonstrates how to build RNNs with arbitrary lookback.
Also (probably) not a super useful model.
'''
def __init__(self, input_dim, output_dim, depth=3,
init='glorot_uniform', inner_init='orthogonal',
activation='sigmoid', inner_activation='hard_sigmoid',
weights=None, truncate_gradient=-1, return_sequences=False):
super(SimpleDeepRNN,self).__init__()
self.init = initializations.get(init)
self.inner_init = initializations.get(inner_init)
self.input_dim = input_dim
self.output_dim = output_dim
self.truncate_gradient = truncate_gradient
self.activation = activations.get(activation)
self.inner_activation = activations.get(inner_activation)
self.depth = depth
self.return_sequences = return_sequences
self.input = T.tensor3()
self.W = self.init((self.input_dim, self.output_dim))
self.Us = [self.inner_init((self.output_dim, self.output_dim)) for _ in range(self.depth)]
self.b = shared_zeros((self.output_dim))
self.params = [self.W] + self.Us + [self.b]
if weights is not None:
self.set_weights(weights)
def _step(self, *args):
o = args[0]
for i in range(1, self.depth+1):
o += self.inner_activation(T.dot(args[i], args[i+self.depth]))
return self.activation(o)
def get_output(self, train):
X = self.get_input(train)
X = X.dimshuffle((1,0,2))
x = T.dot(X, self.W) + self.b
outputs, updates = theano.scan(
self._step,
sequences=x,
outputs_info=[dict(
initial=T.alloc(np.cast[theano.config.floatX](0.), self.depth, X.shape[1], self.output_dim),
taps = [(-i-1) for i in range(self.depth)]
)],
non_sequences=self.Us,
truncate_gradient=self.truncate_gradient
)
if self.return_sequences:
return outputs.dimshuffle((1,0,2))
return outputs[-1]
def get_config(self):
return {"name":self.__class__.__name__,
"input_dim":self.input_dim,
"output_dim":self.output_dim,
"depth":self.depth,
"init":self.init.__name__,
"inner_init":self.inner_init.__name__,
"activation":self.activation.__name__,
"inner_activation":self.inner_activation.__name__,
"truncate_gradient":self.truncate_gradient,
"return_sequences":self.return_sequences}
class GRU(Layer):
class GRU(Recurrent):
'''
Gated Recurrent Unit - Cho et al. 2014
Acts as a spatiotemporal projection,
turning a sequence of vectors into a single vector.
Eats inputs with shape:
(nb_samples, max_sample_length (samples shorter than this are padded with zeros at the end), input_dim)
Takes inputs with shape:
(nb_samples, max_sample_length, input_dim)
(samples shorter than `max_sample_length`
are padded with zeros at the end)
and returns outputs with shape:
if not return_sequences:
(nb_samples, output_dim)
if return_sequences:
(nb_samples, max_sample_length, output_dim)
References:
On the Properties of Neural Machine Translation: Encoder–Decoder Approaches
On the Properties of Neural Machine Translation:
Encoder–Decoder Approaches
http://www.aclweb.org/anthology/W14-4012
Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling
Empirical Evaluation of Gated Recurrent Neural Networks
on Sequence Modeling
http://arxiv.org/pdf/1412.3555v1.pdf
'''
def __init__(self, input_dim, output_dim=128,
init='glorot_uniform', inner_init='orthogonal',
activation='sigmoid', inner_activation='hard_sigmoid',
weights=None, truncate_gradient=-1, return_sequences=False):
super(GRU,self).__init__()
self.input_dim = input_dim
def __init__(self, output_dim,
init='glorot_uniform', inner_init='orthogonal',
activation='sigmoid', inner_activation='hard_sigmoid',
**kwargs):
self.output_dim = output_dim
self.truncate_gradient = truncate_gradient
self.return_sequences = return_sequences
self.init = initializations.get(init)
self.inner_init = initializations.get(inner_init)
self.activation = activations.get(activation)
self.inner_activation = activations.get(inner_activation)
self.input = T.tensor3()
super(GRU, self).__init__(**kwargs)
self.W_z = self.init((self.input_dim, self.output_dim))
def build(self):
input_shape = self.input_shape
input_dim = input_shape[2]
self.input_dim = input_dim
self.input = K.placeholder(input_shape)
self.W_z = self.init((input_dim, self.output_dim))
self.U_z = self.inner_init((self.output_dim, self.output_dim))
self.b_z = shared_zeros((self.output_dim))
self.b_z = K.zeros((self.output_dim,))
self.W_r = self.init((self.input_dim, self.output_dim))
self.W_r = self.init((input_dim, self.output_dim))
self.U_r = self.inner_init((self.output_dim, self.output_dim))
self.b_r = shared_zeros((self.output_dim))
self.b_r = K.zeros((self.output_dim,))
self.W_h = self.init((self.input_dim, self.output_dim))
self.W_h = self.init((input_dim, self.output_dim))
self.U_h = self.inner_init((self.output_dim, self.output_dim))
self.b_h = shared_zeros((self.output_dim))
self.b_h = K.zeros((self.output_dim,))
self.params = [
self.W_z, self.U_z, self.b_z,
self.W_r, self.U_r, self.b_r,
self.W_h, self.U_h, self.b_h,
]
self.params = [self.W_z, self.U_z, self.b_z,
self.W_r, self.U_r, self.b_r,
self.W_h, self.U_h, self.b_h]
if weights is not None:
self.set_weights(weights)
if self.stateful:
if not input_shape[0]:
raise Exception('If a RNN is stateful, a complete ' +
'input_shape must be provided ' +
'(including batch size).')
self.states = [K.zeros(input_shape[0], self.output_dim)]
else:
# initial states: all-zero tensor of shape (output_dim)
self.states = [None]
def _step(self,
xz_t, xr_t, xh_t,
h_tm1,
u_z, u_r, u_h):
z = self.inner_activation(xz_t + T.dot(h_tm1, u_z))
r = self.inner_activation(xr_t + T.dot(h_tm1, u_r))
hh_t = self.activation(xh_t + T.dot(r * h_tm1, u_h))
h_t = z * h_tm1 + (1 - z) * hh_t
return h_t
if self.initial_weights is not None:
self.set_weights(self.initial_weights)
del self.initial_weights
def get_output(self, train):
X = self.get_input(train)
X = X.dimshuffle((1,0,2))
def step(self, x, states):
assert len(states) == 1
x_z = K.dot(x, self.W_z) + self.b_z
x_r = K.dot(x, self.W_r) + self.b_r
x_h = K.dot(x, self.W_h) + self.b_h
x_z = T.dot(X, self.W_z) + self.b_z
x_r = T.dot(X, self.W_r) + self.b_r
x_h = T.dot(X, self.W_h) + self.b_h
outputs, updates = theano.scan(
self._step,
sequences=[x_z, x_r, x_h],
outputs_info=T.unbroadcast(alloc_zeros_matrix(X.shape[1], self.output_dim), 1),
non_sequences=[self.U_z, self.U_r, self.U_h],
truncate_gradient=self.truncate_gradient
)
if self.return_sequences:
return outputs.dimshuffle((1,0,2))
return outputs[-1]
h_tm1 = states[0]
z = self.inner_activation(x_z + K.dot(h_tm1, self.U_z))
r = self.inner_activation(x_r + K.dot(h_tm1, self.U_r))
hh = self.inner_activation(x_h + K.dot(r * h_tm1, self.U_h))
h = z * h_tm1 + (1 - z) * hh
return h, [h]
def get_config(self):
return {"name":self.__class__.__name__,
"input_dim":self.input_dim,
"output_dim":self.output_dim,
"init":self.init.__name__,
"inner_init":self.inner_init.__name__,
"activation":self.activation.__name__,
"inner_activation":self.inner_activation.__name__,
"truncate_gradient":self.truncate_gradient,
"return_sequences":self.return_sequences}
config = {"output_dim": self.output_dim,
"init": self.init.__name__,
"inner_init": self.inner_init.__name__,
"activation": self.activation.__name__,
"inner_activation": self.inner_activation.__name__}
base_config = super(GRU, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
class LSTM(Layer):
class LSTM(Recurrent):
'''
Acts as a spatiotemporal projection,
turning a sequence of vectors into a single vector.
Eats inputs with shape:
(nb_samples, max_sample_length (samples shorter than this are padded with zeros at the end), input_dim)
Takes inputs with shape:
(nb_samples, max_sample_length, input_dim)
(samples shorter than `max_sample_length`
are padded with zeros at the end)
and returns outputs with shape:
if not return_sequences:
(nb_samples, output_dim)
if return_sequences:
(nb_samples, max_sample_length, output_dim)
For a step-by-step description of the algorithm, see:
http://deeplearning.net/tutorial/lstm.html
References:
Long short-term memory (original 97 paper)
http://deeplearning.cs.cmu.edu/pdfs/Hochreiter97_lstm.pdf
@@ -279,92 +272,83 @@ class LSTM(Layer):
Supervised sequence labelling with recurrent neural networks
http://www.cs.toronto.edu/~graves/preprint.pdf
'''
def __init__(self, input_dim, output_dim=128,
init='glorot_uniform', inner_init='orthogonal',
activation='tanh', inner_activation='hard_sigmoid',
weights=None, truncate_gradient=-1, return_sequences=False):
super(LSTM,self).__init__()
self.input_dim = input_dim
def __init__(self, output_dim,
init='glorot_uniform', inner_init='orthogonal',
forget_bias_init='one', activation='tanh',
inner_activation='hard_sigmoid', **kwargs):
self.output_dim = output_dim
self.truncate_gradient = truncate_gradient
self.return_sequences = return_sequences
self.init = initializations.get(init)
self.inner_init = initializations.get(inner_init)
self.forget_bias_init = initializations.get(forget_bias_init)
self.activation = activations.get(activation)
self.inner_activation = activations.get(inner_activation)
self.input = T.tensor3()
super(LSTM, self).__init__(**kwargs)
self.W_i = self.init((self.input_dim, self.output_dim))
def build(self):
input_shape = self.input_shape
input_dim = input_shape[2]
self.input_dim = input_dim
self.input = K.placeholder(input_shape)
if self.stateful:
if not input_shape[0]:
raise Exception('If a RNN is stateful, a complete ' +
'input_shape must be provided ' +
'(including batch size).')
self.states = [K.zeros(input_shape[0], self.output_dim),
K.zeros(input_shape[0], self.output_dim)]
else:
# initial states: 2 all-zero tensor of shape (output_dim)
self.states = [None, None]
self.W_i = self.init((input_dim, self.output_dim))
self.U_i = self.inner_init((self.output_dim, self.output_dim))
self.b_i = shared_zeros((self.output_dim))
self.b_i = K.zeros((self.output_dim))
self.W_f = self.init((self.input_dim, self.output_dim))
self.W_f = self.init((input_dim, self.output_dim))
self.U_f = self.inner_init((self.output_dim, self.output_dim))
self.b_f = shared_zeros((self.output_dim))
self.b_f = self.forget_bias_init((self.output_dim))
self.W_c = self.init((self.input_dim, self.output_dim))
self.W_c = self.init((input_dim, self.output_dim))
self.U_c = self.inner_init((self.output_dim, self.output_dim))
self.b_c = shared_zeros((self.output_dim))
self.b_c = K.zeros((self.output_dim))
self.W_o = self.init((self.input_dim, self.output_dim))
self.W_o = self.init((input_dim, self.output_dim))
self.U_o = self.inner_init((self.output_dim, self.output_dim))
self.b_o = shared_zeros((self.output_dim))
self.b_o = K.zeros((self.output_dim))
self.params = [
self.W_i, self.U_i, self.b_i,
self.W_c, self.U_c, self.b_c,
self.W_f, self.U_f, self.b_f,
self.W_o, self.U_o, self.b_o,
]
self.params = [self.W_i, self.U_i, self.b_i,
self.W_c, self.U_c, self.b_c,
self.W_f, self.U_f, self.b_f,
self.W_o, self.U_o, self.b_o]
if weights is not None:
self.set_weights(weights)
if self.initial_weights is not None:
self.set_weights(self.initial_weights)
del self.initial_weights
def _step(self,
xi_t, xf_t, xo_t, xc_t,
h_tm1, c_tm1,
u_i, u_f, u_o, u_c):
i_t = self.inner_activation(xi_t + T.dot(h_tm1, u_i))
f_t = self.inner_activation(xf_t + T.dot(h_tm1, u_f))
c_t = f_t * c_tm1 + i_t * self.activation(xc_t + T.dot(h_tm1, u_c))
o_t = self.inner_activation(xo_t + T.dot(h_tm1, u_o))
h_t = o_t * self.activation(c_t)
return h_t, c_t
def step(self, x, states):
assert len(states) == 2
h_tm1 = states[0]
c_tm1 = states[1]
def get_output(self, train):
X = self.get_input(train)
X = X.dimshuffle((1,0,2))
x_i = K.dot(x, self.W_i) + self.b_i
x_f = K.dot(x, self.W_f) + self.b_f
x_c = K.dot(x, self.W_c) + self.b_c
x_o = K.dot(x, self.W_o) + self.b_o
xi = T.dot(X, self.W_i) + self.b_i
xf = T.dot(X, self.W_f) + self.b_f
xc = T.dot(X, self.W_c) + self.b_c
xo = T.dot(X, self.W_o) + self.b_o
[outputs, memories], updates = theano.scan(
self._step,
sequences=[xi, xf, xo, xc],
outputs_info=[
T.unbroadcast(alloc_zeros_matrix(X.shape[1], self.output_dim), 1),
T.unbroadcast(alloc_zeros_matrix(X.shape[1], self.output_dim), 1)
],
non_sequences=[self.U_i, self.U_f, self.U_o, self.U_c],
truncate_gradient=self.truncate_gradient
)
if self.return_sequences:
return outputs.dimshuffle((1,0,2))
return outputs[-1]
i = self.inner_activation(x_i + K.dot(h_tm1, self.U_i))
f = self.inner_activation(x_f + K.dot(h_tm1, self.U_f))
c = f * c_tm1 + i * self.activation(x_c + K.dot(h_tm1, self.U_c))
o = self.inner_activation(x_o + K.dot(h_tm1, self.U_o))
h = o * self.activation(c)
return h, [h, c]
def get_config(self):
return {"name":self.__class__.__name__,
"input_dim":self.input_dim,
"output_dim":self.output_dim,
"init":self.init.__name__,
"inner_init":self.inner_init.__name__,
"activation":self.activation.__name__,
"inner_activation":self.inner_activation.__name__,
"truncate_gradient":self.truncate_gradient,
"return_sequences":self.return_sequences}
config = {"output_dim": self.output_dim,
"init": self.init.__name__,
"inner_init": self.inner_init.__name__,
"forget_bias_init": self.forget_bias_init.__name__,
"activation": self.activation.__name__,
"inner_activation": self.inner_activation.__name__}
base_config = super(LSTM, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
+600 -213
Ver Arquivo
@@ -1,27 +1,48 @@
from __future__ import absolute_import
from __future__ import print_function
import theano
import theano.tensor as T
import numpy as np
import warnings, time, copy
import warnings
import time
import copy
import pprint
from six.moves import range
import six
from . import backend as K
from . import optimizers
from . import objectives
from . import regularizers
from . import constraints
from . import callbacks as cbks
from .utils.layer_utils import container_from_config
from .utils.generic_utils import Progbar, printv
from .layers import containers
from six.moves import range
def standardize_y(y):
if not hasattr(y, 'shape'):
y = np.asarray(y)
if len(y.shape) == 1:
y = np.reshape(y, (len(y), 1))
y = np.expand_dims(y, 1)
return y
def batch_shuffle(index_array, batch_size):
batch_count = int(len(index_array) / batch_size)
# to reshape we need to be cleanly divisible by batch size
# we stash extra items and reappend them after shuffling
last_batch = index_array[batch_count * batch_size:]
index_array = index_array[:batch_count * batch_size]
index_array = index_array.reshape((batch_count, batch_size))
np.random.shuffle(index_array)
index_array = index_array.flatten()
return np.append(index_array, last_batch)
def make_batches(size, batch_size):
nb_batch = int(np.ceil(size/float(batch_size)))
return [(i*batch_size, min(size, (i+1)*batch_size)) for i in range(0, nb_batch)]
nb_batch = int(np.ceil(size / float(batch_size)))
return [(i * batch_size, min(size, (i + 1) * batch_size)) for i in range(0, nb_batch)]
def standardize_X(X):
if type(X) == list:
@@ -29,26 +50,322 @@ def standardize_X(X):
else:
return [X]
def slice_X(X, start=None, stop=None):
if type(X) == list:
if hasattr(start, '__len__'):
# hdf5 dataset only support list object as indices
if hasattr(start, 'shape'):
start = start.tolist()
return [x[start] for x in X]
else:
return [x[start:stop] for x in X]
else:
if hasattr(start, '__len__'):
if hasattr(start, 'shape'):
start = start.tolist()
return X[start]
else:
return X[start:stop]
def weighted_objective(fn):
def weighted(y_true, y_pred, weights, mask=None):
'''To be called only with non-zero weights.
mask: binary
'''
score_array = fn(y_true, y_pred)
if mask is not None:
score_array *= mask
# the loss per batch should be proportional
# to the number of unmasked sampled.
score_array /= K.mean(mask)
# reduce score_array to 1D
ndim = K.ndim(score_array)
for d in range(ndim-1):
score_array = K.mean(score_array, axis=-1)
if weights is not None:
score_array *= weights
return K.mean(score_array)
return weighted
def standardize_weights(y, sample_weight=None, class_weight=None):
if sample_weight is not None:
assert len(sample_weight) == len(y)
return sample_weight.flatten()
elif isinstance(class_weight, dict):
if len(y.shape) > 2:
raise Exception('class_weight not supported for 3+ dimensional targets.')
if y.shape[1] > 1:
y_classes = y.argmax(axis=1)
elif y.shape[1] == 1:
y_classes = np.reshape(y, y.shape[0])
else:
y_classes = y
weights = np.asarray([class_weight[cls] for cls in y_classes])
return weights
else:
return np.ones((y.shape[0],))
def model_from_yaml(yaml_string, custom_objects={}):
'''
Returns a model generated from a local yaml file,
which is either created by hand or from to_yaml method
of Sequential or Graph
'''
import yaml
config = yaml.load(yaml_string)
return model_from_config(config, custom_objects=custom_objects)
def model_from_json(json_string, custom_objects={}):
import json
config = json.loads(json_string)
return model_from_config(config, custom_objects=custom_objects)
def model_from_config(config, custom_objects={}):
model_name = config.get('name')
if model_name not in {'Graph', 'Sequential'}:
raise Exception('Unrecognized model:', model_name)
# Create a container then set class to appropriate model
model = container_from_config(config, custom_objects=custom_objects)
if model_name == 'Graph':
model.__class__ = Graph
elif model_name == 'Sequential':
model.__class__ = Sequential
if 'optimizer' in config:
# if it has an optimizer, the model is assumed to be compiled
loss = config.get('loss')
class_mode = config.get('class_mode')
theano_mode = config.get('theano_mode')
optimizer_params = dict([(k, v) for k, v in config.get('optimizer').items()])
optimizer_name = optimizer_params.pop('name')
optimizer = optimizers.get(optimizer_name, optimizer_params)
if model_name == 'Sequential':
model.compile(loss=loss, optimizer=optimizer,
class_mode=class_mode, theano_mode=theano_mode)
elif model_name == 'Graph':
model.compile(loss=loss, optimizer=optimizer,
theano_mode=theano_mode)
return model
def get_function_name(o):
if isinstance(o, six.string_types):
return o
else:
return o.__name__
class Model(object):
def _fit(self, f, ins, out_labels=[], batch_size=128,
nb_epoch=100, verbose=1, callbacks=[],
val_f=None, val_ins=None, shuffle=True, metrics=[]):
'''
Abstract fit function for f(ins).
Assume that f returns a list, labelled by out_labels.
'''
do_validation = False
if val_f and val_ins:
do_validation = True
if verbose:
print("Train on %d samples, validate on %d samples" % (len(ins[0]), len(val_ins[0])))
def compile(self, optimizer, loss, class_mode="categorical", theano_mode=None):
nb_train_sample = len(ins[0])
index_array = np.arange(nb_train_sample)
history = cbks.History()
if verbose:
callbacks = [history, cbks.BaseLogger()] + callbacks
else:
callbacks = [history] + callbacks
callbacks = cbks.CallbackList(callbacks)
callbacks._set_model(self)
callbacks._set_params({
'batch_size': batch_size,
'nb_epoch': nb_epoch,
'nb_sample': nb_train_sample,
'verbose': verbose,
'do_validation': do_validation,
'metrics': metrics,
})
callbacks.on_train_begin()
self.stop_training = False
for epoch in range(nb_epoch):
callbacks.on_epoch_begin(epoch)
if shuffle == 'batch':
index_array = batch_shuffle(index_array, batch_size)
elif shuffle:
np.random.shuffle(index_array)
batches = make_batches(nb_train_sample, batch_size)
for batch_index, (batch_start, batch_end) in enumerate(batches):
batch_ids = index_array[batch_start:batch_end]
try:
ins_batch = slice_X(ins, batch_ids)
except TypeError:
raise Exception('TypeError while preparing batch. \
If using HDF5 input data, pass shuffle="batch".\n')
batch_logs = {}
batch_logs['batch'] = batch_index
batch_logs['size'] = len(batch_ids)
callbacks.on_batch_begin(batch_index, batch_logs)
outs = f(ins_batch)
if type(outs) != list:
outs = [outs]
for l, o in zip(out_labels, outs):
batch_logs[l] = o
callbacks.on_batch_end(batch_index, batch_logs)
epoch_logs = {}
if batch_index == len(batches) - 1: # last batch
# validation
if do_validation:
# replace with self._evaluate
val_outs = self._test_loop(val_f, val_ins,
batch_size=batch_size,
verbose=0)
if type(val_outs) != list:
val_outs = [val_outs]
# same labels assumed
for l, o in zip(out_labels, val_outs):
epoch_logs['val_' + l] = o
callbacks.on_epoch_end(epoch, epoch_logs)
if self.stop_training:
break
callbacks.on_train_end()
return history
def _predict_loop(self, f, ins, batch_size=128, verbose=0):
'''
Abstract method to loop over some data in batches.
'''
nb_sample = len(ins[0])
outs = []
if verbose == 1:
progbar = Progbar(target=nb_sample)
batches = make_batches(nb_sample, batch_size)
index_array = np.arange(nb_sample)
for batch_index, (batch_start, batch_end) in enumerate(batches):
batch_ids = index_array[batch_start:batch_end]
ins_batch = slice_X(ins, batch_ids)
batch_outs = f(ins_batch)
if type(batch_outs) != list:
batch_outs = [batch_outs]
if batch_index == 0:
for batch_out in batch_outs:
shape = (nb_sample,) + batch_out.shape[1:]
outs.append(np.zeros(shape))
for i, batch_out in enumerate(batch_outs):
outs[i][batch_start:batch_end] = batch_out
if verbose == 1:
progbar.update(batch_end)
return outs
def _test_loop(self, f, ins, batch_size=128, verbose=0):
'''
Abstract method to loop over some data in batches.
'''
nb_sample = len(ins[0])
outs = []
if verbose == 1:
progbar = Progbar(target=nb_sample)
batches = make_batches(nb_sample, batch_size)
index_array = np.arange(nb_sample)
for batch_index, (batch_start, batch_end) in enumerate(batches):
batch_ids = index_array[batch_start:batch_end]
ins_batch = slice_X(ins, batch_ids)
batch_outs = f(ins_batch)
if type(batch_outs) == list:
if batch_index == 0:
for batch_out in enumerate(batch_outs):
outs.append(0.)
for i, batch_out in enumerate(batch_outs):
outs[i] += batch_out * len(batch_ids)
else:
if batch_index == 0:
outs.append(0.)
outs[0] += batch_outs * len(batch_ids)
if verbose == 1:
progbar.update(batch_end)
for i, out in enumerate(outs):
outs[i] /= nb_sample
return outs
def get_config(self, verbose=0):
config = super(Model, self).get_config()
for p in ['class_mode', 'theano_mode']:
if hasattr(self, p):
config[p] = getattr(self, p)
if hasattr(self, 'optimizer'):
config['optimizer'] = self.optimizer.get_config()
if hasattr(self, 'loss'):
if type(self.loss) == dict:
config['loss'] = dict([(k, get_function_name(v)) for k, v in self.loss.items()])
else:
config['loss'] = get_function_name(self.loss)
if verbose:
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(config)
return config
def to_yaml(self, **kwargs):
# dump model configuration to yaml string
import yaml
config = self.get_config()
return yaml.dump(config, **kwargs)
def to_json(self, **kwargs):
# dump model configuration to json string
import json
config = self.get_config()
return json.dumps(config, **kwargs)
class Sequential(Model, containers.Sequential):
'''
Inherits from Model the following methods:
- _fit
- _predict
- _evaluate
Inherits from containers.Sequential the following methods:
- __init__
- add
- get_output
- get_input
- get_weights
- set_weights
'''
def compile(self, optimizer, loss,
class_mode="categorical", theano_mode=None):
self.optimizer = optimizers.get(optimizer)
self.loss = objectives.get(loss)
# input of model
self.loss = objectives.get(loss)
weighted_loss = weighted_objective(objectives.get(loss))
# input of model
self.X_train = self.get_input(train=True)
self.X_test = self.get_input(train=False)
@@ -56,175 +373,142 @@ class Model(object):
self.y_test = self.get_output(train=False)
# target of model
self.y = T.zeros_like(self.y_train)
self.y = K.placeholder(ndim=K.ndim(self.y_train))
# weights: one scalar per sample
self.weights = K.placeholder(ndim=1)
train_loss = self.loss(self.y, self.y_train)
test_score = self.loss(self.y, self.y_test)
if hasattr(self.layers[-1], "get_output_mask"):
mask = self.layers[-1].get_output_mask()
else:
mask = None
train_loss = weighted_loss(self.y, self.y_train, self.weights, mask)
test_loss = weighted_loss(self.y, self.y_test, self.weights, mask)
if class_mode == "categorical":
train_accuracy = T.mean(T.eq(T.argmax(self.y, axis=-1), T.argmax(self.y_train, axis=-1)))
test_accuracy = T.mean(T.eq(T.argmax(self.y, axis=-1), T.argmax(self.y_test, axis=-1)))
train_accuracy = K.mean(K.equal(K.argmax(self.y, axis=-1),
K.argmax(self.y_train, axis=-1)))
test_accuracy = K.mean(K.equal(K.argmax(self.y, axis=-1),
K.argmax(self.y_test, axis=-1)))
elif class_mode == "binary":
train_accuracy = T.mean(T.eq(self.y, T.round(self.y_train)))
test_accuracy = T.mean(T.eq(self.y, T.round(self.y_test)))
train_accuracy = K.mean(K.equal(self.y, K.round(self.y_train)))
test_accuracy = K.mean(K.equal(self.y, K.round(self.y_test)))
else:
raise Exception("Invalid class mode:" + str(class_mode))
self.class_mode = class_mode
self.theano_mode = theano_mode
updates = self.optimizer.get_updates(self.params, self.regularizers, self.constraints, train_loss)
for r in self.regularizers:
train_loss = r(train_loss)
updates = self.optimizer.get_updates(self.params,
self.constraints,
train_loss)
updates += self.updates
if type(self.X_train) == list:
train_ins = self.X_train + [self.y]
test_ins = self.X_test + [self.y]
train_ins = self.X_train + [self.y, self.weights]
test_ins = self.X_test + [self.y, self.weights]
assert type(self.X_test) == list
predict_ins = self.X_test
else:
train_ins = [self.X_train, self.y]
test_ins = [self.X_test, self.y]
train_ins = [self.X_train, self.y, self.weights]
test_ins = [self.X_test, self.y, self.weights]
predict_ins = [self.X_test]
self._train = theano.function(train_ins, train_loss,
updates=updates, allow_input_downcast=True, mode=theano_mode)
self._train_with_acc = theano.function(train_ins, [train_loss, train_accuracy],
updates=updates, allow_input_downcast=True, mode=theano_mode)
self._predict = theano.function(predict_ins, self.y_test,
allow_input_downcast=True, mode=theano_mode)
self._test = theano.function(test_ins, test_score,
allow_input_downcast=True, mode=theano_mode)
self._test_with_acc = theano.function(test_ins, [test_score, test_accuracy],
allow_input_downcast=True, mode=theano_mode)
self._train = K.function(train_ins, [train_loss], updates=updates)
self._train_with_acc = K.function(train_ins, [train_loss, train_accuracy], updates=updates)
self._predict = K.function(predict_ins, [self.y_test])
self._test = K.function(test_ins, [test_loss])
self._test_with_acc = K.function(test_ins, [test_loss, test_accuracy])
def train(self, X, y, accuracy=False):
def train_on_batch(self, X, y, accuracy=False,
class_weight=None, sample_weight=None):
X = standardize_X(X)
y = standardize_y(y)
ins = X + [y]
sample_weight = standardize_weights(y, class_weight=class_weight,
sample_weight=sample_weight)
ins = X + [y, sample_weight]
if accuracy:
return self._train_with_acc(*ins)
return self._train_with_acc(ins)
else:
return self._train(*ins)
return self._train(ins)
def test(self, X, y, accuracy=False):
def test_on_batch(self, X, y, accuracy=False, sample_weight=None):
X = standardize_X(X)
y = standardize_y(y)
ins = X + [y]
if accuracy:
return self._test_with_acc(*ins)
else:
return self._test(*ins)
sample_weight = standardize_weights(y, sample_weight=sample_weight)
ins = X + [y, sample_weight]
if accuracy:
return self._test_with_acc(ins)
else:
return self._test(ins)
def predict_on_batch(self, X):
ins = standardize_X(X)
return self._predict(ins)
def fit(self, X, y, batch_size=128, nb_epoch=100, verbose=1, callbacks=[],
validation_split=0., validation_data=None, shuffle=True, show_accuracy=False):
validation_split=0., validation_data=None, shuffle=True,
show_accuracy=False, class_weight=None, sample_weight=None):
X = standardize_X(X)
y = standardize_y(y)
do_validation = False
val_f = None
val_ins = None
if validation_data or validation_split:
if show_accuracy:
val_f = self._test_with_acc
else:
val_f = self._test
if validation_data:
try:
if len(validation_data) == 2:
X_val, y_val = validation_data
except:
raise Exception("Invalid format for validation data; provide a tuple (X_val, y_val). \
X_val = standardize_X(X_val)
y_val = standardize_y(y_val)
sample_weight_val = standardize_weights(y_val)
elif len(validation_data) == 3:
X_val, y_val, sample_weight_val = validation_data
X_val = standardize_X(X_val)
y_val = standardize_y(y_val)
sample_weight_val = standardize_weights(y_val,
sample_weight=sample_weight_val)
else:
raise Exception("Invalid format for validation data; provide a tuple (X_val, y_val) or (X_val, y_val, sample_weight). \
X_val may be a numpy array or a list of numpy arrays depending on your model input.")
do_validation = True
X_val = standardize_X(X_val)
y_val = standardize_y(y_val)
if verbose:
print("Train on %d samples, validate on %d samples" % (len(y), len(y_val)))
val_ins = X_val + [y_val, sample_weight_val]
elif 0 < validation_split < 1:
split_at = int(len(X[0]) * (1 - validation_split))
X, X_val = (slice_X(X, 0, split_at), slice_X(X, split_at))
y, y_val = (slice_X(y, 0, split_at), slice_X(y, split_at))
if sample_weight is not None:
sample_weight, sample_weight_val = (slice_X(sample_weight, 0, split_at), slice_X(sample_weight, split_at))
sample_weight_val = standardize_weights(y_val, sample_weight=sample_weight_val)
else:
sample_weight_val = standardize_weights(y_val)
val_ins = X_val + [y_val, sample_weight_val]
if show_accuracy:
f = self._train_with_acc
out_labels = ['loss', 'acc']
else:
if 0 < validation_split < 1:
# If a validation split size is given (e.g. validation_split=0.2)
# then split X into smaller X and X_val,
# and split y into smaller y and y_val.
do_validation = True
split_at = int(len(y) * (1 - validation_split))
(X, X_val) = (slice_X(X, 0, split_at), slice_X(X, split_at))
(y, y_val) = (y[0:split_at], y[split_at:])
if verbose:
print("Train on %d samples, validate on %d samples" % (len(y), len(y_val)))
f = self._train
out_labels = ['loss']
index_array = np.arange(len(y))
sample_weight = standardize_weights(y, class_weight=class_weight, sample_weight=sample_weight)
ins = X + [y, sample_weight]
metrics = ['loss', 'acc', 'val_loss', 'val_acc']
return self._fit(f, ins, out_labels=out_labels,
batch_size=batch_size, nb_epoch=nb_epoch,
verbose=verbose, callbacks=callbacks,
val_f=val_f, val_ins=val_ins,
shuffle=shuffle, metrics=metrics)
callbacks = cbks.CallbackList(callbacks)
if verbose:
callbacks.append(cbks.BaseLogger())
callbacks.append(cbks.History())
callbacks._set_model(self)
callbacks._set_params({
'batch_size': batch_size,
'nb_epoch': nb_epoch,
'nb_sample': len(y),
'verbose': verbose,
'do_validation': do_validation,
'show_accuracy': show_accuracy
})
callbacks.on_train_begin()
for epoch in range(nb_epoch):
callbacks.on_epoch_begin(epoch)
if shuffle:
np.random.shuffle(index_array)
batches = make_batches(len(y), batch_size)
for batch_index, (batch_start, batch_end) in enumerate(batches):
batch_ids = index_array[batch_start:batch_end]
X_batch = slice_X(X, batch_ids)
y_batch = y[batch_ids]
batch_logs = {}
batch_logs['batch'] = batch_index
batch_logs['size'] = len(batch_ids)
callbacks.on_batch_begin(batch_index, batch_logs)
ins = X_batch + [y_batch]
if show_accuracy:
loss, acc = self._train_with_acc(*ins)
batch_logs['accuracy'] = acc
else:
loss = self._train(*ins)
batch_logs['loss'] = loss
callbacks.on_batch_end(batch_index, batch_logs)
if batch_index == len(batches) - 1: # last batch
# validation
epoch_logs = {}
if do_validation:
if show_accuracy:
val_loss, val_acc = self.evaluate(X_val, y_val, batch_size=batch_size, \
verbose=0, show_accuracy=True)
epoch_logs['val_accuracy'] = val_acc
else:
val_loss = self.evaluate(X_val, y_val, batch_size=batch_size, verbose=0)
epoch_logs['val_loss'] = val_loss
callbacks.on_epoch_end(epoch, epoch_logs)
callbacks.on_train_end()
# return history
return callbacks.callbacks[-1]
def predict(self, X, batch_size=128, verbose=1):
def predict(self, X, batch_size=128, verbose=0):
X = standardize_X(X)
batches = make_batches(len(X[0]), batch_size)
if verbose == 1:
progbar = Progbar(target=len(X[0]))
for batch_index, (batch_start, batch_end) in enumerate(batches):
X_batch = slice_X(X, batch_start, batch_end)
batch_preds = self._predict(*X_batch)
if batch_index == 0:
shape = (len(X[0]),) + batch_preds.shape[1:]
preds = np.zeros(shape)
preds[batch_start:batch_end] = batch_preds
if verbose == 1:
progbar.update(batch_end)
return preds
return self._predict_loop(self._predict, X, batch_size, verbose)[0]
def predict_proba(self, X, batch_size=128, verbose=1):
preds = self.predict(X, batch_size, verbose)
@@ -232,7 +516,6 @@ class Model(object):
warnings.warn("Network returning invalid probability values.")
return preds
def predict_classes(self, X, batch_size=128, verbose=1):
proba = self.predict(X, batch_size=batch_size, verbose=verbose)
if self.class_mode == "categorical":
@@ -240,79 +523,22 @@ class Model(object):
else:
return (proba > 0.5).astype('int32')
def evaluate(self, X, y, batch_size=128, show_accuracy=False, verbose=1):
def evaluate(self, X, y, batch_size=128, show_accuracy=False,
verbose=1, sample_weight=None):
X = standardize_X(X)
y = standardize_y(y)
sample_weight = standardize_weights(y, sample_weight=sample_weight)
ins = X + [y, sample_weight]
if show_accuracy:
tot_acc = 0.
tot_score = 0.
seen = 0
batches = make_batches(len(y), batch_size)
if verbose:
progbar = Progbar(target=len(y), verbose=verbose)
for batch_index, (batch_start, batch_end) in enumerate(batches):
X_batch = slice_X(X, batch_start, batch_end)
y_batch = y[batch_start:batch_end]
ins = X_batch + [y_batch]
if show_accuracy:
loss, acc = self._test_with_acc(*ins)
tot_acc += acc * len(y_batch)
log_values = [('loss', loss), ('acc.', acc)]
else:
loss = self._test(*ins)
log_values = [('loss', loss)]
tot_score += loss * len(y_batch)
seen += len(y_batch)
# logging
if verbose:
progbar.update(batch_end, log_values)
if show_accuracy:
return tot_score / seen, tot_acc / seen
f = self._test_with_acc
else:
return tot_score / seen
class Sequential(Model, containers.Sequential):
'''
Inherits from Model the following methods:
- compile
- train
- test
- evaluate
- fit
- predict
- predict_proba
- predict_classes
Inherits from containers.Sequential the following methods:
- add
- get_output
- get_input
- get_weights
- set_weights
'''
def __init__(self):
self.layers = []
self.params = [] # learnable
self.regularizers = [] # same size as params
self.constraints = [] # same size as params
def get_config(self, verbose=0):
layers = []
for i, l in enumerate(self.layers):
config = l.get_config()
layers.append(config)
if verbose:
printv(layers)
return layers
f = self._test
outs = self._test_loop(f, ins, batch_size, verbose)
if show_accuracy:
return outs
else:
return outs[0]
def save_weights(self, filepath, overwrite=False):
# Save weights from all layers to HDF5
@@ -345,6 +571,10 @@ class Sequential(Model, containers.Sequential):
f.close()
def load_weights(self, filepath):
'''
This method does not make use of Sequential.set_weights()
for backwards compatibility.
'''
# Loads weights from HDF5 file
import h5py
f = h5py.File(filepath)
@@ -353,4 +583,161 @@ class Sequential(Model, containers.Sequential):
weights = [g['param_{}'.format(p)] for p in range(g.attrs['nb_params'])]
self.layers[k].set_weights(weights)
f.close()
class Graph(Model, containers.Graph):
def compile(self, optimizer, loss, theano_mode=None):
# loss is a dictionary mapping output name to loss functions
ys = []
ys_train = []
ys_test = []
weights = []
train_loss = 0.
test_loss = 0.
for output_name in self.output_order:
loss_fn = loss[output_name]
output = self.outputs[output_name]
y_train = output.get_output(True)
y_test = output.get_output(False)
y = K.placeholder(ndim=K.ndim(y_train))
ys.append(y)
ys_train.append(y_train)
ys_test.append(y_test)
if hasattr(output, "get_output_mask"):
mask = output.get_output_mask()
else:
mask = None
weight = K.placeholder(ndim=1)
weights.append(weight)
weighted_loss = weighted_objective(objectives.get(loss_fn))
train_loss += weighted_loss(y, y_train, weight, mask)
test_loss += weighted_loss(y, y_test, weight, mask)
ins = [self.inputs[name].input for name in self.input_order]
train_ins = ins + ys + weights
test_ins = ins + ys + weights
for r in self.regularizers:
train_loss = r(train_loss)
self.optimizer = optimizers.get(optimizer)
updates = self.optimizer.get_updates(self.params, self.constraints, train_loss)
updates += self.updates
self.theano_mode = theano_mode
self.loss = loss
self._train = K.function(train_ins, [train_loss], updates=updates)
self._test = K.function(test_ins, [test_loss])
self._predict = K.function(inputs=ins, outputs=ys_test)
def train_on_batch(self, data, class_weight={}, sample_weight={}):
# data is a dictionary mapping output and input names to arrays
sample_weight = [standardize_weights(data[name],
sample_weight=sample_weight.get(name),
class_weight=class_weight.get(name)) for name in self.output_order]
ins = [data[name] for name in self.input_order] + [standardize_y(data[name]) for name in self.output_order] + sample_weight
return self._train(ins)
def test_on_batch(self, data, sample_weight={}):
# data is a dictionary mapping input names to arrays
sample_weight = [standardize_weights(data[name],
sample_weight=sample_weight.get(name)) for name in self.output_order]
ins = [data[name] for name in self.input_order] + [standardize_y(data[name]) for name in self.output_order] + sample_weight
return self._test(ins)
def predict_on_batch(self, data):
# data is a dictionary mapping input names to arrays
ins = [data[name] for name in self.input_order]
return self._predict(ins)
def fit(self, data, batch_size=128, nb_epoch=100, verbose=1, callbacks=[],
validation_split=0., validation_data=None, shuffle=True,
class_weight={}, sample_weight={}):
X = [data[name] for name in self.input_order]
y = [standardize_y(data[name]) for name in self.output_order]
sample_weight_list = [standardize_weights(y[i],
sample_weight=sample_weight.get(self.output_order[i])) for i in range(len(self.output_order))]
class_weight_list = [class_weight.get(name) for name in self.output_order]
val_f = None
val_ins = None
if validation_data or validation_split:
val_f = self._test
if validation_data:
# can't use sample weights with validation data at this point
y_val = [standardize_y(data[name]) for name in self.output_order]
sample_weight = [standardize_weights(y_val[i]) for i in range(len(y_val))]
val_ins = [validation_data[name] for name in self.input_order] + [standardize_y(validation_data[name]) for name in self.output_order] + sample_weight
elif 0 < validation_split < 1:
split_at = int(len(X[0]) * (1 - validation_split))
X, X_val = (slice_X(X, 0, split_at), slice_X(X, split_at))
y, y_val = (slice_X(y, 0, split_at), slice_X(y, split_at))
sample_weight_list, sample_weight_list_val = (slice_X(sample_weight_list, 0, split_at), slice_X(sample_weight_list, split_at))
val_ins = X_val + y_val + sample_weight_list_val
f = self._train
out_labels = ['loss']
metrics = ['loss', 'val_loss']
sample_weight_list = [standardize_weights(y[i],
sample_weight=sample_weight_list[i],
class_weight=class_weight_list[i]) for i in range(len(self.output_order))]
ins = X + y + sample_weight_list
history = self._fit(f, ins, out_labels=out_labels, batch_size=batch_size, nb_epoch=nb_epoch,
verbose=verbose, callbacks=callbacks,
val_f=val_f, val_ins=val_ins,
shuffle=shuffle, metrics=metrics)
return history
def evaluate(self, data, batch_size=128, verbose=0, sample_weight={}):
sample_weight = [standardize_weights(data[name],
sample_weight=sample_weight.get(name)) for name in self.output_order]
ins = [data[name] for name in self.input_order] + [standardize_y(data[name]) for name in self.output_order] + sample_weight
outs = self._test_loop(self._test, ins, batch_size, verbose)
return outs[0]
def predict(self, data, batch_size=128, verbose=0):
ins = [data[name] for name in self.input_order]
outs = self._predict_loop(self._predict, ins, batch_size, verbose)
return dict(zip(self.output_order, outs))
def save_weights(self, filepath, overwrite=False):
# Save weights from all layers to HDF5
import h5py
import os.path
# if file exists and should not be overwritten
if not overwrite and os.path.isfile(filepath):
import sys
get_input = input
if sys.version_info[:2] <= (2, 7):
get_input = raw_input
overwrite = get_input('[WARNING] %s already exists - overwrite? [y/n]' % (filepath))
while overwrite not in ['y', 'n']:
overwrite = get_input('Enter "y" (overwrite) or "n" (cancel).')
if overwrite == 'n':
return
print('[TIP] Next time specify overwrite=True in save_weights!')
f = h5py.File(filepath, 'w')
g = f.create_group('graph')
weights = self.get_weights()
g.attrs['nb_params'] = len(weights)
for n, param in enumerate(weights):
param_name = 'param_{}'.format(n)
param_dset = g.create_dataset(param_name, param.shape, dtype=param.dtype)
param_dset[:] = param
f.flush()
f.close()
def load_weights(self, filepath):
# Loads weights from HDF5 file
import h5py
f = h5py.File(filepath)
g = f['graph']
weights = [g['param_{}'.format(p)] for p in range(g.attrs['nb_params'])]
self.set_weights(weights)
f.close()
+34 -24
Ver Arquivo
@@ -1,49 +1,59 @@
from __future__ import absolute_import
import theano
import theano.tensor as T
import numpy as np
from six.moves import range
from . import backend as K
epsilon = 1.0e-15
def mean_squared_error(y_true, y_pred):
return T.sqr(y_pred - y_true).mean()
return K.mean(K.square(y_pred - y_true), axis=-1)
def root_mean_squared_error(y_true, y_pred):
return K.sqrt(K.mean(K.square(y_pred - y_true), axis=-1))
def mean_absolute_error(y_true, y_pred):
return T.abs_(y_pred - y_true).mean()
return K.mean(K.abs(y_pred - y_true), axis=-1)
def mean_absolute_percentage_error(y_true, y_pred):
diff = K.abs((y_true - y_pred) / K.clip(K.abs(y_true), K._EPSILON, np.inf))
return 100. * K.mean(diff, axis=-1)
def mean_squared_logarithmic_error(y_true, y_pred):
first_log = K.log(K.clip(y_pred, K._EPSILON, np.inf) + 1.)
second_log = K.log(K.clip(y_true, K._EPSILON, np.inf) + 1.)
return K.mean(K.square(first_log - second_log), axis=-1)
def squared_hinge(y_true, y_pred):
return T.sqr(T.maximum(1. - y_true * y_pred, 0.)).mean()
return K.mean(K.square(K.maximum(1. - y_true * y_pred, 0.)), axis=-1)
def hinge(y_true, y_pred):
return T.maximum(1. - y_true * y_pred, 0.).mean()
return K.mean(K.maximum(1. - y_true * y_pred, 0.), axis=-1)
def categorical_crossentropy(y_true, y_pred):
'''Expects a binary class matrix instead of a vector of scalar classes
'''
y_pred = T.clip(y_pred, epsilon, 1.0 - epsilon)
# scale preds so that the class probas of each sample sum to 1
y_pred /= y_pred.sum(axis=1, keepdims=True)
return T.nnet.categorical_crossentropy(y_pred, y_true).mean()
return K.mean(K.categorical_crossentropy(y_pred, y_true), axis=-1)
def binary_crossentropy(y_true, y_pred):
y_pred = T.clip(y_pred, epsilon, 1.0 - epsilon)
return T.nnet.binary_crossentropy(y_pred, y_true).mean()
return K.mean(K.binary_crossentropy(y_pred, y_true), axis=-1)
def poisson_loss(y_true, y_pred):
return K.mean(y_pred - y_true * K.log(y_pred + K._EPSILON), axis=-1)
# aliases
mse = MSE = mean_squared_error
rmse = RMSE = root_mean_squared_error
mae = MAE = mean_absolute_error
mape = MAPE = mean_absolute_percentage_error
msle = MSLE = mean_squared_logarithmic_error
from .utils.generic_utils import get_from_module
def get(identifier):
return get_from_module(identifier, globals(), 'objective')
def to_categorical(y):
'''Convert class vector (integers from 0 to nb_classes)
to binary class matrix, for use with categorical_crossentropy
'''
nb_classes = np.max(y)+1
Y = np.zeros((len(y), nb_classes))
for i in range(len(y)):
Y[i, y[i]] = 1.
return Y
+142 -96
Ver Arquivo
@@ -1,104 +1,136 @@
from __future__ import absolute_import
import theano
import theano.tensor as T
from . import backend as K
import numpy as np
from .utils.theano_utils import shared_zeros, shared_scalar
from .utils.generic_utils import get_from_module
from six.moves import zip
def clip_norm(g, c, n):
if c > 0:
g = T.switch(T.ge(n, c), g*c/n, g)
g = K.switch(n >= c, g * c / n, g)
return g
def kl_divergence(p, p_hat):
return p_hat - p + p*T.log(p/p_hat)
return p_hat - p + p * K.log(p / p_hat)
class Optimizer(object):
def get_updates(self, params, grads):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
self.updates = []
def get_state(self):
return [K.get_value(u[0]) for u in self.updates]
def set_state(self, value_list):
assert len(self.updates) == len(value_list)
for u, v in zip(self.updates, value_list):
K.set_value(u[0], v)
def get_updates(self, params, constraints, loss):
raise NotImplementedError
def get_gradients(self, cost, params, regularizers):
grads = T.grad(cost, params)
def get_gradients(self, loss, params):
grads = K.gradients(loss, params)
if hasattr(self, 'clipnorm') and self.clipnorm > 0:
norm = T.sqrt(sum([T.sum(g**2) for g in grads]))
norm = K.sqrt(sum([K.sum(K.square(g)) for g in grads]))
grads = [clip_norm(g, self.clipnorm, norm) for g in grads]
if hasattr(self, 'clipvalue') and self.clipvalue > 0:
grads = [K.clip(g, -self.clipvalue, self.clipvalue) for g in grads]
return grads
new_grads = []
for p, g, r in zip(params, grads, regularizers):
g = r(g, p)
new_grads.append(g)
return new_grads
def get_config(self):
return {"name": self.__class__.__name__}
class SGD(Optimizer):
def __init__(self, lr=0.01, momentum=0., decay=0., nesterov=False, *args, **kwargs):
self.__dict__.update(kwargs)
def __init__(self, lr=0.01, momentum=0., decay=0., nesterov=False,
*args, **kwargs):
super(SGD, self).__init__(**kwargs)
self.__dict__.update(locals())
self.iterations = shared_scalar(0)
self.iterations = K.variable(0.)
self.lr = K.variable(lr)
self.momentum = K.variable(momentum)
self.decay = K.variable(decay)
def get_updates(self, params, regularizers, constraints, cost):
grads = self.get_gradients(cost, params, regularizers)
def get_updates(self, params, constraints, loss):
grads = self.get_gradients(loss, params)
lr = self.lr * (1.0 / (1.0 + self.decay * self.iterations))
updates = [(self.iterations, self.iterations+1.)]
self.updates = [(self.iterations, self.iterations + 1.)]
for p, g, c in zip(params, grads, constraints):
m = shared_zeros(p.get_value().shape) # momentum
v = self.momentum * m - lr * g # velocity
updates.append((m, v))
m = K.variable(np.zeros(K.get_value(p).shape)) # momentum
v = self.momentum * m - lr * g # velocity
self.updates.append((m, v))
if self.nesterov:
new_p = p + self.momentum * v - lr * g
else:
new_p = p + v
updates.append((p, c(new_p))) # apply constraints
return updates
self.updates.append((p, c(new_p))) # apply constraints
return self.updates
def get_config(self):
return {"name": self.__class__.__name__,
"lr": float(K.get_value(self.lr)),
"momentum": float(K.get_value(self.momentum)),
"decay": float(K.get_value(self.decay)),
"nesterov": self.nesterov}
class RMSprop(Optimizer):
def __init__(self, lr=0.001, rho=0.9, epsilon=1e-6, *args, **kwargs):
self.__dict__.update(kwargs)
super(RMSprop, self).__init__(**kwargs)
self.__dict__.update(locals())
self.lr = K.variable(lr)
self.rho = K.variable(rho)
def get_updates(self, params, regularizers, constraints, cost):
grads = self.get_gradients(cost, params, regularizers)
accumulators = [shared_zeros(p.get_value().shape) for p in params]
updates = []
def get_updates(self, params, constraints, loss):
grads = self.get_gradients(loss, params)
accumulators = [K.variable(np.zeros(K.get_value(p).shape)) for p in params]
self.updates = []
for p, g, a, c in zip(params, grads, accumulators, constraints):
new_a = self.rho * a + (1 - self.rho) * g ** 2 # update accumulator
updates.append((a, new_a))
# update accumulator
new_a = self.rho * a + (1 - self.rho) * K.square(g)
self.updates.append((a, new_a))
new_p = p - self.lr * g / T.sqrt(new_a + self.epsilon)
updates.append((p, c(new_p))) # apply constraints
return updates
new_p = p - self.lr * g / K.sqrt(new_a + self.epsilon)
self.updates.append((p, c(new_p))) # apply constraints
return self.updates
def get_config(self):
return {"name": self.__class__.__name__,
"lr": float(K.get_value(self.lr)),
"rho": float(K.get_value(self.rho)),
"epsilon": self.epsilon}
class Adagrad(Optimizer):
def __init__(self, lr=0.01, epsilon=1e-6, *args, **kwargs):
self.__dict__.update(kwargs)
super(Adagrad, self).__init__(**kwargs)
self.__dict__.update(locals())
self.lr = K.variable(lr)
def get_updates(self, params, regularizers, constraints, cost):
grads = self.get_gradients(cost, params, regularizers)
accumulators = [shared_zeros(p.get_value().shape) for p in params]
updates = []
def get_updates(self, params, constraints, loss):
grads = self.get_gradients(loss, params)
accumulators = [K.variable(np.zeros(K.get_value(p).shape)) for p in params]
self.updates = []
for p, g, a, c in zip(params, grads, accumulators, constraints):
new_a = a + g ** 2 # update accumulator
updates.append((a, new_a))
new_a = a + K.square(g) # update accumulator
self.updates.append((a, new_a))
new_p = p - self.lr * g / K.sqrt(new_a + self.epsilon)
self.updates.append((p, c(new_p))) # apply constraints
return self.updates
new_p = p - self.lr * g / T.sqrt(new_a + self.epsilon)
updates.append((p, c(new_p))) # apply constraints
return updates
def get_config(self):
return {"name": self.__class__.__name__,
"lr": float(K.get_value(self.lr)),
"epsilon": self.epsilon}
class Adadelta(Optimizer):
@@ -106,70 +138,83 @@ class Adadelta(Optimizer):
Reference: http://arxiv.org/abs/1212.5701
'''
def __init__(self, lr=1.0, rho=0.95, epsilon=1e-6, *args, **kwargs):
self.__dict__.update(kwargs)
super(Adadelta, self).__init__(**kwargs)
self.__dict__.update(locals())
self.lr = K.variable(lr)
def get_updates(self, params, regularizers, constraints, cost):
grads = self.get_gradients(cost, params, regularizers)
accumulators = [shared_zeros(p.get_value().shape) for p in params]
delta_accumulators = [shared_zeros(p.get_value().shape) for p in params]
updates = []
def get_updates(self, params, constraints, loss):
grads = self.get_gradients(loss, params)
accumulators = [K.variable(np.zeros(K.get_value(p).shape)) for p in params]
delta_accumulators = [K.variable(np.zeros(K.get_value(p).shape)) for p in params]
self.updates = []
for p, g, a, d_a, c in zip(params, grads, accumulators, delta_accumulators, constraints):
new_a = self.rho * a + (1 - self.rho) * g ** 2 # update accumulator
updates.append((a, new_a))
for p, g, a, d_a, c in zip(params, grads, accumulators,
delta_accumulators, constraints):
# update accumulator
new_a = self.rho * a + (1 - self.rho) * K.square(g)
self.updates.append((a, new_a))
# use the new accumulator and the *old* delta_accumulator
update = g * T.sqrt(d_a + self.epsilon) / T.sqrt(new_a + self.epsilon)
update = g * K.sqrt(d_a + self.epsilon) / K.sqrt(new_a + self.epsilon)
new_p = p - self.lr * update
updates.append((p, c(new_p))) # apply constraints
self.updates.append((p, c(new_p))) # apply constraints
# update delta_accumulator
new_d_a = self.rho * d_a + (1 - self.rho) * update ** 2
updates.append((d_a, new_d_a))
return updates
new_d_a = self.rho * d_a + (1 - self.rho) * K.square(update)
self.updates.append((d_a, new_d_a))
return self.updates
def get_config(self):
return {"name": self.__class__.__name__,
"lr": float(K.get_value(self.lr)),
"rho": float(K.get_value(self.rho)),
"epsilon": self.epsilon}
class Adam(Optimizer):
'''
Reference: http://arxiv.org/abs/1412.6980
Reference: http://arxiv.org/abs/1412.6980v8
Default parameters follow those provided in the original paper
lambda is renamed kappa.
Default parameters follow those provided in the original paper.
'''
def __init__(self, lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-8, kappa=1-1e-8, *args, **kwargs):
self.__dict__.update(kwargs)
def __init__(self, lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-8,
*args, **kwargs):
super(Adam, self).__init__(**kwargs)
self.__dict__.update(locals())
self.iterations = shared_scalar(0)
self.iterations = K.variable(0)
self.lr = K.variable(lr)
self.beta_1 = K.variable(beta_1)
self.beta_2 = K.variable(beta_2)
def get_updates(self, params, regularizers, constraints, cost):
grads = self.get_gradients(cost, params, regularizers)
updates = [(self.iterations, self.iterations+1.)]
def get_updates(self, params, constraints, loss):
grads = self.get_gradients(loss, params)
self.updates = [(self.iterations, self.iterations+1.)]
i = self.iterations
beta_1_t = self.beta_1 * (self.kappa**i)
# the update below seems missing from the paper, but is obviously required
beta_2_t = self.beta_2 * (self.kappa**i)
t = self.iterations + 1
lr_t = self.lr * K.sqrt(1 - K.pow(self.beta_2, t)) / (1 - K.pow(self.beta_1, t))
for p, g, c in zip(params, grads, constraints):
m = theano.shared(p.get_value() * 0.) # zero init of moment
v = theano.shared(p.get_value() * 0.) # zero init of velocity
# zero init of moment
m = K.variable(np.zeros(K.get_value(p).shape))
# zero init of velocity
v = K.variable(np.zeros(K.get_value(p).shape))
m_t = (beta_1_t * m) + (1 - beta_1_t) * g
v_t = (beta_2_t * v) + (1 - beta_2_t) * (g**2)
m_t = (self.beta_1 * m) + (1 - self.beta_1) * g
v_t = (self.beta_2 * v) + (1 - self.beta_2) * K.square(g)
p_t = p - lr_t * m_t / (K.sqrt(v_t) + self.epsilon)
m_b_t = m_t / (1 - beta_1_t)
v_b_t = v_t / (1 - beta_2_t)
self.updates.append((m, m_t))
self.updates.append((v, v_t))
self.updates.append((p, c(p_t))) # apply constraints
return self.updates
p_t = p - self.lr * m_b_t / (T.sqrt(v_b_t) + self.epsilon)
updates.append((m, m_t))
updates.append((v, v_t))
updates.append((p, c(p_t))) # apply constraints
return updates
def get_config(self):
return {"name": self.__class__.__name__,
"lr": float(K.get_value(self.lr)),
"beta_1": float(K.get_value(self.beta_1)),
"beta_2": float(K.get_value(self.beta_2)),
"epsilon": self.epsilon}
# aliases
sgd = SGD
@@ -178,6 +223,7 @@ adagrad = Adagrad
adadelta = Adadelta
adam = Adam
from .utils.generic_utils import get_from_module
def get(identifier):
return get_from_module(identifier, globals(), 'optimizer', instantiate=True)
def get(identifier, kwargs=None):
return get_from_module(identifier, globals(), 'optimizer',
instantiate=True, kwargs=kwargs)
+6 -10
Ver Arquivo
@@ -1,6 +1,7 @@
from __future__ import absolute_import
import numpy as np
import re
from scipy import ndimage
from scipy import linalg
@@ -103,7 +104,7 @@ def img_to_array(img):
def load_img(path, grayscale=False):
from PIL import Image
img = Image.open(open(path))
img = Image.open(path)
if grayscale:
img = img.convert('L')
else: # Assure 3 channel even when loaded image is grayscale
@@ -213,17 +214,14 @@ class ImageDataGenerator(object):
# channel shifting
return x
def fit(self, X,
augment=False, # fit on randomly augmented samples
rounds=1, # if augment, how many augmentation passes over the data do we use
seed=None
):
def fit(self, X,
augment=False, # fit on randomly augmented samples
rounds=1, # if augment, how many augmentation passes over the data do we use
seed=None):
'''
Required for featurewise_center, featurewise_std_normalization and zca_whitening.
'''
X = np.copy(X)
if augment:
aX = np.zeros(tuple([rounds*X.shape[0]]+list(X.shape)[1:]))
for r in range(rounds):
@@ -246,5 +244,3 @@ class ImageDataGenerator(object):
sigma = np.dot(flatX.T, flatX) / flatX.shape[1]
U, S, V = linalg.svd(sigma)
self.principal_components = np.dot(np.dot(U, np.diag(1. / np.sqrt(S + fudge))), U.T)
+23 -5
Ver Arquivo
@@ -4,13 +4,17 @@ import numpy as np
import random
from six.moves import range
def pad_sequences(sequences, maxlen=None, dtype='int32'):
def pad_sequences(sequences, maxlen=None, dtype='int32', padding='pre', truncating='pre', value=0.):
"""
Pad each sequence to the same length:
the length of the longuest sequence.
the length of the longest sequence.
If maxlen is provided, any sequence longer
than maxlen is truncated to maxlen.
than maxlen is truncated to maxlen. Truncation happens off either the beginning (default) or
the end of the sequence.
Supports post-padding and pre-padding (default).
"""
lengths = [len(s) for s in sequences]
@@ -18,9 +22,23 @@ def pad_sequences(sequences, maxlen=None, dtype='int32'):
if maxlen is None:
maxlen = np.max(lengths)
x = np.zeros((nb_samples, maxlen)).astype(dtype)
x = (np.ones((nb_samples, maxlen)) * value).astype(dtype)
for idx, s in enumerate(sequences):
x[idx, :lengths[idx]] = s[:maxlen]
if len(s) == 0:
continue # empty list was found
if truncating == 'pre':
trunc = s[-maxlen:]
elif truncating == 'post':
trunc = s[:maxlen]
else:
raise ValueError("Truncating type '%s' not understood" % padding)
if padding == 'post':
x[idx, :len(trunc)] = trunc
elif padding == 'pre':
x[idx, -len(trunc):] = trunc
else:
raise ValueError("Padding type '%s' not understood" % padding)
return x
+11 -20
Ver Arquivo
@@ -15,12 +15,14 @@ if sys.version_info < (3,):
else:
maketrans = str.maketrans
def base_filter():
f = string.punctuation
f = f.replace("'", '')
f += '\t\n'
return f
def text_to_word_sequence(text, filters=base_filter(), lower=True, split=" "):
'''prune: sequence of characters to filter out
'''
@@ -32,8 +34,8 @@ def text_to_word_sequence(text, filters=base_filter(), lower=True, split=" "):
def one_hot(text, n, filters=base_filter(), lower=True, split=" "):
seq = text_to_word_sequence(text)
return [(abs(hash(w))%(n-1)+1) for w in seq]
seq = text_to_word_sequence(text, filters=filters, lower=lower, split=split)
return [(abs(hash(w)) % (n - 1) + 1) for w in seq]
class Tokenizer(object):
@@ -67,18 +69,17 @@ class Tokenizer(object):
self.word_docs[w] = 1
wcounts = list(self.word_counts.items())
wcounts.sort(key = lambda x: x[1], reverse=True)
wcounts.sort(key=lambda x: x[1], reverse=True)
sorted_voc = [wc[0] for wc in wcounts]
self.word_index = dict(list(zip(sorted_voc, list(range(1, len(sorted_voc)+1)))))
self.word_index = dict(list(zip(sorted_voc, list(range(1, len(sorted_voc) + 1)))))
self.index_docs = {}
for w, c in list(self.word_docs.items()):
self.index_docs[self.word_index[w]] = c
def fit_on_sequences(self, sequences):
'''
required before using sequences_to_matrix
required before using sequences_to_matrix
(if fit_on_texts was never called)
'''
self.document_count = len(sequences)
@@ -91,7 +92,6 @@ class Tokenizer(object):
else:
self.index_docs[i] += 1
def texts_to_sequences(self, texts):
'''
Transform each text in texts in a sequence of integers.
@@ -126,7 +126,6 @@ class Tokenizer(object):
vect.append(i)
yield vect
def texts_to_matrix(self, texts, mode="binary"):
'''
modes: binary, count, tfidf, freq
@@ -140,7 +139,7 @@ class Tokenizer(object):
'''
if not self.nb_words:
if self.word_index:
nb_words = len(self.word_index)
nb_words = len(self.word_index) + 1
else:
raise Exception("Specify a dimension (nb_words argument), or fit on some text data first")
else:
@@ -165,21 +164,13 @@ class Tokenizer(object):
if mode == "count":
X[i][j] = c
elif mode == "freq":
X[i][j] = c/len(seq)
X[i][j] = c / len(seq)
elif mode == "binary":
X[i][j] = 1
elif mode == "tfidf":
tf = np.log(c/len(seq))
df = (1 + np.log(1 + self.index_docs.get(j, 0)/(1 + self.document_count)))
tf = np.log(c / len(seq))
df = (1 + np.log(1 + self.index_docs.get(j, 0) / (1 + self.document_count)))
X[i][j] = tf / df
else:
raise Exception("Unknown vectorization mode: " + str(mode))
return X
+81 -21
Ver Arquivo
@@ -1,26 +1,86 @@
from __future__ import absolute_import
import theano
import theano.tensor as T
import numpy as np
from . import backend as K
def l1(l=.01):
def l1wrap(g, p):
g += T.sgn(p) * l
return g
return l1wrap
def l2(l=.01):
def l2wrap(g, p):
g += p * l
return g
return l2wrap
class Regularizer(object):
def set_param(self, p):
self.p = p
def l1l2(l1=.01, l2=.01):
def l1l2wrap(g, p):
g += T.sgn(p) * l1
g += p * l2
return g
return l1l2wrap
def set_layer(self, layer):
self.layer = layer
def identity(g, p):
return g
def __call__(self, loss):
return loss
def get_config(self):
return {"name": self.__class__.__name__}
class WeightRegularizer(Regularizer):
def __init__(self, l1=0., l2=0.):
self.l1 = l1
self.l2 = l2
def set_param(self, p):
self.p = p
def __call__(self, loss):
loss += K.sum(K.abs(self.p)) * self.l1
loss += K.sum(K.square(self.p)) * self.l2
return loss
def get_config(self):
return {"name": self.__class__.__name__,
"l1": self.l1,
"l2": self.l2}
class ActivityRegularizer(Regularizer):
def __init__(self, l1=0., l2=0.):
self.l1 = l1
self.l2 = l2
def set_layer(self, layer):
self.layer = layer
def __call__(self, loss):
output = self.layer.get_output(True)
loss += self.l1 * K.sum(K.mean(K.abs(output), axis=0))
loss += self.l2 * K.sum(K.mean(K.square(output), axis=0))
return loss
def get_config(self):
return {"name": self.__class__.__name__,
"l1": self.l1,
"l2": self.l2}
def l1(l=0.01):
return WeightRegularizer(l1=l)
def l2(l=0.01):
return WeightRegularizer(l2=l)
def l1l2(l1=0.01, l2=0.01):
return WeightRegularizer(l1=l1, l2=l2)
def activity_l1(l=0.01):
return ActivityRegularizer(l1=l)
def activity_l2(l=0.01):
return ActivityRegularizer(l2=l)
def activity_l1l2(l1=0.01, l2=0.01):
return ActivityRegularizer(l1=l1, l2=l2)
identity = Regularizer
from .utils.generic_utils import get_from_module
def get(identifier, kwargs=None):
return get_from_module(identifier, globals(), 'regularizer',
instantiate=True, kwargs=kwargs)
-51
Ver Arquivo
@@ -1,51 +0,0 @@
import pydot
from keras.layers.core import Merge
from keras.models import Model
from collections import Counter
class Grapher(object):
def __init__(self):
self.names = {}
self.class_counts = Counter()
def get_name(self, model):
"""
returns the name of the model instance. If model does not have a `name` attribute, then it will be assigned
a generic (and unique) identifier based on its class
"""
if hasattr(model, 'name'):
return model.name
clz = model.__class__.__name__
if model not in self.names:
self.class_counts[clz] += 1
self.names[model] = clz + str(self.class_counts[clz])
return self.names[model]
def add_edge(self, f, t, graph):
if f: graph.add_edge(pydot.Edge(f, t))
return t
def add_model(self, model, graph, parent=None):
"""
Recursively adds `model` and its components to the pydot graph
"""
this = self.get_name(model)
if isinstance(model, Model):
parent = self.add_edge(parent, this, graph)
for child in reversed(model.layers):
parent = self.add_model(child, graph, parent)
elif isinstance(model, Merge):
for child in model.models:
self.add_model(child, graph, this)
return self.add_edge(parent, this, graph)
else:
return self.add_edge(parent, this, graph)
def plot(self, model, to_file):
"""
creates a graph visualizing the structure of `model` and writes it to `to_file`
"""
graph = pydot.Dot(graph_type='graph')
self.add_model(model, graph)
graph.write_png(to_file)
+20 -11
Ver Arquivo
@@ -2,21 +2,27 @@ from __future__ import absolute_import
import numpy as np
import time
import sys
import six
def get_from_module(identifier, module_params, module_name, instantiate=False):
if type(identifier) is str:
def get_from_module(identifier, module_params, module_name, instantiate=False, kwargs=None):
if isinstance(identifier, six.string_types):
res = module_params.get(identifier)
if not res:
raise Exception('Invalid ' + str(module_name) + ': ' + str(identifier))
if instantiate:
if instantiate and not kwargs:
return res()
elif instantiate and kwargs:
return res(**kwargs)
else:
return res
return identifier
def make_tuple(*args):
return args
def printv(v, prefix=''):
if type(v) == dict:
if 'name' in v:
@@ -33,11 +39,12 @@ def printv(v, prefix=''):
prefix += '...'
for i, nv in enumerate(v):
print(prefix + '#' + str(i))
printv(nv, prefix)
printv(nv, prefix)
else:
prefix += '...'
print(prefix + str(v))
class Progbar(object):
def __init__(self, target, width=30, verbose=1):
'''
@@ -60,11 +67,11 @@ class Progbar(object):
'''
for k, v in values:
if k not in self.sum_values:
self.sum_values[k] = [v * (current-self.seen_so_far), current-self.seen_so_far]
self.sum_values[k] = [v * (current - self.seen_so_far), current - self.seen_so_far]
self.unique_values.append(k)
else:
self.sum_values[k][0] += v * (current-self.seen_so_far)
self.sum_values[k][1] += (current-self.seen_so_far)
self.sum_values[k][0] += v * (current - self.seen_so_far)
self.sum_values[k][1] += (current - self.seen_so_far)
self.seen_so_far = current
now = time.time()
@@ -88,7 +95,7 @@ class Progbar(object):
bar += ']'
sys.stdout.write(bar)
self.total_width = len(bar)
if current:
time_per_unit = (now - self.start) / current
else:
@@ -100,7 +107,10 @@ class Progbar(object):
else:
info += ' - %ds' % (now - self.start)
for k in self.unique_values:
info += ' - %s: %.4f' % (k, self.sum_values[k][0]/ max(1, self.sum_values[k][1]))
if type(self.sum_values[k]) is list:
info += ' - %s: %.4f' % (k, self.sum_values[k][0] / max(1, self.sum_values[k][1]))
else:
info += ' - %s: %s' % (k, self.sum_values[k])
self.total_width += len(info)
if prev_total_width > self.total_width:
@@ -116,9 +126,8 @@ class Progbar(object):
if current >= self.target:
info = '%ds' % (now - self.start)
for k in self.unique_values:
info += ' - %s: %.4f' % (k, self.sum_values[k][0]/ max(1, self.sum_values[k][1]))
info += ' - %s: %.4f' % (k, self.sum_values[k][0] / max(1, self.sum_values[k][1]))
sys.stdout.write(info + "\n")
def add(self, n, values=[]):
self.update(self.seen_so_far+n, values)
+6 -5
Ver Arquivo
@@ -3,8 +3,8 @@ import h5py
import numpy as np
from collections import defaultdict
class HDF5Matrix:
class HDF5Matrix():
refs = defaultdict(int)
def __init__(self, datapath, dataset, start, end, normalizer=None):
@@ -17,7 +17,7 @@ class HDF5Matrix:
self.end = end
self.data = f[dataset]
self.normalizer = normalizer
def __len__(self):
return self.end - self.start
@@ -60,11 +60,12 @@ def save_array(array, name):
ds[:] = array
f.close()
def load_array(name):
import tables
f = tables.open_file(name)
array = f.root.data
a=np.empty(shape=array.shape, dtype=array.dtype)
a[:]=array[:]
a = np.empty(shape=array.shape, dtype=array.dtype)
a[:] = array[:]
f.close()
return a
+93
Ver Arquivo
@@ -0,0 +1,93 @@
from __future__ import print_function
import inspect
import numpy as np
import copy
from ..layers.advanced_activations import *
from ..layers.core import *
from ..layers.convolutional import *
from ..layers.embeddings import *
from ..layers.noise import *
from ..layers.normalization import *
from ..layers.recurrent import *
from ..layers import containers
from .. import regularizers
from .. import constraints
def container_from_config(original_layer_dict, custom_objects={}):
layer_dict = copy.deepcopy(original_layer_dict)
name = layer_dict.get('name')
# Insert custom layers into globals so they can
# be accessed by `get_from_module`.
for cls_key in custom_objects:
globals()[cls_key] = custom_objects[cls_key]
if name == 'Merge':
mode = layer_dict.get('mode')
layers = layer_dict.get('layers')
layer_list = []
for layer in layers:
init_layer = container_from_config(layer)
layer_list.append(init_layer)
merge_layer = Merge(layer_list, mode)
return merge_layer
elif name == 'Sequential':
layers = layer_dict.get('layers')
layer_list = []
for layer in layers:
init_layer = container_from_config(layer)
layer_list.append(init_layer)
seq_layer = containers.Sequential(layer_list)
return seq_layer
elif name == 'Graph':
graph_layer = containers.Graph()
inputs = layer_dict.get('input_config')
for input in inputs:
graph_layer.add_input(**input)
nodes = layer_dict.get('node_config')
for node in nodes:
layer = container_from_config(layer_dict['nodes'].get(node['name']))
node['layer'] = layer
graph_layer.add_node(**node)
outputs = layer_dict.get('output_config')
for output in outputs:
graph_layer.add_output(**output)
return graph_layer
elif name == 'AutoEncoder':
kwargs = {'encoder': container_from_config(layer_dict.get('encoder_config')),
'decoder': container_from_config(layer_dict.get('decoder_config'))}
for kwarg in ['output_reconstruction', 'weights']:
if kwarg in layer_dict:
kwargs[kwarg] = layer_dict[kwarg]
return AutoEncoder(**kwargs)
else:
layer_dict.pop('name')
for k, v in layer_dict.items():
if isinstance(v, dict):
vname = v.pop('name')
if vname in [x for x, y in inspect.getmembers(constraints, predicate=inspect.isclass)]:
layer_dict[k] = constraints.get(vname, v)
elif vname in [x for x, y in inspect.getmembers(regularizers, predicate=inspect.isclass)]:
layer_dict[k] = regularizers.get(vname, v)
else:
# not a regularizer of constraint, don't touch it
v['name'] = vname
base_layer = get_layer(name, layer_dict)
return base_layer
from .generic_utils import get_from_module
def get_layer(identifier, kwargs=None):
return get_from_module(identifier, globals(), 'layer',
instantiate=True, kwargs=kwargs)
+10 -5
Ver Arquivo
@@ -4,6 +4,7 @@ import scipy as sp
from six.moves import range
from six.moves import zip
def to_categorical(y, nb_classes=None):
'''Convert class vector (integers from 0 to nb_classes)
to binary class matrix, for use with categorical_crossentropy
@@ -16,9 +17,10 @@ def to_categorical(y, nb_classes=None):
Y[i, y[i]] = 1.
return Y
def normalize(a, axis=-1, order=2):
l2 = np.atleast_1d(np.linalg.norm(a, order, axis))
l2[l2==0] = 1
l2[l2 == 0] = 1
return a / np.expand_dims(l2, axis)
@@ -26,23 +28,26 @@ def binary_logloss(p, y):
epsilon = 1e-15
p = sp.maximum(epsilon, p)
p = sp.minimum(1-epsilon, p)
res = sum(y*sp.log(p) + sp.subtract(1,y)*sp.log(sp.subtract(1,p)))
res = sum(y * sp.log(p) + sp.subtract(1, y) * sp.log(sp.subtract(1, p)))
res *= -1.0/len(y)
return res
def multiclass_logloss(P, Y):
score = 0.
npreds = [P[i][Y[i]-1] for i in range(len(Y))]
score = -(1./len(Y)) * np.sum(np.log(npreds))
score = -(1. / len(Y)) * np.sum(np.log(npreds))
return score
def accuracy(p, y):
return np.mean([a==b for a, b in zip(p, y)])
return np.mean([a == b for a, b in zip(p, y)])
def probas_to_classes(y_pred):
if len(y_pred.shape) > 1 and y_pred.shape[1] > 1:
return categorical_probas_to_classes(y_pred)
return np.array([1 if p > 0.5 else 0 for p in y_pred])
def categorical_probas_to_classes(p):
return np.argmax(p, axis=1)
+27
Ver Arquivo
@@ -0,0 +1,27 @@
import numpy as np
def get_test_data(nb_train=1000, nb_test=500, input_shape=(10,), output_shape=(2,),
classification=True, nb_class=2):
'''
classification=True overrides output_shape
(i.e. output_shape is set to (1,)) and the output
consists in integers in [0, nb_class-1].
Otherwise: float output with shape output_shape.
'''
nb_sample = nb_train + nb_test
if classification:
y = np.random.randint(0, nb_class, size=(nb_sample, 1))
X = np.zeros((nb_sample,) + input_shape)
for i in range(nb_sample):
X[i] = np.random.normal(loc=y[i], scale=1.0, size=input_shape)
else:
y_loc = np.random.random((nb_sample,))
X = np.zeros((nb_sample,) + input_shape)
y = np.zeros((nb_sample,) + output_shape)
for i in range(nb_sample):
X[i] = np.random.normal(loc=y_loc[i], scale=1.0, size=input_shape)
y[i] = np.random.normal(loc=y_loc[i], scale=1.0, size=output_shape)
return (X[:nb_train], y[:nb_train]), (X[nb_train:], y[nb_train:])
-22
Ver Arquivo
@@ -1,22 +0,0 @@
from __future__ import absolute_import
import numpy as np
import theano
import theano.tensor as T
def floatX(X):
return np.asarray(X, dtype=theano.config.floatX)
def sharedX(X, dtype=theano.config.floatX, name=None):
return theano.shared(np.asarray(X, dtype=dtype), name=name)
def shared_zeros(shape, dtype=theano.config.floatX, name=None):
return sharedX(np.zeros(shape), dtype=dtype, name=name)
def shared_scalar(val=0., dtype=theano.config.floatX, name=None):
return theano.shared(np.cast[dtype](val))
def shared_ones(shape, dtype=theano.config.floatX, name=None):
return sharedX(np.ones(shape), dtype=dtype, name=name)
def alloc_zeros_matrix(*dims):
return T.alloc(np.cast[theano.config.floatX](0.), *dims)
+41
Ver Arquivo
@@ -0,0 +1,41 @@
import pydot
# old pydot will not work with python3, must use one
# that works with python3 such as pydot2 or pydot
from keras.models import Sequential, Graph
def to_graph(model):
graph = pydot.Dot(graph_type='digraph')
if type(model) == Sequential:
previous_node = None
written_nodes = []
n = 1
for node in model.get_config()['layers']:
# append number in case layers have same name to differentiate
if (node['name'] + str(n)) in written_nodes:
n += 1
current_node = pydot.Node(node['name'] + str(n))
written_nodes.append(node['name'] + str(n))
graph.add_node(current_node)
if previous_node:
graph.add_edge(pydot.Edge(previous_node, current_node))
previous_node = current_node
elif type(model) == Graph:
# don't need to append number for names since all nodes labeled
for input_node in model.input_config:
graph.add_node(pydot.Node(input_node['name']))
# intermediate and output nodes have input defined
for layer_config in [model.node_config, model.output_config]:
for node in layer_config:
graph.add_node(pydot.Node(node['name']))
# possible to have multiple 'inputs' vs 1 'input'
if node['inputs']:
for e in node['inputs']:
graph.add_edge(pydot.Edge(e, node['name']))
else:
graph.add_edge(pydot.Edge(node['input'], node['name']))
return graph
def plot(model, to_file='model.png'):
graph = to_graph(model)
graph.write_png(to_file)
+141 -47
Ver Arquivo
@@ -1,23 +1,46 @@
from __future__ import absolute_import
import abc
import copy
import numpy as np
from ..utils.np_utils import to_categorical
class KerasClassifier(object):
class BaseWrapper(object):
"""
Implementation of the scikit-learn classifier API for Keras.
Base class for the Keras scikit-learn wrapper.
Warning: This class should not be used directly. Use derived classes instead.
Parameters
----------
model : object
An un-compiled Keras model object is required to use the scikit-learn wrapper.
optimizer : string, optional
Optimization method used by the model during compilation/training.
loss : string, optional
Loss function used by the model during compilation/training.
train_batch_size : int, optional
Number of training samples evaluated at a time.
test_batch_size : int, optional
Number of test samples evaluated at a time.
nb_epochs : int, optional
Number of training epochs.
shuffle : boolean, optional
Whether to shuffle the samples at each epoch.
show_accuracy : boolean, optional
Whether to display class accuracy in the logs at each epoch.
validation_split : float [0, 1], optional
Fraction of the data to use as held-out validation data.
validation_data : tuple (X, y), optional
Data to be used as held-out validation data. Will override validation_split.
callbacks : list, optional
List of callbacks to apply during training.
verbose : int, optional
Verbosity level.
"""
def __init__(self, model, optimizer='adam', loss='categorical_crossentropy'):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def __init__(self, model, optimizer, loss,
train_batch_size=128, test_batch_size=128,
nb_epoch=100, shuffle=True, show_accuracy=False,
validation_split=0, validation_data=None, callbacks=None,
verbose=0,):
self.model = model
self.optimizer = optimizer
self.loss = loss
@@ -26,6 +49,17 @@ class KerasClassifier(object):
self.config_ = []
self.weights_ = []
self.train_batch_size = train_batch_size
self.test_batch_size = test_batch_size
self.nb_epoch = nb_epoch
self.shuffle = shuffle
self.show_accuracy = show_accuracy
self.validation_split = validation_split
self.validation_data = validation_data
self.callbacks = [] if callbacks is None else callbacks
self.verbose = verbose
def get_params(self, deep=True):
"""
Get parameters for this estimator.
@@ -60,7 +94,7 @@ class KerasClassifier(object):
setattr(self, parameter, value)
return self
def fit(self, X, y, batch_size=128, nb_epoch=100, verbose=0, shuffle=True):
def fit(self, X, y):
"""
Fit the model according to the given training data.
@@ -75,19 +109,11 @@ class KerasClassifier(object):
and n_features is the number of features.
y : array-like, shape = (n_samples) or (n_samples, n_outputs)
True labels for X.
batch_size : int, optional
Number of training samples evaluated at a time.
nb_epochs : int, optional
Number of training epochs.
verbose : int, optional
Verbosity level.
shuffle : boolean, optional
Indicator to shuffle the training data.
Returns
-------
self : object
Returns self.
history : object
Returns details about the training history at each epoch.
"""
if len(y.shape) == 1:
self.classes_ = list(np.unique(y))
@@ -98,13 +124,71 @@ class KerasClassifier(object):
self.compiled_model_ = copy.deepcopy(self.model)
self.compiled_model_.compile(optimizer=self.optimizer, loss=self.loss)
self.compiled_model_.fit(X, y, batch_size=batch_size, nb_epoch=nb_epoch, verbose=verbose, shuffle=shuffle)
history = self.compiled_model_.fit(
X, y, batch_size=self.train_batch_size, nb_epoch=self.nb_epoch, verbose=self.verbose,
shuffle=self.shuffle, show_accuracy=self.show_accuracy,
validation_split=self.validation_split, validation_data=self.validation_data,
callbacks=self.callbacks)
self.config_ = self.model.get_config()
self.weights_ = self.model.get_weights()
return self
return history
def score(self, X, y, batch_size=128, verbose=0):
class KerasClassifier(BaseWrapper):
"""
Implementation of the scikit-learn classifier API for Keras.
Parameters
----------
model : object
An un-compiled Keras model object is required to use the scikit-learn wrapper.
optimizer : string
Optimization method used by the model during compilation/training.
loss : string
Loss function used by the model during compilation/training.
"""
def __init__(self, model, optimizer='adam', loss='categorical_crossentropy', **kwargs):
super(KerasClassifier, self).__init__(model, optimizer, loss, **kwargs)
def predict(self, X):
"""
Returns the class predictions for the given test data.
Parameters
----------
X : array-like, shape = (n_samples, n_features)
Test samples where n_samples in the number of samples
and n_features is the number of features.
Returns
-------
preds : array-like, shape = (n_samples)
Class predictions.
"""
return self.compiled_model_.predict_classes(
X, batch_size=self.test_batch_size, verbose=self.verbose)
def predict_proba(self, X):
"""
Returns class probability estimates for the given test data.
Parameters
----------
X : array-like, shape = (n_samples, n_features)
Test samples where n_samples in the number of samples
and n_features is the number of features.
Returns
-------
proba : array-like, shape = (n_samples, n_outputs)
Class probability estimates.
"""
return self.compiled_model_.predict_proba(
X, batch_size=self.test_batch_size, verbose=self.verbose)
def score(self, X, y):
"""
Returns the mean accuracy on the given test data and labels.
@@ -115,58 +199,68 @@ class KerasClassifier(object):
and n_features is the number of features.
y : array-like, shape = (n_samples) or (n_samples, n_outputs)
True labels for X.
batch_size : int, optional
Number of test samples evaluated at a time.
verbose : int, optional
Verbosity level.
Returns
-------
score : float
Mean accuracy of self.predict(X) wrt. y.
Mean accuracy of predictions on X wrt. y.
"""
loss, accuracy = self.compiled_model_.evaluate(X, y, batch_size=batch_size,
show_accuracy=True, verbose=verbose)
loss, accuracy = self.compiled_model_.evaluate(
X, y, batch_size=self.test_batch_size, show_accuracy=True, verbose=self.verbose)
return accuracy
def predict(self, X, batch_size=128, verbose=0):
class KerasRegressor(BaseWrapper):
"""
Implementation of the scikit-learn regressor API for Keras.
Parameters
----------
model : object
An un-compiled Keras model object is required to use the scikit-learn wrapper.
optimizer : string
Optimization method used by the model during compilation/training.
loss : string
Loss function used by the model during compilation/training.
"""
def __init__(self, model, optimizer='adam', loss='mean_squared_error', **kwargs):
super(KerasRegressor, self).__init__(model, optimizer, loss, **kwargs)
def predict(self, X):
"""
Returns the class predictions for the given test data.
Returns predictions for the given test data.
Parameters
----------
X : array-like, shape = (n_samples, n_features)
Test samples where n_samples in the number of samples
and n_features is the number of features.
batch_size : int, optional
Number of test samples evaluated at a time.
verbose : int, optional
Verbosity level.
Returns
-------
preds : array-like, shape = (n_samples)
Class predictions.
Predictions.
"""
return self.compiled_model_.predict_classes(X, batch_size=batch_size, verbose=verbose)
return self.compiled_model_.predict(
X, batch_size=self.test_batch_size, verbose=self.verbose).ravel()
def predict_proba(self, X, batch_size=128, verbose=0):
def score(self, X, y):
"""
Returns class probability estimates for the given test data.
Returns the mean accuracy on the given test data and labels.
Parameters
----------
X : array-like, shape = (n_samples, n_features)
Test samples where n_samples in the number of samples
and n_features is the number of features.
batch_size : int, optional
Number of test samples evaluated at a time.
verbose : int, optional
Verbosity level.
y : array-like, shape = (n_samples)
True labels for X.
Returns
-------
proba : array-like, shape = (n_samples, n_outputs)
Class probability estimates.
score : float
Loss from predictions on X wrt. y.
"""
return self.compiled_model_.predict_proba(X, batch_size=batch_size, verbose=verbose)
loss = self.compiled_model_.evaluate(
X, y, batch_size=self.test_batch_size, show_accuracy=False, verbose=self.verbose)
return loss
+2
Ver Arquivo
@@ -0,0 +1,2 @@
[metadata]
description-file = README.md
+9 -5
Ver Arquivo
@@ -1,13 +1,17 @@
from setuptools import setup
from setuptools import find_packages
setup(name='Keras',
version='0.0.1',
description='Theano-based Deep Learning',
version='0.2.0',
description='Theano-based Deep Learning library',
author='Francois Chollet',
author_email='francois.chollet@gmail.com',
url='https://github.com/fchollet/keras',
download_url='https://github.com/fchollet/keras/tarball/0.2.0',
license='MIT',
install_requires=['theano'],
packages=find_packages(),
)
install_requires=['theano', 'pyyaml', 'six'],
extras_require={
'h5py': ['h5py'],
},
packages=find_packages())
-139
Ver Arquivo
@@ -1,139 +0,0 @@
from __future__ import absolute_import
from __future__ import print_function
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import DenoisingAutoEncoder, AutoEncoder, Dense, Activation, TimeDistributedDense, Flatten
from keras.layers.recurrent import LSTM
from keras.layers.embeddings import Embedding
from keras.layers.core import Layer
from keras.layers import containers
from keras.utils import np_utils
import numpy as np
# Try different things here: 'lstm' or 'classical' or 'denoising'
autoencoder_type = 'denoising'
nb_classes = 10
batch_size = 128
nb_epoch = 5
activation = 'linear'
input_dim = 784
hidden_dim = 392
max_train_samples = 5000
max_test_samples = 1000
# the data, shuffled and split between tran and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(60000, input_dim)[:max_train_samples]
X_test = X_test.reshape(10000, input_dim)[:max_test_samples]
X_train = X_train.astype("float32")
X_test = X_test.astype("float32")
X_train /= 255
X_test /= 255
# convert class vectors to binary class matrices
Y_train = np_utils.to_categorical(y_train, nb_classes)[:max_train_samples]
Y_test = np_utils.to_categorical(y_test, nb_classes)[:max_test_samples]
print("X_train: ", X_train.shape)
print("X_test: ", X_test.shape)
##########################
# dense model test #
##########################
print("Training classical fully connected layer for classification")
model_classical = Sequential()
model_classical.add(Dense(input_dim, 10, activation=activation))
model_classical.add(Activation('softmax'))
model_classical.get_config(verbose=1)
model_classical.compile(loss='categorical_crossentropy', optimizer='adam')
model_classical.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=0, validation_data=(X_test, Y_test))
classical_score = model_classical.evaluate(X_test, Y_test, verbose=0, show_accuracy=True)
print('\nclassical_score:', classical_score)
##########################
# autoencoder model test #
##########################
def build_lstm_autoencoder(autoencoder, X_train, X_test):
X_train = X_train[:, np.newaxis, :]
X_test = X_test[:, np.newaxis, :]
print("Modified X_train: ", X_train.shape)
print("Modified X_test: ", X_test.shape)
# The TimeDistributedDense isn't really necessary, however you need a lot of GPU memory to do 784x394-394x784
autoencoder.add(TimeDistributedDense(input_dim, 16))
autoencoder.add(AutoEncoder(encoder=LSTM(16, 8, activation=activation, return_sequences=True),
decoder=LSTM(8, input_dim, activation=activation, return_sequences=True),
output_reconstruction=False, tie_weights=True))
return autoencoder, X_train, X_test
def build_deep_classical_autoencoder(autoencoder):
encoder = containers.Sequential([Dense(input_dim, hidden_dim, activation=activation), Dense(hidden_dim, hidden_dim/2, activation=activation)])
decoder = containers.Sequential([Dense(hidden_dim/2, hidden_dim, activation=activation), Dense(hidden_dim, input_dim, activation=activation)])
autoencoder.add(AutoEncoder(encoder=encoder, decoder=decoder, output_reconstruction=False, tie_weights=True))
return autoencoder
def build_denoising_autoencoder(autoencoder):
# You need another layer before a denoising autoencoder
# This is similar to the dropout layers, etc..
autoencoder.add(Dense(input_dim, input_dim))
autoencoder.add(DenoisingAutoEncoder(encoder=Dense(input_dim, hidden_dim, activation=activation),
decoder=Dense(hidden_dim, input_dim, activation=activation),
output_reconstruction=False, tie_weights=True, corruption_level=0.3))
return autoencoder
# Build our autoencoder model
autoencoder = Sequential()
if autoencoder_type == 'lstm':
print("Training LSTM AutoEncoder")
autoencoder, X_train, X_test = build_lstm_autoencoder(autoencoder, X_train, X_test)
elif autoencoder_type == 'denoising':
print("Training Denoising AutoEncoder")
autoencoder = build_denoising_autoencoder(autoencoder)
elif autoencoder_type == 'classical':
print("Training Classical AutoEncoder")
autoencoder = build_deep_classical_autoencoder(autoencoder)
else:
print("Error: unknown autoencoder type!")
exit(-1)
autoencoder.get_config(verbose=1)
autoencoder.compile(loss='mean_squared_error', optimizer='adam')
# Do NOT use validation data with return output_reconstruction=True
autoencoder.fit(X_train, X_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=1)
# Do an inference pass
prefilter_train = autoencoder.predict(X_train, verbose=0)
prefilter_test = autoencoder.predict(X_test, verbose=0)
print("prefilter_train: ", prefilter_train.shape)
print("prefilter_test: ", prefilter_test.shape)
# Classify results from Autoencoder
print("Building classical fully connected layer for classification")
model = Sequential()
if autoencoder_type == 'lstm':
model.add(TimeDistributedDense(8, nb_classes, activation=activation))
model.add(Flatten())
elif autoencoder_type == 'classical':
model.add(Dense(prefilter_train.shape[1], nb_classes, activation=activation))
else:
model.add(Dense(prefilter_train.shape[1], nb_classes, activation=activation))
model.add(Activation('softmax'))
model.get_config(verbose=1)
model.compile(loss='categorical_crossentropy', optimizer='adam')
model.fit(prefilter_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=0, validation_data=(prefilter_test, Y_test))
score = model.evaluate(prefilter_test, Y_test, verbose=0, show_accuracy=True)
print('\nscore:', score)
print('Loss change:', (score[0] - classical_score[0])/classical_score[0], '%')
print('Accuracy change:', (score[1] - classical_score[1])/classical_score[1], '%')
-226
Ver Arquivo
@@ -1,226 +0,0 @@
import numpy as np
import random
import theano
from keras.models import Sequential
from keras.callbacks import Callback
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.regularizers import l2
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.utils import np_utils
from keras.datasets import mnist
import keras.callbacks as cbks
from matplotlib import pyplot as plt
from matplotlib import animation
##############################
# model DrawActivations test #
##############################
print('Running DrawActivations test')
nb_classes = 10
batch_size = 128
nb_epoch = 10
max_train_samples = 512
max_test_samples = 1
np.random.seed(1337)
# the data, shuffled and split between tran and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(-1,1,28,28)[:max_train_samples]
X_train = X_train.astype("float32")
X_train /= 255
X_test = X_test.reshape(-1,1,28,28)[:max_test_samples]
X_test = X_test.astype("float32")
X_test /= 255
# convert class vectors to binary class matrices
Y_train = np_utils.to_categorical(y_train, nb_classes)[:max_train_samples]
class Frames(object):
def __init__(self, n_plots=16):
self._n_frames = 0
self._framedata = []
self._titles = []
for i in range(n_plots):
self._framedata.append([])
def add_frame(self, i, frame):
self._framedata[i].append(frame)
def set_title(self, title):
self._titles.append(title)
class SubplotTimedAnimation(animation.TimedAnimation):
def __init__(self, fig, frames, grid=(4, 4), interval=10, blit=False, **kwargs):
self.n_plots = grid[0] * grid[1]
self.axes = [fig.add_subplot(grid[0], grid[1], i + 1) for i in range(self.n_plots)]
for axis in self.axes:
axis.get_xaxis().set_ticks([])
axis.get_yaxis().set_ticks([])
self.frames = frames
self.imgs = [self.axes[i].imshow(frames._framedata[i][0], interpolation='nearest', cmap='bone') for i in range(self.n_plots)]
self.title = fig.suptitle('')
super(SubplotTimedAnimation, self).__init__(fig, interval=interval, blit=blit, **kwargs)
def _draw_frame(self, j):
for i in range(self.n_plots):
self.imgs[i].set_data(self.frames._framedata[i][j])
if len(self.frames._titles) > j:
self.title.set_text(self.frames._titles[j])
self._drawn_artists = self.imgs
def new_frame_seq(self):
return iter(range(len(self.frames._framedata[0])))
def _init_draw(self):
for img in self.imgs:
img.set_data([[]])
def combine_imgs(imgs, grid=(1,1)):
n_imgs, img_h, img_w = imgs.shape
if n_imgs != grid[0] * grid[1]:
raise ValueError()
combined = np.zeros((grid[0] * img_h, grid[1] * img_w))
for i in range(grid[0]):
for j in range(grid[1]):
combined[img_h*i:img_h*(i+1),img_w*j:img_w*(j+1)] = imgs[grid[0] * i + j]
return combined
class DrawActivations(Callback):
def __init__(self, figsize):
self.fig = plt.figure(figsize=figsize)
def on_train_begin(self, logs={}):
self.imgs = Frames(n_plots=5)
layers_0_ids = np.random.choice(32, 16, replace=False)
self.test_layer0 = theano.function([self.model.get_input()], self.model.layers[1].get_output(train=False)[0, layers_0_ids])
layers_1_ids = np.random.choice(64, 36, replace=False)
self.test_layer1 = theano.function([self.model.get_input()], self.model.layers[5].get_output(train=False)[0, layers_1_ids])
self.test_layer2 = theano.function([self.model.get_input()], self.model.layers[10].get_output(train=False)[0])
def on_epoch_begin(self, epoch, logs={}):
self.epoch = epoch
def on_batch_end(self, batch, logs={}):
if batch % 5 == 0:
self.imgs.add_frame(0, X_test[0,0])
self.imgs.add_frame(1, combine_imgs(self.test_layer0(X_test), grid=(4, 4)))
self.imgs.add_frame(2, combine_imgs(self.test_layer1(X_test), grid=(6, 6)))
self.imgs.add_frame(3, self.test_layer2(X_test).reshape((16,16)))
self.imgs.add_frame(4, self.model._predict(X_test)[0].reshape((1,10)))
self.imgs.set_title('Epoch #%d - Batch #%d' % (self.epoch, batch))
def on_train_end(self, logs={}):
anim = SubplotTimedAnimation(self.fig, self.imgs, grid=(1,5), interval=10, blit=False, repeat_delay=1000)
# anim.save('test_gif.gif', fps=15, writer='imagemagick')
plt.show()
# model = Sequential()
# model.add(Dense(784, 50))
# model.add(Activation('relu'))
# model.add(Dense(50, 10))
# model.add(Activation('softmax'))
model = Sequential()
model.add(Convolution2D(32, 1, 3, 3, border_mode='full'))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
model.add(Dropout(0.25))
model.add(Convolution2D(64, 32, 3, 3, border_mode='full'))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(64*8*8, 256))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(256, 10, W_regularizer = l2(0.1)))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
# Fit the model
draw_weights = DrawActivations(figsize=(5.4, 1.35))
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=1, callbacks=[draw_weights])
##########################
# model checkpoint tests #
##########################
print('Running ModelCheckpoint test')
nb_classes = 10
batch_size = 128
nb_epoch = 20
# small sample size to overfit on training data
max_train_samples = 50
max_test_samples = 1000
np.random.seed(1337) # for reproducibility
# the data, shuffled and split between tran and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(60000,784)[:max_train_samples]
X_test = X_test.reshape(10000,784)[:max_test_samples]
X_train = X_train.astype("float32")
X_test = X_test.astype("float32")
X_train /= 255
X_test /= 255
# convert class vectors to binary class matrices
Y_train = np_utils.to_categorical(y_train, nb_classes)[:max_train_samples]
Y_test = np_utils.to_categorical(y_test, nb_classes)[:max_test_samples]
# Create a slightly larger network than required to test best validation save only
model = Sequential()
model.add(Dense(784, 500))
model.add(Activation('relu'))
model.add(Dense(500, 10))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
# test file location
path = "/tmp"
filename = "model_weights.hdf5"
import os
f = os.path.join(path, filename)
print("Test model checkpointer")
# only store best validation model in checkpointer
checkpointer = cbks.ModelCheckpoint(filepath=f, verbose=1, save_best_only=True)
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=True, verbose=0, validation_data=(X_test, Y_test), callbacks =[checkpointer])
if not os.path.isfile(f):
raise Exception("Model weights were not saved to %s" % (f))
print("Test model checkpointer without validation data")
import warnings
warnings.filterwarnings('error')
try:
# this should issue a warning
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=True, verbose=0, callbacks =[checkpointer])
except:
print("Tests passed")
import sys
sys.exit(0)
raise Exception("Modelcheckpoint tests did not pass")
-100
Ver Arquivo
@@ -1,100 +0,0 @@
from __future__ import absolute_import
from __future__ import print_function
import keras
from keras.datasets import mnist
import keras.models
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.regularizers import l2, l1
from keras.constraints import maxnorm, nonneg
from keras.optimizers import SGD, Adam, RMSprop
from keras.utils import np_utils, generic_utils
import theano
import theano.tensor as T
import numpy as np
import scipy
batch_size = 100
nb_classes = 10
nb_epoch = 10
# the data, shuffled and split between tran and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train=X_train.reshape(60000,784)
X_test=X_test.reshape(10000,784)
X_train = X_train.astype("float32")
X_test = X_test.astype("float32")
X_train /= 255
X_test /= 255
# convert class vectors to binary class matrices
Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)
model = Sequential()
model.add(Dense(784, 20, W_constraint=maxnorm(1)))
model.add(Activation('relu'))
model.add(Dropout(0.1))
model.add(Dense(20, 20, W_constraint=nonneg))
model.add(Activation('relu'))
model.add(Dropout(0.1))
model.add(Dense(20, 10, W_constraint=maxnorm(1)))
model.add(Activation('softmax'))
rms = RMSprop()
model.compile(loss='categorical_crossentropy', optimizer=rms)
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=True, verbose=0)
a=model.params[0].eval()
if np.isclose(np.max(np.sqrt(np.sum(a**2, axis=0))),1):
print('Maxnorm test passed')
else:
raise ValueError('Maxnorm test failed!')
b=model.params[2].eval()
if np.min(b)==0 and np.min(a)!=0:
print('Nonneg test passed')
else:
raise ValueError('Nonneg test failed!')
model = Sequential()
model.add(Dense(784, 20))
model.add(Activation('relu'))
model.add(Dense(20, 20, W_regularizer=l1(.01)))
model.add(Activation('relu'))
model.add(Dense(20, 10))
model.add(Activation('softmax'))
rms = RMSprop()
model.compile(loss='categorical_crossentropy', optimizer=rms)
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=20, show_accuracy=True, verbose=0)
a=model.params[2].eval().reshape(400)
(D, p1) = scipy.stats.kurtosistest(a)
model = Sequential()
model.add(Dense(784, 20))
model.add(Activation('relu'))
model.add(Dense(20, 20, W_regularizer=l2(.01)))
model.add(Activation('relu'))
model.add(Dense(20, 10))
model.add(Activation('softmax'))
rms = RMSprop()
model.compile(loss='categorical_crossentropy', optimizer=rms)
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=20, show_accuracy=True, verbose=0)
a=model.params[2].eval().reshape(400)
(D, p2) = scipy.stats.kurtosistest(a)
if p1<.01 and p2>.01:
print('L1 and L2 regularization tests passed')
else:
raise ValueError('L1 and L2 regularization tests failed!')
-27
Ver Arquivo
@@ -1,27 +0,0 @@
from keras.utils.dot_utils import Grapher
from keras.models import Sequential
from keras.layers.core import Dense, Activation, Merge, Flatten
from keras.layers.embeddings import Embedding
from keras.layers.recurrent import GRU
ent_lookup = Sequential()
ent_lookup.add(Embedding(10, 2))
ent_lookup.add(Flatten())
rel_lookup = Sequential()
rel_lookup.add(Embedding(20, 2))
rel_lookup.add(Flatten())
word_sequence = Sequential()
word_sequence.add(Embedding(10, 5))
word_sequence.add(GRU(5, 2))
model = Sequential()
model.add(Merge([word_sequence, ent_lookup, rel_lookup], mode='concat'))
model.add(Activation('relu'))
model.add(Dense(6, 2))
model.add(Activation('softmax'))
g = Grapher()
g.plot(model, 'mymodel.png')
-184
Ver Arquivo
@@ -1,184 +0,0 @@
from __future__ import absolute_import
from __future__ import print_function
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import Dense, Activation, Merge
from keras.utils import np_utils
import numpy as np
nb_classes = 10
batch_size = 128
nb_epoch = 1
max_train_samples = 5000
max_test_samples = 1000
np.random.seed(1337) # for reproducibility
# the data, shuffled and split between tran and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(60000,784)[:max_train_samples]
X_test = X_test.reshape(10000,784)[:max_test_samples]
X_train = X_train.astype("float32")
X_test = X_test.astype("float32")
X_train /= 255
X_test /= 255
# convert class vectors to binary class matrices
Y_train = np_utils.to_categorical(y_train, nb_classes)[:max_train_samples]
Y_test = np_utils.to_categorical(y_test, nb_classes)[:max_test_samples]
#########################
# sequential model test #
#########################
print('Test sequential')
model = Sequential()
model.add(Dense(784, 50))
model.add(Activation('relu'))
model.add(Dense(50, 10))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=True, verbose=0, validation_data=(X_test, Y_test))
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=0, validation_data=(X_test, Y_test))
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=True, verbose=0, validation_split=0.1)
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=0, validation_split=0.1)
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=0)
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=0, shuffle=False)
score = model.evaluate(X_train, Y_train, verbose=0)
print('score:', score)
if score < 0.25:
raise Exception('Score too low, learning issue.')
preds = model.predict(X_test, verbose=0)
classes = model.predict_classes(X_test, verbose=0)
model.get_config(verbose=1)
###################
# merge test: sum #
###################
print('Test merge: sum')
left = Sequential()
left.add(Dense(784, 50))
left.add(Activation('relu'))
right = Sequential()
right.add(Dense(784, 50))
right.add(Activation('relu'))
model = Sequential()
model.add(Merge([left, right], mode='sum'))
model.add(Dense(50, 10))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
model.fit([X_train, X_train], Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=True, verbose=0, validation_data=([X_test, X_test], Y_test))
model.fit([X_train, X_train], Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=0, validation_data=([X_test, X_test], Y_test))
model.fit([X_train, X_train], Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=True, verbose=0, validation_split=0.1)
model.fit([X_train, X_train], Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=0, validation_split=0.1)
model.fit([X_train, X_train], Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=0)
model.fit([X_train, X_train], Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=0, shuffle=False)
score = model.evaluate([X_train, X_train], Y_train, verbose=0)
print('score:', score)
if score < 0.22:
raise Exception('Score too low, learning issue.')
preds = model.predict([X_test, X_test], verbose=0)
classes = model.predict_classes([X_test, X_test], verbose=0)
model.get_config(verbose=1)
###################
# merge test: concat #
###################
print('Test merge: concat')
left = Sequential()
left.add(Dense(784, 50))
left.add(Activation('relu'))
right = Sequential()
right.add(Dense(784, 50))
right.add(Activation('relu'))
model = Sequential()
model.add(Merge([left, right], mode='concat'))
model.add(Dense(50*2, 10))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
model.fit([X_train, X_train], Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=True, verbose=0, validation_data=([X_test, X_test], Y_test))
model.fit([X_train, X_train], Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=0, validation_data=([X_test, X_test], Y_test))
model.fit([X_train, X_train], Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=True, verbose=0, validation_split=0.1)
model.fit([X_train, X_train], Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=0, validation_split=0.1)
model.fit([X_train, X_train], Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=0)
model.fit([X_train, X_train], Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=0, shuffle=False)
score = model.evaluate([X_train, X_train], Y_train, verbose=0)
print('score:', score)
if score < 0.22:
raise Exception('Score too low, learning issue.')
preds = model.predict([X_test, X_test], verbose=0)
classes = model.predict_classes([X_test, X_test], verbose=0)
model.get_config(verbose=1)
##########################
# test merge recursivity #
##########################
print('Test merge recursivity')
left = Sequential()
left.add(Dense(784, 50))
left.add(Activation('relu'))
right = Sequential()
right.add(Dense(784, 50))
right.add(Activation('relu'))
righter = Sequential()
righter.add(Dense(784, 50))
righter.add(Activation('relu'))
intermediate = Sequential()
intermediate.add(Merge([left, right], mode='sum'))
intermediate.add(Dense(50, 50))
intermediate.add(Activation('relu'))
model = Sequential()
model.add(Merge([intermediate, righter], mode='sum'))
model.add(Dense(50, 10))
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, nb_epoch=nb_epoch, show_accuracy=True, 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, nb_epoch=nb_epoch, show_accuracy=False, 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, nb_epoch=nb_epoch, show_accuracy=True, verbose=0, validation_split=0.1)
model.fit([X_train, X_train, X_train], Y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=0, validation_split=0.1)
model.fit([X_train, X_train, X_train], Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=0)
model.fit([X_train, X_train, X_train], Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=0, shuffle=False)
score = model.evaluate([X_train, X_train, X_train], Y_train, verbose=0)
print('score:', score)
if score < 0.19:
raise Exception('Score too low, learning issue.')
preds = model.predict([X_test, X_test, X_test], verbose=0)
classes = model.predict_classes([X_test, X_test, X_test], verbose=0)
model.get_config(verbose=1)
model.save_weights('temp.h5')
model.load_weights('temp.h5')
score = model.evaluate([X_train, X_train, X_train], Y_train, verbose=0)
print('score:', score)
-40
Ver Arquivo
@@ -1,40 +0,0 @@
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.optimizers import SGD
import sys
sys.setrecursionlimit(10000) # to be able to pickle Theano compiled functions
import pickle, numpy
def create_model():
model = Sequential()
model.add(Dense(256, 2048, init='uniform', activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2048, 2048, init='uniform', activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2048, 2048, init='uniform', activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2048, 2048, init='uniform', activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2048, 256, init='uniform', activation='linear'))
return model
model = create_model()
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='mse', optimizer=sgd)
pickle.dump(model, open('/tmp/model.pkl', 'wb'))
model.save_weights('/tmp/model_weights.hdf5')
model_loaded = create_model()
model_loaded.load_weights('/tmp/model_weights.hdf5')
for k in range(len(model.layers)):
weights_orig = model.layers[k].get_weights()
weights_loaded = model_loaded.layers[k].get_weights()
for x, y in zip(weights_orig, weights_loaded):
if numpy.any(x != y):
raise ValueError('Loaded weights are different from pickled weights!')
-77
Ver Arquivo
@@ -1,77 +0,0 @@
from __future__ import absolute_import
from __future__ import print_function
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.utils import np_utils
from keras.wrappers.scikit_learn import KerasClassifier
import numpy as np
nb_classes = 10
batch_size = 128
nb_epoch = 1
max_train_samples = 5000
max_test_samples = 1000
np.random.seed(1337) # for reproducibility
# the data, shuffled and split between tran and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(60000,784)[:max_train_samples]
X_test = X_test.reshape(10000,784)[:max_test_samples]
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255
Y_train = np_utils.to_categorical(y_train, nb_classes)[:max_train_samples]
Y_test = np_utils.to_categorical(y_test, nb_classes)[:max_test_samples]
#############################
# scikit-learn wrapper test #
#############################
print('Beginning scikit-learn wrapper test')
print('Defining model')
model = Sequential()
model.add(Dense(784, 50))
model.add(Activation('relu'))
model.add(Dense(50, 10))
model.add(Activation('softmax'))
print('Creating wrapper')
classifier = KerasClassifier(model)
print('Fitting model')
classifier.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch)
print('Testing score function')
score = classifier.score(X_train, Y_train)
print('Score: ', score)
print('Testing predict function')
preds = classifier.predict(X_test)
print('Preds.shape: ', preds.shape)
print('Testing predict proba function')
proba = classifier.predict_proba(X_test)
print('Proba.shape: ', proba.shape)
print('Testing get params')
print(classifier.get_params())
print('Testing set params')
classifier.set_params(optimizer='sgd', loss='mse')
print(classifier.get_params())
print('Testing attributes')
print('Classes')
print(classifier.classes_)
print('Config')
print(classifier.config_)
print('Weights')
print(classifier.weights_)
print('Test script complete.')
+335
Ver Arquivo
@@ -0,0 +1,335 @@
import sys
import unittest
from numpy.testing import assert_allclose
import numpy as np
import pytest
if sys.version_info.major == 2:
from keras.backend import theano_backend as KTH
from keras.backend import tensorflow_backend as KTF
def check_single_tensor_operation(function_name, input_shape, **kwargs):
val = np.random.random(input_shape) - 0.5
xth = KTH.variable(val)
xtf = KTF.variable(val)
zth = KTH.eval(getattr(KTH, function_name)(xth, **kwargs))
ztf = KTF.eval(getattr(KTF, function_name)(xtf, **kwargs))
assert zth.shape == ztf.shape
assert_allclose(zth, ztf, atol=1e-06)
def check_two_tensor_operation(function_name, x_input_shape,
y_input_shape, **kwargs):
xval = np.random.random(x_input_shape) - 0.5
xth = KTH.variable(xval)
xtf = KTF.variable(xval)
yval = np.random.random(y_input_shape) - 0.5
yth = KTH.variable(yval)
ytf = KTF.variable(yval)
zth = KTH.eval(getattr(KTH, function_name)(xth, yth, **kwargs))
ztf = KTF.eval(getattr(KTF, function_name)(xtf, ytf, **kwargs))
assert zth.shape == ztf.shape
assert_allclose(zth, ztf, atol=1e-06)
@pytest.mark.skipif(sys.version_info.major != 2, reason="Requires Python 2.7")
class TestBackend(unittest.TestCase):
def test_linear_operations(self):
check_two_tensor_operation('dot', (4, 2), (2, 4))
check_single_tensor_operation('transpose', (4, 2))
def test_shape_operations(self):
# concatenate
xval = np.random.random((4, 3))
xth = KTH.variable(xval)
xtf = KTF.variable(xval)
yval = np.random.random((4, 2))
yth = KTH.variable(yval)
ytf = KTF.variable(yval)
zth = KTH.eval(KTH.concatenate([xth, yth], axis=-1))
ztf = KTF.eval(KTF.concatenate([xtf, ytf], axis=-1))
assert zth.shape == ztf.shape
assert_allclose(zth, ztf, atol=1e-06)
check_single_tensor_operation('reshape', (4, 2), shape=(8, 1))
check_single_tensor_operation('permute_dimensions', (4, 2, 3),
pattern=(2, 0, 1))
check_single_tensor_operation('repeat', (4, 1), n=3)
check_single_tensor_operation('flatten', (4, 1))
check_single_tensor_operation('expand_dims', (4, 3), dim=-1)
check_single_tensor_operation('expand_dims', (4, 3, 2), dim=1)
check_single_tensor_operation('squeeze', (4, 3, 1), axis=2)
def test_value_manipulation(self):
val = np.random.random((4, 2))
xth = KTH.variable(val)
xtf = KTF.variable(val)
# get_value
valth = KTH.get_value(xth)
valtf = KTF.get_value(xtf)
assert valtf.shape == valth.shape
assert_allclose(valth, valtf, atol=1e-06)
# set_value
val = np.random.random((4, 2))
KTH.set_value(xth, val)
KTF.set_value(xtf, val)
valth = KTH.get_value(xth)
valtf = KTF.get_value(xtf)
assert valtf.shape == valth.shape
assert_allclose(valth, valtf, atol=1e-06)
# count_params
assert KTH.count_params(xth) == KTF.count_params(xtf)
def test_elementwise_operations(self):
check_single_tensor_operation('max', (4, 2))
check_single_tensor_operation('max', (4, 2), axis=1, keepdims=True)
check_single_tensor_operation('min', (4, 2))
check_single_tensor_operation('min', (4, 2), axis=1, keepdims=True)
check_single_tensor_operation('mean', (4, 2))
check_single_tensor_operation('mean', (4, 2), axis=1, keepdims=True)
check_single_tensor_operation('mean', (4, 2, 3), axis=-1, keepdims=True)
check_single_tensor_operation('std', (4, 2))
check_single_tensor_operation('std', (4, 2), axis=1, keepdims=True)
check_single_tensor_operation('prod', (4, 2))
check_single_tensor_operation('prod', (4, 2), axis=1, keepdims=True)
# does not work yet, wait for bool <-> int casting in TF (coming soon)
# check_single_tensor_operation('any', (4, 2))
# check_single_tensor_operation('any', (4, 2), axis=1, keepdims=True)
check_single_tensor_operation('argmax', (4, 2))
check_single_tensor_operation('argmax', (4, 2), axis=1)
check_single_tensor_operation('argmin', (4, 2))
check_single_tensor_operation('argmin', (4, 2), axis=1)
check_single_tensor_operation('square', (4, 2))
check_single_tensor_operation('abs', (4, 2))
check_single_tensor_operation('sqrt', (4, 2))
check_single_tensor_operation('exp', (4, 2))
check_single_tensor_operation('log', (4, 2))
check_single_tensor_operation('round', (4, 2))
check_single_tensor_operation('pow', (4, 2), a=3)
check_single_tensor_operation('clip', (4, 2), min_value=0.4,
max_value=0.6)
# two-tensor ops
check_two_tensor_operation('equal', (4, 2), (4, 2))
check_two_tensor_operation('maximum', (4, 2), (4, 2))
check_two_tensor_operation('minimum', (4, 2), (4, 2))
def test_gradient(self):
val = np.random.random((4, 2))
xth = KTH.variable(val)
xtf = KTF.variable(val)
expth = xth * KTH.exp(xth)
exptf = xtf * KTF.exp(xtf)
lossth = KTH.sum(expth)
losstf = KTF.sum(exptf)
gradth = KTH.gradients(lossth, [expth])
gradtf = KTF.gradients(losstf, [exptf])
zth = KTH.eval(gradth[0])
ztf = KTF.eval(gradtf[0])
assert zth.shape == ztf.shape
assert_allclose(zth, ztf, atol=1e-06)
def test_function(self):
val = np.random.random((4, 2))
input_val = np.random.random((4, 2))
xth = KTH.variable(val)
xtf = KTF.variable(val)
yth = KTH.placeholder(ndim=2)
ytf = KTF.placeholder(ndim=2)
exp_th = KTH.square(xth) + yth
exp_tf = KTF.square(xtf) + ytf
update_th = xth * 2
update_tf = xtf * 2
fth = KTH.function([yth], [exp_th], updates=[(xth, update_th)])
ftf = KTF.function([ytf], [exp_tf], updates=[(xtf, update_tf)])
function_outputs_th = fth([input_val])[0]
function_outputs_tf = ftf([input_val])[0]
assert function_outputs_th.shape == function_outputs_tf.shape
assert_allclose(function_outputs_th, function_outputs_tf, atol=1e-06)
new_val_th = KTH.get_value(xth)
new_val_tf = KTF.get_value(xtf)
assert new_val_th.shape == new_val_tf.shape
assert_allclose(new_val_th, new_val_tf, atol=1e-06)
def test_rnn(self):
# implement a simple RNN
input_dim = 8
output_dim = 4
timesteps = 5
input_val = np.random.random((32, timesteps, input_dim))
init_state_val = np.random.random((32, output_dim))
W_i_val = np.random.random((input_dim, output_dim))
W_o_val = np.random.random((output_dim, output_dim))
def rnn_step_fn(input_dim, output_dim, K):
W_i = K.variable(W_i_val)
W_o = K.variable(W_o_val)
def step_function(x, states):
assert len(states) == 1
prev_output = states[0]
output = K.dot(x, W_i) + K.dot(prev_output, W_o)
return output, [output]
return step_function
th_rnn_step_fn = rnn_step_fn(input_dim, output_dim, KTH)
inputs = KTH.variable(input_val)
initial_states = [KTH.variable(init_state_val)]
last_output, outputs, new_states = KTH.rnn(th_rnn_step_fn, inputs,
initial_states,
go_backwards=False,
masking=False)
th_last_output = KTH.eval(last_output)
th_outputs = KTH.eval(outputs)
assert len(new_states) == 1
th_state = KTH.eval(new_states[0])
tf_rnn_step_fn = rnn_step_fn(input_dim, output_dim, KTF)
inputs = KTF.variable(input_val)
initial_states = [KTF.variable(init_state_val)]
last_output, outputs, new_states = KTF.rnn(tf_rnn_step_fn, inputs,
initial_states,
go_backwards=False,
masking=False)
tf_last_output = KTF.eval(last_output)
tf_outputs = KTF.eval(outputs)
assert len(new_states) == 1
tf_state = KTF.eval(new_states[0])
assert_allclose(tf_last_output, th_last_output, atol=1e-06)
assert_allclose(tf_outputs, th_outputs, atol=1e-06)
assert_allclose(tf_state, th_state, atol=1e-06)
def test_switch(self):
val = np.random.random()
xth = KTH.variable(val)
xth = KTH.switch(xth >= 0.5, xth * 0.1, xth * 0.2)
xtf = KTF.variable(val)
xtf = KTF.switch(xtf >= 0.5, xtf * 0.1, xtf * 0.2)
zth = KTH.eval(xth)
ztf = KTF.eval(xtf)
assert zth.shape == ztf.shape
assert_allclose(zth, ztf, atol=1e-06)
def test_nn_operations(self):
check_single_tensor_operation('relu', (4, 2), alpha=0.1, max_value=0.5)
check_single_tensor_operation('softmax', (4, 10))
check_single_tensor_operation('softplus', (4, 10))
check_single_tensor_operation('sigmoid', (4, 2))
check_single_tensor_operation('hard_sigmoid', (4, 2))
check_single_tensor_operation('tanh', (4, 2))
# dropout
val = np.random.random((20, 20))
xth = KTH.variable(val)
xtf = KTF.variable(val)
zth = KTH.eval(KTH.dropout(xth, level=0.2))
ztf = KTF.eval(KTF.dropout(xtf, level=0.2))
assert zth.shape == ztf.shape
# dropout patterns are different, only check mean
assert np.abs(zth.mean() - ztf.mean()) < 0.05
check_two_tensor_operation('binary_crossentropy', (4, 2), (4, 2), from_logits=True)
check_two_tensor_operation('categorical_crossentropy', (4, 2), (4, 2), from_logits=True)
check_two_tensor_operation('binary_crossentropy', (4, 2), (4, 2), from_logits=False)
check_two_tensor_operation('categorical_crossentropy', (4, 2), (4, 2), from_logits=False)
# def test_conv2d(self):
# '''conv2d works "properly" with Theano and TF but outputs different
# values in each case. Cause unclear (input / kernel shape format?)
# '''
# # TH kernel shape: (depth, input_depth, rows, cols)
# check_two_tensor_operation('conv2d', (5, 3, 10, 12), (4, 3, 2, 2),
# strides=(1, 1), border_mode='valid')
# check_two_tensor_operation('conv2d', (5, 3, 10, 12), (4, 3, 2, 2),
# strides=(1, 1), border_mode='same')
# # TF kernel shape: (rows, cols, input_depth, depth)
# check_two_tensor_operation('conv2d', (5, 10, 12, 3), (2, 2, 3, 4),
# strides=(1, 1), border_mode='valid', dim_ordering='tf')
# check_two_tensor_operation('conv2d', (5, 10, 12, 3), (2, 2, 3, 4),
# strides=(1, 1), border_mode='same', dim_ordering='tf')
# check_two_tensor_operation('conv2d', (5, 3, 10, 12), (4, 3, 3, 3),
# strides=(1, 1), border_mode='valid')
# check_two_tensor_operation('conv2d', (5, 3, 10, 12), (4, 3, 3, 3),
# strides=(1, 1), border_mode='same')
# check_two_tensor_operation('conv2d', (5, 3, 10, 12), (4, 3, 3, 3),
# strides=(2, 2), border_mode='valid')
# def test_maxpool2d(self):
# '''maxpool2d works "properly" with Theano and TF but outputs different
# values in each case. Cause unclear (input shape format?)
# '''
# check_single_tensor_operation('maxpool2d', (5, 3, 10, 12), pool_size=(2, 2),
# strides=(1, 1), border_mode='valid')
# check_single_tensor_operation('maxpool2d', (5, 3, 9, 11), pool_size=(2, 2),
# strides=(1, 1), border_mode='valid')
# check_single_tensor_operation('maxpool2d', (5, 3, 9, 11), pool_size=(2, 3),
# strides=(1, 1), border_mode='valid')
def test_random_normal(self):
mean = 0.
std = 1.
rand = KTF.get_value(KTF.random_normal((1000, 1000), mean=mean, std=std))
assert(rand.shape == (1000, 1000))
assert(np.abs(np.mean(rand) - mean) < 0.01)
assert(np.abs(np.std(rand) - std) < 0.01)
rand = KTF.get_value(KTF.random_normal((1000, 1000), mean=mean, std=std))
assert(rand.shape == (1000, 1000))
assert(np.abs(np.mean(rand) - mean) < 0.01)
assert(np.abs(np.std(rand) - std) < 0.01)
def test_random_uniform(self):
mean = 0.
std = 1.
rand = KTF.get_value(KTF.random_normal((1000, 1000), mean=mean, std=std))
assert(rand.shape == (1000, 1000))
assert(np.abs(np.mean(rand) - mean) < 0.01)
assert(np.abs(np.std(rand) - std) < 0.01)
rand = KTF.get_value(KTF.random_normal((1000, 1000), mean=mean, std=std))
assert(rand.shape == (1000, 1000))
assert(np.abs(np.mean(rand) - mean) < 0.01)
assert(np.abs(np.std(rand) - std) < 0.01)
if __name__ == '__main__':
unittest.main()
+166
Ver Arquivo
@@ -0,0 +1,166 @@
import unittest
import numpy as np
from numpy.testing import assert_allclose
from keras import backend as K
from keras.layers import convolutional
class TestConvolutions(unittest.TestCase):
def test_convolution_1d(self):
nb_samples = 9
nb_steps = 7
input_dim = 10
filter_length = 6
nb_filter = 5
weights_in = [np.ones((nb_filter, input_dim, filter_length, 1)),
np.ones(nb_filter)]
input = np.ones((nb_samples, nb_steps, input_dim))
for weight in [None, weights_in]:
for border_mode in ['valid', 'same']:
for subsample_length in [1]:
if border_mode == 'same' and subsample_length != 1:
continue
for W_regularizer in [None, 'l2']:
for b_regularizer in [None, 'l2']:
for act_regularizer in [None, 'l2']:
layer = convolutional.Convolution1D(
nb_filter, filter_length,
weights=weight,
border_mode=border_mode,
W_regularizer=W_regularizer,
b_regularizer=b_regularizer,
activity_regularizer=act_regularizer,
subsample_length=subsample_length,
input_shape=(None, input_dim))
layer.input = K.variable(input)
for train in [True, False]:
out = K.eval(layer.get_output(train))
assert input.shape[0] == out.shape[0]
if border_mode == 'same' and subsample_length == 1:
assert input.shape[1] == out.shape[1]
layer.get_config()
def test_maxpooling_1d(self):
nb_samples = 9
nb_steps = 7
input_dim = 10
input = np.ones((nb_samples, nb_steps, input_dim))
for stride in [1, 2]:
layer = convolutional.MaxPooling1D(stride=stride,
border_mode='valid')
layer.input = K.variable(input)
for train in [True, False]:
K.eval(layer.get_output(train))
layer.get_config()
def test_convolution_2d(self):
nb_samples = 8
nb_filter = 9
stack_size = 7
nb_row = 10
nb_col = 6
input_nb_row = 11
input_nb_col = 12
weights_in = [np.ones((nb_filter, stack_size, nb_row, nb_col)), np.ones(nb_filter)]
input = np.ones((nb_samples, stack_size, input_nb_row, input_nb_col))
for weight in [None, weights_in]:
for border_mode in ['valid', 'same']:
for subsample in [(1, 1), (2, 2)]:
if border_mode == 'same' and subsample != (1, 1):
continue
for W_regularizer in [None, 'l2']:
for b_regularizer in [None, 'l2']:
for act_regularizer in [None, 'l2']:
layer = convolutional.Convolution2D(
nb_filter, nb_row, nb_col,
weights=weight,
border_mode=border_mode,
W_regularizer=W_regularizer,
b_regularizer=b_regularizer,
activity_regularizer=act_regularizer,
subsample=subsample,
input_shape=(stack_size, None, None))
layer.input = K.variable(input)
for train in [True, False]:
out = K.eval(layer.get_output(train))
if border_mode == 'same' and subsample == (1, 1):
assert out.shape[2:] == input.shape[2:]
layer.get_config()
def test_maxpooling_2d(self):
nb_samples = 9
stack_size = 7
input_nb_row = 11
input_nb_col = 12
pool_size = (3, 3)
input = np.ones((nb_samples, stack_size, input_nb_row, input_nb_col))
for strides in [(1, 1), (2, 2)]:
layer = convolutional.MaxPooling2D(strides=strides,
border_mode='valid',
pool_size=pool_size)
layer.input = K.variable(input)
for train in [True, False]:
K.eval(layer.get_output(train))
layer.get_config()
def test_zero_padding_2d(self):
nb_samples = 9
stack_size = 7
input_nb_row = 11
input_nb_col = 12
input = np.ones((nb_samples, stack_size, input_nb_row, input_nb_col))
layer = convolutional.ZeroPadding2D(padding=(2, 2))
layer.input = K.variable(input)
for train in [True, False]:
out = K.eval(layer.get_output(train))
for offset in [0, 1, -1, -2]:
assert_allclose(out[:, :, offset, :], 0.)
assert_allclose(out[:, :, :, offset], 0.)
assert_allclose(out[:, :, 2:-2, 2:-2], 1.)
layer.get_config()
def test_upsampling_1d(self):
nb_samples = 9
nb_steps = 7
input_dim = 10
input = np.ones((nb_samples, nb_steps, input_dim))
for length in [2, 3, 9]:
layer = convolutional.UpSampling1D(length=length)
layer.input = K.variable(input)
for train in [True, False]:
out = K.eval(layer.get_output(train))
assert out.shape[1] == length * nb_steps
layer.get_config()
def test_upsampling_2d(self):
nb_samples = 9
stack_size = 7
input_nb_row = 11
input_nb_col = 12
input = np.ones((nb_samples, stack_size, input_nb_row, input_nb_col))
for length_row in [2, 3, 9]:
for length_col in [2, 3, 9]:
layer = convolutional.UpSampling2D(size=(length_row, length_col))
layer.input = K.variable(input)
for train in [True, False]:
out = K.eval(layer.get_output(train))
assert out.shape[2] == length_row * input_nb_row
assert out.shape[3] == length_col * input_nb_col
layer.get_config()
if __name__ == '__main__':
unittest.main()
+166
Ver Arquivo
@@ -0,0 +1,166 @@
import unittest
import numpy as np
from numpy.testing import assert_allclose
from keras import backend as K
from keras.layers import core
class TestLayerBase(unittest.TestCase):
def test_input_output(self):
nb_samples = 10
input_dim = 5
layer = core.Layer()
# Once an input is provided, it should be reachable through the
# appropriate getters
input = np.ones((nb_samples, input_dim))
layer.input = K.variable(input)
for train in [True, False]:
assert_allclose(K.eval(layer.get_input(train)), input)
assert_allclose(K.eval(layer.get_output(train)), input)
def test_connections(self):
nb_samples = 10
input_dim = 5
layer1 = core.Layer()
layer2 = core.Layer()
input = np.ones((nb_samples, input_dim))
layer1.input = K.variable(input)
# After connecting, input of layer1 should be passed through
layer2.set_previous(layer1)
for train in [True, False]:
assert_allclose(K.eval(layer2.get_input(train)), input)
assert_allclose(K.eval(layer2.get_output(train)), input)
class TestConfigParams(unittest.TestCase):
"""
Test the constructor, config and params functions of all layers in core.
"""
def _runner(self, layer):
conf = layer.get_config()
assert (type(conf) == dict)
param = layer.get_params()
# Typically a list or a tuple, but may be any iterable
assert hasattr(param, '__iter__')
def test_base(self):
layer = core.Layer()
self._runner(layer)
def test_masked(self):
layer = core.MaskedLayer()
self._runner(layer)
def test_merge(self):
layer_1 = core.Layer()
layer_2 = core.Layer()
layer_1.set_input_shape((None,))
layer_2.set_input_shape((None,))
layer = core.Merge([layer_1, layer_2])
self._runner(layer)
def test_dropout(self):
layer = core.Dropout(0.5)
self._runner(layer)
def test_activation(self):
layer = core.Activation('linear')
self._runner(layer)
def test_reshape(self):
layer = core.Reshape(dims=(10, 10))
self._runner(layer)
def test_flatten(self):
layer = core.Flatten()
self._runner(layer)
def test_repeat_vector(self):
layer = core.RepeatVector(10)
self._runner(layer)
def test_dense(self):
layer = core.Dense(10, input_shape=(10,))
self._runner(layer)
def test_act_reg(self):
layer = core.ActivityRegularization(0.5, 0.5)
self._runner(layer)
def test_time_dist_dense(self):
layer = core.TimeDistributedDense(10, input_shape=(None, 10))
self._runner(layer)
def test_time_dist_merge(self):
layer = core.TimeDistributedMerge()
self._runner(layer)
def test_autoencoder(self):
layer_1 = core.Layer()
layer_2 = core.Layer()
layer = core.AutoEncoder(layer_1, layer_2)
self._runner(layer)
def test_maxout_dense(self):
layer = core.MaxoutDense(10, 10)
self._runner(layer)
class TestMasking(unittest.TestCase):
"""Test the Masking class"""
def test_sequences(self):
"""Test masking sequences with zeroes as padding"""
if K._BACKEND == "tensorflow":
return
# integer inputs, one per timestep, like embeddings
layer = core.Masking()
func = K.function([layer.input], [layer.get_output_mask()])
input_data = np.array([[[1], [2], [3], [0]],
[[0], [4], [5], [0]]], dtype=np.int32)
# This is the expected output mask, one dimension less
expected = np.array([[1, 1, 1, 0], [0, 1, 1, 0]])
# get mask for this input
output = func([input_data])[0]
self.assertTrue(np.all(output == expected))
def test_non_zero(self):
"""Test masking with non-zero mask value"""
if K._BACKEND == "tensorflow":
return
layer = core.Masking(5)
func = K.function([layer.input], [layer.get_output_mask()])
input_data = np.array([[[1, 1], [2, 1], [3, 1], [5, 5]],
[[1, 5], [5, 0], [0, 0], [0, 0]]],
dtype=np.int32)
output = func([input_data])[0]
expected = np.array([[1, 1, 1, 0], [1, 1, 1, 1]])
self.assertTrue(np.all(output == expected))
def test_non_zero_output(self):
"""Test output of masking layer with non-zero mask value"""
if K._BACKEND == "tensorflow":
return
layer = core.Masking(5)
func = K.function([layer.input], [layer.get_output()])
input_data = np.array([[[1, 1], [2, 1], [3, 1], [5, 5]],
[[1, 5], [5, 0], [0, 0], [0, 0]]],
dtype=np.int32)
output = func([input_data])[0]
expected = np.array([[[1, 1], [2, 1], [3, 1], [0, 0]],
[[1, 5], [5, 0], [0, 0], [0, 0]]])
self.assertTrue(np.all(output == expected))
if __name__ == '__main__':
unittest.main()
+47
Ver Arquivo
@@ -0,0 +1,47 @@
import unittest
import numpy as np
from keras.layers import recurrent
from keras import backend as K
nb_samples, timesteps, input_dim, output_dim = 3, 3, 10, 5
def _runner(layer_class):
"""
All the recurrent layers share the same interface,
so we can run through them with a single function.
"""
for ret_seq in [True, False]:
layer = layer_class(output_dim, return_sequences=ret_seq,
weights=None, input_shape=(timesteps, input_dim))
layer.input = K.variable(np.ones((nb_samples, timesteps, input_dim)))
layer.get_config()
for train in [True, False]:
out = K.eval(layer.get_output(train))
# Make sure the output has the desired shape
if ret_seq:
assert(out.shape == (nb_samples, timesteps, output_dim))
else:
assert(out.shape == (nb_samples, output_dim))
mask = layer.get_output_mask(train)
class TestRNNS(unittest.TestCase):
"""
Test all the RNNs using a generic test runner function defined above.
"""
def test_simple(self):
_runner(recurrent.SimpleRNN)
def test_gru(self):
_runner(recurrent.GRU)
def test_lstm(self):
_runner(recurrent.LSTM)
if __name__ == '__main__':
unittest.main()
+76
Ver Arquivo
@@ -0,0 +1,76 @@
import unittest
from keras import backend as K
import numpy as np
from numpy.testing import assert_allclose
def get_standard_values():
'''
These are just a set of floats used for testing the activation
functions, and are useful in multiple tests.
'''
return np.array([[0, 0.1, 0.5, 0.9, 1.0]], dtype=K.floatx())
class TestActivations(unittest.TestCase):
def test_softmax(self):
from keras.activations import softmax as s
# Test using a reference implementation of softmax
def softmax(values):
m = np.max(values)
e = np.exp(values - m)
return e / np.sum(e)
x = K.placeholder(ndim=2)
exp = s(x)
f = K.function([x], [exp])
test_values = get_standard_values()
result = f([test_values])[0]
expected = softmax(test_values)
assert_allclose(result, expected, rtol=1e-05)
def test_relu(self):
'''
Relu implementation doesn't depend on the value being
a theano variable. Testing ints, floats and theano tensors.
'''
from keras.activations import relu as r
x = K.placeholder(ndim=2)
exp = r(x)
f = K.function([x], [exp])
test_values = get_standard_values()
result = f([test_values])[0]
# because no negatives in test values
assert_allclose(result, test_values, rtol=1e-05)
def test_tanh(self):
from keras.activations import tanh as t
test_values = get_standard_values()
x = K.placeholder(ndim=2)
exp = t(x)
f = K.function([x], [exp])
result = f([test_values])[0]
expected = np.tanh(test_values)
assert_allclose(result, expected, rtol=1e-05)
def test_linear(self):
'''
This function does no input validation, it just returns the thing
that was passed in.
'''
from keras.activations import linear as l
xs = [1, 5, True, None, 'foo']
for x in xs:
assert x == l(x)
if __name__ == '__main__':
unittest.main()

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais