{"cells":[{"metadata":{},"cell_type":"markdown","source":"* In this kernel we are going to use ImageDataGenerator to load images in batches of 8, and adding augmentation.\n* Augmentations - rotation, zoomimg, horizontal and vertical flips.\n* *CROPPING IMAGE* : We will also use image cropping to crop the extra black part in the images in the training data.\n* We will use the DenseNet121 model."},{"metadata":{},"cell_type":"markdown","source":"Imports"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\nfrom keras.applications import DenseNet121\nfrom keras.models import Model\nfrom keras.layers import Dense, GlobalAveragePooling2D, Dropout, Input\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nimport keras\nimport csv\nimport gc\nimport cv2\nfrom tqdm import tqdm_notebook\n\ntrain_csv = \"../input/aptos2019-blindness-detection/train.csv\"\ntest_csv = \"../input/aptos2019-blindness-detection/test.csv\"\ntrain_dir = \"../input/aptos2019-blindness-detection/train_images/\"\ntest_dir = \"../input/aptos2019-blindness-detection/test_images/\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df = pd.read_csv(train_csv) \nsize = 256,256 # input image size","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### CROPPING FUNCTION :"},{"metadata":{"trusted":true},"cell_type":"code","source":"# cropping function (uses edge detection to crop images)\ndef get_cropped_image(image):\n    img = cv2.blur(image,(2,2))\n    slice1Copy = np.uint8(img)\n    canny = cv2.Canny(slice1Copy, 0, 50)\n    pts = np.argwhere(canny>0)\n    y1,x1 = pts.min(axis=0)\n    y2,x2 = pts.max(axis=0)\n    cropped_img = img[y1:y2, x1:x2]\n    cropped_img = cv2.resize(cropped_img, size)\n    return cropped_img","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Demonstration of above function :\n"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"sample_to_show = ['07419eddd6be.png','0124dffecf29.png']\n\ndef get_cropped_image_demo(image):\n    img = cv2.blur(image,(2,2))\n    slice1Copy = np.uint8(img)\n    canny = cv2.Canny(slice1Copy, 0, 50)\n    pts = np.argwhere(canny>0)\n    y1,x1 = pts.min(axis=0)\n    y2,x2 = pts.max(axis=0)\n    cropped_img = img[y1:y2, x1:x2]\n    return np.array(cropped_img)\n\nnames = []\nsamples = []\ncropped_images = []\nfor i in sample_to_show:\n    path = train_dir + str(i)\n    img_ = cv2.imread(path)\n    img_ = cv2.cvtColor(img_, cv2.COLOR_BGR2RGB)\n    samples.append(img_)\n    cropped_ = get_cropped_image_demo(img_)\n    cropped_images.append(cropped_)\n    \nfig = plt.figure(figsize = (5,5))\nax1 = fig.add_subplot(2,2,1)\nax1.title.set_text('original image'), ax1.axis(\"off\"), plt.imshow(samples[0])\nax2 = fig.add_subplot(2,2,2)\nax2.title.set_text('cropped image'), ax2.axis(\"off\"), plt.imshow(cropped_images[0])\nax3 = fig.add_subplot(2,2,3)\nax3.title.set_text('original image'), ax3.axis(\"off\"), plt.imshow(samples[1])\nax4 = fig.add_subplot(2,2,4)\nax4.title.set_text('cropped image'), ax4.axis(\"off\"), plt.imshow(cropped_images[1]);","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Loading Images :"},{"metadata":{"trusted":true},"cell_type":"code","source":"def load_image(path):\n    img = cv2.resize(cv2.cvtColor(cv2.imread(path), cv2.COLOR_BGR2RGB), size)\n    img = get_cropped_image(img)\n    return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"training_paths = [train_dir + str(x) + str(\".png\") for x in df[\"id_code\"]]\nimages = np.empty((len(df), 256,256,3), dtype = np.uint8)\nfor i, path in tqdm_notebook(enumerate(training_paths)):\n    images[i,:,:,:] = load_image(path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = df[\"diagnosis\"].values.tolist()\nlabels = keras.utils.to_categorical(labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"images, x_val, labels, y_val = train_test_split(images, labels, test_size = 0.15)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### ImageDataGenerator (Training data)"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_aug = ImageDataGenerator(horizontal_flip = True,\n                               zoom_range = 0.25,\n                               rotation_range = 360,\n                               vertical_flip = True)\n\ntrain_generator = train_aug.flow(images, labels, batch_size = 8)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"MODEL:"},{"metadata":{"trusted":true},"cell_type":"code","source":"input_layer = Input(shape = (256,256,3))\nbase_model = DenseNet121(include_top = False, input_tensor = input_layer, weights = \"../input/densenet-keras/DenseNet-BC-121-32-no-top.h5\")\nx = GlobalAveragePooling2D()(base_model.output)\nx = Dropout(0.5)(x)\nout = Dense(5, activation = 'softmax')(x)\n\nmodel = Model(inputs = input_layer, outputs = out)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"This kernel helped me choose the model parameters, and callbacks - [APTOS Blindness Detection - EDA and Keras ResNet50](https://www.kaggle.com/dimitreoliveira/aptos-blindness-detection-eda-and-keras-resnet50?scriptVersionId=16639594)"},{"metadata":{"trusted":true},"cell_type":"code","source":"optimizer = keras.optimizers.Adam(lr=3e-4)\n\nes = EarlyStopping(monitor='val_loss', mode='min', patience = 5, restore_best_weights = True)\nrlrop = ReduceLROnPlateau(monitor='val_loss', mode='min', patience = 2, factor = 0.5, min_lr=1e-6)\n    \ncallback_list = [es, rlrop]\n\nmodel.compile(optimizer = optimizer, loss = \"categorical_crossentropy\", metrics = [\"accuracy\"]) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.fit_generator(generator = train_generator, steps_per_epoch = len(train_generator), epochs = 20, validation_data = (x_val, y_val), callbacks = callback_list)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del train_generator, images\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"TEST:"},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.read_csv(test_csv)\ntest_paths = [test_dir + str(x) + str(\".png\") for x in test_df[\"id_code\"]]\ntest_images = np.empty((len(test_df), 256,256,3), dtype = np.uint8)\nfor i, path in tqdm_notebook(enumerate(test_paths)):\n    test_images[i,:,:,:] = cv2.resize(cv2.cvtColor(cv2.imread(path), cv2.COLOR_BGR2RGB), size)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### PREDICTION"},{"metadata":{"trusted":true},"cell_type":"code","source":"predprobs = model.predict(test_images)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predictions = []\nfor i in predprobs:\n    predictions.append(np.argmax(i)) ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Submission :"},{"metadata":{"trusted":true},"cell_type":"code","source":"id_code = test_df[\"id_code\"].values.tolist()\nsubfile = pd.DataFrame({\"id_code\":id_code, \"diagnosis\":predictions})\nsubfile.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}