{"cells":[{"metadata":{},"cell_type":"markdown","source":"# imports"},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom tqdm import tqdm_notebook\nfrom zipfile import ZipFile\nimport os\nimport cv2\nfrom matplotlib import cm\nimport matplotlib.pyplot as plt\n\nfrom keras.models import Sequential\nfrom keras_preprocessing.image import ImageDataGenerator\nfrom keras.layers import Activation, Dropout, Conv2D, GlobalMaxPooling2D, MaxPooling2D, Flatten, Dense, BatchNormalization\nfrom keras.optimizers import Adam, SGD\nfrom sklearn.utils import compute_class_weight\nfrom keras.applications.resnet50 import ResNet50\nfrom keras.regularizers import l2\n\nfrom keras_tqdm import TQDMNotebookCallback\nfrom keras.callbacks import ModelCheckpoint","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Extract images"},{"metadata":{"trusted":true},"cell_type":"code","source":"#! ls ../input","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#!rm -rf ../input/trainedprocessed","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"base_path = \"../input/\"\ntrainProcessed = \"trainedprocessed\"\naptop = 'aptos2019-blindness-detection/'\nlocalModel = 'trained-on-local/'\ntrain = \"train_images\"\nIMG_DIM = 96\nSEED = 6819","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_df = pd.read_csv(\"../input/aptos2019-blindness-detection/train.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_df['id_code'] = data_df['id_code']+\".png\" \ndata_df['diagnosis'] = data_df['diagnosis'].astype(\"str\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Sample Image"},{"metadata":{},"cell_type":"markdown","source":"### Reference\nhttps://www.kaggle.com/ratthachat/aptos-updatedv14-preprocessing-ben-s-cropping"},{"metadata":{"trusted":true},"cell_type":"code","source":"def crop_image_from_gray_sample(img,tol=7):\n    \"\"\"\n    Crop out black borders\n    https://www.kaggle.com/ratthachat/aptos-updated-preprocessing-ben-s-cropping\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","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"imgs = cv2.imread(base_path+aptop+\"train_images/000c1434d8d7.png\")\nimgs = crop_image_from_gray_sample(imgs)\nimgs = cv2.resize(imgs, (IMG_DIM, IMG_DIM))\nimgs = cv2.addWeighted(imgs,4, cv2.GaussianBlur(imgs, (0,0), 10), -4, 128)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Experiment\nplt.imshow(imgs)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data conversion"},{"metadata":{"trusted":true},"cell_type":"code","source":"def 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    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","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def pre_process(img):\n    img = crop_image_from_gray((img).astype(np.uint8))\n    img = cv2.resize(img, (IMG_DIM, IMG_DIM))\n    img = cv2.addWeighted(img,4, cv2.GaussianBlur(img, (0,0), 10), -4, 128)\n    return img.astype(np.float64)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"try:\n    os.mkdir(base_path+trainProcessed)\n    print(\"Directory Created :\"+trainProcessed)\n    \n    for file in tqdm_notebook(data_df[\"id_code\"].iteritems(), total=data_df.shape[0]):\n        img = cv2.imread(base_path+aptop+train+\"/\"+file[1])\n        img = crop_image_from_gray(img)\n        img = cv2.resize(img, (400, 400))\n        img = cv2.addWeighted(img,4, cv2.GaussianBlur(img, (0,0), 10), -4, 128)\n        cv2.imwrite(base_path+trainProcessed+\"/\"+file[1], img)\n    print(\"Conversion done.\")\nexcept:\n    print(\"Directory \"+trainProcessed+\" already exist !\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data Generator"},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size=8\nepochs = 20","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_gen = ImageDataGenerator(vertical_flip=True,\n                             horizontal_flip=True,\n                             rescale=1./255, \n                             #preprocessing_function=pre_process,\n                             data_format='channels_last')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tempGen = data_gen.flow_from_dataframe(dataframe=data_df, \n                                       directory=base_path+trainProcessed,\n                                       x_col=\"id_code\",\n                                       y_col=\"diagnosis\",\n                                       target_size=(IMG_DIM,IMG_DIM),\n                                       class_mode='categorical',\n                                       batch_size=batch_size,\n                                       seed=SEED)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tx, ty = next(tempGen)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize=(100, 100))\ncolumns = 4\nrow = 2\nfor i in range(1, columns*row+1):\n    fig.add_subplot(row, columns, i)\n    #plt.imshow((tx[i-1].reshape((400, 400))*255).astype(np.int32))\n    plt.imshow((tx[i-1]*255).astype(np.uint8))\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = data_df.sample(frac=0.8, random_state=SEED)\nvalidate_df = data_df.loc[~data_df['id_code'].isin(train_df['id_code'].values)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(train_df), len(validate_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.reset_index(inplace=True, drop=True)\nvalidate_df.reset_index(inplace=True, drop=True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Train validate generator"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_generator = data_gen.flow_from_dataframe(dataframe=train_df, \n                                       directory=base_path+trainProcessed,\n                                       x_col=\"id_code\",\n                                       y_col=\"diagnosis\",\n                                       target_size=(IMG_DIM,IMG_DIM),\n                                       class_mode='categorical',\n                                       batch_size=batch_size,\n                                       seed=SEED)\nvalidation_generator = data_gen.flow_from_dataframe(dataframe=validate_df, \n                                       directory=base_path+trainProcessed,\n                                       x_col=\"id_code\",\n                                       y_col=\"diagnosis\",\n                                       target_size=(IMG_DIM,IMG_DIM),\n                                       class_mode='categorical',\n                                       batch_size=batch_size,\n                                       seed=SEED)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X, y = next(train_generator)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X.shape, y.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Class Weight"},{"metadata":{"trusted":true},"cell_type":"code","source":"class_weights = compute_class_weight(\"balanced\", \n                     np.unique(train_generator.classes), \n                     train_generator.classes)\nclass_weights","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# model"},{"metadata":{"trusted":true},"cell_type":"code","source":"model_resnet = ResNet50(include_top=False, \n                        weights = None,\n                        input_shape=(IMG_DIM, IMG_DIM, 3,))\nmodel_resnet.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Sequential()\nmodel.add(model_resnet)\n\n#model.add(Flatten())\nmodel.add(GlobalMaxPooling2D())\nmodel.add(Dense(1000, activation='relu', activity_regularizer=l2(0.001)))\nmodel.add(Dense(500, activation='relu', activity_regularizer=l2(0.001)))\n#model.add(Dense(250, activation='relu', activity_regularizer=l2(0.001)))\n#model.add(BatchNormalization())\n#model.add(Dropout(0.5))\nmodel.add(Dense(5, activation = 'softmax'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.load_weights(base_path+localModel+\"model_resnet_aptos_0.2.hdf5\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(loss='categorical_crossentropy',\n              #optimizer=SGD(lr=0.00001),\n              optimizer=Adam(lr=0.00001),\n              metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"filepath=\"weights-resnet-improvement-{epoch:02d}-{val_acc:.2f}.hdf5\"\n#filepath=\"weights.best.hdf5\"\ncheckpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=0, save_best_only=True, mode='max')\ncallbacks_list = [checkpoint, TQDMNotebookCallback()]\n#callbacks_list = [TQDMNotebookCallback()]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_step = train_df.size//batch_size\nvalid_step = validate_df.size//batch_size\nhistory = model.fit_generator(train_generator,\n                    validation_data=validation_generator,\n                    epochs=epochs, \n                    steps_per_epoch=train_step, \n                    validation_steps=valid_step, \n                    shuffle= True,\n                    workers=6, \n                    verbose=2,\n                    use_multiprocessing=False,\n                    #callbacks=callbacks_list, \n                    initial_epoch=0,\n                    class_weight=class_weights)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.save('model_resnet_aptos_kaggle.hdf5')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Test"},{"metadata":{"trusted":true},"cell_type":"code","source":"test = \"test_images/\"\ntestProcessed = \"testProcessed\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.read_csv(base_path+aptop+\"test.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df['id_code'] = test_df['id_code']+\".png\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#!ls ../input\n#!rm -rf  ../input/testProcessed","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"try:\n    os.mkdir(base_path+testProcessed)\n    print(\"Directory Created :\"+testProcessed)\n    \n    for file in tqdm_notebook(test_df[\"id_code\"].iteritems(), total=test_df.shape[0]):\n        img = cv2.imread(base_path+aptop+test+\"/\"+file[1])\n        img = crop_image_from_gray(img)\n        img = cv2.resize(img, (IMG_DIM, IMG_DIM))\n        img = cv2.addWeighted(img,4, cv2.GaussianBlur(img, (0,0), 10), -4, 128)\n        cv2.imwrite(base_path+testProcessed+\"/\"+file[1], img)\n    print(\"Conversion done.\")\nexcept:\n    print(\"Directory \"+testProcessed+\" already exist !\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_datagen = ImageDataGenerator(rescale=1./255, \n                                  #preprocessing_function=pre_process,\n                                  data_format=\"channels_last\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"testgen = test_datagen.flow_from_dataframe(dataframe=test_df,\n                                       directory=base_path+aptop+test, \n                                       target_size=(IMG_DIM,IMG_DIM), \n                                       x_col=\"id_code\", \n                                       batch_size=batch_size, \n                                       shuffle=False, \n                                       class_mode=None, \n                                       seed=SEED)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"testgen.reset()\nSTEP_TEST_GEN = test_df.size//batch_size\npred = model.predict_generator(testgen,\n                               steps=STEP_TEST_GEN,\n                               verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred_class_indices = np.argmax(pred, axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = (train_generator.class_indices)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = (train_generator.class_indices)\nlabels = dict((c,v) for v, c in labels.items())\nprediction = [labels[k] for k in pred_class_indices]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"filenames = testgen.filenames","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results = pd.DataFrame({\"id_code\": filenames, \n          \"diagnosis\": prediction})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results[\"id_code\"] = results[\"id_code\"].str.rstrip(\".png\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results.to_csv(\"submission.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# End"}],"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.8"}},"nbformat":4,"nbformat_minor":1}