{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras.applications import *\nfrom tensorflow.keras import Model\nfrom tensorflow.keras.layers import *\nimport matplotlib.pyplot as plt\n\nimport seaborn as sns\nimport cv2\nimport re\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"dataset_dir = '../input/ranzcr-clip-catheter-line-classification/'\ntrain_df = pd.read_csv(os.path.join(dataset_dir, 'train.csv'))\n\ntrain_img = os.path.join(dataset_dir,'train')\ntrain_annotations_df = pd.read_csv(os.path.join(dataset_dir, 'train_annotations.csv'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"seed = 456\nbatch_size = 16\nnp.random.seed(seed)\ntf.random.set_seed(seed)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_size = 256\ntrain_tfr = os.path.join(dataset_dir, \"train_tfrecords\")\n\nautotune = tf.data.experimental.AUTOTUNE\n\nfeature_map = {\n        'ETT - Abnormal' : tf.io.FixedLenFeature([], tf.int64),\n        'ETT - Borderline' : tf.io.FixedLenFeature([], tf.int64),\n        'ETT - Normal' : tf.io.FixedLenFeature([], tf.int64),\n        \"NGT - Abnormal\" : tf.io.FixedLenFeature([], tf.int64),\n        'NGT - Borderline' : tf.io.FixedLenFeature([], tf.int64),\n        'NGT - Incompletely Imaged' : tf.io.FixedLenFeature([], tf.int64),\n        'NGT - Normal' : tf.io.FixedLenFeature([], tf.int64),\n        'CVC - Abnormal' : tf.io.FixedLenFeature([], tf.int64),\n        'CVC - Borderline': tf.io.FixedLenFeature([], tf.int64),\n        'CVC - Normal': tf.io.FixedLenFeature([], tf.int64),\n        'StudyInstanceUID' : tf.io.FixedLenFeature([], tf.string),\n        'Swan Ganz Catheter Present' : tf.io.FixedLenFeature([], tf.int64),\n        'image' : tf.io.FixedLenFeature([], tf.string)\n    }","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def read_tfrecords(example):\n    example = tf.io.parse_single_example(example, feature_map)\n    #decoding images\n    image = tf.image.decode_jpeg(example['image'])\n    #converting grayscale to rgb\n    image = tf.image.grayscale_to_rgb(image)\n    #resizing images\n    image = tf.image.resize(image, (img_size, img_size))\n    \n    if augmenter:\n        image = augment(image)\n    \n    image = image/255\n    \n    features = tf.stack([\n        example['ETT - Abnormal'],\n        example['ETT - Borderline'],\n        example['ETT - Normal'],\n        example[\"NGT - Abnormal\"],\n        example['NGT - Borderline'],\n        example['NGT - Incompletely Imaged'],\n        example['NGT - Normal'],\n        example['CVC - Abnormal'],\n        example['CVC - Borderline'],\n        example['CVC - Normal'],\n        example['Swan Ganz Catheter Present']\n        ])\n    \n    \n    return image, features","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow_addons as tfa\n\ndef load_dataset(filenames, aug):\n    \n    tfrecords = tf.data.TFRecordDataset(filenames)\n    \n    tfrecords = tfrecords.map(read_tfrecords, num_parallel_calls = autotune)\n    \n    return tfrecords\n\ndef augment(image):\n    \n    decider = tf.random.uniform(shape = (1,1), minval = 0, maxval = 1)\n    \n    if decider > 0.5:\n        dx_dy = tf.random.uniform(shape = (1,2), minval = -20, maxval = 20)\n        image = tf.image.random_flip_left_right(image)\n        image = tf.image.random_flip_up_down(image)\n        image = tf.image.random_brightness(image, 0.5)\n        image = tf.image.random_contrast(image, 0.2, 0.5)\n\n        image = tfa.image.translate(image, dx_dy)\n\n    \n    return image\n\ndef class_func(images, label):\n    return label\n    \n    \ndef get_dataset(filenames, aug):\n    \n    global augmenter\n    \n    augmenter = aug\n\n    \n    ds = load_dataset(filenames,augmenter)\n    ds = ds.batch(batch_size)\n    #ds = ds.shuffle(512)\n    #ds = ds.cache()\n    ds = ds.repeat()\n    ds = ds.prefetch(autotune)\n    \n    return ds","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"validation_split = 0.25\nTFR_fnames = tf.io.gfile.glob(train_tfr + '/*.tfrec')\nTFR_fnames_train = TFR_fnames[int(len(TFR_fnames) * validation_split):]\nTFR_fnames_valid = TFR_fnames[:int(len(TFR_fnames) * validation_split)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dataset = get_dataset(TFR_fnames_train, True)\nvalid_dataset = get_dataset(TFR_fnames_valid, False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Xception\n\n**It is an Depthwise separable covolutions based pretrained model which was first proposed in 2017, more can be read from [here](https://arxiv.org/pdf/1610.02357.pdf)**\n","attachments":{}},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_model(base_model):\n    inputs = tf.keras.Input(shape = (img_size, img_size, 3,))\n    x = base_model(inputs)\n    x = tf.keras.layers.GlobalAveragePooling2D()(x)\n    x = tf.keras.layers.Dense(1024, activation = 'relu')(x)\n    outputs = tf.keras.layers.Dense(11, activation = 'sigmoid')(x)\n    \n    model = tf.keras.Model(inputs = inputs, outputs = outputs)\n    \n    model.summary()\n    \n    optimizer = tf.keras.optimizers.Adam(9e-6)\n    model.compile(loss = 'binary_crossentropy', optimizer = optimizer, metrics = [tf.keras.metrics.AUC(multi_label=True)])\n    \n    return model\n\nXception = Xception(include_top = False,\n                     weights = '../input/keras-pretrained-models/xception_weights_tf_dim_ordering_tf_kernels_notop.h5',\n                    input_shape = (img_size, img_size, 3))\n\nXception.trainable  = True\n\nxception = create_model(Xception)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Checking Data to be Trained"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_samples = sum(1 for _ in tf.data.TFRecordDataset(TFR_fnames_train))\nvalid_samples = sum(1 for _ in tf.data.TFRecordDataset(TFR_fnames_valid))\nprint(\"There are: \" + str(train_samples) + \" train samples and \" + str(valid_samples) + \" validation samples\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"epochs = 15\n\ncallbacks = [tf.keras.callbacks.EarlyStopping(monitor = 'val_auc',\n                                              mode = 'max',\n                                             patience = 1  ,\n                                             restore_best_weights = True)]\n\nhistory = xception.fit(train_dataset, epochs = epochs,\n             validation_data = valid_dataset, \n              steps_per_epoch = 250,\n             validation_steps = 250, \n              callbacks = callbacks,\n             verbose = 1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Plotting the Metrics"},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.rcParams.update({'font.size': 16})\nhist = pd.DataFrame(history.history)\nfig, (ax1, ax2) = plt.subplots(figsize=(12,12),nrows=2, ncols=1)\nhist['loss'].plot(ax=ax1,c='k',label='training loss')\nhist['val_loss'].plot(ax=ax1,c='r',linestyle='--', label='validation loss')\nax1.legend()\nhist['auc'].plot(ax=ax2,c='k',label='training AUC')\nhist['val_auc'].plot(ax=ax2,c='r',linestyle='--',label='validation AUC')\nax2.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Submissions"},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import classification_report\n\n\ntest_dir = \"../input/ranzcr-clip-catheter-line-classification/test_tfrecords\"\nTFR_fnames_test = tf.io.gfile.glob(test_dir + '/*.tfrec')\n\ntest_feature_map = {\n    \"StudyInstanceUID\" : tf.io.FixedLenFeature([], tf.string),\n    \"image\" : tf.io.FixedLenFeature([], tf.string)\n    }\n\ndef read_tfr(example):\n    \n    example = tf.io.parse_single_example(example, test_feature_map)\n    \n    image = tf.io.decode_jpeg(example['image'])\n    \n    image = tf.image.resize(image, (img_size,img_size))\n    \n    image = tf.image.grayscale_to_rgb(image)\n    \n    image = image / 255\n    \n    return image\n\n\n\ndef load_ds(filenames):\n    \n    tfrecords = tf.data.TFRecordDataset(filenames)\n    \n    tfrecords = tfrecords.map(read_tfr, num_parallel_calls = autotune)\n    \n    return tfrecords\n    \n    \ndef get_ds(filenames):\n    \n    ds = load_ds(filenames)\n    ds = ds.batch(4)\n    ds = ds.prefetch(autotune)\n    \n    return ds\n\ndef read_ids(example):\n    \n    example = tf.io.parse_single_example(example, test_feature_map)\n    ids = example['StudyInstanceUID']\n    \n    \n    return ids\n\ndef load_ds_ids(filenames):\n    \n    tfrecords = tf.data.TFRecordDataset(filenames)\n    \n    tfrecords = tfrecords.map(read_ids, num_parallel_calls = autotune)\n    \n    return tfrecords\n    \n    \ndef get_ds_ids(filenames):\n    \n    ds = load_ds_ids(filenames)\n    ds = ds.batch(test_samples)\n    ds = ds.prefetch(autotune)\n    \n    return ds\n\ntest_samples = sum(1 for _ in tf.data.TFRecordDataset(TFR_fnames_test))\ntest_ds = get_ds(TFR_fnames_test)\ntest_ids = get_ds_ids(TFR_fnames_test)\n\ny_preds = xception.predict(test_ds, batch_size=4)\n\nresults = pd.DataFrame(y_preds)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ids = next(iter(test_ids)).numpy()\n\nfor i in range(ids.shape[0]):\n    ex = str(ids[i])\n    ex = ex[2:-1]\n    ids[i] = ex\nids = pd.Series(ids)\n\ncolumns = ['StudyInstanceUID', 'ETT - Abnormal', 'ETT - Borderline', 'ETT - Normal',\n           \"NGT - Abnormal\", 'NGT - Borderline','NGT - Incompletely Imaged',\n           'NGT - Normal', 'CVC - Abnormal','CVC - Borderline',\n           'CVC - Normal','Swan Ganz Catheter Present']\n\nresults_df = pd.concat([ids, results], axis = 1)\nresults_df.columns = columns\nresults_df.to_csv('submission.csv', index = False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# References\n1. https://www.kaggle.com/tpothjuan/efficientnetb7-resnet50-ensemble-tfrecords\n2. https://keras.io/examples/keras_recipes/tfrecord/\n3. https://arxiv.org/abs/1610.02357"},{"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":4}