{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":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 matplotlib.pyplot as plt\nimport cv2\nfrom sklearn.model_selection import train_test_split\n\nimport tensorflow as tf\nfrom keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, GlobalAveragePooling2D, Input, Dropout\nfrom keras.models import Sequential, Model\nfrom keras import layers\nfrom keras import regularizers\nfrom keras import optimizers\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.applications.resnet50 import ResNet50\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau, Callback\nfrom sklearn.metrics import cohen_kappa_score\n\nimport os\nprint([f for f in os.listdir(\"../input\") if not f.startswith('.')])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"train = pd.read_csv('../input/aptos2019-blindness-detection/train.csv')\ntest = pd.read_csv('../input/aptos2019-blindness-detection/test.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train.id_code = train.id_code.apply(lambda x: x + \".png\")\ntest.id_code = test.id_code.apply(lambda x: x + \".png\")\ntrain['diagnosis'] = train['diagnosis'].astype('str')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def crop_image_from_gray(img, tol=7):\n    \n    \n    \n    if img.ndim == 2:\n        mask = img > tol\n        return img[np.ix_(mask.any(1),mask.any(0))]\n\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 \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 preprocess_image(image, sigmaX=10):\n    \n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    image = crop_image_from_gray(image)\n    image = cv2.resize(image, (300, 300))\n    image = cv2.addWeighted (image,4, cv2.GaussianBlur(image, (0,0) ,sigmaX), -4, 128)\n    return image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_datagen = ImageDataGenerator(rescale=1. / 128, \n                                         validation_split=0.2,\n                                         horizontal_flip=True,\n                                         width_shift_range=0.2,\n                                         height_shift_range=0.2,\n                                         rotation_range=40, \n                                         zoom_range=0.15, \n                                         shear_range=0.15,\n                                         preprocessing_function=preprocess_image,\n                                         fill_mode='nearest')\n\ntrain_generator = train_datagen.flow_from_dataframe(dataframe=train,\n                                                    directory=\"../input/aptos2019-blindness-detection/train_images/\",\n                                                    x_col=\"id_code\",\n                                                    y_col=\"diagnosis\",\n                                                    batch_size=12,\n                                                    class_mode=\"categorical\",\n                                                    target_size=(300, 300),\n                                                    subset='training',\n                                                    shuffle=True)\n                                                    \nvalid_generator = train_datagen.flow_from_dataframe(dataframe=train,\n                                                    directory=\"../input/aptos2019-blindness-detection/train_images/\",\n                                                    x_col=\"id_code\",\n                                                    y_col=\"diagnosis\",\n                                                    batch_size=12,\n                                                    class_mode=\"categorical\",\n                                                    target_size=(300, 300),\n                                                    subset='validation',\n                                                    shuffle=True)  ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"conv_base = ResNet50(weights='../input/resnet50-data/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5', include_top=False,input_shape=(300, 300, 3)) \nconv_base.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Sequential() \nmodel.add(conv_base) \nmodel.add(GlobalAveragePooling2D())\nmodel.add(layers.Dropout(0.5))\nmodel.add(layers.Dense(256))\nmodel.add(layers.BatchNormalization())\nmodel.add(layers.Activation('relu'))\nmodel.add(layers.Dense(5, activation='softmax'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"conv_base.trainable = False\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learning_rate = 1E-3 \n\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=optimizers.RMSprop(lr=learning_rate),\n              metrics=['acc'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit_generator(train_generator,\\\n                              steps_per_epoch=len(train)*0.8//12,\\\n                              epochs=2)\n#                               validation_data=valid_generator,\\\n#                              validation_steps=len(train)*0.2//12)  ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_preds_and_labels(model, generator):\n    preds = []\n    labels = []\n    for _ in range(int(np.ceil(generator.samples / 12))):\n        x, y = next(generator)\n        preds.append(np.argmax(model.predict(x),axis=1))\n        for i in y:\n          labels.append(np.argmax(i))\n        \n    return np.concatenate(preds).ravel(), np.asarray(labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class Metrics(Callback):\n    \n    def on_train_begin(self, logs={}):\n        \n        self.val_kappas = []\n\n    def on_epoch_end(self, epoch, logs={}):\n        \n        \n        y_pred, labels = get_preds_and_labels(model, valid_generator)\n        #y_pred = np.rint(y_pred).astype(np.uint8).clip(0, 4)\n        \n        _val_kappa = cohen_kappa_score(labels, y_pred,labels=[0,1,2,3,4], weights='quadratic')\n        self.val_kappas.append(_val_kappa)\n        print(f\"val_kappa: {round(_val_kappa, 4)}\")\n        if _val_kappa == max(self.val_kappas):\n            print(\"Validation Kappa has improved. Saving model.\")\n            self.model.save('resnet50-3.h5')\n        return","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for layer in model.layers:\n    layer.trainable = True\n    \nkappa_metrics = Metrics()\nes = EarlyStopping(monitor='val_loss', mode='min', patience=5, restore_best_weights=True)\nrlrop = ReduceLROnPlateau(monitor='val_loss', mode='min', patience=3, min_lr=1e-6)\n\ncallback_list = [kappa_metrics,es, rlrop]\nlearning_rate = 1E-4 # to be tuned!\n\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=optimizers.RMSprop(lr=learning_rate),\n              metrics=['acc'])\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history_finetunning = model.fit_generator(train_generator,\n                              steps_per_epoch=len(train)*0.8//12,\n                              validation_data=valid_generator,\n                              validation_steps=len(train)*0.2//12,\n                              epochs=30,\n                              callbacks=callback_list)\n#model_res.save('resnet50-1.h5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"acc = history_finetunning.history['acc']\nval_acc = history_finetunning.history['val_acc']\n\nepochs = range(len(acc))\n\nplt.plot(epochs, acc, 'bo', label='Training acc')\nplt.plot(epochs, val_acc, 'r', label='Validation acc')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_datagen = ImageDataGenerator(rescale=1. / 128,preprocessing_function=preprocess_image)\n\ntest_generator = test_datagen.flow_from_dataframe(dataframe=test,\n                                                  directory=\"../input/aptos2019-blindness-detection/test_images/\",\n                                                  x_col=\"id_code\",\n                                                  target_size=(300, 300),\n                                                  batch_size=1,\n                                                  shuffle=False,                                                  \n                                                  class_mode=None)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_test=np.argmax(model.predict(test_generator), axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"filenames = test_generator.filenames\nresults = pd.DataFrame({'id_code':filenames, 'diagnosis':y_test})\nresults['id_code'] = results['id_code'].map(lambda x: str(x)[:-4])\nresults.to_csv('submission.csv',index=False)\nresults.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":1}