{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"###Importing some libs to make our lives easier\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nimport tensorflow as tf\nimport keras\nfrom keras.preprocessing import image\nfrom sklearn.model_selection import train_test_split\nimport glob\nfrom keras.models import Model\nfrom keras.layers import *\nfrom keras.preprocessing.image import *\nfrom keras.optimizers import *\nfrom keras.callbacks import *\nfrom keras.applications.inception_v3 import InceptionV3\nfrom keras.applications.resnet50 import ResNet50\n\nfrom keras import backend as K\nimport sys\nfrom numpy import genfromtxt\nfrom keras.utils import to_categorical\nfrom skimage.io import imread\nfrom skimage.color import rgb2gray\nfrom PIL import Image\nimport skimage\nimport cv2\nimport pandas as pd\n\nimport os\nimport glob\nimport psutil\nfrom tqdm import tqdm\nfrom math import ceil\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow import set_random_seed\nimport tensorflow as tf\nimport keras","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"###import our csv using Pandas(no animals were harmed during this competition)\n\ntrain_img = glob.glob('../input/aptos2019-blindness-detection/*.png')\ndf_train = pd.read_csv('../input/aptos2019-blindness-detection/train.csv')\n\ntest_img = glob.glob('../input/aptos2019-blindness-detection/*.png')\ndf_test = pd.read_csv('../input/aptos2019-blindness-detection/test.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_dim = 224","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"###This is a function I used from a super helpful kernel \n###to crop the images to remove the unneccessary black borders.\ndef crop_image_from_gray(img,tol=7):\n    \"\"\"\n    Crop out black borders\n    https://www.kaggle.com/ratthachat/aptos-updated-preprocessing-ben-s-cropping\n    \"\"\"  \n    \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_BGR2GRAY)\n        mask = gray_img>tol        \n        check_shape = img[:,:,0][np.ix_(mask.any(1),mask.any(0))].shape[0]\n        if (check_shape == 0):\n            return img\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            img = np.stack([img1,img2,img3],axis=-1)\n        return img\n\n\ndef circle_crop(img):   \n    \"\"\"\n    Create circular crop around image centre    \n    \"\"\"    \n    \n    #img = cv2.imread(img)\n    img = crop_image_from_gray(img)    \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    \n    return img \n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"###This is a contrast filter to intensify the features of the images and to reduce the image size.\ndef conv_clah(img, img_dim = img_dim):\n    \n    img = circle_crop(img) / 255\n    img = skimage.exposure.equalize_adapthist(img)\n    return  (skimage.transform.resize(img, (img_dim, img_dim)).astype('float32'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Split Dataset\n\nx_train, x_test, y_train, y_test = train_test_split(df_train.id_code, df_train.diagnosis, test_size=0.2,\n                                                    random_state=3, stratify=df_train.diagnosis)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"###Make data into matrices from csv\nnum_classes = 5\nlabels = []\nfor index, row in df_train.iterrows():\n    labels.append(to_categorical(row['diagnosis'], num_classes=num_classes))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"###function for getting labels from the one-hot-encoding\ndef get_label(l, one_hot_size=5):\n    ii = np.argmax(l)\n    if ii<one_hot_size :\n        return ii","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"###plot the bar graph of the number of different classes\nll = [get_label(l) for l in labels]\nplt.hist(ll, bins=np.arange(min(ll), max(ll)+2), align='left')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"###This is a weight dictionary to give more weights to the less frequent classes,\n###as there is an imbalanced dataset\nfrom sklearn.utils import class_weight\n\nclass_weights = class_weight.compute_class_weight('balanced',\n                                                 np.unique(ll),\n                                                 ll)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class_weights","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"###Original image as given in the dataset.\nplt.imshow(cv2.imread('../input/aptos2019-blindness-detection/train_images/4289af3afbd2.png'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"###Above image after all the preprocessing\nplt.imshow((conv_clah(imread('../input/aptos2019-blindness-detection/train_images/4289af3afbd2.png'))), cmap ='gray')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**if you want oversampling run these cells below, but it didn't give any good results to me so i didnt use em**"},{"metadata":{"trusted":true},"cell_type":"code","source":"###Don't run this cell if you want to reproduce my results.\n#def get_data(kk, labels=labels, images=images):\n#    labels1 = []\n#    images1 = []\n#    for i, j in zip(labels, images):\n#        if get_label(i)==kk:\n#            labels1.append(i)\n#            images1.append(j)\n#    return labels1, images1\n\n#label_0, images_0 = get_data(0)\n#label_1, images_1 = get_data(1)\n#label_2, images_2 = get_data(2)\n#label_3, images_3 = get_data(3)\n#label_4, images_4 = get_data(4)\n\n#max_size = max(len(label_0),len(label_1),len(label_2),len(label_3),len(label_4))\n\n#labels_Y = []\n#images_X = []\n#labels_Y = label_0*( max_size//(len(label_0))) + label_1*( max_size//(len(label_1))) + label_2*( max_size//(len(label_2))) + label_3*( max_size//(len(label_3))) + label_4*( max_size//(len(label_4)))\n#images_X = images_0*( max_size//(len(images_0))) + images_1*( max_size//(len(images_1))) + images_2*( max_size//(len(images_2))) + images_3*( max_size//(len(images_3))) + images_4*( max_size//(len(images_4)))\n\n#labels_Y = labels_Y + label_1 + label_2[0:500]\n#images_X =  images_X + images_1 + images_2[0:500]\n\n#ll = [get_label(l) for l in labels_Y]\n#plt.hist(ll, bins=np.arange(min(ll), max(ll)+3), align='left')\n\n#images = images_X\n#labels = labels_Y","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"###Using transfer learning cos I tried to make my own architecture and it didn't work,\n####it was ridicilously overfitting and we need something readily available to us.\ndef inception_maker(img_dim, c ,n_class):\n    input_tensor=Input(shape=(img_dim, img_dim,c))\n  \n    model = ResNet50(weights=None, include_top=False, input_tensor=input_tensor)\n    model.load_weights('../input/resnet/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5')\n    \n    x=GlobalAveragePooling2D()(model.output)\n    x=Dropout(0.3)(x)\n    x=Dense(1024, activation='relu')(x)\n    x=Dropout(0.2)(x)\n    x=Dense(512, activation='relu')(x)\n    x=Dropout(0.2)(x)\n    x=BatchNormalization()(x)\n    output =Dense(n_class,activation='softmax', name=\"Output_Layer\")(x)\n    model_inception =Model(input_tensor, output)\n    \n    return model_inception\nmodel_inception=inception_maker(img_dim,3, 5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for layers in model_inception.layers:\n    layers.trainable=True","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lr = 0.005\noptimizer=RMSprop(lr=lr,decay=0.1)\nmodel_inception.compile(optimizer=optimizer, loss=keras.losses.categorical_crossentropy,  metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import gc\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_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\")\ndf_train['diagnosis'] = df_train['diagnosis'].astype('str')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Data Generator\ntrain_datagen = image.ImageDataGenerator(rescale=None, preprocessing_function=conv_clah, validation_split=0.15, horizontal_flip=True,\n                                         vertical_flip=True, rotation_range=360, zoom_range=0.2, shear_range=0.1)","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                                                    x_col='id_code',\n                                                    y_col='diagnosis',\n                                                    batch_size=8,\n                                                    class_mode='categorical',\n                                                    target_size=(img_dim, img_dim),\n                                                    subset='training',\n                                                    shaffle=True,\n                                                    seed=3\n                                                    )\nvalid_generator = train_datagen.flow_from_dataframe(dataframe=df_train,\n                                                    directory='../input/aptos2019-blindness-detection/train_images/',\n                                                    x_col='id_code',\n                                                    y_col='diagnosis',\n                                                    batch_size=8,\n                                                    class_mode='categorical',\n                                                    target_size=(img_dim, img_dim),\n                                                    subset='validation',\n                                                    shaffle=True,\n                                                    seed=3\n                                                    )\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"NUB_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":"earlyStopping = EarlyStopping(monitor='val_loss', patience=10, verbose=0, mode='min')\nmcp_save = ModelCheckpoint('.mdl_wts.hdf5', save_best_only=True, monitor='val_loss', mode='min')\nreduce_lr_loss = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=7, verbose=1, epsilon=1e-4, mode='min')\nd_loss = model_inception.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=50,\n                                     callbacks=[earlyStopping, reduce_lr_loss, mcp_save], class_weight=class_weights)\nprint(d_loss)\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(d_loss.history['acc'])\nplt.plot(d_loss.history['val_acc'])\nplt.title('model loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['train', 'val'], loc='upper left')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_datagen = image.ImageDataGenerator(rescale=None, preprocessing_function=conv_clah, validation_split=0.2, horizontal_flip=True)\n\ntest_generator = test_datagen.flow_from_dataframe(dataframe=df_test,\n                                                  directory= '../input/aptos2019-blindness-detection/test_images/',\n                                                  x_col=\"id_code\",\n                                                  target_size=(img_dim, img_dim),\n                                                  batch_size=1,\n                                                  shuffle=False,\n                                                  class_mode=None,\n                                                  seed=3)\nprint(df_test.shape[0])\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predictions = []\nfor i in tqdm(range(5)):\n    test_generator.reset()\n    preds = model_inception.predict_generator(generator=test_generator, steps=ceil(df_test.shape[0]))\n    predictions.append(preds)\n    \npredictions = np.mean(predictions, axis=0)\npredictions = np.argmax(predictions, axis=1)\nlen(predictions)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results = pd.DataFrame({\"id_code\": test_generator.filenames, \"diagnosis\": predictions})\nresults.id_code = results.id_code.apply(lambda x: x[:-4])\nresults.to_csv(\"submission.csv\", index=False)","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}