{"cells":[{"metadata":{},"cell_type":"markdown","source":"<center><h1>100 each (Balanced)</h1></center>"},{"metadata":{},"cell_type":"markdown","source":"**RESNET50** - Using Keras"},{"metadata":{"trusted":true},"cell_type":"code","source":"#necessary libraries\nimport numpy as np\nimport pandas as pd\nimport os\nfrom glob import glob \nimport matplotlib.pyplot as plt\nfrom sklearn.utils import shuffle\n\nimport random\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import roc_curve, auc, roc_auc_score\n\nfrom keras_preprocessing.image import ImageDataGenerator\n\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Flatten, BatchNormalization, Activation\nfrom keras.layers import Conv2D, MaxPool2D\n\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#for handling the data set\npath = \"../input/histopathologic-cancer-detection/\" \nlabels = pd.read_csv(path + 'train_labels.csv')\ntrain_path = path + 'train/'\ntest_path = path + 'test/'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Create a dataframe which contains every training examples path, id and label**"},{"metadata":{"trusted":true},"cell_type":"code","source":"#fixing the dataframe\ndf = pd.DataFrame({'path': glob(os.path.join(train_path,'*.tif'))})\ndf['id'] = df.path.map(lambda x: ((x.split(\"in\")[2].split('.')[0])[1:]))\ndf = df.merge(labels, on = \"id\")\ndf.head(3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"SAMPLE_SIZE = 100","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#filter out class 0\ndf_0 = df[df['label'] == 0].sample(SAMPLE_SIZE, random_state = 101)\n# filter out class 1\ndf_1 = df[df['label'] == 1].sample(SAMPLE_SIZE, random_state = 101)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n# concat the dataframes\ndf_data = pd.concat([df_0, df_1], axis=0).reset_index(drop=True)\n# shuffle\ndf_data = shuffle(df_data)\n\ndf_data['label'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Going to split 20% of the training set into a validation set**"},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ndf_data['label'] = df_data['label'].astype(str)\ntrain, valid = train_test_split(df_data, test_size=0.2, stratify = df_data['label'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Increasing the size of the image results in a much higher performance**"},{"metadata":{"trusted":true},"cell_type":"code","source":"IMG_SIZE = 196\nBATCH_SIZE = 10","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#image resizing\nfrom keras_preprocessing.image import ImageDataGenerator\ntrain_datagen = ImageDataGenerator(rescale=1./255,\n                                  vertical_flip = True,\n                                  horizontal_flip = True,\n                                  rotation_range=90,\n                                  zoom_range=0.2, \n                                  width_shift_range=0.1,\n                                  height_shift_range=0.1,\n                                  shear_range=0.05,\n                                  channel_shift_range=0.1)\n\ntest_datagen = ImageDataGenerator(rescale = 1./255) ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Resizing and dividing training data into train and validation**"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_generator = train_datagen.flow_from_dataframe(dataframe = train, \n                                                    directory = None,\n                                                    x_col = 'path', \n                                                    y_col = 'label',\n                                                    target_size = (IMG_SIZE,IMG_SIZE),\n                                                    class_mode = \"binary\",\n                                                    batch_size=BATCH_SIZE,\n                                                    seed = 110318,\n                                                    shuffle = True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"valid_generator = test_datagen.flow_from_dataframe(dataframe = valid,\n                                                   directory = None,\n                                                   x_col = 'path',\n                                                   y_col = 'label',\n                                                   target_size = (IMG_SIZE,IMG_SIZE),\n                                                   class_mode = 'binary',\n                                                   batch_size = BATCH_SIZE,\n                                                   shuffle = False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Creating Model**"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications.resnet50 import ResNet50\n\ndropout_fc = 0.5\n\nconv_base = ResNet50(weights = 'imagenet', include_top = False, input_shape = (IMG_SIZE,IMG_SIZE,3))\n\nmy_model = Sequential()\n\nmy_model.add(conv_base)\nmy_model.add(Flatten())\nmy_model.add(Dense(256, use_bias=False))\nmy_model.add(BatchNormalization())\nmy_model.add(Activation(\"relu\"))\nmy_model.add(Dropout(dropout_fc))\nmy_model.add(Dense(1, activation = \"sigmoid\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"my_model.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**As we're using ResNet50 trained on ImageNet, we're going to need to train the last few layers instead of the just the last one. Cell images are quite different to what we see on ImageNet**"},{"metadata":{"trusted":true},"cell_type":"code","source":"conv_base.Trainable=True\n\nset_trainable=False\nfor layer in conv_base.layers:\n    if layer.name == 'res5a_branch2a':\n        set_trainable = True\n    if set_trainable:\n        layer.trainable = True\n    else:\n        layer.trainable = False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#for the last few layers\nfrom keras import optimizers\nmy_model.compile(optimizers.Adam(0.001), loss = \"binary_crossentropy\", metrics = [\"accuracy\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_step_size = train_generator.n // train_generator.batch_size\nvalid_step_size = valid_generator.n // valid_generator.batch_size","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#for the ease of smoother training\nearlystopper = EarlyStopping(monitor='val_loss', patience=3, verbose=2, restore_best_weights=True)\nreduce = ReduceLROnPlateau(monitor='val_loss', patience=1, verbose=1, factor=0.1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#fitting the model \nhistory = my_model.fit_generator(train_generator,\n                                     steps_per_epoch = train_step_size,\n                                     epochs = 30,\n                                     validation_data = valid_generator,\n                                     validation_steps = valid_step_size,\n                                     callbacks = [reduce, earlystopper],\n                                     verbose = 2)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**EVALUATION**"},{"metadata":{"trusted":true},"cell_type":"code","source":"epochs = [i for i in range(1, len(history.history['loss'])+1)]\n\nplt.plot(epochs, history.history['loss'], color='blue', label=\"training_loss\")\nplt.plot(epochs, history.history['val_loss'], color='red', label=\"validation_loss\")\nplt.legend(loc='best')\nplt.title('Loss')\nplt.xlabel('epoch')\nplt.show()\n\nplt.plot(epochs, history.history['accuracy'], color='blue', label=\"training_accuracy\")\nplt.plot(epochs, history.history['val_accuracy'], color='red',label=\"validation_accuracy\")\nplt.legend(loc='best')\nplt.title('Accuracy')\nplt.xlabel('epoch')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**ROC Curve**"},{"metadata":{"trusted":true},"cell_type":"code","source":"roc_validation_generator = ImageDataGenerator(rescale=1./255).flow_from_dataframe(valid,\n                                                                                  x_col = 'path',\n                                                                                  y_col = 'label',\n                                                                                  target_size = (IMG_SIZE,IMG_SIZE),\n                                                                                  class_mode = 'binary',\n                                                                                  batch_size = BATCH_SIZE,\n                                                                                  shuffle = False)\npredictions = my_model.predict_generator(roc_validation_generator, steps=len(roc_validation_generator), verbose=2)\nfalse_positive_rate, true_positive_rate, threshold = roc_curve(roc_validation_generator.classes, predictions)\narea_under_curve = auc(false_positive_rate, true_positive_rate)\n\nplt.plot([0, 1], [0, 1], 'k--')\nplt.plot(false_positive_rate, true_positive_rate, label='AUC = {:.3f}'.format(area_under_curve))\nplt.xlabel('False positive rate')\nplt.ylabel('True positive rate')\nplt.title('ROC curve')\nplt.legend(loc='best')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**PREDICTIONS**"},{"metadata":{},"cell_type":"markdown","source":"**Using Test Time Augmentation. For each test image I will augment it 3 ways and average the prediction.**"},{"metadata":{"trusted":true},"cell_type":"code","source":"testdf = pd.DataFrame({'path': glob(os.path.join(test_path, '*.tif'))})\ntestdf['id'] = testdf.path.map(lambda x: (x.split(\"st/\")[1].split('.')[0]))\ntestdf.head(3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"SAMPLE_SIZE = 1000","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df = testdf.sample(SAMPLE_SIZE, random_state = 101)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tta_datagen = ImageDataGenerator(rescale=1./255, #Normalise\n                                 vertical_flip = True,\n                                 horizontal_flip = True,\n                                 rotation_range=90,\n                                 zoom_range=0.2, \n                                 width_shift_range=0.1,\n                                 height_shift_range=0.1,\n                                 shear_range=0.05,\n                                 channel_shift_range=0.1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\nfrom IPython.display import clear_output\ntta_steps = 3\nfinal = pd.DataFrame()\nfor index in range(0, len(df)):\n    data_frame = pd.DataFrame({'path': df.iloc[index,0]}, index=[index])\n    data_frame['id'] = data_frame.path.map(lambda x: x.split('st/')[1].split('.')[0])\n    img_path = data_frame.iloc[0,0]\n    test_img = cv2.imread(img_path)\n    test_img = cv2.resize(test_img,(IMG_SIZE,IMG_SIZE))\n    test_img = np.expand_dims(test_img, axis = 0)  \n    predictionsTTA = []\n    for i in range(0, tta_steps):\n        preds = my_model.predict_generator(tta_datagen.flow_from_dataframe(dataframe = data_frame,\n                                                                           directory = None,\n                                                                           x_col = 'path',\n                                                                           target_size = (IMG_SIZE, IMG_SIZE),\n                                                                           class_mode = None,\n                                                                           batch_size = 1,\n                                                                           shuffle = False), steps = 1)\n        predictionsTTA.append(preds)\n    clear_output()\n    prediction_entry = np.array(np.round(np.mean(predictionsTTA, axis=0)))\n    data_frame['label'] = prediction_entry\n    final = pd.concat([final, data_frame[['id', 'label']]])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"final.set_index('id')\nfinal.head(3)","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":4}