{"cells":[{"metadata":{"_uuid":"1db83ea6-6950-481e-b403-ae7937aa9928","_cell_guid":"610beef5-27bb-49c6-b360-b0bfeaf88a67","trusted":true},"cell_type":"markdown","source":"> > ## Diabetic Retinopath detection with CNN\n### ---\n### Diabetic retinopathy affects blood vessels in the light-sensitive tissue called the retina that lines the back of the eye. It is the most common cause of vision loss among people with diabetes and the leading cause of vision impairment and blindness among working-age adults. It don't have any earaly symtoms. As of now, Retena photography is a way to detect the stage of Blindness. Automating it with ml, will help a lot in health domain. \n \n### ---------------------------------------\n### 1. [Import Required Libraries](#1)\n### 2. [Loading Data ](#2)\n### 3. [Data Visualization](#3)\n### 4. [Train and Test dataset](#4)\n### 5. [Data Pre-Processing](#6)\n### 6. [Image Data Generator](#7)\n### 7. [Model Architecture Design](#8)\n### 8. [Keras Callback Funcations](#9)\n### 9. [Transfer Learning](#10)\n### 10. [Validation Accuracy & Loss](#11)\n### 11. [Validation Accuracy](#12)\n### 12. [Test-Time Augmentation](#13)\n### 13. [Visualization Test Result](#14)\n### ------------------------------------\n\n\n## Stages Of Diabetic Retinopathy\n### - NO DR\n### - Non-Proliferative DR (NPDR)\n### - Proliferative DR (PDR)"},{"metadata":{"_uuid":"61fe9ee1-c71d-4208-8f89-d1daf053835b","_cell_guid":"d366eb9b-526a-477f-9ce6-27783d2d8db7","trusted":true},"cell_type":"markdown","source":"<a id=\"1\"></a> \n# Import Libraries"},{"metadata":{"_uuid":"5cc1e93e-8e81-45ab-9298-f4498a6f1106","_cell_guid":"3155c4ee-dd48-4a1f-9692-c71684aa2830","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport cv2\nimport PIL\nimport gc\nimport psutil\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.compat.v1 import set_random_seed\nfrom tqdm import tqdm\nfrom math import ceil\nimport math\nimport sys\nimport gc\n\nimport keras\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.preprocessing.image import load_img\nfrom keras.preprocessing.image import array_to_img\nfrom keras.preprocessing.image import img_to_array\nfrom keras.applications.resnet50 import ResNet50\nfrom keras.applications.resnet50 import preprocess_input\nfrom keras.models import Model\nfrom keras.models import Sequential\nfrom keras.layers.convolutional import Conv2D\nfrom keras.layers.convolutional import MaxPooling2D\nfrom keras.layers.pooling import GlobalAveragePooling2D\nfrom keras.layers import Input\nfrom keras.layers.core import Dropout\nfrom keras.layers.core import Flatten\nfrom keras.layers.core import Dense\nfrom keras.callbacks import ModelCheckpoint\nfrom keras.callbacks import ReduceLROnPlateau\nfrom keras.callbacks import EarlyStopping\n\nfrom keras.activations import softmax\nfrom keras.activations import elu\nfrom keras.activations import relu\nfrom keras.optimizers import Adam\nfrom keras.optimizers import RMSprop\nfrom keras.optimizers import SGD\nfrom keras.layers.normalization import BatchNormalization\n\ngc.enable()\n\nprint(os.listdir(\"../input/\"))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7a68cef2-2971-4fc9-b916-95cca19ac7a1","_cell_guid":"c7f42c4f-f77b-4293-970a-8e9a6da825f1","trusted":true},"cell_type":"markdown","source":"<a id=\"2\"></a>\n## Exploratory Data Analysis\n#### - Loading Data \n#### - Data Disribution\n#### - Data Visualization\n"},{"metadata":{"_uuid":"1b175892-88ca-4eb8-bfc9-27c9a498be15","_cell_guid":"f6a09762-cfeb-4582-89bc-73ab5e7dad3c","trusted":true},"cell_type":"code","source":"SEED = 7\nnp.random.seed(SEED)\nset_random_seed(SEED)\ndir_path = \"../input/drdataset2/DR/\"\nIMG_DIM = 256  # 224 399 #\nBATCH_SIZE = 12\nCHANNEL_SIZE = 3\nNUM_EPOCHS = 17\nTRAIN_DIR = 'train_image'\nTEST_DIR = 'test_image'\nFREEZE_LAYERS = 2  # freeze the first this many layers for training\nCLASSS = {0: \"No DR\", 1: \"Non-Proliferative DR\", 2: \"Proliferative DR\", 3: \"Severe\", 4: \"Proliferative DR\"}","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b70a35a8-b26a-4e2f-83e5-d353c8a989fa","_cell_guid":"cc36bb57-648c-4da8-b8fc-f71ae211f749","trusted":true},"cell_type":"markdown","source":"<a id=\"2\"></a>\n### Loading Data"},{"metadata":{"_uuid":"9c80982d-ac9c-4662-9788-14be0a92ad93","_cell_guid":"07f76ffc-f58e-4148-a654-620c47f6d2bf","trusted":true},"cell_type":"code","source":"df_train = pd.read_csv(os.path.join(dir_path, \"train.csv\"))\ndf_test = pd.read_csv(os.path.join(dir_path, \"test.csv\"))\nNUM_CLASSES = df_train['diagnosis'].nunique()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"aa15066f-9f4b-40b2-a7f3-633f532ad945","_cell_guid":"f77416e5-7503-4f1f-b5a6-eefcc45b36a1","trusted":true},"cell_type":"code","source":"print(\"Training set has {} samples and {} classes.\".format(df_train.shape[0], df_train.shape[1]))\nprint(\"Testing set has {} samples and {} classes.\".format(df_test.shape[0], df_test.shape[1]))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"6\"></a>\n### Split DataSet"},{"metadata":{"trusted":true},"cell_type":"code","source":"x_train, x_test, y_train, y_test = train_test_split(df_train.id_code, df_train.diagnosis, test_size=0.15,\n                                                    random_state=SEED, stratify=df_train.diagnosis)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"62aed6f5-6de2-48b6-806a-4861169f3f84","_cell_guid":"1ef3d091-46d3-4009-9b50-275e9d5f28ac","trusted":true},"cell_type":"markdown","source":"<a id=\"3\"></a>\n## Data Visualization\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"chat_data = df_train.diagnosis.value_counts()\nchat_data.plot(kind='bar');\nplt.title('Sample Per Class');\nplt.show()\nplt.pie(chat_data, autopct='%1.1f%%', shadow=True, labels=[\"No DR\", \"Non-Proliferative DR (NPDR)\", \"Proliferative DR (PDR)\"])\nplt.title('Per class sample Percentage');\nplt.show()\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a93814b9-cee0-4ba7-8c78-7d3402d9fc65","_cell_guid":"3ed9cd1a-4925-4e19-a8fa-871047562a4d","trusted":true},"cell_type":"markdown","source":"### Train and Test dataset \n"},{"metadata":{"_uuid":"22382c03-7105-4c97-a3d6-7a42ee46353d","_cell_guid":"6dd839e2-ecac-4196-9131-191313f413f2","trusted":true},"cell_type":"code","source":"# Train & Test samples ratio\n# Plot Data\nlabels = 'Train', 'Test'\nsizes = df_train.shape[0], df_test.shape[0]\ncolors = 'lightskyblue', 'lightcoral'\n# Plot\nplt.figure(figsize=(7, 5))\nplt.pie(sizes, labels=labels, autopct='%1.1f%%', shadow=True)\nplt.axis('equal')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d24bb5d9-7b28-4f21-90e3-4869ac40145d","_cell_guid":"07f29867-1066-40c4-af5a-9dbed6af9250","trusted":true},"cell_type":"code","source":"def draw_img(imgs, target_dir, class_label='0'):\n    fig, axis = plt.subplots(2, 6, figsize=(16, 6))\n    for idnx, (idx, row) in enumerate(imgs.iterrows()):\n        imgPath = os.path.join(dir_path, f\"{target_dir}/{row['id_code']}.png\")\n        img = cv2.imread(imgPath)\n        row = idnx // 6\n        col = idnx % 6\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        axis[row, col].imshow(img)\n    plt.suptitle(class_label)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"da0cdcd8-8b5b-48fc-8a8e-0baeb6b2b85f","_cell_guid":"76c221bc-bcbc-4dc9-903c-bc39c730ac57","trusted":true},"cell_type":"code","source":"CLASS_ID = 0\ndraw_img(df_train[df_train.diagnosis == CLASS_ID].head(12), 'train_image', CLASSS[CLASS_ID])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2348eaba-e119-4344-9c2c-d0946acd8adb","_cell_guid":"247e9916-ef8c-41e5-91e3-098c716c53a0","trusted":true},"cell_type":"code","source":"CLASS_ID = 1\ndraw_img(df_train[df_train.diagnosis == CLASS_ID].head(12), 'train_image', CLASSS[CLASS_ID])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6f612cc3-8ea9-4fb8-9e5c-98081cbb47c1","_cell_guid":"73c9183e-de08-48c6-afbc-eee989b84d8e","trusted":true},"cell_type":"code","source":"CLASS_ID = 2\ndraw_img(df_train[df_train.diagnosis == CLASS_ID].head(12), 'train_image', CLASSS[CLASS_ID])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e632dc82-d948-495e-8b7b-ceafc3547f4c","_cell_guid":"6192ac74-4a36-4929-a9ac-f60f9d013ff0","trusted":true},"cell_type":"code","source":"CLASS_ID = 'Test DataSet'\ndraw_img(df_test.sample(12, random_state=SEED), 'test_image', CLASS_ID)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"f5385cff-1f3c-4f7c-8334-04634116271a","_cell_guid":"194a717b-9c36-4938-93de-8a9e7d91dde8","trusted":true},"cell_type":"markdown","source":"<a id=\"6\"></a>\n## Max Min Height and Width"},{"metadata":{"_uuid":"64169b69-38ba-40ea-9019-31f70ac57583","_cell_guid":"fa259911-04c7-4e65-ae7a-52d8038750b0","trusted":true},"cell_type":"code","source":"def check_max_min_img_height_width(df, img_dir):\n    max_Height , max_Width =0 ,0\n    min_Height , min_Width =sys.maxsize ,sys.maxsize \n    for idx, row in df.iterrows():\n        imgPath=os.path.join(dir_path,f\"{img_dir}/{row['id_code']}.png\") \n        img=cv2.imread(imgPath)\n        H,W=img.shape[:2]\n        max_Height=max(H,max_Height)\n        max_Width =max(W,max_Width)\n        min_Height=min(H,min_Height)\n        min_Width =min(W,min_Width)\n    return max_Height, max_Width, min_Height, min_Width","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c972e5d6-14fa-429c-9f3f-a5405ed7d5d9","_cell_guid":"6a5f16d2-6192-47dd-8d5c-e1c83a07213f","trusted":true},"cell_type":"code","source":"check_max_min_img_height_width(df_train, TRAIN_DIR)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e8bbf826-1582-46ab-9ed1-61dd4aaf2a83","_cell_guid":"b02c3248-bbb6-40b0-88a8-69c8dc8da9bb","trusted":true},"cell_type":"code","source":"check_max_min_img_height_width(df_test, TEST_DIR)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a43227df-6f2a-420e-bfa4-544aee661747","_cell_guid":"bffe8233-e14a-494a-a451-1e1844187019","trusted":true},"cell_type":"markdown","source":"<a id=\"7\"></a>\n## GrayScale Images\n#### Converting the Ratina Images into Grayscale. So, we can understand the regin or intest ."},{"metadata":{"_uuid":"930f04d4-84f6-4546-8e2e-bbc3e19a5d55","_cell_guid":"c011a9a0-b7a1-4822-91d5-2d2f8f1108eb","trusted":true},"cell_type":"code","source":"# Display some random images from Data Set with class categories ing gray\nfigure = plt.figure(figsize=(20, 16))\nfor target_class in (y_train.unique()):\n    for i, (idx, row) in enumerate(\n            df_train.loc[df_train.diagnosis == target_class].sample(5, random_state=SEED).iterrows()):\n        ax = figure.add_subplot(5, 5, target_class * 5 + i + 1)\n        imagefile = f\"../input/drdataset2/DR/train_image/{row['id_code']}.png\"\n        img = cv2.imread(imagefile)\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n        img = cv2.resize(img, (IMG_DIM, IMG_DIM))\n        plt.imshow(img, cmap='gray')\n        ax.set_title(CLASSS[target_class])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5a51ad34-d511-411b-a521-711922279a7e","_cell_guid":"d3529a21-c97a-47c5-a283-5a7a67799687","trusted":true},"cell_type":"markdown","source":"## Gaussian Blur"},{"metadata":{"_uuid":"1ef34dcc-6799-434e-8e48-eb105804af9b","_cell_guid":"b6c5131e-34f8-4990-a3cd-6c4e880f3a99","trusted":true},"cell_type":"code","source":"\n\ndef draw_img_light(imgs, target_dir, class_label='0'):\n    fig, axis = plt.subplots(2, 6, figsize=(15, 6))\n    for idnx, (idx, row) in enumerate(imgs.iterrows()):\n        imgPath = os.path.join(dir_path, f\"{target_dir}/{row['id_code']}.png\")\n        img = cv2.imread(imgPath)\n        row = idnx // 6\n        col = idnx % 6\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        img = cv2.resize(img, (IMG_DIM, IMG_DIM))\n        img = cv2.addWeighted ( img,4, cv2.GaussianBlur( img , (0,0) , IMG_DIM/10) ,-4 ,128) # the trick is to add this line\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n        axis[row, col].imshow(img, cmap='gray')\n    plt.suptitle(class_label)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"CLASS_ID = 0\ndraw_img_light(df_train[df_train.diagnosis == CLASS_ID].head(12), 'train_image', CLASSS[CLASS_ID])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"157b5826-dacb-4a13-8714-15903c247631","_cell_guid":"caad3905-14e9-4d24-82e9-a8a72ab9b84f","trusted":true},"cell_type":"code","source":"CLASS_ID = 1\ndraw_img_light(df_train[df_train.diagnosis == CLASS_ID].head(12), 'train_image', CLASSS[CLASS_ID])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"CLASS_ID = 2\ndraw_img_light(df_train[df_train.diagnosis == CLASS_ID].head(12), 'train_image', CLASSS[CLASS_ID])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"\n<a id=\"2\"></a>\n# Pre-Processing\n#### - Padding (removal) \n#### - Gaussian Blur\n#### - Auto Cropping"},{"metadata":{"trusted":true},"cell_type":"code","source":"def crop_image_from_gray(img,tol=7):\n    if img.ndim ==2:\n        mask = img>tol\n        return img[np.ix_(mask.any(1),mask.any(0))]\n    elif img.ndim==3:\n        gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)\n        mask = gray_img>tol\n        \n        check_shape = img[:,:,0][np.ix_(mask.any(1),mask.any(0))].shape[0]\n        if (check_shape == 0): # image is too dark so that we crop out everything,\n            return img # return original image\n        else:\n            img1=img[:,:,0][np.ix_(mask.any(1),mask.any(0))]\n            img2=img[:,:,1][np.ix_(mask.any(1),mask.any(0))]\n            img3=img[:,:,2][np.ix_(mask.any(1),mask.any(0))]\n    #       print(img1.shape,img2.shape,img3.shape)\n            img = np.stack([img1,img2,img3],axis=-1)\n    #       print(img.shape)\n            return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def circle_crop(img):   \n    \"\"\"\n    Create circular crop around eye centre    \n    \"\"\"    \n    \n    #img = cv2.imread(img)\n    height, width, depth = img.shape\n    largest_side = np.max((height, width))\n    img = cv2.resize(img, (largest_side, largest_side))  \n    \n    x = int(width/2)\n    y = int(height/2)\n    r = np.amin((x,y))\n    \n    circle_img = np.zeros((height, width), np.uint8)\n    cv2.circle(circle_img, (x,y), int(r), 1, thickness=-1)\n    img = cv2.bitwise_and(img, img, mask=circle_img)\n    \n    return img ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"788b03e3-14e5-452a-a4af-3efea94a2ab5","_cell_guid":"62630299-c3a1-4b1e-8bc1-2e46614296b5","trusted":true},"cell_type":"code","source":"def load_ben_color(image, sigmaX=25):\n    #image = cv2.imread(path)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    #image = cv2.resize(image, (IMG_DIM, IMG_DIM))\n    image = crop_image_from_gray(image)\n    image = cv2.resize(image, (IMG_DIM, IMG_DIM))\n    #image = cv2.addWeighted ( image,4, cv2.GaussianBlur( image , (0,0) , sigmaX) ,-4 ,128)\n    image = circle_crop(image)  \n    return image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\n\nNUM_SAMP=7\nfig = plt.figure(figsize=(25, 16))\nfor class_id in sorted(y_train.unique()):\n    for i, (idx, row) in enumerate(df_train.loc[df_train['diagnosis'] == class_id].sample(NUM_SAMP, random_state=SEED).iterrows()):\n        ax = fig.add_subplot(5, NUM_SAMP, class_id * NUM_SAMP + i + 1, xticks=[], yticks=[])\n        path=f\"../input/drdataset2/DR/train_image/{row['id_code']}.png\"\n        image = load_ben_color(cv2.imread(path))\n        plt.imshow(image)\n        ax.set_title('%d-%d-%s' % (class_id, idx, row['id_code']) )","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8fc84b85-31a9-497e-a555-d61856b285c1","_cell_guid":"32eb54a6-b2b9-44da-b83d-9daf825206cc","trusted":true},"cell_type":"markdown","source":"<a id=\"8\"></a>\n# Data Augmentation\n"},{"metadata":{"_uuid":"3912c0a0-1190-4ee3-b980-9e7fe236640f","_cell_guid":"4626c548-965b-4f95-9cbe-975560d3071d","trusted":true},"cell_type":"code","source":"# print(\"available RAM:\", psutil.virtual_memory())\ngc.collect()\n# print(\"available RAM:\", psutil.virtual_memory())\n\ndf_train.id_code = df_train.id_code.apply(lambda x: x + \".png\")\ndf_test.id_code = df_test.id_code.apply(lambda x: x + \".png\")\n#df_train['diagnosis'] = df_train['diagnosis'].astype('str')\n#df_test['diagnosis'] = df_test['diagnosis'].astype('str')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train = pd.concat([df_train,pd.get_dummies(df_train['diagnosis'], prefix='diagnosis')],axis=1)\ndf_train.drop(['diagnosis'],axis=1, inplace=True)\ndf_train['diagnosis_0'] = df_train['diagnosis_0'].astype('str')\ndf_train['diagnosis_1'] = df_train['diagnosis_1'].astype('str')\ndf_train['diagnosis_2'] = df_train['diagnosis_2'].astype('str')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_test = pd.concat([df_test,pd.get_dummies(df_test['diagnosis'], prefix='diagnosis')],axis=1)\ndf_test.drop(['diagnosis'],axis=1, inplace=True)\ndf_test['diagnosis_0'] = df_test['diagnosis_0'].astype('str')\ndf_test['diagnosis_1'] = df_test['diagnosis_1'].astype('str')\ndf_test['diagnosis_2'] = df_test['diagnosis_2'].astype('str')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2d49ff33-2497-4356-ac1d-78f947f5d233","_cell_guid":"fe452ee8-7b22-4196-a803-aa5cd954ffb9","trusted":true},"cell_type":"code","source":"# Creating the imageDatagenerator Instance \ndatagenerator=ImageDataGenerator(#rescale=1./255,\n                                        validation_split=0.15, \n                                        horizontal_flip=True,\n                                        vertical_flip=True, \n                                        #rotation_range=40, \n                                        #zoom_range=0.2, \n                                        preprocessing_function=load_ben_color,\n                                        shear_range=0.1,\n                                        fill_mode='nearest')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"621f4bf7-7c2f-4d17-806c-8a2eff2c0c2a","_cell_guid":"87ca4141-4be3-4397-bb0f-5eeea8e428ef","trusted":true},"cell_type":"code","source":"#imgPath = f\"../input/aptos2019-blindness-detection/train_images/cd54d022e37d.png\"\nimgPath = f\"../input/drdataset2/DR/train_image/02685f13cefd.png\"\n# Loading image\nimg = cv2.imread(imgPath)\n#img = x_train[0]\nimg = cv2.resize(img, (IMG_DIM, IMG_DIM))\ndata = img_to_array(img)\nsamples =np.expand_dims(data, 0)\ni=5\nit=datagenerator.flow(samples , batch_size=1)\nfor i in range(5):\n    plt.subplot(230 + 1 + i)\n    batch = it.next()\n    image = batch[0].astype('uint8')\n    plt.imshow(image)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"4ae00061-89d2-4e5e-ada8-a5c7cca09563","_cell_guid":"1ec88f77-61c3-45bd-bf15-4706eccde138","trusted":true},"cell_type":"markdown","source":"\n## Image Data Generator"},{"metadata":{"_uuid":"edba5cc6-ce18-4a36-9bad-9358799772c7","_cell_guid":"24ae2996-266c-4a9d-a98e-9a401f899353","trusted":true},"cell_type":"code","source":"train_datagen=ImageDataGenerator(rescale=1./255,\n                                        validation_split=0.15, \n                                        horizontal_flip=True,\n                                        vertical_flip=True, \n                                        #rotation_range=40, \n                                        #zoom_range=0.2, \n                                        preprocessing_function=load_ben_color,\n                                        shear_range=0.1,\n                                        #fill_mode='nearest'\n                                )\ntest_datagen=ImageDataGenerator(rescale=1./255, preprocessing_function=load_ben_color)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_generator = train_datagen.flow_from_dataframe(dataframe=df_train,\n                                                    #directory=\"../input/aptos2019-blindness-detection/train_images/\",\n                                                    directory=\"../input/drdataset2/DR/train_image/\",\n                                                    x_col=\"id_code\",\n                                                    y_col=[\"diagnosis_0\",\"diagnosis_1\",\"diagnosis_2\"],\n                                                    batch_size=BATCH_SIZE,\n                                                    class_mode=\"raw\",\n                                                    target_size=(IMG_DIM, IMG_DIM),\n                                                    subset='training',\n                                                    shuffle=True,\n                                                    seed=SEED,\n                                                    )\nvalid_generator = train_datagen.flow_from_dataframe(dataframe=df_train,\n                                                    #directory=\"../input/aptos2019-blindness-detection/train_images/\",\n                                                    directory=\"../input/drdataset2/DR/train_image/\",                                                    \n                                                    x_col=\"id_code\",\n                                                    y_col=[\"diagnosis_0\",\"diagnosis_1\",\"diagnosis_2\"],\n                                                    batch_size=BATCH_SIZE,\n                                                    class_mode=\"raw\",\n                                                    target_size=(IMG_DIM, IMG_DIM),\n                                                    subset='validation',\n                                                    shuffle=True,\n                                                    seed=SEED\n                                                    )\n\n#del x_train\n#del x_test\n#del y_train\n#del y_test\ngc.collect()\n#  color_mode= \"grayscale\",","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_generator = test_datagen.flow_from_dataframe(dataframe=df_test,\n                                                #directory=\"../input/aptos2019-blindness-detection/train_images/\",\n                                                directory=\"../input/drdataset2/DR/test_image/\",                                                    \n                                                x_col=\"id_code\",\n                                                y_col=[\"diagnosis_0\",\"diagnosis_1\",\"diagnosis_2\"],\n                                                batch_size=1,\n                                                class_mode=\"raw\",\n                                                target_size=(IMG_DIM, IMG_DIM),\n                                                shuffle=False,\n                                                )","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Transfer Learning on ResNet50"},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_resnet(img_dim, CHANNEL, n_class):\n    input_tensor = Input(shape=(img_dim, img_dim, CHANNEL))\n    base_model = ResNet50(weights=None, include_top= False, input_tensor=input_tensor)\n    base_model.load_weights('../input/resnet50weightsfile/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5')\n    x = GlobalAveragePooling2D()(base_model.output)\n    x = BatchNormalization()(x)\n    x = Dropout(0.4)(x)\n    x = Dense(2048, activation=elu)(x)\n    x = BatchNormalization()(x)\n    x = Dropout(0.4)(x)\n    x = Dense(1024, activation=elu)(x)\n    x = BatchNormalization()(x)\n    x = Dropout(0.3)(x)\n    x = Dense(512, activation=elu)(x)\n    x = BatchNormalization()(x)\n    x = Dropout(0.5)(x)\n    output_layer = Dense(n_class, activation='softmax', name=\"Output_Layer\")(x)\n    model_resnet = Model(input_tensor, output_layer)\n\n    return model_resnet\n\ngc.collect()\nmodel_resnet = create_resnet(IMG_DIM, CHANNEL_SIZE, NUM_CLASSES)\nmodel_resnet.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### EarlyStopping and Learning Rate"},{"metadata":{"trusted":true},"cell_type":"code","source":"early_stop = EarlyStopping(monitor='val_loss', min_delta=0.0001, patience=10, verbose=1, mode='auto')\n# Reducing the Learning Rate if result is not improving. \nreduce_lr = ReduceLROnPlateau(monitor='val_loss', min_delta=0.0004, patience=3, factor=0.2, min_lr=1e-8, mode='auto',\n                              verbose=1)\nNUB_TRAIN_STEPS = train_generator.n // train_generator.batch_size\nNUB_VALID_STEPS = valid_generator.n // valid_generator.batch_size\n\nNUB_TRAIN_STEPS, NUB_VALID_STEPS","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_resnet.layers[0].trainable =False\nlr = 1e-3\noptimizer = SGD(lr=lr, decay=1e-6, momentum=0.9, nesterov=True) # Adam(lr=lr, decay=0.01) \nmodel_resnet.compile(optimizer=optimizer, loss=keras.losses.categorical_crossentropy, metrics=['accuracy'])\n# model.summary()\ngc.collect()\n\nmodel_resnet.fit_generator(generator=train_generator,\n                                     steps_per_epoch=NUB_TRAIN_STEPS,\n                                     validation_data=valid_generator,\n                                     validation_steps=NUB_VALID_STEPS,\n                                     epochs=5,\n                                     #use_multiprocessing=True,\n                                     #workers=3,\n                                     shuffle=True, \n                                     #callbacks=[early_stop, reduce_lr],\n                                     verbose=1)\n#gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# # Layers \n# for i, lay in enumerate(model_resnet.layers):\n#     print(i,lay.name)\n# Training All Layers\n\nfor layers in model_resnet.layers[10:-1]:\n    layers.trainable = True\n    \n    \nlr = 1e-3\noptimizer = SGD(lr=lr, decay=1e-6, momentum=0.9, nesterov=True) # Adam(lr=lr, decay=0.01) \nmodel_resnet.compile(optimizer=optimizer, loss=keras.losses.categorical_crossentropy, metrics=['accuracy'])\n# model.summary()\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history1 = model_resnet.fit_generator(generator=train_generator,\n                                     steps_per_epoch=NUB_TRAIN_STEPS,\n                                     validation_data=valid_generator,\n                                     validation_steps=NUB_VALID_STEPS,\n                                     epochs=NUM_EPOCHS,\n                                     #use_multiprocessing=True,\n                                     #workers=3,\n                                     shuffle=True, \n                                     callbacks=[early_stop, reduce_lr],\n                                     verbose=1)\n#gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_resnet.save(\"resnet_600.h5\")\nmodel_resnet.save_weights(\"resnet_600_weights.h5\")\n\n\n#from keras.models import model_from_json\n#model_json = model.to_json()\n#with open(\"model.json\", \"w\") as json_file:\n#    json_file.write(model_json)\n\n#model_yaml=model.to_yaml()\n#with open(\"model.yaml\",\"w\") as yaml_file:\n#    yaml_file.write(model_yaml)\n#model.save_weights(\"model.h5\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"score, acc = model_resnet.evaluate_generator(train_generator, steps=150, callbacks=None, max_queue_size=10, workers=1, use_multiprocessing=False, verbose=1)\nprint(score, acc)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6823802d-f2d9-4b57-bd39-492c9ed0fefa","_cell_guid":"94b182f3-f53a-4aae-85b8-cfd5a4b75900","trusted":true},"cell_type":"markdown","source":"<a id=\"8\"></a>\n# CNN-Model Architecture Design"},{"metadata":{"_uuid":"eddd539c-1fb4-4175-b2c2-9f96b5d0a5e9","_cell_guid":"318ec861-e971-4973-8f06-852c7992b615","trusted":true},"cell_type":"code","source":"def design_model():\n    model = Sequential()\n    model.add(Conv2D(filters=16, kernel_size=(2, 2), input_shape=[IMG_DIM, IMG_DIM, CHANNEL_SIZE], activation=relu))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    model.add(Dropout(rate=0.2))\n    model.add(Conv2D(filters=32, kernel_size=(2, 2), activation=relu))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    model.add(Dropout(rate=0.2))\n    model.add(Conv2D(filters=64, kernel_size=(2, 2), activation=relu))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    model.add(Dropout(rate=0.2))\n    model.add(GlobalAveragePooling2D())\n    model.add(Dense(units=256, activation=relu))\n    #model.add(Dropout(rate=0.2))\n    model.add(Dense(units=512, activation=relu))\n    #model.add(Dropout(rate=0.2))\n    model.add(Dense(3, activation='softmax'))\n    return model\n\ngc.collect()\n\nmodel = design_model()\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9933c2c7-21a7-4b90-9286-00c3ee3bb3f0","_cell_guid":"4914069e-4d68-426c-97fd-e2cab924200c","trusted":true},"cell_type":"markdown","source":"### Compile model"},{"metadata":{"_uuid":"30629d96-edbc-453a-9c79-333fa11a87b8","_cell_guid":"9f275e0d-5354-43ac-9ad8-0b41c6450a3e","trusted":true},"cell_type":"code","source":"model.compile(optimizer=Adam(lr = 0.001) , loss='categorical_crossentropy', metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":" history2 = model.fit_generator(generator=train_generator,\n                     validation_data=valid_generator,\n                     steps_per_epoch=NUB_TRAIN_STEPS,\n                     validation_steps=NUB_VALID_STEPS,\n                     verbose=1,\n                     use_multiprocessing=True,\n                     workers=3,\n                     callbacks=[early_stop, reduce_lr],\n                     shuffle=True,\n                     max_queue_size=10,\n                     epochs=NUM_EPOCHS)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d0e9f3f6-fea4-4093-9a5b-c8338320ad61","_cell_guid":"bb8bc0bd-ad82-4fb1-ac18-9c5bd432b2c2","trusted":true},"cell_type":"code","source":"model.save(\"CNN_new.h5\")\nmodel.save_weights(\"CNN_new_weights.h5\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"score, acc = model.evaluate_generator(test_generator, steps=1136, callbacks=None, max_queue_size=10, workers=1, use_multiprocessing=False, verbose=1)\nprint(score, acc)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Display Validation Accuracy & Loss\n"},{"metadata":{},"cell_type":"markdown","source":"## Accuracy ResNet50 vs CNN"},{"metadata":{"trusted":true},"cell_type":"code","source":"val_acc1 = history1.history['val_accuracy']\nval_acc2 = history2.history['val_accuracy']\n\nplt.plot(val_acc1, label=\"accuracy\")\nplt.plot(val_acc2)\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Val Accuracy\")\nplt.legend(['ResNet50', 'CNN'])\nplt.plot(np.argmax(history1.history[\"val_accuracy\"]), np.max(history1.history[\"val_accuracy\"]), marker=\"x\", color=\"r\",\n         label=\"best model\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Resnet"},{"metadata":{"trusted":true},"cell_type":"code","source":"accu = history1.history['accuracy']\nval_acc = history1.history['val_accuracy']\n\nplt.plot(accu, label=\"accuracy\")\nplt.plot(val_acc)\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Accuracy\")\nplt.legend(['accuracy', 'val_accuracy'])\nplt.plot(np.argmax(history1.history[\"val_accuracy\"]), np.max(history1.history[\"val_accuracy\"]), marker=\"x\", color=\"r\",\n         label=\"best model\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(8, 8))\nplt.title(\"Learning curve\")\nplt.plot(history1.history[\"loss\"], label=\"loss\")\nplt.plot(history1.history[\"val_loss\"], label=\"val_loss\")\nplt.plot(np.argmin(history1.history[\"val_loss\"]), np.min(history1.history[\"val_loss\"]), marker=\"x\", color=\"r\",\n         label=\"best model\")\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"log_loss\")\nplt.legend();","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### CNN"},{"metadata":{"trusted":true},"cell_type":"code","source":"accu = history2.history['accuracy']\nval_acc = history2.history['val_accuracy']\n\nplt.plot(accu, label=\"accuracy\")\nplt.plot(val_acc)\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Accuracy\")\nplt.legend(['accuracy', 'val_accuracy'])\nplt.plot(np.argmax(history2.history[\"val_accuracy\"]), np.max(history2.history[\"val_accuracy\"]), marker=\"x\", color=\"r\",\n         label=\"best model\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(8, 8))\nplt.title(\"Learning curve\")\nplt.plot(history2.history[\"loss\"], label=\"loss\")\nplt.plot(history2.history[\"val_loss\"], label=\"val_loss\")\nplt.plot(np.argmin(history2.history[\"val_loss\"]), np.min(history2.history[\"val_loss\"]), marker=\"x\", color=\"r\",\n         label=\"best model\")\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"log_loss\")\nplt.legend();","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":""},{"metadata":{"_uuid":"e10a5544-1849-43a3-af0e-ffddbeedbc90","_cell_guid":"132e1dbd-4ead-423a-969c-f73072d4e93b","trusted":true},"cell_type":"markdown","source":"# Sample User interface"},{"metadata":{"_uuid":"92febbda-6c64-49e1-a015-b83540a06d97","_cell_guid":"dfc1648d-1cc4-4bd8-bdce-81727a468327","trusted":true},"cell_type":"markdown","source":"from keras.models import load_model\nclassifier= load_model(\"../input/drmodels/model_saves/resnet_2048.h5\")\n\nPatient101 = \"../input/drdataset2/DR/train_images/4e54ccfd49b2.png\"\nPatient102 = \"../input/drdataset2/DR/train_images/7a06ea127e02.png\"\nPatient103 = \"../input/drdataset2/DR/train_images/1d3e9b939732.png\"\n\nPatient201 = \"../input/drdataset2/DR/train_images/059bc89df7f4.png\"\nPatient202 = \"../input/drdataset2/DR/train_images/435d900fa7b2.png\"\nPatient203 = \"../input/drdataset2/DR/train_images/1006345f70b7.png\"\n\nPatient301 = \"../input/drdataset2/DR/train_images/5b3e7197ac1c.png\"\nPatient302 = \"../input/drdataset2/DR/train_images/7b211d8bd249.png\"\nPatient303 = \"../input/drdataset2/DR/train_images/dad71ba27a9b.png\""},{"metadata":{"trusted":true},"cell_type":"markdown","source":"#del df_class\ndf_class = pd.read_csv(\"../input/drdataset5/DR_categorical/0.csv\")"},{"metadata":{"trusted":true},"cell_type":"markdown","source":"df_class.id_code = df_class.id_code.apply(lambda x: x + \".png\")\ndf_class['id_code'] = df_class['id_code'].astype('str')"},{"metadata":{"trusted":true},"cell_type":"code","source":"#df_class = pd.concat([df_class,pd.get_dummies(df_class['diagnosis'], prefix='diagnosis')],axis=1)\n#df_class['diagnosis_0']=list(df_class['diagnosis']-1)\n#df_class['diagnosis_1']=list(df_class['diagnosis'])\n#df_class['diagnosis_2']=list(df_class['diagnosis']-1)\n#df_class.drop(['diagnosis'],axis=1, inplace=True)\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#df_class['diagnosis'] = df_class['diagnosis'].astype('str')\n#df_class = pd.concat([df_class,pd.get_dummies(df_class['diagnosis'], prefix='diagnosis')],axis=1)\n#df_class.drop(['diagnosis'],axis=1, inplace=True)\n#df_class['diagnosis_0'] = df_class['diagnosis_0'].astype('str')\n#df_class['diagnosis_1'] = df_class['diagnosis_1'].astype('str')\n#df_class['diagnosis_2'] = df_class['diagnosis_2'].astype('str')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"dummy_datagen=ImageDataGenerator(rescale=1./255, preprocessing_function=load_ben_color)\ndummy_generator = dummy_datagen.flow_from_dataframe(dataframe=df_class,\n                                                    #directory=\"../input/aptos2019-blindness-detection/train_images/\",\n                                                    directory=\"../input/drdataset5/DR_categorical/0/\",                                                    \n                                                    x_col=\"id_code\",\n                                                    #y_col=\"diagnosis\",\n                                                    #y_col=[\"diagnosis_0\",\"diagnosis_1\",\"diagnosis_2\"],\n                                                    batch_size=1,\n                                                    class_mode=None,\n                                                    target_size=(IMG_DIM, IMG_DIM),\n                                                    #shuffle=False,\n                                                   seed = 7\n                                                  )"},{"metadata":{},"cell_type":"markdown","source":"## Generator Pred"},{"metadata":{"trusted":true},"cell_type":"markdown","source":"tta_steps = 1\npreds_tta = []\nfor i in tqdm(range(tta_steps)):\n    dummy_generator.reset()\n    preds = classifier.predict_generator(generator=dummy_generator, steps=ceil(df_class.shape[0]))\n    #     print('Before ', preds.shape)\n    preds_tta.append(preds)\n#     print(i,  len(preds_tta))"},{"metadata":{"trusted":true},"cell_type":"markdown","source":"final_pred = np.mean(preds_tta, axis=0)\npredicted_class_indices = np.argmax(final_pred, axis=1)\n    len(predicted_class_indices)"},{"metadata":{"trusted":true},"cell_type":"markdown","source":"#Label Dictionary\nlabel_maps = {0: 'No DR', 1: 'Non-Proliferative DR', 2: 'Proliferative DR'}\nlabel =[label_maps[k] for k in predicted_class_indices]\n\nprint(label)"}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}