{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":14774,"databundleVersionId":875431,"sourceType":"competition"}],"dockerImageVersionId":30918,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"<div style=\"border:5px solid #85929e; border-radius:10px; padding:5px; padding-top:25px; background-color:#2c2c2c\">\n<img src=\"https://eye7.b-cdn.net/wp-content/uploads/close-up-of-eye-with-blindness.jpg\" style=\"width: 400px;height:150px;  border-radius: 25px; display: block; margin:auto; \">\n<p style=\"margin-top:10px;font-size: 20px; text-align: center; color: #1baad4 ; font-weight: bold;\">Blindness Detection Using CNN</p></div>","metadata":{}},{"cell_type":"markdown","source":"\n\nImagine losing your sight simply because the disease wasn’t detected in time. Diabetic retinopathy is a leading cause of blindness, especially in rural areas where medical care is scarce. But what if we could predict blindness before it happens?\n\nWith Convolutional Neural Networks (CNNs), we can! Instead of relying on slow, manual diagnosis, AI can scan thousands of eye images instantly, identifying the disease before it causes irreversible damage.\n\nBy developing CNN models for early detection, we can save millions from blindness and even expand AI’s power to detect diseases like glaucoma and macular degeneration.🚀","metadata":{}},{"cell_type":"markdown","source":"# **Import Libraries**","metadata":{}},{"cell_type":"code","source":"import os\nimport warnings \nimport cv2 as cv\nimport numpy as np \nimport pandas as pd\nimport seaborn as sns \nimport matplotlib.pyplot as plt\nfrom tensorflow import keras\nfrom tensorflow.keras import Sequential\nfrom tensorflow.keras.losses import SparseCategoricalCrossentropy\nfrom tensorflow.keras.callbacks import EarlyStopping\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\nfrom sklearn.metrics import confusion_matrix,ConfusionMatrixDisplay\nwarnings.filterwarnings(\"ignore\")\nsns.set_style(style=\"darkgrid\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-03-05T04:44:59.302853Z","iopub.execute_input":"2025-03-05T04:44:59.303147Z","iopub.status.idle":"2025-03-05T04:45:13.583133Z","shell.execute_reply.started":"2025-03-05T04:44:59.303114Z","shell.execute_reply":"2025-03-05T04:45:13.582398Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Read Data**","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(\"/kaggle/input/aptos2019-blindness-detection/train.csv\")\nprint(df.shape)\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T05:07:50.894484Z","iopub.execute_input":"2025-03-05T05:07:50.894825Z","iopub.status.idle":"2025-03-05T05:07:50.909202Z","shell.execute_reply.started":"2025-03-05T05:07:50.894797Z","shell.execute_reply":"2025-03-05T05:07:50.908266Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"> **Data consist of two columns, first column have name of image and second column have classify of diagnosis of image**\n","metadata":{}},{"cell_type":"markdown","source":"<ul style=\"font-size:14px; font-style:italic; list-style-type: circle; font-weight:bold;\">\n    <li>0 -> No DR</li>\n    <li>1 -> Mild</li>\n    <li>2 -> Moderate</li>\n    <li>3 -> Severe</li>\n    <li>4 - Proliferative DR</li>\n</ul>","metadata":{}},{"cell_type":"markdown","source":"## **Visualize Distribution**","metadata":{}},{"cell_type":"code","source":"data = df.replace({\"diagnosis\":{0:\"No DR\",1:\"Mild\",2:\"Moderate\",3:\"Severe\",4:\"Proliferative DR\"}})\ndiagnosis_count = data.diagnosis.value_counts()\nsns.countplot(data=data,x=\"diagnosis\",order=diagnosis_count.index)\nplt.xlabel(\"Diagnosis\",weight=\"bold\",size=15)\nplt.ylabel(\"Freq\",weight=\"bold\",size=15)\nfor i,v in enumerate(diagnosis_count.values,0):\n    text = f\"{v*100/len(data):0.2f}%\"\n    plt.text(s=text,x=i,y=v+10,ha=\"center\",weight=\"bold\")\nplt.show()\ndel data","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T04:45:13.625705Z","iopub.execute_input":"2025-03-05T04:45:13.625944Z","iopub.status.idle":"2025-03-05T04:45:13.902392Z","shell.execute_reply.started":"2025-03-05T04:45:13.625924Z","shell.execute_reply":"2025-03-05T04:45:13.901446Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## **Read Image & preprocessing**","metadata":{}},{"cell_type":"markdown","source":"> **From the visualization, we can observe that 'Proliferative DR' and 'Severe' are the least represented classes in the dataset. So I tried increase those data horizontal flip**\n","metadata":{}},{"cell_type":"code","source":"X = []\ny = []\nfor target in range(5):\n    for image in df[df[\"diagnosis\"]==target][\"id_code\"]:\n        path = os.path.join(\"/kaggle/input/aptos2019-blindness-detection/train_images\",f\"{image}.png\")\n        img = cv.imread(path,1)\n        img = cv.resize(img,(224,224))\n        img = img/255.0\n        X.append(img)\n        y.append(target)\n        if target in (3,4) :\n            X.append(cv.flip(img,1))\n            y.append(target)\nX = np.asarray(X)\ny = np.asarray(y)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T04:45:13.903705Z","iopub.execute_input":"2025-03-05T04:45:13.903951Z","iopub.status.idle":"2025-03-05T04:51:41.641018Z","shell.execute_reply.started":"2025-03-05T04:45:13.903931Z","shell.execute_reply":"2025-03-05T04:51:41.640120Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data = pd.Series(y)\ndata = data.replace({0:\"No DR\",1:\"Mild\",2:\"Moderate\",3:\"Severe\",4:\"Proliferative DR\"})\ndiagnosis_count = data.value_counts()\nsns.countplot(x=data,order=diagnosis_count.index)\nplt.xlabel(\"Diagnosis\",weight=\"bold\",size=15)\nplt.ylabel(\"Freq\",weight=\"bold\",size=15)\nfor i,v in enumerate(diagnosis_count.values,0):\n    text = f\"{v*100/len(data):0.2f}%\"\n    plt.text(s=text,x=i,y=v+10,ha=\"center\",weight=\"bold\")\nplt.show()\ndel data","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T04:51:41.641796Z","iopub.execute_input":"2025-03-05T04:51:41.642028Z","iopub.status.idle":"2025-03-05T04:51:41.823570Z","shell.execute_reply.started":"2025-03-05T04:51:41.642010Z","shell.execute_reply":"2025-03-05T04:51:41.822630Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## **Splitting**","metadata":{}},{"cell_type":"code","source":"x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=0,shuffle=True)\nx_test,x_val,y_test,y_val = train_test_split(x_test,y_test,test_size=0.5,random_state=0,shuffle=True)\ndel X,y","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T04:51:41.824502Z","iopub.execute_input":"2025-03-05T04:51:41.824853Z","iopub.status.idle":"2025-03-05T04:51:43.358086Z","shell.execute_reply.started":"2025-03-05T04:51:41.824822Z","shell.execute_reply":"2025-03-05T04:51:43.357243Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Workin On Model**","metadata":{}},{"cell_type":"markdown","source":"## **Building Model**","metadata":{}},{"cell_type":"code","source":"model = Sequential()\n\n# Input Layer\nmodel.add(keras.layers.InputLayer(shape=(224,224,3)))\n\n\n# CNN Layer1   \nmodel.add(keras.layers.Conv2D(32,(3,3),padding=\"valid\",activation=\"relu\")) \nmodel.add(keras.layers.MaxPool2D((2,2),strides=2)) \n\n# CNN Layer2\nmodel.add(keras.layers.Conv2D(64,(3,3),padding=\"valid\",activation=\"relu\"))\nmodel.add(keras.layers.MaxPool2D((3,3),strides=3))\n\n# CNN Layer3\nmodel.add(keras.layers.Conv2D(128,(3,3),padding=\"valid\",activation=\"relu\"))\nmodel.add(keras.layers.MaxPool2D((3,3),strides=3))\n\n# CNN Layer4\nmodel.add(keras.layers.Conv2D(256,(3,3),padding=\"valid\",activation=\"relu\"))\nmodel.add(keras.layers.Dropout(0.5))\nmodel.add(keras.layers.MaxPool2D((3,3),strides=3))\n\n# Flatten Layer\nmodel.add(keras.layers.Flatten())\n\n# Fully Connected layer\nmodel.add(keras.layers.Dense(256,activation=\"relu\"))\nmodel.add(keras.layers.Dense(128,activation=\"relu\"))\nmodel.add(keras.layers.Dense(5,activation=\"softmax\"))\n\n# Compile\nmodel.compile(loss=SparseCategoricalCrossentropy(),metrics=[\"accuracy\"],optimizer=\"adam\")\n\n# Summary for model\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T04:58:11.630695Z","iopub.execute_input":"2025-03-05T04:58:11.631005Z","iopub.status.idle":"2025-03-05T04:58:11.771037Z","shell.execute_reply.started":"2025-03-05T04:58:11.630984Z","shell.execute_reply":"2025-03-05T04:58:11.770338Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## **Model Training**","metadata":{}},{"cell_type":"code","source":"es = EarlyStopping(monitor='val_accuracy',\n                   mode=\"max\",\n                   verbose=1,\n                   patience=6,\n                   restore_best_weights=True)\n\n\nhistory = model.fit(x_train,y_train,\n                    epochs=25,batch_size=190,\n                    validation_data=[x_val,y_val],\n                    callbacks=[es])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T04:58:14.754738Z","iopub.execute_input":"2025-03-05T04:58:14.755048Z","iopub.status.idle":"2025-03-05T04:59:32.393481Z","shell.execute_reply.started":"2025-03-05T04:58:14.755027Z","shell.execute_reply":"2025-03-05T04:59:32.392754Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(13,5))\nplt.subplot(1,2,1)\nplt.title(\"Accuracy\")\nplt.plot(history.history[\"val_accuracy\"],label=\"val accuracy\")\nplt.plot(history.history[\"accuracy\"],label=\"accuracy\")\nplt.legend()\nplt.subplot(1,2,2)\nplt.title(\"Loss\")\nplt.plot(history.history[\"val_loss\"],label=\"val loss\")\nplt.plot(history.history[\"loss\"],label=\"loss\")\nplt.legend()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T04:59:39.240292Z","iopub.execute_input":"2025-03-05T04:59:39.240632Z","iopub.status.idle":"2025-03-05T04:59:39.697232Z","shell.execute_reply.started":"2025-03-05T04:59:39.240603Z","shell.execute_reply":"2025-03-05T04:59:39.696277Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## **Model Evaluation**","metadata":{}},{"cell_type":"code","source":"y_predicted = model.predict(x_test)\ny_predicted = np.argmax(y_predicted,axis=1)\ncm = confusion_matrix(y_test,y_predicted)\ncmd = ConfusionMatrixDisplay(confusion_matrix = cm, display_labels = [\"No DR\",\"Mild\",\"Moderate\",\"Severe\",\"Proliferative DR\"])\ncmd.plot(cmap=plt.cm.Blues, values_format='d',xticks_rotation=\"vertical\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T04:59:57.250395Z","iopub.execute_input":"2025-03-05T04:59:57.250784Z","iopub.status.idle":"2025-03-05T04:59:59.234714Z","shell.execute_reply.started":"2025-03-05T04:59:57.250757Z","shell.execute_reply":"2025-03-05T04:59:59.233858Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"acc = accuracy_score(y_test,y_predicted)\nprint(f\"Test score: {acc*100:.2f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T05:00:08.774765Z","iopub.execute_input":"2025-03-05T05:00:08.775177Z","iopub.status.idle":"2025-03-05T05:00:08.781476Z","shell.execute_reply.started":"2025-03-05T05:00:08.775144Z","shell.execute_reply":"2025-03-05T05:00:08.780477Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## **Random Test**","metadata":{}},{"cell_type":"code","source":"decode = {0:\"No DR\",1:\"Mild\",2:\"Moderate\",3:\"Severe\",4:\"Proliferative DR\"}\nplt.figure(figsize=(15,5))\nfor i,test in enumerate(np.random.randint(0,len(df)-1,8),1):\n    plt.subplot(2,4,i)\n    image = df.loc[test,\"id_code\"]\n    path = os.path.join(\"/kaggle/input/aptos2019-blindness-detection/train_images\",f\"{image}.png\")\n    img = cv.imread(path,1)\n    img = cv.resize(img,(224,224))\n    plt.imshow(cv.cvtColor(img,cv.COLOR_BGR2RGB))\n    img = img/255.0\n    img = np.expand_dims(img,axis=0)\n    res = model.predict(img)\n    res = f\"Prediction is {decode[np.argmax(res)]}\"\n    true = f\"Real is {decode[df.loc[test,'diagnosis']]}\"\n    plt.axis(\"off\")\n    plt.text(x=10,y=20,s=true,color=\"Blue\",weight=\"bold\",backgroundcolor=\"Gray\",size=8)\n    plt.text(x=10,y=215,s=res,color=\"Blue\",weight=\"bold\",backgroundcolor=\"Gray\",size=8)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T05:07:56.380427Z","iopub.execute_input":"2025-03-05T05:07:56.380778Z","iopub.status.idle":"2025-03-05T05:07:58.871061Z","shell.execute_reply.started":"2025-03-05T05:07:56.380750Z","shell.execute_reply":"2025-03-05T05:07:58.870153Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## **Save Model**","metadata":{}},{"cell_type":"code","source":"model.save(\"Blind_DetectionV1.keras\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T05:03:08.027802Z","iopub.execute_input":"2025-03-05T05:03:08.028141Z","iopub.status.idle":"2025-03-05T05:03:08.117052Z","shell.execute_reply.started":"2025-03-05T05:03:08.028113Z","shell.execute_reply":"2025-03-05T05:03:08.116087Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"del x_train,x_test,x_val,y_train,y_test,y_val,history,df","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Submit file**","metadata":{}},{"cell_type":"code","source":"df2 = pd.read_csv(\"/kaggle/input/aptos2019-blindness-detection/test.csv\")\ndf2.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T05:11:01.357826Z","iopub.execute_input":"2025-03-05T05:11:01.358163Z","iopub.status.idle":"2025-03-05T05:11:01.369366Z","shell.execute_reply.started":"2025-03-05T05:11:01.358139Z","shell.execute_reply":"2025-03-05T05:11:01.368536Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"diagnosis = []\nfor j,i in enumerate(df2[\"id_code\"],1):\n    path=os.path.join(\"/kaggle/input/aptos2019-blindness-detection/test_images\",f\"{i}.png\")\n    img = cv.imread(path,1)\n    img = cv.resize(img,(224,224))\n    img = img/255.0\n    diagnosis.append(img)\n    if j%500==0:\n        print(\"Done of 500 images\")\ndiagnosis = np.asarray(diagnosis)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T05:18:14.888245Z","iopub.execute_input":"2025-03-05T05:18:14.888535Z","iopub.status.idle":"2025-03-05T05:19:16.164219Z","shell.execute_reply.started":"2025-03-05T05:18:14.888514Z","shell.execute_reply":"2025-03-05T05:19:16.163533Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"diagnosis = model.predict(diagnosis)\ndiagnosis = np.argmax(diagnosis,axis=1)\ndf2[\"diagnosis\"]=diagnosis\ndf2.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T05:19:55.835459Z","iopub.execute_input":"2025-03-05T05:19:55.835792Z","iopub.status.idle":"2025-03-05T05:20:01.683799Z","shell.execute_reply.started":"2025-03-05T05:19:55.835768Z","shell.execute_reply":"2025-03-05T05:20:01.682890Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df2.to_csv(path_or_buf=\"submission.csv\",index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-05T05:21:30.754174Z","iopub.execute_input":"2025-03-05T05:21:30.754495Z","iopub.status.idle":"2025-03-05T05:21:30.765361Z","shell.execute_reply.started":"2025-03-05T05:21:30.754472Z","shell.execute_reply":"2025-03-05T05:21:30.764652Z"}},"outputs":[],"execution_count":null}]}