{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":10338,"databundleVersionId":862042,"sourceType":"competition"}],"dockerImageVersionId":31236,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# **Set-Up**","metadata":{}},{"cell_type":"code","source":"%pip install torchio --q","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-13T16:32:25.789812Z","iopub.execute_input":"2026-01-13T16:32:25.790156Z","iopub.status.idle":"2026-01-13T16:32:33.042199Z","shell.execute_reply.started":"2026-01-13T16:32:25.790121Z","shell.execute_reply":"2026-01-13T16:32:33.040423Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#@title Imports\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nimport pytorch_lightning as pl\nimport torchio as tio \nimport torchvision\nimport torchvision.transforms as transforms\nfrom torch.utils.data import Dataset, DataLoader\n\nimport pydicom\n\nimport math\nimport os\nimport random\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom IPython.display import clear_output\nfrom tqdm.notebook import trange, tqdm\nfrom pathlib import Path\nfrom tqdm import tqdm\n\n%matplotlib inline","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-01-13T16:32:33.044880Z","iopub.execute_input":"2026-01-13T16:32:33.045280Z","execution_failed":"2026-01-13T16:32:34.970Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Pre-Processing**","metadata":{}},{"cell_type":"code","source":"labels_df = pd.read_csv(\n    \"/kaggle/input/rsna-pneumonia-detection-challenge/stage_2_train_labels.csv\"\n)\n\nlabels_df = labels_df.groupby(\"patientId\")[\"Target\"].max().reset_index()\n\nprint(labels_df[\"Target\"].value_counts())\nprint(labels_df.info(verbose=True, show_counts=True))","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.970Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"labels_df.head()","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.970Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Subjects","metadata":{}},{"cell_type":"code","source":"ROOT_PATH = Path(\"/kaggle/input/rsna-pneumonia-detection-challenge/stage_2_train_images/\")\npatient_dirs = list(ROOT_PATH.glob(\"*\"))\n\npatient_dirs[0] # debug","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.970Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ds = pydicom.dcmread(patient_dirs[0])\nimg = ds.pixel_array\n\nimg.shape","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.970Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def get_patient_label(patient_path: Path, labels_df: pd.DataFrame) -> int:\n    patientID = patient_path.stem\n    label = labels_df.loc[labels_df[\"patientId\"] == patientID, \"Target\"]\n    label = label.iloc[0] if not label.empty else None\n    return int(label)","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"subjects = []\nheights = []\nwidths = []\nlabels = []\n\nfor subject_path in tqdm(patient_dirs):\n    \n    img_path = subject_path\n    label = get_patient_label(subject_path, labels_df)\n\n    ct = tio.ScalarImage(img_path)\n    h, w, _ = ct.spatial_shape   \n\n    subject = tio.Subject(\n        CT = ct,\n        Label = torch.tensor(label, dtype=torch.long),\n        PatientID = subject_path.stem\n    )\n\n    subjects.append(subject)\n    heights.append(h)\n    widths.append(w)\n    labels.append(label)","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(type(subjects[15][\"CT\"]), subjects[15][\"CT\"])\nprint(type(subjects[15][\"Label\"]), subjects[15][\"Label\"])\nsubjects[15][\"CT\"].spatial_shape","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Plot depth (dimensions)\nplt.figure(figsize=(18,5))\n\n# Plot height\nplt.subplot(1,2,1)\nplt.hist(heights, bins=20, color='lightgreen', edgecolor='black')\nplt.title(\"CT Height Distribution\")\nplt.xlabel(\"Height (pixels/voxels)\")\nplt.ylabel(\"Number of Subjects\")\n\n# Plot width\nplt.subplot(1,2,2)\nplt.hist(widths, bins=20, color='salmon', edgecolor='black')\nplt.title(\"CT Width Distribution\")\nplt.xlabel(\"Width (pixels/voxels)\")\nplt.ylabel(\"Number of Subjects\")\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"img_size_og = subjects[15][\"CT\"].spatial_shape[0]","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## **Transforms**","metadata":{}},{"cell_type":"code","source":"process = tio.Compose([\n    tio.ToCanonical(),                        # step 1: fix orientation - RAS              \n    tio.RescaleIntensity((0, 1)),                      # step 2: normalize intensity\n    tio.Resize((356, 356, 1)),\n    tio.CropOrPad((256, 256, 1)),          \n])\n\naugmentation = tio.RandomAffine(scales=(0.9, 1.1), degrees=(-10, 10))\n\ntrain_transform = tio.Compose([process, augmentation])\nval_transform = tio.Compose([process])","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## **DataSet & DataLoader**","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\n# (90/10)\ntrain_val_subjects, test_subjects = train_test_split(\n    subjects,\n    test_size=0.15,\n    stratify=labels,\n    random_state=42\n)\n\n# (80/20)\ntrain_subjects, val_subjects = train_test_split(\n    train_val_subjects,\n    test_size=0.2,\n    stratify=[s.Label.item() for s in train_val_subjects],\n    random_state=42\n)\n\n# Verify class distributions\ntrain_labels = [s.Label.item() for s in train_subjects]\nval_labels   = [s.Label.item() for s in val_subjects]\ntest_labels  = [s.Label.item() for s in test_subjects]\n\nprint(\"Train counts:\", np.bincount(train_labels))\nprint(\"Val counts:\", np.bincount(val_labels))\nprint(\"Test counts:\", np.bincount(test_labels))","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_dataset = tio.SubjectsDataset(train_subjects, transform = train_transform) \nval_dataset = tio.SubjectsDataset(val_subjects, transform = val_transform)  \ntest_dataset = tio.SubjectsDataset(test_subjects, transform = val_transform)  ","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from typing import Tuple, List\n\ndef collate_subjects(batch: List) -> Tuple[torch.Tensor, torch.Tensor]:\n    images = torch.stack([s.CT.data.squeeze(-1) for s in batch])\n    labels = torch.tensor([s.Label.item() for s in batch])\n    return images, labels","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_loader = DataLoader(train_dataset, batch_size=8, num_workers=4, collate_fn=collate_subjects, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=8, num_workers=4, collate_fn=collate_subjects)\ntest_loader = DataLoader(test_dataset, batch_size=8, num_workers=4, collate_fn=collate_subjects)","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## **TEST DATALOADER SETTINGS**","metadata":{}},{"cell_type":"code","source":"import time\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(device)","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def measure_dataloader_time(loader, device='cpu'):\n    start = time.time()\n    \n    for batch_idx, (images, labels) in enumerate(loader):\n        # Optional: move to GPU if you want to measure transfer\n        images = images.to(device, non_blocking=True)\n        labels = labels.to(device, non_blocking=True)\n        \n        # Do nothing else, just iterate\n        pass\n    \n    end = time.time()\n    print(f\"Time to iterate through DataLoader: {end - start:.3f} seconds\")\n    return end - start","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_loader = DataLoader(train_dataset, batch_size=8, num_workers=4, collate_fn=collate_subjects, shuffle=True)\ntime1 = measure_dataloader_time(train_loader, device)","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_loader = DataLoader(train_dataset, batch_size=8, num_workers=4, collate_fn=collate_subjects, shuffle=True, pin_memory = True)\ntime3 = measure_dataloader_time(train_loader, device)","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_loader = DataLoader(train_dataset, batch_size=16, num_workers=4, collate_fn=collate_subjects, shuffle=True)\ntime2 = measure_dataloader_time(train_loader, device)","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_loader = DataLoader(train_dataset, batch_size=32, num_workers=4, collate_fn=collate_subjects, shuffle=True)\ntime4 = measure_dataloader_time(train_loader, device)","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_loader = DataLoader(train_dataset, batch_size=64, num_workers=4, collate_fn=collate_subjects, shuffle=True)\ntime5 = measure_dataloader_time(train_loader, device)","metadata":{"trusted":true,"execution":{"execution_failed":"2026-01-13T16:32:34.971Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_loader = DataLoader(train_dataset, batch_size=128, num_workers=4, collate_fn=collate_subjects, shuffle=True)\ntime6 = measure_dataloader_time(train_loader, device)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_loader = DataLoader(train_dataset, batch_size=256, num_workers=4, collate_fn=collate_subjects, shuffle=True)\ntime6 = measure_dataloader_time(train_loader, device)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# less num_workers = more time taken","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}