├── LICENSE ├── README.md ├── README_DEVELOPER.md ├── configs ├── default.ast ├── ilr │ ├── 0.ast │ ├── 1.ast │ ├── 2.ast │ └── 3.ast ├── lbl │ ├── cv.ast │ ├── glp.ast │ └── uni.ast ├── len │ ├── 1.ast │ ├── 3.ast │ └── 9.ast ├── log │ ├── N.ast │ └── Y.ast ├── mid │ ├── blstm.ast │ ├── brnn.ast │ ├── lstm.ast │ ├── midlayer.ast │ └── rnn.ast ├── midlayer.ast ├── opt │ ├── add.ast │ ├── adm.ast │ ├── adx.ast │ ├── mom.ast │ ├── nes.ast │ ├── rms.ast │ └── sgd.ast ├── optimizers.ast ├── profile.ast └── test.ast ├── data ├── mahaa_small.txt ├── mahaa_two_akshara.txt ├── mahaabhaaratam_aadi.txt ├── praasa.tif ├── praasa_tiny.tif ├── twilight.jpg └── twilight.tiff ├── docs ├── rnn_ctc_presentation.pdf └── script_agnostic_ocr_rnn_ctc_loss.pdf ├── lab ├── ctc_cost_mohpz.py ├── draw_text.py ├── indic_scribe_python2.py └── minibatch_ocr.py ├── line_seperate.py ├── notebooks ├── array_vs_np_vs_list.ipynb ├── encoder_test.ipynb └── profile_get_next_char.ipynb ├── profile ├── README.md ├── parscribe.pstats ├── parscribe_decay.pstats ├── scribe.pstats └── scribe_decay.pstats ├── requirements.txt ├── scripts └── install.sh ├── setup.py ├── train.py └── utils.py /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chamanti OCR in Theano చామంతి 2 | 3 | # Discontinued 4 | As `theano` has been discontinued and `TensorFlow` has taken over. I am moving this project to 5 | TensorFlow. So this work is discontinued. Code duplication from the `rnn_ctc` library for 6 | `Reccurent Nueral Networks` with `Connectionist Temporal Classification` has been deleted. 7 | The code for 'scribe'ing Indian Language Text has also been moved to a new package 8 | [IndicScribe](https://github.com/rakeshvar/IndicScribe) 9 | 10 | # TensorFlow Package 11 | The Chamanti OCR based on `TensorFlow` and `IndicScribe` will be up in my repositories. 12 | 13 | # Mission 14 | This project aims to build a very ambitious OCR framework, that should work on any language. 15 | It will not rely on segmentation algorithms (at the glyph level), making it ideal for highly 16 | agglutinative scripts like Arabic, Devanagari etc. We will be starting with Telugu however. 17 | The core technology behind this is going to be Recurrent Neural Networks using CTC from 18 | the repo [rnn_ctc](https://github.com/rakeshvar/rnn_ctc). 19 | 20 | # Python Dependencies 21 | 1. numpy 22 | 1. scipy 23 | 2. theano 24 | 25 | # My other packages 26 | 1. [rnn_ctc](https://github.com/rakeshvar/rnn_ctc) 27 | 2. [IndicScribe](https://github.com/rakeshvar/IndicScribe) 28 | 29 | 30 | You can read the [developer documentation](README_DEVELOPER.md) for more details about the code and configurations. 31 | -------------------------------------------------------------------------------- /README_DEVELOPER.md: -------------------------------------------------------------------------------- 1 | # Documentation for Developers 2 | 3 | ## Files 4 | 5 | 1. `train.py` Main file to train OCR for a given language. Training and network parameters are specified via `.ast` files in the `config/` directory. 6 | ``` 7 | python3 train.py configs/midlayer.ast configs/len/3.ast 8 | ``` 9 | 10 | ## Directories 11 | 12 | 1. `configs` Contains the training parameters and the network parameters. `default.ast` is loaded by default, other files can be passed in as command line arguments to override default arguments. Each folder has parameters pertaining to individual aspects of the network and training. 13 | 1. `opt` Optimizer 14 | 1. `ilr` Initial Learning Rate 15 | 1. `len` Length of the each slab, width, number of characters, etc. 16 | 1. `lbl` Labelling for the language. For e.g. Telugu can be encoded as a series of Unicode points, as a series of Ligatures, etc. 17 | 1. `mid` Middle Layer (LSTM, GRU, etc.) 18 | 1. `log` Use logarithmic scale for the CTC layer 19 | 1. `lab` Experimental code. 20 | 1. `rnn_ctc` Code duplicated from [rnn_ctc](https://github.com/rakeshvar/rnn_ctc) repo. Needs to be an external dependency. 21 | 1. `data` Sample images. 22 | 1. `profile` Profiling training time vs text image generation time. 23 | 1. `telugu` or any ``. Can be any language should contain the following information pertaining to the language of interest, e.g. Telugu 24 | 1. `fonts.py` A list of fonts available for that language that can be used for training. 25 | 1. `labeler_*.py` A look up for converting a Unicode language string to a string of labels `{0, 1, 2, ..., }`. Each labler will have different number of labels. More if you are using ligatures, fewer if you are using unicode as is. 26 | 1. `texter.py` Generates random text from the language. Could be from a corpus or could be from a language model (like one based on bigrams). 27 | 1. `tests` Testing files for scribe. 28 | 1. `docs` Documentation. 29 | 1. `notebooks` Similar to `tests`, `lab`, `profile` directories. 30 | -------------------------------------------------------------------------------- /configs/default.ast: -------------------------------------------------------------------------------- 1 | { 2 | # Training 3 | 'num_epochs': 1000, 4 | 'num_samples': 1000, # Online: Number of samples per epoch 5 | 'train_on_fraction': .8, # Offline use only 6 | 7 | # Language 8 | 'labeler': 'cv', 9 | 10 | # Data generation 11 | 'scribe_args': { 12 | 'height': 45, 13 | 'hbuffer': 5, 14 | 'vbuffer': 0, 15 | 'maxangle': .05, 16 | 'size': 24, 17 | 'noise': .05, 18 | 'nchars_per_sample': 3, 19 | }, 20 | 21 | # Neural network. 22 | 'nnet_args': { 23 | 'use_log_space': True, 24 | 25 | 'mid_layer': 'RecurrentLayer', 26 | 'mid_layer_args': { 27 | 'nunits': 25, 28 | 'learn_init_state':False}, 29 | 30 | 'optimizer': 'sgd', 31 | 'optimizer_args': {}, 32 | 33 | 'learning_rate_args': { 34 | 'initial_rate': .001, 35 | 'anneal': 'constant', 36 | 'epochs_to_half': 1,} 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /configs/ilr/0.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'use_log_space': True, 4 | 5 | 'learning_rate_args': { 6 | 'initial_rate': 1, 7 | 'anneal': 'inverse_sqrt', 8 | 'epochs_to_half': 5,} 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /configs/ilr/1.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'use_log_space': True, 4 | 5 | 'learning_rate_args': { 6 | 'initial_rate': 1e-1, 7 | 'anneal': 'inverse_sqrt', 8 | 'epochs_to_half': 5,} 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /configs/ilr/2.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'use_log_space': True, 4 | 5 | 'learning_rate_args': { 6 | 'initial_rate': 1e-2, 7 | 'anneal': 'inverse_sqrt', 8 | 'epochs_to_half': 5,} 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /configs/ilr/3.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'use_log_space': True, 4 | 5 | 'learning_rate_args': { 6 | 'initial_rate': 1e-3, 7 | 'anneal': 'inverse_sqrt', 8 | 'epochs_to_half': 5,} 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /configs/lbl/cv.ast: -------------------------------------------------------------------------------- 1 | { 2 | # Language 3 | 'labeler': 'cv', 4 | } 5 | -------------------------------------------------------------------------------- /configs/lbl/glp.ast: -------------------------------------------------------------------------------- 1 | { 2 | # Language 3 | 'labeler': 'glyph', 4 | } -------------------------------------------------------------------------------- /configs/lbl/uni.ast: -------------------------------------------------------------------------------- 1 | { 2 | # Language 3 | 'labeler': 'unicode', 4 | } -------------------------------------------------------------------------------- /configs/len/1.ast: -------------------------------------------------------------------------------- 1 | { 2 | # Data generation 3 | 'scribe_args': { 4 | 'height': 45, 5 | 'hbuffer': 2, 6 | 'vbuffer': 0, 7 | 'maxangle': .05, 8 | 'size': 24, 9 | 'noise': .05, 10 | 'nchars_per_sample': 1, 11 | }, 12 | } -------------------------------------------------------------------------------- /configs/len/3.ast: -------------------------------------------------------------------------------- 1 | { 2 | # Data generation 3 | 'scribe_args': { 4 | 'height': 45, 5 | 'hbuffer': 5, 6 | 'vbuffer': 0, 7 | 'maxangle': .05, 8 | 'size': 24, 9 | 'noise': .05, 10 | 'nchars_per_sample': 3, 11 | }, 12 | } -------------------------------------------------------------------------------- /configs/len/9.ast: -------------------------------------------------------------------------------- 1 | { 2 | # Data generation 3 | 'scribe_args': { 4 | 'height': 45, 5 | 'hbuffer': 5, 6 | 'vbuffer': 0, 7 | 'maxangle': .05, 8 | 'size': 24, 9 | 'noise': .05, 10 | 'nchars_per_sample': 9, 11 | }, 12 | } -------------------------------------------------------------------------------- /configs/log/N.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'use_log_space': False, 4 | } 5 | } -------------------------------------------------------------------------------- /configs/log/Y.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'use_log_space': True, 4 | } 5 | } -------------------------------------------------------------------------------- /configs/mid/blstm.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'mid_layer':'BDLSTM', 4 | 'mid_layer_args': { 5 | 'nunits': 90, 6 | 'forget': True, 7 | # 'actvn_post': 'relu50', 8 | # 'actvn_pre': 'relu10', 9 | 'learn_init_states': False, 10 | }, 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /configs/mid/brnn.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'mid_layer':'BiRecurrentLayer', 4 | 'mid_layer_args': { 5 | 'nunits': 225, 6 | 'learn_init_state':False, 7 | 'conv_sz': 1, 8 | }, 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /configs/mid/lstm.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'mid_layer':'LSTM', 4 | 'mid_layer_args': { 5 | 'nunits': 180, 6 | 'forget': True, 7 | # 'actvn_post': 'relu50', 8 | # 'actvn_pre': 'relu10', 9 | 'learn_init_states': False, 10 | }, 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /configs/mid/midlayer.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | # 'mid_layer':'RecurrentLayer', 4 | # 'mid_layer_args': {'nunits': 9}, 5 | 6 | # 'mid_layer':'RecurrentLayer', 7 | # 'mid_layer_args': {'nunits': 9, 'conv_sz': 3}, 8 | 9 | # 'mid_layer':'RecurrentLayer', 10 | # 'mid_layer_args': {'nunits': 5, 'learn_init_state':False}, 11 | 12 | 'mid_layer':'BiRecurrentLayer', 13 | 'mid_layer_args': {'nunits': 5, 'learn_init_state':False}, 14 | 15 | # 'mid_layer':'BiRecurrentLayer', 16 | # 'mid_layer_args': {'nunits': 3, 'conv_sz': 3}, 17 | 18 | # 'mid_layer':'LSTM', 19 | # 'mid_layer_args': {'nunits': 9}, 20 | 21 | # 'mid_layer':'LSTM', 22 | # 'mid_layer_args': {'nunits': 9, 'forget': True}, 23 | 24 | # 'mid_layer':'LSTM', 25 | # 'mid_layer_args': {'nunits': 9, 'actvn_pre': 'relu10'}, 26 | 27 | # 'mid_layer':'LSTM', 28 | # 'mid_layer_args': {'nunits': 9, 'forget': True, 'actvn_post': 'relu50', 'actvn_pre': 'relu10'}, 29 | 30 | # 'mid_layer':'LSTM', 31 | # 'mid_layer_args': {'nunits': 9, 'learn_init_states': False}, 32 | 33 | # 'mid_layer':'BDLSTM', 34 | # 'mid_layer_args': {'nunits': 9}, 35 | 36 | # 'mid_layer':'BDLSTM', 37 | # 'mid_layer_args': {'nunits': 3}, 38 | 39 | # 'mid_layer':'BDLSTM', 40 | # 'mid_layer_args': {'nunits': 5}, 41 | 42 | # 'mid_layer':'RecurrentLayer', 43 | # 'mid_layer_args': {'nunits': 90}, 44 | }, 45 | } 46 | -------------------------------------------------------------------------------- /configs/mid/rnn.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'mid_layer':'RecurrentLayer', 4 | 'mid_layer_args': { 5 | 'nunits': 360, 6 | 'learn_init_state':False, 7 | 'conv_sz':1, 8 | }, 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /configs/midlayer.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | # 'mid_layer':'RecurrentLayer', 4 | # 'mid_layer_args': {'nunits': 9}, 5 | 6 | # 'mid_layer':'RecurrentLayer', 7 | # 'mid_layer_args': {'nunits': 9, 'conv_sz': 3}, 8 | 9 | # 'mid_layer':'RecurrentLayer', 10 | # 'mid_layer_args': {'nunits': 5, 'learn_init_state':False}, 11 | 12 | 'mid_layer':'BiRecurrentLayer', 13 | 'mid_layer_args': {'nunits': 5, 'learn_init_state':False}, 14 | 15 | # 'mid_layer':'BiRecurrentLayer', 16 | # 'mid_layer_args': {'nunits': 3, 'conv_sz': 3}, 17 | 18 | # 'mid_layer':'LSTM', 19 | # 'mid_layer_args': {'nunits': 9}, 20 | 21 | # 'mid_layer':'LSTM', 22 | # 'mid_layer_args': {'nunits': 9, 'forget': True}, 23 | 24 | # 'mid_layer':'LSTM', 25 | # 'mid_layer_args': {'nunits': 9, 'actvn_pre': 'relu10'}, 26 | 27 | # 'mid_layer':'LSTM', 28 | # 'mid_layer_args': {'nunits': 9, 'forget': True, 'actvn_post': 'relu50', 'actvn_pre': 'relu10'}, 29 | 30 | # 'mid_layer':'LSTM', 31 | # 'mid_layer_args': {'nunits': 9, 'learn_init_states': False}, 32 | 33 | # 'mid_layer':'BDLSTM', 34 | # 'mid_layer_args': {'nunits': 9}, 35 | 36 | # 'mid_layer':'BDLSTM', 37 | # 'mid_layer_args': {'nunits': 3}, 38 | 39 | # 'mid_layer':'BDLSTM', 40 | # 'mid_layer_args': {'nunits': 5}, 41 | 42 | # 'mid_layer':'RecurrentLayer', 43 | # 'mid_layer_args': {'nunits': 90}, 44 | }, 45 | } 46 | -------------------------------------------------------------------------------- /configs/opt/add.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'optimizer':'adadelta', 4 | 'optimizer_args': {}, 5 | }, 6 | } -------------------------------------------------------------------------------- /configs/opt/adm.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'optimizer':'adamax', 4 | 'optimizer_args': {}, 5 | }, 6 | } -------------------------------------------------------------------------------- /configs/opt/adx.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'optimizer':'adamax', 4 | 'optimizer_args': {}, 5 | }, 6 | } -------------------------------------------------------------------------------- /configs/opt/mom.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'optimizer':'momentum', 4 | 'optimizer_args': {'momentum': 0.99}, 5 | }, 6 | } -------------------------------------------------------------------------------- /configs/opt/nes.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'optimizer':'nesterov_momentum', 4 | 'optimizer_args': {'momentum': 0.99}, 5 | }, 6 | } -------------------------------------------------------------------------------- /configs/opt/rms.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'optimizer':'rmsprop', 4 | 'optimizer_args': { 5 | # 'rho':0.9, 'epsilon': 1e-6 6 | }, 7 | }, 8 | } -------------------------------------------------------------------------------- /configs/opt/sgd.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | 'optimizer':'sgd', 4 | 'optimizer_args': {}, 5 | }, 6 | } -------------------------------------------------------------------------------- /configs/optimizers.ast: -------------------------------------------------------------------------------- 1 | { 2 | 'nnet_args': { 3 | # 'optimizer':'sgd', 4 | # 'optimizer':'adagrad', 5 | # 'optimizer_args': {}, 6 | 7 | 'optimizer':'momentum', 8 | # 'optimizer':'nesterov_momentum', 9 | 'optimizer_args': {'momentum': 0.95}, 10 | 11 | # 'optimizer':'rmsprop', 12 | # 'optimizer':'adadelta', 13 | # 'optimizer_args': {'rho':0.9}, 14 | 15 | # 'optimizer':'adam', 16 | # 'optimizer':'adamax', 17 | # 'optimizer_args': {'beta1':0.9, 'beta2':0.999,}, 18 | 19 | 'learning_rate_args': { 20 | 'initial_rate': .0001, 21 | 'anneal': 'constant', 22 | 'epochs_to_half': 1, 23 | }, 24 | 25 | # 'learning_rate_args': { 26 | # 'initial_rate': .1, 27 | # 'anneal': 'inverse', 28 | # 'epochs_to_half': 1, 29 | # }, 30 | 31 | # 'learning_rate_args': { 32 | # 'initial_rate': .1, 33 | # 'anneal': 'inverse_sqrt', 34 | # 'epochs_to_half': 1, 35 | # }, 36 | 37 | }, 38 | } -------------------------------------------------------------------------------- /configs/profile.ast: -------------------------------------------------------------------------------- 1 | { 2 | # Training 3 | 'num_epochs': 100, 4 | 'num_samples': 100, # Online: Number of samples per epoch 5 | 'train_on_fraction': .8, # Offline use only 6 | 7 | # Data generation 8 | 'scribe_args': { 9 | 'height': 45, 10 | 'hbuffer': 5, 11 | 'vbuffer': 0, 12 | 'maxangle': .05, 13 | 'size': 24, 14 | 'noise': .05, 15 | 'nchars_per_sample': 3, 16 | }, 17 | 18 | # Neural network. 19 | 'nnet_args': { 20 | 'use_log_space': True, 21 | 22 | 'mid_layer': 'RecurrentLayer', 23 | 'mid_layer_args': { 24 | 'nunits': 25, 25 | 'learn_init_state':False}, 26 | 27 | 'optimizer': 'sgd', 28 | 'optimizer_args': {}, 29 | 30 | 'learning_rate_args': { 31 | 'initial_rate': .001, 32 | 'anneal': 'constant', 33 | 'epochs_to_half': 1,} 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /configs/test.ast: -------------------------------------------------------------------------------- 1 | { 2 | # Training 3 | 'num_epochs': 10, 4 | 'num_samples': 10, # Online: Number of samples per epoch 5 | } -------------------------------------------------------------------------------- /data/mahaa_small.txt: -------------------------------------------------------------------------------- 1 | శ్రీమ 2 | దాం 3 | ధ్రమ 4 | హాభా 5 | రత 6 | ము 7 | ఆది 8 | పర్వ 9 | ము 10 | నన్న 11 | య కవి 12 | ప్రణీ 13 | తము 14 | పరి 15 | ష్కర్త 16 | కవి 17 | సామ్రా 18 | ట్ శ్రీ 19 | విశ్వ 20 | నాథ 21 | -------------------------------------------------------------------------------- /data/mahaa_two_akshara.txt: -------------------------------------------------------------------------------- 1 | శ్రీమ 2 | దాం 3 | ధ్రమ 4 | హాభా 5 | రత 6 | ము 7 | ఆది 8 | పర్వ 9 | ము 10 | నన్న 11 | య కవి 12 | ప్రణీ 13 | తము 14 | పరి 15 | ష్కర్త 16 | కవి 17 | సామ్రా 18 | ట్ శ్రీ 19 | విశ్వ 20 | నాథ 21 | సత్య 22 | నారా 23 | యణ 24 | ప్రచు 25 | రణ 26 | ఆం 27 | ధ్రప్ర 28 | దేశ్ 29 | సాహి 30 | త్య అకా 31 | డమీ 32 | శార్దూ 33 | లవి 34 | క్రీడి 35 | తము 36 | శ్రీవా 37 | ణీగి 38 | రిజా 39 | శ్చిరా 40 | య దధ 41 | తో వక్షో 42 | ముఖా 43 | ఙ్గేషు 44 | యే 45 | లోకా 46 | నాం 47 | స్థితి 48 | మావ 49 | హన్త్య 50 | విహ 51 | తాం 52 | స్త్రీపు 53 | ంస 54 | యోగో 55 | ద్భవా 56 | ం 57 | తే వేద 58 | త్రయ 59 | మూర్త 60 | య స్త్రిపు 61 | రుషా 62 | స్సం 63 | పూజి 64 | తా వ స్సురై 65 | ర్భూయా 66 | సుః 67 | పురు 68 | షోత్త 69 | మామ్బు 70 | జభ 71 | వ శ్రీక 72 | న్ధరా 73 | శ్శ్రేయ 74 | సే. 75 | అవ 76 | తారి 77 | క 78 | వచ 79 | నము 80 | అని 81 | సక 82 | లభు 83 | వన 84 | రక్ష 85 | ణ ప్రభు 86 | వులై 87 | యాద్యు 88 | లైన 89 | హరి 90 | హర 91 | హిర 92 | ణ్యగ 93 | ర్భ పద్మో 94 | మావా 95 | ణీప 96 | తుల 97 | స్తుతి 98 | యిం 99 | చి 100 | తత్ప్ర 101 | సాద 102 | సమా 103 | సాది 104 | త నిత్య 105 | ప్రవ 106 | ర్ధ మాన 107 | మహా 108 | మహీ 109 | రాజ్య 110 | విభ 111 | వుం 112 | డును 113 | నిజ 114 | భుజ 115 | విక్ర 116 | మవి 117 | జితా 118 | రాతి 119 | రాజ 120 | నివ 121 | హుం 122 | డును 123 | నిఖి 124 | లజ 125 | గజ్జే 126 | గీయ 127 | మాన 128 | నానా 129 | గుణ 130 | రత్న 131 | రత్నా 132 | కరు 133 | ండు 134 | ను నై పర 135 | గుచు 136 | న్న రాజ 137 | రాజ 138 | నరే 139 | ం 140 | ద్రుం 141 | డు. 142 | ఉత్ప 143 | లమా 144 | ల 145 | రాజ 146 | కులై 147 | కభూ 148 | షణు 149 | ఁడు 150 | రాజ 151 | మనో 152 | హరు 153 | ఁ డన్య 154 | రాజ 155 | తే 156 | జోజ 157 | యశా 158 | లిశౌ 159 | ర్యుఁ 160 | డు విశు 161 | ద్ధయ 162 | శశ్శ 163 | రది 164 | ందు 165 | చం 166 | ద్రికా 167 | రాజి 168 | తస 169 | ర్వలో 170 | కుఁ 171 | డప 172 | రాజి 173 | తభూ 174 | రిభు 175 | జాకృ 176 | పాణ 177 | ధా 178 | రాజ 179 | లశా 180 | ంత 181 | శాత్ర 182 | వప 183 | రాగు 184 | ఁడు 185 | రాజ 186 | మహే 187 | ంద్రు 188 | ఁ డున్న 189 | తిన్. 190 | కం 191 | దము 192 | విమ 193 | లాది 194 | త్యత 195 | నూజు 196 | ఁడు 197 | విమ 198 | లవి 199 | చారు 200 | ఁడు 201 | గుమా 202 | రవి 203 | ద్యాధ 204 | రుఁ 205 | డు 206 | త్తమ 207 | చాళు 208 | క్యుఁ 209 | డు వివి 210 | ధా 211 | గమ 212 | విజి 213 | తశ్ర 214 | ముఁ 215 | డు తుహి 216 | నక 217 | రుఁ 218 | డురు 219 | కాం 220 | తిన్. 221 | చం 222 | పక 223 | మాల 224 | ఘన 225 | దురి 226 | తాను 227 | బం 228 | ధక 229 | లికా 230 | లజ 231 | దోష 232 | తుషా 233 | రస 234 | ంహ 235 | తిం 236 | దన 237 | యుద 238 | యప్ర 239 | భావ 240 | మున 241 | దవ్వు 242 | గఁ 243 | జోపి 244 | జగ 245 | జ్జనా 246 | నుర 247 | ం 248 | జన 249 | మగు 250 | రాజ్య 251 | సం 252 | తత 253 | వస 254 | ంత 255 | నితా 256 | ంత 257 | విభూ 258 | తి నెం 259 | తయు 260 | ం 261 | దన 262 | రుఁ 263 | జళు 264 | క్యమ 265 | న్మథు 266 | ఁడు 267 | ధర్మ 268 | నిబ 269 | ద్ధద 270 | యార్ద్ర 271 | బుద్ధి 272 | యై. 273 | ఉత్ప 274 | లమా 275 | ల 276 | ఆశ్రి 277 | తపో 278 | షణ 279 | ంబు 280 | న నన 281 | ంత 282 | విలా 283 | సము 284 | నన్ 285 | మనీ 286 | షివి 287 | ద్యాశ్ర 288 | మత 289 | త్త్వవి 290 | త్త్వము 291 | న దాన 292 | గుణా 293 | భిర 294 | తిన్ 295 | సమ 296 | స్తవ 297 | ర్ణాశ్ర 298 | మధ 299 | ర్మర 300 | క్షణ 301 | మహా 302 | మహి 303 | మన్ 304 | మహి 305 | నొప్పు 306 | సర్వ 307 | లో 308 | కాశ్ర 309 | యుఁ 310 | డాది 311 | రాజ 312 | నిభు 313 | ఁ డత్య 314 | కల 315 | ంక 316 | చరి 317 | త్రస 318 | ంప 319 | దన్. 320 | సీస 321 | ము 322 | నిజ 323 | మహీ 324 | మం 325 | డల 326 | ప్రజ 327 | ఁ బ్రీతి 328 | ఁ బెం 329 | చుచు 330 | ఁ 331 | బర 332 | మం 333 | డల 334 | ంబు 335 | ల ధర 336 | ణిప 337 | తుల 338 | నది 339 | మి కప్ప 340 | ంబు 341 | ల ముద 342 | ముతో 343 | ఁ గొను 344 | చును 345 | బలి 346 | మి నీయ 347 | ని భూమి 348 | వల 349 | యప 350 | తుల 351 | నుక్క 352 | డఁ 353 | గిం 354 | చుచు 355 | దిక్కు 356 | లఁ 357 | దన 358 | యాజ్ఞ 359 | వెలు 360 | ఁగి 361 | ంచు 362 | చును 363 | విప్ర 364 | కుల 365 | ము నెల్ల 366 | ఁ 367 | బ్రోచు 368 | చు శర 369 | ణన్న 370 | ఁ గాచు 371 | చు భీతు 372 | ల 373 | నగ్ర 374 | జన్ము 375 | లకు 376 | నను 377 | గ్రహ 378 | మున 379 | ఁ 380 | ఆట 381 | వెల 382 | ది 383 | జారు 384 | తర 385 | మహా 386 | గ్రహా 387 | రం 388 | బు లిచ్చు 389 | చు 390 | దేవ 391 | భోగ 392 | ముల 393 | మహా 394 | విభూ 395 | తిఁ 396 | దన 397 | రఁ 398 | జేయు 399 | చిట్లు 400 | మను 401 | మార్గు 402 | ఁ డగు 403 | విష్ణు 404 | వర్ధ 405 | నుం 406 | డు వం 407 | శవ 408 | ర్ధను 409 | ండు 410 | . 411 | వచ 412 | నము 413 | అఖి 414 | లజ 415 | లధి 416 | వేలా 417 | వల 418 | యిత 419 | వసు 420 | మతీ 421 | వని 422 | తావి 423 | భూష 424 | ణం 425 | బైన 426 | వేం 427 | గీదే 428 | శం 429 | బున 430 | కు నాయ 431 | కర 432 | త్నం 433 | బును 434 | ంబో 435 | ని రాజ 436 | మహే 437 | ం 438 | ద్రపు 439 | రం 440 | బున 441 | ందు 442 | మహే 443 | ంద్ర 444 | మహి 445 | మ తోఁ 446 | బర 447 | మాన 448 | ంద 449 | ంబు 450 | న నన 451 | వర 452 | తమ 453 | హామ 454 | హీరా 455 | జ్యసు 456 | ఖం 457 | బు లను 458 | భవి 459 | ంచు 460 | చు సక 461 | ల 462 | భువ 463 | నల 464 | క్ష్మీవి 465 | లాస 466 | నివా 467 | సం 468 | బయి 469 | న రమ్య 470 | హర్మ్య 471 | తల 472 | ంబు 473 | న మం 474 | త్రి పురో 475 | హిత 476 | సేనా 477 | పతి 478 | దం 479 | డనా 480 | యక 481 | దౌవా 482 | ర 483 | ిక మహా 484 | ప్రధా 485 | న సామ 486 | ంత 487 | విలా 488 | సినీ 489 | పరి 490 | వృతు 491 | ఁడ 492 | యి యపా 493 | రశ 494 | బ్దశా 495 | స్త్రపా 496 | రగు 497 | లైన 498 | వైయా 499 | కర 500 | ణులు 501 | ను భార 502 | త రామా 503 | యణా 504 | నేక 505 | పురా 506 | ణప్ర 507 | వీణు 508 | లైన 509 | పౌరా 510 | ణికు 511 | లును 512 | మృదు 513 | మధు 514 | రర 515 | సభా 516 | వ భాసు 517 | రన 518 | వార్థ 519 | వచ 520 | నర 521 | చనా 522 | విశా 523 | రదు 524 | లయి 525 | న మహా 526 | కవు 527 | లును 528 | వివి 529 | ధత 530 | ర్కవి 531 | గా హిత 532 | సమ 533 | స్తశా 534 | స్త్రసా 535 | గర 536 | గరీ 537 | యప్ర 538 | తిభు 539 | లైన 540 | తార్కి 541 | కులు 542 | ను నా 543 | దిగా 544 | ఁ గలు 545 | గు విద్వ 546 | జ్జన 547 | ంబు 548 | లు పరి 549 | వేష్ఠి 550 | ంచి 551 | కొలు 552 | చుచు 553 | ండ 554 | విద్యా 555 | విలా 556 | సగో 557 | ష్ఠీసు 558 | ఖోప 559 | విష్టు 560 | ం 561 | డయి 562 | యిష్ట 563 | కథా 564 | వినో 565 | దం 566 | బుల 567 | నుం 568 | డి యొక్క 569 | నాఁ 570 | డు. 571 | సీస 572 | ము 573 | తన 574 | కుల 575 | బ్రాహ్మ 576 | ణు నను 577 | రక్తు 578 | నవి 579 | రత 580 | జప 581 | హోమ 582 | తత్ప 583 | రు విపు 584 | లశ 585 | బ్ద 586 | శాస 587 | ను సం 588 | హితా 589 | భ్యాసు 590 | బ్రహ్మా 591 | ండా 592 | ది 593 | నానా 594 | పురా 595 | ణవి 596 | జ్ఞాన 597 | నిర 598 | తుఁ 599 | బాత్రు 600 | నాప 601 | స్తం 602 | బసూ 603 | త్రు ముద్గ 604 | లగో 605 | త్ర 606 | జాతు 607 | సద్వి 608 | నుతా 609 | వదా 610 | తచ 611 | రితు 612 | లోక 613 | జ్ఞు నుభ 614 | యభా 615 | షాకా 616 | వ్యర 617 | చనా 618 | భి 619 | శోభి 620 | తు సత్ప్ర 621 | తిభా 622 | భియో 623 | గ్యు 624 | ఆట 625 | వెల 626 | ది 627 | నిత్య 628 | సత్య 629 | వచ 630 | ను మత్య 631 | మరా 632 | ధిపా 633 | చార్యు 634 | సుజ 635 | ను నన్న 636 | పార్యు 637 | ఁ జూచి 638 | పర 639 | మధ 640 | ర్మవి 641 | దుఁ 642 | డు వర 643 | చళు 644 | క్యాన్వ 645 | యా 646 | భర 647 | ణుఁ 648 | డిట్టు 649 | లని 650 | యెఁ 651 | గరు 652 | ణతో 653 | డ. 654 | చం 655 | పక 656 | మాల 657 | విమ 658 | లమ 659 | తిం 660 | బురా 661 | ణము 662 | లు విం 663 | టి ననే 664 | కము 665 | లర్థ 666 | ధర్మ 667 | శా 668 | స్త్రము 669 | లతె 670 | ఱం 671 | గెఱి 672 | ంగి 673 | తి నుదా 674 | త్తర 675 | సాన్వి 676 | తకా 677 | వ్యనా 678 | టక 679 | క్రమ 680 | ములు 681 | పెక్కు 682 | సూచి 683 | తి జగ 684 | త్పరి 685 | పూజ్య 686 | మునై 687 | న యీశ్వ 688 | రా 689 | గమ 690 | ముల 691 | యం 692 | దు నిల్పి 693 | తిఁ 694 | బ్రకా 695 | శము 696 | గా హృద 697 | యం 698 | బు భక్తి 699 | తోన్. 700 | వచ 701 | నము 702 | అయి 703 | నను 704 | నాకు 705 | నన 706 | వర 707 | తం 708 | బును 709 | శ్రీమ 710 | హాభా 711 | రత 712 | ంబు 713 | నం 714 | దుల 715 | యభి 716 | ప్రాయ 717 | ంబు 718 | పెద్ద 719 | యై యుం 720 | డు. 721 | మత్తే 722 | భము 723 | ఇవి 724 | యేను 725 | న్ సత 726 | తం 727 | బు నాయె 728 | డఁ 729 | గర 730 | ం బిష్ట 731 | ంబు 732 | లై యుం 733 | డుఁ 734 | బా 735 | యవు 736 | భూదే 737 | వకు 738 | లాభి 739 | తర్ప 740 | ణమ 741 | హీయ 742 | ఃప్రీ 743 | తియు 744 | న్ భార 745 | త 746 | శ్రవ 747 | ణాస 748 | క్తియు 749 | ఁ బార్వ 750 | తీప 751 | తిప 752 | దాబ్జ 753 | ధ్యాన 754 | పూజా 755 | మహో 756 | త్సవ 757 | మున్ 758 | సం 759 | తత 760 | దాన 761 | శీల 762 | తయు 763 | శశ్వ 764 | త్సాధు 765 | సాం 766 | గత్య 767 | మున్. 768 | వచ 769 | నము 770 | మఱి 771 | యది 772 | యును 773 | ంగా 774 | క. 775 | చం 776 | పక 777 | మాల 778 | హిమ 779 | కరు 780 | ఁ దొట్టి 781 | పూరు 782 | భర 783 | తేశ 784 | కురు 785 | ప్రభు 786 | పాం 787 | డుభూ 788 | పతు 789 | ల్ 790 | క్రమ 791 | మున 792 | వం 793 | శక 794 | ర్త లన 795 | ఁగా 796 | మహి 797 | నొప్పి 798 | న యస్మ 799 | దీయ 800 | వం 801 | శము 802 | నఁ 803 | బ్రసి 804 | ద్ధులై 805 | విమ 806 | లస 807 | ద్గుణ 808 | శోభి 809 | తులై 810 | న పాం 811 | డవో 812 | త్తము 813 | ల చరి 814 | త్ర నాకు 815 | సత 816 | తం 817 | బు విన 818 | ంగ 819 | నభీ 820 | ష్ట మెం 821 | తయు 822 | న్. 823 | చం 824 | పక 825 | మాల 826 | అమ 827 | లసు 828 | వర్ణ 829 | శృం 830 | గఖు 831 | రమై 832 | కపి 833 | లం 834 | బగు 835 | గోశ 836 | తం 837 | బు ను 838 | త్తమ 839 | బహు 840 | వేద 841 | విప్రు 842 | లకు 843 | దాన 844 | ము సేసి 845 | న తత్ఫ 846 | లం 847 | బు త 848 | ధ్యమ 849 | సమ 850 | కూరు 851 | భార 852 | తక 853 | థాశ్ర 854 | వణా 855 | భిర 856 | తిన్ 857 | మదీ 858 | యచి 859 | త్తము 860 | నని 861 | శం 862 | బు భార 863 | తక 864 | థాశ్ర 865 | వణ 866 | ప్రవ 867 | ణం 868 | బ కావు 869 | నన్. 870 | కం 871 | దము 872 | జన 873 | నుత 874 | కృష్ణ 875 | ద్వైపా 876 | యన 877 | ముని 878 | వృష 879 | భాభి 880 | హిత 881 | మహా 882 | భార 883 | తబ 884 | ద్ధని 885 | రూపి 886 | తార్థ 887 | మేర్ప 888 | డఁ 889 | దెను 890 | ఁగు 891 | న రచి 892 | యిం 893 | పు మధి 894 | కధీ 895 | యుక్తి 896 | మెయి 897 | న్. 898 | కం 899 | దము 900 | బహు 901 | భాష 902 | ల బహు 903 | విధ 904 | ముల 905 | బహు 906 | జన 907 | ముల 908 | వల 909 | న విను 910 | చు భార 911 | తబ 912 | ద్ధ 913 | స్పృహు 914 | లగు 915 | వారి 916 | కి నెప్పు 917 | డు 918 | బహు 919 | యాగ 920 | ంబు 921 | లఫ 922 | లం 923 | బు పర 924 | మార్థ 925 | మిల 926 | న్ 927 | వచ 928 | నము 929 | అని 930 | యాన 931 | తిచ్చి 932 | న విని 933 | యక్క 934 | వివ 935 | రుం 936 | డిట్ల 937 | నియె 938 | . 939 | చం 940 | పక 941 | మాల 942 | అమ 943 | లిన 944 | తార 945 | కాస 946 | ముద 947 | యం 948 | బుల 949 | నెన్న 950 | ను సర్వ 951 | వేద 952 | శా 953 | స్త్రము 954 | ల యశే 955 | షపా 956 | రము 957 | ముద 958 | ంబు 959 | నఁ 960 | బొం 961 | దను 962 | బుద్ధి 963 | బాహు 964 | వి 965 | క్రమ 966 | మున 967 | దుర్గ 968 | మార్థ 969 | జల 970 | గౌర 971 | వభా 972 | రత 973 | భార 974 | తీస 975 | ము 976 | ద్రము 977 | ఁ దఱి 978 | యం 979 | గ నీఁ 980 | దను 981 | విధా 982 | తృన 983 | కైన 984 | ను నేర 985 | ఁ బోలు 986 | నే. 987 | వచ 988 | నము 989 | అయి 990 | నను 991 | దేవా 992 | నీయ 993 | నుమ 994 | తం 995 | బున 996 | విద్వ 997 | జ్జన 998 | ంబు 999 | ల యను 1000 | గ్రహ 1001 | ంబు 1002 | నం 1003 | నానే 1004 | ర్చువి 1005 | ధం 1006 | బున 1007 | నిక్కా 1008 | వ్యం 1009 | బు 1010 | రచి 1011 | యిం 1012 | చెద 1013 | నని 1014 | . 1015 | తర 1016 | లము 1017 | హరి 1018 | హరా 1019 | జగ 1020 | జాన 1021 | నార్క 1022 | షడా 1023 | స్యమా 1024 | తృస 1025 | రస్వ 1026 | తీ 1027 | గిరి 1028 | సుతా 1029 | దిక 1030 | దేవ 1031 | తాత 1032 | తికి 1033 | న్ నమ 1034 | స్కృతి 1035 | సేసి 1036 | దు 1037 | ర్భర 1038 | తపో 1039 | విభ 1040 | వాధి 1041 | కున్ 1042 | గురు 1043 | ఁ బద్య 1044 | విద్య 1045 | కునా 1046 | ద్యు నం 1047 | బురు 1048 | హగ 1049 | ర్భని 1050 | భుం 1051 | బ్రచే 1052 | తసు 1053 | పుత్త్రు 1054 | భక్తి 1055 | ఁ దల 1056 | ంచు 1057 | చున్. 1058 | ఉత్ప 1059 | లమా 1060 | ల 1061 | భార 1062 | తభా 1063 | రతీ 1064 | శుభ 1065 | గభ 1066 | స్తిచ 1067 | యం 1068 | బుల 1069 | ఁ జేసి 1070 | ఘోర 1071 | సం 1072 | సార 1073 | వికా 1074 | రస 1075 | ంత 1076 | మస 1077 | జాల 1078 | విజృ 1079 | ంభ 1080 | ము వాపి 1081 | సూరి 1082 | చే 1083 | తోరు 1084 | చిరా 1085 | బ్జబో 1086 | ధన 1087 | రతు 1088 | ండ 1089 | గు దివ్యు 1090 | ఁ బరా 1091 | శరా 1092 | త్మజా 1093 | ం 1094 | భోరు 1095 | హమి 1096 | త్రుఁ 1097 | గొల్చి 1098 | ముని 1099 | పూజి 1100 | తు భూరి 1101 | యశో 1102 | విరా 1103 | జితు 1104 | న్. 1105 | వచ 1106 | నము 1107 | మఱి 1108 | యును 1109 | చం 1110 | పక 1111 | మాల 1112 | పర 1113 | మవి 1114 | వేక 1115 | సౌర 1116 | భవి 1117 | భాసి 1118 | తస 1119 | ద్గుణ 1120 | పుం 1121 | జవా 1122 | రిజో 1123 | త్కర 1124 | రుచి 1125 | రం 1126 | బులై 1127 | సక 1128 | లగ 1129 | మ్యసు 1130 | తీర్థ 1131 | ములై 1132 | మహా 1133 | మనో 1134 | హర 1135 | సుచ 1136 | రిత్ర 1137 | పావ 1138 | నప 1139 | యః 1140 | పరి 1141 | పూర్ణ 1142 | ములై 1143 | న సత్సా 1144 | భాం 1145 | తర 1146 | సర 1147 | సీవ 1148 | నం 1149 | బుల 1150 | ముద 1151 | ం బొన 1152 | రం 1153 | గొని 1154 | యాడి 1155 | వేడు 1156 | కన్. 1157 | ఉత్ప 1158 | లమా 1159 | ల 1160 | పాయ 1161 | క పాక 1162 | శాస 1163 | నికి 1164 | భార 1165 | త ఘోర 1166 | రణ 1167 | ంబు 1168 | నం 1169 | దు నా 1170 | రాయ 1171 | ణున 1172 | ట్లు తాను 1173 | ను ధరా 1174 | మర 1175 | వం 1176 | శవి 1177 | భూష 1178 | ణుం 1179 | డు నా 1180 | రాయ 1181 | ణభ 1182 | ట్టు వాఙ్మ 1183 | యధు 1184 | రం 1185 | ధరు 1186 | ఁడు 1187 | ం దన 1188 | కిష్టు 1189 | ఁడు 1190 | న్ సహా 1191 | ధ్యాయు 1192 | ఁడు 1193 | నైన 1194 | వాఁ 1195 | డభి 1196 | మత 1197 | ంబు 1198 | గఁ 1199 | దోడ 1200 | యి నిర్వ 1201 | హిం 1202 | పఁ 1203 | గన్. 1204 | ఉత్ప 1205 | లమా 1206 | ల 1207 | సార 1208 | మతి 1209 | ం గవీ 1210 | ంద్రు 1211 | లు ప్రస 1212 | న్నక 1213 | థాక 1214 | వితా 1215 | ర్థయు 1216 | క్తి లో 1217 | నార 1218 | సి మేలు 1219 | నా నిత 1220 | రు లక్ష 1221 | రర 1222 | మ్యత 1223 | నాద 1224 | రిం 1225 | ప నా 1226 | నారు 1227 | చిరా 1228 | ర్థసూ 1229 | క్తిని 1230 | ధి నన్న 1231 | యభ 1232 | ట్టు తెను 1233 | ంగు 1234 | నన్ 1235 | మహా 1236 | భార 1237 | తస 1238 | ంహి 1239 | తార 1240 | చన 1241 | బం 1242 | ధురు 1243 | ఁ డయ్యె 1244 | జగ 1245 | ద్ధిత 1246 | ంబు 1247 | గన్. 1248 | భార 1249 | తక 1250 | థాప్ర 1251 | స్తావ 1252 | న 1253 | వచ 1254 | నము 1255 | తత్క 1256 | థాప్రా 1257 | రం 1258 | భం 1259 | బెట్టి 1260 | దని 1261 | న. 1262 | సీస 1263 | ము 1264 | నైమి 1265 | శార 1266 | ణ్యపు 1267 | ణ్యక్షే 1268 | త్రము 1269 | నఁ 1270 | గుల 1271 | పతి 1272 | శౌన 1273 | కుం 1274 | డను 1275 | పర 1276 | మమౌ 1277 | ని 1278 | బ్రహ్మ 1279 | ర్షి గణ 1280 | సము 1281 | పాసి 1282 | తుం 1283 | డై సర్వ 1284 | లోక 1285 | హితా 1286 | ర్థం 1287 | బు లోక 1288 | సుతు 1289 | ఁడు 1290 | ద్వాద 1291 | శవా 1292 | ర్షికో 1293 | త్తమ 1294 | సత్ర 1295 | యాగ 1296 | ంబు 1297 | మొగి 1298 | ఁ జేయు 1299 | చున్న 1300 | నమ్ము 1301 | నుల 1302 | కడ 1303 | కు 1304 | వచ్చి 1305 | తా నుగ్ర 1306 | శ్రవ 1307 | సుఁ 1308 | డను 1309 | సూతు 1310 | ఁడు 1311 | రౌమ 1312 | హర్ష 1313 | ణి సుపౌ 1314 | రాణి 1315 | కుం 1316 | డు 1317 | ఆట 1318 | వెల 1319 | ది 1320 | పర 1321 | మభ 1322 | క్తితో 1323 | డఁ 1324 | బ్రణ 1325 | మిల్లి 1326 | యున్న 1327 | నక్క 1328 | థకు 1329 | వల 1330 | న ముని 1331 | నికా 1332 | య మెల్ల 1333 | వివి 1334 | ధపు 1335 | ణ్యక 1336 | థలు 1337 | విను 1338 | వేడ్క 1339 | నత 1340 | నిఁ 1341 | బూజి 1342 | ంచి 1343 | రప 1344 | రిమి 1345 | తవి 1346 | శేష 1347 | విధు 1348 | ల. 1349 | వచ 1350 | నము 1351 | అక్క 1352 | థకు 1353 | ండు 1354 | వెం 1355 | డియు 1356 | నమ్ము 1357 | ని సం 1358 | ఘం 1359 | బున 1360 | కు నమ 1361 | స్కార 1362 | ంబు 1363 | చేసి 1364 | యే ననే 1365 | క పురా 1366 | ణపు 1367 | ణ్యక 1368 | థాక 1369 | థన 1370 | దక్ 1371 | షుం 1372 | డ వ్యాస 1373 | శిష్యు 1374 | ండై 1375 | న రోమ 1376 | హర్ష 1377 | ణున 1378 | కుఁ 1379 | బుత్త్రు 1380 | ండ 1381 | నావ 1382 | లన 1383 | నెక్క 1384 | థ విన 1385 | వల 1386 | తు రని 1387 | న నమ్ము 1388 | ను 1389 | లత 1390 | ని కిట్ల 1391 | నిరి 1392 | కం 1393 | దము 1394 | కం 1395 | దము 1396 | ఏయ 1397 | ది హృద్య 1398 | మపూ 1399 | ర్వం 1400 | బేయ 1401 | ది యెద్దా 1402 | ని విని 1403 | న నెఱు 1404 | క సమ 1405 | గ్రం 1406 | బై యుం 1407 | డు నఘ 1408 | నిబ 1409 | ర్హ ణ 1410 | మేయ 1411 | ది యక్క 1412 | థయ 1413 | విన 1414 | ఁగ 1415 | నిష్ట 1416 | ము మాకు 1417 | న్. 1418 | -------------------------------------------------------------------------------- /data/mahaabhaaratam_aadi.txt: -------------------------------------------------------------------------------- 1 | శ్రీమదాంధ్రమహాభారతము 2 | ఆదిపర్వము 3 | నన్నయ కవి ప్రణీతము 4 | పరిష్కర్త కవిసామ్రాట్ శ్రీ విశ్వనాథ సత్యనారాయణ 5 | ప్రచురణ ఆంధ్రప్రదేశ్ సాహిత్య అకాడమీ 6 | శార్దూలవిక్రీడితము 7 | శ్రీవాణీగిరిజా శ్చిరాయ దధతో వక్షోముఖాఙ్గేషు యే 8 | లోకానాం స్థితి మావహన్త్యవిహతాం స్త్రీపుంసయోగోద్భవాం 9 | తే వేదత్రయమూర్తయ స్త్రిపురుషా స్సంపూజితా వ స్సురై 10 | ర్భూయాసుః పురుషోత్త మామ్బుజభవ శ్రీకన్ధరా శ్శ్రేయసే. 11 | అవతారిక 12 | వచనము 13 | అని సకలభువనరక్షణ ప్రభువులై యాద్యులైన హరిహరహిరణ్యగర్భ పద్మోమావాణీపతుల స్తుతియించి 14 | తత్ప్రసాదసమాసాదిత నిత్యప్రవర్ధ మాన మహామహీరాజ్యవిభవుండును నిజభుజవిక్రమవిజితారాతి 15 | రాజ నివహుండును నిఖిలజగజ్జేగీయమాననానాగుణరత్నరత్నాకరుండును నై పరగుచున్న రాజరాజనరేం 16 | ద్రుండు. 17 | ఉత్పలమాల 18 | రాజకులైకభూషణుఁడు రాజమనోహరుఁ డన్యరాజతే 19 | జోజయశాలిశౌర్యుఁడు విశుద్ధయశశ్శరదిందుచంద్రికా 20 | రాజితసర్వలోకుఁ డపరాజితభూరిభుజాకృపాణధా 21 | రాజలశాంతశాత్రవపరాగుఁడు రాజమహేంద్రుఁ డున్నతిన్. 22 | కందము 23 | విమలాదిత్యతనూజుఁడు 24 | విమలవిచారుఁడు గుమారవిద్యాధరుఁ డు 25 | త్తమచాళుక్యుఁడు వివిధా 26 | గమవిజితశ్రముఁడు తుహినకరుఁ డురుకాంతిన్. 27 | చంపకమాల 28 | ఘనదురితానుబంధకలికాలజదోషతుషారసంహతిం 29 | దన యుదయప్రభావమున దవ్వుగఁ జోపి జగజ్జనానురం 30 | జన మగు రాజ్యసంతతవసంతనితాంతవిభూతి నెంతయుం 31 | దనరుఁ జళుక్యమన్మథుఁడు ధర్మనిబద్ధదయార్ద్రబుద్ధి యై. 32 | ఉత్పలమాల 33 | ఆశ్రితపోషణంబున ననంతవిలాసమునన్ మనీషివి 34 | ద్యాశ్రమత త్త్వవిత్త్వమున దానగుణాభిరతిన్ సమ స్తవ 35 | ర్ణాశ్రమధర్మరక్షణమహామహిమన్ మహి నొప్పు సర్వలో 36 | కాశ్రయుఁ డాదిరాజనిభుఁ డత్యకలంకచరిత్రసంపదన్. 37 | సీసము 38 | నిజమహీమండలప్రజఁ బ్రీతిఁ బెంచుచుఁ 39 | బరమండలంబుల ధరణిపతుల 40 | నదిమి కప్పంబుల ముదముతోఁ గొనుచును 41 | బలిమి నీయని భూమివలయపతుల 42 | నుక్కడఁగించుచు దిక్కులఁ దనయాజ్ఞ 43 | వెలుఁగించుచును విప్రకులము నెల్లఁ 44 | బ్రోచుచు శర ణన్నఁ గాచుచు భీతుల 45 | నగ్రజన్ములకు ననుగ్రహమునఁ 46 | ఆటవెలది 47 | జారుతరమహాగ్రహారంబు లిచ్చుచు 48 | దేవభోగముల మహావిభూతిఁ 49 | దనరఁ జేయు చిట్లు మనుమార్గుఁ డగు 50 | విష్ణువర్ధనుండు వంశవర్ధనుండు. 51 | వచనము 52 | అఖిలజలధివేలావలయితవసుమతీవనితావిభూషణంబైన వేంగీదేశంబునకు నాయకరత్నంబునుంబోని రాజమహేం 53 | ద్రపురంబునందు మహేంద్రమహిమ తోఁ బరమానందంబున ననవరతమహామహీరాజ్యసుఖంబు లనుభవించుచు సకల 54 | భువనలక్ష్మీవిలాసనివాసంబయిన రమ్యహర్మ్యతలంబున మంత్రి పురోహిత సేనాపతి దండనాయక దౌవార 55 | ిక మహాప్రధాన సామంత విలాసినీ పరివృతుఁడయి యపారశబ్దశాస్త్రపారగులైన వైయాకరణులును భార 56 | త రామాయణానేకపురాణప్రవీణులైన పౌరాణికులును మృదుమధురరసభావ భాసురనవార్థవచనరచనావిశారదు 57 | లయిన మహాకవులును వివిధతర్కవిగా హితసమస్తశాస్త్రసాగరగరీయప్రతిభులైన తార్కికులును నా 58 | దిగాఁ గలుగు విద్వజ్జనంబులు పరివేష్ఠించి కొలుచుచుండ విద్యావిలాసగోష్ఠీసుఖోపవిష్టుం 59 | డయి యిష్టకథావినోదంబుల నుండి యొక్కనాఁడు. 60 | సీసము 61 | తన కులబ్రాహ్మణు ననురక్తు నవిరత 62 | జపహోమతత్పరు విపులశబ్ద 63 | శాసను సంహితాభ్యాసు బ్రహ్మాండాది 64 | నానాపురాణవిజ్ఞాననిరతుఁ 65 | బాత్రు నాపస్తంబసూత్రు ముద్గలగోత్ర 66 | జాతు సద్వినుతావదాతచరితు 67 | లోకజ్ఞు నుభయభాషాకావ్యరచనాభి 68 | శోభితు సత్ప్రతిభాభియోగ్యు 69 | ఆటవెలది 70 | నిత్యసత్యవచను మత్యమరాధిపా 71 | చార్యు సుజను నన్నపార్యుఁ జూచి 72 | పరమధర్మవిదుఁడు వరచళుక్యాన్వయా 73 | భరణుఁ డిట్టు లనియెఁ గరుణతోడ. 74 | చంపకమాల 75 | విమలమతిం బురాణములు వింటి ననేకము లర్థధర్మశా 76 | స్త్రములతెఱం గెఱింగితి నుదాత్తరసాన్వితకావ్యనాటక 77 | క్రమములు పెక్కు సూచితి జగత్పరిపూజ్యమునైన యీశ్వరా 78 | గమములయందు నిల్పితిఁ బ్రకాశముగా హృదయంబు భక్తితోన్. 79 | వచనము 80 | అయినను నాకు ననవరతంబును శ్రీమహాభారతంబునందుల యభిప్రాయంబు పెద్దయై యుండు. 81 | మత్తేభము 82 | ఇవి యేనున్ సతతంబు నాయెడఁ గరం బిష్టంబు లై యుండుఁ బా 83 | యవు భూదేవకులాభితర్పణమహీయఃప్రీతియున్ భారత 84 | శ్రవణాసక్తియుఁ బార్వతీపతిపదాబ్జధ్యానపూజామహో 85 | త్సవమున్ సంతతదానశీలతయు శశ్వత్సాధుసాంగత్యమున్. 86 | వచనము 87 | మఱి యదియునుంగాక. 88 | చంపకమాల 89 | హిమకరుఁ దొట్టి పూరుభరతేశకురుప్రభుపాండుభూపతుల్ 90 | క్రమమున వంశకర్త లనఁగా మహి నొప్పిన యస్మదీయవం 91 | శమునఁ బ్రసిద్ధులై విమలస ద్గుణశోభితులైన పాండవో 92 | త్తముల చరిత్ర నాకు సతతంబు వినంగ నభీష్ట మెంతయున్. 93 | చంపకమాల 94 | అమలసువర్ణశృంగఖురమై కపిలంబగు గోశతంబు ను 95 | త్తమబహువేదవిప్రులకు దానము సేసిన తత్ఫలంబు త 96 | ధ్యమ సమకూరు భారతకథాశ్రవణాభిరతిన్ మదీయచి 97 | త్తము ననిశంబు భారతకథాశ్రవణప్రవణంబ కావునన్. 98 | కందము 99 | జననుతకృష్ణద్వైపా 100 | యన మునివృషభాభిహిత మహాభారతబ 101 | ద్ధనిరూపితార్థ మేర్పడఁ 102 | దెనుఁగున రచియింపు మధికధీయుక్తిమెయిన్. 103 | కందము 104 | బహుభాషల బహువిధముల 105 | బహుజనములవలన వినుచు భారతబద్ధ 106 | స్పృహులగు వారికి నెప్పుడు 107 | బహుయాగంబులఫలంబు పరమార్థ మిలన్ 108 | వచనము 109 | అని యానతిచ్చిన విని యక్కవివరుం డిట్లనియె. 110 | చంపకమాల 111 | అమలినతారకాసముదయంబుల నెన్నను సర్వవేదశా 112 | స్త్రముల యశేషపారము ముదంబునఁ బొందను బుద్ధిబాహువి 113 | క్రమమున దుర్గమార్థ జలగౌరవభారతభారతీసము 114 | ద్రముఁ దఱియంగ నీఁదను విధాతృనకైనను నేరఁ బోలునే. 115 | వచనము 116 | అయినను దేవా నీయనుమతంబున విద్వజ్జనంబుల యనుగ్రహంబునం నానేర్చువిధంబున నిక్కావ్యంబు 117 | రచియించెద నని. 118 | తరలము 119 | హరిహరాజగజాననార్కషడాస్యమాతృసరస్వతీ 120 | గిరిసుతాదిక దేవతాతతికిన్ నమస్కృతి సేసి దు 121 | ర్భరతపోవిభవాధికున్ గురుఁ బద్యవిద్యకునాద్యు నం 122 | బురుహగర్భనిభుం బ్రచేతసుపుత్త్రు భక్తిఁ దలంచుచున్. 123 | ఉత్పలమాల 124 | భారతభారతీశుభగభస్తిచయంబులఁ జేసి ఘోరసం 125 | సారవికారసంతమసజాలవిజృంభము వాపి సూరిచే 126 | తోరుచిరాబ్జబోధనరతుండగు దివ్యుఁ బరాశరాత్మజాం 127 | భోరుహమిత్రుఁ గొల్చి మునిపూజితు భూరియశోవిరాజితున్. 128 | వచనము 129 | మఱియును 130 | చంపకమాల 131 | పరమవివేకసౌరభవిభాసితసద్గుణపుంజవారిజో 132 | త్కరరుచిరంబులై సకలగమ్యసుతీర్థములై మహామనో 133 | హరసుచరిత్రపావనపయఃపరిపూర్ణములైన సత్సాభాం 134 | తరసరసీవనంబుల ముదం బొనరం గొనియాడి వేడుకన్. 135 | ఉత్పలమాల 136 | పాయక పాకశాసనికి భారత ఘోరరణంబునందు నా 137 | రాయణునట్లు తానును ధరామరవంశవిభూషణుండు నా 138 | రాయణభట్టు వాఙ్మయధురంధరుఁడుం దనకిష్టుఁడున్ సహా 139 | ధ్యాయుఁడు నైనవాఁ డభిమతంబుగఁ దోడయి నిర్వహింపఁగన్. 140 | ఉత్పలమాల 141 | సారమతిం గవీంద్రులు ప్రసన్నకథాకవితార్థయుక్తి లో 142 | నారసి మేలు నా నితరు లక్షరరమ్యత నాదరింప నా 143 | నారుచిరార్థసూక్తినిధి నన్నయభట్టు తెనుంగునన్ మహా 144 | భారతసంహితారచనబంధురుఁ డయ్యె జగద్ధితంబుగన్. 145 | భారతకథాప్రస్తావన 146 | వచనము 147 | తత్కథాప్రారంభం బెట్టి దనిన. 148 | సీసము 149 | నైమిశారణ్యపుణ్యక్షేత్రమునఁ గుల 150 | పతి శౌనకుండను పరమమౌని 151 | బ్రహ్మర్షి గణసముపాసితుండై సర్వ 152 | లోకహితార్థంబు లోకసుతుఁడు 153 | ద్వాదశవార్షికోత్తమసత్రయాగంబు 154 | మొగిఁ జేయుచున్న నమ్మునులకడకు 155 | వచ్చి తా నుగ్రశ్రవసుఁడను సూతుఁడు 156 | రౌమహర్షణి సుపౌరాణికుండు 157 | ఆటవెలది 158 | పరమభక్తితోడఁ బ్రణమిల్లి యున్న 159 | నక్కథకువలన మునినికాయ మెల్ల 160 | వివిధపుణ్యకథలు వినువేడ్క నతనిఁ 161 | బూజించి రపరిమితవిశేషవిధుల. 162 | వచనము 163 | అక్కథకుండు వెండియు నమ్ముని సంఘంబునకు నమస్కారంబు చేసి యే ననేక పురాణపుణ్యకథాకథనదక్ 164 | షుండ వ్యాసశిష్యుండైన రోమహర్షణునకుఁ బుత్త్రుండ నావలన నెక్కథ విన వలతు రనిన నమ్మును 165 | లతని కిట్లనిరి 166 | కందము 167 | కందము 168 | ఏయది హృద్య మపూర్వం 169 | బేయది యెద్దాని వినిన నెఱుక సమగ్రం 170 | బై యుండు నఘనిబర్హ ణ 171 | మేయది యక్కథయ వినఁగ నిష్టము మాకున్. 172 | -------------------------------------------------------------------------------- /data/praasa.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakeshvar/chamanti_ocr_theano/4eb457ebf9cf6157f7d3fa8f42ae8e98766ad2ac/data/praasa.tif -------------------------------------------------------------------------------- /data/praasa_tiny.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakeshvar/chamanti_ocr_theano/4eb457ebf9cf6157f7d3fa8f42ae8e98766ad2ac/data/praasa_tiny.tif -------------------------------------------------------------------------------- /data/twilight.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakeshvar/chamanti_ocr_theano/4eb457ebf9cf6157f7d3fa8f42ae8e98766ad2ac/data/twilight.jpg -------------------------------------------------------------------------------- /data/twilight.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakeshvar/chamanti_ocr_theano/4eb457ebf9cf6157f7d3fa8f42ae8e98766ad2ac/data/twilight.tiff -------------------------------------------------------------------------------- /docs/rnn_ctc_presentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakeshvar/chamanti_ocr_theano/4eb457ebf9cf6157f7d3fa8f42ae8e98766ad2ac/docs/rnn_ctc_presentation.pdf -------------------------------------------------------------------------------- /docs/script_agnostic_ocr_rnn_ctc_loss.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakeshvar/chamanti_ocr_theano/4eb457ebf9cf6157f7d3fa8f42ae8e98766ad2ac/docs/script_agnostic_ocr_rnn_ctc_loss.pdf -------------------------------------------------------------------------------- /lab/ctc_cost_mohpz.py: -------------------------------------------------------------------------------- 1 | """ 2 | CTC-Connectionist Temporal Classification 3 | 4 | Code provided by Mohammad Pezeshki - May. 2015 - 5 | Montreal Institute for Learning Algorithms 6 | 7 | Referece: Graves, Alex, et al. "Connectionist temporal classification: 8 | labelling unsegmented sequence data with recurrent neural networks." 9 | Proceedings of the 23rd international conference on Machine learning. 10 | ACM, 2006. 11 | 12 | Credits: Shawn Tan, Rakesh Var 13 | 14 | This code is distributed without any warranty, express or implied. 15 | """ 16 | 17 | import theano 18 | from theano import tensor 19 | 20 | floatX = theano.config.floatX 21 | 22 | 23 | # T: INPUT_SEQUENCE_LENGTH 24 | # B: BATCH_SIZE 25 | # L: OUTPUT_SEQUENCE_LENGTH 26 | # C: NUM_CLASSES 27 | class CTC(object): 28 | """Connectionist Temporal Classification 29 | y_hat : T x B x C+1 30 | y : L x B 31 | y_hat_mask : T x B 32 | y_mask : L x B 33 | """ 34 | @staticmethod 35 | def add_blanks(y, blank_symbol, y_mask=None): 36 | """Add blanks to a matrix and updates mask 37 | 38 | Input shape: L x B 39 | Output shape: 2L+1 x B 40 | 41 | """ 42 | # for y 43 | y_extended = y.T.dimshuffle(0, 1, 'x') 44 | blanks = tensor.zeros_like(y_extended) + blank_symbol 45 | concat = tensor.concatenate([y_extended, blanks], axis=2) 46 | res = concat.reshape((concat.shape[0], 47 | concat.shape[1] * concat.shape[2])).T 48 | begining_blanks = tensor.zeros((1, res.shape[1])) + blank_symbol 49 | blanked_y = tensor.concatenate([begining_blanks, res], axis=0) 50 | # for y_mask 51 | if y_mask is not None: 52 | y_mask_extended = y_mask.T.dimshuffle(0, 1, 'x') 53 | concat = tensor.concatenate([y_mask_extended, 54 | y_mask_extended], axis=2) 55 | res = concat.reshape((concat.shape[0], 56 | concat.shape[1] * concat.shape[2])).T 57 | begining_blanks = tensor.ones((1, res.shape[1]), dtype=floatX) 58 | blanked_y_mask = tensor.concatenate([begining_blanks, res], axis=0) 59 | else: 60 | blanked_y_mask = None 61 | return blanked_y, blanked_y_mask 62 | 63 | @staticmethod 64 | def class_batch_to_labeling_batch(y, y_hat, y_hat_mask=None): 65 | y_hat = y_hat * y_hat_mask.dimshuffle(0, 'x', 1) 66 | batch_size = y_hat.shape[2] 67 | res = y_hat[:, y.astype('int32'), tensor.arange(batch_size)] 68 | return res 69 | 70 | @staticmethod 71 | def recurrence_relation(y, y_mask, blank_symbol): 72 | n_y = y.shape[0] 73 | blanks = tensor.zeros((2, y.shape[1])) + blank_symbol 74 | ybb = tensor.concatenate((y, blanks), axis=0).T 75 | sec_diag = (tensor.neq(ybb[:, :-2], ybb[:, 2:]) * 76 | tensor.eq(ybb[:, 1:-1], blank_symbol) * 77 | y_mask.T) 78 | 79 | # r1: LxL 80 | # r2: LxL 81 | # r3: LxLxB 82 | r2 = tensor.eye(n_y, k=1) 83 | r3 = (tensor.eye(n_y, k=2).dimshuffle(0, 1, 'x') * 84 | sec_diag.dimshuffle(1, 'x', 0)) 85 | 86 | return r2, r3 87 | 88 | @classmethod 89 | def path_probabs(cls, y, y_hat, y_mask, y_hat_mask, blank_symbol): 90 | pred_y = cls.class_batch_to_labeling_batch(y, y_hat, y_hat_mask) 91 | 92 | r2, r3 = cls.recurrence_relation(y, y_mask, blank_symbol) 93 | 94 | def step(p_curr, p_prev): 95 | # instead of dot product, we * first 96 | # and then sum oven one dimension. 97 | # objective: T.dot((p_prev)BxL, LxLxB) 98 | # solusion: Lx1xB * LxLxB --> LxLxB --> (sumover)xLxB 99 | dotproduct = (p_prev + tensor.dot(p_prev, r2) + 100 | (p_prev.dimshuffle(1, 'x', 0) * r3).sum(axis=0).T) 101 | return p_curr.T * dotproduct * y_mask.T # B x L 102 | 103 | probabilities, _ = theano.scan( 104 | step, 105 | sequences=[pred_y], 106 | outputs_info=[tensor.eye(y.shape[0])[0] * tensor.ones(y.T.shape)]) 107 | return probabilities, probabilities.shape 108 | 109 | @classmethod 110 | def cost(cls, y, y_hat, y_mask, y_hat_mask, blank_symbol): 111 | y_hat_mask_len = tensor.sum(y_hat_mask, axis=0, dtype='int32') 112 | y_mask_len = tensor.sum(y_mask, axis=0, dtype='int32') 113 | probabilities, sth = cls.path_probabs(y, y_hat, 114 | y_mask, y_hat_mask, 115 | blank_symbol) 116 | batch_size = probabilities.shape[1] 117 | labels_probab = (probabilities[y_hat_mask_len - 1, 118 | tensor.arange(batch_size), 119 | y_mask_len - 1] + 120 | probabilities[y_hat_mask_len - 1, 121 | tensor.arange(batch_size), 122 | y_mask_len - 2]) 123 | avg_cost = tensor.mean(-tensor.log(labels_probab)) 124 | return avg_cost, sth 125 | 126 | @staticmethod 127 | def _epslog(x): 128 | return tensor.cast(tensor.log(tensor.clip(x, 1E-12, 1E12)), 129 | theano.config.floatX) 130 | 131 | @staticmethod 132 | def log_add(a, b): 133 | max_ = tensor.maximum(a, b) 134 | return (max_ + tensor.log1p(tensor.exp(a + b - 2 * max_))) 135 | 136 | @staticmethod 137 | def log_dot_matrix(x, z): 138 | inf = 1E12 139 | log_dot = tensor.dot(x, z) 140 | zeros_to_minus_inf = (z.max(axis=0) - 1) * inf 141 | return log_dot + zeros_to_minus_inf 142 | 143 | @staticmethod 144 | def log_dot_tensor(x, z): 145 | inf = 1E12 146 | log_dot = (x.dimshuffle(1, 'x', 0) * z).sum(axis=0).T 147 | zeros_to_minus_inf = (z.max(axis=0) - 1) * inf 148 | return log_dot + zeros_to_minus_inf.T 149 | 150 | @classmethod 151 | def log_path_probabs(cls, y, y_hat, y_mask, y_hat_mask, blank_symbol): 152 | pred_y = cls.class_batch_to_labeling_batch(y, y_hat, y_hat_mask) 153 | r2, r3 = cls.recurrence_relation(y, y_mask, blank_symbol) 154 | 155 | def step(log_p_curr, log_p_prev): 156 | p1 = log_p_prev 157 | p2 = cls.log_dot_matrix(p1, r2) 158 | p3 = cls.log_dot_tensor(p1, r3) 159 | p123 = cls.log_add(p3, cls.log_add(p1, p2)) 160 | 161 | return (log_p_curr.T + 162 | p123 + 163 | cls._epslog(y_mask.T)) 164 | 165 | log_probabilities, _ = theano.scan( 166 | step, 167 | sequences=[cls._epslog(pred_y)], 168 | outputs_info=[cls._epslog(tensor.eye(y.shape[0])[0] * 169 | tensor.ones(y.T.shape))]) 170 | return log_probabilities 171 | 172 | @classmethod 173 | def log_cost(cls, y, y_hat, y_mask, y_hat_mask, blank_symbol): 174 | y_hat_mask_len = tensor.sum(y_hat_mask, axis=0, dtype='int32') 175 | y_mask_len = tensor.sum(y_mask, axis=0, dtype='int32') 176 | log_probabs = cls.log_path_probabs(y, y_hat, 177 | y_mask, y_hat_mask, 178 | blank_symbol) 179 | batch_size = log_probabs.shape[1] 180 | labels_probab = cls.log_add( 181 | log_probabs[y_hat_mask_len - 1, 182 | tensor.arange(batch_size), 183 | y_mask_len - 1], 184 | log_probabs[y_hat_mask_len - 1, 185 | tensor.arange(batch_size), 186 | y_mask_len - 2]) 187 | avg_cost = tensor.mean(-labels_probab) 188 | return avg_cost 189 | 190 | @classmethod 191 | def apply(cls, y, y_hat, y_mask, y_hat_mask, scale='log_scale'): 192 | y_hat = y_hat.dimshuffle(0, 2, 1) 193 | num_classes = y_hat.shape[1] - 1 194 | blanked_y, blanked_y_mask = cls.add_blanks( 195 | y=y, 196 | blank_symbol=num_classes.astype(floatX), 197 | y_mask=y_mask) 198 | if scale == 'log_scale': 199 | final_cost = cls.log_cost(blanked_y, y_hat, 200 | blanked_y_mask, y_hat_mask, 201 | num_classes) 202 | else: 203 | final_cost, sth = cls.cost(blanked_y, y_hat, 204 | blanked_y_mask, y_hat_mask, 205 | num_classes) 206 | return final_cost 207 | -------------------------------------------------------------------------------- /lab/draw_text.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from gi.repository import Gtk, Gdk, cairo, Pango, PangoCairo 4 | import math 5 | import sys 6 | 7 | 8 | RADIUS = 150 9 | N_WORDS = 10 10 | FONT = "Sans Bold 12" 11 | 12 | 13 | class Squareset(Gtk.DrawingArea): 14 | def __init__ (self, upper=9, text=''): 15 | ## Gtk.Widget.__init__(self) 16 | Gtk.DrawingArea.__init__(self) 17 | self.set_size_request (200, 200) 18 | ## self.show_all() 19 | 20 | def do_draw_cb(self, widget, cr): 21 | # The do_draw_cb is called when the widget is asked to draw itself 22 | # with the 'draw' as opposed to old function 'expose event' 23 | # Remember that this will be called a lot of times, so it's usually 24 | # a good idea to write this code as optimized as it can be, don't 25 | # Create any resources in here. 26 | 27 | cr.translate ( RADIUS, RADIUS) 28 | 29 | layout = PangoCairo.create_layout (cr) 30 | layout.set_text("శ్రీమదాంధ్రమహాభారతము", -1) 31 | desc = Pango.font_description_from_string (FONT) 32 | layout.set_font_description( desc) 33 | 34 | rangec = range(0, N_WORDS) 35 | for i in rangec: 36 | width, height = 0,0 37 | angle = (360. * i) / N_WORDS; 38 | 39 | cr.save () 40 | 41 | red = (1 + math.cos ((angle - 60) * math.pi / 180.)) / 2 42 | cr.set_source_rgb ( red, 0, 1.0 - red) 43 | cr.rotate ( angle * math.pi / 180.) 44 | #/* Inform Pango to re-layout the text with the new transformation */ 45 | PangoCairo.update_layout (cr, layout) 46 | width, height = layout.get_size() 47 | cr.move_to ( - (float(width) / 1024.) / 2, - RADIUS) 48 | PangoCairo.show_layout (cr, layout) 49 | cr.restore() 50 | 51 | 52 | def destroy(window): 53 | Gtk.main_quit() 54 | 55 | 56 | def main(): 57 | window = Gtk.Window() 58 | window.set_title ("Hello World") 59 | 60 | app = Squareset() 61 | 62 | window.add(app) 63 | 64 | app.connect('draw', app.do_draw_cb) 65 | window.connect_after('destroy', destroy) 66 | window.show_all() 67 | Gtk.main() 68 | 69 | 70 | if __name__ == "__main__": 71 | sys.exit(main()) -------------------------------------------------------------------------------- /lab/indic_scribe_python2.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | from __future__ import print_function 4 | import cairo 5 | import pango 6 | import pangocairo 7 | import numpy as np 8 | 9 | styles = '', ' Italic', ' Bold', ' Bold Italic' 10 | 11 | 12 | def scribe(text, fontname, ten=10, style=0, 13 | sz=48, spc=1, movex=10, movey=0, twist=0): 14 | lines = text.split('\n') 15 | n_lines = len(lines) 16 | n_letters = max(len(line) for line in lines) 17 | 18 | size_x = 3 * ten * n_letters + 5 * ten 19 | size_y = 5 * ten * n_lines + 5 * ten 20 | 21 | # print("Lines: {} Letters:{} Size:{}x{}".format( 22 | # n_lines, n_letters, size_x, size_y)) 23 | 24 | data = np.zeros((size_y, size_x, 4), dtype=np.uint8) 25 | surf = cairo.ImageSurface.create_for_data(data, cairo.FORMAT_ARGB32, 26 | size_x, size_y) 27 | cr = cairo.Context(surf) 28 | pc = pangocairo.CairoContext(cr) 29 | pc.set_antialias(cairo.ANTIALIAS_SUBPIXEL) 30 | 31 | layout = pc.create_layout() 32 | layout.set_text(text) 33 | 34 | style = styles[style] 35 | font_style = "{} {} {}".format(fontname, style, (sz * ten)//10) 36 | layout.set_font_description(pango.FontDescription(font_style)) 37 | layout.set_spacing(spc * 32) 38 | 39 | cr.rectangle(0, 0, size_x, size_y) 40 | cr.set_source_rgb(1, 1, 1) 41 | cr.fill() 42 | cr.translate(ten, 0) 43 | cr.set_source_rgb(0, 0, 0) 44 | 45 | pc.update_layout(layout) 46 | pc.show_layout(layout) 47 | 48 | return data[:, :, 0] < 128 49 | -------------------------------------------------------------------------------- /lab/minibatch_ocr.py: -------------------------------------------------------------------------------- 1 | """ 2 | bitmap utils and much of the ctc code modified 3 | From Shawn Tan, Rakesh and Mohammad Pezeshki 4 | """ 5 | # Author: Kyle Kastner 6 | # License: BSD 3-clause 7 | from theano import tensor 8 | from scipy import linalg 9 | import theano 10 | import numpy as np 11 | import matplotlib.pyplot as plt 12 | 13 | eps = 1E-12 14 | 15 | characters = np.array([ 16 | 0x0, 17 | 0x808080800080000, 18 | 0x2828000000000000, 19 | 0x287C287C280000, 20 | 0x81E281C0A3C0800, 21 | 0x6094681629060000, 22 | 0x1C20201926190000, 23 | 0x808000000000000, 24 | 0x810202010080000, 25 | 0x1008040408100000, 26 | 0x2A1C3E1C2A000000, 27 | 0x8083E08080000, 28 | 0x81000, 29 | 0x3C00000000, 30 | 0x80000, 31 | 0x204081020400000, 32 | 0x1824424224180000, 33 | 0x8180808081C0000, 34 | 0x3C420418207E0000, 35 | 0x3C420418423C0000, 36 | 0x81828487C080000, 37 | 0x7E407C02423C0000, 38 | 0x3C407C42423C0000, 39 | 0x7E04081020400000, 40 | 0x3C423C42423C0000, 41 | 0x3C42423E023C0000, 42 | 0x80000080000, 43 | 0x80000081000, 44 | 0x6186018060000, 45 | 0x7E007E000000, 46 | 0x60180618600000, 47 | 0x3844041800100000, 48 | 0x3C449C945C201C, 49 | 0x1818243C42420000, 50 | 0x7844784444780000, 51 | 0x3844808044380000, 52 | 0x7844444444780000, 53 | 0x7C407840407C0000, 54 | 0x7C40784040400000, 55 | 0x3844809C44380000, 56 | 0x42427E4242420000, 57 | 0x3E080808083E0000, 58 | 0x1C04040444380000, 59 | 0x4448507048440000, 60 | 0x40404040407E0000, 61 | 0x4163554941410000, 62 | 0x4262524A46420000, 63 | 0x1C222222221C0000, 64 | 0x7844784040400000, 65 | 0x1C222222221C0200, 66 | 0x7844785048440000, 67 | 0x1C22100C221C0000, 68 | 0x7F08080808080000, 69 | 0x42424242423C0000, 70 | 0x8142422424180000, 71 | 0x4141495563410000, 72 | 0x4224181824420000, 73 | 0x4122140808080000, 74 | 0x7E040810207E0000, 75 | 0x3820202020380000, 76 | 0x4020100804020000, 77 | 0x3808080808380000, 78 | 0x1028000000000000, 79 | 0x7E0000, 80 | 0x1008000000000000, 81 | 0x3C023E463A0000, 82 | 0x40407C42625C0000, 83 | 0x1C20201C0000, 84 | 0x2023E42463A0000, 85 | 0x3C427E403C0000, 86 | 0x18103810100000, 87 | 0x344C44340438, 88 | 0x2020382424240000, 89 | 0x800080808080000, 90 | 0x800180808080870, 91 | 0x20202428302C0000, 92 | 0x1010101010180000, 93 | 0x665A42420000, 94 | 0x2E3222220000, 95 | 0x3C42423C0000, 96 | 0x5C62427C4040, 97 | 0x3A46423E0202, 98 | 0x2C3220200000, 99 | 0x1C201804380000, 100 | 0x103C1010180000, 101 | 0x2222261A0000, 102 | 0x424224180000, 103 | 0x81815A660000, 104 | 0x422418660000, 105 | 0x422214081060, 106 | 0x3C08103C0000, 107 | 0x1C103030101C0000, 108 | 0x808080808080800, 109 | 0x38080C0C08380000, 110 | 0x324C000000, 111 | ], dtype=np.uint64) 112 | 113 | bitmap = np.unpackbits(characters.view(np.uint8)).reshape(characters.shape[0], 114 | 8, 8) 115 | bitmap = bitmap[:, ::-1, :] 116 | 117 | chars = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~" 118 | mapping = {c: i for i, c in enumerate(chars)} 119 | 120 | 121 | def string_to_image(string): 122 | return np.hstack(np.array([bitmap[mapping[c]] for c in string])).T[:, ::-1] 123 | 124 | 125 | def string_to_index(string): 126 | return np.asarray([mapping[c] for c in string]) 127 | 128 | 129 | def recurrence_relation(y, y_mask): 130 | # with blank symbol of -1 this falls back to the recurrence that fails 131 | # with repeating symbols! 132 | blank_symbol = -1 133 | n_y = y.shape[0] 134 | blanks = tensor.zeros((2, y.shape[1])) + blank_symbol 135 | ybb = tensor.concatenate((y, blanks), axis=0).T 136 | sec_diag = (tensor.neq(ybb[:, :-2], ybb[:, 2:]) * 137 | tensor.eq(ybb[:, 1:-1], blank_symbol) * 138 | y_mask.T) 139 | 140 | # r1: LxL 141 | # r2: LxL 142 | # r3: LxLxB 143 | r2 = tensor.eye(n_y, k=1) 144 | r3 = (tensor.eye(n_y, k=2).dimshuffle(0, 1, 'x') * 145 | sec_diag.dimshuffle(1, 'x', 0)) 146 | return r2, r3 147 | 148 | 149 | def _epslog(x): 150 | return tensor.cast(tensor.log(tensor.clip(x, 1E-12, 1E12)), 151 | theano.config.floatX) 152 | 153 | 154 | def _log_add(a, b): 155 | max_ = tensor.maximum(a, b) 156 | return (max_ + tensor.log1p(tensor.exp(a + b - 2 * max_))) 157 | 158 | 159 | def _log_dot_matrix(x, z): 160 | inf = 1E12 161 | log_dot = tensor.dot(x, z) 162 | zeros_to_minus_inf = (z.max(axis=0) - 1) * inf 163 | return log_dot + zeros_to_minus_inf 164 | 165 | 166 | def _log_dot_tensor(x, z): 167 | inf = 1E12 168 | log_dot = (x.dimshuffle(1, 'x', 0) * z).sum(axis=0).T 169 | zeros_to_minus_inf = (z.max(axis=0) - 1) * inf 170 | return log_dot + zeros_to_minus_inf.T 171 | 172 | 173 | def class_batch_to_labeling_batch(y, y_hat, y_hat_mask): 174 | # ?? 175 | y_hat = y_hat.dimshuffle(0, 2, 1) 176 | y_hat = y_hat * y_hat_mask.dimshuffle(0, 'x', 1) 177 | batch_size = y_hat.shape[2] 178 | res = y_hat[:, y.astype('int32'), tensor.arange(batch_size)] 179 | return res 180 | 181 | 182 | def log_path_probs(y, y_mask, y_hat, y_hat_mask): 183 | pred_y = class_batch_to_labeling_batch(y, y_hat, y_hat_mask) 184 | r2, r3 = recurrence_relation(y, y_mask) 185 | 186 | def step(log_p_curr, log_p_prev): 187 | p1 = log_p_prev 188 | p2 = _log_dot_matrix(p1, r2) 189 | p3 = _log_dot_tensor(p1, r3) 190 | p123 = _log_add(p3, _log_add(p1, p2)) 191 | 192 | return (log_p_curr.T + 193 | p123 + 194 | _epslog(y_mask.T)) 195 | 196 | log_probabilities, _ = theano.scan( 197 | step, 198 | sequences=[_epslog(pred_y)], 199 | outputs_info=[_epslog(tensor.eye(y.shape[0])[0] * 200 | tensor.ones(y.T.shape))]) 201 | return log_probabilities 202 | 203 | 204 | def log_ctc_cost(y, y_mask, y_hat, y_hat_mask): 205 | y_hat_mask_len = tensor.sum(y_hat_mask, axis=0, dtype='int32') 206 | y_mask_len = tensor.sum(y_mask, axis=0, dtype='int32') 207 | log_probs = log_path_probs(y, y_mask, y_hat, y_hat_mask) 208 | batch_size = log_probs.shape[1] 209 | labels_prob = _log_add( 210 | log_probs[y_hat_mask_len - 1, tensor.arange(batch_size), 211 | y_mask_len - 1], 212 | log_probs[y_hat_mask_len - 1, tensor.arange(batch_size), 213 | y_mask_len - 2]) 214 | avg_cost = tensor.mean(-labels_prob) 215 | return avg_cost 216 | 217 | 218 | def as_shared(arr, name=None): 219 | if type(arr) in [float, int]: 220 | if name is not None: 221 | return theano.shared(np.cast[theano.config.floatX](arr)) 222 | else: 223 | return theano.shared(np.cast[theano.config.floatX](arr), name=name) 224 | if name is not None: 225 | return theano.shared(value=arr, borrow=True) 226 | else: 227 | return theano.shared(value=arr, name=name, borrow=True) 228 | 229 | 230 | def np_zeros(shape): 231 | """ Builds a numpy variable filled with zeros """ 232 | return np.zeros(shape).astype(theano.config.floatX) 233 | 234 | 235 | def np_ones(shape): 236 | """ Builds a numpy variable filled with zeros """ 237 | return np.ones(shape).astype(theano.config.floatX) 238 | 239 | 240 | def np_rand(shape, random_state): 241 | # Make sure bounds aren't the same 242 | return random_state.uniform(low=-0.08, high=0.08, size=shape).astype( 243 | theano.config.floatX) 244 | 245 | 246 | def np_randn(shape, random_state): 247 | """ Builds a numpy variable filled with random normal values """ 248 | return (0.01 * random_state.randn(*shape)).astype(theano.config.floatX) 249 | 250 | 251 | def np_tanh_fan(shape, random_state): 252 | # The . after the 6 is critical! shape has dtype int... 253 | bound = np.sqrt(6. / np.sum(shape)) 254 | return random_state.uniform(low=-bound, high=bound, 255 | size=shape).astype(theano.config.floatX) 256 | 257 | 258 | def np_sigmoid_fan(shape, random_state): 259 | return 4 * np_tanh_fan(shape, random_state) 260 | 261 | 262 | def np_ortho(shape, random_state): 263 | """ Builds a theano variable filled with orthonormal random values """ 264 | g = random_state.randn(*shape) 265 | o_g = linalg.svd(g)[0] 266 | return o_g.astype(theano.config.floatX) 267 | 268 | 269 | def build_tanh_rnn(hidden_input, mask_input, W_hidden_hidden, initial_hidden): 270 | def step(x_t, m_t, h_tm1, U): 271 | h_ti = tensor.tanh(x_t + tensor.dot(h_tm1, U)) 272 | h_t = m_t[:, None] * h_ti + (1 - m_t)[:, None] * h_tm1 273 | return h_t 274 | 275 | h, updates = theano.scan(step, 276 | sequences=[hidden_input, mask_input], 277 | outputs_info=[initial_hidden], 278 | non_sequences=[W_hidden_hidden]) 279 | return h 280 | 281 | 282 | def build_model(X, X_mask, minibatch_size, input_size, hidden_size, 283 | output_size): 284 | random_state = np.random.RandomState(1999) 285 | W_input_hidden = as_shared(np_tanh_fan((input_size, hidden_size), 286 | random_state)) 287 | W_hidden_hidden = as_shared(np_ortho((hidden_size, hidden_size), 288 | random_state)) 289 | W_hidden_output = as_shared(np_tanh_fan((hidden_size, output_size), 290 | random_state)) 291 | initial_hidden = as_shared(np_zeros((minibatch_size, hidden_size))) 292 | b_hidden = as_shared(np_zeros((hidden_size,))) 293 | b_output = as_shared(np_zeros((output_size,))) 294 | hidden = build_tanh_rnn(tensor.dot(X, W_input_hidden) + b_hidden, X_mask, 295 | W_hidden_hidden, initial_hidden) 296 | hidden_proj = tensor.dot(hidden, W_hidden_output) + b_output 297 | hidden_proj_shapes = hidden_proj.shape 298 | hidden_proj = hidden_proj.reshape(( 299 | hidden_proj_shapes[0] * hidden_proj_shapes[1], hidden_proj_shapes[2])) 300 | predict = tensor.nnet.softmax(hidden_proj).reshape(hidden_proj_shapes) 301 | params = [W_input_hidden, W_hidden_hidden, W_hidden_output, initial_hidden, 302 | b_output] 303 | return X, predict, params 304 | 305 | 306 | def theano_label_seq(y, y_mask): 307 | blank_symbol = -1 308 | # for y 309 | y_extended = y.T.dimshuffle(0, 1, 'x') 310 | blanks = tensor.zeros_like(y_extended) + blank_symbol 311 | concat = tensor.concatenate([y_extended, blanks], axis=2) 312 | res = concat.reshape((concat.shape[0], 313 | concat.shape[1] * concat.shape[2])).T 314 | beginning_blanks = tensor.zeros((1, res.shape[1])) + blank_symbol 315 | blanked_y = tensor.concatenate([beginning_blanks, res], axis=0) 316 | 317 | y_mask_extended = y_mask.T.dimshuffle(0, 1, 'x') 318 | concat = tensor.concatenate([y_mask_extended, 319 | y_mask_extended], axis=2) 320 | res = concat.reshape((concat.shape[0], 321 | concat.shape[1] * concat.shape[2])).T 322 | beginning_blanks = tensor.ones((1, res.shape[1]), 323 | dtype=theano.config.floatX) 324 | blanked_y_mask = tensor.concatenate([beginning_blanks, res], axis=0) 325 | return blanked_y, blanked_y_mask 326 | 327 | 328 | class adadelta(object): 329 | """ 330 | An adaptive learning rate optimizer 331 | 332 | For more information, see: 333 | Matthew D. Zeiler, "ADADELTA: An Adaptive Learning Rate Method" 334 | arXiv:1212.5701. 335 | """ 336 | def __init__(self, params, running_grad_decay=0.95, running_up_decay=0.95, 337 | eps=1E-6): 338 | self.running_grad_decay = running_grad_decay 339 | self.running_up_decay = running_up_decay 340 | self.eps = eps 341 | self.running_up2_ = [theano.shared(np.zeros_like(p.get_value())) 342 | for p in params] 343 | self.running_grads2_ = [theano.shared(np.zeros_like(p.get_value())) 344 | for p in params] 345 | self.previous_grads_ = [theano.shared(np.zeros_like(p.get_value())) 346 | for p in params] 347 | 348 | def updates(self, params, grads): 349 | running_grad_decay = self.running_grad_decay 350 | running_up_decay = self.running_up_decay 351 | eps = self.eps 352 | updates = [] 353 | for n, (param, grad) in enumerate(zip(params, grads)): 354 | running_grad2 = self.running_grads2_[n] 355 | running_up2 = self.running_up2_[n] 356 | previous_grad = self.previous_grads_[n] 357 | rg2up = running_grad_decay * running_grad2 + ( 358 | 1. - running_grad_decay) * (grad ** 2) 359 | updir = -tensor.sqrt(running_up2 + eps) / tensor.sqrt( 360 | running_grad2 + eps) * previous_grad 361 | ru2up = running_up_decay * running_up2 + ( 362 | 1. - running_up_decay) * (updir ** 2) 363 | updates.append((previous_grad, grad)) 364 | updates.append((running_grad2, rg2up)) 365 | updates.append((running_up2, ru2up)) 366 | updates.append((param, param + updir)) 367 | return updates 368 | 369 | 370 | def ctc_prediction_to_string(y_pred): 371 | indices = y_pred.argmax(axis=1) 372 | # remove blanks 373 | indices = indices[indices != len(chars)] 374 | # remove repeats 375 | not_same = np.where((indices[1:] != indices[:-1]))[0] 376 | last_char = "" 377 | if len(not_same) > 0: 378 | last_char = chars[indices[-1]] 379 | indices = indices[not_same] 380 | s = "".join([chars[i] for i in indices]) 381 | return s + last_char 382 | 383 | 384 | def prediction_to_string(y_pred): 385 | indices = y_pred.argmax(axis=1) 386 | # remove blanks 387 | indices = indices[indices != len(chars)] 388 | s = "".join([chars[i] for i in indices]) 389 | return s 390 | 391 | 392 | def make_minibatch_from_strings(strings): 393 | X_shapes = [string_to_image(s).shape for s in strings] 394 | y_shapes = [string_to_index(s).shape for s in strings] 395 | max_X_len = max([sh[0] for sh in X_shapes]) 396 | max_y_len = max([sh[0] for sh in y_shapes]) 397 | minibatch_size = len(strings) 398 | # assume all feature dimensions are equal! 399 | X_mb = np.zeros((max_X_len, minibatch_size, X_shapes[-1][1])).astype( 400 | theano.config.floatX) 401 | X_mask = np.zeros((max_X_len, len(strings))).astype(theano.config.floatX) 402 | y_mb = np.zeros((max_y_len, minibatch_size)).astype("int32") 403 | y_mask = np.ones_like(y_mb).astype(theano.config.floatX) 404 | for n, s in enumerate(strings): 405 | X = string_to_image(s) 406 | y = string_to_index(s) 407 | X_mb[:X.shape[0], n, :] = X 408 | X_mask[:X.shape[0], n] = 1. 409 | y_mb[:y.shape[0], n] = y 410 | y_mask[:y.shape[0], n] = 1. 411 | return X_mb, X_mask, y_mb, y_mask 412 | 413 | 414 | if __name__ == "__main__": 415 | true_strings = ["Hello", "World"] 416 | minibatch_size = len(true_strings) 417 | X, X_mask, y, y_mask = make_minibatch_from_strings(true_strings) 418 | 419 | X_sym = tensor.tensor3('X') 420 | X_mask_sym = tensor.matrix('X_mask') 421 | y_sym = tensor.imatrix('Y_s') 422 | y_mask_sym = tensor.matrix('Y_s_mask') 423 | X_sym.tag.test_value = X 424 | X_mask_sym.tag.test_value = X_mask 425 | y_sym.tag.test_value = y 426 | y_mask_sym.tag.test_value = y_mask 427 | 428 | X_res, predict, params = build_model(X_sym, X_mask_sym, minibatch_size, 429 | X.shape[-1], 256, len(chars) + 1) 430 | y_ctc_sym, y_ctc_mask_sym = theano_label_seq(y_sym, y_mask_sym) 431 | cost = log_ctc_cost(y_ctc_sym, y_ctc_mask_sym, predict, X_mask_sym) 432 | 433 | grads = tensor.grad(cost, wrt=params) 434 | opt = adadelta(params) 435 | train = theano.function(inputs=[X_sym, X_mask_sym, y_sym, y_mask_sym], 436 | outputs=cost, 437 | updates=opt.updates(params, grads)) 438 | pred = theano.function(inputs=[X_sym, X_mask_sym], outputs=predict) 439 | 440 | for i in range(1000): 441 | train_cost = train(X, X_mask, y, y_mask) 442 | if i % 100 == 0: 443 | print("Iteration %i:" % i) 444 | print(train_cost) 445 | p = pred(X, X_mask) 446 | for n in range(p.shape[1]): 447 | print(prediction_to_string(p[:, n, :])) 448 | print(ctc_prediction_to_string(p[:, n, :])) 449 | p = pred(X, X_mask) 450 | f, axarr = plt.subplots(p.shape[1]) 451 | print("Final predictions:") 452 | predicted_strings = [] 453 | for n in range(p.shape[1]): 454 | p_n = p[:, n, :] 455 | s = ctc_prediction_to_string(p_n) 456 | predicted_strings.append(s) 457 | X_n = X[:, n, :] 458 | axarr[n].matshow(X_n.T[::-1], cmap="gray") 459 | axarr[n].set_xticks([]) 460 | axarr[n].set_yticks([]) 461 | plt.suptitle(" ".join(predicted_strings) + " : " + " ".join(true_strings)) 462 | plt.tight_layout() 463 | plt.show() 464 | -------------------------------------------------------------------------------- /line_seperate.py: -------------------------------------------------------------------------------- 1 | # /usr/bin/env python3 2 | #*-* coding: utf-8 *-* 3 | ''' 4 | Detects lines in a binary text image. 5 | ''' 6 | import numpy as np 7 | from scipy import ndimage as nd 8 | from PIL import Image as im 9 | from PIL import ImageDraw as id 10 | from scipy.ndimage import interpolation as inter 11 | 12 | if False: 13 | log = print 14 | else: 15 | log = lambda *_, **__: None 16 | 17 | 18 | class Page(): 19 | def __init__(self, path): 20 | self.path = path 21 | self.orig = im.open(path) 22 | self.wd, self.ht = self.orig.size 23 | self.imgarr = np.asarray(self.orig.getdata()).reshape((self.ht, self.wd)) 24 | self.imgarr //= 255 25 | self.imgarr = 1 - self.imgarr 26 | 27 | self.angle = None 28 | self.fft, self.best_harmonic, self.closed = [None] * 3 29 | self.hist, self.gauss_hist, self.d_gauss_hist = [None] * 3 30 | self.base_lines, self.top_lines, self.line_sep = [None] * 3 31 | self.num_lines = None 32 | 33 | def process(self): 34 | self.filter_noise() 35 | self.skew_correct() 36 | self.calc_hist() 37 | self.find_baselines() 38 | self.separate_lines() 39 | 40 | def filter_noise(self, ): 41 | self.imgarr = nd.median_filter(self.imgarr, size=3) 42 | 43 | def skew_correct(self, ): 44 | best_score = -1 45 | for a in np.linspace(-2, 2, 21): 46 | data = inter.rotate(self.imgarr, a, reshape=0, order=0) 47 | hist = np.sum(data, axis=1) 48 | score = np.sum((hist[1:] - hist[:-1]) ** 2) 49 | if score > best_score: 50 | self.angle = float(a) 51 | self.imgarr = data 52 | best_score = score 53 | 54 | print("Angle: ", self.angle) 55 | self.ht, self.wd = self.imgarr.shape 56 | self.img = im.fromarray(255 * (1 - self.imgarr).astype("uint8")).convert("RGB") 57 | 58 | def calc_hist(self, ): 59 | hist_ = np.sum(self.imgarr, axis=1).astype('float') 60 | hist_mean = np.mean(hist_) 61 | self.fft = abs(np.fft.rfft(hist_ - hist_mean)) 62 | max_harm = int(np.argmax(self.fft)) 63 | self.best_harmonic = self.ht // (1 + max_harm) 64 | assert max_harm > 0 65 | 66 | self.closed = nd.binary_closing(self.imgarr, structure=np.ones((1, self.best_harmonic // 4))) 67 | self.hist = np.sum(self.closed, axis=1).astype("float") 68 | self.gauss_hist = nd.filters.gaussian_filter1d( 69 | self.hist, 70 | self.best_harmonic / 16, mode='constant', 71 | cval=0, 72 | truncate=2.0) 73 | self.d_gauss_hist = nd.filters.convolve(self.gauss_hist, [-1, 0, 1]) 74 | 75 | def find_baselines(self, ): 76 | d_hist = self.d_gauss_hist 77 | gmaxval = np.max(d_hist) 78 | maxloc = np.argmax(d_hist) 79 | peakthresh = gmaxval / 10.0 80 | zerothresh = gmaxval / 50.0 81 | inpeak = False 82 | min_dist_in_peak = self.best_harmonic / 2.0 83 | self.base_lines = [] 84 | log("Max Hist: {:.2f} Peakthresh: {:.2f} Zerothresh: {:.2f} Min Dist in Peak: {:.2f}" 85 | "".format(gmaxval, peakthresh, zerothresh, min_dist_in_peak)) 86 | 87 | for irow, val in enumerate(d_hist): 88 | if not inpeak: 89 | if val > peakthresh: 90 | inpeak = True 91 | maxval = val 92 | maxloc = irow 93 | mintosearch = irow + min_dist_in_peak 94 | log('\ntransition to in-peak: mintosearch : ', mintosearch, end='') 95 | # accept no zeros between i and i+mintosearch 96 | 97 | else: # in peak, look for max 98 | if val > maxval: 99 | maxval = val 100 | maxloc = irow 101 | mintosearch = irow + min_dist_in_peak 102 | log('\nMoved mintosearch to', mintosearch, end='') 103 | elif irow > mintosearch and val <= zerothresh: 104 | # leave peak and save the last baseline found 105 | inpeak = False 106 | log('\nFound baseline #', maxloc, end='') 107 | self.base_lines.append(maxloc) 108 | 109 | log(' @{}'.format(irow), end='') 110 | 111 | if inpeak: 112 | self.base_lines.append(maxloc) 113 | log('\nFound baseline #', maxloc, end='') 114 | 115 | self.num_lines = len(self.base_lines) 116 | 117 | def separate_lines(self, ): 118 | self.top_lines = [] 119 | self.line_sep = [np.where(self.gauss_hist[0:self.base_lines[0]] == 0)[0][-1]] 120 | log(self.base_lines) 121 | 122 | for ibase, base in enumerate(self.base_lines): 123 | # Find top lines 124 | frm = 0 if ibase == 0 else self.line_sep[ibase] 125 | log(" Searching for top line in range : ", frm, base) 126 | top_at = np.argmin(self.d_gauss_hist[frm:base]) 127 | self.top_lines.append(frm + top_at) 128 | log(" Top at: ", top_at, frm + top_at) 129 | 130 | # Find line separation 131 | to = self.base_lines[ibase + 1] if ibase + 1 < self.num_lines else self.ht 132 | sep_at = np.argmin(self.gauss_hist[base + 1:to]) 133 | self.line_sep.append(base + 1 + sep_at) 134 | log(" Line Sep at ", sep_at, base + 1 + sep_at) 135 | 136 | def get_line(self, iline): 137 | return self.imgarr[self.line_sep[iline]:self.line_sep[iline + 1]] 138 | 139 | def get_info(self): 140 | ret = ( 141 | "\nImage: {} " 142 | "\nHeight, Width: {}, {}" 143 | "\nShapes: Image Array:{} closed:{}" 144 | "\nRotated by angle: {:.2f}" 145 | "\nBest Harmonic: {}" 146 | "\nLengths: hist:{} gauss_hist:{} d_gauss_hist:{} FFT:{}" 147 | "\nNumber of lines:{} " 148 | "".format( 149 | self.path, 150 | self.ht, self.wd, 151 | self.imgarr.shape, self.closed.shape, 152 | self.angle, self.best_harmonic, 153 | len(self.hist), len(self.gauss_hist), len(self.d_gauss_hist), 154 | len(self.fft), 155 | self.num_lines)) 156 | 157 | ret += "\nLine From Top Base Till" 158 | for line in range(self.num_lines): 159 | ret += "\n{:3d}: {:4d} {:4d} {:4d} {:4d}".format(line, 160 | self.line_sep[line], self.top_lines[line], 161 | self.base_lines[line], self.line_sep[line+1]) 162 | 163 | return ret 164 | 165 | def get_hists_info(self): 166 | return "Line Hist GHist DGHist" + \ 167 | "\n".join( 168 | ["{:4d} {:7.2f} {:7.2f} {:7.2f}".format(l, i, j, k) 169 | for l, i, j, k in zip( 170 | range(self.ht), self.hist, self.gauss_hist, self.d_gauss_hist)]) 171 | 172 | def get_image_with_hist(self, width): 173 | hist = width * self.gauss_hist / np.max(self.gauss_hist) 174 | appendage = np.full((self.ht, width), 255, dtype='uint8') 175 | for row, count in enumerate(hist.astype('int')): 176 | appendage[row, :count] = 0 177 | 178 | appendage = im.fromarray(appendage) 179 | appended_img = im.new('RGB', (self.wd + width, self.ht)) 180 | appended_img.paste(self.img, (0, 0)) 181 | appended_img.paste(appendage, (self.wd, 0)) 182 | return appended_img 183 | 184 | def draw_lines(self, target): 185 | width = target.size[0] 186 | draw = id.Draw(target) 187 | 188 | def draw_lines(locations, col): 189 | for loc in locations: 190 | draw.line((0, loc, width, loc), fill=col, width=1) 191 | 192 | draw_lines(self.top_lines, (200, 200, 0)) 193 | draw_lines(self.base_lines, (0, 255, 0)) 194 | draw_lines(self.line_sep, (0, 0, 255)) 195 | 196 | return target 197 | 198 | def get_image_with_hist_and_lines(self, width): 199 | appended_img = self.get_image_with_hist(width) 200 | return self.draw_lines(appended_img) 201 | 202 | def save_image_with_hist_and_lines(self, width): 203 | target_name = self.path[:-4] + ".png" 204 | appended_img = self.get_image_with_hist(width) 205 | self.draw_lines(appended_img).save(target_name) 206 | print("Saving:", target_name) 207 | 208 | 209 | ################################ UNIT TEST ################################ 210 | 211 | def main(image_name): 212 | page = Page(image_name) 213 | page.process() 214 | print(page.get_info()) 215 | page.save_image_with_hist_and_lines(100) 216 | 217 | 218 | if __name__ == '__main__': 219 | import sys 220 | main(sys.argv[1]) -------------------------------------------------------------------------------- /notebooks/array_vs_np_vs_list.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import array as ar\n", 12 | "import numpy as np\n", 13 | "from bisect import bisect\n", 14 | "from itertools import accumulate\n", 15 | "from random import random, randrange" 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 2, 21 | "metadata": { 22 | "collapsed": false 23 | }, 24 | "outputs": [], 25 | "source": [ 26 | "N = 1000\n", 27 | "tpcounts = tuple(int(5*random()) for i in range(N))\n", 28 | "tpcuml = tuple(accumulate(tpcounts))\n", 29 | "tot = tpcuml[-1]\n", 30 | "\n", 31 | "arcounts = ar.array('l', tpcounts)\n", 32 | "arcuml = ar.array('l', accumulate(tpcounts))\n", 33 | "arcounts = ar.array('l', tpcounts)\n", 34 | "arcuml = ar.array('l', accumulate(tpcounts))\n", 35 | "npcounts = np.array(tpcounts, dtype=np.uint32)\n", 36 | "npcuml = np.cumsum(npcounts, dtype=np.uint32)" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 3, 42 | "metadata": { 43 | "collapsed": true 44 | }, 45 | "outputs": [], 46 | "source": [ 47 | "seek = list(randrange(tot) for i in range(N))\n", 48 | "npseek = np.array(seek, dtype=np.uint32)" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 4, 54 | "metadata": { 55 | "collapsed": false 56 | }, 57 | "outputs": [ 58 | { 59 | "data": { 60 | "text/plain": [ 61 | "(int, int, int, int, numpy.uint32, numpy.uint32, int)" 62 | ] 63 | }, 64 | "execution_count": 4, 65 | "metadata": {}, 66 | "output_type": "execute_result" 67 | } 68 | ], 69 | "source": [ 70 | "type(tpcounts[0]), type(tpcuml[0]), type(arcounts[0]), type(arcuml[0]), type(npcounts[0]), type(npcuml[0]), type(seek[0])" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 5, 76 | "metadata": { 77 | "collapsed": false 78 | }, 79 | "outputs": [ 80 | { 81 | "name": "stdout", 82 | "output_type": "stream", 83 | "text": [ 84 | "1000 loops, best of 3: 316 µs per loop\n", 85 | "1000 loops, best of 3: 393 µs per loop\n", 86 | "1000 loops, best of 3: 797 µs per loop\n", 87 | "1000 loops, best of 3: 1.16 ms per loop\n", 88 | "100 loops, best of 3: 1.93 ms per loop\n", 89 | "100 loops, best of 3: 16.2 ms per loop\n" 90 | ] 91 | } 92 | ], 93 | "source": [ 94 | "%timeit for i in seek: bisect(tpcuml, i)\n", 95 | "%timeit for i in seek: bisect(arcuml, i)\n", 96 | "%timeit for i in npseek: bisect(npcuml, i) # Good enough?\n", 97 | "%timeit for i in npseek: np.searchsorted(npcuml, i, \"right\") \n", 98 | "%timeit for i in seek: np.searchsorted(npcuml, i, \"right\")\n", 99 | "%timeit -n 10 for i in seek: bisect(npcuml, i) # Worst" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": 6, 105 | "metadata": { 106 | "collapsed": false 107 | }, 108 | "outputs": [], 109 | "source": [ 110 | "arloc = [bisect(arcuml, i) for i in seek ]\n", 111 | "tploc = [bisect(tpcuml, i) for i in seek]\n", 112 | "nploc = [bisect(npcuml, i) for i in npseek]" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": 7, 118 | "metadata": { 119 | "collapsed": false 120 | }, 121 | "outputs": [ 122 | { 123 | "name": "stdout", 124 | "output_type": "stream", 125 | "text": [ 126 | "1 loop, best of 3: 72.7 ms per loop\n" 127 | ] 128 | } 129 | ], 130 | "source": [ 131 | "%%timeit -n 1\n", 132 | "for loc in arloc: \n", 133 | " val = arcuml[loc]\n", 134 | " if loc:\n", 135 | " val -= arcuml[loc-1]\n", 136 | " for j in range(loc, N):\n", 137 | " arcuml[j] -= val//2" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": 8, 143 | "metadata": { 144 | "collapsed": true 145 | }, 146 | "outputs": [], 147 | "source": [ 148 | "tpcuml = list(tpcuml)" 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": 9, 154 | "metadata": { 155 | "collapsed": false 156 | }, 157 | "outputs": [ 158 | { 159 | "name": "stdout", 160 | "output_type": "stream", 161 | "text": [ 162 | "1 loop, best of 3: 53.8 ms per loop\n" 163 | ] 164 | } 165 | ], 166 | "source": [ 167 | "%%timeit -n 1\n", 168 | "for loc in tploc: \n", 169 | " val = tpcuml[loc]\n", 170 | " if loc:\n", 171 | " val -= tpcuml[loc-1]\n", 172 | " for j in range(loc, N):\n", 173 | " tpcuml[j] -= val//2" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": 10, 179 | "metadata": { 180 | "collapsed": false 181 | }, 182 | "outputs": [ 183 | { 184 | "name": "stdout", 185 | "output_type": "stream", 186 | "text": [ 187 | "1 loop, best of 3: 2.81 ms per loop\n" 188 | ] 189 | } 190 | ], 191 | "source": [ 192 | "%%timeit -n 1\n", 193 | "for loc in tploc: \n", 194 | " val = npcuml[loc]\n", 195 | " if loc:\n", 196 | " val -= npcuml[loc-1]\n", 197 | " npcuml[loc:] -= val" 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": null, 203 | "metadata": { 204 | "collapsed": true 205 | }, 206 | "outputs": [], 207 | "source": [] 208 | } 209 | ], 210 | "metadata": { 211 | "kernelspec": { 212 | "display_name": "Python 3", 213 | "language": "python", 214 | "name": "python3" 215 | }, 216 | "language_info": { 217 | "codemirror_mode": { 218 | "name": "ipython", 219 | "version": 3 220 | }, 221 | "file_extension": ".py", 222 | "mimetype": "text/x-python", 223 | "name": "python", 224 | "nbconvert_exporter": "python", 225 | "pygments_lexer": "ipython3", 226 | "version": "3.4.3" 227 | } 228 | }, 229 | "nbformat": 4, 230 | "nbformat_minor": 1 231 | } 232 | -------------------------------------------------------------------------------- /notebooks/encoder_test.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [ 10 | { 11 | "ename": "ImportError", 12 | "evalue": "No module named 'encoders'", 13 | "traceback": [ 14 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 15 | "\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)", 16 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mencoders\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mencoders\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mencode_big\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0meb\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mencoders\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mencode_small\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mes\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 17 | "\u001b[0;31mImportError\u001b[0m: No module named 'encoders'" 18 | ], 19 | "output_type": "error" 20 | } 21 | ], 22 | "source": [ 23 | "import encoders\n", 24 | "from encoders import encode_big as eb\n", 25 | "from encoders import encode_small as es" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 2, 31 | "metadata": { 32 | "collapsed": false 33 | }, 34 | "outputs": [], 35 | "source": [ 36 | "aks = ['అ', 'ం', 'క్క', 'క్రి', 'స్త్రీ', ' ', 'క్క', ]" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 3, 42 | "metadata": { 43 | "collapsed": false 44 | }, 45 | "outputs": [ 46 | { 47 | "data": { 48 | "text/plain": [ 49 | "[45, 43, 65, 520, 67, 546, 497, 535, 546, 0, 65, 520]" 50 | ] 51 | }, 52 | "execution_count": 3, 53 | "metadata": {}, 54 | "output_type": "execute_result" 55 | } 56 | ], 57 | "source": [ 58 | "eb.enc(aks)" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 4, 64 | "metadata": { 65 | "collapsed": false 66 | }, 67 | "outputs": [ 68 | { 69 | "data": { 70 | "text/plain": [ 71 | "[45, 43, 65, 520, 67, 546, 497, 535, 546, 0, 65, 520]" 72 | ] 73 | }, 74 | "execution_count": 4, 75 | "metadata": {}, 76 | "output_type": "execute_result" 77 | } 78 | ], 79 | "source": [ 80 | "eb.encode(aks)" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 5, 86 | "metadata": { 87 | "collapsed": false 88 | }, 89 | "outputs": [ 90 | { 91 | "data": { 92 | "text/plain": [ 93 | "[45, 43, 78, 61, 113, 78, 63, 139, 111, 64, 128, 139, 0, 78, 61, 113]" 94 | ] 95 | }, 96 | "execution_count": 5, 97 | "metadata": {}, 98 | "output_type": "execute_result" 99 | } 100 | ], 101 | "source": [ 102 | "es.encode(aks)" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 6, 108 | "metadata": { 109 | "collapsed": false 110 | }, 111 | "outputs": [ 112 | { 113 | "data": { 114 | "text/plain": [ 115 | "[111, 64, 128, 139]" 116 | ] 117 | }, 118 | "execution_count": 6, 119 | "metadata": {}, 120 | "output_type": "execute_result" 121 | } 122 | ], 123 | "source": [ 124 | "es.encode(['స్త్రీ'])" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": 7, 130 | "metadata": { 131 | "collapsed": false 132 | }, 133 | "outputs": [ 134 | { 135 | "data": { 136 | "text/plain": [ 137 | "True" 138 | ] 139 | }, 140 | "execution_count": 7, 141 | "metadata": {}, 142 | "output_type": "execute_result" 143 | } 144 | ], 145 | "source": [ 146 | "'క' < 'కి'" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 8, 152 | "metadata": { 153 | "collapsed": false 154 | }, 155 | "outputs": [ 156 | { 157 | "data": { 158 | "text/plain": [ 159 | "True" 160 | ] 161 | }, 162 | "execution_count": 8, 163 | "metadata": {}, 164 | "output_type": "execute_result" 165 | } 166 | ], 167 | "source": [ 168 | "'కి' < 'హ'" 169 | ] 170 | }, 171 | { 172 | "cell_type": "code", 173 | "execution_count": 9, 174 | "metadata": { 175 | "collapsed": false 176 | }, 177 | "outputs": [ 178 | { 179 | "ename": "SyntaxError", 180 | "evalue": "invalid character in identifier (, line 1)", 181 | "traceback": [ 182 | "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m ౦౦\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid character in identifier\n" 183 | ], 184 | "output_type": "error" 185 | } 186 | ], 187 | "source": [ 188 | "౦౦" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": 11, 194 | "metadata": { 195 | "collapsed": false 196 | }, 197 | "outputs": [ 198 | { 199 | "data": { 200 | "text/plain": [ 201 | "154" 202 | ] 203 | }, 204 | "execution_count": 11, 205 | "metadata": {}, 206 | "output_type": "execute_result" 207 | } 208 | ], 209 | "source": [ 210 | "len(encoders.list_glyphs_minimal.symbols)" 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "execution_count": null, 216 | "metadata": { 217 | "collapsed": true 218 | }, 219 | "outputs": [], 220 | "source": [ 221 | "" 222 | ] 223 | } 224 | ], 225 | "metadata": { 226 | "kernelspec": { 227 | "display_name": "Python 3", 228 | "language": "python", 229 | "name": "python3" 230 | }, 231 | "language_info": { 232 | "codemirror_mode": { 233 | "name": "ipython", 234 | "version": 3.0 235 | }, 236 | "file_extension": ".py", 237 | "mimetype": "text/x-python", 238 | "name": "python", 239 | "nbconvert_exporter": "python", 240 | "pygments_lexer": "ipython3", 241 | "version": "3.4.3" 242 | } 243 | }, 244 | "nbformat": 4, 245 | "nbformat_minor": 0 246 | } -------------------------------------------------------------------------------- /notebooks/profile_get_next_char.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [ 10 | { 11 | "name": "stdout", 12 | "output_type": "stream", 13 | "text": [ 14 | "Loading the uni and bigram counts\n" 15 | ] 16 | } 17 | ], 18 | "source": [ 19 | "from bisect import bisect\n", 20 | "from collections import Counter\n", 21 | "from random import randrange, randint, choice, seed\n", 22 | "import numpy as np\n", 23 | "import cProfile as pro\n", 24 | "import importlib\n", 25 | "from math import ceil\n", 26 | "\n", 27 | "import telugu as te" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 34, 33 | "metadata": { 34 | "collapsed": false 35 | }, 36 | "outputs": [ 37 | { 38 | "name": "stdout", 39 | "output_type": "stream", 40 | "text": [ 41 | "Loading the uni and bigram counts\n", 42 | "53356\n" 43 | ] 44 | } 45 | ], 46 | "source": [ 47 | "importlib.reload(te)\n", 48 | "importlib.reload(te.texter)\n", 49 | "ss = randrange(100000)\n", 50 | "print(ss)\n", 51 | "\n", 52 | "def profile(fn, n=10**6, l=5):\n", 53 | " seed(ss)\n", 54 | " np.random.seed(ss)\n", 55 | " te.texter.bi_acc_cache = {}\n", 56 | " te.texter.bi_acc_cache_np = {}\n", 57 | " if fn:\n", 58 | " fn = '_' + fn\n", 59 | " fn = 'get_next_char{}'.format(fn)\n", 60 | " print(fn)\n", 61 | " cmd = 'te.texter.get_words({}, {}, te.texter.{})'.format(n, l, fn)\n", 62 | " pro.run(cmd, sort=2)\n", 63 | " print(len(te.texter.bi_acc_cache), len(te.texter.bi_acc_cache_np))\n" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 35, 69 | "metadata": { 70 | "collapsed": false, 71 | "scrolled": true 72 | }, 73 | "outputs": [ 74 | { 75 | "name": "stdout", 76 | "output_type": "stream", 77 | "text": [ 78 | "get_next_char\n", 79 | " 1601822 function calls in 1.114 seconds\n", 80 | "\n", 81 | " Ordered by: cumulative time\n", 82 | "\n", 83 | " ncalls tottime percall cumtime percall filename:lineno(function)\n", 84 | " 1 0.000 0.000 1.114 1.114 {built-in method exec}\n", 85 | " 1 0.000 0.000 1.114 1.114 :1()\n", 86 | " 1 0.028 0.028 1.114 1.114 texter.py:76(get_words)\n", 87 | " 100000 0.225 0.000 1.086 0.000 texter.py:64(get_word)\n", 88 | " 500000 0.595 0.000 0.861 0.000 texter.py:18(get_next_char)\n", 89 | " 500000 0.229 0.000 0.229 0.000 {built-in method bisect}\n", 90 | " 500000 0.036 0.000 0.036 0.000 {method 'random' of '_random.Random' objects}\n", 91 | " 1818 0.000 0.000 0.000 0.000 {method 'items' of 'dict' objects}\n", 92 | " 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}\n", 93 | "\n", 94 | "\n", 95 | "1818 0\n", 96 | "get_next_char_decay\n", 97 | "5) 171 < 179 picks 3 removed 165//8 = 20 from [ 1 11 13 178 179] ణ్ని\n", 98 | "5) 53 < 159 picks 3 removed 145//8 = 18 from [ 1 11 13 158 159] ణ్ని\n", 99 | "5) 92 < 141 picks 3 removed 127//8 = 15 from [ 1 11 13 140 141] ణ్ని\n", 100 | "5) 72 < 126 picks 3 removed 112//8 = 14 from [ 1 11 13 125 126] ణ్ని\n", 101 | "5) 99 < 112 picks 3 removed 98//8 = 12 from [ 1 11 13 111 112] ణ్ని\n", 102 | "5) 41 < 100 picks 3 removed 86//8 = 10 from [ 1 11 13 99 100] ణ్ని\n", 103 | "5) 49 < 90 picks 3 removed 76//8 = 9 from [ 1 11 13 89 90] ణ్ని\n", 104 | "5) 21 < 81 picks 3 removed 67//8 = 8 from [ 1 11 13 80 81] ణ్ని\n", 105 | "5) 40 < 73 picks 3 removed 59//8 = 7 from [ 1 11 13 72 73] ణ్ని\n", 106 | "5) 48 < 66 picks 3 removed 52//8 = 6 from [ 1 11 13 65 66] ణ్ని\n", 107 | "5) 12 < 60 picks 2 removed 2//8 = 1 from [ 1 11 13 59 60] ణ్ని\n", 108 | "5) 58 < 59 picks 4 removed 1//8 = 0 from [ 1 11 12 58 59] ణ్ని\n", 109 | "5) 40 < 59 picks 3 removed 46//8 = 5 from [ 1 11 12 58 59] ణ్ని\n", 110 | "5) 53 < 54 picks 4 removed 1//8 = 0 from [ 1 11 12 53 54] ణ్ని\n", 111 | "5) 47 < 54 picks 3 removed 41//8 = 5 from [ 1 11 12 53 54] ణ్ని\n", 112 | "5) 48 < 49 picks 4 removed 1//8 = 0 from [ 1 11 12 48 49] ణ్ని\n", 113 | "5) 30 < 49 picks 3 removed 36//8 = 4 from [ 1 11 12 48 49] ణ్ని\n", 114 | "5) 32 < 45 picks 3 removed 32//8 = 4 from [ 1 11 12 44 45] ణ్ని\n", 115 | "5) 17 < 41 picks 3 removed 28//8 = 3 from [ 1 11 12 40 41] ణ్ని\n", 116 | "5) 33 < 38 picks 3 removed 25//8 = 3 from [ 1 11 12 37 38] ణ్ని\n", 117 | "5) 26 < 35 picks 3 removed 22//8 = 2 from [ 1 11 12 34 35] ణ్ని\n", 118 | "5) 12 < 33 picks 3 removed 20//8 = 2 from [ 1 11 12 32 33] ణ్ని\n", 119 | "5) 0 < 31 picks 0 removed 1//8 = 0 from [ 1 11 12 30 31] ణ్ని\n", 120 | "5) 26 < 31 picks 3 removed 18//8 = 2 from [ 1 11 12 30 31] ణ్ని\n", 121 | "5) 2 < 29 picks 1 removed 10//8 = 1 from [ 1 11 12 28 29] ణ్ని\n", 122 | "5) 11 < 28 picks 3 removed 16//8 = 2 from [ 1 10 11 27 28] ణ్ని\n", 123 | "5) 15 < 26 picks 3 removed 14//8 = 1 from [ 1 10 11 25 26] ణ్ని\n", 124 | "5) 5 < 25 picks 1 removed 9//8 = 1 from [ 1 10 11 24 25] ణ్ని\n", 125 | "5) 23 < 24 picks 4 removed 1//8 = 0 from [ 1 9 10 23 24] ణ్ని\n", 126 | "5) 8 < 24 picks 1 removed 8//8 = 1 from [ 1 9 10 23 24] ణ్ని\n", 127 | "5) 6 < 23 picks 1 removed 7//8 = 1 from [ 1 8 9 22 23] ణ్ని\n", 128 | "5) 2 < 22 picks 1 removed 6//8 = 1 from [ 1 7 8 21 22] ణ్ని\n", 129 | "5) 15 < 21 picks 3 removed 13//8 = 1 from [ 1 6 7 20 21] ణ్ని\n", 130 | "5) 14 < 20 picks 3 removed 12//8 = 1 from [ 1 6 7 19 20] ణ్ని\n", 131 | "5) 2 < 19 picks 1 removed 5//8 = 1 from [ 1 6 7 18 19] ణ్ని\n", 132 | "5) 1 < 18 picks 1 removed 4//8 = 1 from [ 1 5 6 17 18] ణ్ని\n", 133 | "5) 16 < 17 picks 4 removed 1//8 = 0 from [ 1 4 5 16 17] ణ్ని\n", 134 | "5) 5 < 17 picks 3 removed 11//8 = 1 from [ 1 4 5 16 17] ణ్ని\n", 135 | "5) 7 < 16 picks 3 removed 10//8 = 1 from [ 1 4 5 15 16] ణ్ని\n", 136 | "5) 4 < 15 picks 2 removed 1//8 = 0 from [ 1 4 5 14 15] ణ్ని\n", 137 | "5) 6 < 15 picks 3 removed 9//8 = 1 from [ 1 4 5 14 15] ణ్ని\n", 138 | "5) 5 < 14 picks 3 removed 8//8 = 1 from [ 1 4 5 13 14] ణ్ని\n", 139 | "5) 7 < 13 picks 3 removed 7//8 = 1 from [ 1 4 5 12 13] ణ్ని\n", 140 | "5) 1 < 12 picks 1 removed 3//8 = 1 from [ 1 4 5 11 12] ణ్ని\n", 141 | "5) 2 < 11 picks 1 removed 2//8 = 1 from [ 1 3 4 10 11] ణ్ని\n", 142 | "5) 1 < 10 picks 1 removed 1//8 = 0 from [ 1 2 3 9 10] ణ్ని\n", 143 | "5) 3 < 10 picks 3 removed 6//8 = 1 from [ 1 2 3 9 10] ణ్ని\n", 144 | "5) 4 < 9 picks 3 removed 5//8 = 1 from [1 2 3 8 9] ణ్ని\n", 145 | "5) 5 < 8 picks 3 removed 4//8 = 1 from [1 2 3 7 8] ణ్ని\n", 146 | "5) 5 < 7 picks 3 removed 3//8 = 1 from [1 2 3 6 7] ణ్ని\n", 147 | "5) 4 < 6 picks 3 removed 2//8 = 1 from [1 2 3 5 6] ణ్ని\n", 148 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 149 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 150 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 151 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 152 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 153 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 154 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 155 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 156 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 157 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 158 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 159 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 160 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 161 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 162 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 163 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 164 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 165 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 166 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 167 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 168 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 169 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 170 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 171 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 172 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 173 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 174 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 175 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 176 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 177 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 178 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 179 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 180 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 181 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 182 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 183 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 184 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 185 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 186 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 187 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 188 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 189 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 190 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 191 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 192 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 193 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 194 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 195 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 196 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 197 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 198 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 199 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 200 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 201 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 202 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 203 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 204 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 205 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 206 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 207 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 208 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 209 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 210 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 211 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 212 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 213 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 214 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 215 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 216 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 217 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 218 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 219 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 220 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 221 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 222 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 223 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 224 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 225 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 226 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 227 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 228 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 229 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 230 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 231 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 232 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 233 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 234 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 235 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 236 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 237 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 238 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 239 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 240 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 241 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 242 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 243 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 244 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 245 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 246 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 247 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 248 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 249 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 250 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 251 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 252 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 253 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 254 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 255 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 256 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 257 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 258 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 259 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 260 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 261 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 262 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 263 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 264 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 265 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 266 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 267 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 268 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 269 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 270 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 271 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 272 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 273 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 274 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 275 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 276 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 277 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 278 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 279 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 280 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 281 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 282 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 283 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 284 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 285 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 286 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 287 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 288 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 289 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 290 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 291 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 292 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 293 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 294 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 295 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 296 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 297 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 298 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 299 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 300 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 301 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 302 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 303 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 304 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 305 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 306 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 307 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 308 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 309 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 310 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 311 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 312 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 313 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 314 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 315 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 316 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 317 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 318 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 319 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 320 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 321 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 322 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 323 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 324 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 325 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 326 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 327 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 328 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 329 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 330 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 331 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 332 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 333 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 334 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 335 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 336 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 337 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 338 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 339 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 340 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 341 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 342 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 343 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 344 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 345 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 346 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 347 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 348 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 349 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 350 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 351 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 352 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 353 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 354 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 355 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 356 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 357 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 358 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 359 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 360 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 361 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 362 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 363 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 364 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 365 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 366 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 367 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 368 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 369 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 370 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 371 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 372 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 373 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 374 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 375 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 376 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 377 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 378 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 379 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 380 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 381 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 382 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 383 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 384 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 385 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 386 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 387 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 388 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 389 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 390 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 391 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 392 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 393 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 394 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 395 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 396 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 397 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 398 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 399 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 400 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 401 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 402 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 403 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 404 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 405 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 406 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 407 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 408 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 409 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 410 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 411 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 412 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 413 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 414 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 415 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 416 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 417 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 418 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 419 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 420 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 421 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 422 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 423 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 424 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 425 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 426 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 427 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 428 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 429 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 430 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 431 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 432 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 433 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 434 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 435 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 436 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 437 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 438 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 439 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 440 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 441 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 442 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 443 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 444 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 445 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 446 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 447 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 448 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 449 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 450 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 451 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 452 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 453 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 454 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 455 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 456 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 457 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 458 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 459 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 460 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 461 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 462 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 463 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 464 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 465 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 466 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 467 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 468 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 469 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 470 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 471 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 472 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 473 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 474 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 475 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 476 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 477 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 478 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 479 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 480 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 481 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 482 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 483 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 484 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 485 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 486 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 487 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 488 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 489 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 490 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 491 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 492 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 493 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 494 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 495 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 496 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 497 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 498 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 499 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 500 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 501 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 502 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 503 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 504 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 505 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 506 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 507 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 508 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 509 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 510 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 511 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 512 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 513 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 514 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 515 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 516 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 517 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 518 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 519 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 520 | "5) 1 < 5 picks 1 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 521 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 522 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 523 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 524 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 525 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 526 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 527 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 528 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 529 | "5) 4 < 5 picks 4 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 530 | "5) 2 < 5 picks 2 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 531 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 532 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 533 | "5) 3 < 5 picks 3 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 534 | "5) 0 < 5 picks 0 removed 1//8 = 0 from [1 2 3 4 5] ణ్ని\n", 535 | " 21115266 function calls (21113514 primitive calls) in 63.871 seconds\n", 536 | "\n", 537 | " Ordered by: cumulative time\n", 538 | "\n", 539 | " ncalls tottime percall cumtime percall filename:lineno(function)\n", 540 | " 1 0.000 0.000 63.871 63.871 {built-in method exec}\n", 541 | " 1 0.000 0.000 63.870 63.870 :1()\n", 542 | " 1 0.440 0.440 63.870 63.870 texter.py:76(get_words)\n", 543 | " 1000000 4.175 0.000 63.430 0.000 texter.py:64(get_word)\n", 544 | " 5000000 52.240 0.000 59.255 0.000 texter.py:33(get_next_char_decay)\n", 545 | " 5000000 5.491 0.000 5.491 0.000 {built-in method bisect}\n", 546 | " 5020148 0.640 0.000 0.640 0.000 {built-in method len}\n", 547 | " 5000000 0.580 0.000 0.580 0.000 {method 'random' of '_random.Random' objects}\n", 548 | " 438 0.009 0.000 0.208 0.000 {method 'format' of 'str' objects}\n", 549 | " 1314/438 0.002 0.000 0.199 0.000 numeric.py:1835(array_str)\n", 550 | " 1314/438 0.005 0.000 0.198 0.000 arrayprint.py:340(array2string)\n", 551 | " 438 0.010 0.000 0.195 0.000 arrayprint.py:237(_array2string)\n", 552 | " 1314 0.004 0.000 0.134 0.000 arrayprint.py:529(__init__)\n", 553 | " 1314 0.053 0.000 0.130 0.000 arrayprint.py:543(fillFormat)\n", 554 | " 438 0.002 0.000 0.075 0.000 arrayprint.py:696(__init__)\n", 555 | " 438 0.002 0.000 0.070 0.000 {built-in method print}\n", 556 | " 876 0.004 0.000 0.067 0.000 iostream.py:361(write)\n", 557 | " 978 0.024 0.000 0.062 0.000 iostream.py:180(schedule)\n", 558 | " 978 0.033 0.000 0.033 0.000 {built-in method urandom}\n", 559 | " 5809 0.028 0.000 0.028 0.000 {built-in method fromiter}\n", 560 | " 3942 0.024 0.000 0.024 0.000 {method 'reduce' of 'numpy.ufunc' objects}\n", 561 | " 438 0.006 0.000 0.024 0.000 arrayprint.py:458(_formatArray)\n", 562 | " 876 0.007 0.000 0.018 0.000 arrayprint.py:575()\n", 563 | " 2628 0.007 0.000 0.017 0.000 numeric.py:2576(seterr)\n", 564 | " 438 0.004 0.000 0.016 0.000 arrayprint.py:635(__init__)\n", 565 | " 1314 0.003 0.000 0.014 0.000 fromnumeric.py:1900(any)\n", 566 | " 2190 0.014 0.000 0.014 0.000 arrayprint.py:648(__call__)\n", 567 | " 1314 0.002 0.000 0.012 0.000 numeric.py:2967(__enter__)\n", 568 | " 4380 0.008 0.000 0.011 0.000 arrayprint.py:628(_digits)\n", 569 | " 1314 0.010 0.000 0.010 0.000 {method 'compress' of 'numpy.ndarray' objects}\n", 570 | " 1314 0.001 0.000 0.009 0.000 {method 'any' of 'numpy.ndarray' objects}\n", 571 | " 1314 0.002 0.000 0.009 0.000 numeric.py:2972(__exit__)\n", 572 | " 1314 0.001 0.000 0.008 0.000 _methods.py:37(_any)\n", 573 | " 2628 0.006 0.000 0.006 0.000 numeric.py:2676(geterr)\n", 574 | " 876 0.000 0.000 0.006 0.000 iostream.py:298(_schedule_flush)\n", 575 | " 978 0.002 0.000 0.004 0.000 threading.py:1108(is_alive)\n", 576 | " 2190 0.003 0.000 0.004 0.000 arrayprint.py:450(_extendLine)\n", 577 | " 438 0.001 0.000 0.004 0.000 fromnumeric.py:1383(ravel)\n", 578 | " 1314 0.002 0.000 0.003 0.000 :2264(_handle_fromlist)\n", 579 | " 8760 0.003 0.000 0.003 0.000 {method 'rstrip' of 'str' objects}\n", 580 | " 1752 0.002 0.000 0.002 0.000 numeric.py:484(asanyarray)\n", 581 | " 2628 0.002 0.000 0.002 0.000 {built-in method seterrobj}\n", 582 | " 978 0.001 0.000 0.002 0.000 threading.py:1066(_wait_for_tstate_lock)\n", 583 | " 1314 0.002 0.000 0.002 0.000 numeric.py:2963(__init__)\n", 584 | " 438 0.001 0.000 0.001 0.000 arrayprint.py:713(__init__)\n", 585 | " 438 0.001 0.000 0.001 0.000 numeric.py:414(asarray)\n", 586 | " 2190 0.001 0.000 0.001 0.000 {built-in method isinstance}\n", 587 | " 438 0.001 0.000 0.001 0.000 arrayprint.py:685(__init__)\n", 588 | " 978 0.001 0.000 0.001 0.000 {method 'acquire' of '_thread.lock' objects}\n", 589 | " 876 0.001 0.000 0.001 0.000 iostream.py:285(_is_master_process)\n", 590 | " 5256 0.001 0.000 0.001 0.000 {built-in method geterrobj}\n", 591 | " 5809 0.001 0.000 0.001 0.000 {method 'items' of 'dict' objects}\n", 592 | " 1314 0.001 0.000 0.001 0.000 {built-in method max}\n", 593 | " 438 0.001 0.000 0.001 0.000 {method 'ravel' of 'numpy.ndarray' objects}\n", 594 | " 978 0.001 0.000 0.001 0.000 iostream.py:89(_event_pipe)\n", 595 | " 2190 0.001 0.000 0.001 0.000 {built-in method array}\n", 596 | " 1314 0.001 0.000 0.001 0.000 arrayprint.py:657(__init__)\n", 597 | " 1314 0.001 0.000 0.001 0.000 {built-in method issubclass}\n", 598 | " 1314 0.001 0.000 0.001 0.000 {built-in method min}\n", 599 | " 2628 0.001 0.000 0.001 0.000 {built-in method hasattr}\n", 600 | " 438 0.000 0.000 0.000 0.000 {built-in method reduce}\n", 601 | " 876 0.000 0.000 0.000 0.000 {method 'item' of 'numpy.ndarray' objects}\n", 602 | " 1314 0.000 0.000 0.000 0.000 {method 'pop' of 'dict' objects}\n", 603 | " 876 0.000 0.000 0.000 0.000 {built-in method getpid}\n", 604 | " 438 0.000 0.000 0.000 0.000 arrayprint.py:734(__init__)\n", 605 | " 978 0.000 0.000 0.000 0.000 threading.py:501(is_set)\n", 606 | " 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}\n", 607 | "\n", 608 | "\n", 609 | "0 5809\n" 610 | ] 611 | } 612 | ], 613 | "source": [ 614 | "profile('', n=10**5)\n", 615 | "profile('decay', n=10**6)" 616 | ] 617 | }, 618 | { 619 | "cell_type": "code", 620 | "execution_count": null, 621 | "metadata": { 622 | "collapsed": false 623 | }, 624 | "outputs": [], 625 | "source": [ 626 | "profile('', n=10**5, l=10)\n", 627 | "profile('decay', n=10**5, l=10)\n" 628 | ] 629 | }, 630 | { 631 | "cell_type": "code", 632 | "execution_count": null, 633 | "metadata": { 634 | "collapsed": false 635 | }, 636 | "outputs": [], 637 | "source": [ 638 | "12.3/1.971" 639 | ] 640 | }, 641 | { 642 | "cell_type": "code", 643 | "execution_count": null, 644 | "metadata": { 645 | "collapsed": true 646 | }, 647 | "outputs": [], 648 | "source": [] 649 | } 650 | ], 651 | "metadata": { 652 | "kernelspec": { 653 | "display_name": "Python 3", 654 | "language": "python", 655 | "name": "python3" 656 | }, 657 | "language_info": { 658 | "codemirror_mode": { 659 | "name": "ipython", 660 | "version": 3 661 | }, 662 | "file_extension": ".py", 663 | "mimetype": "text/x-python", 664 | "name": "python", 665 | "nbconvert_exporter": "python", 666 | "pygments_lexer": "ipython3", 667 | "version": "3.4.3" 668 | } 669 | }, 670 | "nbformat": 4, 671 | "nbformat_minor": 1 672 | } 673 | -------------------------------------------------------------------------------- /profile/README.md: -------------------------------------------------------------------------------- 1 | # Profiling 2 | 3 | ## To Create 4 | 5 | ```sh 6 | python3 -m cProfile -o profile/parscribe.pstats train.py config/profile.ast 7 | ``` 8 | 9 | ## To Visualise 10 | 11 | ```sh 12 | sudo pip3 install snakeviz 13 | snakeviz profile/parscribe.pstats 14 | ``` 15 | 16 | ## To generate SVG 17 | 18 | ```sh 19 | #sudo apt-get install gprof2dot 20 | #sudo pip3 install gprof2dot 21 | gprof2dot -f pstats parscribe.pstats | dot -Tsvg -o parscribe.svg 22 | ``` 23 | -------------------------------------------------------------------------------- /profile/parscribe.pstats: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakeshvar/chamanti_ocr_theano/4eb457ebf9cf6157f7d3fa8f42ae8e98766ad2ac/profile/parscribe.pstats -------------------------------------------------------------------------------- /profile/parscribe_decay.pstats: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakeshvar/chamanti_ocr_theano/4eb457ebf9cf6157f7d3fa8f42ae8e98766ad2ac/profile/parscribe_decay.pstats -------------------------------------------------------------------------------- /profile/scribe.pstats: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakeshvar/chamanti_ocr_theano/4eb457ebf9cf6157f7d3fa8f42ae8e98766ad2ac/profile/scribe.pstats -------------------------------------------------------------------------------- /profile/scribe_decay.pstats: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakeshvar/chamanti_ocr_theano/4eb457ebf9cf6157f7d3fa8f42ae8e98766ad2ac/profile/scribe_decay.pstats -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | scipy 3 | theano 4 | editdistance 5 | ### Also needs the following personal repositories 6 | # rnn_ctc 7 | # IndicScribe 8 | -------------------------------------------------------------------------------- /scripts/install.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | echo "Installing system dependencies..." 4 | sudo apt-get install libffi-dev 5 | 6 | echo "Installing python packages..." 7 | sudo pip3 install --upgrade pip 8 | sudo pip3 install -r requirements.txt 9 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from setuptools import setup 4 | 5 | requirements = open('requirements.txt').read().splitlines() 6 | 7 | setup( 8 | name='chamanti_ocr', 9 | version='0.1', 10 | description='Telugu OCR framework using RNN, CTC in Theano & Python3', 11 | url='https://github.com/rakeshvar/chamanti_ocr', 12 | author='Rakeshvar Achanta', 13 | author_email='rakeshvar@gmail.com', 14 | license='Apache', 15 | classifiers=[ 16 | 'Development Status :: 4 - Beta', 17 | 'Topic :: Software Development :: Libraries', 18 | 'License :: OSI Approved :: Apache License', 19 | 'Programming Language :: Python :: 3', 20 | ], 21 | keywords='telugu ocr', 22 | install_requires=requirements, 23 | py_modules=['.py', 'rnn_ctc', 'lab', 'telugu'], 24 | package_data={ 25 | '': ['*.ast'] 26 | }, 27 | include_package_data=True, 28 | ) 29 | -------------------------------------------------------------------------------- /train.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pickle 3 | import sys 4 | from datetime import datetime as dt 5 | 6 | import editdistance 7 | import numpy as np 8 | import theano as th 9 | 10 | import rnn_ctc.neuralnet as nn 11 | # from parscribe import ParScribe as Scribe 12 | from scribe import Scribe 13 | import utils 14 | import telugu as lang 15 | import utils 16 | 17 | ############################################ Read Args 18 | args = utils.read_args(sys.argv[1:]) 19 | num_samples, num_epochs = args['num_samples'], args['num_epochs'] 20 | scribe_args, nnet_args = args['scribe_args'], args['nnet_args'] 21 | 22 | if len(sys.argv) > 1: 23 | output_fname = '-'.join(sorted(sys.argv[1:])) 24 | output_fname = output_fname.replace('.ast', '').replace('/', '').replace('configs', '') 25 | else: 26 | output_fname = "default" 27 | network_fname = '{}.pkl'.format(output_fname) 28 | output_fname += '_' + dt.now().strftime('%y%m%d_%H%M') + '.txt' 29 | distances, wts = [], [] 30 | print("Output will be written to: ", output_fname) 31 | 32 | # Initialize Language 33 | lang.select_labeler(args['labeler']) 34 | alphabet_size = len(lang.symbols) 35 | 36 | # Initialize Scriber 37 | scribe_args['dtype'] = th.config.floatX 38 | scriber = Scribe(lang, **scribe_args) 39 | printer = utils.Printer(lang.symbols) 40 | 41 | sys.setrecursionlimit(1000000) 42 | 43 | # Initialize the Neural Network 44 | if os.path.exists(network_fname): 45 | print('Loading existing network file') 46 | with open(network_fname, 'rb') as fh: 47 | ntwk = pickle.load(fh) 48 | else: 49 | print('Building the Network') 50 | ntwk = nn.NeuralNet(scriber.height, alphabet_size, **nnet_args) 51 | with open(network_fname, 'wb') as fh: 52 | pickle.dump(ntwk, fh) 53 | 54 | 55 | # Print 56 | print('\nArguments:') 57 | utils.write_dict(args) 58 | print('FloatX: {}'.format(th.config.floatX)) 59 | print('Alphabet Size: {}'.format(alphabet_size)) 60 | 61 | ################################ Train 62 | print('Training the Network') 63 | for epoch in range(num_epochs): 64 | ntwk.update_learning_rate(epoch) 65 | edit_dist, tot_len = 0, 0 66 | 67 | print('Epoch: {} '.format(epoch)) 68 | # keeping 1 backup file as data might get lost, if script is stopped while pickling 69 | os.rename(network_fname, 'ntwk.bkp.pkl') 70 | with open(network_fname, 'wb') as fh: 71 | pickle.dump(ntwk, fh) 72 | print('Network saved to {}'.format(network_fname)) 73 | 74 | for samp in range(num_samples): 75 | x, _, y = scriber.get_text_image() 76 | y_blanked = utils.insert_blanks(y, alphabet_size, num_blanks_at_start=2) 77 | # if len(y_blanked) < 2: 78 | # print(y_blanked, end=' ') 79 | # continue 80 | cst, pred, forward_probs = ntwk.trainer(x, y_blanked) 81 | 82 | if np.isinf(cst): 83 | printer.show_all(y, x, pred, 84 | (forward_probs > 1e-20, 'Forward probabilities:', y_blanked)) 85 | print('Exiting on account of Inf Cost...') 86 | break 87 | 88 | if samp == 0 and epoch==num_epochs-1: # or len(y) == 0: 89 | pred, hidden = ntwk.tester(x) 90 | 91 | print('Epoch:{:6d} Cost:{:.3f}'.format(epoch, float(cst))) 92 | printer.show_all(y, x, pred, 93 | (forward_probs > -6, 'Forward probabilities:', y_blanked), 94 | ((hidden + 1)/2, 'Hidden Layer:')) 95 | utils.pprint_probs(forward_probs) 96 | 97 | edit_dist += editdistance.eval(printer.decode(pred), y) 98 | tot_len += len(y) 99 | 100 | distances.append((edit_dist, tot_len)) 101 | # wts.append(ntwk.layers[0].params[1].get_value()) 102 | # print("Successes: {0[0]}/{0[1]}".format(edit_dist)) 103 | 104 | 105 | ################################ save 106 | with open(output_fname, 'w') as f: 107 | # pickle.dump((wts, successes), f, -1) 108 | utils.write_dict(args, f) 109 | 110 | f.write("Edit Distances\n") 111 | for i, (e, t) in enumerate(distances): 112 | f.write("{:4d}: {:5d}/{:5d}\n".format(i, e, t)) 113 | 114 | print(output_fname, distances[-1]) 115 | -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import ast 3 | import numpy as np 4 | import sys 5 | 6 | 7 | def slab_print_ascii(nparr): 8 | print('-' * (len(nparr[0]) + 5)) 9 | for ir, r in enumerate(nparr): 10 | print('{:3d}|'.format(ir), end='') 11 | for c in r: 12 | if c == 0: v = ' ' 13 | elif c < .2: v = '.' 14 | elif c < .4: v = '*' 15 | elif c < .6: v = 'o' 16 | elif c < .8: v = '0' 17 | elif c < 1: v = '@' 18 | else: v = '#' 19 | print(v, end='') 20 | print('|') 21 | print('-' * (len(nparr[0]) + 5)) 22 | 23 | 24 | def slab_print_binary(nparr): 25 | print('-' * (len(nparr[0]) + 5)) 26 | for ir, r in enumerate(nparr): 27 | print('{:3d}|'.format(ir), end='') 28 | for p in r: 29 | print([' ', '#'][1 * p], end='') 30 | print('|') 31 | print('-' * (len(nparr[0]) + 5)) 32 | 33 | 34 | def slab_print(slab, col_names=None): 35 | """ 36 | Prints a 'slab' of printed 'text' using ascii. 37 | :param slab: A matrix of floats from [0, 1] 38 | """ 39 | if slab.max() == 255: 40 | slab1 = slab/255. 41 | else: 42 | slab1 = slab 43 | 44 | for ir, r in enumerate(slab1): 45 | print('{:2d}¦'.format(ir), end='') 46 | for val in r: 47 | if val < 0.0: print('-', end='') 48 | elif val < .15: print(' ', end=''), 49 | elif val < .35: print('░', end=''), 50 | elif val < .65: print('▒', end=''), 51 | elif val < .85: print('▓', end=''), 52 | elif val <= 1.: print('█', end=''), 53 | else: print('+', end='') 54 | print('¦ {}'.format(col_names[ir] if col_names else '')) 55 | 56 | 57 | class Printer(): 58 | def __init__(self, symbols): 59 | """ 60 | Creates a function that can print a predicted output of the CTC RNN 61 | It removes the blank characters (need to be set to n_classes), 62 | It also removes duplicates 63 | :param list symbols: list of symbols in the language encoding 64 | """ 65 | self.symbols = symbols + ['_'] 66 | self.n_classes = len(self.symbols) - 1 67 | 68 | def labels_to_chars(self, labels_out): 69 | return [self.symbols[l] for l in labels_out] 70 | 71 | def remove_blanks_repeats(self, labels): 72 | labels_out = [] 73 | for il, l in enumerate(labels): 74 | if (l != self.n_classes) and (il == 0 or l != labels[il - 1]): 75 | labels_out.append(l) 76 | return labels_out 77 | 78 | def ylen(self, labels): 79 | return len(self.remove_blanks_repeats(labels)) 80 | 81 | def show_labels(self, seq): 82 | labels = self.remove_blanks_repeats(seq) 83 | chars = self.labels_to_chars(labels) 84 | print(labels, ''.join(chars)) 85 | return labels, chars 86 | 87 | def decode(self, softmax_firings): 88 | max_labels = np.argmax(softmax_firings, 0) 89 | seen_labels = self.remove_blanks_repeats(max_labels) 90 | return seen_labels 91 | 92 | def show_all(self, shown_seq, shown_img, 93 | softmax_firings=None, 94 | *aux_imgs): 95 | """ 96 | Utility function to show the input and output and debug 97 | :param shown_seq: Labelings of the input 98 | :param shown_img: Input Image 99 | :param softmax_firings: Seen Probabilities (Excitations of Softmax) 100 | :param aux_imgs: List of pairs of images and names 101 | :return: 102 | """ 103 | print('Shown : ', end='') 104 | labels, chars = self.show_labels(shown_seq) 105 | 106 | if softmax_firings is not None: 107 | print('Seen : ', end='') 108 | seen_labels = self.decode(softmax_firings) 109 | self.show_labels(seen_labels) 110 | 111 | print('Image Shown:') 112 | slab_print(shown_img) 113 | 114 | if softmax_firings is not None: 115 | seen_labels = list(set(seen_labels) - set(labels)) 116 | seen_chars = self.labels_to_chars(seen_labels) 117 | l = labels + [self.n_classes] + seen_labels 118 | c = chars + ['blank'] + seen_chars 119 | print('SoftMax Firings:') 120 | slab_print(softmax_firings[l], c) 121 | 122 | for aux_img, aux_name, *col_names in aux_imgs: 123 | col_names = self.labels_to_chars(col_names[0]) if col_names else None 124 | print(aux_name) 125 | slab_print(aux_img, col_names) 126 | 127 | 128 | def insert_blanks(y, blank, num_blanks_at_start=1): 129 | # Insert blanks at alternate locations in the labelling (blank is blank) 130 | y1 = [blank] * num_blanks_at_start 131 | for char in y: 132 | y1 += [char, blank] 133 | return y1 134 | 135 | 136 | def read_args(files, default='configs/default.ast'): 137 | with open(default, 'r') as dfp: 138 | args = ast.literal_eval(dfp.read()) 139 | 140 | for config_file in files: 141 | with open(config_file, 'r') as cfp: 142 | override_args = ast.literal_eval(cfp.read()) 143 | 144 | for key in args: 145 | if key in override_args: 146 | try: 147 | args[key].update(override_args[key]) 148 | except AttributeError: 149 | args[key] = override_args[key] 150 | 151 | return args 152 | 153 | 154 | def pprint_probs(probs): 155 | for row in (10 * probs).astype(int): 156 | for val in row: 157 | print('{:+04d}'.format(val), end='') 158 | print() 159 | 160 | 161 | def write_dict(d, f=sys.stdout, level=0): 162 | tabs = '\t' * level 163 | print(file=f) 164 | for k in sorted(d.keys()): 165 | v = d[k] 166 | print('{}{}: '.format(tabs, k), file=f, end='') 167 | if type(v) is dict: 168 | write_dict(v, f, level+1) 169 | else: 170 | print('{}'.format(v), file=f) --------------------------------------------------------------------------------