{"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_train = pd.read_csv(train_csv) \nsize = 256,256 # input image size\ndf_test = pd.read_csv(test_csv)\nNUM_CLASSES = df_train['diagnosis'].nunique()\nprint(NUM_CLASSES)","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    #gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\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.cvtColor(cv2.imread(path), cv2.COLOR_BGR2GRAY)\n    img = cv2.resize(cv2.imread(path), size)\n    img = get_cropped_image(img)\n    return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport PIL     #df.at[2, 'StartDate']\n\nimg1 = load_image(train_dir+str(df_train.at[0,\"id_code\"])+str(\".png\"))\nimg2 = load_image(train_dir+str(df_train.at[1,\"id_code\"])+str(\".png\"))\n\n#fig, ax = plt.subplots(nrows=2, ncols=2)\n\nplt.figure(1)\nplt.subplot(211)\nplt.imshow(img1)\n\nplt.subplot(212)\nplt.imshow(img2)\nplt.show()\n ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"training_paths = [train_dir + str(x) + str(\".png\") for x in df_train[\"id_code\"]]\nimages = np.empty((len(df_train), 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":"print(len(images))\n#plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = df_train[\"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":{"trusted":true},"cell_type":"code","source":"images, x_test, labels, y_test = train_test_split(images, labels, test_size = 0.08,shuffle=False)","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 = 60,\n                               vertical_flip = True,\n                              shear_range=0.1)\n\ntrain_generator = train_aug.flow(images, labels, batch_size = 8)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"val_aug=train_aug.flow(x_val,y_val,batch_size=8)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_aug=train_aug.flow(x_test,y_test,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":"OTHER MODEL COPIED FROM APTOS 2019: DenseNet modified Keras Starter(15-12)"},{"metadata":{"trusted":true},"cell_type":"code","source":"BATCH_SIZE = 32\nEPOCHS = 20\nWARMUP_EPOCHS = 2\nLEARNING_RATE = 1e-4\nWARMUP_LEARNING_RATE = 1e-3\nHEIGHT = 256\nWIDTH = 256\nCANAL = 3\nN_CLASSES = 5\nES_PATIENCE = 5\nRLROP_PATIENCE = 3\nDECAY_DROP = 0.5","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras.applications import ResNet50 \ndef build_model(input_shape, n_out):\n    input_tensor = Input(shape=input_shape)\n    base_model = applications.ResNet50(weights='imagenet', \n                                       include_top=False,\n                                       input_tensor=input_tensor)\n    #base_model = ResNet50(include_top = False,weights = 'imagenet',input_tensor = input_tensor)\n\n    x = GlobalAveragePooling2D()(base_model.output)\n    x = Dropout(0.5)(x)\n    x = Dense(2048, activation='relu')(x)\n    x = Dropout(0.5)(x)\n    final_output = Dense(n_out, activation='softmax', name='final_output')(x)\n    model = Model(input_tensor, final_output)\n    \n    return model\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras import optimizers, applications\nfrom keras.models import Model\nmodel = build_model(input_shape=(HEIGHT, WIDTH, CANAL), n_out=N_CLASSES)\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.callbacks import EarlyStopping, ReduceLROnPlateau\nfor layer in model.layers:\n    layer.trainable = True\n\nes = EarlyStopping(monitor='val_loss', mode='min', patience=ES_PATIENCE, restore_best_weights=True, verbose=1)\nrlrop = ReduceLROnPlateau(monitor='val_loss', mode='min', patience=RLROP_PATIENCE, factor=DECAY_DROP, min_lr=1e-6, verbose=1)\n\ncallback_list = [es, rlrop]\noptimizer = optimizers.Adam(lr=LEARNING_RATE)\nmodel.compile(optimizer=optimizer, loss=\"categorical_crossentropy\",  metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#kappa_metrics = Metrics()\nhistory = model.fit_generator(\n    train_generator,\n    steps_per_epoch=images.shape[0] / 8,\n    epochs=20,\n    validation_data=(x_val, y_val),\n    callbacks=callback_list\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#model.save('densenet.h5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"accu = history.history['acc']\nval_acc = history.history['val_acc']\n\nplt.plot(accu, label=\"Accuracy\")\nplt.plot(val_acc)\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Accuracy\")\nplt.legend(['Acc', 'val_acc'])\nplt.plot(np.argmax(history.history[\"val_acc\"]), np.max(history.history[\"val_acc\"]), marker=\"x\", color=\"r\",\n         label=\"best model\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tqdm import tqdm\n(eval_loss, eval_accuracy) = tqdm(\n    model.evaluate_generator(generator=val_aug, steps=201, pickle_safe=False))\nprint(\"[INFO] accuracy: {:.2f}%\".format(eval_accuracy * 100))\nprint(\"[INFO] Loss: {}\".format(eval_loss))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tqdm import tqdm\n(eval_loss, eval_accuracy) = tqdm(model.evaluate_generator(generator=test_aug, steps=201, pickle_safe=False))\nprint(\"[INFO] accuracy: {:.2f}%\".format(eval_accuracy * 100))\nprint(\"[INFO] Loss: {}\".format(eval_loss))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"ORIGINAL CODE:"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications.resnet50 import ResNet50\nfrom keras.applications.resnet50 import preprocess_input\nfrom keras.models import Model\nfrom keras.models import Sequential\nfrom keras.layers.convolutional import Conv2D\nfrom keras.layers.convolutional import MaxPooling2D\nfrom keras.layers.pooling import GlobalAveragePooling2D\nfrom keras.layers import Input\nfrom keras.activations import softmax\nfrom keras.activations import elu\nfrom keras.activations import relu\nfrom keras.optimizers import SGD\nfrom keras.layers.normalization import BatchNormalization\nfrom tqdm import tqdm\nfrom keras.layers import LeakyReLU\n\n\ndef create_resnet(img_dim, CHANNEL, n_class):\n    input_tensor = Input(shape=(256, 256, 3))\n    base_model = ResNet50(include_top=False, input_tensor=input_tensor,weights='../input/resnet50weightsfile/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5')\n    #base_model.load_weights('../input/ResNet50/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5')\n    x = GlobalAveragePooling2D()(base_model.output)\n    x = BatchNormalization()(x)\n    x = Dropout(0.4)(x)\n    x = Dense(2048)(x)\n    x = LeakyReLU(alpha=0.3)(x)\n    x = BatchNormalization()(x)\n    x = Dropout(0.3)(x)\n    x = Dense(1024)(x)\n    x = LeakyReLU(alpha=0.3)(x)\n    #x.add(LeakyReLU(alpha=0.1))\n    x = BatchNormalization()(x)\n    x = Dropout(0.2)(x)\n    x = Dense(512)(x)\n    x = LeakyReLU(alpha=0.3)(x)\n    #x.add(LeakyReLU(alpha=0.1))\n    x = BatchNormalization()(x)\n    x = Dropout(0.4)(x)\n    output_layer = Dense(n_class, activation='softmax', name=\"Output_Layer\")(x)\n    model_resnet = Model(input_tensor, output_layer)\n\n    return model_resnet\n\n\nmodel_resnet = create_resnet(256, 3, NUM_CLASSES)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for layers in model_resnet.layers:\n    layers.trainable = True","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lr = 1e-3\noptimizer = SGD(lr=lr, decay=1e-6, momentum=0.9, nesterov=True) \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_resnet.compile(optimizer = optimizer, loss = \"categorical_crossentropy\", metrics = [\"accuracy\"]) ","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":"h=model_resnet.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":""},{"metadata":{"trusted":true},"cell_type":"code","source":"model_json = model_resnet.to_json()\nwith open(\"model2.json\", \"w\") as json_file:\n    json_file.write(model_json)\n# serialize weights to HDF5\nmodel_resnet.save_weights(\"model2.h5\")\nprint(\"Saved model to disk\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"h.history.keys()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"accu = h.history['acc']\nval_acc = h.history['val_acc']\n\nplt.plot(accu, label=\"Accuracy\")\nplt.plot(val_acc)\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Accuracy\")\nplt.legend(['Acc', 'val_acc'])\nplt.plot(np.argmax(h.history[\"val_acc\"]), np.max(h.history[\"val_acc\"]), marker=\"x\", color=\"r\",\n         label=\"best model\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tqdm import tqdm\n(eval_loss, eval_accuracy) = tqdm(\n    model.evaluate_generator(generator=val_aug, steps=201, pickle_safe=False))\nprint(\"[INFO] accuracy: {:.2f}%\".format(eval_accuracy * 100))\nprint(\"[INFO] Loss: {}\".format(eval_loss))","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_resnet.predict(test_images)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"accu = h.history['acc']\nval_acc = h.history['val_acc']\n\nplt.plot(accu, label=\"Accuracy\")\nplt.plot(val_acc)\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Accuracy\")\nplt.legend(['Acc', 'val_acc'])\nplt.plot(np.argmax(h.history[\"val_acc\"]), np.max(h.history[\"val_acc\"]), marker=\"x\", color=\"r\",\n         label=\"best model\")\nplt.show()","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":{},"cell_type":"markdown","source":"#TESTING WITH IDRID DATASET"},{"metadata":{"trusted":true},"cell_type":"code","source":"#loaded_model.load_weights(\"..input/MY model/model2.h5\")\n#print(\"Loaded model from disk\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"from keras.models import load_model\nmodel = load_weights('../input/My model/model2.h5')"},{"metadata":{"_cell_guid":"","_uuid":"","trusted":true},"cell_type":"code","source":"","execution_count":0,"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":4}