{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np \nimport pandas as pd \nimport seaborn as sns\nimport matplotlib.pyplot as plt \nimport matplotlib.image as mpimg\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator \nfrom tensorflow.keras.applications.densenet import DenseNet121 \nfrom tensorflow.keras.layers import Dense, GlobalAveragePooling2D \nfrom tensorflow.keras.models import Model \nfrom tensorflow.keras import backend as K \nfrom tensorflow.keras.models import load_model\nfrom tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau\nimport os, sys\nimport cv2\nimport random\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#ROOT_DIR = \n#DATA_SETS = '../datasets'\nDATA_SETS = '../input/ranzcr-clip-catheter-line-classification'\n#SCRIPTS = ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"datasets_list = os.listdir(DATA_SETS)\ndatasets_list","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = os.path.join(DATA_SETS, 'train')\nsubmission = os.path.join(DATA_SETS,'sample_submission.csv')\ntest = os.path.join(DATA_SETS, 'test')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv(DATA_SETS+'/train.csv')\nprint(f'Train Data CSV: {train_df.shape[0]}')\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub_df = pd.read_csv(submission)\nprint(f'Sub CSV: {sub_df.shape[0]}')\nsub_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# label column names\nlabel_cols = list(sub_df.columns[1:])\nimage_labels = train_df[label_cols].values # will be used for train validation splitting","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Count up the number of instances of each class (drop non-class columns from the counts) \nclass_counts = train_df.sum().drop(['StudyInstanceUID','PatientID'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# we plot the distribution of patients to check if there is any class imbalance in the dataset\ndef plot_class_distributions(values, index):\n    sns.barplot(x=values, y=index)\n    plt.title('Distribution of classes for the patients')\n    plt.xlabel('Patient Count', fontsize=15)\n    plt.ylabel('Catheter Position', fontsize=15)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_class_distributions(class_counts.values, class_counts.index)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_images = DATA_SETS + \"/train/\" + train_df['StudyInstanceUID'] + '.jpg'   \ntest_images = DATA_SETS + \"/test/\" + sub_df['StudyInstanceUID'] + '.jpg'\nlen(test_images)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_image = os.path.join(DATA_SETS, \"train_annotations.csv\")\ndata_image = pd.read_csv(data_image)\ndata_image.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# display images randomly on a grid\ndef display_images(image_ids, labels):\n    fig = plt.figure(figsize = (16,12))\n    \n    for index, (image_id, label) in enumerate(zip(image_ids,labels)):\n        plt.subplot(3,3, index+1)\n        image = image_id + '.jpg'\n        image = mpimg.imread(os.path.join(DATA_SETS, \"train\", image))\n        plt.title(label, fontsize=12)\n        plt.imshow(image,cmap='Greys')\n    \n    fig.tight_layout()\n    plt.show()    \n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tmp_train = data_image.sample(9)\nimage_ids = tmp_train[\"StudyInstanceUID\"].values\nlabels = tmp_train['label'].values\ndisplay_images(image_ids, labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# now we check for any kinds of data leakage between any two data sets, train-test, train-valid, valid-test\ndef check_for_leakage(df1, df2, patient_col):\n    \n    df1_unique = set(df1[patient_col])\n    df2_unique = set(df2[patient_col])\n    \n    common_patients = df1_unique.intersection(df2_unique)\n    \n    return True if len(common_patients) > 0 else False\n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"check_for_leakage(train_df, sub_df, 'StudyInstanceUID')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# for making validation set from given train set\ndef make_val_set(data, val_size):\n    val_patientid = random.sample(list(train_df['PatientID'].unique()),int(val_size*len(train_df['PatientID'].unique())))\n    df_train = data[~data['PatientID'].isin(val_patientid)]\n    df_val = data[data['PatientID'].isin(val_patientid)]\n    return df_train, df_val","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train, df_val = make_val_set(train_df, val_size=0.2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"check_for_leakage(df_train, df_val, 'PatientID')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(f'Train Data Size: {df_train.shape[0]}')\nprint(f'Validation Data Size: {df_val.shape[0]}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"TRAIN_IMAGE_DIR = DATA_SETS + '/train/'\nTEST_IMAGE_DIR = DATA_SETS + '/test/'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# with augmentation\ndef get_train_generator(df, image_dir, image_id, label_names, shuffle=True, batch_size=32, seed=1, target_width=256, target_height=256):\n    print('Train Generator Preparation: ')\n    \n    # first we normalize the images and add light augmentation to the images\n    image_generator = ImageDataGenerator(\n        samplewise_center=True,\n        samplewise_std_normalization=True,\n        horizontal_flip=True,\n        vertical_flip=True,\n        zoom_range=0.2\n    )\n    \n    # next we flow from data frame with a certain batch size.\n    # This flows the images from the directory\n    generator = image_generator.flow_from_dataframe(\n        dataframe=df,\n        directory=image_dir,\n        x_col=image_id,\n        y_col=label_names,\n        class_mode=\"raw\",\n        classes=label_names,\n        batch_size=batch_size,\n        shuffle=shuffle,\n        seed=1,\n        target_size=(target_width, target_height)\n    )\n    \n    return generator\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# create image generator\ndef get_image_generator(train_df, image_dir, image_id, label_names, shuffle=True, batch_size=32, seed=1, target_width=256, target_height=256, sample_size=100):\n    # generator to sample dataset\n    raw_train_generator = ImageDataGenerator().flow_from_dataframe(\n        dataframe=train_df,\n        directory=image_dir,\n        x_col=image_id,\n        y_col=label_names,\n        class_mode='raw',\n        batch_size=sample_size,\n        shuffle=shuffle,\n        target_size=(target_width, target_height)\n    )\n    \n    batch = raw_train_generator.next() \n    data_sample = batch[0] \n    \n    # use sample to fit mean and std for test set generator\n    # featurewise mean and normalization is done on all the images\n    image_generator = ImageDataGenerator( \n        featurewise_center=True, \n        featurewise_std_normalization= True) \n    \n    # fit generator to sample from training data \n    image_generator.fit(data_sample)\n    \n    return image_generator","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_generator(df, image_dir, x_col, y_cols, image_generator, batch_size=32, seed=1, target_width = 256, target_height = 256):\n    # get valid generator\n    \n    generator = image_generator.flow_from_dataframe( \n        dataframe=df, \n        directory=image_dir, \n        x_col=x_col, y_col=y_cols, \n        class_mode=\"raw\", \n        batch_size=batch_size, \n        shuffle=False, \n        seed=seed, \n        target_size=(target_width,target_height)\n    )\n    \n    return generator","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def append_ext(fn, ext='.jpg'):\n    return fn+ext\n\ndf_train['StudyInstanceUID'] = df_train['StudyInstanceUID'].apply(append_ext)\ndf_val['StudyInstanceUID'] = df_val['StudyInstanceUID'].apply(append_ext)\nsub_df['StudyInstanceUID'] = sub_df['StudyInstanceUID'].apply(append_ext)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub_df['StudyInstanceUID'][0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_generator = get_train_generator(df_train, TRAIN_IMAGE_DIR, \"StudyInstanceUID\", label_cols)\nraw_image_generator = get_image_generator(df_train, TRAIN_IMAGE_DIR, \"StudyInstanceUID\", label_cols)\nvalid_generator = get_generator(df_val, TRAIN_IMAGE_DIR, \"StudyInstanceUID\", label_cols, raw_image_generator)\ntest_generator= get_generator(sub_df, TEST_IMAGE_DIR, \"StudyInstanceUID\", label_cols, raw_image_generator)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model Building"},{"metadata":{},"cell_type":"markdown","source":"## Custom Weighted Loss Function and Frequency analysis"},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_generator.labels[100]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Training Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls /kaggle/checkpoints","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# base pre-trained model\nmodel = DenseNet121(\n    include_top=False,\n    weights=\"imagenet\",\n)\n\nlayer = model.output\n\n# adding a global pooling layer\nlayer = GlobalAveragePooling2D()(layer)\n\n# adding a simple dense layer for testing purposes\ndense_layer1 = Dense(len(class_counts.index), activation=\"sigmoid\")(layer)\n\nmodel = Model(inputs=model.input, outputs=dense_layer1)\ncheckpoint = ModelCheckpoint('/kaggle/checkpoints/model-{epoch:03d}-{accuracy:03f}-{val_accuracy:03f}.h5', verbose=1, monitor='val_loss',save_best_only=True, mode='auto') \nmodel.compile(optimizer='adam', loss='binary_crossentropy',metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit(train_generator,\n                             validation_data=valid_generator,\n                             steps_per_epoch=100,\n                             epochs=20,\n                   callbacks=[checkpoint])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_metrices(history):\n    acc = history.history['accuracy']\n    val_acc = history.history['val_accuracy']\n    loss = history.history['loss']\n    val_loss = history.history['val_loss']\n\n    epochs = range(len(acc))\n\n    plt.plot(epochs, acc, 'r', label='Training accuracy')\n    plt.plot(epochs, val_acc, 'b', label='Validation accuracy')\n    plt.title('Training and validation accuracy')\n\n    plt.figure()\n    \n    plt.plot(epochs, loss, 'r', label='Training Loss')\n    plt.plot(epochs, val_loss, 'b', label='Validation Loss')\n    plt.title('Training and validation loss')\n    plt.legend()\n\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_metrices(history)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predicted_vals = model.predict(test_generator, steps = len(test_generator))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predicted_vals[0]","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}