Comparar commits

..

344 Commits

Autor SHA1 Mensagem Data
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
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
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
72 arquivos alterados com 4052 adições e 1036 exclusões
+5 -1
Ver Arquivo
@@ -1,6 +1,10 @@
*.DS_Store
*.pyc
*.swp
temp/*
dist/*
build/*
keras/datasets/data/*
keras/datasets/temp/*
keras/datasets/temp/*
docs/site/*
docs/theme/*
+20
Ver Arquivo
@@ -0,0 +1,20 @@
language: python
# Setup anaconda
before_install:
- wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh
- chmod +x miniconda.sh
- ./miniconda.sh -b
- export PATH=/home/travis/miniconda/bin:$PATH
- conda update --yes conda
# The next couple lines fix a crash with multiprocessing on Travis and are not specific to using Miniconda
- sudo rm -rf /dev/shm
- sudo ln -s /run/shm /dev/shm
python:
- "3.4"
# command to install dependencies
install:
- conda install --yes python=$TRAVIS_PYTHON_VERSION numpy scipy matplotlib pandas pytest
# Coverage packages are on my binstar channel
- python setup.py install
# command to run tests
script: py.test
+30 -32
Ver Arquivo
@@ -1,43 +1,41 @@
site_name: Keras Documentation
theme: readthedocs
#theme: readthedocs
docs_dir: sources
repo_url: http://github.com/fchollet/keras
site_url: /
#theme_dir: theme
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
- 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
- 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
- Utils:
- Visualization Utilities: utils/visualization.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]
+2 -3
Ver Arquivo
@@ -26,8 +26,7 @@ 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.
+21 -4
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,23 @@ 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.
```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
@@ -44,11 +61,11 @@ 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={}):
@@ -71,7 +88,7 @@ print history.losses
---
### Example to checkpoint models
### Example: model checkpoints
```python
from keras.callbacks import ModelCheckpoint
+5 -2
Ver Arquivo
@@ -2,9 +2,12 @@
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
+8
Ver Arquivo
@@ -15,6 +15,9 @@
- [Models](models.md)
- [Activations](activations.md)
- [Initializations](initializations.md)
- [Regularizers](regularizers.md)
- [Constraints](constraints.md)
- [Callbacks](callbacks.md)
- [Datasets](datasets.md)
---
@@ -33,3 +36,8 @@
- [Sequence](preprocessing/sequence.md)
- [Text](preprocessing/text.md)
- [Image](preprocessing/image.md)
---
## Utils
- [Visualization](utils/visualization.md)
+5 -3
Ver Arquivo
@@ -35,7 +35,7 @@ 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')
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)
@@ -92,6 +92,7 @@ from keras.layers.embeddings import Embedding
from keras.layers.recurrent import LSTM
model = Sequential()
# Add a mask_zero=True to the Embedding connstructor if 0 is a left-padding value in your data
model.add(Embedding(max_features, 256))
model.add(LSTM(256, 128, activation='sigmoid', inner_activation='hard_sigmoid'))
model.add(Dropout(0.5))
@@ -106,8 +107,9 @@ score = model.evaluate(X_test, Y_test, batch_size=16)
---
### Architecture for learning image captions with a convnet and a Gated Recurrent Unit
(word-level embedding, caption of maximum length 16 words).
### Image captioning
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.
+18 -16
Ver Arquivo
@@ -2,7 +2,7 @@
## Overview
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 network library in the spirit of Torch, written in Python, that uses [Theano](http://deeplearning.net/software/theano/) under the hood for optimized tensor manipulation on GPU and CPU. It was developed with a focus on enabling fast experimentation.
Use Keras if you need a deep learning library that:
@@ -12,13 +12,13 @@ Use Keras if you need a deep learning library that:
## 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 (<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.
- __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/functions), and existing modules provide ample examples. To be able to easily create new modules allows for total expressiveness, making Keras suitable for adavanced 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 (like in Caffe or PyLearn2). Models are described in Python code, which is compact, easier to debug, and allows for ease of extensibility.
## Code
@@ -30,7 +30,9 @@ 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 +45,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(input_dim=100, output_dim=64, init="glorot_uniform"))
model.add(Activation("relu"))
model.add(Dense(input_dim=64, output_dim=10, init="uniform"))
model.add(Dense(input_dim=64, output_dim=10, init="glorot_uniform"))
model.add(Activation("softmax"))
```
@@ -67,7 +69,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,7 +83,7 @@ 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 the [examples](examples.md).
@@ -89,11 +91,11 @@ Have a look at the [examples](examples.md).
Keras uses the following dependencies:
- numpy, scipy
- Theano
- __numpy__, __scipy__
- __Theano__
- See [installation instructions](http://deeplearning.net/software/theano/install.html#install).
- HDF5 and h5py (optional, required if you use model saving/loading functions)
- Optional but recommended if you use CNNs: cuDNN.
- __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
@@ -116,7 +118,7 @@ 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.
- 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.
- 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).
@@ -124,7 +126,7 @@ Keras welcomes all contributions from the community.
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 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."_
+1 -1
Ver Arquivo
@@ -1,4 +1,3 @@
# Initializations
## Usage of 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)
-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
+87 -3
Ver Arquivo
@@ -1,13 +1,89 @@
## Convolution1D
```python
keras.layers.convolutional.Convolution1D(input_dim, 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)
```
Convolution operator for filtering neighborhoods of one-dimensional inputs.
- __Input shape__: 3D tensor with shape: `(nb_samples, steps, input_dim)`.
- __Output shape__: 3D tensor with shape: `(nb_samples, steps, nb_filter)`. `steps` value might have changed due to padding.
- __Arguments__:
- __input_dim__: Number of channels/dimensions in the input.
- __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 'full'. see scipy.signal.convolve2d.
- __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.
---
## 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))
border_mode='valid', subsample=(1, 1),
W_regularizer=None, b_regularizer=None, W_constraint=None)
```
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.
- __Input shape__: 4D tensor with shape: `(nb_samples, stack_size, nb_row, nb_col)`.
- __Output shape__: 4D tensor with shape: `(nb_samples, nb_filter, nb_row, nb_col)`. `nb_row`, `nb_col` might have changed due to padding.
- __Arguments__:
- __nb_filter__: Number of convolution kernels to use.
- __stack_size__: Number of channels in the input.
- __nb_row__: Number of rows in the convolution kernels
- __nb_col__: Number of columns in the convolution kernels
- __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', 'full', or 'same'. See scipy.signal.convolve2d.
- __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.
---
## MaxPooling1D
```python
keras.layers.convolutional.MaxPooling1D(pool_length=2, stride=None, ignore_border=True)
```
- __Input shape__: 3D tensor with shape: `(nb_samples, steps, dim)`.
- __Output shape__: 3D tensor with shape: `(nb_samples, steps, new_dim)`.
- __Arguments__:
- __pool_length__: factor by which to downscale. 2 will halve the input.
- __stride__: integer or None. Stride value.
- __ignore_border__: boolean.
---
@@ -17,4 +93,12 @@ This is a wrapper for Theano's [conv2d](http://deeplearning.net/software/theano/
keras.layers.convolutional.MaxPooling2D(poolsize=(2, 2), ignore_border=True)
```
This is a wrapper for Theano's [max_pool_2d](http://deeplearning.net/software/theano/library/tensor/signal/downsample.html).
- __Input shape__: 4D tensor with shape: `(nb_samples, stack_size, nb_row, nb_col)`.
- __Output shape__: 4D tensor with shape: `(nb_samples, stack_size, new_nb_row, new_nb_col)`.
- __Arguments__:
- __pool_size__: factor by which to downscale (vertical ds, horizontal ds). (2, 2) will halve the image in each dimension.
- __ignore_border__: boolean. When True, (5, 5) input with pool_size=(2, 2) will generate a (2, 2) output, (3, 3) otherwise.
+33 -55
Ver Arquivo
@@ -71,7 +71,7 @@ Set the weights of the parameters of 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)
W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_constraint=None, b_constraint=None)
```
Standard 1D fully-connect layer.
@@ -87,8 +87,9 @@ Standard 1D fully-connect layer.
- __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.
@@ -97,7 +98,7 @@ Standard 1D fully-connect layer.
## 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)
W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_constraint=None, b_constraint=None)
```
Fully-connected layer distributed over the time dimension. Useful after a recurrent network set to `return_sequences=True`.
@@ -110,8 +111,9 @@ Fully-connected layer distributed over the time dimension. Useful after a recurr
- __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.
@@ -127,7 +129,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)
@@ -145,8 +147,6 @@ A customizable autoencoder model. If `output_reconstruction = True` then dim(inp
- __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)`.
- __Example__:
@@ -156,45 +156,9 @@ 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))
```
---
## 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))
```
@@ -231,9 +195,9 @@ 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)
@@ -276,7 +240,9 @@ 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)`.
Note that the output is still a single tensor; `RepeatVector` does not split the data flow.
- __Input shape__: This layer does not assume a specific input shape. This layer cannot be used as the first layer in a model.
@@ -289,10 +255,21 @@ Repeat the 1D input n times. Dimensions of input are assumed to be (nb_samples,
---
## 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)
W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_constraint=None, b_constraint=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.
@@ -308,8 +285,9 @@ A dense maxout layer. A `MaxoutDense` layer takes the element-wise maximum of `n
- __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.
@@ -325,11 +303,11 @@ model.add(RepeatVector(2)) # output shape: (nb_samples, 2, 10)
keras.layers.core.Merge(models, mode='sum')
```
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, following one of two modes: `sum` or `concat`.
- __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', 'concat'}`. `sum` will simply sum the outputs of the layers (therefore all layers should have an output with the same shape). `concat` will concatenate the outputs along the last dimension (therefore all layers should have an output that only differ along the last dimension).
- __Example__:
+2 -1
Ver Arquivo
@@ -2,7 +2,7 @@
## 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)
```
Turn positive integers (indexes) into denses vectors of fixed size,
@@ -20,6 +20,7 @@ eg. `[[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]]`
- __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.
## WordContextProduct
+38
Ver Arquivo
@@ -0,0 +1,38 @@
## 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.
The Gaussian noise is only added at training time.
- __Input shape__: This layer does not assume a specific input shape.
- __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.
http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf
The Gaussian noise is only used at training time.
- __Input shape__: This layer does not assume a specific input shape.
- __Output shape__: Same as input.
- __Arguments__:
- __p__: float, drop probability as with Dropout.
+50 -4
Ver Arquivo
@@ -6,7 +6,7 @@ keras.layers.recurrent.SimpleRNN(input_dim, output_dim,
init='glorot_uniform', inner_init='orthogonal', activation='sigmoid', weights=None,
truncate_gradient=-1, return_sequences=False)
```
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)`.
@@ -14,6 +14,9 @@ Fully connected RNN where output is to fed back to input. Not a particularly use
- if `return_sequences`: 3D tensor with shape: `(nb_samples, timesteps, ouput_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`.
- __Arguments__:
- __input_dim__: dimension of the input.
- __output_dim__: dimension of the internal projections and the final output.
@@ -47,6 +50,9 @@ Not a particularly useful model, included for demonstration purposes.
- if `return_sequences`: 3D tensor with shape: `(nb_samples, timesteps, ouput_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`.
- __Arguments__:
- __input_dim__: dimension of the input.
- __output_dim__: dimension of the internal projections and the final output.
@@ -79,6 +85,8 @@ Gated Recurrent Unit - Cho et al. 2014.
- if `return_sequences`: 3D tensor with shape: `(nb_samples, timesteps, ouput_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.
- __Arguments__:
- __input_dim__: dimension of the input.
- __output_dim__: dimension of the internal projections and the final output.
@@ -100,7 +108,7 @@ Gated Recurrent Unit - Cho et al. 2014.
```python
keras.layers.recurrent.LSTM(input_dim, output_dim=128,
init='glorot_uniform', inner_init='orthogonal',
init='glorot_uniform', inner_init='orthogonal', forget_bias_init='one',
activation='tanh', inner_activation='hard_sigmoid',
weights=None, truncate_gradient=-1, return_sequences=False)
```
@@ -113,11 +121,14 @@ Long-Short Term Memory unit - Hochreiter 1997.
- if `return_sequences`: 3D tensor with shape: `(nb_samples, timesteps, ouput_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.
- __Arguments__:
- __input_dim__: dimension of the input.
- __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.
@@ -128,6 +139,41 @@ Long-Short Term Memory unit - Hochreiter 1997.
- [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)
---
## JZS1, JZS2, JZS3
```python
keras.layers.recurrent.JZS1(input_dim, output_dim=128,
init='glorot_uniform', inner_init='orthogonal',
activation='tanh', inner_activation='sigmoid',
weights=None, truncate_gradient=-1, return_sequences=False)
```
Top 3 RNN architectures evolved from the evaluation of thousands of models. Serves as alternatives to LSTMs and GRUs. Corresponds to `MUT1`, `MUT2`, and `MUT3` architectures described in the paper: An Empirical Exploration of Recurrent Network Architectures, Jozefowicz et al. 2015.
- __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)`.
- __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.
- __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.
- __References__:
- [An Empirical Exploration of Recurrent Network Architectures](http://www.jmlr.org/proceedings/papers/v37/jozefowicz15.pdf)
+103 -12
Ver Arquivo
@@ -7,40 +7,42 @@ 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.
- __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.
- __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 dictionary with a record of training loss values at successive epochs, as well as validation loss values (if applicable), accuracy (if applicable), etc.
- __Arguments__:
- __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.
- __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).
- __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).
- __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.
- __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): 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): 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__:
@@ -112,3 +114,92 @@ 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, ndim=2, dtype='float'): Add an input with shape dimensionality `ndim`.
- __Arguments__:
- __ndim__: Use `ndim=2` for vector input `(samples, features)`, ndim=3 for temporal input `(samples, time, features)`, ndim=4 for image input `(samples, channels, height, width)`.
- __dtype__: `float` or `int`. Use `int` if the input is connected to an Embedding layer, `float` otherwise.
- __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.
- __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 dictionary with 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', ndim=2)
graph.add_node(Dense(32, 16), name='dense1', input='input')
graph.add_node(Dense(32, 4), name='dense2', input='input')
graph.add_node(Dense(16, 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', ndim=2)
graph.add_input(name='input2', ndim=2)
graph.add_node(Dense(32, 16), name='dense1', input='input1')
graph.add_node(Dense(32, 4), name='dense2', input='input2')
graph.add_node(Dense(16, 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':...}
```
+6 -2
Ver Arquivo
@@ -7,18 +7,22 @@ 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__
- __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)`.
+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, 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
+6 -5
Ver Arquivo
@@ -30,6 +30,7 @@ data_augmentation = True
# the data, shuffled and split between tran 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')
@@ -54,11 +55,11 @@ model.add(MaxPooling2D(poolsize=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(64*8*8, 512, init='normal'))
model.add(Dense(64*8*8, 512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(512, nb_classes, init='normal'))
model.add(Dense(512, nb_classes))
model.add(Activation('softmax'))
# let's train the model using SGD + momentum (how original).
@@ -72,7 +73,7 @@ if not data_augmentation:
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)
@@ -104,14 +105,14 @@ 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)])
+82
Ver Arquivo
@@ -0,0 +1,82 @@
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 RMSprop
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.8330 test accuracy after 3 epochs. 100s/epoch on K520 GPU.
'''
# set parameters:
max_features = 5000
maxlen = 100
batch_size = 32
embedding_dims = 100
nb_filters = 250
filter_length = 3
hidden_dims = 250
nb_epoch = 3
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))
model.add(Dropout(0.25))
# we add a Convolution1D, which will learn nb_filters
# word group filters of size filter_length:
model.add(Convolution1D(input_dim=embedding_dims,
nb_filter=nb_filters,
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())
# Computing the output shape of a conv layer can be tricky;
# for a good tutorial, see: http://cs231n.github.io/convolutional-networks/
output_size = nb_filters * (((maxlen - filter_length) / 1) + 1) / 2
# We add a vanilla hidden layer:
model.add(Dense(output_size, 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(hidden_dims, 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))
+10 -16
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.preprocessing import sequence
from keras.optimizers import SGD, RMSprop, Adagrad
@@ -21,21 +22,18 @@ from keras.datasets import imdb
- RNNs are tricky. Choice of batch size is important,
choice of loss and optimizer is critical, etc.
Most configurations won't converge.
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
max_features = 20000
maxlen = 100 # cut texts after this number of words (among top max_features most common words)
batch_size = 16
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)
@@ -50,8 +48,8 @@ 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))
model.add(LSTM(128, 128)) # try using a GRU instead, for fun
model.add(Dropout(0.5))
model.add(Dense(128, 1))
model.add(Activation('sigmoid'))
@@ -60,11 +58,7 @@ 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=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=4, 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)
+2 -4
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,7 +18,7 @@ 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:
Command: THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python kaggle_otto_nn.py
@@ -35,8 +36,6 @@ 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()
@@ -121,4 +120,3 @@ print("Generating submission...")
proba = model.predict_proba(X_test)
make_submission(proba, ids, encoder, fname='keras-otto.csv')
+104
Ver Arquivo
@@ -0,0 +1,104 @@
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, 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(len(chars), 512, return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(512, 512, return_sequences=False))
model.add(Dropout(0.2))
model.add(Dense(512, len(chars)))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
# helper function to sample an index from a probability array
def sample(a, diversity=0.75):
if random.random() > diversity:
return np.argmax(a)
while 1:
i = random.randint(0, len(a)-1)
if a[i] > random.random():
return i
# 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.4, 0.6, 0.8]:
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()
+64
Ver Arquivo
@@ -0,0 +1,64 @@
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
# 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, 28, 28)
X_test = X_test.reshape(X_test.shape[0], 1, 28, 28)
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(32, 1, 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(Flatten())
model.add(Dense(32*196, 128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(128, 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])
+87
Ver Arquivo
@@ -0,0 +1,87 @@
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
BPTT_truncate = 28*28
# 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(input_dim=1, output_dim=hidden_units,
init=lambda shape: normal(shape, scale=0.001),
inner_init=lambda shape: identity(shape, scale=1.0),
activation='relu', truncate_gradient=BPTT_truncate))
model.add(Dense(hidden_units, 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(1, hidden_units))
model.add(Dense(hidden_units, 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])
+10 -7
Ver Arquivo
@@ -1,29 +1,32 @@
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.30% test accuracy after 20 epochs (there is *a lot* of margin for parameter tuning).
2 seconds per epoch on a GRID 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
+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(max_words, 512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(256, nb_classes, init='normal'))
model.add(Dense(512, 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])
+2
Ver Arquivo
@@ -53,6 +53,8 @@ load_model = False
load_tokenizer = False
train_model = True
save_dir = os.path.expanduser("~/.keras/models")
if not os.path.exists(save_dir):
os.makedirs(save_dir)
model_load_fname = "HN_skipgram_model.pkl"
model_save_fname = "HN_skipgram_model.pkl"
tokenizer_fname = "HN_tokenizer.pkl"
+8 -7
Ver Arquivo
@@ -1,15 +1,13 @@
from __future__ import absolute_import
import theano
import theano.tensor as T
import types
def softmax(x):
return T.nnet.softmax(x)
return T.nnet.softmax(x.reshape((-1, x.shape[-1]))).reshape(x.shape)
def time_distributed_softmax(x):
xshape = x.shape
X = x.reshape((xshape[0] * xshape[1], xshape[2]))
return T.nnet.softmax(X).reshape(xshape)
import warnings
warnings.warn("time_distributed_softmax is deprecated. Just use softmax!", DeprecationWarning)
return softmax(x)
def softplus(x):
return T.nnet.softplus(x)
@@ -27,8 +25,11 @@ def hard_sigmoid(x):
return T.nnet.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')
+113 -68
Ver Arquivo
@@ -4,7 +4,7 @@ import theano
import theano.tensor as T
import numpy as np
import warnings
import time
import time, json
from collections import deque
from .utils.generic_utils import Progbar
@@ -109,110 +109,155 @@ class BaseLogger(Callback):
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.
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):
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
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)
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 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, self.filepath))
self.best = current
self.model.save_weights(self.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)
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 self.logs:
send[k] = v
r = requests.post(self.root + '/publish/epoch/end/', {'data':json.dumps(send)})
+32 -11
Ver Arquivo
@@ -3,20 +3,41 @@ import theano
import theano.tensor as T
import numpy as np
def maxnorm(m=2):
def maxnorm_wrap(p):
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 = T.sqrt(T.sum(T.sqr(p), axis=0))
desired = T.clip(norms, 0, m)
desired = T.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
class NonNeg(Constraint):
def __call__(self, p):
p *= T.ge(p, 0)
return p
def unitnorm(e):
return e / T.sqrt(T.sum(e**2, axis=-1, keepdims=True))
class UnitNorm(Constraint):
def __call__(self, p):
return p / T.sqrt(T.sum(p**2, 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)
+27 -6
Ver Arquivo
@@ -4,8 +4,11 @@ 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"):
@@ -16,10 +19,15 @@ def load_data(path="imdb.pkl", nb_words=None, skip_top=0, maxlen=None, test_spli
X, labels = six.moves.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 +42,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))]
+33 -8
Ver Arquivo
@@ -7,6 +7,7 @@ import random
import os
import six.moves.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,7 +19,7 @@ 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):]
@@ -70,25 +71,36 @@ 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)
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'))
six.moves.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):
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):
path = get_file(path, origin="https://s3.amazonaws.com/text-datasets/reuters.pkl")
f = open(path, 'rb')
X, labels = six.moves.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 +115,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))]
+13 -4
Ver Arquivo
@@ -3,7 +3,7 @@ import theano
import theano.tensor as T
import numpy as np
from .utils.theano_utils import sharedX, shared_zeros
from .utils.theano_utils import sharedX, shared_zeros, shared_ones
def get_fans(shape):
fan_in = shape[0] if len(shape) == 2 else np.prod(shape[1:])
@@ -22,7 +22,7 @@ def lecun_uniform(shape):
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):
@@ -34,7 +34,7 @@ def glorot_normal(shape):
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):
@@ -46,7 +46,7 @@ def he_normal(shape):
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):
@@ -59,9 +59,18 @@ def orthogonal(shape, scale=1.1):
q = q.reshape(shape)
return sharedX(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 sharedX(scale * np.identity(shape[0]))
def zero(shape):
return shared_zeros(shape)
def one(shape):
return shared_ones(shape)
from .utils.generic_utils import get_from_module
def get(identifier):
+158 -10
Ver Arquivo
@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import print_function
import theano.tensor as T
from ..layers.core import Layer
from ..layers.core import Layer, Merge
from six.moves import range
def ndim_tensor(ndim):
@@ -15,22 +16,32 @@ def ndim_tensor(ndim):
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])
self.layers[-1].set_previous(self.layers[-2])
params, regularizers, constraints = layer.get_params()
self.params += params
self.regularizers += regularizers
@@ -39,13 +50,16 @@ class Sequential(Layer):
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 = l.input.ndim
self.layers[0].input = ndim_tensor(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
@@ -66,4 +80,138 @@ class Sequential(Layer):
def get_config(self):
return {"name":self.__class__.__name__,
"layers":[layer.get_config() for layer in self.layers]}
"layers":[layer.get_config() 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_params
- get_output_mask
- supports_masked_input
- get_weights
- set_weights
'''
def __init__(self):
self.namespace = set() # strings
self.nodes = {} # 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
self.params = []
self.regularizers = []
self.constraints = []
def set_previous(self, layer):
if len(self.inputs) != 1 or len(self.outputs) != 1:
raise Exception('The Graph container can only be used as a layer \
when it has exactly one input and one output.')
self.inputs[self.input_order[0]].set_previous(layer)
def get_input(self, train=False):
if len(self.inputs) != 1 or len(self.outputs) != 1:
raise Exception('The Graph container can only be used as a layer \
when it has exactly one input and one output.')
return self.inputs[self.input_order[0]].get_input(train)
@property
def input(self):
return self.get_input()
def get_output(self, train=False):
if len(self.inputs) != 1 or len(self.outputs) != 1:
raise Exception('The Graph container can only be used as a layer \
when it has exactly one input and one output.')
return self.outputs[self.output_order[0]].get_output(train)
def add_input(self, name, ndim=2, 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
if dtype == 'float':
layer.input = ndim_tensor(ndim)
else:
if ndim == 2:
layer.input = T.imatrix()
else:
raise Exception('Type "int" can only be used with ndim==2.')
layer.input.name = name
self.inputs[name] = layer
self.input_config.append({'name':name, 'ndim':ndim, 'dtype':dtype})
def add_node(self, layer, name, input=None, inputs=[], merge_mode='concat'):
if hasattr(layer, 'set_name'):
layer.set_name(name)
if name in self.namespace:
raise Exception('Duplicate node identifier: ' + name)
if input:
if input not in self.namespace:
raise Exception('Unknown 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)
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})
params, regularizers, constraints = layer.get_params()
self.params += params
self.regularizers += regularizers
self.constraints += constraints
def add_output(self, name, input=None, inputs=[], merge_mode='concat'):
if name in self.namespace:
raise Exception('Duplicate node identifier: ' + name)
if input:
if input not in self.namespace:
raise Exception('Unknown identifier: ' + input)
if input in self.nodes:
self.outputs[name] = self.nodes[input]
elif input in self.inputs:
self.ouputs[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)
self.outputs[name] = merge
self.namespace.add(name)
self.output_order.append(name)
self.output_config.append({'name':name, 'input':input, 'inputs':inputs, 'merge_mode':merge_mode})
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])}
+129 -52
Ver Arquivo
@@ -5,98 +5,130 @@ import theano
import theano.tensor as T
from theano.tensor.signal import downsample
from .. import activations, initializations
from .. import activations, initializations, regularizers, constraints
from ..utils.theano_utils import shared_zeros
from ..layers.core import Layer
class Convolution1D(Layer):
def __init__(self, nb_filter, stack_size, filter_length,
def __init__(self, input_dim, nb_filter, 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):
border_mode='valid', subsample_length=1,
W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_constraint=None, b_constraint=None):
nb_row = 1
nb_col = filter_length
if border_mode not in {'valid', 'full'}:
raise Exception('Invalid border mode for Convolution1D:', border_mode)
super(Convolution1D,self).__init__()
self.nb_filter = nb_filter
self.stack_size = stack_size
self.input_dim = input_dim
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)
self.border_mode = border_mode
self.image_shape = image_shape
self.input = T.tensor4()
self.W_shape = (nb_filter, stack_size, nb_row, nb_col)
self.input = T.tensor3()
self.W_shape = (nb_filter, input_dim, filter_length, 1)
self.W = self.init(self.W_shape)
self.b = shared_zeros((nb_filter,))
self.params = [self.W, self.b]
self.regularizers = [W_regularizer, b_regularizer]
self.constraints = [W_constraint, b_constraint]
self.regularizers = []
self.W_regularizer = regularizers.get(W_regularizer)
if self.W_regularizer:
self.W_regularizer.set_param(self.W)
self.regularizers.append(self.W_regularizer)
self.b_regularizer = regularizers.get(b_regularizer)
if self.b_regularizer:
self.b_regularizer.set_param(self.b)
self.regularizers.append(self.b_regularizer)
self.activity_regularizer = regularizers.get(activity_regularizer)
if self.activity_regularizer:
self.activity_regularizer.set_layer(self)
self.regularizers.append(self.activity_regularizer)
self.W_constraint = constraints.get(W_constraint)
self.b_constraint = constraints.get(b_constraint)
self.constraints = [self.W_constraint, self.b_constraint]
if weights is not None:
self.set_weights(weights)
def get_output(self, train):
X = self.get_input(train)
conv_out = theano.tensor.nnet.conv.conv2d(X, self.W,
border_mode=self.border_mode, subsample=self.subsample, image_shape=self.image_shape)
X = theano.tensor.reshape(X, (X.shape[0], X.shape[1], X.shape[2], 1)).dimshuffle(0, 2, 1, 3)
conv_out = theano.tensor.nnet.conv.conv2d(X, self.W, border_mode=self.border_mode, subsample=self.subsample)
output = self.activation(conv_out + self.b.dimshuffle('x', 0, 'x', 'x'))
return output
return theano.tensor.reshape(output, (output.shape[0], output.shape[1], output.shape[2])).dimshuffle(0, 2, 1)
def get_config(self):
return {"name":self.__class__.__name__,
"input_dim":self.input_dim,
"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}
"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}
class MaxPooling1D(Layer):
def __init__(self, pool_length=2, ignore_border=True):
def __init__(self, pool_length=2, stride=None, ignore_border=True):
super(MaxPooling1D,self).__init__()
self.pool_length = pool_length
self.stride = stride
if self.stride:
self.st = (1, self.stride)
else:
self.st = None
self.input = T.tensor3()
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
X = theano.tensor.reshape(X, (X.shape[0], X.shape[1], X.shape[2], 1)).dimshuffle(0, 1, 3, 2)
output = downsample.max_pool_2d(X, ds=self.poolsize, st=self.st, ignore_border=self.ignore_border)
output = output.dimshuffle(0, 1, 3, 2)
return theano.tensor.reshape(output, (output.shape[0], output.shape[1], output.shape[2]))
def get_config(self):
return {"name":self.__class__.__name__,
"pool_length":self.pool_length,
"ignore_border":self.ignore_border}
"stride":self.stride,
"pool_length":self.pool_length,
"ignore_border":self.ignore_border,
"subsample_length": self.subsample_length}
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__()
def __init__(self, nb_filter, stack_size, nb_row, nb_col,
init='glorot_uniform', activation='linear', weights=None,
border_mode='valid', subsample=(1, 1),
W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_constraint=None, b_constraint=None):
if border_mode not in {'valid', 'full', 'same'}:
raise Exception('Invalid border mode for Convolution2D:', border_mode)
super(Convolution2D,self).__init__()
self.init = initializations.get(init)
self.activation = activations.get(activation)
self.subsample = subsample
self.border_mode = border_mode
self.image_shape = image_shape
self.nb_filter = nb_filter
self.stack_size = stack_size
self.nb_row = nb_row
self.nb_col = nb_col
@@ -107,19 +139,46 @@ class Convolution2D(Layer):
self.params = [self.W, self.b]
self.regularizers = [W_regularizer, b_regularizer]
self.constraints = [W_constraint, b_constraint]
self.regularizers = []
self.W_regularizer = regularizers.get(W_regularizer)
if self.W_regularizer:
self.W_regularizer.set_param(self.W)
self.regularizers.append(self.W_regularizer)
self.b_regularizer = regularizers.get(b_regularizer)
if self.b_regularizer:
self.b_regularizer.set_param(self.b)
self.regularizers.append(self.b_regularizer)
self.activity_regularizer = regularizers.get(activity_regularizer)
if self.activity_regularizer:
self.activity_regularizer.set_layer(self)
self.regularizers.append(self.activity_regularizer)
self.W_constraint = constraints.get(W_constraint)
self.b_constraint = constraints.get(b_constraint)
self.constraints = [self.W_constraint, self.b_constraint]
if weights is not None:
self.set_weights(weights)
def get_output(self, train):
X = self.get_input(train)
border_mode = self.border_mode
if border_mode == 'same':
border_mode = 'full'
conv_out = theano.tensor.nnet.conv.conv2d(X, self.W,
border_mode=border_mode, subsample=self.subsample)
if self.border_mode == 'same':
shift_x = (self.nb_row - 1) // 2
shift_y = (self.nb_col - 1) // 2
conv_out = conv_out[:, :, shift_x:X.shape[2] + shift_x, shift_y:X.shape[3] + shift_y]
return self.activation(conv_out + self.b.dimshuffle('x', 0, 'x', 'x'))
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'))
return output
def get_config(self):
return {"name":self.__class__.__name__,
@@ -129,33 +188,51 @@ class Convolution2D(Layer):
"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}
"subsample":self.subsample,
"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}
class MaxPooling2D(Layer):
def __init__(self, poolsize=(2, 2), ignore_border=True):
def __init__(self, poolsize=(2, 2), stride=None, ignore_border=True):
super(MaxPooling2D,self).__init__()
self.input = T.tensor4()
self.poolsize = poolsize
self.stride = stride
self.ignore_border = ignore_border
def get_output(self, train):
X = self.get_input(train)
output = downsample.max_pool_2d(X, self.poolsize, ignore_border=self.ignore_border)
output = downsample.max_pool_2d(X, ds=self.poolsize, st=self.stride, ignore_border=self.ignore_border)
return output
def get_config(self):
return {"name":self.__class__.__name__,
"poolsize":self.poolsize,
"ignore_border":self.ignore_border}
"poolsize":self.poolsize,
"ignore_border":self.ignore_border,
"stride": self.stride}
class ZeroPadding2D(Layer):
def __init__(self, width=1):
super(ZeroPadding2D, self).__init__()
self.width = width
self.input = T.tensor4()
# class ZeroPadding2D(Layer): TODO
def get_output(self, train):
X = self.get_input(train)
width = self.width
in_shape = X.shape
out_shape = (in_shape[0], in_shape[1], in_shape[2] + 2 * width, in_shape[3] + 2 * width)
out = T.zeros(out_shape)
indices = (slice(None), slice(None), slice(width, in_shape[2] + width), slice(width, in_shape[3] + width))
return T.set_subtensor(out[indices], X)
# class Convolution3D: TODO
# class MaxPooling3D: TODO
def get_config(self):
return {"name":self.__class__.__name__,
"width":self.width}
+248 -140
Ver Arquivo
@@ -3,33 +3,57 @@ from __future__ import absolute_import, division
import theano
import theano.tensor as T
import numpy as np
from .. import activations, initializations
from .. import activations, initializations, regularizers, constraints
from ..utils.theano_utils import shared_zeros, floatX
from ..utils.generic_utils import make_tuple
from .. import regularizers
from .. import constraints
from ..regularizers import ActivityRegularizer, Regularizer
from theano.sandbox.rng_mrg import MRG_RandomStreams as RandomStreams
from six.moves import zip
srng = RandomStreams()
srng = RandomStreams(seed=np.random.randint(10e6))
class Layer(object):
def __init__(self):
self.params = []
def connect(self, layer):
def set_previous(self, layer):
if not self.supports_masked_input() and layer.get_output_mask() is not None:
raise Exception("Attached non-masking layer to layer with masked output")
self.previous = layer
def get_output(self, train):
raise NotImplementedError
def get_output(self, train=False):
return self.get_input(train)
def get_input(self, train):
def get_input(self, train=False):
if hasattr(self, 'previous'):
return self.previous.get_output(train=train)
else:
return self.input
def supports_masked_input(self):
''' Whether or not this layer respects the output mask of its previous layer in its calculations. If you try
to attach a layer that does *not* support masked_input to a layer that gives a non-None output_mask() that is
an error'''
return False
def get_output_mask(self, train=None):
'''
For some models (such as RNNs) you want a way of being able to mark some output data-points as
"masked", so they are not used in future calculations. In such a model, get_output_mask() should return a mask
of one less dimension than get_output() (so if get_output is (nb_samples, nb_timesteps, nb_dimensions), then the mask
is (nb_samples, nb_timesteps), with a one for every unmasked datapoint, and a zero for every masked one.
If there is *no* masking then it shall return None. For instance if you attach an Activation layer (they support masking)
to a layer with an output_mask, then that Activation shall also have an output_mask. If you attach it to a layer with no
such mask, then the Activation's get_output_mask shall return None.
Some layers have an output_mask even if their input is unmasked, notably Embedding which can turn the entry "0" into
a mask.
'''
return None
def set_weights(self, weights):
for p, w in zip(self.params, weights):
if p.eval().shape != w.shape:
@@ -46,107 +70,131 @@ class Layer(object):
return {"name":self.__class__.__name__}
def get_params(self):
regs = []
consts = []
if hasattr(self, 'regularizers') and len(self.regularizers) == len(self.params):
for r in self.regularizers:
if r:
regs.append(r)
else:
regs.append(regularizers.identity)
elif hasattr(self, 'regularizer') and self.regularizer:
regs += [self.regularizer for _ in range(len(self.params))]
if hasattr(self, 'regularizers'):
regularizers = self.regularizers
else:
regs += [regularizers.identity for _ in range(len(self.params))]
regularizers = []
if hasattr(self, 'constraints') and len(self.constraints) == len(self.params):
for c in self.constraints:
if c:
consts.append(c)
else:
consts.append(constraints.identity)
consts.append(constraints.identity())
elif hasattr(self, 'constraint') and self.constraint:
consts += [self.constraint for _ in range(len(self.params))]
else:
consts += [constraints.identity for _ in range(len(self.params))]
consts += [constraints.identity() for _ in range(len(self.params))]
return self.params, regs, consts
return self.params, regularizers, consts
class MaskedLayer(Layer):
'''
If your layer trivially supports masking (by simply copying the input mask to the output), then subclass MaskedLayer
instead of Layer, and make sure that you incorporate the input mask into your calculation of get_output()
'''
def supports_masked_input(self):
return True
def get_input_mask(self, train=False):
if hasattr(self, 'previous'):
return self.previous.get_output_mask(train)
else:
return None
def get_output_mask(self, train=False):
''' The default output mask is just the input mask unchanged. Override this in your own
implementations if, for instance, you are reshaping the input'''
return self.get_input_mask(train)
class Merge(object):
def __init__(self, models, mode='sum'):
''' Merge the output of a list of models into a single tensor.
def __init__(self, layers, mode='sum'):
''' Merge the output of a list of layers or containers into a single tensor.
mode: {'sum', 'concat'}
'''
if len(models) < 2:
raise Exception("Please specify two or more input models to merge")
if len(layers) < 2:
raise Exception("Please specify two or more input layers (or containers) to merge")
self.mode = mode
self.models = models
self.layers = layers
self.params = []
self.regularizers = []
self.constraints = []
for m in self.models:
self.params += m.params
self.regularizers += m.regularizers
self.constraints += m.constraints
for l in self.layers:
params, regs, consts = l.get_params()
self.regularizers += regs
# params and constraints have the same size
for p, c in zip(params, consts):
if not p in self.params:
self.params.append(p)
self.constraints.append(c)
def get_params(self):
return self.params, self.regularizers, self.constraints
def get_output(self, train=False):
if self.mode == 'sum':
s = self.models[0].get_output(train)
for i in range(1, len(self.models)):
s += self.models[i].get_output(train)
s = self.layers[0].get_output(train)
for i in range(1, len(self.layers)):
s += self.layers[i].get_output(train)
return s
elif self.mode == 'concat':
inputs = [self.models[i].get_output(train) for i in range(len(self.models))]
inputs = [self.layers[i].get_output(train) for i in range(len(self.layers))]
return T.concatenate(inputs, axis=-1)
else:
raise Exception('Unknown merge mode')
def get_input(self, train=False):
res = []
for i in range(len(self.models)):
o = self.models[i].get_input(train)
if type(o) == list:
res += o
else:
res.append(o)
return res
for i in range(len(self.layers)):
o = self.layers[i].get_input(train)
if not type(o) == list:
o = [o]
for output in o:
if output not in res:
res.append(output)
return res
@property
def input(self):
return self.get_input()
def supports_masked_input(self):
return False
def get_output_mask(self, train=None):
return None
def get_weights(self):
weights = []
for m in self.models:
weights += m.get_weights()
for l in self.layers:
weights += l.get_weights()
return weights
def set_weights(self, weights):
for i in range(len(self.models)):
nb_param = len(self.models[i].params)
self.models[i].set_weights(weights[:nb_param])
for i in range(len(self.layers)):
nb_param = len(self.layers[i].params)
self.layers[i].set_weights(weights[:nb_param])
weights = weights[nb_param:]
def get_config(self):
return {"name":self.__class__.__name__,
"models":[m.get_config() for m in self.models],
"layers":[l.get_config() for l in self.layers],
"mode":self.mode}
class Dropout(Layer):
class Dropout(MaskedLayer):
'''
Hinton's dropout.
'''
def __init__(self, p):
super(Dropout,self).__init__()
super(Dropout, self).__init__()
self.p = p
def get_output(self, train):
def get_output(self, train=False):
X = self.get_input(train)
if self.p > 0.:
retain_prob = 1. - self.p
@@ -161,17 +209,17 @@ class Dropout(Layer):
"p":self.p}
class Activation(Layer):
class Activation(MaskedLayer):
'''
Apply an activation function to an output.
'''
def __init__(self, activation, target=0, beta=0.1):
super(Activation,self).__init__()
super(Activation, self).__init__()
self.activation = activations.get(activation)
self.target = target
self.beta = beta
def get_output(self, train):
def get_output(self, train=False):
X = self.get_input(train)
return self.activation(X)
@@ -189,10 +237,10 @@ class Reshape(Layer):
First dimension is assumed to be nb_samples.
'''
def __init__(self, *dims):
super(Reshape,self).__init__()
super(Reshape, self).__init__()
self.dims = dims
def get_output(self, train):
def get_output(self, train=False):
X = self.get_input(train)
nshape = make_tuple(X.shape[0], *self.dims)
return theano.tensor.reshape(X, nshape)
@@ -208,9 +256,9 @@ class Flatten(Layer):
First dimension is assumed to be nb_samples.
'''
def __init__(self):
super(Flatten,self).__init__()
super(Flatten, self).__init__()
def get_output(self, train):
def get_output(self, train=False):
X = self.get_input(train)
size = theano.tensor.prod(X.shape) // X.shape[0]
nshape = (X.shape[0], size)
@@ -225,14 +273,14 @@ class RepeatVector(Layer):
Return tensor of shape (nb_samples, n, dim).
'''
def __init__(self, n):
super(RepeatVector,self).__init__()
super(RepeatVector, self).__init__()
self.n = n
def get_output(self, train):
def get_output(self, train=False):
X = self.get_input(train)
tensors = [X]*self.n
stacked = theano.tensor.stack(*tensors)
return stacked.dimshuffle((1,0,2))
return stacked.dimshuffle((1, 0, 2))
def get_config(self):
return {"name":self.__class__.__name__,
@@ -243,10 +291,10 @@ class Dense(Layer):
'''
Just your regular fully connected NN layer.
'''
def __init__(self, input_dim, output_dim, init='glorot_uniform', activation='linear', weights=None,
W_regularizer=None, b_regularizer=None, W_constraint=None, b_constraint=None):
def __init__(self, input_dim, output_dim, init='glorot_uniform', activation='linear', weights=None, name=None,
W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_constraint=None, b_constraint=None):
super(Dense,self).__init__()
super(Dense, self).__init__()
self.init = initializations.get(init)
self.activation = activations.get(activation)
self.input_dim = input_dim
@@ -258,13 +306,38 @@ class Dense(Layer):
self.params = [self.W, self.b]
self.regularizers = [W_regularizer, b_regularizer]
self.constraints = [W_constraint, b_constraint]
self.regularizers = []
self.W_regularizer = regularizers.get(W_regularizer)
if self.W_regularizer:
self.W_regularizer.set_param(self.W)
self.regularizers.append(self.W_regularizer)
self.b_regularizer = regularizers.get(b_regularizer)
if self.b_regularizer:
self.b_regularizer.set_param(self.b)
self.regularizers.append(self.b_regularizer)
self.activity_regularizer = regularizers.get(activity_regularizer)
if self.activity_regularizer:
self.activity_regularizer.set_layer(self)
self.regularizers.append(self.activity_regularizer)
self.W_constraint = constraints.get(W_constraint)
self.b_constraint = constraints.get(b_constraint)
self.constraints = [self.W_constraint, self.b_constraint]
if weights is not None:
self.set_weights(weights)
def get_output(self, train):
if name is not None:
self.set_name(name)
def set_name(self, name):
self.W.name = '%s_W' % name
self.b.name = '%s_b' % name
def get_output(self, train=False):
X = self.get_input(train)
output = self.activation(T.dot(X, self.W) + self.b)
return output
@@ -274,10 +347,38 @@ class Dense(Layer):
"input_dim":self.input_dim,
"output_dim":self.output_dim,
"init":self.init.__name__,
"activation":self.activation.__name__}
"activation":self.activation.__name__,
"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}
class TimeDistributedDense(Layer):
class ActivityRegularization(Layer):
'''
Layer that passes through its input unchanged, but applies an update
to the cost function based on the activity.
'''
def __init__(self, l1=0., l2=0.):
super(ActivityRegularization, self).__init__()
self.l1 = l1
self.l2 = l2
activity_regularizer = ActivityRegularizer(l1=l1, l2=l2)
activity_regularizer.set_layer(self)
self.regularizers = [activity_regularizer]
def get_output(self, train=False):
return self.get_input(train)
def get_config(self):
return {"name":self.__class__.__name__,
"l1":self.l1,
"l2":self.l2}
class TimeDistributedDense(MaskedLayer):
'''
Apply a same DenseLayer for each dimension[1] (shared_dimension) input
Especially useful after a recurrent network with 'return_sequence=True'
@@ -286,9 +387,9 @@ class TimeDistributedDense(Layer):
'''
def __init__(self, input_dim, output_dim, init='glorot_uniform', activation='linear', weights=None,
W_regularizer=None, b_regularizer=None, W_constraint=None, b_constraint=None):
W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_constraint=None, b_constraint=None):
super(TimeDistributedDense,self).__init__()
super(TimeDistributedDense, self).__init__()
self.init = initializations.get(init)
self.activation = activations.get(activation)
self.input_dim = input_dim
@@ -300,29 +401,48 @@ class TimeDistributedDense(Layer):
self.params = [self.W, self.b]
self.regularizers = [W_regularizer, b_regularizer]
self.constraints = [W_constraint, b_constraint]
self.regularizers = []
self.W_regularizer = regularizers.get(W_regularizer)
if self.W_regularizer:
self.W_regularizer.set_param(self.W)
self.regularizers.append(self.W_regularizer)
self.b_regularizer = regularizers.get(b_regularizer)
if self.b_regularizer:
self.b_regularizer.set_param(self.b)
self.regularizers.append(self.b_regularizer)
self.activity_regularizer = regularizers.get(activity_regularizer)
if self.activity_regularizer:
self.activity_regularizer.set_layer(self)
self.regularizers.append(self.activity_regularizer)
self.W_constraint = constraints.get(W_constraint)
self.b_constraint = constraints.get(b_constraint)
self.constraints = [self.W_constraint, self.b_constraint]
if weights is not None:
self.set_weights(weights)
def get_output(self, train):
def get_output(self, train=False):
X = self.get_input(train)
output = self.activation(T.dot(X.dimshuffle(1, 0, 2), self.W) + self.b)
return output.dimshuffle(1, 0, 2)
def act_func(X):
return self.activation(T.dot(X, self.W) + self.b)
output, _ = theano.scan(fn = act_func,
sequences = X.dimshuffle(1,0,2),
outputs_info=None)
return output.dimshuffle(1,0,2)
def get_config(self):
return {"name":self.__class__.__name__,
"input_dim":self.input_dim,
"output_dim":self.output_dim,
"init":self.init.__name__,
"activation":self.activation.__name__}
"activation":self.activation.__name__,
"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}
class AutoEncoder(Layer):
'''
@@ -330,32 +450,32 @@ class AutoEncoder(Layer):
If output_reconstruction then dim(input) = dim(output)
else dim(output) = dim(hidden)
'''
def __init__(self, encoder, decoder, output_reconstruction=True, tie_weights=False, weights=None):
def __init__(self, encoder, decoder, output_reconstruction=True, weights=None):
super(AutoEncoder,self).__init__()
super(AutoEncoder, self).__init__()
self.output_reconstruction = output_reconstruction
self.tie_weights = tie_weights
self.encoder = encoder
self.decoder = decoder
self.decoder.connect(self.encoder)
self.decoder.set_previous(self.encoder)
self.params = []
self.regularizers = []
self.constraints = []
for layer in [self.encoder, self.decoder]:
self.params += layer.params
if hasattr(layer, 'regularizers'):
self.regularizers += layer.regularizers
if hasattr(layer, 'constraints'):
self.constraints += layer.constraints
params, regularizers, constraints = layer.get_params()
self.constraints += constraints
for p, r in zip(params, regularizers):
if p not in self.params:
self.params.append(p)
self.regularizers.append(r)
if weights is not None:
self.set_weights(weights)
def connect(self, node):
self.encoder.previous = node
def set_previous(self, node):
self.encoder.set_previous(node)
def get_weights(self):
weights = []
@@ -375,57 +495,22 @@ class AutoEncoder(Layer):
def input(self):
return self.encoder.input
def _get_hidden(self, train):
def _get_hidden(self, train=False):
return self.encoder.get_output(train)
def get_output(self, train):
decoded = self.decoder.get_output(train)
def get_output(self, train=False):
if not train and not self.output_reconstruction:
return self.encoder.get_output(train)
if self.tie_weights:
encoder_params = self.encoder.get_weights()
decoder_params = self.decoder.get_weights()
for dec_param, enc_param in zip(decoder_params, encoder_params):
if len(dec_param.shape) > 1:
enc_param = dec_param.T
return decoded
return self.decoder.get_output(train)
def get_config(self):
return {"name":self.__class__.__name__,
"encoder_config":self.encoder.get_config(),
"decoder_config":self.decoder.get_config(),
"output_reconstruction":self.output_reconstruction,
"tie_weights":self.tie_weights}
"output_reconstruction":self.output_reconstruction}
class DenoisingAutoEncoder(AutoEncoder):
'''
A denoising autoencoder model that inherits the base features from autoencoder
'''
def __init__(self, encoder=None, decoder=None, output_reconstruction=True, tie_weights=False, weights=None, corruption_level=0.3):
super(DenoisingAutoEncoder, self).__init__(encoder, decoder, output_reconstruction, tie_weights, weights)
self.corruption_level = corruption_level
def _get_corrupted_input(self, input):
"""
http://deeplearning.net/tutorial/dA.html
"""
return srng.binomial(size=(self.input_dim, 1), n=1,
p=1-self.corruption_level,
dtype=theano.config.floatX) * input
def get_input(self, train=False):
uncorrupted_input = super(DenoisingAutoEncoder, self).get_input(train)
return self._get_corrupted_input(uncorrupted_input)
def get_config(self):
return {"name":self.__class__.__name__,
"encoder_config":self.encoder.get_config(),
"decoder_config":self.decoder.get_config(),
"corruption_level":self.corruption_level,
"output_reconstruction":self.output_reconstruction,
"tie_weights":self.tie_weights}
class MaxoutDense(Layer):
'''
@@ -433,9 +518,9 @@ class MaxoutDense(Layer):
Refer to http://arxiv.org/pdf/1302.4389.pdf
'''
def __init__(self, input_dim, output_dim, nb_feature=4, init='glorot_uniform', weights=None,
W_regularizer=None, b_regularizer=None, W_constraint=None, b_constraint=None):
W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_constraint=None, b_constraint=None):
super(MaxoutDense,self).__init__()
super(MaxoutDense, self).__init__()
self.init = initializations.get(init)
self.input_dim = input_dim
self.output_dim = output_dim
@@ -447,13 +532,31 @@ class MaxoutDense(Layer):
self.params = [self.W, self.b]
self.regularizers = [W_regularizer, b_regularizer]
self.constraints = [W_constraint, b_constraint]
self.regularizers = []
self.W_regularizer = regularizers.get(W_regularizer)
if self.W_regularizer:
self.W_regularizer.set_param(self.W)
self.regularizers.append(self.W_regularizer)
self.b_regularizer = regularizers.get(b_regularizer)
if self.b_regularizer:
self.b_regularizer.set_param(self.b)
self.regularizers.append(self.b_regularizer)
self.activity_regularizer = regularizers.get(activity_regularizer)
if self.activity_regularizer:
self.activity_regularizer.set_layer(self)
self.regularizers.append(self.activity_regularizer)
self.W_constraint = constraints.get(W_constraint)
self.b_constraint = constraints.get(b_constraint)
self.constraints = [self.W_constraint, self.b_constraint]
if weights is not None:
self.set_weights(weights)
def get_output(self, train):
def get_output(self, train=False):
X = self.get_input(train)
# -- don't need activation since it's just linear.
output = T.max(T.dot(X, self.W) + self.b, axis=1)
@@ -464,4 +567,9 @@ class MaxoutDense(Layer):
"input_dim":self.input_dim,
"output_dim":self.output_dim,
"init":self.init.__name__,
"nb_feature" : self.nb_feature}
"nb_feature" : self.nb_feature,
"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}
+36 -6
Ver Arquivo
@@ -2,8 +2,10 @@ from __future__ import absolute_import
import theano
import theano.tensor as T
from .. import activations, initializations
from ..layers.core import Layer
from .. import activations, initializations, regularizers, constraints
from ..layers.core import Layer, MaskedLayer
from ..utils.theano_utils import sharedX
from ..constraints import unitnorm
@@ -15,7 +17,10 @@ class Embedding(Layer):
@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):
def __init__(self, input_dim, output_dim, init='uniform',
W_regularizer=None, activity_regularizer=None, W_constraint=None,
mask_zero=False, weights=None):
super(Embedding,self).__init__()
self.init = initializations.get(init)
self.input_dim = input_dim
@@ -23,13 +28,35 @@ class Embedding(Layer):
self.input = T.imatrix()
self.W = self.init((self.input_dim, self.output_dim))
self.mask_zero = mask_zero
self.params = [self.W]
self.constraints = [W_constraint]
self.regularizers = [W_regularizer]
self.W_constraint = constraints.get(W_constraint)
self.constraints = [self.W_constraint]
self.regularizers = []
self.W_regularizer = regularizers.get(W_regularizer)
if self.W_regularizer:
self.W_regularizer.set_param(self.W)
self.regularizers.append(self.W_regularizer)
self.activity_regularizer = regularizers.get(activity_regularizer)
if self.activity_regularizer:
self.activity_regularizer.set_layer(self)
self.regularizers.append(self.activity_regularizer)
if weights is not None:
self.set_weights(weights)
def get_output_mask(self, train=None):
X = self.get_input(train)
if not self.mask_zero:
return None
else:
return T.ones_like(X) * (1 - T.eq(X,0))
def get_output(self, train=False):
X = self.get_input(train)
out = self.W[X]
@@ -39,7 +66,10 @@ class Embedding(Layer):
return {"name":self.__class__.__name__,
"input_dim":self.input_dim,
"output_dim":self.output_dim,
"init":self.init.__name__}
"init":self.init.__name__,
"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}
class WordContextProduct(Layer):
+47
Ver Arquivo
@@ -0,0 +1,47 @@
from __future__ import absolute_import
from .core import srng, MaskedLayer
import theano
import theano.tensor as T
class GaussianNoise(MaskedLayer):
'''
Corruption process with GaussianNoise
'''
def __init__(self, sigma):
super(GaussianNoise, self).__init__()
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 + srng.normal(size=X.shape, avg=0.0, std=self.sigma,
dtype=theano.config.floatX)
def get_config(self):
return {"name":self.__class__.__name__,
"sigma":self.sigma}
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):
super(GaussianDropout,self).__init__()
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) to match Dropout layer syntax
X *= srng.normal(size=X.shape, avg=1.0, std=T.sqrt(self.p / (1.0 - self.p)), dtype=theano.config.floatX)
return X
def get_config(self):
return {"name":self.__class__.__name__,
"p":self.p}
+37 -1
Ver Arquivo
@@ -6,7 +6,7 @@ import theano.tensor as T
class BatchNormalization(Layer):
'''
Reference:
Reference:
Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift
http://arxiv.org/pdf/1502.03167v3.pdf
@@ -67,3 +67,39 @@ class BatchNormalization(Layer):
"input_shape":self.input_shape,
"epsilon":self.epsilon,
"mode":self.mode}
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):
if n % 2 == 0:
raise NotImplementedError("LRN2D only works with odd n. n provided: " + str(n))
super(LRN2D, self).__init__()
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 = X.shape
half_n = self.n // 2
input_sqr = T.sqr(X)
extra_channels = T.alloc(0., b, ch + 2*half_n, r, c)
input_sqr = T.set_subtensor(extra_channels[:, half_n:half_n+ch, :, :], input_sqr)
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):
return {"name":self.__class__.__name__,
"alpha":self.alpha,
"k":self.k,
"beta":self.beta,
"n": self.n}
+412 -45
Ver Arquivo
@@ -5,11 +5,35 @@ import theano.tensor as T
import numpy as np
from .. import activations, initializations
from ..utils.theano_utils import shared_zeros, alloc_zeros_matrix
from ..layers.core import Layer
from ..utils.theano_utils import shared_scalar, shared_zeros, alloc_zeros_matrix
from ..layers.core import Layer, MaskedLayer
from six.moves import range
class SimpleRNN(Layer):
class Recurrent(MaskedLayer):
def get_output_mask(self, train=None):
if self.return_sequences:
return super(Recurrent, self).get_output_mask(train)
else:
return None
def get_padded_shuffled_mask(self, train, X, pad=0):
mask = self.get_input_mask(train)
if mask is None:
mask = T.ones_like(X.sum(axis=-1)) # is there a better way to do this without a sum?
# mask is (nb_samples, time)
mask = T.shape_padright(mask) # (nb_samples, time, 1)
mask = T.addbroadcast(mask, -1) # (time, nb_samples, 1) matrix.
mask = mask.dimshuffle(1, 0, 2) # (time, nb_samples, 1)
if pad > 0:
# left-pad in time with 0
padding = alloc_zeros_matrix(pad, mask.shape[1], 1)
mask = T.concatenate([padding, mask], axis=0)
return mask.astype('int8')
class SimpleRNN(Recurrent):
'''
Fully connected RNN where output is to fed back to input.
@@ -20,6 +44,7 @@ class SimpleRNN(Layer):
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__()
self.init = initializations.get(init)
self.inner_init = initializations.get(inner_init)
@@ -38,19 +63,19 @@ class SimpleRNN(Layer):
if weights is not None:
self.set_weights(weights)
def _step(self, x_t, h_tm1, u):
def _step(self, x_t, mask_tm1, 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))
return self.activation(x_t + mask_tm1 * 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)
def get_output(self, train=False):
X = self.get_input(train) # shape: (nb_samples, time (padded with zeros), input_dim)
# new shape: (time, nb_samples, input_dim) -> because theano.scan iterates over main dimension
X = X.dimshuffle((1,0,2))
padded_mask = self.get_padded_shuffled_mask(train, X, pad=1)
X = X.dimshuffle((1, 0, 2))
x = T.dot(X, self.W) + self.b
# scan = theano symbolic loop.
@@ -58,14 +83,15 @@ class SimpleRNN(Layer):
# 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
sequences=[x, dict(input=padded_mask, taps=[-1])], # 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.dimshuffle((1, 0, 2))
return outputs[-1]
def get_config(self):
@@ -79,7 +105,7 @@ class SimpleRNN(Layer):
"return_sequences":self.return_sequences}
class SimpleDeepRNN(Layer):
class SimpleDeepRNN(Recurrent):
'''
Fully connected RNN where the output of multiple timesteps
(up to "depth" steps in the past) is fed back to the input:
@@ -93,6 +119,7 @@ class SimpleDeepRNN(Layer):
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)
@@ -113,30 +140,43 @@ class SimpleDeepRNN(Layer):
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]))
def _step(self, x_t, *args):
o = x_t
for i in range(self.depth):
mask_tmi = args[i]
h_tmi = args[i + self.depth]
U_tmi = args[i + 2*self.depth]
o += mask_tmi*self.inner_activation(T.dot(h_tmi, U_tmi))
return self.activation(o)
def get_output(self, train):
def get_output(self, train=False):
X = self.get_input(train)
X = X.dimshuffle((1,0,2))
padded_mask = self.get_padded_shuffled_mask(train, X, pad=self.depth)
X = X.dimshuffle((1, 0, 2))
x = T.dot(X, self.W) + self.b
if self.depth == 1:
initial = T.unbroadcast(alloc_zeros_matrix(X.shape[1], self.output_dim), 1)
else:
initial = T.unbroadcast(T.unbroadcast(alloc_zeros_matrix(self.depth, X.shape[1], self.output_dim), 0), 2)
outputs, updates = theano.scan(
self._step,
sequences=x,
sequences=[x, dict(
input = padded_mask,
taps = [(-i) for i in range(self.depth)]
)],
outputs_info=[dict(
initial=T.alloc(np.cast[theano.config.floatX](0.), self.depth, X.shape[1], self.output_dim),
initial = initial,
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.dimshuffle((1, 0, 2))
return outputs[-1]
def get_config(self):
@@ -152,8 +192,7 @@ class SimpleDeepRNN(Layer):
"return_sequences":self.return_sequences}
class GRU(Layer):
class GRU(Recurrent):
'''
Gated Recurrent Unit - Cho et al. 2014
@@ -214,31 +253,34 @@ class GRU(Layer):
self.set_weights(weights)
def _step(self,
xz_t, xr_t, xh_t,
xz_t, xr_t, xh_t, mask_tm1,
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
h_mask_tm1 = mask_tm1 * h_tm1
z = self.inner_activation(xz_t + T.dot(h_mask_tm1, u_z))
r = self.inner_activation(xr_t + T.dot(h_mask_tm1, u_r))
hh_t = self.activation(xh_t + T.dot(r * h_mask_tm1, u_h))
h_t = z * h_mask_tm1 + (1 - z) * hh_t
return h_t
def get_output(self, train):
def get_output(self, train=False):
X = self.get_input(train)
X = X.dimshuffle((1,0,2))
padded_mask = self.get_padded_shuffled_mask(train, X, pad=1)
X = X.dimshuffle((1, 0, 2))
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],
sequences=[x_z, x_r, x_h, padded_mask],
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.dimshuffle((1, 0, 2))
return outputs[-1]
def get_config(self):
@@ -254,7 +296,7 @@ class GRU(Layer):
class LSTM(Layer):
class LSTM(Recurrent):
'''
Acts as a spatiotemporal projection,
turning a sequence of vectors into a single vector.
@@ -280,7 +322,7 @@ class LSTM(Layer):
http://www.cs.toronto.edu/~graves/preprint.pdf
'''
def __init__(self, input_dim, output_dim=128,
init='glorot_uniform', inner_init='orthogonal',
init='glorot_uniform', inner_init='orthogonal', forget_bias_init='one',
activation='tanh', inner_activation='hard_sigmoid',
weights=None, truncate_gradient=-1, return_sequences=False):
@@ -292,6 +334,7 @@ class LSTM(Layer):
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()
@@ -302,7 +345,7 @@ class LSTM(Layer):
self.W_f = self.init((self.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.U_c = self.inner_init((self.output_dim, self.output_dim))
@@ -323,19 +366,23 @@ class LSTM(Layer):
self.set_weights(weights)
def _step(self,
xi_t, xf_t, xo_t, xc_t,
xi_t, xf_t, xo_t, xc_t, mask_tm1,
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_mask_tm1 = mask_tm1 * h_tm1
c_mask_tm1 = mask_tm1 * c_tm1
i_t = self.inner_activation(xi_t + T.dot(h_mask_tm1, u_i))
f_t = self.inner_activation(xf_t + T.dot(h_mask_tm1, u_f))
c_t = f_t * c_mask_tm1 + i_t * self.activation(xc_t + T.dot(h_mask_tm1, u_c))
o_t = self.inner_activation(xo_t + T.dot(h_mask_tm1, u_o))
h_t = o_t * self.activation(c_t)
return h_t, c_t
def get_output(self, train):
def get_output(self, train=False):
X = self.get_input(train)
X = X.dimshuffle((1,0,2))
padded_mask = self.get_padded_shuffled_mask(train, X, pad=1)
X = X.dimshuffle((1, 0, 2))
xi = T.dot(X, self.W_i) + self.b_i
xf = T.dot(X, self.W_f) + self.b_f
@@ -344,7 +391,7 @@ class LSTM(Layer):
[outputs, memories], updates = theano.scan(
self._step,
sequences=[xi, xf, xo, xc],
sequences=[xi, xf, xo, xc, padded_mask],
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)
@@ -352,8 +399,117 @@ class LSTM(Layer):
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.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,
"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__,
"truncate_gradient":self.truncate_gradient,
"return_sequences":self.return_sequences}
class JZS1(Recurrent):
'''
Evolved recurrent neural network architectures from the evaluation of thousands
of models, serving as alternatives to LSTMs and GRUs. See Jozefowicz et al. 2015.
This corresponds to the `MUT1` architecture described in the paper.
Takes inputs with shape:
(nb_samples, max_sample_length (samples shorter than this are padded with zeros at the end), input_dim)
and returns outputs with shape:
if not return_sequences:
(nb_samples, output_dim)
if return_sequences:
(nb_samples, max_sample_length, output_dim)
References:
An Empirical Exploration of Recurrent Network Architectures
http://www.jmlr.org/proceedings/papers/v37/jozefowicz15.pdf
'''
def __init__(self, input_dim, output_dim=128,
init='glorot_uniform', inner_init='orthogonal',
activation='tanh', inner_activation='sigmoid',
weights=None, truncate_gradient=-1, return_sequences=False):
super(JZS1,self).__init__()
self.input_dim = input_dim
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()
self.W_z = self.init((self.input_dim, self.output_dim))
self.b_z = shared_zeros((self.output_dim))
self.W_r = self.init((self.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.U_h = self.inner_init((self.output_dim, self.output_dim))
self.b_h = shared_zeros((self.output_dim))
# P_h used to project X onto different dimension, using sparse random projections
if self.input_dim == self.output_dim:
self.Pmat = theano.shared(np.identity(self.output_dim, dtype=theano.config.floatX), name=None)
else:
P = np.random.binomial(1, 0.5, size=(self.input_dim, self.output_dim)).astype(theano.config.floatX) * 2 - 1
P = 1 / np.sqrt(self.input_dim) * P
self.Pmat = theano.shared(P, name=None)
self.params = [
self.W_z, self.b_z,
self.W_r, self.U_r, self.b_r,
self.U_h, self.b_h,
]
if weights is not None:
self.set_weights(weights)
def _step(self,
xz_t, xr_t, xh_t, mask_tm1,
h_tm1,
u_r, u_h):
h_mask_tm1 = mask_tm1 * h_tm1
z = self.inner_activation(xz_t)
r = self.inner_activation(xr_t + T.dot(h_mask_tm1, u_r))
hh_t = self.activation(xh_t + T.dot(r * h_mask_tm1, u_h))
h_t = hh_t * z + h_mask_tm1 * (1 - z)
return h_t
def get_output(self, train=False):
X = self.get_input(train)
padded_mask = self.get_padded_shuffled_mask(train, X, pad=1)
X = X.dimshuffle((1, 0, 2))
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.tanh(T.dot(X, self.Pmat)) + self.b_h
outputs, updates = theano.scan(
self._step,
sequences=[x_z, x_r, x_h, padded_mask],
outputs_info=T.unbroadcast(alloc_zeros_matrix(X.shape[1], self.output_dim), 1),
non_sequences=[self.U_r, self.U_h],
truncate_gradient=self.truncate_gradient
)
if self.return_sequences:
return outputs.dimshuffle((1, 0, 2))
return outputs[-1]
def get_config(self):
@@ -366,5 +522,216 @@ class LSTM(Layer):
"inner_activation":self.inner_activation.__name__,
"truncate_gradient":self.truncate_gradient,
"return_sequences":self.return_sequences}
class JZS2(Recurrent):
'''
Evolved recurrent neural network architectures from the evaluation of thousands
of models, serving as alternatives to LSTMs and GRUs. See Jozefowicz et al. 2015.
This corresponds to the `MUT2` architecture described in the paper.
Takes inputs with shape:
(nb_samples, max_sample_length (samples shorter than this are padded with zeros at the end), input_dim)
and returns outputs with shape:
if not return_sequences:
(nb_samples, output_dim)
if return_sequences:
(nb_samples, max_sample_length, output_dim)
References:
An Empirical Exploration of Recurrent Network Architectures
http://www.jmlr.org/proceedings/papers/v37/jozefowicz15.pdf
'''
def __init__(self, input_dim, output_dim=128,
init='glorot_uniform', inner_init='orthogonal',
activation='tanh', inner_activation='sigmoid',
weights=None, truncate_gradient=-1, return_sequences=False):
super(JZS2,self).__init__()
self.input_dim = input_dim
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()
self.W_z = self.init((self.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.U_r = self.inner_init((self.output_dim, self.output_dim))
self.b_r = shared_zeros((self.output_dim))
self.W_h = self.init((self.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))
# P_h used to project X onto different dimension, using sparse random projections
if self.input_dim == self.output_dim:
self.Pmat = theano.shared(np.identity(self.output_dim, dtype=theano.config.floatX), name=None)
else:
P = np.random.binomial(1, 0.5, size=(self.input_dim, self.output_dim)).astype(theano.config.floatX) * 2 - 1
P = 1 / np.sqrt(self.input_dim) * P
self.Pmat = theano.shared(P, name=None)
self.params = [
self.W_z, self.U_z, self.b_z,
self.U_r, self.b_r,
self.W_h, self.U_h, self.b_h,
]
if weights is not None:
self.set_weights(weights)
def _step(self,
xz_t, xr_t, xh_t, mask_tm1,
h_tm1,
u_z, u_r, u_h):
h_mask_tm1 = mask_tm1 * h_tm1
z = self.inner_activation(xz_t + T.dot(h_mask_tm1, u_z))
r = self.inner_activation(xr_t + T.dot(h_mask_tm1, u_r))
hh_t = self.activation(xh_t + T.dot(r * h_mask_tm1, u_h))
h_t = hh_t * z + h_mask_tm1 * (1 - z)
return h_t
def get_output(self, train=False):
X = self.get_input(train)
padded_mask = self.get_padded_shuffled_mask(train, X, pad=1)
X = X.dimshuffle((1, 0, 2))
x_z = T.dot(X, self.W_z) + self.b_z
x_r = T.dot(X, self.Pmat) + 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, padded_mask],
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]
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}
class JZS3(Recurrent):
'''
Evolved recurrent neural network architectures from the evaluation of thousands
of models, serving as alternatives to LSTMs and GRUs. See Jozefowicz et al. 2015.
This corresponds to the `MUT3` architecture described in the paper.
Takes inputs with shape:
(nb_samples, max_sample_length (samples shorter than this are padded with zeros at the end), input_dim)
and returns outputs with shape:
if not return_sequences:
(nb_samples, output_dim)
if return_sequences:
(nb_samples, max_sample_length, output_dim)
References:
An Empirical Exploration of Recurrent Network Architectures
http://www.jmlr.org/proceedings/papers/v37/jozefowicz15.pdf
'''
def __init__(self, input_dim, output_dim=128,
init='glorot_uniform', inner_init='orthogonal',
activation='tanh', inner_activation='sigmoid',
weights=None, truncate_gradient=-1, return_sequences=False):
super(JZS3,self).__init__()
self.input_dim = input_dim
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()
self.W_z = self.init((self.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.W_r = self.init((self.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.W_h = self.init((self.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.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)
def _step(self,
xz_t, xr_t, xh_t, mask_tm1,
h_tm1,
u_z, u_r, u_h):
h_mask_tm1 = mask_tm1 * h_tm1
z = self.inner_activation(xz_t + T.dot(T.tanh(h_mask_tm1), u_z))
r = self.inner_activation(xr_t + T.dot(h_mask_tm1, u_r))
hh_t = self.activation(xh_t + T.dot(r * h_mask_tm1, u_h))
h_t = hh_t * z + h_mask_tm1 * (1 - z)
return h_t
def get_output(self, train=False):
X = self.get_input(train)
padded_mask = self.get_padded_shuffled_mask(train, X, pad=1)
X = X.dimshuffle((1, 0, 2))
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, padded_mask],
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]
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}
+473 -179
Ver Arquivo
@@ -3,32 +3,41 @@ from __future__ import print_function
import theano
import theano.tensor as T
import numpy as np
import warnings, time, copy
import warnings, time, copy, yaml
from . import optimizers
from . import objectives
from . import regularizers
from . import constraints
from . import callbacks as cbks
import time, copy, pprint
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 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)]
def standardize_X(X):
if type(X) == list:
return X
else:
return [X]
def slice_X(X, start=None, stop=None):
if type(X) == list:
if hasattr(start, '__len__'):
@@ -42,13 +51,236 @@ def slice_X(X, start=None, stop=None):
return X[start:stop]
def weighted_objective(fn):
def weighted(y_true, y_pred, weights):
# it's important that 0 * Inf == 0, not NaN, so I need to mask first
masked_y_true = y_true[weights.nonzero()[:-1]]
masked_y_pred = y_pred[weights.nonzero()[:-1]]
masked_weights = weights[weights.nonzero()]
obj_output = fn(masked_y_true, masked_y_pred)
return (masked_weights.flatten() * obj_output.flatten()).mean()
return weighted
def standardize_weights(y, sample_weight=None, class_weight=None):
if sample_weight is not None:
return standardize_y(sample_weight)
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
return np.expand_dims(np.array(list(map(lambda x: class_weight[x], y_classes))), 1)
else:
return np.ones(y.shape[:-1] + (1,))
def model_from_yaml(yaml_string):
'''
Returns a model generated from a local yaml file,
which is either created by hand or from to_yaml method of Sequential or Graph
'''
model_params = yaml.load(yaml_string)
model_name = model_params.get('name')
if not model_name in {'Graph', 'Sequential'}:
raise Exception('Unrecognized model:', model_name)
# Create a container then set class to appropriate model
model = container_from_config(model_params)
model.__class__ = get(model_name)
if 'optimizer' in model_params: # if it has an optimizer, the model is assumed to be compiled
loss = objectives.get(model_params.get('loss'))
class_mode = model_params.get('class_mode')
theano_mode = model_params.get('theano_mode')
optimizer_params = model_params.get('optimizer')
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
class Model(object):
def _fit(self, f, ins, out_labels=[], batch_size=128, nb_epoch=100, verbose=1, callbacks=[], \
validation_split=0., 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])))
else:
if 0 < validation_split < 1:
do_validation = True
split_at = int(len(ins[0]) * (1 - validation_split))
(ins, val_ins) = (slice_X(ins, 0, split_at), slice_X(ins, split_at))
if verbose:
print("Train on %d samples, validate on %d samples" % (len(ins[0]), len(val_ins[0])))
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:
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]
ins_batch = slice_X(ins, batch_ids)
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)
if batch_index == len(batches) - 1: # last batch
# validation
epoch_logs = {}
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()
if verbose:
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(config)
return config
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.unweighted_loss = objectives.get(loss)
self.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)
@@ -58,8 +290,14 @@ class Model(object):
# target of model
self.y = T.zeros_like(self.y_train)
train_loss = self.loss(self.y, self.y_train)
test_score = self.loss(self.y, self.y_test)
self.weights = T.ones_like(self.y_train)
train_loss = self.loss(self.y, self.y_train, self.weights)
test_loss = self.loss(self.y, self.y_test, self.weights)
train_loss.name = 'train_loss'
test_loss.name = 'test_loss'
self.y.name = 'y'
if class_mode == "categorical":
train_accuracy = T.mean(T.eq(T.argmax(self.y, axis=-1), T.argmax(self.y_train, axis=-1)))
@@ -71,160 +309,114 @@ class Model(object):
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)
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]
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,
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],
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,
self._predict = theano.function(predict_ins, self.y_test,
allow_input_downcast=True, mode=theano_mode)
self._test = theano.function(test_ins, test_score,
self._test = theano.function(test_ins, test_loss,
allow_input_downcast=True, mode=theano_mode)
self._test_with_acc = theano.function(test_ins, [test_score, test_accuracy],
self._test_with_acc = theano.function(test_ins, [test_loss, test_accuracy],
allow_input_downcast=True, mode=theano_mode)
def train(self, X, y, accuracy=False, sample_weight=None):
warnings.warn('The "train" method is deprecated, use "train_on_batch" instead.')
return self.train_on_batch(X, y, accuracy, sample_weight)
def train(self, X, y, accuracy=False):
def test(self, X, y, accuracy=False):
warnings.warn('The "test" method is deprecated, use "test_on_batch" instead.')
return self.test_on_batch(X, y, accuracy)
def train_on_batch(self, X, y, accuracy=False, sample_weight=None):
X = standardize_X(X)
y = standardize_y(y)
ins = X + [y]
if sample_weight is None:
sample_weight = np.ones(list(y.shape[0:-1]) + [1])
else:
sample_weight = standardize_y(sample_weight)
ins = X + [y, sample_weight]
if accuracy:
return self._train_with_acc(*ins)
else:
return self._train(*ins)
def test(self, X, y, accuracy=False):
def test_on_batch(self, X, y, accuracy=False):
X = standardize_X(X)
y = standardize_y(y)
ins = X + [y]
sample_weight = np.ones(y.shape[:-1] + (1,))
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)
sample_weight = standardize_weights(y, class_weight=class_weight, sample_weight=sample_weight)
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:
X_val, y_val = validation_data
except:
raise Exception("Invalid format for validation data; provide a tuple (X_val, y_val). \
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, np.ones(y_val.shape[:-1] + (1,))]
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))
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, \
validation_split=validation_split, 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)
return self._predict_loop(self._predict, X, batch_size, verbose)[0]
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
def predict_proba(self, X, batch_size=128, verbose=1):
preds = self.predict(X, batch_size, verbose)
@@ -241,77 +433,21 @@ class Model(object):
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):
@@ -344,7 +480,12 @@ class Sequential(Model, containers.Sequential):
f.flush()
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 +494,157 @@ 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()
def to_yaml(self):
'''
Stores a model to yaml string, optionally with all learnable parameters
If the model is compiled, it will also serialize the necessary components
'''
model_params = self.get_config()
if hasattr(self, 'optimizer'):
model_params['class_mode'] = self.class_mode
model_params['theano_mode'] = self.theano_mode
model_params['loss'] = self.unweighted_loss.__name__
model_params['optimizer'] = self.optimizer.get_config()
return yaml.dump(model_params)
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 = []
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 = T.zeros_like(y_test)
ys.append(y)
ys_train.append(y_train)
ys_test.append(y_test)
train_loss += objectives.get(loss_fn)(y, y_train).mean()
test_loss += objectives.get(loss_fn)(y, y_test).mean()
train_loss.name = 'train_loss'
test_loss.name = 'test_loss'
ins = [self.inputs[name].input for name in self.input_order]
train_ins = ins + ys
test_ins = ins + ys
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)
self.theano_mode = theano_mode
self.loss = loss
self._train = theano.function(train_ins, train_loss,
updates=updates, allow_input_downcast=True, mode=theano_mode)
self._test = theano.function(test_ins, test_loss,
allow_input_downcast=True, mode=theano_mode)
self._predict = theano.function(inputs=ins, outputs=ys_test,
allow_input_downcast=True, mode=theano_mode)
def train_on_batch(self, data):
# data is a dictionary mapping output and input names to arrays
ins = [data[name] for name in self.input_order] + [standardize_y(data[name]) for name in self.output_order]
return self._train(*ins)
def test_on_batch(self, data):
# data is a dictionary mapping input names to arrays
ins = [data[name] for name in self.input_order] + [standardize_y(data[name]) for name in self.output_order]
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):
ins = [data[name] for name in self.input_order] + [standardize_y(data[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:
val_ins = [validation_data[name] for name in self.input_order] + [standardize_y(validation_data[name]) for name in self.output_order]
f = self._train
out_labels = self.output_order
metrics = self.output_order + ['val_' + m for m in self.output_order]
history = self._fit(f, ins, out_labels=out_labels, batch_size=batch_size, nb_epoch=nb_epoch, verbose=verbose, callbacks=callbacks, \
validation_split=validation_split, val_f=val_f, val_ins=val_ins, shuffle=shuffle, metrics=metrics)
return history
def evaluate(self, data, batch_size=128, verbose=0):
ins = [data[name] for name in self.input_order] + [standardize_y(data[name]) for name in self.output_order]
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()
def to_yaml(self):
'''
Stores a model to yaml string, optionally with all learnable parameters
If the model is compiled, it will also serialize the necessary components
'''
model_params = self.get_config()
if hasattr(self, 'optimizer'):
model_params['theano_mode'] = self.theano_mode
model_params['loss'] = self.loss
model_params['optimizer'] = self.optimizer.get_config()
return yaml.dump(model_params)
from .utils.generic_utils import get_from_module
def get(identifier):
return get_from_module(identifier, globals(), 'model')
+21 -17
Ver Arquivo
@@ -4,46 +4,50 @@ import theano.tensor as T
import numpy as np
from six.moves import range
epsilon = 1.0e-15
if theano.config.floatX == 'float64':
epsilon = 1.0e-9
else:
epsilon = 1.0e-7
def mean_squared_error(y_true, y_pred):
return T.sqr(y_pred - y_true).mean()
return T.sqr(y_pred - y_true).mean(axis=-1)
def mean_absolute_error(y_true, y_pred):
return T.abs_(y_pred - y_true).mean()
return T.abs_(y_pred - y_true).mean(axis=-1)
def mean_absolute_percentage_error(y_true, y_pred):
return T.abs_((y_true - y_pred) / T.clip(T.abs_(y_true), epsilon, np.inf)).mean(axis=-1) * 100.
def mean_squared_logarithmic_error(y_true, y_pred):
return T.sqr(T.log(T.clip(y_pred, epsilon, np.inf) + 1.) - T.log(T.clip(y_true, epsilon, np.inf) + 1.)).mean(axis=-1)
def squared_hinge(y_true, y_pred):
return T.sqr(T.maximum(1. - y_true * y_pred, 0.)).mean()
return T.sqr(T.maximum(1. - y_true * y_pred, 0.)).mean(axis=-1)
def hinge(y_true, y_pred):
return T.maximum(1. - y_true * y_pred, 0.).mean()
return T.maximum(1. - y_true * y_pred, 0.).mean(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()
y_pred /= y_pred.sum(axis=-1, keepdims=True)
cce = T.nnet.categorical_crossentropy(y_pred, y_true)
return cce
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()
bce = T.nnet.binary_crossentropy(y_pred, y_true).mean(axis=-1)
return bce
# aliases
mse = MSE = 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
+52 -25
Ver Arquivo
@@ -8,31 +8,29 @@ 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 = T.switch(T.ge(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 * T.log(p / p_hat)
class Optimizer(object):
def get_updates(self, params, grads):
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 = T.grad(loss, params)
if hasattr(self, 'clipnorm') and self.clipnorm > 0:
norm = T.sqrt(sum([T.sum(g**2) for g in grads]))
norm = T.sqrt(sum([T.sum(g ** 2) for g in grads]))
grads = [clip_norm(g, self.clipnorm, norm) for g in grads]
new_grads = []
for p, g, r in zip(params, grads, regularizers):
g = r(g, p)
new_grads.append(g)
return new_grads
return grads
def get_config(self):
return {"name":self.__class__.__name__}
class SGD(Optimizer):
@@ -41,10 +39,10 @@ class SGD(Optimizer):
self.__dict__.update(locals())
self.iterations = shared_scalar(0)
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.)]
updates = [(self.iterations, self.iterations + 1.)]
for p, g, c in zip(params, grads, constraints):
m = shared_zeros(p.get_value().shape) # momentum
@@ -59,6 +57,13 @@ class SGD(Optimizer):
updates.append((p, c(new_p))) # apply constraints
return updates
def get_config(self):
return {"name":self.__class__.__name__,
"lr":self.lr,
"momentum":self.momentum,
"decay":self.decay,
"nesterov":self.nesterov}
class RMSprop(Optimizer):
@@ -66,8 +71,8 @@ class RMSprop(Optimizer):
self.__dict__.update(kwargs)
self.__dict__.update(locals())
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)
accumulators = [shared_zeros(p.get_value().shape) for p in params]
updates = []
@@ -80,6 +85,11 @@ class RMSprop(Optimizer):
return updates
def get_config(self):
return {"name":self.__class__.__name__,
"lr":self.lr,
"rho":self.rho,
"epsilon":self.epsilon}
class Adagrad(Optimizer):
@@ -87,8 +97,8 @@ class Adagrad(Optimizer):
self.__dict__.update(kwargs)
self.__dict__.update(locals())
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)
accumulators = [shared_zeros(p.get_value().shape) for p in params]
updates = []
@@ -100,6 +110,10 @@ class Adagrad(Optimizer):
updates.append((p, c(new_p))) # apply constraints
return updates
def get_config(self):
return {"name":self.__class__.__name__,
"lr":self.lr,
"epsilon":self.epsilon}
class Adadelta(Optimizer):
'''
@@ -109,8 +123,8 @@ class Adadelta(Optimizer):
self.__dict__.update(kwargs)
self.__dict__.update(locals())
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)
accumulators = [shared_zeros(p.get_value().shape) for p in params]
delta_accumulators = [shared_zeros(p.get_value().shape) for p in params]
updates = []
@@ -130,6 +144,11 @@ class Adadelta(Optimizer):
updates.append((d_a, new_d_a))
return updates
def get_config(self):
return {"name":self.__class__.__name__,
"lr":self.lr,
"rho":self.rho,
"epsilon":self.epsilon}
class Adam(Optimizer):
'''
@@ -144,8 +163,8 @@ class Adam(Optimizer):
self.__dict__.update(locals())
self.iterations = shared_scalar(0)
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)
updates = [(self.iterations, self.iterations+1.)]
i = self.iterations
@@ -171,6 +190,14 @@ class Adam(Optimizer):
updates.append((p, c(p_t))) # apply constraints
return updates
def get_config(self):
return {"name":self.__class__.__name__,
"lr":self.lr,
"beta_1":self.beta_1,
"beta_2":self.beta_2,
"epsilon":self.epsilon,
"kappa":self.kappa}
# aliases
sgd = SGD
rmsprop = RMSprop
@@ -179,5 +206,5 @@ 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)
+20 -4
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.
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,21 @@ 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 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
+69 -20
Ver Arquivo
@@ -1,26 +1,75 @@
from __future__ import absolute_import
import theano
import theano.tensor as T
import numpy as np
def l1(l=.01):
def l1wrap(g, p):
g += T.sgn(p) * l
return g
return l1wrap
class Regularizer(object):
def set_param(self, p):
self.p = p
def l2(l=.01):
def l2wrap(g, p):
g += p * l
return g
return l2wrap
def set_layer(self, layer):
self.layer = layer
def l1l2(l1=.01, l2=.01):
def l1l2wrap(g, p):
g += T.sgn(p) * l1
g += p * l2
return g
return l1l2wrap
def __call__(self, loss):
return loss
def identity(g, p):
return g
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 += T.sum(abs(self.p)) * self.l1
loss += T.sum(self.p ** 2) * 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):
loss += self.l1 * T.sum(T.mean(abs(self.layer.get_output(True)), axis=0))
loss += self.l2 * T.sum(T.mean(self.layer.get_output(True) ** 2, 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)
+6 -3
Ver Arquivo
@@ -2,14 +2,17 @@ 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
+88
Ver Arquivo
@@ -0,0 +1,88 @@
import inspect
import numpy as np
from ..layers.advanced_activations import LeakyReLU, PReLU
from ..layers.core import Dense, Merge, Dropout, Activation, Reshape, Flatten, RepeatVector, Layer
from ..layers.core import ActivityRegularization, TimeDistributedDense, AutoEncoder, MaxoutDense
from ..layers.embeddings import Embedding, WordContextProduct
from ..layers.noise import GaussianNoise, GaussianDropout
from ..layers.normalization import BatchNormalization
from ..layers.recurrent import SimpleRNN, SimpleDeepRNN, GRU, LSTM, JZS1, JZS2, JZS3
from ..layers import containers
from .. import regularizers
from .. import constraints
def container_from_config(layer_dict):
name = layer_dict.get('name')
hasParams = False
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
else: # The case in which layer_dict represents an "atomic" layer
layer_dict.pop('name')
if 'parameters' in layer_dict:
params = layer_dict.get('parameters')
layer_dict.pop('parameters')
hasParams = True
for k, v in layer_dict.items():
# For now, this can only happen for regularizers and constraints
if isinstance(v, dict):
vname = v.get('name')
v.pop('name')
if vname in [x for x,y in inspect.getmembers(constraints, predicate=inspect.isclass)]:
layer_dict[k] = constraints.get(vname, v)
if vname in [x for x,y in inspect.getmembers(regularizers, predicate=inspect.isclass)]:
layer_dict[k] = regularizers.get(vname, v)
base_layer = get_layer(name, layer_dict)
if hasParams:
shaped_params = []
for param in params:
data = np.asarray(param.get('data'))
shape = tuple(param.get('shape'))
shaped_params.append(data.reshape(shape))
base_layer.set_weights(shaped_params)
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)
-1
Ver Arquivo
@@ -21,7 +21,6 @@ def normalize(a, axis=-1, order=2):
l2[l2==0] = 1
return a / np.expand_dims(l2, axis)
def binary_logloss(p, y):
epsilon = 1e-15
p = sp.maximum(epsilon, p)
+26
Ver Arquivo
@@ -0,0 +1,26 @@
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:])
+1
Ver Arquivo
@@ -20,3 +20,4 @@ def shared_ones(shape, dtype=theano.config.floatX, name=None):
def alloc_zeros_matrix(*dims):
return T.alloc(np.cast[theano.config.floatX](0.), *dims)
+3 -3
Ver Arquivo
@@ -2,13 +2,13 @@ from setuptools import setup
from setuptools import find_packages
setup(name = 'Keras',
version = '0.1.0',
version = '0.1.1',
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.1.0',
download_url = 'https://github.com/fchollet/keras/tarball/0.1.1',
license = 'MIT',
install_requires = ['theano'],
install_requires = ['theano', 'pyyaml'],
packages = find_packages(),
)
-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)
Ver Arquivo
+104
Ver Arquivo
@@ -0,0 +1,104 @@
import math
import keras
import theano
import theano.tensor as T
import numpy
def list_assert_equal(a, b, round_to=7):
'''
This will do a pairwise, rounded equality test across two lists of
numbers.
'''
pairs = zip(a, b)
for i, j in pairs:
assert round(i, round_to) == round(j, round_to)
def get_standard_values():
'''
These are just a set of floats used for testing the activation
functions, and are useful in multiple tests.
'''
return [0,0.1,0.5,0.9,1.0]
def test_softmax():
from keras.activations import softmax as s
# Test using a reference implementation of softmax
def softmax(values):
m = max(values)
values = numpy.array(values)
e = numpy.exp(values - m)
dist = list(e / numpy.sum(e))
return dist
x = T.vector()
exp = s(x)
f = theano.function([x], exp)
test_values=get_standard_values()
result = f(test_values)
expected = softmax(test_values)
print(str(result))
print(str(expected))
list_assert_equal(result, expected)
def test_relu():
'''
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
assert r(5) == 5
assert r(-5) == 0
assert r(-0.1) == 0
assert r(0.1) == 0.1
x = T.vector()
exp = r(x)
f = theano.function([x], exp)
test_values = get_standard_values()
result = f(test_values)
list_assert_equal(result, test_values) # because no negatives in test values
def test_tanh():
from keras.activations import tanh as t
test_values = get_standard_values()
x = T.vector()
exp = t(x)
f = theano.function([x], exp)
result = f(test_values)
expected = [math.tanh(v) for v in test_values]
print(result)
print(expected)
list_assert_equal(result, expected)
def test_linear():
'''
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)
+69
Ver Arquivo
@@ -0,0 +1,69 @@
import unittest
import numpy as np
from numpy.testing import assert_allclose
from theano import tensor as T
class TestConstraints(unittest.TestCase):
def setUp(self):
self.some_values = [0.1, 0.5, 3, 8, 1e-7]
np.random.seed(3537)
self.example_array = np.random.random((100, 100)) * 100. - 50.
self.example_array[0, 0] = 0. # 0 could possibly cause trouble
def test_maxnorm(self):
from keras.constraints import maxnorm
for m in self.some_values:
norm_instance = maxnorm(m)
normed = norm_instance(self.example_array)
assert (np.all(normed.eval() < m))
# a more explicit example
norm_instance = maxnorm(2.0)
x = np.array([[0, 0, 0], [1.0, 0, 0], [3, 0, 0], [3, 3, 3]]).T
x_normed_target = np.array([[0, 0, 0], [1.0, 0, 0], [2.0, 0, 0], [2./np.sqrt(3), 2./np.sqrt(3), 2./np.sqrt(3)]]).T
x_normed_actual = norm_instance(x).eval()
assert_allclose(x_normed_actual, x_normed_target)
def test_nonneg(self):
from keras.constraints import nonneg
nonneg_instance = nonneg()
normed = nonneg_instance(self.example_array)
assert (np.all(np.min(normed.eval(), axis=1) == 0.))
def test_identity(self):
from keras.constraints import identity
identity_instance = identity()
normed = identity_instance(self.example_array)
assert (np.all(normed == self.example_array))
def test_identity_oddballs(self):
"""
test the identity constraint on some more exotic input.
this does not need to pass for the desired real life behaviour,
but it should in the current implementation.
"""
from keras.constraints import identity
identity_instance = identity()
oddball_examples = ["Hello", [1], -1, None]
assert(oddball_examples == identity_instance(oddball_examples))
def test_unitnorm(self):
from keras.constraints import unitnorm
unitnorm_instance = unitnorm()
normalized = unitnorm_instance(self.example_array)
norm_of_normalized = np.sqrt(np.sum(normalized.eval()**2, axis=1))
difference = norm_of_normalized - 1. #in the unit norm constraint, it should be equal to 1.
largest_difference = np.max(np.abs(difference))
self.assertAlmostEqual(largest_difference, 0.)
if __name__ == '__main__':
unittest.main()
@@ -14,7 +14,7 @@ class TestConcatenation(unittest.TestCase):
def test_unitnorm_constraint(self):
lookup = Sequential()
lookup.add(Embedding(3, 2, weights=[self.W1], W_constraint=unitnorm))
lookup.add(Embedding(3, 2, weights=[self.W1], W_constraint=unitnorm()))
lookup.add(Flatten())
lookup.add(Dense(2, 1))
lookup.add(Activation('sigmoid'))
+160
Ver Arquivo
@@ -0,0 +1,160 @@
from __future__ import print_function
import unittest
import numpy as np
np.random.seed(1337)
from keras.models import Graph, Sequential
from keras.layers import containers
from keras.layers.core import Dense, Activation
from keras.utils.test_utils import get_test_data
X = np.random.random((100, 32))
X2 = np.random.random((100, 32))
y = np.random.random((100, 4))
y2 = np.random.random((100,))
(X_train, y_train), (X_test, y_test) = get_test_data(nb_train=1000, nb_test=200, input_shape=(32,),
classification=False, output_shape=(4,))
(X2_train, y2_train), (X2_test, y2_test) = get_test_data(nb_train=1000, nb_test=200, input_shape=(32,),
classification=False, output_shape=(1,))
class TestGraph(unittest.TestCase):
def test_1o_1i(self):
print('test a non-sequential graph with 1 input and 1 output')
graph = Graph()
graph.add_input(name='input1', ndim=2)
graph.add_node(Dense(32, 16), name='dense1', input='input1')
graph.add_node(Dense(32, 4), name='dense2', input='input1')
graph.add_node(Dense(16, 4), name='dense3', input='dense1')
graph.add_output(name='output1', inputs=['dense2', 'dense3'], merge_mode='sum')
graph.compile('rmsprop', {'output1':'mse'})
history = graph.fit({'input1':X_train, 'output1':y_train}, nb_epoch=10)
out = graph.predict({'input1':X_test})
assert(type(out == dict))
assert(len(out) == 1)
loss = graph.test_on_batch({'input1':X_test, 'output1':y_test})
loss = graph.train_on_batch({'input1':X_test, 'output1':y_test})
loss = graph.evaluate({'input1':X_test, 'output1':y_test})
print(loss)
assert(loss < 2.5)
def test_1o_1i_2(self):
print('test a more complex non-sequential graph with 1 input and 1 output')
graph = Graph()
graph.add_input(name='input1', ndim=2)
graph.add_node(Dense(32, 16), name='dense1', input='input1')
graph.add_node(Dense(32, 4), name='dense2-0', input='input1')
graph.add_node(Activation('relu'), name='dense2', input='dense2-0')
graph.add_node(Dense(4, 16), name='dense3', input='dense2')
graph.add_node(Dense(16, 4), name='dense4', inputs=['dense1', 'dense3'], merge_mode='sum')
graph.add_output(name='output1', inputs=['dense2', 'dense4'], merge_mode='sum')
graph.compile('rmsprop', {'output1':'mse'})
history = graph.fit({'input1':X_train, 'output1':y_train}, nb_epoch=10)
out = graph.predict({'input1':X_train})
assert(type(out == dict))
assert(len(out) == 1)
loss = graph.test_on_batch({'input1':X_test, 'output1':y_test})
loss = graph.train_on_batch({'input1':X_test, 'output1':y_test})
loss = graph.evaluate({'input1':X_test, 'output1':y_test})
print(loss)
assert(loss < 2.5)
graph.get_config(verbose=1)
def test_1o_2i(self):
print('test a non-sequential graph with 2 inputs and 1 output')
graph = Graph()
graph.add_input(name='input1', ndim=2)
graph.add_input(name='input2', ndim=2)
graph.add_node(Dense(32, 16), name='dense1', input='input1')
graph.add_node(Dense(32, 4), name='dense2', input='input2')
graph.add_node(Dense(16, 4), name='dense3', input='dense1')
graph.add_output(name='output1', inputs=['dense2', 'dense3'], merge_mode='sum')
graph.compile('rmsprop', {'output1':'mse'})
history = graph.fit({'input1':X_train, 'input2':X2_train, 'output1':y_train}, nb_epoch=10)
out = graph.predict({'input1':X_test, 'input2':X2_test})
assert(type(out == dict))
assert(len(out) == 1)
loss = graph.test_on_batch({'input1':X_test, 'input2':X2_test, 'output1':y_test})
loss = graph.train_on_batch({'input1':X_test, 'input2':X2_test, 'output1':y_test})
loss = graph.evaluate({'input1':X_test, 'input2':X2_test, 'output1':y_test})
print(loss)
assert(loss < 3.0)
graph.get_config(verbose=1)
def test_2o_1i_weights(self):
print('test a non-sequential graph with 1 input and 2 outputs')
graph = Graph()
graph.add_input(name='input1', ndim=2)
graph.add_node(Dense(32, 16), name='dense1', input='input1')
graph.add_node(Dense(32, 4), name='dense2', input='input1')
graph.add_node(Dense(16, 1), 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({'input1':X_train, 'output1':y_train, 'output2':y2_train}, nb_epoch=10)
out = graph.predict({'input1':X_test})
assert(type(out == dict))
assert(len(out) == 2)
loss = graph.test_on_batch({'input1':X_test, 'output1':y_test, 'output2':y2_test})
loss = graph.train_on_batch({'input1':X_test, 'output1':y_test, 'output2':y2_test})
loss = graph.evaluate({'input1':X_test, 'output1':y_test, 'output2':y2_test})
print(loss)
assert(loss < 4.)
print('test weight saving')
graph.save_weights('temp.h5', overwrite=True)
graph = Graph()
graph.add_input(name='input1', ndim=2)
graph.add_node(Dense(32, 16), name='dense1', input='input1')
graph.add_node(Dense(32, 4), name='dense2', input='input1')
graph.add_node(Dense(16, 1), 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'})
graph.load_weights('temp.h5')
nloss = graph.evaluate({'input1':X_test, 'output1':y_test, 'output2':y2_test})
print(nloss)
assert(loss == nloss)
def test_recursive(self):
print('test layer-like API')
graph = containers.Graph()
graph.add_input(name='input1', ndim=2)
graph.add_node(Dense(32, 16), name='dense1', input='input1')
graph.add_node(Dense(32, 4), name='dense2', input='input1')
graph.add_node(Dense(16, 4), name='dense3', input='dense1')
graph.add_output(name='output1', inputs=['dense2', 'dense3'], merge_mode='sum')
seq = Sequential()
seq.add(Dense(32, 32, name='first_seq_dense'))
seq.add(graph)
seq.add(Dense(4, 4, name='last_seq_dense'))
seq.compile('rmsprop', 'mse')
history = seq.fit(X_train, y_train, batch_size=10, nb_epoch=10)
loss = seq.evaluate(X_test, y_test)
print(loss)
assert(loss < 2.5)
loss = seq.evaluate(X_test, y_test, show_accuracy=True)
pred = seq.predict(X_test)
seq.get_config(verbose=1)
if __name__ == '__main__':
print('Test graph model')
unittest.main()
+79
Ver Arquivo
@@ -0,0 +1,79 @@
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
import numpy as np
import unittest
nb_classes = 10
batch_size = 128
nb_epoch = 5
weighted_class = 9
standard_weight = 1
high_weight = 5
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") / 255
X_test = X_test.astype("float32") / 255
# convert class vectors to binary class matrices
y_train = y_train[:max_train_samples]
y_test = y_test[:max_test_samples]
Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)
test_ids = np.where(y_test == np.array(weighted_class))[0]
def create_model():
model = Sequential()
model.add(Dense(784, 50))
model.add(Activation('relu'))
model.add(Dense(50, 10))
model.add(Activation('softmax'))
return model
def _test_weights(model, class_weight=None, sample_weight=None):
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=0, \
class_weight=class_weight, sample_weight=sample_weight)
score = model.evaluate(X_test[test_ids, :], Y_test[test_ids, :], verbose=0)
return score
class TestConcatenation(unittest.TestCase):
def test_loss_weighting(self):
class_weight = dict([(i, standard_weight) for i in range(nb_classes)])
class_weight[weighted_class] = high_weight
sample_weight = np.ones((y_train.shape[0])) * standard_weight
sample_weight[y_train == weighted_class] = high_weight
for loss in ['mae', 'mse', 'categorical_crossentropy']:
print('loss:', loss)
# no weights: reference point
model = create_model()
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
standard_score = _test_weights(model)
# test class_weight
model = create_model()
model.compile(loss=loss, optimizer='rmsprop')
score = _test_weights(model, class_weight=class_weight)
print('score:', score, ' vs.', standard_score)
self.assertTrue(score < standard_score)
# test sample_weight
model = create_model()
model.compile(loss=loss, optimizer='rmsprop')
score = _test_weights(model, sample_weight=sample_weight)
print('score:', score, ' vs.', standard_score)
self.assertTrue(score < standard_score)
if __name__ == '__main__':
print('Test class_weight and sample_weight')
unittest.main()
+61
Ver Arquivo
@@ -0,0 +1,61 @@
import unittest
import numpy as np
np.random.seed(1337) # for reproducibility
from keras.models import Sequential
from keras.layers.core import Merge, Dense, Activation, Flatten, ActivityRegularization
from keras.layers.embeddings import Embedding
from keras.datasets import mnist
from keras.utils import np_utils
from keras import regularizers
nb_classes = 10
batch_size = 128
nb_epoch = 5
weighted_class = 9
standard_weight = 1
high_weight = 5
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, 784)[:max_train_samples]
X_test = X_test.reshape(10000, 784)[:max_test_samples]
X_train = X_train.astype("float32") / 255
X_test = X_test.astype("float32") / 255
# convert class vectors to binary class matrices
y_train = y_train[:max_train_samples]
y_test = y_test[:max_test_samples]
Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)
test_ids = np.where(y_test == np.array(weighted_class))[0]
def create_model(weight_reg=None, activity_reg=None):
model = Sequential()
model.add(Dense(784, 50))
model.add(Activation('relu'))
model.add(Dense(50, 10, W_regularizer=weight_reg, activity_regularizer=activity_reg))
model.add(Activation('softmax'))
return model
class TestRegularizers(unittest.TestCase):
def test_W_reg(self):
for reg in [regularizers.identity(), regularizers.l1(), regularizers.l2(), regularizers.l1l2()]:
model = create_model(weight_reg=reg)
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=0)
model.evaluate(X_test[test_ids, :], Y_test[test_ids, :], verbose=0)
def test_A_reg(self):
for reg in [regularizers.activity_l1(), regularizers.activity_l2()]:
model = create_model(activity_reg=reg)
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=0)
model.evaluate(X_test[test_ids, :], Y_test[test_ids, :], verbose=0)
if __name__ == '__main__':
print('Test weight and activity regularizers')
unittest.main()
+278
Ver Arquivo
@@ -0,0 +1,278 @@
from __future__ import absolute_import
from __future__ import print_function
import unittest
import numpy as np
np.random.seed(1337)
from keras.models import Sequential
from keras.layers.core import Dense, Activation, Merge
from keras.utils import np_utils
from keras.utils.test_utils import get_test_data
input_dim = 32
nb_hidden = 16
nb_class = 4
batch_size = 64
nb_epoch = 1
train_samples = 5000
test_samples = 1000
(X_train, y_train), (X_test, y_test) = get_test_data(nb_train=train_samples, nb_test=test_samples, input_shape=(input_dim,),
classification=True, nb_class=4)
y_test = np_utils.to_categorical(y_test)
y_train = np_utils.to_categorical(y_train)
print(X_train.shape)
print(y_train.shape)
class TestSequential(unittest.TestCase):
def test_sequential(self):
print('Test sequential')
model = Sequential()
model.add(Dense(input_dim, nb_hidden))
model.add(Activation('relu'))
model.add(Dense(nb_hidden, nb_class))
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=1, validation_data=(X_test, y_test))
model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=2, validation_data=(X_test, y_test))
model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=True, verbose=2, validation_split=0.1)
model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=1, 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=1, shuffle=False)
model.train_on_batch(X_train[:32], y_train[:32])
loss = model.evaluate(X_train, y_train, verbose=0)
print('loss:', loss)
if loss > 0.6:
raise Exception('Score too low, learning issue.')
preds = model.predict(X_test, verbose=0)
classes = model.predict_classes(X_test, verbose=0)
probas = model.predict_proba(X_test, verbose=0)
print(model.get_config(verbose=1))
print('test weight saving')
model.save_weights('temp.h5', overwrite=True)
model = Sequential()
model.add(Dense(input_dim, nb_hidden))
model.add(Activation('relu'))
model.add(Dense(nb_hidden, nb_class))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
model.load_weights('temp.h5')
nloss = model.evaluate(X_train, y_train, verbose=0)
print(nloss)
assert(loss == nloss)
def test_merge_sum(self):
print('Test merge: sum')
left = Sequential()
left.add(Dense(input_dim, nb_hidden))
left.add(Activation('relu'))
right = Sequential()
right.add(Dense(input_dim, nb_hidden))
right.add(Activation('relu'))
model = Sequential()
model.add(Merge([left, right], mode='sum'))
model.add(Dense(nb_hidden, nb_class))
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)
loss = model.evaluate([X_train, X_train], y_train, verbose=0)
print('loss:', loss)
if loss > 0.7:
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)
probas = model.predict_proba([X_test, X_test], verbose=0)
print(model.get_config(verbose=1))
print('test weight saving')
model.save_weights('temp.h5', overwrite=True)
left = Sequential()
left.add(Dense(input_dim, nb_hidden))
left.add(Activation('relu'))
right = Sequential()
right.add(Dense(input_dim, nb_hidden))
right.add(Activation('relu'))
model = Sequential()
model.add(Merge([left, right], mode='sum'))
model.add(Dense(nb_hidden, nb_class))
model.add(Activation('softmax'))
model.load_weights('temp.h5')
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
nloss = model.evaluate([X_train, X_train], y_train, verbose=0)
print(nloss)
assert(loss == nloss)
def test_merge_concat(self):
print('Test merge: concat')
left = Sequential()
left.add(Dense(input_dim, nb_hidden))
left.add(Activation('relu'))
right = Sequential()
right.add(Dense(input_dim, nb_hidden))
right.add(Activation('relu'))
model = Sequential()
model.add(Merge([left, right], mode='concat'))
model.add(Dense(nb_hidden * 2, nb_class))
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)
loss = model.evaluate([X_train, X_train], y_train, verbose=0)
print('loss:', loss)
if loss > 0.6:
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)
probas = model.predict_proba([X_test, X_test], verbose=0)
print(model.get_config(verbose=1))
print('test weight saving')
model.save_weights('temp.h5', overwrite=True)
left = Sequential()
left.add(Dense(input_dim, nb_hidden))
left.add(Activation('relu'))
right = Sequential()
right.add(Dense(input_dim, nb_hidden))
right.add(Activation('relu'))
model = Sequential()
model.add(Merge([left, right], mode='concat'))
model.add(Dense(nb_hidden * 2, nb_class))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
model.load_weights('temp.h5')
nloss = model.evaluate([X_train, X_train], y_train, verbose=0)
print(nloss)
assert(loss == nloss)
def test_merge_recursivity(self):
print('Test merge recursivity')
left = Sequential()
left.add(Dense(input_dim, nb_hidden))
left.add(Activation('relu'))
right = Sequential()
right.add(Dense(input_dim, nb_hidden))
right.add(Activation('relu'))
righter = Sequential()
righter.add(Dense(input_dim, nb_hidden))
righter.add(Activation('relu'))
intermediate = Sequential()
intermediate.add(Merge([left, right], mode='sum'))
intermediate.add(Dense(nb_hidden, nb_hidden))
intermediate.add(Activation('relu'))
model = Sequential()
model.add(Merge([intermediate, righter], mode='sum'))
model.add(Dense(nb_hidden, nb_class))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
model.fit([X_train, X_train, X_train], y_train, batch_size=batch_size, 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)
loss = model.evaluate([X_train, X_train, X_train], y_train, verbose=0)
print('loss:', loss)
if loss > 0.6:
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)
probas = model.predict_proba([X_test, X_test, X_test], verbose=0)
print(model.get_config(verbose=1))
model.save_weights('temp.h5', overwrite=True)
model.load_weights('temp.h5')
nloss = model.evaluate([X_train, X_train, X_train], y_train, verbose=0)
print(nloss)
assert(loss == nloss)
def test_merge_overlap(self):
print('Test merge overlap')
left = Sequential()
left.add(Dense(input_dim, nb_hidden))
left.add(Activation('relu'))
model = Sequential()
model.add(Merge([left, left], mode='sum'))
model.add(Dense(nb_hidden, nb_class))
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=1, validation_data=(X_test, y_test))
model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=2, validation_data=(X_test, y_test))
model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=True, verbose=2, validation_split=0.1)
model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=nb_epoch, show_accuracy=False, verbose=1, 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=1, shuffle=False)
model.train_on_batch(X_train[:32], y_train[:32])
loss = model.evaluate(X_train, y_train, verbose=0)
print('loss:', loss)
if loss > 0.6:
raise Exception('Score too low, learning issue.')
preds = model.predict(X_test, verbose=0)
classes = model.predict_classes(X_test, verbose=0)
probas = model.predict_proba(X_test, verbose=0)
print(model.get_config(verbose=1))
model.save_weights('temp.h5', overwrite=True)
model.load_weights('temp.h5')
nloss = model.evaluate(X_train, y_train, verbose=0)
print(nloss)
assert(loss == nloss)
if __name__ == '__main__':
print('Test Sequential model')
unittest.main()
+131
Ver Arquivo
@@ -0,0 +1,131 @@
from __future__ import print_function
import numpy as np
np.random.seed(1337)
from keras.utils.test_utils import get_test_data
from keras.models import Sequential
from keras.layers.core import Dense, Activation, TimeDistributedDense, Flatten
from keras.layers.recurrent import GRU
from keras.layers.convolutional import Convolution2D
from keras.utils.np_utils import to_categorical
import unittest
class TestRegularizers(unittest.TestCase):
def test_vector_clf(self):
nb_hidden = 10
print('vector classification data:')
(X_train, y_train), (X_test, y_test) = get_test_data(nb_train=1000, nb_test=200, input_shape=(10,),
classification=True, nb_class=2)
print('X_train:', X_train.shape)
print('X_test:', X_test.shape)
print('y_train:', y_train.shape)
print('y_test:', y_test.shape)
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
model = Sequential()
model.add(Dense(X_train.shape[-1], nb_hidden))
model.add(Activation('relu'))
model.add(Dense(nb_hidden, y_train.shape[-1]))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
history = model.fit(X_train, y_train, nb_epoch=12, batch_size=16, validation_data=(X_test, y_test), show_accuracy=True, verbose=2)
print(history.history)
self.assertTrue(history.history['val_acc'][-1] > 0.9)
def test_vector_reg(self):
nb_hidden = 10
print('vector regression data:')
(X_train, y_train), (X_test, y_test) = get_test_data(nb_train=1000, nb_test=200, input_shape=(10,), output_shape=(2,),
classification=False)
print('X_train:', X_train.shape)
print('X_test:', X_test.shape)
print('y_train:', y_train.shape)
print('y_test:', y_test.shape)
model = Sequential()
model.add(Dense(X_train.shape[-1], nb_hidden))
model.add(Activation('tanh'))
model.add(Dense(nb_hidden, y_train.shape[-1]))
model.compile(loss='hinge', optimizer='adagrad')
history = model.fit(X_train, y_train, nb_epoch=12, batch_size=16, validation_data=(X_test, y_test), verbose=2)
self.assertTrue(history.history['val_loss'][-1] < 0.9)
def test_temporal_clf(self):
print('temporal classification data:')
(X_train, y_train), (X_test, y_test) = get_test_data(nb_train=1000, nb_test=200, input_shape=(5,10),
classification=True, nb_class=2)
print('X_train:', X_train.shape)
print('X_test:', X_test.shape)
print('y_train:', y_train.shape)
print('y_test:', y_test.shape)
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
model = Sequential()
model.add(GRU(X_train.shape[-1], y_train.shape[-1]))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adadelta')
history = model.fit(X_train, y_train, nb_epoch=12, batch_size=16, validation_data=(X_test, y_test), show_accuracy=True, verbose=2)
self.assertTrue(history.history['val_acc'][-1] > 0.9)
def test_temporal_reg(self):
print('temporal regression data:')
(X_train, y_train), (X_test, y_test) = get_test_data(nb_train=1000, nb_test=200, input_shape=(5, 10), output_shape=(2,),
classification=False)
print('X_train:', X_train.shape)
print('X_test:', X_test.shape)
print('y_train:', y_train.shape)
print('y_test:', y_test.shape)
model = Sequential()
model.add(GRU(X_train.shape[-1], y_train.shape[-1]))
model.compile(loss='hinge', optimizer='adam')
history = model.fit(X_train, y_train, nb_epoch=12, batch_size=16, validation_data=(X_test, y_test), verbose=2)
self.assertTrue(history.history['val_loss'][-1] < 0.75)
def test_seq_to_seq(self):
print('sequence to sequence data:')
(X_train, y_train), (X_test, y_test) = get_test_data(nb_train=1000, nb_test=200, input_shape=(5, 10), output_shape=(5, 10),
classification=False)
print('X_train:', X_train.shape)
print('X_test:', X_test.shape)
print('y_train:', y_train.shape)
print('y_test:', y_test.shape)
model = Sequential()
model.add(TimeDistributedDense(X_train.shape[-1], y_train.shape[-1]))
model.compile(loss='hinge', optimizer='rmsprop')
history = model.fit(X_train, y_train, nb_epoch=12, batch_size=16, validation_data=(X_test, y_test), verbose=2)
self.assertTrue(history.history['val_loss'][-1] < 0.75)
def test_img_clf(self):
print('image classification data:')
(X_train, y_train), (X_test, y_test) = get_test_data(nb_train=1000, nb_test=200, input_shape=(3, 32, 32),
classification=True, nb_class=2)
print('X_train:', X_train.shape)
print('X_test:', X_test.shape)
print('y_train:', y_train.shape)
print('y_test:', y_test.shape)
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
model = Sequential()
model.add(Convolution2D(32, 3, 32, 32))
model.add(Activation('sigmoid'))
model.add(Flatten())
model.add(Dense(32, y_test.shape[-1]))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='sgd')
history = model.fit(X_train, y_train, nb_epoch=12, batch_size=16, validation_data=(X_test, y_test), show_accuracy=True, verbose=2)
self.assertTrue(history.history['val_acc'][-1] > 0.9)
if __name__ == '__main__':
print('Test different types of classification and regression tasks')
unittest.main()
Ver Arquivo
@@ -2,18 +2,14 @@ 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.core import 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
@@ -42,6 +38,7 @@ 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 #
##########################
@@ -70,70 +67,66 @@ def build_lstm_autoencoder(autoencoder, X_train, X_test):
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))
output_reconstruction=False))
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))
autoencoder.add(AutoEncoder(encoder=encoder, decoder=decoder, output_reconstruction=False))
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)
# Try different things here: 'lstm' or 'classical' or 'denoising'
# or 'deep_denoising'
# 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)
for autoencoder_type in ['classical', 'lstm']:
print(autoencoder_type)
print('-'*40)
# 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 == 'classical':
print("Training Classical AutoEncoder")
autoencoder = build_deep_classical_autoencoder(autoencoder)
else:
print("Error: unknown autoencoder type!")
exit(-1)
# 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))
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)
model.add(Activation('softmax'))
# 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)
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))
# 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))
score = model.evaluate(prefilter_test, Y_test, verbose=0, show_accuracy=True)
print('\nscore:', score)
model.add(Activation('softmax'))
print('Loss change:', (score[0] - classical_score[0])/classical_score[0], '%')
print('Accuracy change:', (score[1] - classical_score[1])/classical_score[1], '%')
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], '%')
@@ -35,7 +35,7 @@ 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(Dense(20, 20, W_constraint=nonneg()))
model.add(Activation('relu'))
model.add(Dropout(0.1))
model.add(Dense(20, 10, W_constraint=maxnorm(1)))
+130
Ver Arquivo
@@ -0,0 +1,130 @@
# Dummy test data as input to RNN. This input is 3 timesteps long where the third timestep always matches the
# first. Without masking it should be able to learn it, with masking it should fail.
import numpy as np
from keras.utils.theano_utils import sharedX
from keras.models import Sequential
from keras.layers.core import Dense, Activation, Merge, Dropout, TimeDistributedDense
from keras.layers.embeddings import Embedding
from keras.layers.recurrent import SimpleRNN, SimpleDeepRNN, LSTM, GRU
import theano
theano.config.exception_verbosity = 'high'
# (nb_samples, timesteps, dimensions)
X = np.random.random_integers(1, 4, size=(500000, 15))
print("About to compile the first model")
model = Sequential()
model.add(Embedding(5, 4, mask_zero=True))
model.add(TimeDistributedDense(4, 4)) # obviously this is redundant. Just testing.
model.add(SimpleRNN(4, 4, activation='relu', return_sequences=True))
model.add(Dropout(0.5))
model.add(SimpleDeepRNN(4, 4, depth=2, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(4, 4, activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='rmsprop', theano_mode=theano.compile.mode.FAST_RUN)
print("Compiled model")
W = model.get_weights() # We'll save these so we can reset it later
X[:, : 10] = 0
Xmask0 = X.copy()
Xmask0[:, 10] = 0
Xmask12 = X.copy()
Xmask12[:, 11] = 0
Xmask12[:, 12] = 0
X0_onehot = np.zeros((X.shape[0], 4))
X1_onehot = np.zeros((X.shape[0], 4))
for i, row in enumerate(X):
X0_onehot[i, row[10] - 1] = 1
X1_onehot[i, row[11] - 1] = 1
# Uniform score: 4 options = ln(4) nats (2 bits)
# we should not do better than this when we mask out the part of the input
# that gives us the correct answer
uniform_score = np.log(4)
batch_size=512
# Train it to guess 0th dim
model.fit(X, X0_onehot, nb_epoch=1, batch_size=batch_size)
score = model.evaluate(X, X0_onehot, batch_size=batch_size)
if score > uniform_score * 0.9:
raise Exception('Failed to learn to copy timestep 0, score %f' % score)
model.set_weights(W)
# Train without showing it the 0th dim to learn 1st dim
model.fit(X[: , 1:], X1_onehot, nb_epoch=1, batch_size=batch_size)
score = model.evaluate(X[:, 1:], X1_onehot, batch_size=batch_size)
if score > uniform_score * 0.9:
raise Exception('Failed to learn to copy timestep 1, score %f' % score)
model.set_weights(W)
# Train to guess 0th dim when 0th dim has been masked (should fail)
model.fit(Xmask0, X0_onehot, nb_epoch=1, batch_size=batch_size)
score = model.evaluate(Xmask0, X0_onehot, batch_size=batch_size)
if score < uniform_score * 0.9:
raise Exception('Somehow learned to copy timestep 0 despite mask, score %f' % score)
model.set_weights(W)
# Train to guess 1st dim when 0th dim has been masked (should succeed)
model.fit(Xmask0, X1_onehot, nb_epoch=1, batch_size=batch_size)
score = model.evaluate(Xmask0, X1_onehot, batch_size=batch_size)
if score > uniform_score * 0.9:
raise Exception('Failed to learn to copy timestep 1 in masked model, score %f' % score)
model.set_weights(W)
# Finally, make sure the mask is actually blocking input, mask out timesteps 1 and 2, and see if
# it can learn timestep 0 (should fail)
model.fit(Xmask12, X0_onehot, nb_epoch=1, batch_size=batch_size)
score = model.evaluate(Xmask12, X0_onehot, batch_size=batch_size)
if score < uniform_score * 0.9:
raise Exception('Somehow learned to copy timestep 0 despite masking 1, score %f' % score)
# Another testing approach, just initialize models and make sure that prepending zeros doesn't affect
# their output
print("About to compile the second model")
model2 = Sequential()
model2.add(Embedding(5, 4, mask_zero=True))
model2.add(TimeDistributedDense(4, 4))
model2.add(Activation('time_distributed_softmax'))
model2.add(LSTM(4, 4, return_sequences=True))
model2.add(Activation('tanh'))
model2.add(GRU(4, 4, activation='softmax', return_sequences=True))
model2.add(SimpleDeepRNN(4, 4, depth=2, activation='relu', return_sequences=True))
model2.add(SimpleRNN(4, 4, activation='relu', return_sequences=True))
model2.compile(loss='categorical_crossentropy',
optimizer='rmsprop', theano_mode=theano.compile.mode.FAST_RUN)
print("Compiled model2")
X2 = np.random.random_integers(1, 4, size=(2, 5))
y2 = np.random.random((X2.shape[0], X2.shape[1], 4))
ref = model2.predict(X2)
ref_eval = model2.evaluate(X2, y2)
mask = np.ones((y2.shape[0], y2.shape[1], 1))
for pre_zeros in range(1, 10):
padded_X2 = np.concatenate((np.zeros((X2.shape[0], pre_zeros)), X2), axis=1)
padded_mask = np.concatenate((np.zeros((mask.shape[0], pre_zeros, mask.shape[2])), mask), axis=1)
padded_y2 = np.concatenate((np.zeros((y2.shape[0], pre_zeros, y2.shape[2])), y2), axis=1)
pred = model2.predict(padded_X2)
if not np.allclose(ref[:, -1, :], pred[:, -1, :]):
raise Exception("Different result after left-padding %d zeros. Ref: %s, Pred: %s" % (pre_zeros, ref, pred))
pad_eval = model2.evaluate(padded_X2, padded_y2, weights=padded_mask)
if not np.allclose([pad_eval], [ref_eval]):
raise Exception("Got dissimilar categorical_crossentropy after left-padding %d zeros. Ref: %f, Pred %f" %\
(pref_eval, pred_val))
+101
Ver Arquivo
@@ -0,0 +1,101 @@
from __future__ import absolute_import
from __future__ import print_function
import numpy as np
from keras.utils.test_utils import get_test_data
from keras.preprocessing import sequence
from keras.optimizers import SGD, RMSprop, Adagrad
from keras.utils import np_utils
from keras.models import Sequential, Graph
from keras.layers.core import Dense, Dropout, Activation, Merge
from keras.layers.embeddings import Embedding
from keras.layers.recurrent import LSTM, GRU
from keras.datasets import imdb
from keras.models import model_from_yaml
'''
This is essentially the IMDB test. Deserialized models should yield
the same config as the original one.
'''
max_features = 10000
maxlen = 100
batch_size = 32
(X_train, y_train), (X_test, y_test) = imdb.load_data(nb_words=max_features, test_split=0.2)
X_train = sequence.pad_sequences(X_train, maxlen=maxlen)
X_test = sequence.pad_sequences(X_test, maxlen=maxlen)
model = Sequential()
model.add(Embedding(max_features, 128))
model.add(LSTM(128, 128))
model.add(Dropout(0.5))
model.add(Dense(128, 1, W_regularizer='identity', b_constraint='maxnorm'))
model.add(Activation('sigmoid'))
model.get_config(verbose=1)
#####################################
# save model w/o parameters to yaml #
#####################################
yaml_no_params = model.to_yaml()
no_param_model = model_from_yaml(yaml_no_params)
no_param_model.get_config(verbose=1)
######################################
# save multi-branch sequential model #
######################################
seq = Sequential()
seq.add(Merge([model, model], mode='sum'))
seq.get_config(verbose=1)
merge_yaml = seq.to_yaml()
merge_model = model_from_yaml(merge_yaml)
large_model = Sequential()
large_model.add(Merge([seq,model], mode='concat'))
large_model.get_config(verbose=1)
large_model.to_yaml()
####################
# save graph model #
####################
X = np.random.random((100, 32))
X2 = np.random.random((100, 32))
y = np.random.random((100, 4))
y2 = np.random.random((100,))
(X_train, y_train), (X_test, y_test) = get_test_data(nb_train=1000, nb_test=200, input_shape=(32,),
classification=False, output_shape=(4,))
graph = Graph()
graph.add_input(name='input1', ndim=2)
graph.add_node(Dense(32, 16), name='dense1', input='input1')
graph.add_node(Dense(32, 4), name='dense2', input='input1')
graph.add_node(Dense(16, 4), name='dense3', input='dense1')
graph.add_output(name='output1', inputs=['dense2', 'dense3'], merge_mode='sum')
graph.compile('rmsprop', {'output1':'mse'})
graph.get_config(verbose=1)
history = graph.fit({'input1':X_train, 'output1':y_train}, nb_epoch=10)
original_pred = graph.predict({'input1':X_test})
graph_yaml = graph.to_yaml()
graph.save_weights('temp.h5', overwrite=True)
reloaded_graph = model_from_yaml(graph_yaml)
reloaded_graph.load_weights('temp.h5')
reloaded_graph.get_config(verbose=1)
reloaded_graph.compile('rmsprop', {'output1':'mse'})
new_pred = reloaded_graph.predict({'input1':X_test})
assert(new_pred['output1'][3][1] == original_pred['output1'][3][1])