{"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":[{"sourceType":"competition","sourceId":13451,"datasetId":654585,"databundleVersionId":1188070}],"dockerImageVersionId":31328,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install pydicom nibabel SimpleITK -q","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-10T18:06:22.269254Z","iopub.execute_input":"2026-05-10T18:06:22.269619Z","iopub.status.idle":"2026-05-10T18:06:26.594782Z","shell.execute_reply.started":"2026-05-10T18:06:22.269562Z","shell.execute_reply":"2026-05-10T18:06:26.593542Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pydicom\nimport nibabel as nib\nimport SimpleITK as sitk\nimport torch\nfrom torch.utils.data import Dataset, DataLoader, WeightedRandomSampler\nfrom torchvision import transforms\nfrom sklearn.model_selection import train_test_split\nimport pandas as pd\nfrom PIL import Image\nimport matplotlib.pyplot as plt","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-05-10T18:06:26.597065Z","iopub.execute_input":"2026-05-10T18:06:26.597361Z","iopub.status.idle":"2026-05-10T18:06:26.604388Z","shell.execute_reply.started":"2026-05-10T18:06:26.597328Z","shell.execute_reply":"2026-05-10T18:06:26.603281Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"base = '/kaggle/input/competitions/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/'\ntrain_img_dir = os.path.join(base, 'stage_2_train')\ncsv_path = os.path.join(base, 'stage_2_train.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-10T18:06:26.605473Z","iopub.execute_input":"2026-05-10T18:06:26.605834Z","iopub.status.idle":"2026-05-10T18:06:26.627178Z","shell.execute_reply.started":"2026-05-10T18:06:26.60579Z","shell.execute_reply":"2026-05-10T18:06:26.625964Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def apply_windowing(image, window_center=40, window_width=80):\n    lower = window_center - (window_width // 2)\n    upper = window_center + (window_width // 2)\n    image = np.clip(image, lower, upper)\n    image = (image - lower) / window_width\n    return image.astype(np.float32)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-10T18:06:26.629319Z","iopub.execute_input":"2026-05-10T18:06:26.629699Z","iopub.status.idle":"2026-05-10T18:06:26.64823Z","shell.execute_reply.started":"2026-05-10T18:06:26.629667Z","shell.execute_reply":"2026-05-10T18:06:26.647185Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def load_dicom_slice(filepath):\n    dcm = pydicom.dcmread(filepath)\n    image = dcm.pixel_array.astype(np.float32)\n    if hasattr(dcm, 'RescaleSlope'):\n        image = image * dcm.RescaleSlope + dcm.RescaleIntercept\n    image = apply_windowing(image)\n    return image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-10T18:06:26.649453Z","iopub.execute_input":"2026-05-10T18:06:26.649773Z","iopub.status.idle":"2026-05-10T18:06:26.669681Z","shell.execute_reply.started":"2026-05-10T18:06:26.649741Z","shell.execute_reply":"2026-05-10T18:06:26.668523Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class RSNADataset(Dataset):\n    def __init__(self, df, img_dir, transform=None):\n        self.df = df.reset_index(drop=True)\n        self.img_dir = img_dir\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        row = self.df.iloc[idx]\n        img_path = os.path.join(self.img_dir, row['ID'] + '.dcm')\n        image = load_dicom_slice(img_path)\n        image = Image.fromarray((image * 255).astype(np.uint8)).convert('RGB')\n        if self.transform:\n            image = self.transform(image)\n        label = torch.tensor(row['label'], dtype=torch.float32)\n        return image, label","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-10T18:06:26.670942Z","iopub.execute_input":"2026-05-10T18:06:26.67125Z","iopub.status.idle":"2026-05-10T18:06:26.691013Z","shell.execute_reply.started":"2026-05-10T18:06:26.671219Z","shell.execute_reply":"2026-05-10T18:06:26.690016Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_transforms = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomRotation(15),\n    transforms.ColorJitter(brightness=0.2, contrast=0.2),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406],\n                         std=[0.229, 0.224, 0.225])\n])\n\nval_transforms = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406],\n                         std=[0.229, 0.224, 0.225])\n])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-10T18:06:26.692578Z","iopub.execute_input":"2026-05-10T18:06:26.693017Z","iopub.status.idle":"2026-05-10T18:06:26.720755Z","shell.execute_reply.started":"2026-05-10T18:06:26.692964Z","shell.execute_reply":"2026-05-10T18:06:26.71968Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = pd.read_csv(csv_path)\nprint(\"CSV shape:\", df.shape)\nprint(df.head())\n\n# Split ID and subtype\ndf[['ID', 'subtype']] = df['ID'].str.rsplit('_', n=1, expand=True)\ndf_binary = df.groupby('ID')['Label'].max().reset_index()\ndf_binary.columns = ['ID', 'label']\nprint(\"\\nClass distribution:\")\nprint(df_binary['label'].value_counts())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-10T18:06:26.721917Z","iopub.execute_input":"2026-05-10T18:06:26.722387Z","iopub.status.idle":"2026-05-10T18:06:43.4635Z","shell.execute_reply.started":"2026-05-10T18:06:26.722334Z","shell.execute_reply":"2026-05-10T18:06:43.462515Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df, temp_df = train_test_split(df_binary, test_size=0.3,\n                                      stratify=df_binary['label'],\n                                      random_state=42)\nval_df, test_df = train_test_split(temp_df, test_size=0.5,\n                                    stratify=temp_df['label'],\n                                    random_state=42)\nprint(f\"\\nTrain: {len(train_df)} | Val: {len(val_df)} | Test: {len(test_df)}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-10T18:06:43.464546Z","iopub.execute_input":"2026-05-10T18:06:43.464831Z","iopub.status.idle":"2026-05-10T18:06:43.998627Z","shell.execute_reply.started":"2026-05-10T18:06:43.464802Z","shell.execute_reply":"2026-05-10T18:06:43.997621Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class_counts = train_df['label'].value_counts().to_dict()\nweights = train_df['label'].map(lambda x: 1.0 / class_counts[x]).values\nsampler = WeightedRandomSampler(weights, num_samples=len(weights), replacement=True)\n\ntrain_dataset = RSNADataset(train_df, train_img_dir, transform=train_transforms)\nval_dataset   = RSNADataset(val_df,   train_img_dir, transform=val_transforms)\ntest_dataset  = RSNADataset(test_df,  train_img_dir, transform=val_transforms)\n\ntrain_loader = DataLoader(train_dataset, batch_size=32, sampler=sampler, num_workers=2)\nval_loader   = DataLoader(val_dataset,   batch_size=32, shuffle=False,   num_workers=2)\ntest_loader  = DataLoader(test_dataset,  batch_size=32, shuffle=False,   num_workers=2)\n\nprint(\"\\nDataLoaders ready!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-10T18:06:44.000732Z","iopub.execute_input":"2026-05-10T18:06:44.001051Z","iopub.status.idle":"2026-05-10T18:06:44.187441Z","shell.execute_reply.started":"2026-05-10T18:06:44.00101Z","shell.execute_reply":"2026-05-10T18:06:44.186276Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"images, labels = next(iter(train_loader))\nprint(f\"Batch shape: {images.shape}\")\nprint(f\"Sample labels: {labels[:8]}\")\n\nfig, axes = plt.subplots(1, 4, figsize=(16, 4))\nfor i in range(4):\n    img = images[i].permute(1, 2, 0).numpy()\n    img = (img - img.min()) / (img.max() - img.min())\n    axes[i].imshow(img)\n    axes[i].set_title(f\"Label: {int(labels[i].item())}\")\n    axes[i].axis('off')\nplt.suptitle(\"Sample Preprocessed Brain CT Slices\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-10T18:29:57.059262Z","iopub.execute_input":"2026-05-10T18:29:57.059618Z","iopub.status.idle":"2026-05-10T18:30:00.082438Z","shell.execute_reply.started":"2026-05-10T18:29:57.059568Z","shell.execute_reply":"2026-05-10T18:30:00.081329Z"}},"outputs":[],"execution_count":null}]}