{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.utils import shuffle\nimport os\nimport pydicom\nimport cv2\nfrom keras.preprocessing.image import ImageDataGenerator\nimport shutil","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-11-26T03:31:16.807858Z","iopub.execute_input":"2021-11-26T03:31:16.808113Z","iopub.status.idle":"2021-11-26T03:31:16.812609Z","shell.execute_reply.started":"2021-11-26T03:31:16.808084Z","shell.execute_reply":"2021-11-26T03:31:16.811901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nfrom PIL import Image\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.models import load_model\nfrom numpy import load\nfrom numpy import vstack\nfrom matplotlib import pyplot\nfrom numpy.random import randint\nfrom tensorflow.keras.preprocessing.image import img_to_array\nfrom tensorflow.keras.preprocessing.image import load_img\nfrom numpy import expand_dims\nfrom skimage import morphology, io, color, exposure, img_as_float, transform\n","metadata":{"execution":{"iopub.status.busy":"2021-11-26T03:31:19.54838Z","iopub.execute_input":"2021-11-26T03:31:19.549194Z","iopub.status.idle":"2021-11-26T03:31:19.55529Z","shell.execute_reply.started":"2021-11-26T03:31:19.549144Z","shell.execute_reply":"2021-11-26T03:31:19.554626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def convert_to_array(file):\n    ds = pydicom.dcmread(file)\n\n    shape = ds.pixel_array.shape\n\n    # Convert to float to avoid overflow or underflow losses.\n    image_2d = ds.pixel_array.astype(float)\n\n    # Rescaling grey scale between 0-255\n    image_2d_scaled = (np.maximum(image_2d,0) / image_2d.max()) * 255.0\n\n    # Convert to uint\n    image_2d_scaled = np.uint8(image_2d_scaled)\n    return image_2d_scaled","metadata":{"execution":{"iopub.status.busy":"2021-11-26T03:31:23.174338Z","iopub.execute_input":"2021-11-26T03:31:23.174873Z","iopub.status.idle":"2021-11-26T03:31:23.179693Z","shell.execute_reply.started":"2021-11-26T03:31:23.174834Z","shell.execute_reply":"2021-11-26T03:31:23.179021Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def preprocess_for_segmentation(img,im_shape):\n    img = transform.resize(img, im_shape)\n    img = exposure.equalize_hist(img)\n    img = np.expand_dims(img, -1)\n    X = np.array(img)\n    y = np.array(img)\n    X -= X.mean()\n    X /= X.std()\n    return X","metadata":{"execution":{"iopub.status.busy":"2021-11-26T03:31:26.100098Z","iopub.execute_input":"2021-11-26T03:31:26.100814Z","iopub.status.idle":"2021-11-26T03:31:26.106426Z","shell.execute_reply.started":"2021-11-26T03:31:26.100773Z","shell.execute_reply":"2021-11-26T03:31:26.105297Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def removal_of_white_text(img):\n    ret,image=cv2.threshold(img,250,255,cv2.THRESH_TOZERO_INV)\n    return image","metadata":{"execution":{"iopub.status.busy":"2021-11-26T03:31:29.166557Z","iopub.execute_input":"2021-11-26T03:31:29.167213Z","iopub.status.idle":"2021-11-26T03:31:29.171993Z","shell.execute_reply.started":"2021-11-26T03:31:29.167175Z","shell.execute_reply":"2021-11-26T03:31:29.170837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def crop_img(dcm_img_path, seg_model, InputShapeOfModel):\n    # InputShapeOfModel is the input shape of the segmentation model\n    xray_image = convert_to_array(dcm_img_path)\n    xray_image = cv2.resize(xray_image, (1024, 1024))\n    width_scale = xray_image.shape[1] // InputShapeOfModel[1] # width-scaling factor for resize\n    height_scale = xray_image.shape[0] // InputShapeOfModel[0]  # height-scaling factor for resize\n    # The scaling factors are later used to find the cropping region for original image size\n\n    #segment the lung by seg_model\n    img = preprocess_for_segmentation(xray_image, InputShapeOfModel)  # preprocessing the Xray image for segmentation\n    inp_shape = img.shape\n    X = np.expand_dims(img, axis=0)\n    pred = seg_model.predict(X)[..., 0].reshape(inp_shape[:2])  # predicted segmentation\n    \n    # find bounding box around the two lungs\n    ret, pr = cv2.threshold(pred, 0.95, 1, cv2.THRESH_BINARY)\n    kernel = np.ones((3, 3), np.uint8)\n    pr = np.array(pr * 255, dtype=np.uint8)\n    pr = cv2.morphologyEx(pr, cv2.MORPH_OPEN, kernel, iterations=3)\n    pr_canny = cv2.Canny(pr, 170, 255)\n    cnts = cv2.findContours(pr_canny, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)\n    cntsSorted = sorted(cnts[0], key=lambda x: cv2.contourArea(x), reverse=True)\n    x_c = []\n    y_c = []\n    b = 0\n    for i in range(len(cntsSorted)):\n        x, y, w, h = cv2.boundingRect(cntsSorted[i])\n        if (w*h > 2500):\n            x_c.append(x)\n            x_c.append(x + w)\n            y_c.append(y)\n            y_c.append(y + h)\n    crp_p1 = (max([min(x_c) - 20, 0]), max([min(y_c) - 20, 0]))\n    crp_p2 = (min([max(x_c) + 20, pr.shape[0]]), min([max(y_c) + 20, pr.shape[1]]))\n    # the crop area is scaled to the original image size\n    x1 = int(crp_p1[0] * width_scale)\n    y1 = int(crp_p1[1] * height_scale)\n    x2 = int(crp_p2[0] * width_scale)\n    y2 = int(crp_p2[1] * height_scale)\n    h=y2-y1\n    w=x2-x1\n    if h > w:\n        for a in range(x1+1):\n            if (x2 - a + h - w) < xray_image.shape[1]:\n#                 return x1-a, y1, x1+h, y2\n                return xray_image[x1-a:x1+h, y1:y2]\n    if w > h:\n        for a in range(y1+1):\n            if (y2 - a + w - h) < xray_image.shape[0]:\n#                 return x1, y1-a, x2, y1+w\n                return xray_image[x1:x2, y1-a:y1+w]\n               \n#     print(min(x_c))\n#     print((min(x_c), min(y_c)), (max(x_c), max(y_c)))\n#     print(crp_p1, crp_p2)\n#     print((x1, y1), (x2, y2))\n#     cv2.rectangle(pr, (min(x_c), min(y_c)), (max(x_c), max(y_c)), (0, 255, 0), 10)\n#     cv2.rectangle(pr, crp_p1, crp_p2, (255, 0, 0), 5)\n#     cv2.rectangle(xray_image, (x1, y1), (x2, y2), (255, 0, 0), 5)\n#     plt.imshow(xray_image)\n    return xray_image[x1:x2, y1:y2]","metadata":{"execution":{"iopub.status.busy":"2021-11-26T03:31:32.499122Z","iopub.execute_input":"2021-11-26T03:31:32.499463Z","iopub.status.idle":"2021-11-26T03:31:32.517267Z","shell.execute_reply.started":"2021-11-26T03:31:32.499428Z","shell.execute_reply":"2021-11-26T03:31:32.514562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"seg_model = load_model('../input/cgan-model/CGAN_model.h5')\nInputShapeOfModel = (512, 512)\nimg_path = '../input/rsna-pneumonia-detection-challenge/stage_2_train_images/0092d9c5-26b6-4e66-b196-49b2224ab8d1.dcm'\nimg = crop_img(img_path, seg_model, InputShapeOfModel)\nplt.imshow(img)\n","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:53:56.167167Z","iopub.execute_input":"2021-11-26T06:53:56.167809Z","iopub.status.idle":"2021-11-26T06:54:00.666083Z","shell.execute_reply.started":"2021-11-26T06:53:56.167773Z","shell.execute_reply":"2021-11-26T06:54:00.665324Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv(\"../input/rsna-pneumonia-detection-challenge/stage_2_detailed_class_info.csv\")\nnormal_df = df[df['class'] == 'Normal']\nabnormal_df = df[df['class'] != 'Normal']\n_,normal_df_rand = train_test_split(normal_df, test_size = 6000/8851, shuffle=True)\n_,abnormal_df_rand = train_test_split(abnormal_df, test_size = 6000/21376, shuffle=True)\nmy_df = shuffle(normal_df_rand.append(abnormal_df_rand))","metadata":{"execution":{"iopub.status.busy":"2021-11-26T03:32:51.487924Z","iopub.execute_input":"2021-11-26T03:32:51.488692Z","iopub.status.idle":"2021-11-26T03:32:51.539344Z","shell.execute_reply.started":"2021-11-26T03:32:51.488643Z","shell.execute_reply":"2021-11-26T03:32:51.538579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"my_df","metadata":{"execution":{"iopub.status.busy":"2021-11-26T03:32:54.724496Z","iopub.execute_input":"2021-11-26T03:32:54.725051Z","iopub.status.idle":"2021-11-26T03:32:54.736123Z","shell.execute_reply.started":"2021-11-26T03:32:54.725016Z","shell.execute_reply":"2021-11-26T03:32:54.735095Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df, test_df = train_test_split(my_df, test_size=0.3)\ntest_df, valid_df = train_test_split(test_df, test_size=0.5)\nnormal_train_df = train_df[train_df['class'] == 'Normal']\nabnormal_train_df = train_df[train_df['class'] != 'Normal']\nnormal_valid_df = valid_df[valid_df['class'] == 'Normal']\nabnormal_valid_df = valid_df[valid_df['class'] != 'Normal']\nnormal_test_df = test_df[test_df['class'] == 'Normal']\nabnormal_test_df = test_df[test_df['class'] != 'Normal']\n\n\nprint('train_valid_test: %d, %d, %d' %(len(train_df), len(valid_df), len(test_df)))\nprint('train_normal/anormal: %d/%d' %(len(normal_train_df), len(abnormal_train_df)))\nprint('valid_normal/anormal: %d/%d' %(len(normal_valid_df), len(abnormal_valid_df)))\nprint('test_normal/anormal: %d/%d' %(len(normal_test_df), len(abnormal_test_df)))","metadata":{"execution":{"iopub.status.busy":"2021-11-26T03:33:25.926103Z","iopub.execute_input":"2021-11-26T03:33:25.926862Z","iopub.status.idle":"2021-11-26T03:33:25.948501Z","shell.execute_reply.started":"2021-11-26T03:33:25.92681Z","shell.execute_reply":"2021-11-26T03:33:25.947649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"normal_train_list = list(normal_train_df['patientId'])\nnormal_valid_list = list(normal_valid_df['patientId'])\nnormal_test_list = list(normal_test_df['patientId'])\n\nabnormal_train_list = list(abnormal_train_df['patientId'])\nabnormal_valid_list = list(abnormal_valid_df['patientId'])\nabnormal_test_list = list(abnormal_test_df['patientId'])","metadata":{"execution":{"iopub.status.busy":"2021-11-26T03:33:29.910511Z","iopub.execute_input":"2021-11-26T03:33:29.911403Z","iopub.status.idle":"2021-11-26T03:33:29.921139Z","shell.execute_reply.started":"2021-11-26T03:33:29.911354Z","shell.execute_reply":"2021-11-26T03:33:29.920336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# shutil.rmtree('RSNA_dataset')","metadata":{"execution":{"iopub.status.busy":"2021-11-26T03:33:44.331538Z","iopub.execute_input":"2021-11-26T03:33:44.331797Z","iopub.status.idle":"2021-11-26T03:33:45.067058Z","shell.execute_reply.started":"2021-11-26T03:33:44.331768Z","shell.execute_reply":"2021-11-26T03:33:45.066189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.mkdir('RSNA_dataset')\n\ntrain_path = os.path.join('./RSNA_dataset', 'train')\nos.mkdir(train_path)\nnormal_train_path = os.path.join(train_path, 'normal')\nos.mkdir(normal_train_path)\nabnormal_train_path = os.path.join(train_path, 'abnormal')\nos.mkdir(abnormal_train_path)\n\nvalid_path = os.path.join('./RSNA_dataset', 'valid')\nos.mkdir(valid_path)\nnormal_valid_path = os.path.join(valid_path, 'normal')\nos.mkdir(normal_valid_path)\nabnormal_valid_path = os.path.join(valid_path, 'abnormal')\nos.mkdir(abnormal_valid_path)\n\ntest_path = os.path.join('./RSNA_dataset', 'test')\nos.mkdir(test_path)\nnormal_test_path = os.path.join(test_path, 'normal')\nos.mkdir(normal_test_path)\nabnormal_test_path = os.path.join(test_path, 'abnormal')\nos.mkdir(abnormal_test_path)","metadata":{"execution":{"iopub.status.busy":"2021-11-26T03:33:48.018149Z","iopub.execute_input":"2021-11-26T03:33:48.018906Z","iopub.status.idle":"2021-11-26T03:33:48.028036Z","shell.execute_reply.started":"2021-11-26T03:33:48.018868Z","shell.execute_reply":"2021-11-26T03:33:48.027029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_dir1 = '../input/rsna-pneumonia-detection-challenge/stage_2_test_images/'\ndata_dir2 = '../input/rsna-pneumonia-detection-challenge/stage_2_train_images/'","metadata":{"execution":{"iopub.status.busy":"2021-11-26T03:34:32.340855Z","iopub.execute_input":"2021-11-26T03:34:32.341121Z","iopub.status.idle":"2021-11-26T03:34:32.344952Z","shell.execute_reply.started":"2021-11-26T03:34:32.341091Z","shell.execute_reply":"2021-11-26T03:34:32.344096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for img in normal_train_list:\n    if ((img + '.dcm') in os.listdir(data_dir1)):\n        im_array = crop_img(data_dir1 + img + '.dcm', seg_model, InputShapeOfModel)\n        dst = normal_train_path + '/' + img + '.png'\n        cv2.imwrite(dst, im_array)\n    if ((img + '.dcm') in os.listdir(data_dir2)):\n        im_array = crop_img(data_dir2 + img + '.dcm', seg_model, InputShapeOfModel)\n        dst = normal_train_path + '/' + img + '.png'\n        cv2.imwrite(dst, im_array)\n        \nfor img in abnormal_train_list:\n    if ((img + '.dcm') in os.listdir(data_dir1)):\n        im_array = crop_img(data_dir1 + img + '.dcm', seg_model, InputShapeOfModel)\n        dst = abnormal_train_path + '/' + img + '.png'\n        cv2.imwrite(dst, im_array)\n    if ((img + '.dcm') in os.listdir(data_dir2)):\n        im_array = crop_img(data_dir2 + img + '.dcm', seg_model, InputShapeOfModel)\n        dst = abnormal_train_path + '/' + img + '.png'\n        cv2.imwrite(dst, im_array)","metadata":{"execution":{"iopub.status.busy":"2021-11-26T03:34:34.742664Z","iopub.execute_input":"2021-11-26T03:34:34.743417Z","iopub.status.idle":"2021-11-26T04:02:17.176869Z","shell.execute_reply.started":"2021-11-26T03:34:34.743285Z","shell.execute_reply":"2021-11-26T04:02:17.176144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for img in normal_valid_list:\n    if ((img + '.dcm') in os.listdir(data_dir1)):\n        im_array = crop_img(data_dir1 + img + '.dcm', seg_model, InputShapeOfModel)\n        dst = normal_valid_path + '/' + img + '.png'\n        cv2.imwrite(dst, im_array)\n    if ((img + '.dcm') in os.listdir(data_dir2)):\n        im_array = crop_img(data_dir2 + img + '.dcm', seg_model, InputShapeOfModel)\n        dst = normal_valid_path + '/' + img + '.png'\n        cv2.imwrite(dst, im_array)\n        \nfor img in abnormal_valid_list:\n    if ((img + '.dcm') in os.listdir(data_dir1)):\n        im_array = crop_img(data_dir1 + img + '.dcm', seg_model, InputShapeOfModel)\n        dst = abnormal_valid_path + '/' + img + '.png'\n        cv2.imwrite(dst, im_array)\n    if ((img + '.dcm') in os.listdir(data_dir2)):\n        im_array = crop_img(data_dir2 + img + '.dcm', seg_model, InputShapeOfModel)\n        dst = abnormal_valid_path + '/' + img + '.png'\n        cv2.imwrite(dst, im_array)","metadata":{"execution":{"iopub.status.busy":"2021-11-26T04:03:28.735217Z","iopub.execute_input":"2021-11-26T04:03:28.73595Z","iopub.status.idle":"2021-11-26T04:09:25.208126Z","shell.execute_reply.started":"2021-11-26T04:03:28.735912Z","shell.execute_reply":"2021-11-26T04:09:25.207402Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for img in normal_test_list:\n    if ((img + '.dcm') in os.listdir(data_dir1)):\n        im_array = crop_img(data_dir1 + img + '.dcm', seg_model, InputShapeOfModel)\n        dst = normal_test_path + '/' + img + '.png'\n        cv2.imwrite(dst, im_array)\n    if ((img + '.dcm') in os.listdir(data_dir2)):\n        im_array = crop_img(data_dir2 + img + '.dcm', seg_model, InputShapeOfModel)\n        dst = normal_test_path + '/' + img + '.png'\n        cv2.imwrite(dst, im_array)\n        \nfor img in abnormal_test_list:\n    if ((img + '.dcm') in os.listdir(data_dir1)):\n        im_array = crop_img(data_dir1 + img + '.dcm', seg_model, InputShapeOfModel)\n        dst = abnormal_test_path + '/' + img + '.png'\n        cv2.imwrite(dst, im_array)\n    if ((img + '.dcm') in os.listdir(data_dir2)):\n        im_array = crop_img(data_dir2 + img + '.dcm', seg_model, InputShapeOfModel)\n        dst = abnormal_test_path + '/' + img + '.png'\n        cv2.imwrite(dst, im_array)","metadata":{"execution":{"iopub.status.busy":"2021-11-26T04:10:11.232199Z","iopub.execute_input":"2021-11-26T04:10:11.232777Z","iopub.status.idle":"2021-11-26T04:16:14.153651Z","shell.execute_reply.started":"2021-11-26T04:10:11.232738Z","shell.execute_reply":"2021-11-26T04:16:14.152886Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path = './RSNA_dataset/train/'","metadata":{"execution":{"iopub.status.busy":"2021-11-26T04:17:24.138151Z","iopub.execute_input":"2021-11-26T04:17:24.138812Z","iopub.status.idle":"2021-11-26T04:17:24.143892Z","shell.execute_reply.started":"2021-11-26T04:17:24.138768Z","shell.execute_reply":"2021-11-26T04:17:24.141906Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"NUM_AUG_IMAGES_WANTED = 8000\n\nIMAGE_HEIGHT = 256\nIMAGE_WIDTH = 256","metadata":{"execution":{"iopub.status.busy":"2021-11-26T04:17:44.968877Z","iopub.execute_input":"2021-11-26T04:17:44.96914Z","iopub.status.idle":"2021-11-26T04:17:44.974895Z","shell.execute_reply.started":"2021-11-26T04:17:44.96911Z","shell.execute_reply":"2021-11-26T04:17:44.972018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_list = ['normal','abnormal']\ndata_path = './RSNA_dataset/'\nfor item in class_list:\n    aug_dir = os.path.join(data_path, 'aug_dir')\n    os.mkdir(aug_dir)\n    img_dir = os.path.join(aug_dir, 'img_dir')\n    os.mkdir(img_dir)\n    img_class = item\n    img_list = os.listdir(train_path + img_class)\n    for fname in img_list:\n            src = os.path.join(train_path + img_class, fname)\n            dst = os.path.join(img_dir, fname)\n            shutil.copyfile(src, dst)\n    path = aug_dir\n    save_path = train_path + img_class\n\n    datagen = ImageDataGenerator(\n        rescale=1.0/255,\n        featurewise_center=False,  # set input mean to 0 over the dataset\n        samplewise_center=False,  # set each sample mean to 0\n        featurewise_std_normalization=False,  # divide inputs by std of the dataset\n        samplewise_std_normalization=False,  # divide each input by its std\n        zca_whitening=False,  # apply ZCA whitening\n        rotation_range = 6,  # randomly rotate images in the range (degrees, 0 to 180)\n        zoom_range = 0.2, # Randomly zoom image \n        width_shift_range=0.1,  # randomly shift images horizontally (fraction of total width)\n        height_shift_range=0.1,  # randomly shift images vertically (fraction of total height)\n        horizontal_flip = True,  # randomly flip images\n        vertical_flip=False\n        )  # randomly flip images\n\n    batch_size = 50\n\n    aug_datagen = datagen.flow_from_directory(path,save_to_dir=save_path,save_format='png',target_size=(IMAGE_HEIGHT,IMAGE_WIDTH),batch_size=batch_size)\n    num_files = len(os.listdir(img_dir))\n    num_batches = int(np.ceil((NUM_AUG_IMAGES_WANTED-num_files)/batch_size))\n\n    for i in range(0,num_batches):\n        imgs, labels = next(aug_datagen)\n    shutil.rmtree(aug_dir)","metadata":{"execution":{"iopub.status.busy":"2021-11-26T04:17:57.635276Z","iopub.execute_input":"2021-11-26T04:17:57.635541Z","iopub.status.idle":"2021-11-26T04:23:30.537087Z","shell.execute_reply.started":"2021-11-26T04:17:57.635512Z","shell.execute_reply":"2021-11-26T04:23:30.536178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"datagen = ImageDataGenerator(rescale=1.0/255)\ntrain_gen = datagen.flow_from_directory(train_path,\n                                        target_size=(256,256),\n                                        batch_size=10,\n                                        class_mode='categorical')                                      \nval_gen = datagen.flow_from_directory(valid_path,\n                                        target_size=(256,256),\n                                        batch_size=10,\n                                        class_mode='categorical')\ntest_gen = datagen.flow_from_directory(test_path,\n                                        target_size=(256,256),\n                                        batch_size=1,\n                                        class_mode='categorical',\n                                        shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2021-11-26T04:24:43.369324Z","iopub.execute_input":"2021-11-26T04:24:43.370096Z","iopub.status.idle":"2021-11-26T04:24:44.327047Z","shell.execute_reply.started":"2021-11-26T04:24:43.370042Z","shell.execute_reply":"2021-11-26T04:24:44.326297Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# With data augmentation to prevent overfitting and handling the imbalance in dataset\n \n# datagen = ImageDataGenerator(\n#         rescale=1.0/255,\n#         featurewise_center=False,  # set input mean to 0 over the dataset\n#         samplewise_center=False,  # set each sample mean to 0\n#         featurewise_std_normalization=False,  # divide inputs by std of the dataset\n#         samplewise_std_normalization=False,  # divide each input by its std\n#         zca_whitening=False,  # apply ZCA whitening\n#         rotation_range = 6,  # randomly rotate images in the range (degrees, 0 to 180)\n#         zoom_range = 0.2, # Randomly zoom image \n#         width_shift_range=0.1,  # randomly shift images horizontally (fraction of total width)\n#         height_shift_range=0.1,  # randomly shift images vertically (fraction of total height)\n#         horizontal_flip = True,  # randomly flip images\n#         vertical_flip=False\n#         )  # randomly flip images\n# train_gen = datagen.flow_from_dataframe(train_df, data_path,\n#                                         x_col = 'patientId',\n#                                         y_col = 'class',\n#                                         target_size=(256,256),\n#                                         batch_size=10,\n#                                         classes= [0, 1],\n#                                         class_mode='categorical')\n# datagen = ImageDataGenerator(rescale=1.0/255)\n# valid_gen = datagen.flow_from_dataframe(valid_df, data_path,\n#                                         x_col = 'patientId',\n#                                         y_col = 'class',\n#                                         target_size=(256,256),\n#                                         batch_size=10,\n#                                         classes= [0, 1],\n#                                         class_mode='categorical')\n# test_gen = datagen.flow_from_dataframe(test_df, data_path,\n#                                         x_col = 'patientId',\n#                                         y_col = 'class',\n#                                         target_size=(256,256),\n#                                         batch_size=1,\n#                                         classes= [0, 1],\n#                                         class_mode='categorical')\n","metadata":{"execution":{"iopub.status.busy":"2021-11-11T05:54:16.09821Z","iopub.execute_input":"2021-11-11T05:54:16.098671Z","iopub.status.idle":"2021-11-11T05:54:16.257664Z","shell.execute_reply.started":"2021-11-11T05:54:16.098632Z","shell.execute_reply":"2021-11-11T05:54:16.256859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Dense\nfrom tensorflow.keras.layers import AvgPool2D, GlobalAveragePooling2D, MaxPool2D\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import ReLU, concatenate, Dropout\nimport tensorflow.keras.backend as K\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint\nfrom tensorflow.keras.optimizers import Adam, SGD\nfrom tensorflow.keras.applications.densenet import DenseNet121","metadata":{"execution":{"iopub.status.busy":"2021-11-26T04:24:52.628497Z","iopub.execute_input":"2021-11-26T04:24:52.628754Z","iopub.status.idle":"2021-11-26T04:24:52.648482Z","shell.execute_reply.started":"2021-11-26T04:24:52.628725Z","shell.execute_reply":"2021-11-26T04:24:52.647617Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(cv2.imread('./RSNA_dataset/train/normal/' + os.listdir('./RSNA_dataset/train/normal')[200]))","metadata":{"execution":{"iopub.status.busy":"2021-11-26T04:24:58.712933Z","iopub.execute_input":"2021-11-26T04:24:58.713536Z","iopub.status.idle":"2021-11-26T04:24:59.04779Z","shell.execute_reply.started":"2021-11-26T04:24:58.713495Z","shell.execute_reply":"2021-11-26T04:24:59.047109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(os.listdir('./RSNA_dataset/train/abnormal'))","metadata":{"execution":{"iopub.status.busy":"2021-11-26T04:25:07.522381Z","iopub.execute_input":"2021-11-26T04:25:07.522896Z","iopub.status.idle":"2021-11-26T04:25:07.53659Z","shell.execute_reply.started":"2021-11-26T04:25:07.522858Z","shell.execute_reply":"2021-11-26T04:25:07.535912Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.amax(cv2.imread('./RSNA_dataset/train/normal/' + os.listdir('./RSNA_dataset/train/normal')[2000]))","metadata":{"execution":{"iopub.status.busy":"2021-11-26T04:25:10.281729Z","iopub.execute_input":"2021-11-26T04:25:10.28227Z","iopub.status.idle":"2021-11-26T04:25:10.30992Z","shell.execute_reply.started":"2021-11-26T04:25:10.282215Z","shell.execute_reply":"2021-11-26T04:25:10.309188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_d=DenseNet121(weights='imagenet',include_top=False, \ninput_shape=(256, 256, 3)) \n\nx=model_d.output\n\nx= GlobalAveragePooling2D()(x)\nx= BatchNormalization()(x)\nx= Dropout(0.3)(x)\nx= Dense(1024,activation='relu')(x) \nx= Dense(512,activation='relu')(x) \nx= BatchNormalization()(x)\nx= Dropout(0.3)(x)\n\npreds=Dense(2,activation='softmax')(x) \n\nmodel=Model(inputs=model_d.input,outputs=preds) ","metadata":{"execution":{"iopub.status.busy":"2021-11-26T04:34:18.031842Z","iopub.execute_input":"2021-11-26T04:34:18.03234Z","iopub.status.idle":"2021-11-26T04:34:20.405107Z","shell.execute_reply.started":"2021-11-26T04:34:18.032303Z","shell.execute_reply":"2021-11-26T04:34:20.404388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2021-11-26T04:34:24.347554Z","iopub.execute_input":"2021-11-26T04:34:24.347884Z","iopub.status.idle":"2021-11-26T04:34:24.531669Z","shell.execute_reply.started":"2021-11-26T04:34:24.347845Z","shell.execute_reply":"2021-11-26T04:34:24.530892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(Adam(learning_rate=0.00001), loss='categorical_crossentropy', \n              metrics=['accuracy'])\n\n# model.compile(SGD(learning_rate=0.01, momentum=0.0, nesterov=False, name=\"SGD\"), loss='categorical_crossentropy', \n#               metrics=['accuracy'])\n ","metadata":{"execution":{"iopub.status.busy":"2021-11-26T04:34:34.305187Z","iopub.execute_input":"2021-11-26T04:34:34.305754Z","iopub.status.idle":"2021-11-26T04:34:34.325427Z","shell.execute_reply.started":"2021-11-26T04:34:34.305716Z","shell.execute_reply":"2021-11-26T04:34:34.324765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfilepath = \"./DenseNet121.h5\"\nkeras_callbacks   = [\n    tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=20, mode='min', min_delta=0.0001),\n    tf.keras.callbacks.ModelCheckpoint(filepath, monitor='val_accuracy', verbose=1, save_best_only=True, mode='max')\n]\nhistory = model.fit(train_gen, steps_per_epoch=200, validation_data=val_gen,epochs=200, verbose=1, callbacks = keras_callbacks)","metadata":{"execution":{"iopub.status.busy":"2021-11-26T04:34:36.789526Z","iopub.execute_input":"2021-11-26T04:34:36.79005Z","iopub.status.idle":"2021-11-26T06:02:08.963496Z","shell.execute_reply.started":"2021-11-26T04:34:36.790011Z","shell.execute_reply":"2021-11-26T06:02:08.962723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Plot accuracy: ')\nplt.plot(history.history['accuracy'])\nplt.plot(history.history['val_accuracy'])\nplt.title('model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', 'test'], loc='upper left')\nplt.show()\n# summarize history for loss\nprint('Plot Loss')\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('model loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['train', 'test'], loc='upper left')\nplt.show()\n# test\n","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:09:11.668932Z","iopub.execute_input":"2021-11-26T06:09:11.66926Z","iopub.status.idle":"2021-11-26T06:09:48.377634Z","shell.execute_reply.started":"2021-11-26T06:09:11.669212Z","shell.execute_reply":"2021-11-26T06:09:48.376792Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = model.predict_generator(test_gen, verbose = 1)","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:10:03.290754Z","iopub.execute_input":"2021-11-26T06:10:03.291024Z","iopub.status.idle":"2021-11-26T06:10:51.134821Z","shell.execute_reply.started":"2021-11-26T06:10:03.290994Z","shell.execute_reply":"2021-11-26T06:10:51.134093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions.argmax(axis = 1)","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:11:23.611224Z","iopub.execute_input":"2021-11-26T06:11:23.611994Z","iopub.status.idle":"2021-11-26T06:11:23.619259Z","shell.execute_reply.started":"2021-11-26T06:11:23.611942Z","shell.execute_reply":"2021-11-26T06:11:23.61833Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_gen.class_indices","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:11:26.378725Z","iopub.execute_input":"2021-11-26T06:11:26.379483Z","iopub.status.idle":"2021-11-26T06:11:26.386349Z","shell.execute_reply.started":"2021-11-26T06:11:26.379433Z","shell.execute_reply":"2021-11-26T06:11:26.385446Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('TEST: ')\nscores = model.evaluate_generator(test_gen,1797)\nprint(\"Test Accuracy = \", scores[1])\nprint(\"Test Loss = \", scores[0])","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:11:29.736652Z","iopub.execute_input":"2021-11-26T06:11:29.737343Z","iopub.status.idle":"2021-11-26T06:12:11.866725Z","shell.execute_reply.started":"2021-11-26T06:11:29.737305Z","shell.execute_reply":"2021-11-26T06:12:11.864327Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_labels = test_gen.classes","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:12:18.313631Z","iopub.execute_input":"2021-11-26T06:12:18.314059Z","iopub.status.idle":"2021-11-26T06:12:18.321683Z","shell.execute_reply.started":"2021-11-26T06:12:18.314026Z","shell.execute_reply":"2021-11-26T06:12:18.320125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\nimport seaborn as sns\ncm = confusion_matrix(test_labels, predictions.argmax(axis = 1))\nsns.heatmap(cm, annot = True)","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:12:22.010418Z","iopub.execute_input":"2021-11-26T06:12:22.01098Z","iopub.status.idle":"2021-11-26T06:12:22.364825Z","shell.execute_reply.started":"2021-11-26T06:12:22.010941Z","shell.execute_reply":"2021-11-26T06:12:22.364086Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install openpyxl","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:14:12.466794Z","iopub.execute_input":"2021-11-26T06:14:12.467579Z","iopub.status.idle":"2021-11-26T06:14:24.096596Z","shell.execute_reply.started":"2021-11-26T06:14:12.467543Z","shell.execute_reply":"2021-11-26T06:14:24.095622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"excel_data_df = pd.read_excel('../input/mycxr/image_test/export_df.xlsx', sheet_name='Sheet1')","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:14:31.103857Z","iopub.execute_input":"2021-11-26T06:14:31.104133Z","iopub.status.idle":"2021-11-26T06:14:31.490711Z","shell.execute_reply.started":"2021-11-26T06:14:31.104101Z","shell.execute_reply":"2021-11-26T06:14:31.49Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"excel_data_df['path_image'] = excel_data_df['patient_id'].apply(str) + '-' + excel_data_df['accession_num'] + '.dcm'","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:14:36.042903Z","iopub.execute_input":"2021-11-26T06:14:36.043167Z","iopub.status.idle":"2021-11-26T06:14:36.057703Z","shell.execute_reply.started":"2021-11-26T06:14:36.043135Z","shell.execute_reply":"2021-11-26T06:14:36.056692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"normal_image_list = list(excel_data_df['path_image'])","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:14:38.793414Z","iopub.execute_input":"2021-11-26T06:14:38.793981Z","iopub.status.idle":"2021-11-26T06:14:38.798446Z","shell.execute_reply.started":"2021-11-26T06:14:38.793944Z","shell.execute_reply":"2021-11-26T06:14:38.79739Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"inputdir = '../input/mycxr/image_test/test_image/'\noutdir = './'\nmy_test_dir = os.path.join(outdir, 'my_test_image')\nos.mkdir(my_test_dir)\nnormal_dir = os.path.join(my_test_dir, 'normal')\nos.mkdir(normal_dir)\nabnormal_dir = os.path.join(my_test_dir, 'abnormal')\nos.mkdir(abnormal_dir)","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:14:42.12988Z","iopub.execute_input":"2021-11-26T06:14:42.130149Z","iopub.status.idle":"2021-11-26T06:14:42.136886Z","shell.execute_reply.started":"2021-11-26T06:14:42.130118Z","shell.execute_reply":"2021-11-26T06:14:42.135937Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"normal_dir","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:14:45.177453Z","iopub.execute_input":"2021-11-26T06:14:45.17804Z","iopub.status.idle":"2021-11-26T06:14:45.184419Z","shell.execute_reply.started":"2021-11-26T06:14:45.177998Z","shell.execute_reply":"2021-11-26T06:14:45.183519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"abnormal_dir","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:14:47.579264Z","iopub.execute_input":"2021-11-26T06:14:47.579879Z","iopub.status.idle":"2021-11-26T06:14:47.586683Z","shell.execute_reply.started":"2021-11-26T06:14:47.579843Z","shell.execute_reply":"2021-11-26T06:14:47.585823Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"inputdir","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:14:50.679974Z","iopub.execute_input":"2021-11-26T06:14:50.68054Z","iopub.status.idle":"2021-11-26T06:14:50.686652Z","shell.execute_reply.started":"2021-11-26T06:14:50.680499Z","shell.execute_reply":"2021-11-26T06:14:50.685806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_list = os.listdir(inputdir)","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:14:53.41873Z","iopub.execute_input":"2021-11-26T06:14:53.419024Z","iopub.status.idle":"2021-11-26T06:14:53.66246Z","shell.execute_reply.started":"2021-11-26T06:14:53.418993Z","shell.execute_reply":"2021-11-26T06:14:53.661474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for im in test_list:\n    img = crop_img(inputdir + im, seg_model, InputShapeOfModel)\n    if im in normal_image_list:\n        cv2.imwrite(normal_dir + '/' + im.replace('.dcm','.png'),img)\n    else:\n        cv2.imwrite(abnormal_dir + '/' + im.replace('.dcm','.png'),img)","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:14:56.536669Z","iopub.execute_input":"2021-11-26T06:14:56.536938Z","iopub.status.idle":"2021-11-26T06:17:57.606861Z","shell.execute_reply.started":"2021-11-26T06:14:56.536908Z","shell.execute_reply":"2021-11-26T06:17:57.606089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(cv2.imread('./my_test_image/normal/18006863-21.0204.007245.png'))","metadata":{"execution":{"iopub.status.busy":"2021-11-25T16:18:37.992005Z","iopub.execute_input":"2021-11-25T16:18:37.992475Z","iopub.status.idle":"2021-11-25T16:18:38.32341Z","shell.execute_reply.started":"2021-11-25T16:18:37.992431Z","shell.execute_reply":"2021-11-25T16:18:38.32267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"datagen = ImageDataGenerator(rescale=1.0/255)\ntest_gen = datagen.flow_from_directory(my_test_dir,\n                                        target_size=(256,256),\n                                        batch_size=1,\n                                        class_mode='categorical',\n                                        shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:18:03.238493Z","iopub.execute_input":"2021-11-26T06:18:03.238758Z","iopub.status.idle":"2021-11-26T06:18:03.348016Z","shell.execute_reply.started":"2021-11-26T06:18:03.238729Z","shell.execute_reply":"2021-11-26T06:18:03.347087Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_gen.class_indices","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:18:07.645704Z","iopub.execute_input":"2021-11-26T06:18:07.645973Z","iopub.status.idle":"2021-11-26T06:18:07.651124Z","shell.execute_reply.started":"2021-11-26T06:18:07.645942Z","shell.execute_reply":"2021-11-26T06:18:07.650303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_labels = test_gen.classes\npredictions = model.predict_generator(test_gen, verbose = 1)\npredictions.argmax(axis = 1)\ncm = confusion_matrix(test_labels, predictions.argmax(axis = 1))\ntest_gen.class_indices\nsns.heatmap(cm, annot = True)","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:18:09.818809Z","iopub.execute_input":"2021-11-26T06:18:09.819075Z","iopub.status.idle":"2021-11-26T06:18:30.557863Z","shell.execute_reply.started":"2021-11-26T06:18:09.819045Z","shell.execute_reply":"2021-11-26T06:18:30.557133Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"GRAD CAM","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras.models import load_model\nimport cv2\n# Display\nfrom IPython.display import Image, display\nimport matplotlib.pyplot as plt\nimport matplotlib.cm as cm\nimport pydicom","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:19:20.45186Z","iopub.execute_input":"2021-11-26T06:19:20.45213Z","iopub.status.idle":"2021-11-26T06:19:20.456707Z","shell.execute_reply.started":"2021-11-26T06:19:20.452098Z","shell.execute_reply":"2021-11-26T06:19:20.456005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mytest_normal_img = os.listdir('./my_test_image/normal/')\nmytest_abnormal_img = os.listdir('./my_test_image/abnormal/')","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:19:23.002156Z","iopub.execute_input":"2021-11-26T06:19:23.002948Z","iopub.status.idle":"2021-11-26T06:19:23.008339Z","shell.execute_reply.started":"2021-11-26T06:19:23.002908Z","shell.execute_reply":"2021-11-26T06:19:23.006924Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_builder = keras.applications.xception.Xception\nimg_size = (256, 256)\npreprocess_input = keras.applications.xception.preprocess_input\ndecode_predictions = keras.applications.xception.decode_predictions","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:19:25.193754Z","iopub.execute_input":"2021-11-26T06:19:25.194041Z","iopub.status.idle":"2021-11-26T06:19:25.200168Z","shell.execute_reply.started":"2021-11-26T06:19:25.194009Z","shell.execute_reply":"2021-11-26T06:19:25.198687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_img_array(img_path, size):\n    # `img` is a PIL image of size 299x299\n    img = keras.preprocessing.image.load_img(img_path, target_size=size)\n    # `array` is a float32 Numpy array of shape (299, 299, 3)\n    array = keras.preprocessing.image.img_to_array(img)\n    # We add a dimension to transform our array into a \"batch\"\n    # of size (1, 299, 299, 3)\n    array = np.expand_dims(array, axis=0)\n    return array\n\n\ndef make_gradcam_heatmap(img_array, model, last_conv_layer_name, pred_index=None):\n    # First, we create a model that maps the input image to the activations\n    # of the last conv layer as well as the output predictions\n    grad_model = tf.keras.models.Model(\n        [model.inputs], [model.get_layer(last_conv_layer_name).output, model.output]\n    )\n\n    # Then, we compute the gradient of the top predicted class for our input image\n    # with respect to the activations of the last conv layer\n    with tf.GradientTape() as tape:\n        last_conv_layer_output, preds = grad_model(img_array)\n        if pred_index is None:\n            pred_index = tf.argmax(preds[0])\n        class_channel = preds[:, pred_index]\n\n    # This is the gradient of the output neuron (top predicted or chosen)\n    # with regard to the output feature map of the last conv layer\n    grads = tape.gradient(class_channel, last_conv_layer_output)\n\n    # This is a vector where each entry is the mean intensity of the gradient\n    # over a specific feature map channel\n    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))\n\n    # We multiply each channel in the feature map array\n    # by \"how important this channel is\" with regard to the top predicted class\n    # then sum all the channels to obtain the heatmap class activation\n    last_conv_layer_output = last_conv_layer_output[0]\n    heatmap = last_conv_layer_output @ pooled_grads[..., tf.newaxis]\n    heatmap = tf.squeeze(heatmap)\n\n    # For visualization purpose, we will also normalize the heatmap between 0 & 1\n    heatmap = tf.maximum(heatmap, 0) / tf.math.reduce_max(heatmap)\n    return heatmap.numpy()","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:19:28.23624Z","iopub.execute_input":"2021-11-26T06:19:28.236821Z","iopub.status.idle":"2021-11-26T06:19:28.247623Z","shell.execute_reply.started":"2021-11-26T06:19:28.236784Z","shell.execute_reply":"2021-11-26T06:19:28.246744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def save_and_display_gradcam(img_path, heatmap, cam_path=\"gradcam.jpg\", alpha=0.4):\n    # Load the original image\n    img = keras.preprocessing.image.load_img(img_path)\n    img = keras.preprocessing.image.img_to_array(img)\n\n    # Rescale heatmap to a range 0-255\n    heatmap = np.uint8(255 * heatmap)\n\n    # Use jet colormap to colorize heatmap\n    jet = cm.get_cmap(\"jet\")\n\n    # Use RGB values of the colormap\n    jet_colors = jet(np.arange(256))[:, :3]\n    jet_heatmap = jet_colors[heatmap]\n\n    # Create an image with RGB colorized heatmap\n    jet_heatmap = keras.preprocessing.image.array_to_img(jet_heatmap)\n    jet_heatmap = jet_heatmap.resize((img.shape[1], img.shape[0]))\n    jet_heatmap = keras.preprocessing.image.img_to_array(jet_heatmap)\n\n    # Superimpose the heatmap on original image\n    superimposed_img = jet_heatmap * alpha + img\n    superimposed_img = keras.preprocessing.image.array_to_img(superimposed_img)\n    \n    return jet_heatmap, superimposed_img\n","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:21:00.355434Z","iopub.execute_input":"2021-11-26T06:21:00.356178Z","iopub.status.idle":"2021-11-26T06:21:00.363573Z","shell.execute_reply.started":"2021-11-26T06:21:00.356136Z","shell.execute_reply":"2021-11-26T06:21:00.362802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_path = './my_test_image/abnormal/' + mytest_abnormal_img[80]\n\n# Prepare image\nimg_array = preprocess_input(get_img_array(test_path, size=img_size))\n\n# Remove last layer's softmax\n#model.layers[-1].activation = None\n\n# Print what the top predicted class is\npreds = model.predict(img_array)\nprint('Prediction Result: ', list(test_gen.class_indices.keys())[np.where(preds[0] == np.amax(preds[0]))[0][0]])\n\n\n\n# Generate class activation heatmap\nlast_conv_layer_name = \"conv5_block16_concat\"\nheatmap = make_gradcam_heatmap(img_array, model, last_conv_layer_name)\n\n# Display heatmap\nprint('GRAD CAM: ')\njet_heatmap, superimposed_img = save_and_display_gradcam(test_path, heatmap)\nfig = plt.figure(figsize=(20, 20))\nplt.subplot(2,2,1)\nplt.imshow(heatmap)\nplt.subplot(2,2,2)\nplt.imshow(superimposed_img)\n\nb,g,r = cv2.split(jet_heatmap)\ngray = 0.299 * r + 0.587 * g + 0.114 * b\ngray = np.asarray(r, np.uint8)\n(T, thresh) = cv2.threshold(gray, 200, np.amax(gray), cv2.THRESH_BINARY)\npr_canny = cv2.Canny(thresh, 170, np.amax(thresh))\ncnts = cv2.findContours(pr_canny, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)\ncntsSorted = sorted(cnts[0], key=lambda x: cv2.contourArea(x), reverse=True)\n# find bounding box\nimg = cv2.imread(test_path)\nplt.subplot(2,2,4)\nplt.imshow(img)\nfor i in range(len(cntsSorted)):\n    x, y, w, h = cv2.boundingRect(cntsSorted[i])\n    cv2.rectangle(img, (x, x+w), (y, y+h), (0, 255, 0), 5)\n    ","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:41:03.629118Z","iopub.execute_input":"2021-11-26T06:41:03.62972Z","iopub.status.idle":"2021-11-26T06:41:05.480011Z","shell.execute_reply.started":"2021-11-26T06:41:03.629678Z","shell.execute_reply":"2021-11-26T06:41:05.47931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_path = './my_test_image/abnormal/' + mytest_abnormal_img[10]\n\n# Prepare image\nimg_array = preprocess_input(get_img_array(test_path, size=img_size))\n\n# Remove last layer's softmax\n#model.layers[-1].activation = None\n\n# Print what the top predicted class is\npreds = model.predict(img_array)\nprint('Prediction Result: ', list(test_gen.class_indices.keys())[np.where(preds[0] == np.amax(preds[0]))[0][0]])\n\n\n\n# Generate class activation heatmap\nlast_conv_layer_name = \"conv5_block16_concat\"\nheatmap = make_gradcam_heatmap(img_array, model, last_conv_layer_name)\n\n# Display heatmap\nprint('GRAD CAM: ')\njet_heatmap, superimposed_img = save_and_display_gradcam(test_path, heatmap)\nfig = plt.figure(figsize=(20, 20))\nplt.subplot(2,2,1)\nplt.imshow(heatmap)\nplt.subplot(2,2,2)\nplt.imshow(superimposed_img)\n\nb,g,r = cv2.split(jet_heatmap)\ngray = 0.299 * r + 0.587 * g + 0.114 * b\ngray = np.asarray(r, np.uint8)\n(T, thresh) = cv2.threshold(gray, 200, np.amax(gray), cv2.THRESH_BINARY)\npr_canny = cv2.Canny(thresh, 170, np.amax(thresh))\ncnts = cv2.findContours(pr_canny, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)\ncntsSorted = sorted(cnts[0], key=lambda x: cv2.contourArea(x), reverse=True)\n# find bounding box\nimg = cv2.imread(test_path)\nplt.subplot(2,2,4)\nplt.imshow(img)\nfor i in range(len(cntsSorted)):\n    x, y, w, h = cv2.boundingRect(cntsSorted[i])\n    cv2.rectangle(img, (x, x+w), (y, y+h), (0, 255, 0), 5)\n    ","metadata":{"execution":{"iopub.status.busy":"2021-11-26T06:41:58.595276Z","iopub.execute_input":"2021-11-26T06:41:58.595569Z","iopub.status.idle":"2021-11-26T06:42:00.050011Z","shell.execute_reply.started":"2021-11-26T06:41:58.595538Z","shell.execute_reply":"2021-11-26T06:42:00.049263Z"},"trusted":true},"execution_count":null,"outputs":[]}]}