{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np \nimport pandas as pd\nimport os        ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Load CSV Data","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"# Load detail dataset\ndetail_class_info_df = pd.read_csv('../input/rsna-pneumonia-detection-challenge/stage_2_detailed_class_info.csv')\n\n# Load train dataset\ntrain_labels_df = pd.read_csv('../input/rsna-pneumonia-detection-challenge/stage_2_train_labels.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Check no. of rows and columns of each dataset\nprint('Shape of Detail class dataset: ', detail_class_info_df.shape)\nprint('Shaoe of Train dataset:', train_labels_df.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Read 7 data from datasets\ndetail_class_info_df.head(7)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Find number of occurences of different types of classes for patients\ndetail_class_info_df['class'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"From the above analysis, 9555 patients has lung opacity","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import seaborn as sns\nsns.countplot(x=\"class\", hue=\"class\", data=detail_class_info_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_labels_df.head(7)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Find number of occurences of different targets for patients\ntrain_labels_df['Target'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.countplot(x=\"Target\", hue=\"Target\", data=train_labels_df)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"From the above analysis, 9555 patients has evidence of pneumonia","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Check Missing Data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Check in each column how many null values are there in train label dataset\ntrain_labels_df.isnull().sum()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Check how many patients has bounding box co-ordinates\ntrain_labels_df.groupby(['Target']).count()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"9555 patients has bounding box co-ordinates","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Load Images from dataset","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import pydicom as dcm\nfrom pydicom import dcmread","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Get list of all dcm images\nimport glob \ntrain_image_list = glob.glob('../input/rsna-pneumonia-detection-challenge/stage_2_train_images/*.dcm')\ntest_image_list = glob.glob('../input/rsna-pneumonia-detection-challenge/stage_2_test_images/*.dcm')\nprint('Number of images in train image list: ', len(train_image_list))\nprint('Number of images in test image list: ', len(test_image_list))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We have 30227 rows in the training dataset and 26684 images in the train image list. So it might be a chance that some rows has duplicate entries in the training and class dataset.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Check unique patients in the dataset\nprint('Number of unique patients are: ', train_labels_df['patientId'].nunique())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We can see that number of unique patients are equal to the number of images present in the train image list.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Read one sample image information\nsample_image_index = 4\nsample_image_path = train_image_list[sample_image_index]\nprint('Sample image path is: ',sample_image_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_image_dataset = dcm.read_file(sample_image_path)\nsample_image_dataset","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"From the above dataset, we can see some useful information like\n* Patient's Name \n* Patient's Sex\n* Patient's Age\n* Body Part Examined\netc","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Load sample image\nimport matplotlib.pyplot as plt\nplt.imshow(sample_image_dataset.pixel_array, cmap=plt.cm.bone)\nsample_patient = train_labels_df[train_labels_df['patientId'] == sample_image_dataset.PatientID]\nsample_patient_data = list(sample_patient.T.to_dict().values())\nprint(\"Shape of the image: \", sample_image_dataset.pixel_array.shape)\nprint(\"Patient's Sex: \", sample_image_dataset.PatientSex)\nprint(\"Modality: \", sample_image_dataset.Modality)\nprint(\"Patient's Age: \", sample_image_dataset.PatientAge)\nprint(\"Body part examined: \", sample_image_dataset.BodyPartExamined)\nprint(\"Target: \", sample_patient_data[0]['Target'])\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Draw a bounding box on the image\n\nimport matplotlib.patches as patches\nimageArea, axes = plt.subplots(1)\nx, y, width, height  = sample_patient_data[0]['x'], sample_patient_data[0]['y'], sample_patient_data[0]['width'], sample_patient_data[0]['height']\n\n# Create a Rectangle patch\nrect = patches.Rectangle((x, y), width, height, linewidth = 1, edgecolor = 'r', facecolor = 'none')\naxes.imshow(sample_image_dataset.pixel_array, cmap=plt.cm.bone)\n\n# Add the patch to the Axes\naxes.add_patch(rect)\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Merge two datasets\n\n# train_class_df = pd.merge(detail_class_info_df, train_labels_df, on='patientId')\ntrain_class_df = pd.concat([train_labels_df, detail_class_info_df[\"class\"]], axis=1, sort=False)\ntrain_class_df.head(7)\ntrain_class_df.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_class_df.isna().apply(pd.value_counts)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.countplot(x='Target', hue='class', data=train_class_df)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"From the above analysis, \n* Target 1 (evidence of pneumonia) has Lung Opacity\n* Target 0 (no evidence of pneunomia) has No Lung Opacity / Not Normal","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Visualization of data for class 'No Lung Opacity / Not Normal'","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"index = 3        # This patient has class 'No Lung Opacity / Not Normal'\nimage_path_1 = train_image_list[index]\nsample_image_data1 = dcm.read_file(image_path_1)\npatient1 = train_class_df[train_class_df['patientId'] == sample_image_data1.PatientID]\nsample_patient_data1 = list(patient1.T.to_dict().values())\nprint(sample_patient_data1[0]['class'])\nimageArea, axes = plt.subplots(1)\nx, y, width, height  = sample_patient_data1[0]['x'], sample_patient_data1[0]['y'], sample_patient_data1[0]['width'], sample_patient_data1[0]['height']\n\n# Create a Rectangle patch\nrect1 = patches.Rectangle((x, y), width, height, linewidth = 1, edgecolor = 'r', facecolor = 'none')\naxes.imshow(sample_image_data1.pixel_array, cmap=plt.cm.bone)\n\n# Add the patch to the Axes\naxes.add_patch(rect1)\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Visualization of data for class 'Normal'","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"index1 = 5        # This patient has class 'Normal'\nimage_path_2 = train_image_list[index1]\nsample_image_data2 = dcm.read_file(image_path_2)\npatient2 = train_class_df[train_class_df['patientId'] == sample_image_data2.PatientID]\nsample_patient_data2 = list(patient2.T.to_dict().values())\nprint(sample_patient_data2[0]['class'])\nimageArea, axes = plt.subplots(1)\nx, y, width, height  = sample_patient_data2[0]['x'], sample_patient_data2[0]['y'], sample_patient_data2[0]['width'], sample_patient_data2[0]['height']\n\n# Create a Rectangle patch\nrect2 = patches.Rectangle((x, y), width, height, linewidth = 1, edgecolor = 'r', facecolor = 'none')\naxes.imshow(sample_image_data2.pixel_array, cmap=plt.cm.bone)\n\n# Add the patch to the Axes\naxes.add_patch(rect2)\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(len(train_class_df[(train_class_df['Target'] == 1) & (train_class_df['class'] == 'Lung Opacity')]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow as tf\nfrom keras import layers\nfrom keras.layers import BatchNormalization, Conv2D, MaxPooling2D, Dropout, GlobalAveragePooling2D, Add, Activation, Input, Flatten, Dense, AveragePooling2D, ZeroPadding2D\nfrom keras.models import Model\nfrom keras.applications.resnet50 import ResNet50, preprocess_input\nimport sklearn\nfrom sklearn.preprocessing import LabelEncoder\n\n# Define Convolution block\ndef residual_convolutionBlock(layers, f, filters):\n    f1, f2, f3 = filters\n    x_shortcut = layers\n    \n    # First convolutional block\n    x = Conv2D(filters = f1, kernel_size = (1, 1), padding = 'same')(inputs)\n    x = BatchNormalization()(x)\n    x = Activation('relu')(x)\n\n    # Second convolutional block\n    x = Conv2D(filters = f2, kernel_size = (f, f), padding = 'same')(x)\n    x = BatchNormalization()(x)\n    x = Activation('relu')(x)\n\n    # Third convolutional block\n    x = Conv2D(filters = f3, kernel_size = (1, 1), padding = 'same')(x)\n    x = BatchNormalization()(x)\n\n    # Shortcut path\n    x_shortcut = Conv2D(filters = f3, kernel_size = (1, 1), activation = 'relu', padding = 'same')(x_shortcut)\n    x_shortcut = BatchNormalization()(x_shortcut)\n\n    # Add shortcut value to main path\n    x = Add()([x, x_shortcut])\n\n    # Pass it through RELU activation\n    x = Activation('relu')(x)\n\n    return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Define Identity block\ndef residual_identityBlock(layers, f, filters):\n    f1, f2, f3 = filters\n    x_shortcut = layers\n    \n    # First convolutional block\n    x = Conv2D(filters = f1, kernel_size = (1, 1), padding = 'same')(inputs)\n    x = BatchNormalization()(x)\n    x = Activation('relu')(x)\n\n    # Second convolutional block\n    x = Conv2D(filters = f2, kernel_size = (f, f), padding = 'same')(x)\n    x = BatchNormalization()(x)\n    x = Activation('relu')(x)\n\n    # Third convolutional block\n    x = Conv2D(filters = f3, kernel_size = (1, 1), padding = 'same')(x)\n    x = BatchNormalization()(x)\n    \n    # Add shortcut value to main path\n    x = Add()([x, x_shortcut])\n\n    # Pass it through RELU activation\n    x = Activation('relu')(x)\n\n    return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Define ResNet Model (50-layer) \n\ninputs = Input(shape=(64, 64, 1)) # Size of the image\n\n# Zero-Padding\nx = ZeroPadding2D((3, 3))(inputs)\n\n# Stage 1 (Initial convolution and max pooling)\nx = Conv2D(64,(7, 7), strides = (2, 2))(inputs)\nx = BatchNormalization()(x)\nx = Activation('relu')(x)\nx = MaxPooling2D((3, 3), strides=(2, 2))(x)\n\n# Stage 2    \nx = residual_convolutionBlock(inputs, f = 3, filters = [64, 64, 256])\nx = residual_identityBlock(inputs, f = 3, filters = [64, 64, 256]) \nx = residual_identityBlock(inputs, f = 3, filters = [64, 64, 256]) \n\n# Stage 3    \nx = residual_convolutionBlock(inputs, f = 3, filters = [128, 128, 512])\nx = residual_identityBlock(inputs, f = 3, filters = [128, 128, 512]) \nx = residual_identityBlock(inputs, f = 3, filters = [128, 128, 512])\nx = residual_identityBlock(inputs, f = 3, filters = [128, 128, 512]) \n\n# Stage 4    \nx = residual_convolutionBlock(inputs, f = 3, filters = [256, 256, 1024])\nx = residual_identityBlock(inputs, f = 3, filters = [256, 256, 1024]) \nx = residual_identityBlock(inputs, f = 3, filters = [256, 256, 1024])\nx = residual_identityBlock(inputs, f = 3, filters = [256, 256, 1024]) \nx = residual_identityBlock(inputs, f = 3, filters = [256, 256, 1024]) \nx = residual_identityBlock(inputs, f = 3, filters = [256, 256, 1024]) \n\n# Stage 5\nx = residual_convolutionBlock(inputs, f = 3, filters = [512, 512, 2048])\nx = residual_identityBlock(inputs, f = 3, filters = [512, 512, 2048]) \nx = residual_identityBlock(inputs, f = 3, filters = [512, 512, 2048])\n\nx = AveragePooling2D(pool_size=(2, 2))(x)\nx = Flatten()(x)\nx = Dense(units=1, activation='softmax')(x)\n\n# create model\nmodel = Model(inputs = inputs, outputs = x)\n    \n# compile model\nmodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n\n# summarize model\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"trainSetImageMetadata_df = pd.DataFrame(train_image_list, columns=[\"Path\"])\ntrainSetImageMetadata_df.head(2)\n\ndef getImgId(_imgData) :\n    return str(_imgData).split(\".dcm\")[0].split(\"/\")[4]\n\nimageIdPaths = pd.DataFrame(columns=[\"patientId\", \"imgPath\"])\nimageIdPaths[\"patientId\"] = trainSetImageMetadata_df[\"Path\"].apply(getImgId)\nimageIdPaths[\"imgPath\"] = trainSetImageMetadata_df[\"Path\"]\n\nprint(\"imageIdPaths\", imageIdPaths.shape)\nimageIdPaths.head(2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_CombinedData = train_class_df[0:15000]\nvalidate_CombinedData = train_class_df[15000:25000]\ntest_CombinedData = train_class_df[25000:30227]\n\ntrain_imageIdPaths = imageIdPaths[0:13163]\nvalidate_imageIdPaths = imageIdPaths[13163:21764]\ntest_imageIdPaths = imageIdPaths[21764:26684]\n\nprint(\"Train image path shape: \",train_imageIdPaths.shape)\nprint(\"Train Data shape: \",train_CombinedData.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\nimport math\nfrom keras.utils import Sequence\n\n\nCLSI_IMAGE_SIZE = 224    \nCLSI_BATCH_SIZE = 64 \nCLSI_IMG_PX_SIZE = 224\nIMG_WIDTH = 1024\nIMG_HEIGHT = 1024\n\nclass ClassifierSequenceGenerator(Sequence):\n    \n    def __init__(self, _imageIdPaths, _CombinedData):\n        self.pids = _CombinedData[\"patientId\"].to_numpy()\n        encoder = LabelEncoder()\n        self.classes = encoder.fit_transform(_CombinedData[\"class\"].to_numpy())\n        self.samples = len(_CombinedData)\n        self.imgIdPaths = _imageIdPaths\n                \n    def __len__(self):\n        return math.ceil(len(self.classes) / CLSI_BATCH_SIZE)\n\n    \n    def __getitem__(self, idx): # Get a batch\n        batch_pids = self.pids[idx * CLSI_BATCH_SIZE:(idx + 1) * CLSI_BATCH_SIZE] # Image pids\n        batch_classes = self.classes[idx * CLSI_BATCH_SIZE:(idx + 1) * CLSI_BATCH_SIZE] # Image coords      \n        \n        batch_images = np.zeros((len(batch_pids), CLSI_IMAGE_SIZE, CLSI_IMAGE_SIZE, 3), dtype=np.float32)\n        for _indx, _path in enumerate(batch_pids):\n            _imgData = dcm.read_file(str(_path)) # Read image\n            img = _imgData.pixel_array \n            \n            # Resize image\n            resized_img = cv2.resize(img, (CLSI_IMG_PX_SIZE, CLSI_IMG_PX_SIZE))\n            \n            # Preprocess image for the batch\n            batch_images[_indx][:,:,0] = preprocess_input(np.array(resized_img, dtype=np.float32)) # Convert to float32 array\n            batch_images[_indx][:,:,1] = preprocess_input(np.array(resized_img, dtype=np.float32)) # Convert to float32 array\n            batch_images[_indx][:,:,2] = preprocess_input(np.array(resized_img, dtype=np.float32)) # Convert to float32 array\n\n        return batch_images, batch_classes","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"trainDataGen = ClassifierSequenceGenerator(train_imageIdPaths, train_CombinedData)\ntestDataGen = ClassifierSequenceGenerator(test_imageIdPaths, test_CombinedData)\n\nprint(len(trainDataGen))\nprint(len(testDataGen))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model.fit_generator(\n#           trainDataGen, steps_per_epoch = CLSI_BATCH_SIZE, \n#           epochs = 16, validation_data=testDataGen, \n#           validation_steps = CLSI_BATCH_SIZE)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.optimizers import Adam\n\n# Use pretrained ResNet50 Model\nbase_model = ResNet50(weights= None, include_top=False, input_shape= (CLSI_IMAGE_SIZE,CLSI_IMAGE_SIZE,3))\n\nX = base_model.output\nX = GlobalAveragePooling2D()(X)\nX = Dropout(0.7)(X)\npredictions = Dense(1, activation= 'softmax')(X)\nmodel1 = Model(inputs = base_model.input, outputs = predictions)\n\n# compile model\nadam = Adam(lr=0.0001)\nmodel1.compile(optimizer=adam, loss='categorical_crossentropy', metrics=['accuracy'])\n\n# summarize model\nmodel1.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":" model.fit_generator(\n           trainDataGen, steps_per_epoch = CLSI_BATCH_SIZE, \n           epochs = 16, validation_data=testDataGen, \n           validation_steps = CLSI_BATCH_SIZE)","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}