{"cells":[{"metadata":{},"cell_type":"markdown","source":"<h1>APTOS Diabetic Retinopathy Severity Prediction</h1>\nIn this kernel we will EfficientNetB3 which I pretrained on 2015 dataset and fine-tune on 2019 dataset for 30 epochs.\n<br></br>\nWe will also perform pseudo labeling (which I wish I had tried during competition, I still have a lot to learn though :D)"},{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","trusted":true},"cell_type":"code","source":"'''\n    Build and install EfficientNet\n    Import necessary libraries\n'''\n!pip install ../input/efficientnet/efficientnet-master/efficientnet-master\nfrom efficientnet.keras import *\n\nimport cv2\nimport numpy as np \n\nimport pandas as pd\nimport tensorflow as tf\n\nimport keras\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras import backend as K\nfrom keras import Input\nfrom keras.models import Model\nfrom keras.utils import *\nfrom keras.layers import *\n\nfrom tensorflow import set_random_seed\nimport matplotlib.pyplot as plt\n\nset_random_seed(2)\nnp.random.seed(0)\n\nimport os\nimport gc","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\n    Config\n'''\nIMG_SIZE = 300\nBATCH_SIZE = 16","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\n    Preprocessing using Ben Graham's method (Last competition's winner) \n    https://www.kaggle.com/ratthachat/aptos-updatedv14-preprocessing-ben-s-cropping\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): \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    \ndef load_ben_color(image, sigmaX=10):\n    image = crop_image_from_gray(image).astype('uint8')\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.astype('float32') / 255.\n\n'''\n    Preprocessing for ImageDataGenerator since ImageDataGenerator reads images in rgb mode, while opencv in bgr\n'''\ndef preprocessing(image, sigmaX=10):\n    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)\n    image = crop_image_from_gray(image).astype('uint8')\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.astype('float32') / 255.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\n    Initialize EfficientNetB3\n    Output relu is relu rectifier with max_value of 4 to restrain predictions to proper range\n'''\ndef output_relu(x):\n    return K.relu(x, max_value=4)\n\nbase_model = EfficientNetB3(weights=None, include_top=False, input_shape=(IMG_SIZE,IMG_SIZE,3))\nx = base_model.output\nx = GlobalAveragePooling2D()(x)\nx = Dropout(0.4)(x)\nx = Dense(1, activation=output_relu, kernel_initializer='he_normal')(x)\nmodel = Model(inputs=base_model.input, outputs=x)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\n    Load pretrained weights\n'''\nmodel.load_weights('../input/pretrained-weights/model_b3_epochs_30_300.h5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\n    Load training df and test df for pseudo labeling\n'''\ntrain_csv = pd.read_csv('../input/aptos2019-blindness-detection/train.csv')\ntrain_id_codes = train_csv['id_code']\ntrain_labels = train_csv['diagnosis']\n\nfor i in range(len(train_id_codes)):\n    train_id_codes[i] = '../input/aptos2019-blindness-detection/train_images/{}.png'.format(train_id_codes[i])\n\ntest_csv = pd.read_csv('../input/aptos2019-blindness-detection/sample_submission.csv')\ntest_id_codes = test_csv['id_code']\ntest_pseudo_labels = np.empty(len(test_id_codes), dtype='float32')\nfor i in range(len(test_id_codes)):\n    test_id_codes[i] = '../input/aptos2019-blindness-detection/test_images/{}.png'.format(test_id_codes[i])\n    img = cv2.imread(test_id_codes[i])\n    img = load_ben_color(img)\n    X = np.array([img])\n    pred = model.predict(X)\n    test_pseudo_labels[i] = pred","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\n    Float to integer prediction function. In this case round to nearest integer\n'''\ndef predict(X, coef=[0.5, 1.5, 2.5, 3.5]):\n        X_p = np.copy(X)\n        for i, pred in enumerate(X_p):\n            if pred < coef[0]:\n                X_p[i] = 0\n            elif pred >= coef[0] and pred < coef[1]:\n                X_p[i] = 1\n            elif pred >= coef[1] and pred < coef[2]:\n                X_p[i] = 2\n            elif pred >= coef[2] and pred < coef[3]:\n                X_p[i] = 3\n            else:\n                X_p[i] = 4\n        return X_p","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\n    Round pseudo_labels\n'''\ntest_pseudo_labels = predict(test_pseudo_labels).astype('uint8')\nprint(test_pseudo_labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\n    Create DataFrame for ImageDataGenerator\n    Combine training and test images with pseudo labels\n'''\nd = {}\nd['id_code'] = np.concatenate((train_id_codes, test_id_codes), axis=0)\nd['diagnosis'] = np.concatenate((train_labels, test_pseudo_labels), axis=0).astype('str')\ndf = pd.DataFrame(data=d)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\n    Create Image Data Generator\n'''\ngen = ImageDataGenerator(preprocessing_function=preprocessing)\npseudo_datagen = gen.flow_from_dataframe(df, directory='.', x_col='id_code', y_col='diagnosis', target_size=(IMG_SIZE, IMG_SIZE), class_mode='sparse', batch_size=16)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\n    Double check preprocessing function\n'''\nfig, ax = plt.subplots(nrows=1, ncols=4, figsize=(20,4))\nit = 0\nfor x, y in pseudo_datagen:\n    ax[it].imshow((x[0]*255.).astype('uint8'))\n    ax[it].axis('off')\n    it += 1\n    if it == 4:\n        break","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\n    Compiling model and retraining for 5 epochs\n'''\nmodel.compile(optimizer=keras.optimizers.SGD(lr=1e-3, momentum=0.9, nesterov=True, decay=1e-6), loss='mse')\nmodel.fit_generator(pseudo_datagen,\n                    steps_per_epoch=len(pseudo_datagen),\n                    epochs=5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\n    Final prediction on testset\n'''\ntest_csv = pd.read_csv('../input/aptos2019-blindness-detection/sample_submission.csv')\nid_code = test_csv['id_code']\ntest_prediction = np.empty(len(id_code), dtype='float32')\nfor i in range(len(id_code)):\n    img = cv2.imread('../input/aptos2019-blindness-detection/test_images/{}.png'.format(id_code[i]))\n    img = load_ben_color(img)\n    X = np.array([img])\n    pred = model.predict(X)\n    test_prediction[i] = pred","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\n    Submission\n'''\nprediction = predict(test_prediction).astype('uint8')\ntest_csv['diagnosis'] = prediction\ntest_csv.to_csv(\"submission.csv\", index=False)\nunique, counts = np.unique(prediction, return_counts=True)\ntmp = dict(zip(unique, counts))\nprint(tmp)\nprint('Done!')","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":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.6"}},"nbformat":4,"nbformat_minor":1}