├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.rst ├── data ├── left_eye.jpg ├── pigment_label_sample.csv ├── right_eye.jpg ├── test_set_patients.txt └── training_set_patients.txt ├── deepseenet ├── __init__.py ├── data_generator.py ├── deepseenet_adv_amd.py ├── deepseenet_cga.py ├── deepseenet_drusen.py ├── deepseenet_ga.py ├── deepseenet_pigment.py ├── deepseenet_risk_factor.py ├── deepseenet_simplified.py └── utils.py ├── docs ├── images │ ├── Fig1.png │ ├── Fig5.png │ ├── Fig6.png │ ├── Tab4.png │ ├── dhhs-logo-white.svg │ ├── nih-logo-white.svg │ ├── nlm-logo-letters-white.svg │ └── usagov-logo-white.svg └── index.html ├── examples ├── __init__.py ├── predict_drusen.py ├── predict_simplified_score.py ├── train.py └── utils.py ├── images └── deepseenet.png ├── requirements.txt └── tests ├── __init__.py ├── context.py └── deepseenet ├── __init__.py ├── test_get_file.py └── test_simplified_score.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | 3 | deep-learning-models 4 | .pytest_cache/ 5 | backup 6 | examples-local 7 | 8 | ### Python template 9 | # Byte-compiled / optimized / DLL files 10 | __pycache__/ 11 | *.py[cod] 12 | *$py.class 13 | 14 | # C extensions 15 | *.so 16 | 17 | # Distribution / packaging 18 | .Python 19 | env/ 20 | build/ 21 | develop-eggs/ 22 | dist/ 23 | downloads/ 24 | eggs/ 25 | .eggs/ 26 | lib/ 27 | lib64/ 28 | parts/ 29 | sdist/ 30 | var/ 31 | wheels/ 32 | *.egg-info/ 33 | .installed.cfg 34 | *.egg 35 | 36 | # PyInstaller 37 | # Usually these files are written by a python script from a template 38 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 39 | *.manifest 40 | *.spec 41 | 42 | # Installer logs 43 | pip-log.txt 44 | pip-delete-this-directory.txt 45 | 46 | # Unit test / coverage reports 47 | htmlcov/ 48 | .tox/ 49 | .coverage 50 | .coverage.* 51 | .cache 52 | nosetests.xml 53 | coverage.xml 54 | *,cover 55 | .hypothesis/ 56 | 57 | # Translations 58 | *.mo 59 | *.pot 60 | 61 | # Django stuff: 62 | *.log 63 | local_settings.py 64 | 65 | # Flask stuff: 66 | instance/ 67 | .webassets-cache 68 | 69 | # Scrapy stuff: 70 | .scrapy 71 | 72 | # Sphinx documentation 73 | docs/_build/ 74 | 75 | # PyBuilder 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # pyenv 82 | .python-version 83 | 84 | # celery beat schedule file 85 | celerybeat-schedule 86 | 87 | # SageMath parsed files 88 | *.sage.py 89 | 90 | # dotenv 91 | .env 92 | 93 | # virtualenv 94 | .venv 95 | venv/ 96 | ENV/ 97 | 98 | # Spyder project settings 99 | .spyderproject 100 | 101 | # Rope project settings 102 | .ropeproject 103 | ### JetBrains template 104 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 105 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 106 | 107 | # User-specific stuff: 108 | .idea 109 | .idea/**/workspace.xml 110 | .idea/**/tasks.xml 111 | .idea/dictionaries 112 | 113 | # Sensitive or high-churn files: 114 | .idea/**/dataSources/ 115 | .idea/**/dataSources.ids 116 | .idea/**/dataSources.xml 117 | .idea/**/dataSources.local.xml 118 | .idea/**/sqlDataSources.xml 119 | .idea/**/dynamic.xml 120 | .idea/**/uiDesigner.xml 121 | 122 | # Gradle: 123 | .idea/**/gradle.xml 124 | .idea/**/libraries 125 | 126 | # Mongo Explorer plugin: 127 | .idea/**/mongoSettings.xml 128 | 129 | ## File-based project format: 130 | *.iws 131 | 132 | ## Plugin-specific files: 133 | 134 | # IntelliJ 135 | /out/ 136 | 137 | # mpeltonen/sbt-idea plugin 138 | .idea_modules/ 139 | 140 | # JIRA plugin 141 | atlassian-ide-plugin.xml 142 | 143 | # Crashlytics plugin (for Android Studio and IntelliJ) 144 | com_crashlytics_export_strings.xml 145 | crashlytics.properties 146 | crashlytics-build.properties 147 | fabric.properties 148 | 149 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.6" 4 | install: 5 | pip install -r requirements.txt 6 | 7 | script: 8 | - py.test 9 | 10 | notifications: 11 | email: false -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | This project adheres to the [Contributor Covenant Code of Conduct](http://contributor-covenant.org/). 6 | 7 | # Maintainers 8 | 9 | DeepSeeNet is maintained with :heart: by: 10 | 11 | - **@yfpeng** 12 | 13 | See also the list of [contributors](https://github.com/ncbi-nlp/DeepSeeNet/contributors) who participated in this project. 14 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | PUBLIC DOMAIN NOTICE 2 | National Center for Biotechnology Information 3 | 4 | This software/database is a "United States Government Work" under the terms of 5 | the United States Copyright Act. It was written as part of the author's 6 | official duties as a United States Government employee and thus cannot be 7 | copyrighted. This software/database is freely available to the public for use. 8 | The National Library of Medicine and the U.S. Government have not placed any 9 | restriction on its use or reproduction. 10 | 11 | Although all reasonable efforts have been taken to ensure the accuracy and 12 | reliability of the software and data, the NLM and the U.S. Government do not and 13 | cannot warrant the performance or results that may be obtained by using this 14 | software or data. The NLM and the U.S. Government disclaim all warranties, 15 | express or implied, including warranties of performance, merchantability or 16 | fitness for any particular purpose. 17 | 18 | Please cite the author in any work or product based on this material: 19 | 20 | Peng Y, Dharssi S, Chen Q, Keenan T, Agron E, Wong W, Chew E, Lu Z. DeepSeeNet: 21 | A deep learning model for automated classification of patientbased age-related 22 | macular degeneration severity from color fundus photographs. Ophthalmology. 2018. 23 | 24 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | .. image:: https://github.com/ncbi-nlp/DeepSeeNet/blob/master/images/deepseenet.png?raw=true 2 | :target: https://github.com/ncbi-nlp/DeepSeeNet/blob/master/images/deepseenet.png?raw=true 3 | :alt: DeepSeeNet 4 | 5 | .. role:: raw-html(raw) 6 | :format: html 7 | 8 | ----------------------- 9 | 10 | DeepSeeNet is a high-performance deep learning framework for grading of color fundus photographs using the AREDS simplified severity scale. For more details, please see ``_. 11 | 12 | Getting Started with DeepSeeNet 13 | =============================== 14 | 15 | These instructions will get you a copy of the project up and run on your local machine for development and testing purposes. 16 | The package should successfully install on Linux. 17 | 18 | Installing 19 | ---------- 20 | 21 | Prerequisites 22 | ~~~~~~~~~~~~~ 23 | 24 | * python =3.6 25 | * tensorflow >=1.6.0 26 | * keras =2.2.4 27 | * Linux 28 | 29 | Tensorflow can be downloaded from `https://www.tensorflow.org `_. 30 | 31 | 32 | Installing from source 33 | ~~~~~~~~~~~~~~~~~~~~~~ 34 | 35 | 1. Download the source code from GitHub: ``git clone https://github.com/ncbi-nlp/DeepSeeNet.git`` 36 | 2. Change to the directory of ``DeepSeeNet`` 37 | 3. Install required packages: ``pip install -r requirements.txt`` 38 | 4. Add the code directory to ``PYTHONPATH``: ``export PYTHONPATH=.:$PYTHONPATH`` 39 | 40 | 41 | Using DeepSeeNet for grading simplified scores 42 | ---------------------------------------------- 43 | 44 | The easiest way is to run the following command 45 | 46 | .. code-block:: bash 47 | 48 | $ python examples/predict_simplified_score.py data/left_eye.jpg data/right_eye.jpg 49 | ... 50 | Downloading data from https://github.com/ncbi-nlp/DeepSeeNet/releases/download/0.1/drusen_model.h5 51 | INFO:root:Loading the model: /tmp/.keras/datasets/drusen_model.h5 52 | Downloading data from https://github.com/ncbi-nlp/DeepSeeNet/releases/download/0.1/pigment_model.h5 53 | INFO:root:Loading the model: /tmp/.keras/datasets/pigment_model.h5 54 | Downloading data from https://github.com/ncbi-nlp/DeepSeeNet/releases/download/0.1/advanced_amd_model.h5 55 | INFO:root:Loading the model: /tmp/.keras/datasets/advanced_amd_model.h5 56 | ... 57 | INFO:root:Processing: data/left_eye.jpg 58 | INFO:root:Processing: data/right_eye.jpg 59 | ... 60 | INFO:root:Risk factors: {'pigment': (0, 0), 'advanced_amd': (0, 0), 'drusen': (2, 2)} 61 | The simplified score: 2 62 | 63 | The script will 64 | 65 | 1. Download the models from the ``DeepSeeNet`` repository 66 | 2. Predict the simplified score based on the sample left and right eyes 67 | 68 | More options (e.g., setting the models) can be obtained by running 69 | 70 | .. code-block:: bash 71 | 72 | $ python examples/predict_simplified_score.py --help 73 | 74 | 75 | Pre-trained DeepSeeNet models 76 | ----------------------------- 77 | 78 | Besides grading the simplified score, we also provide individual risk factor models. For example 79 | 80 | .. code-block:: bash 81 | 82 | $ python examples/predict_drusen.py data/left_eye.jpg 83 | ... 84 | INFO:root:Loading the model: /tmp/.keras/datasets/drusen_model.h5 85 | ... 86 | INFO:root:Processing: data/left_eye.jpg 87 | ... 88 | The drusen score: [[0.21020733 0.2953384 0.49445423]] 89 | The drusen size: large 90 | 91 | Here, we provide the following pre-trained models: 92 | 93 | * `drusen size `_: non/small, intermediate, large 94 | * `pigmentary abnormalities `_: no, yes 95 | * `late AMD `_: no, yes 96 | * `geographic atrophy (GA) `_: no, yes 97 | * `central GA `_: no, yes 98 | 99 | 100 | Training DeepSeeNet model 101 | ------------------------- 102 | 103 | You can train the individual risk factor model too. For example 104 | 105 | .. code-block:: bash 106 | 107 | $ python examples/train.py data/pigment_label_sample.csv data/pigment_best_model.h5 108 | ... 109 | Epoch 1/100 110 | 2/2 [==============================] - 27s 14s/step - loss: 1.0103 - acc: 0.5148... 111 | ... 112 | early stopping 113 | 114 | 115 | The program will read images and labels from a CSV file, train the model, and save the latest best model according to the ``val_acc``. 116 | 117 | 118 | Acknowledgments 119 | =============== 120 | 121 | This work was supported by the Intramural Research Programs of the National Institutes of Health, National Library of Medicine and National Eye Institute. 122 | 123 | 124 | Citing DeepSeeNet 125 | ================= 126 | 127 | If you're running the DeepSeeNet framework, please cite: 128 | 129 | * Peng Y*, Dharssi S*, Chen Q, Keenan T, Agron E, Wong W, Chew E, Lu Z. DeepSeeNet: A deep learning model for automated classification of patientbased age-related macular degeneration severity from color fundus photographs. Ophthalmology. 2019. 126(4), 565-575. 130 | 131 | * Keenan T*, Dharssi S*, Peng Y*, Chen Q, Agron E, Wong W, Lu Z, Chew E. A deep learning approach for automated detection of geographic atrophy from color fundus photographs. Ophthalmology. 2019 (Accepted). 132 | 133 | 134 | NCBI's Disclaimer 135 | ================= 136 | 137 | This tool shows the results of research conducted in the `Computational Biology Branch `_, `NCBI `_. 138 | 139 | The information produced on this website is not intended for direct diagnostic use or medical decision-making without review and oversight by a clinical professional. Individuals should not change their health behavior solely on the basis of information produced on this website. NIH does not independently verify the validity or utility of the information produced by this tool. If you have questions about the information produced on this website, please see a health care professional. 140 | 141 | More information about `NCBI's disclaimer policy `_ is available. 142 | 143 | About `text mining group `_. 144 | 145 | For Research Use Only 146 | ===================== 147 | 148 | The performance characteristics of this product have not been evaluated by the Food and Drug Administration and is not intended for commercial use or purposes beyond research use only. 149 | 150 | 151 | -------------------------------------------------------------------------------- /data/left_eye.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncbi-nlp/DeepSeeNet/fb0c3a3d907756abf6f4a2d3a7f58a37d864b4a9/data/left_eye.jpg -------------------------------------------------------------------------------- /data/pigment_label_sample.csv: -------------------------------------------------------------------------------- 1 | 51003/QUA/51003 QUA F2 RE LS.jpg,0 2 | 51003/QUA/51003 QUA F2 LE LS.jpg,0 3 | 51003/04/51003 04 F2 RE LS.jpg,0 4 | 51003/04/51003 04 F2 LE LS.jpg,0 5 | 51003/06/51003 06 F2 RE LS.jpg,0 6 | 51003/06/51003 06 F2 LE LS.jpg,0 7 | 51003/08/51003 08 F2 RE LS.jpg,0 8 | 51003/08/51003 08 F2 LE LS.jpg,0 9 | 51003/10/51003 10 F2 RE LS.jpg,0 10 | 51003/10/51003 10 F2 LE LS.jpg,0 11 | 51003/12/51003 12 F2 RE LS.jpg,0 12 | 51003/12/51003 12 F2 LE LS.jpg,0 13 | 51003/14/51003 14 F2 RE LS.jpg,0 14 | 51003/14/51003 14 F2 LE LS.jpg,0 15 | 51003/18/51003 18 F2 RE LS.jpg,0 16 | 51003/18/51003 18 F2 LE LS.jpg,0 17 | 51003/20/51003 20 F2 RE LS.jpg,0 18 | 51003/20/51003 20 F2 LE LS.jpg,0 19 | 51003/22/51003 22 F2 RE LS.jpg,0 20 | 51003/22/51003 22 F2 LE LS.jpg,0 21 | 51008/QUA/51008 QUA F2 RE LS.jpg,0 22 | 51008/QUA/51008 QUA F2 LE LS.jpg,0 23 | 51008/06/51008 06 F2 RE LS.jpg,0 24 | 51008/06/51008 06 F2 LE LS.jpg,0 25 | 51008/08/51008 08 F2 RE LS.jpg,0 26 | 51008/08/51008 08 F2 LE LS.jpg,0 27 | 51008/20/51008 20 F2 RE LS.jpg,1 28 | 51008/20/51008 20 F2 LE LS.jpg,1 29 | 51011/QUA/51011 QUA F2 RE LS.jpg,0 30 | 51011/QUA/51011 QUA F2 LE LS.jpg,0 31 | 51017/QUA/51017 QUA F2 LE LS.jpg,1 32 | 51018/QUA/51018 QUA F2 RE LS.jpg,0 33 | 51018/QUA/51018 QUA F2 LE LS.jpg,0 34 | 51018/04/51018 04 F2 RE LS.jpg,0 35 | 51018/04/51018 04 F2 LE LS.jpg,0 36 | 51018/06/51018 06 F2 RE LS.jpg,0 37 | 51018/06/51018 06 F2 LE LS.jpg,0 38 | 51018/08/51018 08 F2 RE LS.jpg,0 39 | 51018/08/51018 08 F2 LE LS.jpg,0 40 | 51018/10/51018 10 F2 RE LS.jpg,0 41 | 51018/10/51018 10 F2 LE LS.jpg,0 42 | 51018/12/51018 12 F2 RE LS.jpg,0 43 | 51018/12/51018 12 F2 LE LS.jpg,0 44 | 51018/16/51018 16 F2 RE LS.jpg,0 45 | 51018/16/51018 16 F2 LE LS.jpg,0 46 | 51018/18/51018 18 F2 RE LS.jpg,1 47 | 51018/18/51018 18 F2 LE LS.jpg,1 48 | 51018/20/51018 20 F2 RE LS.jpg,0 49 | 51018/20/51018 20 F2 LE LS.jpg,0 50 | 51019/QUA/51019 QUA F2 RE LS.jpg,0 51 | -------------------------------------------------------------------------------- /data/right_eye.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncbi-nlp/DeepSeeNet/fb0c3a3d907756abf6f4a2d3a7f58a37d864b4a9/data/right_eye.jpg -------------------------------------------------------------------------------- /data/test_set_patients.txt: -------------------------------------------------------------------------------- 1 | 51008 2 | 51018 3 | 51036 4 | 51074 5 | 51103 6 | 51133 7 | 51189 8 | 51213 9 | 51218 10 | 51222 11 | 51238 12 | 51243 13 | 51248 14 | 51290 15 | 51313 16 | 51317 17 | 51322 18 | 51328 19 | 51340 20 | 51410 21 | 51428 22 | 51480 23 | 51536 24 | 51537 25 | 51541 26 | 51551 27 | 51554 28 | 51559 29 | 51566 30 | 51569 31 | 51570 32 | 51580 33 | 51631 34 | 51647 35 | 51649 36 | 51690 37 | 51694 38 | 51698 39 | 51703 40 | 51712 41 | 51713 42 | 51717 43 | 51730 44 | 51737 45 | 51742 46 | 51743 47 | 51757 48 | 51762 49 | 52085 50 | 52086 51 | 52088 52 | 52106 53 | 52127 54 | 52129 55 | 52135 56 | 52143 57 | 52166 58 | 52173 59 | 52187 60 | 52194 61 | 52224 62 | 52226 63 | 52230 64 | 52242 65 | 52279 66 | 52283 67 | 52305 68 | 52314 69 | 52323 70 | 52337 71 | 52340 72 | 52435 73 | 52439 74 | 52516 75 | 52529 76 | 52561 77 | 52601 78 | 52637 79 | 52657 80 | 52673 81 | 52682 82 | 52690 83 | 52696 84 | 52726 85 | 52742 86 | 52761 87 | 52765 88 | 52827 89 | 52828 90 | 52832 91 | 52836 92 | 52870 93 | 52912 94 | 52914 95 | 52915 96 | 52923 97 | 52942 98 | 52946 99 | 52947 100 | 53003 101 | 53038 102 | 53040 103 | 53045 104 | 53124 105 | 53198 106 | 53203 107 | 53219 108 | 53236 109 | 53243 110 | 53245 111 | 53248 112 | 53259 113 | 53267 114 | 53309 115 | 53314 116 | 53347 117 | 53348 118 | 53370 119 | 53377 120 | 53428 121 | 53437 122 | 53441 123 | 53453 124 | 53478 125 | 53481 126 | 53497 127 | 53498 128 | 53503 129 | 53523 130 | 53529 131 | 53538 132 | 53558 133 | 53577 134 | 53579 135 | 53594 136 | 53610 137 | 53639 138 | 53640 139 | 53650 140 | 53658 141 | 53682 142 | 53691 143 | 53737 144 | 53747 145 | 53810 146 | 53811 147 | 53836 148 | 53850 149 | 53855 150 | 53857 151 | 54007 152 | 54014 153 | 54095 154 | 54097 155 | 54098 156 | 54101 157 | 54109 158 | 54112 159 | 54116 160 | 54206 161 | 54241 162 | 54246 163 | 54303 164 | 54318 165 | 54330 166 | 54344 167 | 54347 168 | 54366 169 | 54425 170 | 54433 171 | 54441 172 | 54446 173 | 54516 174 | 54545 175 | 54567 176 | 54569 177 | 54590 178 | 54596 179 | 54610 180 | 54613 181 | 54615 182 | 54640 183 | 54651 184 | 54665 185 | 54718 186 | 54724 187 | 54725 188 | 54735 189 | 54752 190 | 54776 191 | 54777 192 | 54785 193 | 54786 194 | 54788 195 | 54794 196 | 54812 197 | 54830 198 | 54840 199 | 55017 200 | 55057 201 | 55060 202 | 55072 203 | 55080 204 | 55153 205 | 55225 206 | 55233 207 | 55323 208 | 55340 209 | 55354 210 | 55476 211 | 55477 212 | 55478 213 | 55498 214 | 55510 215 | 55533 216 | 55548 217 | 55559 218 | 55563 219 | 55587 220 | 55595 221 | 55612 222 | 55614 223 | 55628 224 | 55642 225 | 55646 226 | 55704 227 | 55717 228 | 55732 229 | 55734 230 | 56041 231 | 56069 232 | 56072 233 | 56093 234 | 56152 235 | 56158 236 | 56178 237 | 56187 238 | 56258 239 | 56266 240 | 56277 241 | 56278 242 | 56338 243 | 56345 244 | 56351 245 | 56356 246 | 56370 247 | 56394 248 | 56416 249 | 56419 250 | 56444 251 | 56456 252 | 56462 253 | 56488 254 | 56498 255 | 56511 256 | 56514 257 | 56516 258 | 56526 259 | 56534 260 | 56559 261 | 56565 262 | 56579 263 | 56588 264 | 56592 265 | 56593 266 | 56595 267 | 56611 268 | 56616 269 | 56625 270 | 56633 271 | 56642 272 | 56647 273 | 56650 274 | 56676 275 | 56706 276 | 56715 277 | 56718 278 | 56748 279 | 56769 280 | 56781 281 | 56809 282 | 56818 283 | 56822 284 | 56842 285 | 56844 286 | 56850 287 | 57015 288 | 57039 289 | 57101 290 | 57102 291 | 57103 292 | 57127 293 | 57151 294 | 57179 295 | 57185 296 | 57192 297 | 57198 298 | 57202 299 | 57217 300 | 57247 301 | 57248 302 | 57255 303 | 57265 304 | 58001 305 | 58014 306 | 58065 307 | 58105 308 | 58112 309 | 58146 310 | 58157 311 | 58194 312 | 58203 313 | 58222 314 | 58264 315 | 58282 316 | 58287 317 | 58302 318 | 58332 319 | 58404 320 | 58410 321 | 58414 322 | 58510 323 | 58514 324 | 58523 325 | 58530 326 | 58536 327 | 58600 328 | 58609 329 | 58620 330 | 58623 331 | 58627 332 | 58634 333 | 58643 334 | 58648 335 | 58657 336 | 58674 337 | 58675 338 | 58680 339 | 58684 340 | 58703 341 | 58706 342 | 58709 343 | 58717 344 | 58727 345 | 58733 346 | 58744 347 | 58757 348 | 58773 349 | 58776 350 | 58784 351 | 58788 352 | 58791 353 | 58806 354 | 58823 355 | 59004 356 | 59012 357 | 59074 358 | 59105 359 | 59108 360 | 59118 361 | 59139 362 | 59203 363 | 59225 364 | 59254 365 | 59305 366 | 59343 367 | 59352 368 | 59399 369 | 59426 370 | 59430 371 | 59438 372 | 59470 373 | 59500 374 | 59567 375 | 59588 376 | 59593 377 | 59605 378 | 59632 379 | 59638 380 | 59646 381 | 59690 382 | 59694 383 | 59700 384 | 59720 385 | 59738 386 | 59753 387 | 59801 388 | 59810 389 | 59830 390 | 59841 391 | 59850 392 | 59865 393 | 59884 394 | 59888 395 | 59896 396 | 59914 397 | 59916 398 | 59926 399 | 59939 400 | 60012 401 | 60056 402 | 60098 403 | 60102 404 | 601032 405 | 60284 406 | 60290 407 | 60343 408 | 60361 409 | 60384 410 | 60394 411 | 60460 412 | 60539 413 | 60609 414 | 60636 415 | 60666 416 | 60693 417 | 60761 418 | 60776 419 | 60778 420 | 60782 421 | 60818 422 | 60827 423 | 60839 424 | 60883 425 | 60888 426 | 60892 427 | 60910 428 | 60923 429 | 60929 430 | 60958 431 | 60966 432 | 60977 433 | 60979 434 | 61011 435 | 61065 436 | 61069 437 | 61074 438 | 61092 439 | 61134 440 | 61153 441 | 61159 442 | 61163 443 | 61170 444 | 61187 445 | 61226 446 | 61245 447 | 61254 448 | 61269 449 | 61281 450 | 61298 -------------------------------------------------------------------------------- /data/training_set_patients.txt: -------------------------------------------------------------------------------- 1 | 51003 2 | 51011 3 | 51019 4 | 51023 5 | 51026 6 | 51027 7 | 51030 8 | 51031 9 | 51034 10 | 51035 11 | 51038 12 | 51045 13 | 51046 14 | 51048 15 | 51051 16 | 51054 17 | 51055 18 | 51056 19 | 51057 20 | 51060 21 | 51062 22 | 51064 23 | 51066 24 | 51070 25 | 51076 26 | 51077 27 | 51078 28 | 51080 29 | 51082 30 | 51083 31 | 51084 32 | 51086 33 | 51091 34 | 51094 35 | 51096 36 | 51097 37 | 51098 38 | 51101 39 | 51107 40 | 51108 41 | 51109 42 | 51110 43 | 51111 44 | 51115 45 | 51117 46 | 51124 47 | 51126 48 | 51128 49 | 51130 50 | 51131 51 | 51132 52 | 51135 53 | 51136 54 | 51137 55 | 51141 56 | 51146 57 | 51149 58 | 51150 59 | 51151 60 | 51153 61 | 51154 62 | 51155 63 | 51158 64 | 51160 65 | 51161 66 | 51162 67 | 51166 68 | 51167 69 | 51171 70 | 51175 71 | 51176 72 | 51177 73 | 51180 74 | 51184 75 | 51188 76 | 51191 77 | 51196 78 | 51197 79 | 51198 80 | 51199 81 | 51200 82 | 51201 83 | 51205 84 | 51210 85 | 51215 86 | 51223 87 | 51226 88 | 51228 89 | 51229 90 | 51231 91 | 51232 92 | 51233 93 | 51235 94 | 51244 95 | 51249 96 | 51250 97 | 51256 98 | 51261 99 | 51262 100 | 51263 101 | 51265 102 | 51266 103 | 51270 104 | 51274 105 | 51275 106 | 51277 107 | 51285 108 | 51288 109 | 51289 110 | 51291 111 | 51293 112 | 51295 113 | 51298 114 | 51301 115 | 51302 116 | 51304 117 | 51314 118 | 51323 119 | 51325 120 | 51326 121 | 51331 122 | 51341 123 | 51342 124 | 51343 125 | 51345 126 | 51350 127 | 51355 128 | 51356 129 | 51362 130 | 51367 131 | 51372 132 | 51373 133 | 51377 134 | 51379 135 | 51382 136 | 51383 137 | 51384 138 | 51385 139 | 51386 140 | 51388 141 | 51390 142 | 51396 143 | 51397 144 | 51399 145 | 51400 146 | 51401 147 | 51402 148 | 51404 149 | 51406 150 | 51409 151 | 51411 152 | 51412 153 | 51421 154 | 51427 155 | 51429 156 | 51430 157 | 51431 158 | 51437 159 | 51454 160 | 51455 161 | 51457 162 | 51458 163 | 51459 164 | 51465 165 | 51467 166 | 51477 167 | 51481 168 | 51482 169 | 51488 170 | 51489 171 | 51491 172 | 51492 173 | 51500 174 | 51501 175 | 51505 176 | 51509 177 | 51513 178 | 51514 179 | 51518 180 | 51521 181 | 51529 182 | 51535 183 | 51538 184 | 51542 185 | 51544 186 | 51548 187 | 51549 188 | 51553 189 | 51558 190 | 51562 191 | 51563 192 | 51565 193 | 51568 194 | 51571 195 | 51572 196 | 51573 197 | 51574 198 | 51575 199 | 51576 200 | 51577 201 | 51578 202 | 51579 203 | 51581 204 | 51582 205 | 51583 206 | 51585 207 | 51587 208 | 51588 209 | 51590 210 | 51591 211 | 51593 212 | 51595 213 | 51597 214 | 51598 215 | 51602 216 | 51604 217 | 51605 218 | 51606 219 | 51607 220 | 51608 221 | 51610 222 | 51611 223 | 51612 224 | 51613 225 | 51614 226 | 51616 227 | 51617 228 | 51618 229 | 51619 230 | 51620 231 | 51622 232 | 51623 233 | 51624 234 | 51625 235 | 51626 236 | 51629 237 | 51630 238 | 51632 239 | 51635 240 | 51636 241 | 51638 242 | 51639 243 | 51640 244 | 51642 245 | 51644 246 | 51645 247 | 51646 248 | 51650 249 | 51651 250 | 51652 251 | 51654 252 | 51655 253 | 51658 254 | 51659 255 | 51660 256 | 51661 257 | 51662 258 | 51663 259 | 51664 260 | 51666 261 | 51669 262 | 51671 263 | 51673 264 | 51675 265 | 51676 266 | 51678 267 | 51680 268 | 51682 269 | 51685 270 | 51686 271 | 51687 272 | 51688 273 | 51689 274 | 51691 275 | 51693 276 | 51695 277 | 51697 278 | 51700 279 | 51701 280 | 51702 281 | 51704 282 | 51705 283 | 51706 284 | 51707 285 | 51708 286 | 51709 287 | 51711 288 | 51714 289 | 51716 290 | 51718 291 | 51721 292 | 51722 293 | 51723 294 | 51724 295 | 51725 296 | 51728 297 | 51729 298 | 51731 299 | 51732 300 | 51733 301 | 51734 302 | 51736 303 | 51738 304 | 51739 305 | 51740 306 | 51744 307 | 51745 308 | 51746 309 | 51747 310 | 51748 311 | 51749 312 | 51750 313 | 51751 314 | 51752 315 | 51753 316 | 51754 317 | 51755 318 | 51756 319 | 51758 320 | 51759 321 | 51760 322 | 51761 323 | 51764 324 | 51767 325 | 51768 326 | 51770 327 | 51771 328 | 51772 329 | 51773 330 | 51774 331 | 51775 332 | 51776 333 | 51777 334 | 51779 335 | 51780 336 | 51781 337 | 51784 338 | 51785 339 | 51787 340 | 51788 341 | 51789 342 | 51790 343 | 51791 344 | 51792 345 | 51794 346 | 51795 347 | 51796 348 | 51798 349 | 51799 350 | 51800 351 | 51802 352 | 52001 353 | 52004 354 | 52012 355 | 52014 356 | 52018 357 | 52019 358 | 52020 359 | 52024 360 | 52025 361 | 52027 362 | 52030 363 | 52033 364 | 52037 365 | 52043 366 | 52044 367 | 52049 368 | 52050 369 | 52052 370 | 52054 371 | 52058 372 | 52059 373 | 52060 374 | 52063 375 | 52067 376 | 52068 377 | 52070 378 | 52074 379 | 52075 380 | 52077 381 | 52081 382 | 52084 383 | 52087 384 | 52090 385 | 52093 386 | 52094 387 | 52095 388 | 52096 389 | 52098 390 | 52105 391 | 52109 392 | 52111 393 | 52112 394 | 52114 395 | 52116 396 | 52117 397 | 52119 398 | 52130 399 | 52134 400 | 52136 401 | 52139 402 | 52140 403 | 52144 404 | 52146 405 | 52161 406 | 52169 407 | 52172 408 | 52181 409 | 52183 410 | 52184 411 | 52186 412 | 52190 413 | 52191 414 | 52197 415 | 52202 416 | 52206 417 | 52207 418 | 52212 419 | 52215 420 | 52217 421 | 52218 422 | 52219 423 | 52220 424 | 52229 425 | 52231 426 | 52232 427 | 52234 428 | 52237 429 | 52245 430 | 52248 431 | 52250 432 | 52251 433 | 52255 434 | 52256 435 | 52258 436 | 52261 437 | 52262 438 | 52265 439 | 52266 440 | 52271 441 | 52275 442 | 52286 443 | 52291 444 | 52296 445 | 52297 446 | 52299 447 | 52308 448 | 52309 449 | 52310 450 | 52325 451 | 52330 452 | 52333 453 | 52338 454 | 52341 455 | 52342 456 | 52346 457 | 52348 458 | 52350 459 | 52352 460 | 52359 461 | 52360 462 | 52362 463 | 52367 464 | 52368 465 | 52369 466 | 52370 467 | 52371 468 | 52372 469 | 52373 470 | 52375 471 | 52376 472 | 52377 473 | 52378 474 | 52379 475 | 52380 476 | 52384 477 | 52385 478 | 52386 479 | 52387 480 | 52388 481 | 52389 482 | 52390 483 | 52391 484 | 52396 485 | 52397 486 | 52401 487 | 52403 488 | 52405 489 | 52406 490 | 52408 491 | 52409 492 | 52416 493 | 52419 494 | 52421 495 | 52423 496 | 52424 497 | 52425 498 | 52426 499 | 52430 500 | 52431 501 | 52436 502 | 52437 503 | 52438 504 | 52442 505 | 52444 506 | 52450 507 | 52454 508 | 52455 509 | 52461 510 | 52463 511 | 52467 512 | 52468 513 | 52470 514 | 52472 515 | 52475 516 | 52477 517 | 52479 518 | 52481 519 | 52482 520 | 52483 521 | 52485 522 | 52493 523 | 52494 524 | 52497 525 | 52499 526 | 52502 527 | 52503 528 | 52504 529 | 52506 530 | 52508 531 | 52510 532 | 52511 533 | 52512 534 | 52513 535 | 52521 536 | 52527 537 | 52530 538 | 52532 539 | 52534 540 | 52535 541 | 52536 542 | 52539 543 | 52542 544 | 52543 545 | 52546 546 | 52548 547 | 52549 548 | 52550 549 | 52552 550 | 52554 551 | 52556 552 | 52558 553 | 52559 554 | 52560 555 | 52562 556 | 52563 557 | 52565 558 | 52569 559 | 52570 560 | 52573 561 | 52575 562 | 52577 563 | 52578 564 | 52580 565 | 52583 566 | 52585 567 | 52586 568 | 52587 569 | 52588 570 | 52590 571 | 52591 572 | 52593 573 | 52594 574 | 52595 575 | 52598 576 | 52599 577 | 52600 578 | 52602 579 | 52603 580 | 52604 581 | 52606 582 | 52609 583 | 52610 584 | 52612 585 | 52613 586 | 52615 587 | 52616 588 | 52620 589 | 52621 590 | 52626 591 | 52630 592 | 52631 593 | 52633 594 | 52634 595 | 52635 596 | 52636 597 | 52638 598 | 52639 599 | 52640 600 | 52641 601 | 52642 602 | 52643 603 | 52644 604 | 52646 605 | 52648 606 | 52649 607 | 52651 608 | 52653 609 | 52654 610 | 52655 611 | 52656 612 | 52659 613 | 52660 614 | 52661 615 | 52662 616 | 52663 617 | 52666 618 | 52667 619 | 52668 620 | 52670 621 | 52671 622 | 52672 623 | 52674 624 | 52679 625 | 52680 626 | 52681 627 | 52685 628 | 52686 629 | 52691 630 | 52692 631 | 52694 632 | 52699 633 | 52701 634 | 52703 635 | 52704 636 | 52705 637 | 52708 638 | 52709 639 | 52710 640 | 52711 641 | 52712 642 | 52713 643 | 52715 644 | 52717 645 | 52718 646 | 52719 647 | 52720 648 | 52722 649 | 52723 650 | 52724 651 | 52730 652 | 52731 653 | 52732 654 | 52734 655 | 52735 656 | 52736 657 | 52738 658 | 52739 659 | 52740 660 | 52741 661 | 52744 662 | 52745 663 | 52746 664 | 52747 665 | 52748 666 | 52749 667 | 52750 668 | 52751 669 | 52752 670 | 52753 671 | 52754 672 | 52756 673 | 52757 674 | 52758 675 | 52759 676 | 52760 677 | 52762 678 | 52766 679 | 52767 680 | 52801 681 | 52802 682 | 52803 683 | 52805 684 | 52806 685 | 52808 686 | 52809 687 | 52810 688 | 52811 689 | 52812 690 | 52814 691 | 52815 692 | 52816 693 | 52817 694 | 52819 695 | 52821 696 | 52822 697 | 52823 698 | 52824 699 | 52831 700 | 52834 701 | 52837 702 | 52839 703 | 52841 704 | 52842 705 | 52843 706 | 52844 707 | 52846 708 | 52849 709 | 52851 710 | 52852 711 | 52853 712 | 52854 713 | 52855 714 | 52856 715 | 52857 716 | 52862 717 | 52863 718 | 52864 719 | 52865 720 | 52866 721 | 52868 722 | 52869 723 | 52871 724 | 52872 725 | 52873 726 | 52874 727 | 52875 728 | 52876 729 | 52877 730 | 52878 731 | 52879 732 | 52880 733 | 52881 734 | 52882 735 | 52883 736 | 52884 737 | 52885 738 | 52886 739 | 52887 740 | 52888 741 | 52891 742 | 52892 743 | 52893 744 | 52894 745 | 52895 746 | 52896 747 | 52897 748 | 52899 749 | 52900 750 | 52901 751 | 52902 752 | 52904 753 | 52907 754 | 52908 755 | 52909 756 | 52910 757 | 52911 758 | 52913 759 | 52916 760 | 52919 761 | 52920 762 | 52921 763 | 52922 764 | 52927 765 | 52928 766 | 52929 767 | 52930 768 | 52931 769 | 52932 770 | 52935 771 | 52936 772 | 52937 773 | 52938 774 | 52940 775 | 52943 776 | 52944 777 | 52948 778 | 53002 779 | 53004 780 | 53006 781 | 53010 782 | 53011 783 | 53013 784 | 53016 785 | 53018 786 | 53026 787 | 53027 788 | 53028 789 | 53030 790 | 53032 791 | 53037 792 | 53039 793 | 53046 794 | 53047 795 | 53051 796 | 53053 797 | 53054 798 | 53056 799 | 53057 800 | 53058 801 | 53061 802 | 53065 803 | 53066 804 | 53069 805 | 53077 806 | 53078 807 | 53079 808 | 53080 809 | 53081 810 | 53082 811 | 53083 812 | 53084 813 | 53085 814 | 53096 815 | 53102 816 | 53104 817 | 53105 818 | 53106 819 | 53108 820 | 53109 821 | 53119 822 | 53122 823 | 53125 824 | 53126 825 | 53128 826 | 53130 827 | 53133 828 | 53135 829 | 53137 830 | 53138 831 | 53141 832 | 53142 833 | 53143 834 | 53149 835 | 53152 836 | 53154 837 | 53155 838 | 53160 839 | 53162 840 | 53163 841 | 53164 842 | 53166 843 | 53168 844 | 53174 845 | 53179 846 | 53182 847 | 53183 848 | 53185 849 | 53186 850 | 53187 851 | 53190 852 | 53191 853 | 53192 854 | 53193 855 | 53194 856 | 53195 857 | 53199 858 | 53202 859 | 53204 860 | 53205 861 | 53208 862 | 53209 863 | 53210 864 | 53214 865 | 53215 866 | 53216 867 | 53217 868 | 53224 869 | 53226 870 | 53227 871 | 53230 872 | 53231 873 | 53233 874 | 53234 875 | 53235 876 | 53237 877 | 53238 878 | 53240 879 | 53244 880 | 53250 881 | 53251 882 | 53252 883 | 53260 884 | 53262 885 | 53263 886 | 53268 887 | 53275 888 | 53276 889 | 53277 890 | 53279 891 | 53281 892 | 53283 893 | 53284 894 | 53285 895 | 53292 896 | 53293 897 | 53295 898 | 53296 899 | 53298 900 | 53300 901 | 53301 902 | 53302 903 | 53303 904 | 53308 905 | 53310 906 | 53311 907 | 53312 908 | 53313 909 | 53315 910 | 53317 911 | 53319 912 | 53320 913 | 53321 914 | 53324 915 | 53328 916 | 53329 917 | 53330 918 | 53331 919 | 53333 920 | 53334 921 | 53336 922 | 53338 923 | 53342 924 | 53343 925 | 53346 926 | 53350 927 | 53351 928 | 53353 929 | 53354 930 | 53356 931 | 53357 932 | 53358 933 | 53359 934 | 53360 935 | 53361 936 | 53364 937 | 53365 938 | 53371 939 | 53373 940 | 53376 941 | 53381 942 | 53386 943 | 53393 944 | 53396 945 | 53398 946 | 53399 947 | 53400 948 | 53403 949 | 53408 950 | 53410 951 | 53415 952 | 53418 953 | 53422 954 | 53424 955 | 53426 956 | 53429 957 | 53430 958 | 53431 959 | 53432 960 | 53435 961 | 53436 962 | 53440 963 | 53442 964 | 53443 965 | 53444 966 | 53451 967 | 53452 968 | 53455 969 | 53456 970 | 53457 971 | 53461 972 | 53462 973 | 53464 974 | 53467 975 | 53469 976 | 53470 977 | 53472 978 | 53473 979 | 53474 980 | 53475 981 | 53483 982 | 53486 983 | 53487 984 | 53488 985 | 53489 986 | 53495 987 | 53496 988 | 53511 989 | 53512 990 | 53514 991 | 53516 992 | 53519 993 | 53521 994 | 53525 995 | 53527 996 | 53528 997 | 53535 998 | 53536 999 | 53537 1000 | 53539 1001 | 53540 1002 | 53546 1003 | 53548 1004 | 53549 1005 | 53550 1006 | 53553 1007 | 53555 1008 | 53559 1009 | 53560 1010 | 53561 1011 | 53562 1012 | 53565 1013 | 53567 1014 | 53570 1015 | 53571 1016 | 53572 1017 | 53573 1018 | 53575 1019 | 53576 1020 | 53578 1021 | 53580 1022 | 53584 1023 | 53585 1024 | 53587 1025 | 53588 1026 | 53589 1027 | 53590 1028 | 53596 1029 | 53597 1030 | 53599 1031 | 53600 1032 | 53601 1033 | 53604 1034 | 53605 1035 | 53606 1036 | 53607 1037 | 53608 1038 | 53609 1039 | 53612 1040 | 53613 1041 | 53614 1042 | 53615 1043 | 53616 1044 | 53617 1045 | 53618 1046 | 53619 1047 | 53620 1048 | 53621 1049 | 53622 1050 | 53623 1051 | 53624 1052 | 53625 1053 | 53626 1054 | 53627 1055 | 53628 1056 | 53629 1057 | 53631 1058 | 53633 1059 | 53634 1060 | 53635 1061 | 53637 1062 | 53638 1063 | 53641 1064 | 53642 1065 | 53644 1066 | 53645 1067 | 53646 1068 | 53647 1069 | 53648 1070 | 53651 1071 | 53652 1072 | 53654 1073 | 53659 1074 | 53660 1075 | 53661 1076 | 53662 1077 | 53663 1078 | 53664 1079 | 53666 1080 | 53667 1081 | 53669 1082 | 53670 1083 | 53671 1084 | 53672 1085 | 53673 1086 | 53674 1087 | 53675 1088 | 53676 1089 | 53677 1090 | 53680 1091 | 53681 1092 | 53683 1093 | 53685 1094 | 53689 1095 | 53690 1096 | 53693 1097 | 53695 1098 | 53696 1099 | 53697 1100 | 53698 1101 | 53699 1102 | 53700 1103 | 53701 1104 | 53702 1105 | 53705 1106 | 53706 1107 | 53707 1108 | 53708 1109 | 53709 1110 | 53710 1111 | 53711 1112 | 53712 1113 | 53713 1114 | 53714 1115 | 53715 1116 | 53716 1117 | 53718 1118 | 53720 1119 | 53721 1120 | 53722 1121 | 53726 1122 | 53727 1123 | 53728 1124 | 53729 1125 | 53730 1126 | 53731 1127 | 53732 1128 | 53733 1129 | 53734 1130 | 53735 1131 | 53736 1132 | 53738 1133 | 53741 1134 | 53743 1135 | 53745 1136 | 53748 1137 | 53749 1138 | 53750 1139 | 53751 1140 | 53752 1141 | 53754 1142 | 53755 1143 | 53756 1144 | 53757 1145 | 53761 1146 | 53762 1147 | 53763 1148 | 53764 1149 | 53765 1150 | 53766 1151 | 53767 1152 | 53768 1153 | 53803 1154 | 53804 1155 | 53805 1156 | 53806 1157 | 53807 1158 | 53808 1159 | 53809 1160 | 53812 1161 | 53814 1162 | 53815 1163 | 53817 1164 | 53818 1165 | 53820 1166 | 53821 1167 | 53822 1168 | 53823 1169 | 53824 1170 | 53825 1171 | 53826 1172 | 53827 1173 | 53828 1174 | 53832 1175 | 53834 1176 | 53835 1177 | 53838 1178 | 53839 1179 | 53840 1180 | 53842 1181 | 53843 1182 | 53844 1183 | 53847 1184 | 53848 1185 | 53849 1186 | 53851 1187 | 53852 1188 | 53853 1189 | 53854 1190 | 53856 1191 | 53858 1192 | 53859 1193 | 53860 1194 | 53861 1195 | 53862 1196 | 53863 1197 | 53865 1198 | 53866 1199 | 53867 1200 | 53868 1201 | 53869 1202 | 53870 1203 | 53871 1204 | 53872 1205 | 53873 1206 | 53875 1207 | 53876 1208 | 53877 1209 | 53878 1210 | 54002 1211 | 54004 1212 | 54011 1213 | 54012 1214 | 54015 1215 | 54016 1216 | 54020 1217 | 54023 1218 | 54024 1219 | 54025 1220 | 54030 1221 | 54032 1222 | 54033 1223 | 54036 1224 | 54040 1225 | 54041 1226 | 54043 1227 | 54044 1228 | 54045 1229 | 54050 1230 | 54058 1231 | 54061 1232 | 54062 1233 | 54063 1234 | 54066 1235 | 54067 1236 | 54069 1237 | 54072 1238 | 54086 1239 | 54088 1240 | 54092 1241 | 54094 1242 | 54096 1243 | 54103 1244 | 54110 1245 | 54113 1246 | 54115 1247 | 54119 1248 | 54120 1249 | 54123 1250 | 54127 1251 | 54128 1252 | 54130 1253 | 54131 1254 | 54134 1255 | 54137 1256 | 54140 1257 | 54143 1258 | 54146 1259 | 54150 1260 | 54154 1261 | 54158 1262 | 54160 1263 | 54161 1264 | 54165 1265 | 54169 1266 | 54170 1267 | 54172 1268 | 54173 1269 | 54174 1270 | 54179 1271 | 54180 1272 | 54182 1273 | 54183 1274 | 54184 1275 | 54185 1276 | 54187 1277 | 54196 1278 | 54198 1279 | 54199 1280 | 54202 1281 | 54203 1282 | 54205 1283 | 54214 1284 | 54222 1285 | 54232 1286 | 54233 1287 | 54235 1288 | 54236 1289 | 54237 1290 | 54242 1291 | 54245 1292 | 54247 1293 | 54250 1294 | 54256 1295 | 54257 1296 | 54262 1297 | 54263 1298 | 54264 1299 | 54265 1300 | 54271 1301 | 54274 1302 | 54275 1303 | 54279 1304 | 54280 1305 | 54283 1306 | 54284 1307 | 54289 1308 | 54291 1309 | 54292 1310 | 54299 1311 | 54301 1312 | 54307 1313 | 54309 1314 | 54316 1315 | 54317 1316 | 54321 1317 | 54322 1318 | 54324 1319 | 54325 1320 | 54326 1321 | 54328 1322 | 54329 1323 | 54336 1324 | 54337 1325 | 54338 1326 | 54339 1327 | 54341 1328 | 54346 1329 | 54357 1330 | 54361 1331 | 54362 1332 | 54363 1333 | 54365 1334 | 54367 1335 | 54369 1336 | 54375 1337 | 54376 1338 | 54377 1339 | 54379 1340 | 54381 1341 | 54382 1342 | 54387 1343 | 54390 1344 | 54396 1345 | 54398 1346 | 54399 1347 | 54404 1348 | 54409 1349 | 54410 1350 | 54414 1351 | 54416 1352 | 54418 1353 | 54424 1354 | 54428 1355 | 54435 1356 | 54440 1357 | 54444 1358 | 54448 1359 | 54449 1360 | 54452 1361 | 54457 1362 | 54459 1363 | 54460 1364 | 54465 1365 | 54466 1366 | 54467 1367 | 54468 1368 | 54471 1369 | 54475 1370 | 54480 1371 | 54482 1372 | 54483 1373 | 54484 1374 | 54485 1375 | 54487 1376 | 54488 1377 | 54490 1378 | 54491 1379 | 54492 1380 | 54496 1381 | 54497 1382 | 54499 1383 | 54500 1384 | 54501 1385 | 54502 1386 | 54503 1387 | 54504 1388 | 54506 1389 | 54508 1390 | 54509 1391 | 54511 1392 | 54512 1393 | 54513 1394 | 54515 1395 | 54518 1396 | 54521 1397 | 54522 1398 | 54523 1399 | 54524 1400 | 54525 1401 | 54526 1402 | 54527 1403 | 54529 1404 | 54530 1405 | 54531 1406 | 54532 1407 | 54534 1408 | 54535 1409 | 54536 1410 | 54537 1411 | 54538 1412 | 54541 1413 | 54542 1414 | 54543 1415 | 54544 1416 | 54546 1417 | 54548 1418 | 54549 1419 | 54550 1420 | 54551 1421 | 54552 1422 | 54556 1423 | 54557 1424 | 54558 1425 | 54559 1426 | 54560 1427 | 54561 1428 | 54562 1429 | 54564 1430 | 54565 1431 | 54566 1432 | 54570 1433 | 54572 1434 | 54573 1435 | 54576 1436 | 54580 1437 | 54581 1438 | 54582 1439 | 54584 1440 | 54585 1441 | 54587 1442 | 54588 1443 | 54589 1444 | 54591 1445 | 54592 1446 | 54593 1447 | 54594 1448 | 54595 1449 | 54599 1450 | 54601 1451 | 54602 1452 | 54606 1453 | 54607 1454 | 54611 1455 | 54612 1456 | 54617 1457 | 54618 1458 | 54619 1459 | 54621 1460 | 54622 1461 | 54623 1462 | 54624 1463 | 54625 1464 | 54626 1465 | 54628 1466 | 54629 1467 | 54630 1468 | 54631 1469 | 54632 1470 | 54633 1471 | 54634 1472 | 54635 1473 | 54636 1474 | 54637 1475 | 54639 1476 | 54641 1477 | 54642 1478 | 54643 1479 | 54644 1480 | 54646 1481 | 54648 1482 | 54649 1483 | 54650 1484 | 54654 1485 | 54655 1486 | 54656 1487 | 54659 1488 | 54660 1489 | 54662 1490 | 54663 1491 | 54664 1492 | 54666 1493 | 54667 1494 | 54670 1495 | 54672 1496 | 54673 1497 | 54674 1498 | 54675 1499 | 54677 1500 | 54679 1501 | 54681 1502 | 54682 1503 | 54683 1504 | 54686 1505 | 54688 1506 | 54689 1507 | 54691 1508 | 54694 1509 | 54695 1510 | 54696 1511 | 54697 1512 | 54698 1513 | 54700 1514 | 54704 1515 | 54705 1516 | 54706 1517 | 54707 1518 | 54708 1519 | 54709 1520 | 54710 1521 | 54711 1522 | 54712 1523 | 54713 1524 | 54714 1525 | 54716 1526 | 54719 1527 | 54726 1528 | 54727 1529 | 54733 1530 | 54736 1531 | 54738 1532 | 54745 1533 | 54746 1534 | 54747 1535 | 54749 1536 | 54750 1537 | 54751 1538 | 54755 1539 | 54756 1540 | 54757 1541 | 54760 1542 | 54762 1543 | 54763 1544 | 54765 1545 | 54766 1546 | 54768 1547 | 54770 1548 | 54771 1549 | 54774 1550 | 54775 1551 | 54779 1552 | 54782 1553 | 54784 1554 | 54787 1555 | 54789 1556 | 54792 1557 | 54795 1558 | 54796 1559 | 54797 1560 | 54799 1561 | 54800 1562 | 54802 1563 | 54806 1564 | 54811 1565 | 54813 1566 | 54815 1567 | 54818 1568 | 54819 1569 | 54823 1570 | 54825 1571 | 54826 1572 | 54827 1573 | 54828 1574 | 54831 1575 | 54834 1576 | 54836 1577 | 54837 1578 | 54838 1579 | 54839 1580 | 54845 1581 | 54846 1582 | 54847 1583 | 54849 1584 | 54850 1585 | 54851 1586 | 54852 1587 | 54853 1588 | 54854 1589 | 54855 1590 | 54856 1591 | 54857 1592 | 54858 1593 | 55008 1594 | 55013 1595 | 55016 1596 | 55024 1597 | 55027 1598 | 55028 1599 | 55033 1600 | 55035 1601 | 55039 1602 | 55047 1603 | 55050 1604 | 55051 1605 | 55054 1606 | 55061 1607 | 55066 1608 | 55071 1609 | 55074 1610 | 55077 1611 | 55078 1612 | 55081 1613 | 55082 1614 | 55084 1615 | 55085 1616 | 55090 1617 | 55098 1618 | 55099 1619 | 55100 1620 | 55106 1621 | 55112 1622 | 55117 1623 | 55118 1624 | 55122 1625 | 55127 1626 | 55134 1627 | 55138 1628 | 55143 1629 | 55154 1630 | 55158 1631 | 55166 1632 | 55168 1633 | 55179 1634 | 55181 1635 | 55183 1636 | 55185 1637 | 55193 1638 | 55196 1639 | 55197 1640 | 55203 1641 | 55205 1642 | 55207 1643 | 55209 1644 | 55213 1645 | 55214 1646 | 55215 1647 | 55216 1648 | 55227 1649 | 55229 1650 | 55236 1651 | 55237 1652 | 55241 1653 | 55243 1654 | 55257 1655 | 55258 1656 | 55267 1657 | 55273 1658 | 55275 1659 | 55279 1660 | 55282 1661 | 55283 1662 | 55289 1663 | 55291 1664 | 55293 1665 | 55295 1666 | 55299 1667 | 55300 1668 | 55301 1669 | 55302 1670 | 55303 1671 | 55317 1672 | 55319 1673 | 55320 1674 | 55327 1675 | 55333 1676 | 55337 1677 | 55339 1678 | 55341 1679 | 55343 1680 | 55346 1681 | 55349 1682 | 55353 1683 | 55355 1684 | 55357 1685 | 55359 1686 | 55360 1687 | 55361 1688 | 55363 1689 | 55365 1690 | 55367 1691 | 55370 1692 | 55372 1693 | 55384 1694 | 55388 1695 | 55389 1696 | 55393 1697 | 55395 1698 | 55399 1699 | 55400 1700 | 55404 1701 | 55408 1702 | 55417 1703 | 55418 1704 | 55420 1705 | 55421 1706 | 55424 1707 | 55426 1708 | 55429 1709 | 55431 1710 | 55433 1711 | 55438 1712 | 55440 1713 | 55441 1714 | 55442 1715 | 55443 1716 | 55444 1717 | 55445 1718 | 55446 1719 | 55448 1720 | 55452 1721 | 55453 1722 | 55454 1723 | 55455 1724 | 55456 1725 | 55458 1726 | 55461 1727 | 55466 1728 | 55468 1729 | 55471 1730 | 55472 1731 | 55473 1732 | 55474 1733 | 55479 1734 | 55480 1735 | 55481 1736 | 55482 1737 | 55483 1738 | 55484 1739 | 55485 1740 | 55486 1741 | 55487 1742 | 55488 1743 | 55490 1744 | 55491 1745 | 55492 1746 | 55493 1747 | 55494 1748 | 55496 1749 | 55497 1750 | 55500 1751 | 55501 1752 | 55502 1753 | 55503 1754 | 55504 1755 | 55507 1756 | 55508 1757 | 55511 1758 | 55516 1759 | 55518 1760 | 55519 1761 | 55521 1762 | 55522 1763 | 55524 1764 | 55525 1765 | 55527 1766 | 55528 1767 | 55530 1768 | 55531 1769 | 55534 1770 | 55535 1771 | 55536 1772 | 55537 1773 | 55538 1774 | 55539 1775 | 55541 1776 | 55543 1777 | 55546 1778 | 55549 1779 | 55550 1780 | 55551 1781 | 55552 1782 | 55553 1783 | 55554 1784 | 55555 1785 | 55557 1786 | 55558 1787 | 55560 1788 | 55561 1789 | 55562 1790 | 55564 1791 | 55565 1792 | 55566 1793 | 55567 1794 | 55569 1795 | 55570 1796 | 55571 1797 | 55572 1798 | 55573 1799 | 55574 1800 | 55576 1801 | 55577 1802 | 55578 1803 | 55579 1804 | 55581 1805 | 55584 1806 | 55585 1807 | 55586 1808 | 55588 1809 | 55589 1810 | 55591 1811 | 55592 1812 | 55593 1813 | 55599 1814 | 55600 1815 | 55601 1816 | 55602 1817 | 55603 1818 | 55604 1819 | 55605 1820 | 55607 1821 | 55608 1822 | 55609 1823 | 55610 1824 | 55611 1825 | 55613 1826 | 55622 1827 | 55623 1828 | 55624 1829 | 55625 1830 | 55626 1831 | 55627 1832 | 55631 1833 | 55634 1834 | 55635 1835 | 55637 1836 | 55639 1837 | 55640 1838 | 55641 1839 | 55643 1840 | 55644 1841 | 55645 1842 | 55647 1843 | 55648 1844 | 55649 1845 | 55651 1846 | 55653 1847 | 55654 1848 | 55656 1849 | 55658 1850 | 55659 1851 | 55660 1852 | 55661 1853 | 55662 1854 | 55663 1855 | 55664 1856 | 55666 1857 | 55667 1858 | 55668 1859 | 55670 1860 | 55676 1861 | 55677 1862 | 55680 1863 | 55681 1864 | 55682 1865 | 55684 1866 | 55685 1867 | 55686 1868 | 55687 1869 | 55688 1870 | 55689 1871 | 55692 1872 | 55693 1873 | 55694 1874 | 55695 1875 | 55696 1876 | 55698 1877 | 55699 1878 | 55700 1879 | 55703 1880 | 55706 1881 | 55708 1882 | 55709 1883 | 55710 1884 | 55712 1885 | 55715 1886 | 55716 1887 | 55719 1888 | 55720 1889 | 55721 1890 | 55724 1891 | 55725 1892 | 55726 1893 | 55727 1894 | 55728 1895 | 55729 1896 | 55731 1897 | 55735 1898 | 55737 1899 | 55738 1900 | 55739 1901 | 55740 1902 | 55741 1903 | 56001 1904 | 56004 1905 | 56006 1906 | 56007 1907 | 56009 1908 | 56010 1909 | 56013 1910 | 56014 1911 | 56021 1912 | 56023 1913 | 56024 1914 | 56039 1915 | 56042 1916 | 56043 1917 | 56044 1918 | 56046 1919 | 56050 1920 | 56052 1921 | 56053 1922 | 56056 1923 | 56060 1924 | 56061 1925 | 56062 1926 | 56065 1927 | 56067 1928 | 56068 1929 | 56070 1930 | 56073 1931 | 56076 1932 | 56080 1933 | 56085 1934 | 56086 1935 | 56087 1936 | 56088 1937 | 56091 1938 | 56092 1939 | 56096 1940 | 56100 1941 | 56101 1942 | 56103 1943 | 56104 1944 | 56107 1945 | 56111 1946 | 56112 1947 | 56116 1948 | 56118 1949 | 56119 1950 | 56120 1951 | 56122 1952 | 56128 1953 | 56131 1954 | 56132 1955 | 56134 1956 | 56135 1957 | 56136 1958 | 56139 1959 | 56140 1960 | 56142 1961 | 56143 1962 | 56144 1963 | 56148 1964 | 56150 1965 | 56151 1966 | 56153 1967 | 56154 1968 | 56156 1969 | 56160 1970 | 56161 1971 | 56162 1972 | 56163 1973 | 56164 1974 | 56165 1975 | 56166 1976 | 56168 1977 | 56170 1978 | 56171 1979 | 56176 1980 | 56177 1981 | 56189 1982 | 56190 1983 | 56192 1984 | 56193 1985 | 56196 1986 | 56198 1987 | 56199 1988 | 56200 1989 | 56201 1990 | 56202 1991 | 56203 1992 | 56206 1993 | 56210 1994 | 56211 1995 | 56213 1996 | 56215 1997 | 56216 1998 | 56217 1999 | 56220 2000 | 56222 2001 | 56223 2002 | 56224 2003 | 56227 2004 | 56230 2005 | 56232 2006 | 56234 2007 | 56237 2008 | 56242 2009 | 56246 2010 | 56250 2011 | 56253 2012 | 56254 2013 | 56255 2014 | 56260 2015 | 56262 2016 | 56270 2017 | 56271 2018 | 56274 2019 | 56276 2020 | 56279 2021 | 56280 2022 | 56281 2023 | 56287 2024 | 56288 2025 | 56291 2026 | 56292 2027 | 56293 2028 | 56298 2029 | 56300 2030 | 56303 2031 | 56304 2032 | 56306 2033 | 56308 2034 | 56309 2035 | 56318 2036 | 56319 2037 | 56321 2038 | 56325 2039 | 56327 2040 | 56328 2041 | 56329 2042 | 56333 2043 | 56337 2044 | 56340 2045 | 56341 2046 | 56342 2047 | 56344 2048 | 56349 2049 | 56352 2050 | 56354 2051 | 56355 2052 | 56358 2053 | 56360 2054 | 56362 2055 | 56363 2056 | 56365 2057 | 56368 2058 | 56372 2059 | 56373 2060 | 56376 2061 | 56378 2062 | 56380 2063 | 56382 2064 | 56383 2065 | 56384 2066 | 56388 2067 | 56391 2068 | 56393 2069 | 56398 2070 | 56400 2071 | 56401 2072 | 56405 2073 | 56407 2074 | 56409 2075 | 56410 2076 | 56411 2077 | 56412 2078 | 56414 2079 | 56420 2080 | 56423 2081 | 56424 2082 | 56426 2083 | 56429 2084 | 56432 2085 | 56433 2086 | 56435 2087 | 56436 2088 | 56437 2089 | 56439 2090 | 56441 2091 | 56443 2092 | 56446 2093 | 56448 2094 | 56449 2095 | 56450 2096 | 56451 2097 | 56455 2098 | 56457 2099 | 56458 2100 | 56461 2101 | 56463 2102 | 56465 2103 | 56466 2104 | 56467 2105 | 56469 2106 | 56472 2107 | 56473 2108 | 56477 2109 | 56479 2110 | 56480 2111 | 56481 2112 | 56482 2113 | 56483 2114 | 56484 2115 | 56486 2116 | 56487 2117 | 56489 2118 | 56491 2119 | 56493 2120 | 56495 2121 | 56496 2122 | 56497 2123 | 56503 2124 | 56504 2125 | 56507 2126 | 56508 2127 | 56510 2128 | 56513 2129 | 56518 2130 | 56519 2131 | 56523 2132 | 56524 2133 | 56525 2134 | 56527 2135 | 56529 2136 | 56532 2137 | 56535 2138 | 56536 2139 | 56537 2140 | 56538 2141 | 56539 2142 | 56540 2143 | 56541 2144 | 56544 2145 | 56545 2146 | 56546 2147 | 56547 2148 | 56548 2149 | 56550 2150 | 56551 2151 | 56553 2152 | 56555 2153 | 56560 2154 | 56561 2155 | 56562 2156 | 56564 2157 | 56566 2158 | 56567 2159 | 56569 2160 | 56571 2161 | 56573 2162 | 56576 2163 | 56577 2164 | 56578 2165 | 56580 2166 | 56581 2167 | 56582 2168 | 56585 2169 | 56586 2170 | 56589 2171 | 56590 2172 | 56591 2173 | 56594 2174 | 56597 2175 | 56598 2176 | 56599 2177 | 56600 2178 | 56601 2179 | 56602 2180 | 56603 2181 | 56604 2182 | 56606 2183 | 56607 2184 | 56608 2185 | 56609 2186 | 56610 2187 | 56613 2188 | 56614 2189 | 56615 2190 | 56617 2191 | 56618 2192 | 56619 2193 | 56620 2194 | 56621 2195 | 56623 2196 | 56626 2197 | 56628 2198 | 56629 2199 | 56631 2200 | 56632 2201 | 56634 2202 | 56635 2203 | 56636 2204 | 56637 2205 | 56638 2206 | 56639 2207 | 56640 2208 | 56643 2209 | 56646 2210 | 56651 2211 | 56652 2212 | 56654 2213 | 56655 2214 | 56656 2215 | 56657 2216 | 56658 2217 | 56661 2218 | 56662 2219 | 56664 2220 | 56665 2221 | 56667 2222 | 56669 2223 | 56670 2224 | 56673 2225 | 56674 2226 | 56675 2227 | 56678 2228 | 56679 2229 | 56680 2230 | 56681 2231 | 56682 2232 | 56684 2233 | 56685 2234 | 56686 2235 | 56687 2236 | 56689 2237 | 56690 2238 | 56691 2239 | 56694 2240 | 56695 2241 | 56696 2242 | 56697 2243 | 56698 2244 | 56699 2245 | 56700 2246 | 56702 2247 | 56705 2248 | 56707 2249 | 56708 2250 | 56710 2251 | 56711 2252 | 56712 2253 | 56713 2254 | 56714 2255 | 56716 2256 | 56719 2257 | 56720 2258 | 56721 2259 | 56722 2260 | 56723 2261 | 56724 2262 | 56725 2263 | 56726 2264 | 56727 2265 | 56728 2266 | 56729 2267 | 56730 2268 | 56731 2269 | 56732 2270 | 56734 2271 | 56735 2272 | 56736 2273 | 56737 2274 | 56740 2275 | 56741 2276 | 56742 2277 | 56743 2278 | 56744 2279 | 56747 2280 | 56749 2281 | 56752 2282 | 56753 2283 | 56754 2284 | 56757 2285 | 56759 2286 | 56760 2287 | 56761 2288 | 56763 2289 | 56764 2290 | 56766 2291 | 56767 2292 | 56768 2293 | 56770 2294 | 56771 2295 | 56772 2296 | 56773 2297 | 56774 2298 | 56776 2299 | 56777 2300 | 56780 2301 | 56784 2302 | 56785 2303 | 56786 2304 | 56787 2305 | 56789 2306 | 56790 2307 | 56791 2308 | 56792 2309 | 56794 2310 | 56796 2311 | 56798 2312 | 56799 2313 | 56800 2314 | 56801 2315 | 56805 2316 | 56807 2317 | 56808 2318 | 56810 2319 | 56811 2320 | 56812 2321 | 56813 2322 | 56814 2323 | 56816 2324 | 56817 2325 | 56819 2326 | 56820 2327 | 56821 2328 | 56824 2329 | 56825 2330 | 56826 2331 | 56829 2332 | 56830 2333 | 56831 2334 | 56835 2335 | 56837 2336 | 56838 2337 | 56840 2338 | 56843 2339 | 56846 2340 | 56847 2341 | 56848 2342 | 56851 2343 | 56853 2344 | 56854 2345 | 56855 2346 | 57001 2347 | 57004 2348 | 57007 2349 | 57010 2350 | 57014 2351 | 57017 2352 | 57019 2353 | 57027 2354 | 57031 2355 | 57032 2356 | 57033 2357 | 57034 2358 | 57035 2359 | 57037 2360 | 57038 2361 | 57047 2362 | 57048 2363 | 57049 2364 | 57055 2365 | 57057 2366 | 57059 2367 | 57072 2368 | 57075 2369 | 57076 2370 | 57078 2371 | 57082 2372 | 57084 2373 | 57088 2374 | 57092 2375 | 57096 2376 | 57107 2377 | 57109 2378 | 57114 2379 | 57115 2380 | 57116 2381 | 57119 2382 | 57122 2383 | 57131 2384 | 57132 2385 | 57139 2386 | 57141 2387 | 57142 2388 | 57149 2389 | 57155 2390 | 57160 2391 | 57161 2392 | 57162 2393 | 57164 2394 | 57165 2395 | 57171 2396 | 57175 2397 | 57182 2398 | 57186 2399 | 57187 2400 | 57188 2401 | 57189 2402 | 57190 2403 | 57191 2404 | 57193 2405 | 57194 2406 | 57195 2407 | 57196 2408 | 57197 2409 | 57200 2410 | 57201 2411 | 57203 2412 | 57204 2413 | 57205 2414 | 57208 2415 | 57209 2416 | 57211 2417 | 57212 2418 | 57213 2419 | 57214 2420 | 57218 2421 | 57219 2422 | 57220 2423 | 57221 2424 | 57222 2425 | 57223 2426 | 57224 2427 | 57225 2428 | 57227 2429 | 57228 2430 | 57230 2431 | 57231 2432 | 57232 2433 | 57233 2434 | 57234 2435 | 57235 2436 | 57237 2437 | 57238 2438 | 57240 2439 | 57241 2440 | 57243 2441 | 57245 2442 | 57246 2443 | 57249 2444 | 57250 2445 | 57251 2446 | 57252 2447 | 57253 2448 | 57254 2449 | 57259 2450 | 57261 2451 | 57262 2452 | 57263 2453 | 57264 2454 | 57266 2455 | 57268 2456 | 57269 2457 | 57270 2458 | 57272 2459 | 57273 2460 | 57274 2461 | 57275 2462 | 57276 2463 | 57278 2464 | 57279 2465 | 57280 2466 | 57281 2467 | 57282 2468 | 57283 2469 | 57284 2470 | 57285 2471 | 57286 2472 | 57287 2473 | 58003 2474 | 58005 2475 | 58007 2476 | 58008 2477 | 58009 2478 | 58011 2479 | 58015 2480 | 58016 2481 | 58023 2482 | 58024 2483 | 58025 2484 | 58028 2485 | 58029 2486 | 58032 2487 | 58033 2488 | 58035 2489 | 58037 2490 | 58040 2491 | 58046 2492 | 58048 2493 | 58051 2494 | 58057 2495 | 58058 2496 | 58060 2497 | 58062 2498 | 58063 2499 | 58067 2500 | 58068 2501 | 58071 2502 | 58072 2503 | 58073 2504 | 58076 2505 | 58080 2506 | 58081 2507 | 58083 2508 | 58084 2509 | 58085 2510 | 58091 2511 | 58092 2512 | 58093 2513 | 58094 2514 | 58098 2515 | 58104 2516 | 58108 2517 | 58113 2518 | 58114 2519 | 58115 2520 | 58116 2521 | 58117 2522 | 58118 2523 | 58119 2524 | 58120 2525 | 58124 2526 | 58127 2527 | 58133 2528 | 58137 2529 | 58139 2530 | 58141 2531 | 58143 2532 | 58144 2533 | 58145 2534 | 58149 2535 | 58163 2536 | 58169 2537 | 58170 2538 | 58174 2539 | 58177 2540 | 58178 2541 | 58183 2542 | 58184 2543 | 58186 2544 | 58191 2545 | 58193 2546 | 58197 2547 | 58204 2548 | 58205 2549 | 58206 2550 | 58209 2551 | 58212 2552 | 58221 2553 | 58223 2554 | 58224 2555 | 58226 2556 | 58228 2557 | 58238 2558 | 58239 2559 | 58240 2560 | 58241 2561 | 58244 2562 | 58245 2563 | 58246 2564 | 58247 2565 | 58249 2566 | 58252 2567 | 58253 2568 | 58255 2569 | 58258 2570 | 58259 2571 | 58263 2572 | 58265 2573 | 58266 2574 | 58268 2575 | 58275 2576 | 58280 2577 | 58283 2578 | 58284 2579 | 58292 2580 | 58295 2581 | 58296 2582 | 58298 2583 | 58303 2584 | 58306 2585 | 58310 2586 | 58317 2587 | 58318 2588 | 58322 2589 | 58325 2590 | 58329 2591 | 58330 2592 | 58331 2593 | 58337 2594 | 58338 2595 | 58340 2596 | 58341 2597 | 58342 2598 | 58348 2599 | 58350 2600 | 58353 2601 | 58359 2602 | 58360 2603 | 58362 2604 | 58364 2605 | 58365 2606 | 58366 2607 | 58374 2608 | 58375 2609 | 58376 2610 | 58378 2611 | 58379 2612 | 58387 2613 | 58388 2614 | 58390 2615 | 58401 2616 | 58403 2617 | 58405 2618 | 58409 2619 | 58417 2620 | 58420 2621 | 58428 2622 | 58430 2623 | 58431 2624 | 58433 2625 | 58436 2626 | 58437 2627 | 58444 2628 | 58445 2629 | 58448 2630 | 58451 2631 | 58452 2632 | 58457 2633 | 58462 2634 | 58467 2635 | 58468 2636 | 58469 2637 | 58471 2638 | 58473 2639 | 58475 2640 | 58479 2641 | 58480 2642 | 58481 2643 | 58482 2644 | 58483 2645 | 58485 2646 | 58486 2647 | 58488 2648 | 58490 2649 | 58491 2650 | 58493 2651 | 58496 2652 | 58497 2653 | 58500 2654 | 58502 2655 | 58504 2656 | 58506 2657 | 58508 2658 | 58515 2659 | 58516 2660 | 58517 2661 | 58518 2662 | 58520 2663 | 58521 2664 | 58525 2665 | 58528 2666 | 58529 2667 | 58531 2668 | 58532 2669 | 58533 2670 | 58534 2671 | 58535 2672 | 58537 2673 | 58538 2674 | 58539 2675 | 58540 2676 | 58542 2677 | 58544 2678 | 58545 2679 | 58546 2680 | 58549 2681 | 58550 2682 | 58552 2683 | 58554 2684 | 58555 2685 | 58556 2686 | 58557 2687 | 58558 2688 | 58559 2689 | 58560 2690 | 58561 2691 | 58562 2692 | 58563 2693 | 58564 2694 | 58566 2695 | 58567 2696 | 58569 2697 | 58570 2698 | 58571 2699 | 58572 2700 | 58573 2701 | 58574 2702 | 58576 2703 | 58578 2704 | 58579 2705 | 58580 2706 | 58581 2707 | 58582 2708 | 58583 2709 | 58584 2710 | 58585 2711 | 58586 2712 | 58588 2713 | 58589 2714 | 58590 2715 | 58592 2716 | 58593 2717 | 58594 2718 | 58599 2719 | 58604 2720 | 58605 2721 | 58606 2722 | 58608 2723 | 58610 2724 | 58611 2725 | 58613 2726 | 58614 2727 | 58615 2728 | 58616 2729 | 58617 2730 | 58619 2731 | 58621 2732 | 58624 2733 | 58625 2734 | 58626 2735 | 58628 2736 | 58629 2737 | 58630 2738 | 58631 2739 | 58632 2740 | 58633 2741 | 58637 2742 | 58638 2743 | 58640 2744 | 58641 2745 | 58642 2746 | 58645 2747 | 58646 2748 | 58649 2749 | 58650 2750 | 58651 2751 | 58653 2752 | 58654 2753 | 58655 2754 | 58656 2755 | 58658 2756 | 58659 2757 | 58660 2758 | 58662 2759 | 58663 2760 | 58665 2761 | 58666 2762 | 58667 2763 | 58669 2764 | 58670 2765 | 58672 2766 | 58673 2767 | 58676 2768 | 58679 2769 | 58682 2770 | 58685 2771 | 58686 2772 | 58688 2773 | 58689 2774 | 58690 2775 | 58691 2776 | 58693 2777 | 58695 2778 | 58696 2779 | 58697 2780 | 58700 2781 | 58701 2782 | 58702 2783 | 58707 2784 | 58708 2785 | 58710 2786 | 58711 2787 | 58713 2788 | 58714 2789 | 58715 2790 | 58716 2791 | 58718 2792 | 58721 2793 | 58722 2794 | 58726 2795 | 58729 2796 | 58731 2797 | 58732 2798 | 58735 2799 | 58736 2800 | 58737 2801 | 58738 2802 | 58739 2803 | 58740 2804 | 58743 2805 | 58745 2806 | 58746 2807 | 58747 2808 | 58749 2809 | 58750 2810 | 58751 2811 | 58753 2812 | 58754 2813 | 58755 2814 | 58756 2815 | 58758 2816 | 58759 2817 | 58760 2818 | 58764 2819 | 58766 2820 | 58767 2821 | 58768 2822 | 58769 2823 | 58770 2824 | 58771 2825 | 58774 2826 | 58777 2827 | 58778 2828 | 58781 2829 | 58782 2830 | 58783 2831 | 58785 2832 | 58786 2833 | 58787 2834 | 58789 2835 | 58790 2836 | 58792 2837 | 58794 2838 | 58795 2839 | 58796 2840 | 58797 2841 | 58798 2842 | 58799 2843 | 58800 2844 | 58801 2845 | 58802 2846 | 58803 2847 | 58804 2848 | 58805 2849 | 58809 2850 | 58810 2851 | 58811 2852 | 58813 2853 | 58814 2854 | 58815 2855 | 58817 2856 | 58819 2857 | 58820 2858 | 58821 2859 | 58822 2860 | 58824 2861 | 58825 2862 | 58826 2863 | 58828 2864 | 58829 2865 | 58830 2866 | 58834 2867 | 58835 2868 | 58836 2869 | 58837 2870 | 58838 2871 | 58839 2872 | 59007 2873 | 59008 2874 | 59009 2875 | 59013 2876 | 59015 2877 | 59017 2878 | 59020 2879 | 59022 2880 | 59023 2881 | 59025 2882 | 59026 2883 | 59027 2884 | 59030 2885 | 59037 2886 | 59038 2887 | 59039 2888 | 59044 2889 | 59045 2890 | 59048 2891 | 59054 2892 | 59055 2893 | 59056 2894 | 59061 2895 | 59062 2896 | 59067 2897 | 59071 2898 | 59073 2899 | 59075 2900 | 59076 2901 | 59079 2902 | 59080 2903 | 59082 2904 | 59084 2905 | 59092 2906 | 59093 2907 | 59095 2908 | 59098 2909 | 59106 2910 | 59107 2911 | 59115 2912 | 59119 2913 | 59121 2914 | 59123 2915 | 59125 2916 | 59131 2917 | 59132 2918 | 59133 2919 | 59152 2920 | 59153 2921 | 59161 2922 | 59163 2923 | 59164 2924 | 59172 2925 | 59174 2926 | 59178 2927 | 59179 2928 | 59188 2929 | 59190 2930 | 59191 2931 | 59192 2932 | 59193 2933 | 59194 2934 | 59195 2935 | 59196 2936 | 59197 2937 | 59200 2938 | 59202 2939 | 59205 2940 | 59206 2941 | 59208 2942 | 59209 2943 | 59213 2944 | 59224 2945 | 59226 2946 | 59228 2947 | 59229 2948 | 59231 2949 | 59241 2950 | 59242 2951 | 59244 2952 | 59247 2953 | 59257 2954 | 59266 2955 | 59267 2956 | 59271 2957 | 59272 2958 | 59273 2959 | 59274 2960 | 59277 2961 | 59281 2962 | 59282 2963 | 59283 2964 | 59289 2965 | 59290 2966 | 59291 2967 | 59292 2968 | 59293 2969 | 59295 2970 | 59304 2971 | 59306 2972 | 59309 2973 | 59311 2974 | 59318 2975 | 59320 2976 | 59322 2977 | 59328 2978 | 59330 2979 | 59331 2980 | 59332 2981 | 59337 2982 | 59341 2983 | 59342 2984 | 59344 2985 | 59347 2986 | 59349 2987 | 59350 2988 | 59351 2989 | 59354 2990 | 59362 2991 | 59364 2992 | 59365 2993 | 59366 2994 | 59369 2995 | 59377 2996 | 59378 2997 | 59379 2998 | 59384 2999 | 59389 3000 | 59393 3001 | 59395 3002 | 59396 3003 | 59398 3004 | 59404 3005 | 59408 3006 | 59409 3007 | 59410 3008 | 59422 3009 | 59423 3010 | 59425 3011 | 59427 3012 | 59435 3013 | 59437 3014 | 59439 3015 | 59441 3016 | 59442 3017 | 59445 3018 | 59448 3019 | 59450 3020 | 59462 3021 | 59465 3022 | 59471 3023 | 59472 3024 | 59477 3025 | 59478 3026 | 59484 3027 | 59485 3028 | 59486 3029 | 59487 3030 | 59489 3031 | 59493 3032 | 59496 3033 | 59497 3034 | 59498 3035 | 59501 3036 | 59504 3037 | 59512 3038 | 59513 3039 | 59514 3040 | 59517 3041 | 59518 3042 | 59520 3043 | 59523 3044 | 59525 3045 | 59526 3046 | 59528 3047 | 59529 3048 | 59531 3049 | 59532 3050 | 59536 3051 | 59537 3052 | 59542 3053 | 59545 3054 | 59549 3055 | 59550 3056 | 59555 3057 | 59559 3058 | 59562 3059 | 59563 3060 | 59566 3061 | 59570 3062 | 59574 3063 | 59575 3064 | 59577 3065 | 59579 3066 | 59581 3067 | 59586 3068 | 59587 3069 | 59589 3070 | 59592 3071 | 59599 3072 | 59601 3073 | 59604 3074 | 59614 3075 | 59615 3076 | 59616 3077 | 59617 3078 | 59618 3079 | 59619 3080 | 59620 3081 | 59622 3082 | 59623 3083 | 59624 3084 | 59629 3085 | 59630 3086 | 59631 3087 | 59636 3088 | 59637 3089 | 59639 3090 | 59641 3091 | 59642 3092 | 59645 3093 | 59647 3094 | 59648 3095 | 59649 3096 | 59650 3097 | 59652 3098 | 59653 3099 | 59654 3100 | 59655 3101 | 59656 3102 | 59657 3103 | 59658 3104 | 59659 3105 | 59660 3106 | 59661 3107 | 59662 3108 | 59664 3109 | 59668 3110 | 59669 3111 | 59673 3112 | 59674 3113 | 59676 3114 | 59677 3115 | 59678 3116 | 59680 3117 | 59681 3118 | 59682 3119 | 59683 3120 | 59684 3121 | 59687 3122 | 59688 3123 | 59692 3124 | 59693 3125 | 59695 3126 | 59697 3127 | 59698 3128 | 59701 3129 | 59702 3130 | 59703 3131 | 59704 3132 | 59705 3133 | 59706 3134 | 59707 3135 | 59708 3136 | 59709 3137 | 59710 3138 | 59711 3139 | 59712 3140 | 59713 3141 | 59714 3142 | 59716 3143 | 59718 3144 | 59722 3145 | 59723 3146 | 59724 3147 | 59725 3148 | 59727 3149 | 59728 3150 | 59729 3151 | 59731 3152 | 59732 3153 | 59734 3154 | 59737 3155 | 59739 3156 | 59740 3157 | 59743 3158 | 59744 3159 | 59745 3160 | 59746 3161 | 59749 3162 | 59756 3163 | 59757 3164 | 59758 3165 | 59760 3166 | 59761 3167 | 59764 3168 | 59765 3169 | 59766 3170 | 59767 3171 | 59768 3172 | 59802 3173 | 59804 3174 | 59806 3175 | 59807 3176 | 59808 3177 | 59811 3178 | 59812 3179 | 59814 3180 | 59815 3181 | 59816 3182 | 59818 3183 | 59819 3184 | 59820 3185 | 59823 3186 | 59824 3187 | 59829 3188 | 59831 3189 | 59833 3190 | 59835 3191 | 59836 3192 | 59838 3193 | 59839 3194 | 59840 3195 | 59842 3196 | 59843 3197 | 59844 3198 | 59847 3199 | 59849 3200 | 59851 3201 | 59852 3202 | 59853 3203 | 59854 3204 | 59855 3205 | 59858 3206 | 59860 3207 | 59861 3208 | 59864 3209 | 59870 3210 | 59871 3211 | 59872 3212 | 59874 3213 | 59876 3214 | 59877 3215 | 59878 3216 | 59879 3217 | 59882 3218 | 59883 3219 | 59885 3220 | 59892 3221 | 59893 3222 | 59894 3223 | 59897 3224 | 59898 3225 | 59899 3226 | 59900 3227 | 59901 3228 | 59902 3229 | 59904 3230 | 59905 3231 | 59908 3232 | 59910 3233 | 59911 3234 | 59915 3235 | 59917 3236 | 59919 3237 | 59920 3238 | 59921 3239 | 59922 3240 | 59924 3241 | 59925 3242 | 59927 3243 | 59929 3244 | 59930 3245 | 59931 3246 | 59932 3247 | 59933 3248 | 59936 3249 | 59937 3250 | 59938 3251 | 59940 3252 | 59941 3253 | 59942 3254 | 59946 3255 | 60001 3256 | 60013 3257 | 60018 3258 | 60023 3259 | 60024 3260 | 60040 3261 | 60058 3262 | 60060 3263 | 60061 3264 | 60064 3265 | 60065 3266 | 60070 3267 | 60072 3268 | 60074 3269 | 60080 3270 | 60081 3271 | 60090 3272 | 60092 3273 | 60096 3274 | 601000 3275 | 601004 3276 | 601006 3277 | 601007 3278 | 60101 3279 | 601011 3280 | 601012 3281 | 601013 3282 | 601021 3283 | 601022 3284 | 601023 3285 | 601026 3286 | 601027 3287 | 601030 3288 | 601031 3289 | 601033 3290 | 60105 3291 | 60108 3292 | 60112 3293 | 60121 3294 | 60123 3295 | 60124 3296 | 60135 3297 | 60136 3298 | 60137 3299 | 60139 3300 | 60143 3301 | 60144 3302 | 60146 3303 | 60147 3304 | 60154 3305 | 60157 3306 | 60159 3307 | 60161 3308 | 60164 3309 | 60175 3310 | 60176 3311 | 60180 3312 | 60187 3313 | 60188 3314 | 60203 3315 | 60205 3316 | 60206 3317 | 60207 3318 | 60208 3319 | 60209 3320 | 60215 3321 | 60216 3322 | 60219 3323 | 60221 3324 | 60225 3325 | 60226 3326 | 60227 3327 | 60228 3328 | 60232 3329 | 60234 3330 | 60235 3331 | 60240 3332 | 60241 3333 | 60244 3334 | 60249 3335 | 60253 3336 | 60256 3337 | 60258 3338 | 60261 3339 | 60263 3340 | 60264 3341 | 60270 3342 | 60272 3343 | 60273 3344 | 60275 3345 | 60276 3346 | 60280 3347 | 60282 3348 | 60297 3349 | 60298 3350 | 60301 3351 | 60302 3352 | 60303 3353 | 60306 3354 | 60312 3355 | 60313 3356 | 60315 3357 | 60319 3358 | 60320 3359 | 60323 3360 | 60326 3361 | 60332 3362 | 60333 3363 | 60336 3364 | 60348 3365 | 60352 3366 | 60353 3367 | 60360 3368 | 60364 3369 | 60365 3370 | 60367 3371 | 60374 3372 | 60375 3373 | 60376 3374 | 60378 3375 | 60385 3376 | 60386 3377 | 60392 3378 | 60393 3379 | 60398 3380 | 60412 3381 | 60413 3382 | 60417 3383 | 60419 3384 | 60420 3385 | 60423 3386 | 60425 3387 | 60428 3388 | 60430 3389 | 60433 3390 | 60434 3391 | 60436 3392 | 60439 3393 | 60440 3394 | 60442 3395 | 60443 3396 | 60444 3397 | 60447 3398 | 60448 3399 | 60451 3400 | 60455 3401 | 60462 3402 | 60463 3403 | 60466 3404 | 60467 3405 | 60471 3406 | 60479 3407 | 60484 3408 | 60489 3409 | 60492 3410 | 60505 3411 | 60511 3412 | 60513 3413 | 60517 3414 | 60522 3415 | 60523 3416 | 60525 3417 | 60535 3418 | 60536 3419 | 60537 3420 | 60541 3421 | 60544 3422 | 60546 3423 | 60554 3424 | 60558 3425 | 60559 3426 | 60560 3427 | 60563 3428 | 60564 3429 | 60565 3430 | 60570 3431 | 60571 3432 | 60572 3433 | 60575 3434 | 60577 3435 | 60579 3436 | 60580 3437 | 60582 3438 | 60584 3439 | 60595 3440 | 60596 3441 | 60601 3442 | 60602 3443 | 60603 3444 | 60604 3445 | 60606 3446 | 60608 3447 | 60610 3448 | 60611 3449 | 60613 3450 | 60614 3451 | 60616 3452 | 60617 3453 | 60620 3454 | 60621 3455 | 60624 3456 | 60625 3457 | 60626 3458 | 60627 3459 | 60630 3460 | 60631 3461 | 60632 3462 | 60633 3463 | 60635 3464 | 60637 3465 | 60638 3466 | 60639 3467 | 60640 3468 | 60641 3469 | 60642 3470 | 60644 3471 | 60645 3472 | 60652 3473 | 60653 3474 | 60654 3475 | 60657 3476 | 60659 3477 | 60660 3478 | 60661 3479 | 60663 3480 | 60665 3481 | 60668 3482 | 60669 3483 | 60670 3484 | 60671 3485 | 60672 3486 | 60673 3487 | 60675 3488 | 60676 3489 | 60677 3490 | 60678 3491 | 60682 3492 | 60683 3493 | 60684 3494 | 60685 3495 | 60686 3496 | 60687 3497 | 60690 3498 | 60691 3499 | 60692 3500 | 60695 3501 | 60696 3502 | 60697 3503 | 60698 3504 | 60702 3505 | 60705 3506 | 60709 3507 | 60711 3508 | 60715 3509 | 60716 3510 | 60719 3511 | 60720 3512 | 60722 3513 | 60723 3514 | 60725 3515 | 60726 3516 | 60727 3517 | 60728 3518 | 60730 3519 | 60732 3520 | 60741 3521 | 60743 3522 | 60744 3523 | 60745 3524 | 60746 3525 | 60749 3526 | 60750 3527 | 60751 3528 | 60752 3529 | 60755 3530 | 60759 3531 | 60760 3532 | 60762 3533 | 60764 3534 | 60767 3535 | 60768 3536 | 60769 3537 | 60771 3538 | 60772 3539 | 60774 3540 | 60775 3541 | 60777 3542 | 60780 3543 | 60781 3544 | 60783 3545 | 60784 3546 | 60786 3547 | 60788 3548 | 60795 3549 | 60798 3550 | 60799 3551 | 60800 3552 | 60801 3553 | 60804 3554 | 60807 3555 | 60809 3556 | 60811 3557 | 60814 3558 | 60817 3559 | 60819 3560 | 60820 3561 | 60828 3562 | 60829 3563 | 60831 3564 | 60832 3565 | 60833 3566 | 60837 3567 | 60838 3568 | 60840 3569 | 60845 3570 | 60846 3571 | 60851 3572 | 60852 3573 | 60853 3574 | 60854 3575 | 60856 3576 | 60857 3577 | 60858 3578 | 60859 3579 | 60860 3580 | 60864 3581 | 60869 3582 | 60870 3583 | 60871 3584 | 60872 3585 | 60873 3586 | 60876 3587 | 60877 3588 | 60878 3589 | 60879 3590 | 60880 3591 | 60881 3592 | 60882 3593 | 60884 3594 | 60885 3595 | 60886 3596 | 60887 3597 | 60889 3598 | 60890 3599 | 60891 3600 | 60895 3601 | 60896 3602 | 60897 3603 | 60898 3604 | 60899 3605 | 60902 3606 | 60903 3607 | 60904 3608 | 60908 3609 | 60909 3610 | 60917 3611 | 60921 3612 | 60922 3613 | 60924 3614 | 60926 3615 | 60930 3616 | 60931 3617 | 60932 3618 | 60933 3619 | 60934 3620 | 60937 3621 | 60939 3622 | 60940 3623 | 60941 3624 | 60943 3625 | 60946 3626 | 60949 3627 | 60950 3628 | 60951 3629 | 60952 3630 | 60954 3631 | 60955 3632 | 60956 3633 | 60960 3634 | 60962 3635 | 60963 3636 | 60964 3637 | 60965 3638 | 60967 3639 | 60968 3640 | 60969 3641 | 60970 3642 | 60971 3643 | 60972 3644 | 60976 3645 | 60980 3646 | 60983 3647 | 60984 3648 | 60985 3649 | 60986 3650 | 60987 3651 | 60988 3652 | 60993 3653 | 60994 3654 | 60995 3655 | 61001 3656 | 61005 3657 | 61006 3658 | 61010 3659 | 61012 3660 | 61013 3661 | 61014 3662 | 61015 3663 | 61019 3664 | 61027 3665 | 61029 3666 | 61030 3667 | 61034 3668 | 61035 3669 | 61041 3670 | 61043 3671 | 61044 3672 | 61050 3673 | 61051 3674 | 61054 3675 | 61057 3676 | 61059 3677 | 61062 3678 | 61067 3679 | 61072 3680 | 61073 3681 | 61076 3682 | 61080 3683 | 61081 3684 | 61082 3685 | 61083 3686 | 61084 3687 | 61089 3688 | 61090 3689 | 61094 3690 | 61095 3691 | 61103 3692 | 61106 3693 | 61107 3694 | 61110 3695 | 61116 3696 | 61117 3697 | 61118 3698 | 61119 3699 | 61120 3700 | 61121 3701 | 61122 3702 | 61127 3703 | 61130 3704 | 61131 3705 | 61132 3706 | 61133 3707 | 61138 3708 | 61143 3709 | 61147 3710 | 61150 3711 | 61151 3712 | 61152 3713 | 61158 3714 | 61161 3715 | 61162 3716 | 61165 3717 | 61167 3718 | 61168 3719 | 61171 3720 | 61174 3721 | 61180 3722 | 61181 3723 | 61184 3724 | 61186 3725 | 61188 3726 | 61189 3727 | 61190 3728 | 61191 3729 | 61192 3730 | 61194 3731 | 61199 3732 | 61203 3733 | 61204 3734 | 61205 3735 | 61209 3736 | 61211 3737 | 61217 3738 | 61220 3739 | 61223 3740 | 61236 3741 | 61237 3742 | 61240 3743 | 61244 3744 | 61247 3745 | 61249 3746 | 61252 3747 | 61253 3748 | 61255 3749 | 61257 3750 | 61258 3751 | 61260 3752 | 61261 3753 | 61262 3754 | 61263 3755 | 61267 3756 | 61271 3757 | 61273 3758 | 61274 3759 | 61275 3760 | 61279 3761 | 61280 3762 | 61282 3763 | 61283 3764 | 61290 3765 | 61292 3766 | 61294 3767 | 61296 3768 | 61297 3769 | 61300 3770 | 61302 3771 | 61305 3772 | 61306 3773 | 61307 3774 | 61309 3775 | 61310 3776 | 61311 3777 | 61312 3778 | 61314 3779 | 61319 3780 | 61324 3781 | 61325 3782 | 61326 3783 | 61327 3784 | 61328 3785 | 61329 3786 | 61330 3787 | 61333 3788 | 61336 3789 | 61337 3790 | 61340 3791 | 61343 3792 | 61344 3793 | 61346 3794 | 61348 3795 | 61349 3796 | 61351 3797 | 61356 3798 | 61357 3799 | 61360 3800 | 61361 3801 | 61363 3802 | 61365 3803 | 61367 3804 | 61368 3805 | 61371 3806 | 61372 3807 | 61373 3808 | 61374 3809 | 61377 3810 | 61379 3811 | 61380 3812 | 61383 3813 | 61384 3814 | 61386 3815 | 61387 3816 | 61389 3817 | 61391 3818 | 61393 3819 | 61397 3820 | 61400 3821 | 61402 3822 | 61403 3823 | 61405 3824 | 61411 3825 | 61412 3826 | 61413 3827 | 61414 3828 | 61416 3829 | 61417 3830 | 61419 3831 | 61420 3832 | 61422 3833 | 61423 3834 | 61425 3835 | 61427 3836 | 61429 3837 | 61430 3838 | 61431 3839 | 61432 3840 | 61433 3841 | 61435 3842 | 61438 3843 | 61439 3844 | 61440 3845 | 61441 3846 | 61443 3847 | 61446 3848 | 61447 3849 | 61450 3850 | 61453 3851 | 61454 3852 | 61457 3853 | 61458 3854 | 61459 3855 | 61460 3856 | 61461 3857 | 61462 3858 | 61463 3859 | 61464 3860 | 61465 3861 | 61467 3862 | 61468 3863 | 61469 3864 | 61470 3865 | 61471 3866 | 61472 3867 | 61473 3868 | 61474 3869 | 61476 3870 | 61477 3871 | 61478 3872 | 61480 3873 | 61481 3874 | 61483 3875 | 61484 3876 | 61485 3877 | 61486 3878 | 61488 3879 | 61490 3880 | 61491 3881 | 61492 3882 | 61493 3883 | 61494 3884 | 61495 3885 | 61496 3886 | 61497 3887 | 61498 3888 | 61499 3889 | 61500 3890 | 61502 3891 | 61503 3892 | 61504 3893 | 61505 3894 | 61506 3895 | 61507 3896 | 61508 3897 | 61510 3898 | 61511 3899 | 61513 3900 | 61514 3901 | 61515 3902 | 61516 3903 | 61517 3904 | 61518 3905 | 61519 3906 | 61520 3907 | 61523 3908 | 61524 3909 | 61525 3910 | 61526 3911 | 61527 3912 | 61528 3913 | 61532 3914 | 61533 3915 | 61534 3916 | 61537 3917 | 61538 3918 | 61539 3919 | 61540 3920 | 61541 3921 | 61542 3922 | 61543 3923 | 61544 3924 | 61545 3925 | 61546 3926 | 61547 3927 | 61548 3928 | 61549 3929 | 61550 3930 | 61552 3931 | 61554 3932 | 61555 3933 | 61556 3934 | 61557 3935 | 61558 3936 | 61559 3937 | 61560 3938 | 61561 3939 | 61562 3940 | 61563 3941 | 61564 3942 | 61565 3943 | 61566 3944 | 61567 3945 | 61568 3946 | 61569 3947 | 61572 3948 | 61573 3949 | 61574 3950 | 61575 3951 | 61576 3952 | 61578 3953 | 61579 3954 | 61580 3955 | 61581 3956 | 61582 3957 | 61583 3958 | 61584 3959 | 61585 3960 | 61586 3961 | 61587 3962 | 61588 3963 | 61589 3964 | 61592 3965 | 61593 3966 | 61594 3967 | 61595 3968 | 61597 3969 | 61598 3970 | 61599 3971 | 61600 3972 | 61601 3973 | 61602 3974 | 61603 3975 | 61604 3976 | 61605 3977 | 61607 3978 | 61608 3979 | 61610 3980 | 61611 3981 | 61612 3982 | 61613 3983 | 61614 3984 | 61615 3985 | 61616 3986 | 61617 3987 | 61621 3988 | 61624 3989 | 61625 3990 | 61626 3991 | 61628 3992 | 61631 3993 | 61633 3994 | 61635 3995 | 61636 3996 | 61637 3997 | 61640 3998 | 61642 3999 | 61643 4000 | 61644 4001 | 61645 4002 | 61646 4003 | 61649 4004 | 61650 4005 | 61651 4006 | 61653 4007 | 61654 4008 | 61655 4009 | 61656 4010 | 61658 4011 | 61659 4012 | 61660 4013 | 61662 4014 | 61663 4015 | 61664 4016 | 61665 4017 | 61667 4018 | 61668 4019 | 61670 4020 | 61672 4021 | 61673 4022 | 61674 4023 | 61675 4024 | 61676 4025 | 61677 4026 | 61678 4027 | 61679 4028 | 61680 4029 | 61681 4030 | 61682 4031 | 61684 4032 | 61685 4033 | 61686 4034 | 61688 4035 | 61689 4036 | 61690 4037 | 61691 4038 | 61693 4039 | 61694 4040 | 61695 4041 | 61696 4042 | 61697 4043 | 61698 4044 | 61699 4045 | 61700 4046 | 61701 4047 | 61702 4048 | 61704 4049 | 61705 4050 | 61706 4051 | 61707 4052 | 61708 4053 | 61710 4054 | 61711 4055 | 61712 4056 | 61713 4057 | 61714 4058 | 61717 4059 | 61718 4060 | 61720 4061 | 61721 4062 | 61722 4063 | 61723 4064 | 61725 4065 | 61727 4066 | 61730 4067 | 61731 4068 | 61735 4069 | 61736 4070 | 61737 4071 | 61739 4072 | 61740 4073 | 61741 4074 | 61742 4075 | 61743 4076 | 61745 4077 | 61747 4078 | 61749 4079 | 61751 4080 | 61753 4081 | 61754 4082 | 61757 4083 | 61758 4084 | 61759 4085 | 62003 4086 | 62004 4087 | 62011 4088 | 62012 4089 | 62014 4090 | 62016 4091 | 62017 4092 | 62020 4093 | 62022 4094 | 62023 4095 | 62026 4096 | 62030 4097 | 62031 4098 | 62033 4099 | 62034 -------------------------------------------------------------------------------- /deepseenet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncbi-nlp/DeepSeeNet/fb0c3a3d907756abf6f4a2d3a7f58a37d864b4a9/deepseenet/__init__.py -------------------------------------------------------------------------------- /deepseenet/data_generator.py: -------------------------------------------------------------------------------- 1 | from typing import Callable 2 | 3 | import numpy as np 4 | from keras.utils import Sequence, to_categorical 5 | from sklearn.utils import class_weight 6 | 7 | from deepseenet.utils import cal_chunk_number 8 | 9 | 10 | class DataGenerator(Sequence): 11 | def __init__(self, data, *, batch_size: int, n_classes: int, 12 | preprocess_image: Callable, shuffle: bool=False): 13 | """ 14 | 15 | Args: 16 | data: input data 17 | batch_size(int): batch size 18 | n_classes(int): number of classes 19 | shuffle(bool): Whether or not to shuffle the data after each epoch. 20 | preprocess_image: a function to preprocess a image file encoding a batch of images 21 | """ 22 | self.data = data 23 | self.batch_size = batch_size 24 | self.shuffle = shuffle 25 | self.n_classes = n_classes 26 | self._get_chunks() 27 | self.preprocess_image = preprocess_image 28 | 29 | def __len__(self): 30 | return len(self.chunks) 31 | 32 | def __getitem__(self, index): 33 | rows = self.chunks[index] 34 | batch_images, batch_labels = self.process_instances(rows) 35 | return batch_images, batch_labels 36 | 37 | def on_epoch_end(self): 38 | if self.shuffle: 39 | np.random.shuffle(self.data) 40 | self._get_chunks() 41 | 42 | def process_instances(self, rows): 43 | batch_images = [] 44 | batch_labels = [] 45 | for row in rows: 46 | file_path, label = row[0], row[1] 47 | x = self.preprocess_image(file_path) 48 | batch_images.append(x) 49 | batch_labels.append(label) 50 | return np.concatenate(batch_images, axis=0), to_categorical(np.array(batch_labels), self.n_classes) 51 | 52 | def get_epoch_num(self): 53 | return cal_chunk_number(len(self.data), self.batch_size) 54 | 55 | def _get_chunks(self): 56 | self.chunks = np.array_split(self.data, cal_chunk_number(len(self.data), self.batch_size)) 57 | 58 | def class_weights(self): 59 | labels = [] 60 | for row in self.data: 61 | _, label = row[0], row[1] 62 | labels.append(label) 63 | class_weight_list = class_weight.compute_class_weight('balanced', np.unique(labels), labels) 64 | cw = dict(zip(np.unique(labels), class_weight_list)) 65 | return cw 66 | -------------------------------------------------------------------------------- /deepseenet/deepseenet_adv_amd.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import numpy as np 3 | 4 | from keras import models 5 | from keras.preprocessing import image 6 | from keras.utils import get_file 7 | 8 | from deepseenet import deepseenet_risk_factor 9 | from deepseenet.utils import crop2square 10 | 11 | ADVANCED_AMD_PATH = 'https://github.com/ncbi-nlp/DeepSeeNet/releases/download/0.1/adv_amd_model.h5' 12 | ADVANCED_AMD_MD5 = '0adbf448491ead63ac384da671c4f7ee' 13 | 14 | 15 | def preprocess_image(image_path): 16 | """ 17 | Loads an image into a Numpy array 18 | 19 | Args: 20 | image_path: Path or file object. 21 | 22 | Returns: 23 | Numpy array 24 | """ 25 | logging.debug('Processing: %s', image_path) 26 | img = crop2square(image.load_img(image_path)).resize((224, 224)) 27 | x = image.img_to_array(img) 28 | x = np.expand_dims(x, axis=0) 29 | x = deepseenet_risk_factor.preprocess_input(x) 30 | return x 31 | 32 | 33 | def DeepSeeNetAdvancedAMD(model='areds'): 34 | """ 35 | Instantiates the EyesNet advanced AMD architecture. 36 | 37 | Args: 38 | model: One of 'areds1' (pre-training on AREDS), 39 | or the path to the model file to be loaded. 40 | 41 | Returns: 42 | A Keras model instance. 43 | """ 44 | if model == 'areds': 45 | model = get_file( 46 | 'advanced_amd_model.h5', 47 | ADVANCED_AMD_PATH, 48 | cache_dir='models', 49 | file_hash=ADVANCED_AMD_MD5 50 | ) 51 | logging.info('Loading the model: %s', model) 52 | return models.load_model(model) 53 | -------------------------------------------------------------------------------- /deepseenet/deepseenet_cga.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import numpy as np 3 | 4 | from keras import models 5 | from keras.preprocessing import image 6 | from keras.utils import get_file 7 | 8 | from deepseenet import deepseenet_risk_factor 9 | from deepseenet.utils import crop2square 10 | 11 | CGA_PATH = 'https://github.com/ncbi-nlp/DeepSeeNet/releases/download/0.2/cga_model.h5' 12 | CGA_MD5 = 'fe4a441d5286154633de46c25099b520' 13 | 14 | 15 | def preprocess_image(image_path): 16 | """ 17 | Loads an image into a Numpy array 18 | 19 | Args: 20 | image_path: Path or file object. 21 | 22 | Returns: 23 | Numpy array 24 | """ 25 | logging.debug('Processing: %s', image_path) 26 | img = crop2square(image.load_img(image_path)).resize((224, 224)) 27 | x = image.img_to_array(img) 28 | x = np.expand_dims(x, axis=0) 29 | x = deepseenet_risk_factor.preprocess_input(x) 30 | return x 31 | 32 | 33 | def DeepSeeNetGA(model='areds'): 34 | """ 35 | Instantiates the EyesNet pigmentary abnormality architecture. 36 | 37 | Args: 38 | model: One of 'areds1' (pre-training on AREDS1), 39 | or the path to the model file to be loaded. 40 | 41 | Returns: 42 | A Keras model instance. 43 | """ 44 | if model == 'areds': 45 | model = get_file( 46 | 'cga_model.h5', 47 | CGA_PATH, 48 | cache_dir='models', 49 | file_hash=CGA_MD5 50 | ) 51 | logging.info('Loading the model: %s', model) 52 | return models.load_model(model) 53 | -------------------------------------------------------------------------------- /deepseenet/deepseenet_drusen.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | import numpy as np 4 | from keras import models 5 | from keras.preprocessing import image 6 | from keras.utils import get_file 7 | 8 | from deepseenet import deepseenet_risk_factor 9 | from deepseenet.utils import crop2square 10 | 11 | DRUSEN_PATH = 'https://github.com/ncbi-nlp/DeepSeeNet/releases/download/0.1/drusen_model.h5' 12 | DRUSEN_MD5 = '997a8229f972482e127e8a32d1967549' 13 | 14 | 15 | def preprocess_image(image_path): 16 | """ 17 | Loads an image into a Numpy array 18 | 19 | Args: 20 | image_path: Path or file object. 21 | 22 | Returns: 23 | Numpy array 24 | """ 25 | logging.debug('Processing: %s', image_path) 26 | img = crop2square(image.load_img(image_path)).resize((224, 224)) 27 | x = image.img_to_array(img) 28 | x = np.expand_dims(x, axis=0) 29 | x = deepseenet_risk_factor.preprocess_input(x) 30 | return x 31 | 32 | 33 | def DeepSeeNetDrusen(model='areds'): 34 | """ 35 | Instantiates the EyesNet drusen architecture. 36 | 37 | Args: 38 | model: One of 'areds1' (pre-training on AREDS1), 39 | or the path to the model file to be loaded. 40 | 41 | Returns: 42 | A Keras model instance. 43 | """ 44 | if model == 'areds': 45 | model = get_file( 46 | 'drusen_model.h5', 47 | DRUSEN_PATH, 48 | cache_dir='models', 49 | file_hash=DRUSEN_MD5 50 | ) 51 | logging.info('Loading the model: %s', model) 52 | return models.load_model(model) 53 | 54 | 55 | def get_drusen_size(score): 56 | y = np.argmax(score, axis=1) 57 | if y == 0: 58 | return 'small/none' 59 | elif y == 1: 60 | return 'intermediate' 61 | elif y == 2: 62 | return 'large' 63 | else: 64 | raise KeyError -------------------------------------------------------------------------------- /deepseenet/deepseenet_ga.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import numpy as np 3 | 4 | from keras import models 5 | from keras.preprocessing import image 6 | from keras.utils import get_file 7 | 8 | from deepseenet import deepseenet_risk_factor 9 | from deepseenet.utils import crop2square 10 | 11 | GA_PATH = 'https://github.com/ncbi-nlp/DeepSeeNet/releases/download/0.2/ga_model.h5' 12 | GA_MD5 = '59350371c73eaaff397d477b702c456a' 13 | 14 | 15 | def preprocess_image(image_path): 16 | """ 17 | Loads an image into a Numpy array 18 | 19 | Args: 20 | image_path: Path or file object. 21 | 22 | Returns: 23 | Numpy array 24 | """ 25 | logging.debug('Processing: %s', image_path) 26 | img = crop2square(image.load_img(image_path)).resize((224, 224)) 27 | x = image.img_to_array(img) 28 | x = np.expand_dims(x, axis=0) 29 | x = deepseenet_risk_factor.preprocess_input(x) 30 | return x 31 | 32 | 33 | def DeepSeeNetGA(model='areds'): 34 | """ 35 | Instantiates the EyesNet pigmentary abnormality architecture. 36 | 37 | Args: 38 | model: One of 'areds1' (pre-training on AREDS1), 39 | or the path to the model file to be loaded. 40 | 41 | Returns: 42 | A Keras model instance. 43 | """ 44 | if model == 'areds': 45 | model = get_file( 46 | 'ga_model.h5', 47 | GA_PATH, 48 | cache_dir='models', 49 | file_hash=GA_MD5 50 | ) 51 | logging.info('Loading the model: %s', model) 52 | return models.load_model(model) 53 | -------------------------------------------------------------------------------- /deepseenet/deepseenet_pigment.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import numpy as np 3 | 4 | from keras import models 5 | from keras.preprocessing import image 6 | from keras.utils import get_file 7 | 8 | from deepseenet import deepseenet_risk_factor 9 | from deepseenet.utils import crop2square 10 | 11 | PIGMENT_PATH = 'https://github.com/ncbi-nlp/DeepSeeNet/releases/download/0.1/pigment_model.h5' 12 | PIGMENT_MD5 = 'e38f60fa9c0fc6cd7a5022b07b722927' 13 | 14 | 15 | def preprocess_image(image_path): 16 | """ 17 | Loads an image into a Numpy array 18 | 19 | Args: 20 | image_path: Path or file object. 21 | 22 | Returns: 23 | Numpy array 24 | """ 25 | logging.debug('Processing: %s', image_path) 26 | img = crop2square(image.load_img(image_path)).resize((224, 224)) 27 | x = image.img_to_array(img) 28 | x = np.expand_dims(x, axis=0) 29 | x = deepseenet_risk_factor.preprocess_input(x) 30 | return x 31 | 32 | 33 | def DeepSeeNetPigment(model='areds'): 34 | """ 35 | Instantiates the EyesNet pigmentary abnormality architecture. 36 | 37 | Args: 38 | model: One of 'areds1' (pre-training on AREDS1), 39 | or the path to the model file to be loaded. 40 | 41 | Returns: 42 | A Keras model instance. 43 | """ 44 | if model == 'areds': 45 | model = get_file( 46 | 'pigment_model.h5', 47 | PIGMENT_PATH, 48 | cache_dir='models', 49 | file_hash=PIGMENT_MD5 50 | ) 51 | logging.info('Loading the model: %s', model) 52 | return models.load_model(model) 53 | -------------------------------------------------------------------------------- /deepseenet/deepseenet_risk_factor.py: -------------------------------------------------------------------------------- 1 | from keras import Model 2 | from keras.applications import inception_v3, imagenet_utils 3 | from keras.layers import GlobalAveragePooling2D, Dense, Dropout 4 | 5 | 6 | def preprocess_input(x): 7 | """Preprocesses a numpy array encoding a batch of images. 8 | 9 | # Arguments 10 | x: a 4D numpy array consists of RGB values within [0, 255]. 11 | 12 | # Returns 13 | Preprocessed array. 14 | """ 15 | return imagenet_utils.preprocess_input(x, mode='tf') 16 | 17 | 18 | def RiskFactorModel(n_classes=2, input_shape=(224, 224, 3)): 19 | base_model = inception_v3.InceptionV3(weights='imagenet', include_top=False, input_shape=input_shape) 20 | model = Model(inputs=base_model.input, outputs=base_model.get_layer('mixed10').output) 21 | x = model.output 22 | x = GlobalAveragePooling2D()(x) 23 | x = Dense(256, activation='relu', name='global_dense1')(x) 24 | x = Dropout(0.5)(x) 25 | x = Dense(128, activation='relu', name='global_dense2')(x) 26 | x = Dropout(0.5)(x) 27 | predictions = Dense(n_classes, activation='softmax', name='global_predictions')(x) 28 | final_model = Model(inputs=model.input, outputs=predictions) 29 | return final_model 30 | -------------------------------------------------------------------------------- /deepseenet/deepseenet_simplified.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | import numpy as np 4 | 5 | from deepseenet import deepseenet_drusen, deepseenet_pigment, deepseenet_adv_amd 6 | 7 | 8 | def get_simplified_score(scores): 9 | """ 10 | Get AREDS simplified severity score from drusen size, pigmentary abnormality, and advanced AMD. 11 | 12 | Args: 13 | scores: a dict of individual risk factors 14 | 15 | Returns: 16 | a score of 0-5 17 | """ 18 | def has_adv_amd(score): 19 | return True if score == 1 else False 20 | 21 | def has_pigment(score): 22 | return True if score == 1 else False 23 | 24 | def has_large_drusen(score): 25 | return True if score == 2 else False 26 | 27 | def has_intermediate_drusen(score): 28 | return True if score == 1 else False 29 | 30 | score = 0 31 | if has_adv_amd(scores['advanced_amd'][0]): 32 | score += 5 33 | if has_adv_amd(scores['advanced_amd'][1]): 34 | score += 5 35 | if has_pigment(scores['pigment'][0]): 36 | score += 1 37 | if has_pigment(scores['pigment'][1]): 38 | score += 1 39 | if has_large_drusen(scores['drusen'][0]): 40 | score += 1 41 | if has_large_drusen(scores['drusen'][1]): 42 | score += 1 43 | if has_intermediate_drusen(scores['drusen'][0]) \ 44 | and has_intermediate_drusen(scores['drusen'][1]): 45 | score += 1 46 | 47 | return 5 if score >= 5 else score 48 | 49 | 50 | class DeepSeeNetSimplifiedScore(object): 51 | def __init__(self, drusen_model='areds', pigment_model='areds', advanced_amd_model='areds'): 52 | """ 53 | Args: 54 | drusen_model: Path or file object. 55 | pigment_model: Path or file object. 56 | advanced_amd_model: Path or file object. 57 | """ 58 | self.drusen = deepseenet_drusen.DeepSeeNetDrusen(drusen_model) 59 | self.pigment = deepseenet_pigment.DeepSeeNetPigment(pigment_model) 60 | self.adv = deepseenet_adv_amd.DeepSeeNetAdvancedAMD(advanced_amd_model) 61 | self.models = { 62 | 'drusen': (self.drusen, deepseenet_drusen.preprocess_image), 63 | 'pigment': (self.pigment, deepseenet_pigment.preprocess_image), 64 | 'advanced_amd': (self.adv, deepseenet_adv_amd.preprocess_image), 65 | } 66 | 67 | def predict(self, x_left, x_right, verbose=0): 68 | """ 69 | Generates simplified severity score for one left eye and one right eye 70 | 71 | Args: 72 | x_left: input data of the left eye, as a Path or file object. 73 | x_right: input data of the right eye, as a Path or file object. 74 | verbose: Verbosity mode, 0 or 1. 75 | 76 | Returns: 77 | Numpy array of scores of 0-5 78 | """ 79 | # assert x_left.shape[0] == x_right.shape[0] 80 | scores = {} 81 | for model_name, (model, preprocess_image) in self.models.items(): 82 | left_score = np.argmax(model.predict(preprocess_image(x_left)), axis=1)[0] 83 | right_score = np.argmax(model.predict(preprocess_image(x_right)), axis=1)[0] 84 | scores[model_name] = (left_score, right_score) 85 | if verbose == 1: 86 | logging.info('Risk factors: %s', scores) 87 | return get_simplified_score(scores) 88 | -------------------------------------------------------------------------------- /deepseenet/utils.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | 4 | import GPUtil 5 | 6 | 7 | def pick_device(): 8 | try: 9 | GPUtil.showUtilization() 10 | # Get the first available GPU 11 | DEVICE_ID_LIST = GPUtil.getFirstAvailable() 12 | DEVICE_ID = DEVICE_ID_LIST[0] # grab first element from list 13 | # Set CUDA_VISIBLE_DEVICES to mask out all other GPUs than the first available device id 14 | os.environ["CUDA_VISIBLE_DEVICES"] = str(DEVICE_ID) 15 | logging.debug('Device ID (unmasked): ' + str(DEVICE_ID)) 16 | except: 17 | logging.exception('Cannot detect GPUs') 18 | 19 | 20 | def crop2square(img): 21 | """ 22 | Crop the image to a square based on the short edge. 23 | 24 | Args: 25 | img: PIL Image instance. 26 | 27 | Returns: 28 | A PIL Image instance. 29 | """ 30 | short_side = min(img.size) 31 | x0 = (img.size[0] - short_side) / 2 32 | y0 = (img.size[1] - short_side) / 2 33 | x1 = img.size[0] - x0 34 | y1 = img.size[1] - y0 35 | return img.crop((x0, y0, x1, y1)) 36 | 37 | 38 | def cal_chunk_number(total_size, batch_size): 39 | if total_size % batch_size == 0: 40 | return total_size // batch_size 41 | else: 42 | return (total_size // batch_size) + 1 43 | -------------------------------------------------------------------------------- /docs/images/Fig1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncbi-nlp/DeepSeeNet/fb0c3a3d907756abf6f4a2d3a7f58a37d864b4a9/docs/images/Fig1.png -------------------------------------------------------------------------------- /docs/images/Fig5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncbi-nlp/DeepSeeNet/fb0c3a3d907756abf6f4a2d3a7f58a37d864b4a9/docs/images/Fig5.png -------------------------------------------------------------------------------- /docs/images/Fig6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncbi-nlp/DeepSeeNet/fb0c3a3d907756abf6f4a2d3a7f58a37d864b4a9/docs/images/Fig6.png -------------------------------------------------------------------------------- /docs/images/Tab4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncbi-nlp/DeepSeeNet/fb0c3a3d907756abf6f4a2d3a7f58a37d864b4a9/docs/images/Tab4.png -------------------------------------------------------------------------------- /docs/images/dhhs-logo-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 12 | 14 | 17 | 21 | 22 | 26 | 27 | 31 | 35 | 39 | 43 | 47 | 49 | 50 | 54 | 55 | 59 | 63 | 68 | 69 | 73 | 74 | 77 | 81 | 90 | 91 | 97 | 98 | 103 | 110 | 113 | 116 | 117 | 121 | 122 | 126 | 130 | 134 | 139 | 140 | 144 | 145 | 148 | 152 | 156 | 161 | 164 | 165 | 169 | 170 | 174 | 175 | 178 | 179 | 180 | 184 | 185 | 186 | 189 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /docs/images/nih-logo-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 12 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/images/nlm-logo-letters-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /docs/images/usagov-logo-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 12 | 13 | 14 | 15 | 19 | 22 | 24 | 26 | 27 | 28 | 32 | 35 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | DeepSeeNet: A deep learning framework for classifying patient-based age-related macular degeneration severity in 12 | retinal color fundus photographs 13 | 14 | 80 | 81 | 82 | 83 |
84 |
85 |
86 |
87 |
88 |

DeepSeeNet: A deep learning framework for classifying patient-based 89 | age-related macular degeneration severity in retinal color fundus photographs

90 |
91 |
92 |
Yifan Peng1*, Shazia Dharssi1,2*, Qingyu Chen1, Tiarnan D. Keenan2, Elvira Agrón2, Wai Wong2, Emily Y. Chew2†, Zhiyong Lu1†
93 |

1. National Center for Biotechnology Information (NCBI), National Library of Medicine (NLM), National Institutes of Health (NIH), Bethesda, Maryland, United States;

94 |

2. National Eye Institute (NEI), National Institutes of Health (NIH), Bethesda, Maryland, United States;

95 |

* These authors contributed equally to this work.

96 |

† zhiyong.lu@nih.gov; echew@nei.nih.gov

97 |
98 |
99 |
> Source code: https://github.com/ncbi-nlp/DeepSeeNet
100 |
101 |
102 |
103 |
104 | 105 | 106 |
107 |
108 |
109 |
110 |
We developed a deep learning framework that can classify retinal color fundus photographs into a 6 class patient-based age-related macular degeneration (AMD) severity score at a level that exceeds retinal specialists.
111 |

Age-related macular degeneration (AMD) is the leading cause of incurable blindness worldwide in people over the age of 65. The Age-Related Eye Disease Study (AREDS) Simplified Severity Scale uses two risk factors found in color fundus photographs (drusen and pigmentary abnormalities) to provide convenient risk categories for the development of late AMD. However, manual assignment can still be time consuming, expensive, and requires domain expertise.

112 |

Our model, DeepSeeNet, mimics the human grading process by first detecting risk factors for each eye (large drusen and pigmentary abnormalities) and subsequently calculates patient-based AMD severity scores. DeepSeeNet was trained and validated on 59,302 color fundus photographs from 4,549 participants.

113 |
114 |
115 |
116 |
117 |
118 | 119 |
120 |
121 |
122 |
123 |
124 |
DeepSeeNet was trained on the NIH AREDS dataset, the largest publicly available dataset of color fundus images for AMD analysis
125 |

This dataset, released by the NIH, contains retinal color fundus images from over 4,549 patients. Grades obtained from a central reading center were used to calculate AMD severity scores for ground truth labels. Performance of DeepSeeNet was compared to the performance of retinal specialists, who independently assessed 450 AREDS participants as part of a qualification survey used to determine initial AMD severity for each eye.

126 |
127 |
128 |
129 |
130 | 131 |
132 |
133 |
134 |
135 |
Our model consistently exceeds retinal specialists on drusen and pigmentary abnormalities, and is comparable to retinal specialists on late AMD detection.
136 |

As seen to the right, DeepSeeNet's performance (accuracy=0.671; kappa=0.558) exceeds retinal specialists performance levels (accuracy=0.599; kappa=0.467) on identifying AREDS Simplified Severity Scale scores. Additionally, DeepSeeNet's performance was compared to two other deep learning models with different training strategies employed. Again, DeepSeeNet's performance is superior to both model performance levels.

137 |
138 |
139 |
140 |
141 |
142 | 143 |
144 |
145 |
146 |
147 |
Summary
148 |

While several automated deep learning systems have been developed for classifying color fundus photographs of individual eyes by AMD severity score, none to date have utilized a patient-based scoring system that employs images from both eyes to obtain one classification score for the individual.

149 |

DeepSeeNet, trained on one of the largest color fundus image datasets for AMD analysis, shows high classification accuracy in the AREDS dataset and can be used to assign individual patients to AMD risk categories based on the AREDS Simplified Severity Scale. DeepSeeNet performed better on patient-based, multi-class classification (accuracy=0.671; kappa=0.558) than retinal specialists (accuracy=0.599; kappa=0.467) with high AUCs in the detection of large drusen (0.94), pigmentary abnormalities (0.93) and late AMD (0.97), respectively. 150 | Its superior performance highlights the potential of deep learning systems to enhance clinical decision-making processes and allow for better understanding of retinal disease.

151 |
152 |
153 |
154 |
155 | 156 | 157 |
158 |
159 |
160 |
161 |
Acknowledgments
162 |

This work was supported by the Intramural Research Programs of the National Institutes of Health, National Library of Medicine and National Eye Institute.

163 |
164 |
165 |
166 |
167 | 168 |
169 |
170 | 176 |
177 | 178 | -------------------------------------------------------------------------------- /examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncbi-nlp/DeepSeeNet/fb0c3a3d907756abf6f4a2d3a7f58a37d864b4a9/examples/__init__.py -------------------------------------------------------------------------------- /examples/predict_drusen.py: -------------------------------------------------------------------------------- 1 | """ 2 | Predict the drusen size of color fundus photographs. 3 | 4 | Usage: 5 | predict_drusen [options] 6 | 7 | Options: 8 | -d Drusen model file. [default: areds] 9 | """ 10 | import logging 11 | import sys 12 | 13 | import docopt 14 | 15 | from deepseenet.deepseenet_drusen import DeepSeeNetDrusen, preprocess_image, get_drusen_size 16 | from deepseenet.utils import pick_device 17 | 18 | if __name__ == '__main__': 19 | argv = docopt.docopt(__doc__, argv=sys.argv[1:]) 20 | logging.basicConfig(level=logging.DEBUG) 21 | logging.debug(argv) 22 | 23 | pick_device() 24 | clf = DeepSeeNetDrusen(argv['-d']) 25 | x = preprocess_image(argv['']) 26 | score = clf.predict(x, verbose=1) 27 | print('The drusen score:', score) 28 | print('The drusen size:', get_drusen_size(score)) 29 | -------------------------------------------------------------------------------- /examples/predict_simplified_score.py: -------------------------------------------------------------------------------- 1 | """ 2 | Grades color fundus photographs using the AREDS Simplified Severity Scale. 3 | 4 | Usage: 5 | predict_simplified_score [options] 6 | 7 | Options: 8 | -d Drusen model path [default: areds] 9 | -p Pigment model path [default: areds] 10 | -a Advanced AMD model path [default: areds] 11 | """ 12 | import logging 13 | import sys 14 | 15 | import docopt 16 | import numpy as np 17 | from keras.preprocessing import image 18 | 19 | from deepseenet import deepseenet_simplified 20 | from deepseenet.utils import crop2square, pick_device 21 | 22 | 23 | def preprocess_image(image_path, target_size=(224, 224)): 24 | """ 25 | Loads an image into a Numpy array 26 | 27 | Args: 28 | image_path: Path or file object. 29 | model_name: only 'inceptionv3' supported 30 | target_size: 224x224 by default 31 | 32 | Returns: 33 | Numpy array 34 | """ 35 | logging.info('Processing: %s', image_path) 36 | img = crop2square(image.load_img(image_path)).resize(target_size) 37 | x = image.img_to_array(img) 38 | x = np.expand_dims(x, axis=0) 39 | return x 40 | 41 | 42 | if __name__ == '__main__': 43 | argv = docopt.docopt(__doc__, argv=sys.argv[1:]) 44 | logging.basicConfig(level=logging.DEBUG) 45 | logging.debug(argv) 46 | 47 | drusen_model = argv['-d'] 48 | pigment_model = argv['-p'] 49 | advanced_amd_model = argv['-a'] 50 | 51 | pick_device() 52 | clf = deepseenet_simplified.DeepSeeNetSimplifiedScore(drusen_model, pigment_model, advanced_amd_model) 53 | score = clf.predict(argv[''], argv[''], verbose=1) 54 | print('The simplified score:', score) 55 | -------------------------------------------------------------------------------- /examples/train.py: -------------------------------------------------------------------------------- 1 | """ 2 | Train an individual risk factor model. 3 | 4 | Usage: 5 | train [options] 6 | 7 | Options: 8 | --n_classes= Number of classes [default: 2] 9 | --prefix= Data directory [default: .] 10 | """ 11 | import logging 12 | import multiprocessing 13 | import os 14 | import sys 15 | 16 | import docopt 17 | import numpy as np 18 | import pandas as pd 19 | from keras import backend as K 20 | from keras import callbacks 21 | from keras.optimizers import Adam 22 | from keras.preprocessing import image 23 | 24 | from deepseenet import deepseenet_risk_factor 25 | from deepseenet.data_generator import DataGenerator 26 | from deepseenet.utils import pick_device, crop2square 27 | 28 | 29 | def preprocess_image(image_path): 30 | img = crop2square(image.load_img(image_path)).resize((224, 224)) 31 | x = image.img_to_array(img) 32 | x = np.expand_dims(x, axis=0) 33 | x = deepseenet_risk_factor.preprocess_input(x) 34 | return x 35 | 36 | 37 | def train(model, train_data, valid_data, best_model, batch_size=32, n_classes=2): 38 | early_stop = callbacks.EarlyStopping(monitor='val_loss', min_delta=K.epsilon(), patience=2, verbose=1) 39 | best_model_cp = callbacks.ModelCheckpoint(best_model, save_best_only=True, monitor='val_acc', verbose=1) 40 | 41 | optimizer = Adam(lr=1e-4, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False) 42 | 43 | if n_classes == 2: 44 | model.compile(optimizer, loss='binary_crossentropy', metrics=['accuracy']) 45 | else: 46 | model.compile(optimizer, loss='categorical_crossentropy', metrics=['accuracy']) 47 | 48 | cpu_count = multiprocessing.cpu_count() 49 | workers = max(int(cpu_count / 3), 1) 50 | 51 | train_generator = DataGenerator(train_data, preprocess_image=preprocess_image, 52 | batch_size=batch_size, n_classes=n_classes, shuffle=True) 53 | valid_generator = DataGenerator(valid_data, preprocess_image=preprocess_image, 54 | batch_size=batch_size, n_classes=n_classes, shuffle=False) 55 | train_chunck_number = train_generator.get_epoch_num() 56 | model.fit_generator( 57 | train_generator, 58 | class_weight=train_generator.class_weights(), 59 | use_multiprocessing=True, 60 | workers=workers, 61 | steps_per_epoch=train_chunck_number, 62 | callbacks=[early_stop, best_model_cp], 63 | epochs=100, 64 | validation_data=valid_generator, 65 | validation_steps=valid_generator.get_epoch_num(), 66 | verbose=1) 67 | 68 | 69 | def prep_instances(train_file, val_size=0.8, shuffle=True, parent='.'): 70 | """ 71 | Read the dataset. 72 | 73 | Args: 74 | train_file(str): the file path of training dataset 75 | val_size(float): should be between 0.0 and 1.0 and represent the proportion of the dataset to include in the 76 | validation split. 77 | shuffle(bool): Whether or not to shuffle the data before splitting. 78 | parent(str): data directory 79 | Returns: 80 | list: List containing train-validation split of inputs. 81 | """ 82 | df = pd.read_csv(train_file) 83 | rows = df.values.tolist() 84 | 85 | for i in range(len(rows)): 86 | rows[i][0] = os.path.join(parent, rows[i][0]) 87 | 88 | if shuffle: 89 | np.random.shuffle(rows) 90 | split_size = int(len(rows) * val_size) 91 | return rows[:split_size], rows[split_size:] 92 | 93 | 94 | if __name__ == '__main__': 95 | argv = docopt.docopt(__doc__, argv=sys.argv[1:]) 96 | logging.basicConfig(level=logging.DEBUG) 97 | logging.debug(argv) 98 | 99 | pick_device() 100 | n_classes = int(argv['--n_classes']) 101 | 102 | train_data, valid_data = prep_instances(argv[''], parent=argv['--prefix']) 103 | logging.info('Training instances: %s', len(train_data)) 104 | logging.info('Validation instances: %s', len(valid_data)) 105 | model = deepseenet_risk_factor.RiskFactorModel(n_classes=n_classes) 106 | train(model, train_data, valid_data, argv[''], n_classes=n_classes) 107 | 108 | -------------------------------------------------------------------------------- /examples/utils.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | import docopt 4 | 5 | 6 | def get_args(args): 7 | s = '' 8 | for k in args: 9 | s += ' {}: {}\n'.format(k, args[k]) 10 | return s 11 | 12 | 13 | def parse_args(doc, **kwargs): 14 | argv = docopt.docopt(doc, **kwargs) 15 | if argv['--verbose']: 16 | logging.basicConfig(level=logging.DEBUG) 17 | else: 18 | logging.basicConfig(level=logging.INFO) 19 | logging.debug('Arguments:\n%s', get_args(argv)) 20 | return argv -------------------------------------------------------------------------------- /images/deepseenet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncbi-nlp/DeepSeeNet/fb0c3a3d907756abf6f4a2d3a7f58a37d864b4a9/images/deepseenet.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | docutils==0.13.1 2 | docopt==0.6.2 3 | tqdm==4.28.1 4 | pytest==3.9.3 5 | numpy==1.21 6 | keras==2.2.4 7 | gputil==1.3.0 8 | sklearn=0.20.1 9 | opencv-python 10 | tensorflow 11 | Pillow==9.1.0 12 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncbi-nlp/DeepSeeNet/fb0c3a3d907756abf6f4a2d3a7f58a37d864b4a9/tests/__init__.py -------------------------------------------------------------------------------- /tests/context.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | import os 4 | import sys 5 | sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) 6 | 7 | import deepseenet.deepseenet_drusen 8 | import deepseenet.deepseenet_simplified 9 | -------------------------------------------------------------------------------- /tests/deepseenet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ncbi-nlp/DeepSeeNet/fb0c3a3d907756abf6f4a2d3a7f58a37d864b4a9/tests/deepseenet/__init__.py -------------------------------------------------------------------------------- /tests/deepseenet/test_get_file.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from ..context import deepseenet 4 | from keras.utils import get_file 5 | 6 | 7 | def test_get_file(): 8 | drusen_model = get_file( 9 | 'drusen_model.h5', 10 | deepseenet.deepseenet_drusen.DRUSEN_PATH, 11 | cache_dir='models', 12 | md5_hash=deepseenet.deepseenet_drusen.DRUSEN_MD5 13 | ) 14 | print(drusen_model) 15 | assert os.path.exists(drusen_model) 16 | -------------------------------------------------------------------------------- /tests/deepseenet/test_simplified_score.py: -------------------------------------------------------------------------------- 1 | from ..context import deepseenet 2 | 3 | 4 | def test_advanced_amd(): 5 | for drusen in (0, 1, 2): 6 | for pigment in (0, 1): 7 | scores = { 8 | 'drusen': (drusen, 0), 9 | 'pigment': (pigment, 0), 10 | 'advanced_amd': (0, 1) 11 | } 12 | assert deepseenet.deepseenet_simplified.get_simplified_score(scores) == 5 13 | scores['advanced_amd'] = (1, 0) 14 | assert deepseenet.deepseenet_simplified.get_simplified_score(scores) == 5 15 | scores['advanced_amd'] = (1, 1) 16 | assert deepseenet.deepseenet_simplified.get_simplified_score(scores) == 5 17 | 18 | 19 | def test_single_eye(): 20 | simple_scores = { 21 | (0, 0): 0, 22 | (0, 1): 1, 23 | (1, 0): 0, 24 | (1, 1): 1, 25 | (2, 0): 1, 26 | (2, 1): 2 27 | } 28 | scores = {'advanced_amd': (0, 0)} 29 | for k in simple_scores: 30 | scores['drusen'] = (k[0], 0) 31 | scores['pigment'] = (k[1], 0) 32 | assert deepseenet.deepseenet_simplified.get_simplified_score(scores) == simple_scores[k] 33 | scores['drusen'] = (0, k[0]) 34 | scores['pigment'] = (0, k[1]) 35 | assert deepseenet.deepseenet_simplified.get_simplified_score(scores) == simple_scores[k] 36 | scores['drusen'] = (k[0], 0) 37 | scores['pigment'] = (0, k[1]) 38 | assert deepseenet.deepseenet_simplified.get_simplified_score(scores) == simple_scores[k] 39 | scores['drusen'] = (k[0], 0) 40 | scores['pigment'] = (0, k[1]) 41 | assert deepseenet.deepseenet_simplified.get_simplified_score(scores) == simple_scores[k] 42 | 43 | 44 | def test_both_eyes(): 45 | simple_scores = { 46 | (0, 0): 0, 47 | (0, 1): 2, 48 | (1, 0): 1, 49 | (1, 1): 3, 50 | (2, 0): 2, 51 | (2, 1): 4 52 | } 53 | scores = {'advanced_amd': (0, 0)} 54 | for k in simple_scores: 55 | scores['drusen'] = (k[0], k[0]) 56 | scores['pigment'] = (k[1], k[1]) 57 | assert deepseenet.deepseenet_simplified.get_simplified_score(scores) == simple_scores[k] 58 | --------------------------------------------------------------------------------