{"cells":[{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","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.applications import DenseNet121\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.preprocessing import image\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 accuracy_score\nimport scipy\nimport tensorflow as tf\nfrom tqdm import tqdm\nIMG_SIZE = 224\n\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Set random seed for reproducibility.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"\n\nnp.random.seed(2019)\ntf.random.set_random_seed(2019)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Loading & Exploration","execution_count":null},{"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')\nprint(train_df.shape)\nprint(test_df.shape)\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['diagnosis'].hist()\ntrain_df['diagnosis'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Displaying some Sample Images","execution_count":null},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"def display_samples(df, columns=4, rows=3):\n    fig=plt.figure(figsize=(4*columns, 3*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        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":{},"cell_type":"markdown","source":"# Image Preprocessing using ben's idea\n\n\nWe will resize the images to 224x224, then create a single numpy array to hold the data.","execution_count":null},{"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\n    \n    \ndef load_ben_color(path, sigmaX=10):\n    image = cv2.imread(path)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    image = crop_image_from_gray(image)\n    image = cv2.resize(image, (IMG_SIZE, IMG_SIZE))\n    image=cv2.addWeighted ( image,4, cv2.GaussianBlur( image , (0,0) , sigmaX) ,-4 ,128)\n        \n    return image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def preprocess_image(image_path, desired_size=IMG_SIZE):\n    im = load_ben_color(image_path,sigmaX = 30)\n    return im","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Converting Preprocessed images to Numpy arrays ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"N = train_df.shape[0]\nx_train = np.empty((N, IMG_SIZE, IMG_SIZE, 3), dtype=np.uint8)\n\nfor i, image_id in enumerate(tqdm(train_df['id_code'])):\n    x_train[i, :, :, :] = preprocess_image(\n        f'../input/aptos2019-blindness-detection/train_images/{image_id}.png'\n    )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"N = test_df.shape[0]\nx_test = np.empty((N, IMG_SIZE, IMG_SIZE, 3), dtype=np.uint8)\n\nfor i, image_id in enumerate(tqdm(test_df['id_code'])):\n    x_test[i, :, :, :] = preprocess_image(\n        f'../input/aptos2019-blindness-detection/test_images/{image_id}.png'\n    )","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Shapes of data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"y_train = pd.get_dummies(train_df['diagnosis']).values\n\nprint(\"NO of train images in x\",x_train.shape)\nprint(\"NO of train images in y\",y_train.shape)\nprint(\"NO of test images\",x_test.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Splitting into train and validations","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"x_train, x_val, y_train, y_val = train_test_split(\n    x_train, y_train, \n    test_size=0.15, \n    random_state=2019\n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data Augmentation ","execution_count":null},{"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\n#mixup_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":"plt.imshow(x_train[5], interpolation='nearest')\n\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model: DenseNet-121","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"densenet = DenseNet121(\n    weights='../input/densenet-keras/DenseNet-BC-121-32-no-top.h5',\n    include_top=False,\n    input_shape=(IMG_SIZE,IMG_SIZE,3)\n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Building the model","execution_count":null},{"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.00005),\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":{},"cell_type":"markdown","source":"# Training & Evaluation","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#appa_metrics = Metrics()\n\nhistory = model.fit_generator(\n    data_generator,\n    steps_per_epoch=x_train.shape[0] / BATCH_SIZE,\n    epochs=15,\n    validation_data=(x_val, y_val),\n    \n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Saving the model as CNN.model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"model.save_weights(\"model.h5\")\nmodel.save('CNNmodel.h5')\nprint(\"model saved to disk\")\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Saving the model as joblib file","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import joblib\njoblib.dump(model,'JOBmodel.sav')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Jmodel = joblib.load('JOBmodel.sav')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Saving the model as Pickle file","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import pickle\nfilename = 'pickel_model.pkl'\nloadedModel = pickle.dump(model,open(filename,'wb'))\nprint(\"model saved\")\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from IPython.display import FileLink\nFileLink(r'JOBmodel.sav')\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Plotting accuracy curves of both train & validation","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"print(history.history.keys())\nplt.figure(1)\nplt.plot(history.history['acc'])\nplt.plot(history.history['val_acc'])\nplt.title('model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', 'validation'], loc='upper left')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Predicting a single image","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"image_path=f'../input/aptos2019-blindness-detection/train_images/02358b47ea89.png'\nimg = image.load_img(image_path, target_size=(IMG_SIZE, IMG_SIZE))\nplt.imshow(img)\nimg = preprocess_image(image_path)\nimg = np.expand_dims(img, axis=0)\nresult=Jmodel.predict_classes(img)\nplt.title(label = result[0])\nplt.show()\nprint(\"the diabetic retinopathy level of this eye is {}\".format(result))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_test_images = []\nim_names = []\nfor i in range(0,20):\n    img_path = train_df.loc[i,'id_code']\n    im_names.append(img_path)\n    img = preprocess_image(f'../input/aptos2019-blindness-detection/train_images/{img_path}.png')\n    sample_test_images.append(img)\n\nprint(len(sample_test_images),\"images are stored in a list\")\n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(im_names)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Predicting multiple images:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def predict_multiple(li, columns=5, rows=4):\n    fig=plt.figure(figsize=(5*columns, 4*rows))\n    for i in range(columns*rows):\n        im = li[i]\n        img = np.expand_dims(im, axis=0)\n        result=Jmodel.predict_classes(img)\n        fig.add_subplot(rows, columns, i+1)\n        plt.title(result[0])\n        plt.imshow(im, interpolation='nearest')\n        \n    plt.tight_layout()\n    \npredict_multiple(sample_test_images)    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"","execution_count":null}],"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}