{ "cells": [ { "cell_type": "markdown", "id": "e25e43bd", "metadata": {}, "source": [ "## MODEL TRAINING" ] }, { "cell_type": "code", "execution_count": 1, "id": "4b632063", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "0ec2b3fd7ede4583bf8671e0e41d07dd", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Output()" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n" ], "text/plain": [] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# ct_liver_seg.ipynb\n", "# train a semantic segmentation model to predict the liver & tumor region in CT volume\n", "#\n", "# author : xiao deng\n", "# date : 20210613\n", "# platform: Macbook pro 14\n", "\n", "import os\n", "import random\n", "\n", "import numpy as np\n", "from scipy.ndimage import zoom\n", "from rich.progress import track\n", "import matplotlib.pyplot as plt\n", "\n", "\n", "# 1) Load CT scans and corresponding masks\n", "# file name format: {series_uid}_{slice_index}.npy\n", "# series ids: 0~49, 50 CT scans in total\n", "ct_dir = 'images'\n", "mask_dir = 'labels'\n", "file_names = os.listdir(ct_dir)\n", "\n", "images = {}\n", "masks = {}\n", "for file_name in track(file_names, 'Load & preprocess data ...'):\n", " series_uid = int(file_name[:3])\n", " slice_index = int(file_name[4:7])\n", " \n", " # 2) CT image preprocessing\n", " # Load image\n", " image = np.load(f'{ct_dir}/{file_name}')\n", " mask = np.load(f'{mask_dir}/{file_name}')\n", " \n", " # Resizing\n", " # image size: 512*512 -> 256*256\n", " image = zoom(image, 0.5, mode='nearest')\n", " mask = zoom(mask, 0.5, mode='nearest')\n", " image = image.astype('float32')\n", " \n", " # Split and binarize masks\n", " liver_mask = np.where(mask > 0, 1, 0).astype('float32')\n", " tumor_mask = np.where(mask > 1, 1, 0).astype('float32')\n", " mask = np.zeros((256, 256, 2), dtype='float32')\n", " mask[:, :, 0] = liver_mask\n", " mask[:, :, 1] = tumor_mask\n", " \n", " # CT windowing (Liver window adjustment)\n", " # ref: https://radiopaedia.org/articles/windowing-ct\n", " liver_wind_upper_bound = 180\n", " liver_wind_lower_bound = -120\n", " image[image > liver_wind_upper_bound] = liver_wind_upper_bound\n", " image[image < liver_wind_lower_bound] = liver_wind_lower_bound\n", " \n", " # Min-max normalization\n", " image = (image - liver_wind_lower_bound) / (liver_wind_upper_bound - liver_wind_lower_bound)\n", " \n", " if series_uid not in images:\n", " images[series_uid] = []\n", " masks[series_uid] = []\n", " images[series_uid].append(image)\n", " masks[series_uid].append(mask)" ] }, { "cell_type": "code", "execution_count": 2, "id": "5e5fb92d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "train series uids: [43, 1, 28, 14, 36, 12, 0, 27, 47, 7, 33, 34, 20, 49, 5, 38, 11, 23, 40, 15, 10, 21, 46, 3, 9, 4, 41, 42, 39, 17, 29, 45, 6, 35, 18, 8, 44, 13, 37, 22]\n", "valid series uids: [30, 19, 25, 31, 32, 16, 2, 26, 48, 24]\n", "\n", "train_x shape: (1160, 256, 256, 1)\n", "train_y shape: (1160, 256, 256, 2)\n", "valid_x shape: (290, 256, 256, 1)\n", "valid_y shape: (290, 256, 256, 2)\n", "Metal device set to: Apple M1 Pro\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2022-06-15 12:33:14.407365: I tensorflow/core/common_runtime/pluggable_device/pluggable_device_factory.cc:305] Could not identify NUMA node of platform GPU ID 0, defaulting to 0. Your kernel may not have been built with NUMA support.\n", "2022-06-15 12:33:14.407462: I tensorflow/core/common_runtime/pluggable_device/pluggable_device_factory.cc:271] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 0 MB memory) -> physical PluggableDevice (device: 0, name: METAL, pci bus id: