{"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 os\nimport zipfile\nimport numpy as np\nimport tensorflow as tf\n\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\n\nimport os\nimport sys \nimport json\nimport glob\nimport random\nimport collections\nimport time\nimport re\nimport math\nimport numpy as np\nimport pandas as pd\nimport cv2","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:22:21.426345Z","iopub.execute_input":"2022-08-06T19:22:21.426851Z","iopub.status.idle":"2022-08-06T19:22:21.621687Z","shell.execute_reply.started":"2022-08-06T19:22:21.426807Z","shell.execute_reply":"2022-08-06T19:22:21.620134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We will be following the code presented to us in Keras notebook for 3D image classification on CT scan of chest. Here is the code one can find : https://keras.io/examples/vision/3D_image_classification/","metadata":{}},{"cell_type":"code","source":"# Lets read the train data and the train labels. \ntrain_data_directory = '../input/rsna-miccai-brain-tumor-radiogenomic-classification/train'\ndata_directory = '../input/rsna-miccai-brain-tumor-radiogenomic-classification'\nIMAGE_SIZE = 128\nNUM_IMAGES = 64\ndef load_dicom_image(path, img_size=IMAGE_SIZE, voi_lut=True, rotate=0):\n    dicom = pydicom.read_file(path)\n    data = dicom.pixel_array\n    if voi_lut:\n        data = apply_voi_lut(dicom.pixel_array, dicom)\n    else:\n        data = dicom.pixel_array\n        \n    if rotate > 0:\n        rot_choices = [0, cv2.ROTATE_90_CLOCKWISE, cv2.ROTATE_90_COUNTERCLOCKWISE, cv2.ROTATE_180]\n        data = cv2.rotate(data, rot_choices[rotate])\n        \n    data = cv2.resize(data, (img_size, img_size))\n    return data\n\n\ndef load_dicom_images_3d(scan_id, num_imgs=NUM_IMAGES, img_size=IMAGE_SIZE, mri_type=\"FLAIR\", split=\"test\", rotate=0):\n\n    files = sorted(glob.glob(f\"{data_directory}/{split}/{scan_id}/{mri_type}/*.dcm\"), \n               key=lambda var:[int(x) if x.isdigit() else x for x in re.findall(r'[^0-9]|[0-9]+', var)])\n\n    middle = len(files)//2\n    num_imgs2 = num_imgs//2\n    p1 = max(0, middle - num_imgs2)\n    p2 = min(len(files), middle + num_imgs2)\n    img3d = np.stack([load_dicom_image(f, rotate=rotate) for f in files[p1:p2]]).T \n    if img3d.shape[-1] < num_imgs:\n        n_zero = np.zeros((img_size, img_size, num_imgs - img3d.shape[-1]))\n        img3d = np.concatenate((img3d,  n_zero), axis = -1)\n        \n    if np.min(img3d) < np.max(img3d):\n        img3d = img3d - np.min(img3d)\n        img3d = img3d / np.max(img3d)\n            \n    return np.expand_dims(img3d,0)\n\n","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:08:08.255145Z","iopub.execute_input":"2022-08-06T20:08:08.255542Z","iopub.status.idle":"2022-08-06T20:08:08.267925Z","shell.execute_reply.started":"2022-08-06T20:08:08.255508Z","shell.execute_reply":"2022-08-06T20:08:08.267124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"a = load_dicom_images_3d(\"00001\")\nprint(a.shape)\nprint(np.min(a), np.max(a), np.mean(a), np.median(a))\nimage = a[0]\nprint(\"Dimension of the CT scan is:\", image.shape)\nplt.imshow(np.squeeze(image[:, :, 15]), cmap=\"gray\")","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:24:44.763891Z","iopub.execute_input":"2022-08-06T19:24:44.764375Z","iopub.status.idle":"2022-08-06T19:24:45.409195Z","shell.execute_reply.started":"2022-08-06T19:24:44.764338Z","shell.execute_reply":"2022-08-06T19:24:45.407927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## EXPLANATION OF ABOVE DEF FUNCTIONS \n\nLets trace how this image is getting loaded by completely following the def function to have a full understanding of what this 3D image","metadata":{}},{"cell_type":"code","source":"num_imgs=NUM_IMAGES\nimg_size=IMAGE_SIZE\nmri_type=\"FLAIR\"\nsplit=\"test\"\nrotate=0\nscan_id = \"00001\"","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:26:09.254062Z","iopub.execute_input":"2022-08-06T19:26:09.254500Z","iopub.status.idle":"2022-08-06T19:26:09.261148Z","shell.execute_reply.started":"2022-08-06T19:26:09.254464Z","shell.execute_reply":"2022-08-06T19:26:09.259761Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The below address essentially points out that we should take all the files within 00001 under test folder under flair mri images. We are pointing to all the images within that. ","metadata":{}},{"cell_type":"code","source":"f\"{data_directory}/{split}/{scan_id}/{mri_type}/*.dcm\"","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:26:24.543247Z","iopub.execute_input":"2022-08-06T19:26:24.543703Z","iopub.status.idle":"2022-08-06T19:26:24.553656Z","shell.execute_reply.started":"2022-08-06T19:26:24.543667Z","shell.execute_reply":"2022-08-06T19:26:24.552318Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This is a simple lambda function that returns the key if all is numerical otherwise just the numerical part. ","metadata":{}},{"cell_type":"code","source":"key=lambda var:[int(x) if x.isdigit() else x for x in re.findall(r'[^0-9]|[0-9]+', var)]","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:29:30.265578Z","iopub.execute_input":"2022-08-06T19:29:30.266072Z","iopub.status.idle":"2022-08-06T19:29:30.273172Z","shell.execute_reply.started":"2022-08-06T19:29:30.266032Z","shell.execute_reply":"2022-08-06T19:29:30.271520Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"files = sorted(glob.glob(f\"{data_directory}/{split}/{scan_id}/{mri_type}/*.dcm\"), \n               key=lambda var:[int(x) if x.isdigit() else x for x in re.findall(r'[^0-9]|[0-9]+', var)])\nprint(files)","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:30:25.913454Z","iopub.execute_input":"2022-08-06T19:30:25.914538Z","iopub.status.idle":"2022-08-06T19:30:25.933253Z","shell.execute_reply.started":"2022-08-06T19:30:25.914487Z","shell.execute_reply":"2022-08-06T19:30:25.932043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"middle = len(files)//2\nnum_imgs2 = num_imgs//2\np1 = max(0, middle - num_imgs2)\np2 = min(len(files), middle + num_imgs2)\n\nprint(p1,p2)","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:31:28.749554Z","iopub.execute_input":"2022-08-06T19:31:28.750226Z","iopub.status.idle":"2022-08-06T19:31:28.759886Z","shell.execute_reply.started":"2022-08-06T19:31:28.750134Z","shell.execute_reply":"2022-08-06T19:31:28.758343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"I am choosing 64 images within 72 and 136 i.e my number of Images and stacking them in a numpy array taking their transpose ","metadata":{}},{"cell_type":"code","source":"img3d = np.stack([load_dicom_image(f, rotate=rotate) for f in files[p1:p2]]).T ","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:33:46.683143Z","iopub.execute_input":"2022-08-06T19:33:46.683624Z","iopub.status.idle":"2022-08-06T19:33:47.076532Z","shell.execute_reply.started":"2022-08-06T19:33:46.683587Z","shell.execute_reply":"2022-08-06T19:33:47.075080Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img3d.T.shape","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:59:40.464230Z","iopub.execute_input":"2022-08-06T19:59:40.464786Z","iopub.status.idle":"2022-08-06T19:59:40.475388Z","shell.execute_reply.started":"2022-08-06T19:59:40.464739Z","shell.execute_reply":"2022-08-06T19:59:40.473856Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img3d.shape\nprint(img3d.shape,img3d.shape[-1])","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:34:47.230476Z","iopub.execute_input":"2022-08-06T19:34:47.230919Z","iopub.status.idle":"2022-08-06T19:34:47.237522Z","shell.execute_reply.started":"2022-08-06T19:34:47.230882Z","shell.execute_reply":"2022-08-06T19:34:47.236519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img3d.shape[-1] < num_imgs","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:35:04.402843Z","iopub.execute_input":"2022-08-06T19:35:04.403302Z","iopub.status.idle":"2022-08-06T19:35:04.412293Z","shell.execute_reply.started":"2022-08-06T19:35:04.403268Z","shell.execute_reply":"2022-08-06T19:35:04.410663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"If the sampled images are less than 64 i.e the number of images then we will put black array of pixels of the same size to take the number of images to 64","metadata":{}},{"cell_type":"code","source":"if img3d.shape[-1] < num_imgs:\n        n_zero = np.zeros((img_size, img_size, num_imgs - img3d.shape[-1]))\n        img3d = np.concatenate((img3d,  n_zero), axis = -1)","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:34:56.406112Z","iopub.execute_input":"2022-08-06T19:34:56.406504Z","iopub.status.idle":"2022-08-06T19:34:56.412355Z","shell.execute_reply.started":"2022-08-06T19:34:56.406467Z","shell.execute_reply":"2022-08-06T19:34:56.410782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(np.min(img3d),np.max(img3d))","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:36:51.656004Z","iopub.execute_input":"2022-08-06T19:36:51.656640Z","iopub.status.idle":"2022-08-06T19:36:51.665466Z","shell.execute_reply.started":"2022-08-06T19:36:51.656446Z","shell.execute_reply":"2022-08-06T19:36:51.664180Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The below operation is basically the scaling of pixels where we subtract the minimum value and divide by the maximum value. ","metadata":{}},{"cell_type":"code","source":"if np.min(img3d) < np.max(img3d):\n        img3d = img3d - np.min(img3d)\n        img3d = img3d / np.max(img3d)","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:37:59.261892Z","iopub.execute_input":"2022-08-06T19:37:59.262356Z","iopub.status.idle":"2022-08-06T19:37:59.275088Z","shell.execute_reply.started":"2022-08-06T19:37:59.262319Z","shell.execute_reply":"2022-08-06T19:37:59.273915Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img3d.shape","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:03:37.647830Z","iopub.execute_input":"2022-08-06T20:03:37.648254Z","iopub.status.idle":"2022-08-06T20:03:37.656473Z","shell.execute_reply.started":"2022-08-06T20:03:37.648222Z","shell.execute_reply":"2022-08-06T20:03:37.655125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.expand_dims(img3d,0).T.shape","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:04:06.218744Z","iopub.execute_input":"2022-08-06T20:04:06.219170Z","iopub.status.idle":"2022-08-06T20:04:06.227546Z","shell.execute_reply.started":"2022-08-06T20:04:06.219140Z","shell.execute_reply":"2022-08-06T20:04:06.226296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Generate the training Dataset","metadata":{}},{"cell_type":"code","source":"df_train_labels = pd.read_csv('../input/rsna-miccai-brain-tumor-radiogenomic-classification/train_labels.csv')\ndf_train_labels.head()","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:40:43.711101Z","iopub.execute_input":"2022-08-06T19:40:43.711433Z","iopub.status.idle":"2022-08-06T19:40:43.730395Z","shell.execute_reply.started":"2022-08-06T19:40:43.711404Z","shell.execute_reply":"2022-08-06T19:40:43.729633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data_directory = '../input/rsna-miccai-brain-tumor-radiogenomic-classification/train'\nprint(min(os.listdir(train_data_directory)), max(os.listdir(train_data_directory)))","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:44:41.400022Z","iopub.execute_input":"2022-08-06T19:44:41.400473Z","iopub.status.idle":"2022-08-06T19:44:41.408712Z","shell.execute_reply.started":"2022-08-06T19:44:41.400440Z","shell.execute_reply":"2022-08-06T19:44:41.407857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Lets not take all 1010 samples for training as this will led to a lot of memory and time consumption hence lets take only 140 samples out of these all. You can use below line of code for all. ","metadata":{}},{"cell_type":"code","source":"total_training_scans = np.array([load_dicom_images_3d(a, split = 'train') for a in os.listdir(train_data_directory)])","metadata":{"execution":{"iopub.status.busy":"2022-08-06T19:52:28.967150Z","iopub.execute_input":"2022-08-06T19:52:28.967588Z","iopub.status.idle":"2022-08-06T19:59:14.983504Z","shell.execute_reply.started":"2022-08-06T19:52:28.967539Z","shell.execute_reply":"2022-08-06T19:59:14.981924Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"count = 0\nlist_train_files = []\nfor file in os.listdir(train_data_directory):\n    if count<140:\n        list_train_files.append(file)\n        count = count+1","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:02:49.032430Z","iopub.execute_input":"2022-08-06T20:02:49.032839Z","iopub.status.idle":"2022-08-06T20:02:49.040236Z","shell.execute_reply.started":"2022-08-06T20:02:49.032808Z","shell.execute_reply":"2022-08-06T20:02:49.039016Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(list_train_files)","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:02:50.040122Z","iopub.execute_input":"2022-08-06T20:02:50.040531Z","iopub.status.idle":"2022-08-06T20:02:50.049049Z","shell.execute_reply.started":"2022-08-06T20:02:50.040499Z","shell.execute_reply":"2022-08-06T20:02:50.047602Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"total_training_scans = np.array([load_dicom_images_3d(a, split = 'train') for a in list_train_files])","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:08:16.242903Z","iopub.execute_input":"2022-08-06T20:08:16.243489Z","iopub.status.idle":"2022-08-06T20:09:00.921211Z","shell.execute_reply.started":"2022-08-06T20:08:16.243414Z","shell.execute_reply":"2022-08-06T20:09:00.920178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(total_training_scans.shape)\nprint(len(total_training_scans))\nimage = total_training_scans[20]\nprint(\"Dimension of the CT scan is:\", image.shape)\nplt.imshow(np.squeeze(image[:, :, 25]), cmap=\"gray\")","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:10:37.218568Z","iopub.execute_input":"2022-08-06T20:10:37.219283Z","iopub.status.idle":"2022-08-06T20:10:37.413737Z","shell.execute_reply.started":"2022-08-06T20:10:37.219239Z","shell.execute_reply":"2022-08-06T20:10:37.412612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Split data in the ratio 70-30 for training and validation.\nx_train = np.array([train.T for train in total_training_scans[:100]])\nx_val = np.array([train.T for train in total_training_scans[100:]])\n","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:35:55.638783Z","iopub.execute_input":"2022-08-06T20:35:55.639169Z","iopub.status.idle":"2022-08-06T20:35:56.901265Z","shell.execute_reply.started":"2022-08-06T20:35:55.639138Z","shell.execute_reply":"2022-08-06T20:35:56.900288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_train.shape","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:36:07.555572Z","iopub.execute_input":"2022-08-06T20:36:07.555941Z","iopub.status.idle":"2022-08-06T20:36:07.563000Z","shell.execute_reply.started":"2022-08-06T20:36:07.555912Z","shell.execute_reply":"2022-08-06T20:36:07.561905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_train = x_train[:100]","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:34:18.708954Z","iopub.execute_input":"2022-08-06T20:34:18.709364Z","iopub.status.idle":"2022-08-06T20:34:18.714763Z","shell.execute_reply.started":"2022-08-06T20:34:18.709332Z","shell.execute_reply":"2022-08-06T20:34:18.713099Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_train.shape","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:34:33.258152Z","iopub.execute_input":"2022-08-06T20:34:33.258603Z","iopub.status.idle":"2022-08-06T20:34:33.286176Z","shell.execute_reply.started":"2022-08-06T20:34:33.258554Z","shell.execute_reply":"2022-08-06T20:34:33.284644Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"total_training_labels = df_train_labels[\"MGMT_value\"].to_list()","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:18:30.090102Z","iopub.execute_input":"2022-08-06T20:18:30.090586Z","iopub.status.idle":"2022-08-06T20:18:30.103458Z","shell.execute_reply.started":"2022-08-06T20:18:30.090534Z","shell.execute_reply":"2022-08-06T20:18:30.101677Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"total_training_labels = total_training_labels[:140]","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:19:00.115297Z","iopub.execute_input":"2022-08-06T20:19:00.115779Z","iopub.status.idle":"2022-08-06T20:19:00.121260Z","shell.execute_reply.started":"2022-08-06T20:19:00.115742Z","shell.execute_reply":"2022-08-06T20:19:00.120259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(total_training_labels)","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:19:05.928208Z","iopub.execute_input":"2022-08-06T20:19:05.928743Z","iopub.status.idle":"2022-08-06T20:19:05.937838Z","shell.execute_reply.started":"2022-08-06T20:19:05.928701Z","shell.execute_reply":"2022-08-06T20:19:05.936350Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_train = total_training_labels[:100]\ny_val = total_training_labels[100:]","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:20:41.850667Z","iopub.execute_input":"2022-08-06T20:20:41.851224Z","iopub.status.idle":"2022-08-06T20:20:41.857871Z","shell.execute_reply.started":"2022-08-06T20:20:41.851181Z","shell.execute_reply":"2022-08-06T20:20:41.856378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_slices(num_rows, num_columns, width, height, data):\n    \"\"\"Plot a montage of 20 CT slices\"\"\"\n    data = np.rot90(np.array(data))\n    data = np.transpose(data)\n    data = np.reshape(data, (num_rows, num_columns, width, height))\n    rows_data, columns_data = data.shape[0], data.shape[1]\n    heights = [slc[0].shape[0] for slc in data]\n    widths = [slc.shape[1] for slc in data[0]]\n    fig_width = 12.0\n    fig_height = fig_width * sum(heights) / sum(widths)\n    f, axarr = plt.subplots(\n        rows_data,\n        columns_data,\n        figsize=(fig_width, fig_height),\n        gridspec_kw={\"height_ratios\": heights},\n    )\n    for i in range(rows_data):\n        for j in range(columns_data):\n            axarr[i, j].imshow(data[i][j], cmap=\"gray\")\n            axarr[i, j].axis(\"off\")\n    plt.subplots_adjust(wspace=0, hspace=0, left=0, right=1, bottom=0, top=1)\n    plt.show()\n\n\n# Visualize montage of slices.\n# 4 rows and 10 columns for 100 slices of the CT scan.\na = load_dicom_images_3d(\"00001\")\nprint(a.shape)\nprint(np.min(a), np.max(a), np.mean(a), np.median(a))\nimage = a[0]\nprint(\"Dimension of the CT scan is:\", image.shape)\nplt.imshow(np.squeeze(image[:, :, 30]), cmap=\"gray\")\nplot_slices(4, 10, 128, 128, image[:, :, :40])","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:28:16.994395Z","iopub.execute_input":"2022-08-06T20:28:16.995520Z","iopub.status.idle":"2022-08-06T20:28:19.026284Z","shell.execute_reply.started":"2022-08-06T20:28:16.995465Z","shell.execute_reply":"2022-08-06T20:28:19.025194Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## MODEL","metadata":{}},{"cell_type":"code","source":"def get_model(width=128, height=128, depth=64):\n    \"\"\"Build a 3D convolutional neural network model.\"\"\"\n\n    inputs = keras.Input((depth,width, height,1))\n\n    x = layers.Conv3D(filters=64, kernel_size=3, activation=\"relu\")(inputs)\n    x = layers.MaxPool3D(pool_size=2)(x)\n    x = layers.BatchNormalization()(x)\n\n    x = layers.Conv3D(filters=64, kernel_size=3, activation=\"relu\")(x)\n    x = layers.MaxPool3D(pool_size=2)(x)\n    x = layers.BatchNormalization()(x)\n\n    x = layers.Conv3D(filters=128, kernel_size=3, activation=\"relu\")(x)\n    x = layers.MaxPool3D(pool_size=2)(x)\n    x = layers.BatchNormalization()(x)\n\n    x = layers.Conv3D(filters=256, kernel_size=3, activation=\"relu\")(x)\n    x = layers.MaxPool3D(pool_size=2)(x)\n    x = layers.BatchNormalization()(x)\n\n    x = layers.GlobalAveragePooling3D()(x)\n    x = layers.Dense(units=512, activation=\"relu\")(x)\n    x = layers.Dropout(0.3)(x)\n\n    outputs = layers.Dense(units=1, activation=\"sigmoid\")(x)\n\n    # Define the model.\n    model = keras.Model(inputs, outputs, name=\"3dcnn\")\n    return model\n\n\n# Build model.\nmodel = get_model(width=128, height=128, depth=64)\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:36:34.184488Z","iopub.execute_input":"2022-08-06T20:36:34.184926Z","iopub.status.idle":"2022-08-06T20:36:34.321666Z","shell.execute_reply.started":"2022-08-06T20:36:34.184891Z","shell.execute_reply":"2022-08-06T20:36:34.320574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Training it for one epoch because we have a limited memory with this. All above transpose operations has been made in order to provide an input image according to the dimensions we have specified. Also We need to ensure that we provide a batch in order to cover for None in (None, 64,128,128,1). Check the stack overflow here for this : https://stackoverflow.com/questions/49840968/valueerror-input-0-is-incompatible-with-layer-conv1d-1-expected-ndim-3-found","metadata":{}},{"cell_type":"code","source":"# Compile model.\ninitial_learning_rate = 0.0001\nlr_schedule = keras.optimizers.schedules.ExponentialDecay(\n    initial_learning_rate, decay_steps=100000, decay_rate=0.96, staircase=True\n)\nmodel.compile(\n    loss=\"binary_crossentropy\",\n    optimizer=keras.optimizers.Adam(learning_rate=lr_schedule),\n    metrics=[\"acc\"],\n)\n\n# Define callbacks.\ncheckpoint_cb = keras.callbacks.ModelCheckpoint(\n    \"3d_image_classification.h5\", save_best_only=True\n)\nearly_stopping_cb = keras.callbacks.EarlyStopping(monitor=\"val_acc\", patience=15)\n\n# Train the model, doing validation at the end of each epoch\nepochs = 1\nmodel.fit(\n    tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(4),\n    validation_data=tf.data.Dataset.from_tensor_slices((x_val,y_val)).batch(4),\n    epochs=epochs,\n    shuffle=True,\n    verbose=2,\n    callbacks=[checkpoint_cb, early_stopping_cb],\n)","metadata":{"execution":{"iopub.status.busy":"2022-08-06T20:42:27.066237Z","iopub.execute_input":"2022-08-06T20:42:27.067624Z","iopub.status.idle":"2022-08-06T20:44:45.713942Z","shell.execute_reply.started":"2022-08-06T20:42:27.067555Z","shell.execute_reply":"2022-08-06T20:44:45.712541Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}