{"id":13856932,"url":"https://github.com/gregwchase/eyenet","last_synced_at":"2025-07-13T19:33:25.331Z","repository":{"id":91094144,"uuid":"103049010","full_name":"gregwchase/eyenet","owner":"gregwchase","description":"Identifying diabetic retinopathy using convolutional neural networks","archived":false,"fork":false,"pushed_at":"2021-05-21T21:28:08.000Z","size":48161,"stargazers_count":195,"open_issues_count":3,"forks_count":76,"subscribers_count":17,"default_branch":"master","last_synced_at":"2024-08-06T03:03:17.390Z","etag":null,"topics":["deep-learning","keras","machine-learning","neural-network","retinopathy","tensorflow"],"latest_commit_sha":null,"homepage":"https://www.youtube.com/watch?v=pMGLFlgqxuY","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gregwchase.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2017-09-10T17:42:38.000Z","updated_at":"2024-07-22T06:27:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"a925408f-b3e2-401a-9c05-1cc728285645","html_url":"https://github.com/gregwchase/eyenet","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gregwchase%2Feyenet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gregwchase%2Feyenet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gregwchase%2Feyenet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gregwchase%2Feyenet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gregwchase","download_url":"https://codeload.github.com/gregwchase/eyenet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225912401,"owners_count":17544165,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deep-learning","keras","machine-learning","neural-network","retinopathy","tensorflow"],"created_at":"2024-08-05T03:01:19.393Z","updated_at":"2024-11-22T14:31:25.018Z","avatar_url":"https://github.com/gregwchase.png","language":"Python","funding_links":[],"categories":["Python","Projects"],"sub_categories":["Enhancement"],"readme":"# EyeNet\n\n## Detecting Diabetic Retinopathy With Deep Learning\n\n## Objective\n\nDiabetic retinopathy is the leading cause of blindness in the working-age population of the developed world. The condition is estimated to affect over 93 million people.\n\nThe need for a comprehensive and automated method of diabetic retinopathy screening has long been recognized, and previous efforts have made good progress using image classification, pattern recognition, and machine learning. With photos of eyes as input, the goal of this capstone is to create a new model, ideally resulting in realistic clinical potential.\n\nThe motivations for this project are twofold:\n\n* Image classification has been a personal interest for years, in addition to classification\non a large scale data set.\n\n* Time is lost between patients getting their eyes scanned (shown below), having their images analyzed by doctors, and scheduling a follow-up appointment. By processing images in real-time, EyeNet would allow people to seek \u0026 schedule treatment the same day.\n\n\n\u003cp align = \"center\"\u003e\n\u003cimg align=\"center\" src=\"images/readme/dr_scan.gif\" alt=\"Retinopathy GIF\"/\u003e\n\u003c/p\u003e\n\n\n## Table of Contents\n1. [Data](#data)\n2. [Exploratory Data Analysis](#exploratory-data-analysis)\n3. [Preprocessing](#preprocessing)\n    * [Download Images to EC2](#download-all-images-to-ec2)\n    * [Crop \u0026 Resize Images](#crop-and-resize-all-images)\n    * [Rotate and Mirror All Images](#rotate-and-mirror-all-images)\n4. [CNN Architecture](#neural-network-architecture)\n5. [Results](#results)\n6. [Next Steps](#next-steps)\n7. [References](#references)\n\n## Data\n\nThe data originates from a [2015 Kaggle competition](https://www.kaggle.com/c/diabetic-retinopathy-detection). However, is an atypical Kaggle dataset. In most Kaggle competitions, the data has already been cleaned, giving the data scientist very little to preprocess. With this dataset, this isn't the case.\n\nAll images are taken of different people, using different cameras, and of different sizes. Pertaining to the [preprocessing](#preprocessing) section, this data is extremely noisy, and requires multiple preprocessing steps to get all images to a useable format for training a model.\n\nThe training data is comprised of 35,126 images, which are augmented during preprocessing.\n\n\n## Exploratory Data Analysis\n\nThe very first item analyzed was the training labels. While there are\nfive categories to predict against, the plot below shows the severe class imbalance in the original dataset.\n\n\u003cp align = \"center\"\u003e\n\u003cimg align=\"center\" src=\"images/eda/DR_vs_Frequency_tableau.png\" alt=\"EDA - Class Imbalance\" height=\"458\" width=\"736\" /\u003e\n\u003c/p\u003e\n\nOf the original training data, 25,810 images are classified as not having retinopathy,\nwhile 9,316 are classified as having retinopathy.\n\nDue to the class imbalance, steps taken during [preprocessing](#preprocessing) in order to rectify the imbalance, and when training the model.\n\nFurthermore, the variance between images of the eyes is extremely high. The first two rows of images\nshow class 0 (no retinopathy); the second two rows show class 4 (proliferative retinopathy).\n\n\n\u003cp align = \"center\"\u003e\n\u003cimg align=\"center\" src=\"images/readme/No_DR_white_border_1.png\" alt=\"No DR 1\"/\u003e\n\u003cimg align=\"center\" src=\"images/readme/No_DR_white_border_2.png\" alt=\"No DR 2\"/\u003e\n\u003cbr\u003e\u003c/br\u003e\n\u003cimg align=\"center\" src=\"images/readme/Proliferative_DR_white_border_1.png\" alt=\"Proliferative DR 1\"/\u003e\n\u003cimg align=\"center\" src=\"images/readme/Proliferative_DR_white_border_2.png\" alt=\"Proliferative DR 2\"/\u003e\n\u003c/p\u003e\n\n\n\n## Preprocessing\n\nThe preprocessing pipeline is the following:\n\n1. Download all images to EC2 using the [download script](src/download_data.sh).\n2. Crop \u0026 resize all images using the [resizing script](src/resize_images.py) and the [preprocessing script](src/preprocess_images.py).\n3. Rotate \u0026 mirror all images using the [rotation script](src/rotate_images.py).\n4. Convert all images to array of NumPy arrays, using the [conversion script](src/image_to_array.py).\n\n### Download All Images to EC2\nThe images were downloaded using the Kaggle CLI. Running this on an EC2 instance\nallows you to download the images in about 30 minutes. All images are then placed\nin their respective folders, and expanded from their compressed files. In total,\nthe original dataset totals 35 gigabytes.\n\n### Crop and Resize All Images\nAll images were scaled down to 256 by 256. Despite taking longer to train, the\ndetail present in photos of this size is much greater then at 128 by 128.\n\nAdditionally, 403 images were dropped from the training set. Scikit-Image raised\nmultiple warnings during resizing, due to these images having no color space.\nBecause of this, any images that were completely black were removed from the\ntraining data.\n\n### Rotate and Mirror All Images\nAll images were rotated and mirrored.Images without retinopathy were mirrored;\nimages that had retinopathy were mirrored, and rotated 90, 120, 180, and 270\ndegrees.\n\nThe first images show two pairs of eyes, along with the black borders. Notice in\nthe cropping and rotations how the majority of noise is removed.\n\n![Unscaled Images](images/readme/sample_images_unscaled.jpg)\n![Rotated Images](images/readme/17_left_horizontal_white.jpg)\n\nAfter rotations and mirroring, the class imbalance is rectified, with a few thousand\nmore images having retinopathy. In total, there are 106,386 images being processed\nby the neural network.\n\n\n\u003cp align = \"center\"\u003e\n\u003cimg align=\"center\" src=\"images/eda/DR_vs_frequency_balanced.png\" alt=\"EDA - Corrected Class Imbalance\" width=\"664\" height=\"458\" /\u003e\n\u003c/p\u003e\n\n## Neural Network Architecture\n\nThe model is built using Keras, utilizing TensorFlow as the backend.\nTensorFlow was chosen as the backend due to better performance over\nTheano, and the ability to visualize the neural network using TensorBoard.\n\nFor predicting two categories, EyeNet utilizes three convolutional layers,\neach having a depth of 32. A Max Pooling layer is applied after all three\nconvolutional layers with size (2,2).\n\nAfter pooling, the data is fed through a single dense layer of size 128,\nand finally to the output layer, consisting of 2 softmax nodes.\n\n![TensorBoard CNN](images/readme/cnn_two_classes_tensorboard.png)\n\n## Results\nThe EyeNet classifier was created to determine if a patient has retinopathy. The current model returns the following scores.\n\n\n| Metric | Value |\n| :-----: | :-----: |\n| Accuracy (Train) | 82% |\n| Accuracy (Test) | 80% |\n| Precision | 88% |\n| Recall | 77% |\n\n\nSo, why does the neural network perform this way? Besides the class imbalance,\nthe cropping is definitely helping in the network's performance. By not having\nextra black parts in the images, the network is able to process only the eye\nitself.\n\n## Next Steps\n1. Program the neural network to retrain with new photos. This is a common practice,\nand only serves to optimize the model. Checks would be put in place to validate the\nimages before being added to the classifier, in order to prevent low quality images\nfrom altering the classifier too drastically.\n\n\n2. Port the Keras model to CoreML, and deploy to an EyeNet iOS application. CoreML\nis a framework designed by Apple for adding machine learning to iOS devices.\nThis allows the ability of Python developers to export their models, convert the\nfile to a `.mlmodel` file, and add the file to the iOS development cycle.\n\nFurthermore, the model is able to perform classification on the local\ndevice. There is no need for an internet connection for the application to work. Because of this, the ability to use EyeNet in remote areas is further justified, and that much easier.\n\n\n## References\n\n1. [What is Diabetic Retinopathy?](http://www.mayoclinic.org/diseases-conditions/diabetic-retinopathy/basics/definition/con-20023311)\n\n2. [Diabetic Retinopathy Winners' Interview: 4th place, Julian \u0026 Daniel](http://blog.kaggle.com/2015/08/14/diabetic-retinopathy-winners-interview-4th-place-julian-daniel/)\n\n3. [TensorFlow: Machine Learning For Everyone](https://youtu.be/mWl45NkFBOc)\n\n## Tech Stack\n\u003cimg align=\"center\" src=\"images/tech_stack/tech_stack_banner.png\" alt=\"tech_stack_banner\"/\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgregwchase%2Feyenet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgregwchase%2Feyenet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgregwchase%2Feyenet/lists"}