{"cells":[{"metadata":{},"cell_type":"markdown","source":"\n![](https://www.eye7.in/wp-content/uploads/illustration-showing-diabetic-retinopathy.jpg)\n\nIncreased urbanization, the consumption of less-nutritious foods, more sedentary lifestyles and resulting obesity have all contributed to the dramatic rise in the global prevalence of diabetes, particularly in resource-poor countries.\n\n![](http://atlas.iapb.org/wp-content/uploads/VA-DR-Map-new3.gif)\n\nCurrently, South East Asia and the Western Pacific account for more than half of adults with diabetes world-wide. Efforts to reduce its prevalence and more effectively manage its health consequences are further undermined by the fact that roughly half of all people with diabetes are currently undiagnosed.\n\nEvery person living with diabetes is at risk of developing Diabetic Retinopathy (DR). Poorly controlled blood sugars, high blood pressure and high cholesterol increase the likelihood of vision loss due to DR, along with the risk of associated vision disorders such as Cataract or Glaucoma.\n\nDR is the leading cause of vision loss in working-age adults (20 to 65 years) so it has profound economic consequences from lost productivity and the cost of ongoing care. Approximately one in three people living with diabetes have some degree of DR and one in 10 will develop a vision-threatening form of the disease . Over time, poor glycemic control can result in improper growth or blockage of blood vessels that nourish the retina and lead to leakage of blood, fluids and the formation of lipid deposits in the eye. In more advanced forms of DR, new abnormal vessel growth occurs due to reduced oxygen flow caused by damaged or blocked vessels. The resulting retinal scarring, retinal detachment, along with fluid build-up and swelling in the central part of the retina (the macula), lead to impaired vision. Damage to the retina is often irreversible in the later stages of the disease and results in blindness.\n\n**What are the stages of Diabetic Retinopathy?**\n\nDiabetic Retinopathy has four stages:\n\n*     Mild Nonproliferative Retinopathy\n*     Moderate Nonproliferative Retinopathy\n*     Severe Nonproliferative Retinopathy\n*     Proliferative Retinopathy\n\n\n\n**How does Diabetic Retinopathy cause vision loss?**\n\nBlood vessels damaged from Diabetic Retinopathy can cause vision loss in two ways:\n\n*     Fragile, abnormal blood vessels can develop and leak blood into the center of the eye, blurring vision. This is proliferative retinopathy and is the fourth and most advanced stage of the disease.\n*     Fluid can leak into the center of the macula, the part of the eye where sharp, straight-ahead vision occurs. The fluid makes the macula swell, blurring vision. This condition is called Macular Edema. It can happen at any stage of Diabetic Retinopathy, although it is more likely to occur as the disease progresses. About half of the people with proliferative retinopathy also have Macular Edema.\n"},{"metadata":{},"cell_type":"markdown","source":"**Global prevalence of people with diabetes and Diabetic Retinopathy**\n\nThe Vision Loss Expert Group estimated that in 2015 , some 1.07% of blindness world-wide could be attributed to Diabetic Retinopathy; this is predicted to increase as the global prevalence of diabetes continues to rise. Although early identification and treatment can prevent almost all blindness from DR, people living with diabetes are often unaware that they should have their vision examined annually, are asymptomatic during the early stages of DR, and fail to access timely care. In most resource-poor countries, the clinicians, medical technology and systems of care needed to identify and effectively treat DR are often lacking, so significant investment will be required in order to forestall the inevitable rise in vision loss to DR.\n\n![](http://atlas.iapb.org/wp-content/uploads/VA-DR-infographic-resized.gif)\n\n\n\nDiabetes prevention and treatment can play a vital role in reducing vision loss from DR. Although more than 75% of people with diabetes will develop some retinopathy after 15 years, recent studies have determined that intensive glucose therapy achieved through diet and/or medication can reduce the onset of Diabetic Retinopathy by 76% and the progression of the disease by 54%.\n\nThe most effective Diabetic Retinopathy programmes will take a holistic approach, focusing on patient education, behaviour change, and effective disease management strategies in addition to the provision of annual vision exams and high-quality, affordable treatment. Increased co-operation between the diabetes care and ophthalmic communities is essential to prevent the impending epidemic of vision loss due to Diabetic Retinopathy.\n\n**How is Diabetic Retinopathy treated?**\n\nDuring the first three stages of Diabetic Retinopathy, no treatment is needed, unless you have Macular Edema. To prevent progression of Diabetic Retinopathy, people with diabetes should control their levels of blood sugar, blood pressure, and blood cholesterol.\n\nProliferative Retinopathy is treated with laser surgery. This procedure is called Panretinal Photocoagulation which helps to shrink the abnormal blood vessels. Your doctor places 1,000 to 2,000 laser burns in the areas of the retina away from the macula, causing the abnormal blood vessels to shrink. Because a high number of laser burns are necessary, two or more sessions usually are required to complete treatment. Although you may notice some loss of your side vision, Laser Photocoagulation can save the rest of your sight.\n\nLaser Photocoagulation works better before the fragile, new blood vessels have started to bleed. That is why it is essential to have regular, comprehensive dilated eye exams. Even if bleeding has started, laser treatment may still be possible, depending on the amount of bleeding.\n\nIf the bleeding is severe, you may need a surgical procedure called a vitrectomy. During a vitrectomy, blood is removed from the center of your eye.\n"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import json\nimport math\nimport os\nimport cv2\nfrom PIL import Image\nimport numpy as np\nfrom keras import layers\nfrom keras.callbacks import Callback, ModelCheckpoint\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential\nfrom keras.optimizers import Adam\nimport matplotlib.pyplot as plt\nimport pandas as pd\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import cohen_kappa_score, accuracy_score\nimport scipy\nimport tensorflow as tf\nfrom tqdm import tqdm\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"np.random.seed(2019)\ntf.set_random_seed(2019)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('../input/aptos2019-blindness-detection/train.csv')\ntest_df = pd.read_csv('../input/aptos2019-blindness-detection/test.csv')\ntrain_df['diagnosis'].hist()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**A clinician has rated each image for the severity of diabetic retinopathy on a scale of 0 to 4:**\n\n\n\n    0 - No DR\n\n    1 - Mild\n\n    2 - Moderate\n\n    3 - Severe\n\n    4 - Proliferative DR\n\n"},{"metadata":{"_kg_hide-input":false,"trusted":true},"cell_type":"code","source":"def display_samples(df, columns=4, rows=3):\n    fig=plt.figure(figsize=(5*columns, 4*rows))\n\n    for i in range(columns*rows):\n        image_path = df.loc[i,'id_code']\n        image_id = df.loc[i,'diagnosis']\n        img = cv2.imread(f'../input/aptos2019-blindness-detection/train_images/{image_path}.png')\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        \n        \n        \n        fig.add_subplot(rows, columns, i+1)\n        plt.title(image_id)\n        plt.imshow(img)\n    \n    plt.tight_layout()\n\ndisplay_samples(train_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_pad_width(im, new_shape, is_rgb=True):\n    pad_diff = new_shape - im.shape[0], new_shape - im.shape[1]\n    t, b = math.floor(pad_diff[0]/2), math.ceil(pad_diff[0]/2)\n    l, r = math.floor(pad_diff[1]/2), math.ceil(pad_diff[1]/2)\n    if is_rgb:\n        pad_width = ((t,b), (l,r), (0, 0))\n    else:\n        pad_width = ((t,b), (l,r))\n    return pad_width\n\n\n\n\ndef 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\n\n\n\ndef circle_crop(img, sigmaX=45):   \n    \"\"\"\n    Create circular crop around image centre    \n    \"\"\"    \n    \n    img = cv2.imread(img)\n    img = crop_image_from_gray(img)    \n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    \n    height, width, depth = img.shape    \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    img = crop_image_from_gray(img)\n    img=cv2.resize(img, (224, 224))\n    img=cv2.addWeighted ( img,4, cv2.GaussianBlur( img , (0,0) , sigmaX) ,-4 ,128)\n    return img ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"N = train_df.shape[0]\nx_train = np.empty((N, 224, 224, 3), dtype=np.uint8)\n\nfor i, image_id in enumerate(tqdm(train_df['id_code'])):\n    x_train[i, :, :, :] = circle_crop(\n        f'../input/aptos2019-blindness-detection/train_images/{image_id}.png')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"N = test_df.shape[0]\nx_test = np.empty((N, 224, 224, 3), dtype=np.uint8)\n\nfor i, image_id in enumerate(tqdm(test_df['id_code'])):\n    x_test[i, :, :, :] = circle_crop(\n        f'../input/aptos2019-blindness-detection/test_images/{image_id}.png')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_train = pd.get_dummies(train_df['diagnosis']).values\n\ny_train_multi = np.empty(y_train.shape, dtype=y_train.dtype)\ny_train_multi[:, 4] = y_train[:, 4]\n\nfor i in range(3, -1, -1):\n    y_train_multi[:, i] = np.logical_or(y_train[:, i], y_train_multi[:, i+1])\n\nprint(\"Original y_train:\", y_train.sum(axis=0))\nprint(\"Multilabel version:\", y_train_multi.sum(axis=0))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x_train, x_val, y_train, y_val = train_test_split(\n    x_train, y_train_multi, \n    test_size=0.15, \n    random_state=2019\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class MixupGenerator():\n    def __init__(self, X_train, y_train, batch_size=32, alpha=0.2, shuffle=True, datagen=None):\n        self.X_train = X_train\n        self.y_train = y_train\n        self.batch_size = batch_size\n        self.alpha = alpha\n        self.shuffle = shuffle\n        self.sample_num = len(X_train)\n        self.datagen = datagen\n\n    def __call__(self):\n        while True:\n            indexes = self.__get_exploration_order()\n            itr_num = int(len(indexes) // (self.batch_size * 2))\n\n            for i in range(itr_num):\n                batch_ids = indexes[i * self.batch_size * 2:(i + 1) * self.batch_size * 2]\n                X, y = self.__data_generation(batch_ids)\n\n                yield X, y\n\n    def __get_exploration_order(self):\n        indexes = np.arange(self.sample_num)\n\n        if self.shuffle:\n            np.random.shuffle(indexes)\n\n        return indexes\n\n    def __data_generation(self, batch_ids):\n        _, h, w, c = self.X_train.shape\n        l = np.random.beta(self.alpha, self.alpha, self.batch_size)\n        X_l = l.reshape(self.batch_size, 1, 1, 1)\n        y_l = l.reshape(self.batch_size, 1)\n\n        X1 = self.X_train[batch_ids[:self.batch_size]]\n        X2 = self.X_train[batch_ids[self.batch_size:]]\n        X = X1 * X_l + X2 * (1 - X_l)\n\n        if self.datagen:\n            for i in range(self.batch_size):\n                X[i] = self.datagen.random_transform(X[i])\n                X[i] = self.datagen.standardize(X[i])\n\n        if isinstance(self.y_train, list):\n            y = []\n\n            for y_train_ in self.y_train:\n                y1 = y_train_[batch_ids[:self.batch_size]]\n                y2 = y_train_[batch_ids[self.batch_size:]]\n                y.append(y1 * y_l + y2 * (1 - y_l))\n        else:\n            y1 = self.y_train[batch_ids[:self.batch_size]]\n            y2 = self.y_train[batch_ids[self.batch_size:]]\n            y = y1 * y_l + y2 * (1 - y_l)\n\n        return X, y","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"BATCH_SIZE = 32\n\ndef create_datagen():\n    return ImageDataGenerator(\n        zoom_range=0.15,  # set range for random zoom\n        # set mode for filling points outside the input boundaries\n        fill_mode='constant',\n        cval=0.,  # value used for fill_mode = \"constant\"\n        horizontal_flip=True,  # randomly flip images\n        vertical_flip=True,  # randomly flip images\n    )\n\n# Using original generator\ndata_generator = create_datagen().flow(x_train, y_train, batch_size=BATCH_SIZE, seed=2019)\n# Using Mixup\nmixup_generator = MixupGenerator(x_train, y_train, batch_size=BATCH_SIZE, alpha=0.2, datagen=create_datagen())()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class Metrics(Callback):\n    def on_train_begin(self, logs={}):\n        self.val_kappas = []\n\n    def on_epoch_end(self, epoch, logs={}):\n        X_val, y_val = self.validation_data[:2]\n        y_val = y_val.sum(axis=1) - 1\n        \n        y_pred = self.model.predict(X_val) > 0.5\n        y_pred = y_pred.astype(int).sum(axis=1) - 1\n\n        _val_kappa = cohen_kappa_score(\n            y_val,\n            y_pred, \n            weights='quadratic'\n        )\n\n        self.val_kappas.append(_val_kappa)\n\n        print(f\"val_kappa: {_val_kappa:.4f}\")\n        \n        if _val_kappa == max(self.val_kappas):\n            print(\"Validation Kappa has improved. Saving model.\")\n            self.model.save('model.h5')\n\n        return","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications import DenseNet169\ndensenet = DenseNet169(\n    weights='../input/densenet-keras/DenseNet-BC-169-32-no-top.h5',\n    include_top=False,\n    input_shape=(224,224,3)\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_model():\n    model = Sequential()\n    model.add(densenet)\n    model.add(layers.GlobalAveragePooling2D())\n    model.add(layers.Dropout(0.5))\n    model.add(layers.Dense(5, activation='sigmoid'))\n    \n    model.compile(\n        loss='binary_crossentropy',\n        optimizer=Adam(lr=0.0005),\n        metrics=['accuracy']\n    )\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = build_model()\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"kappa_metrics = Metrics()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n\nhistory = model.fit_generator(\n    data_generator,\n    steps_per_epoch=x_train.shape[0] / BATCH_SIZE,\n    epochs=100,\n    validation_data=(x_val, y_val),\n    callbacks=[kappa_metrics]\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with open('history.json', 'w') as f:\n    json.dump(history.history, f)\n\nhistory_df = pd.DataFrame(history.history)\nhistory_df[['loss', 'val_loss']].plot()\nhistory_df[['acc', 'val_acc']].plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.load_weights('model.h5')\ny_val_pred = model.predict(x_val)\n\ndef compute_score_inv(threshold):\n    y1 = y_val_pred > threshold\n    y1 = y1.astype(int).sum(axis=1) - 1\n    y2 = y_val.sum(axis=1) - 1\n    score = cohen_kappa_score(y1, y2, weights='quadratic')\n    \n    return 1 - score\n\nsimplex = scipy.optimize.minimize(\n    compute_score_inv, 0.5, method='nelder-mead'\n)\n\nbest_threshold = simplex['x'][0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_test = model.predict(x_test) > 0.5\ny_test = y_test.astype(int).sum(axis=1) - 1\n\ntest_df['diagnosis'] = y_test","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def xdisplay_samples(df, columns=4, rows=12):\n    fig=plt.figure(figsize=(5*columns, 4*rows))\n\n    for i in range(columns*rows):\n        image_path = df.loc[i,'id_code']\n        image_id = df.loc[i,'diagnosis']\n        #img = cv2.imread(f'../input/aptos2019-blindness-detection/test_images/{image_path}.png')\n        image = circle_crop(f'../input/aptos2019-blindness-detection/test_images/{image_path}.png')\n        \n        \n        fig.add_subplot(rows, columns, i+1)\n        plt.title(image_id)\n        plt.imshow(image)\n    \n    plt.tight_layout()\n\nxdisplay_samples(test_df)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**This Images are the preprocessed one with the predicted classes **"},{"metadata":{"trusted":true},"cell_type":"code","source":"model.save(\"modelx.h5\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df.to_csv('submission.csv',index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}