{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":29653,"databundleVersionId":2420395,"sourceType":"competition"}],"dockerImageVersionId":31012,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# =============================\n# 1. Imports\n# =============================\nimport os\nimport numpy as np\nimport pandas as pd\nimport pydicom\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader, random_split\nfrom torchvision import models, transforms\nfrom sklearn.metrics import accuracy_score, f1_score, cohen_kappa_score, roc_auc_score\nfrom skimage.transform import resize\n\n# =============================\n# 2. Configurations\n# =============================\nclass CFG:\n    train_folder = \"/kaggle/input/rsna-miccai-brain-tumor-radiogenomic-classification/train\"\n    csv_file = \"/kaggle/input/rsna-miccai-brain-tumor-radiogenomic-classification/train_labels.csv\"\n    num_classes = 2\n    batch_size = 8\n    num_epochs = 10\n    learning_rate = 1e-4\n    device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n    img_size = (224, 224)\n\n# =============================\n# 3. Dataset\n# =============================\nclass BrainTumorDataset(Dataset):\n    def __init__(self, csv_file, folder, transform=None):\n        self.labels = pd.read_csv(csv_file)\n        self.folder = folder\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.labels)\n\n    def __getitem__(self, idx):\n        patient_id = str(self.labels.iloc[idx, 0]).zfill(5)\n        label = self.labels.iloc[idx, 1]\n        flair_folder = os.path.join(self.folder, patient_id, \"T1wCE\")\n        slices = []\n        if os.path.exists(flair_folder):\n            for fname in sorted(os.listdir(flair_folder)):\n                if fname.endswith(\".dcm\"):\n                    dcm = pydicom.dcmread(os.path.join(flair_folder, fname))\n                    slices.append(dcm.pixel_array)\n        if len(slices) == 0:\n            img = np.zeros(CFG.img_size)\n        else:\n            mid_slice = slices[len(slices) // 2]\n            img = resize(mid_slice, CFG.img_size)\n\n        img = np.stack([img]*3, axis=0)  # Convert to 3 channels\n        img = torch.tensor(img, dtype=torch.float32)\n\n        if self.transform:\n            img = self.transform(img)\n\n        return img, torch.tensor(label, dtype=torch.long)\n\n# =============================\n# 4. Model\n# =============================\nclass ResNetClassifier(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.backbone = models.resnet152(pretrained=True)\n        self.backbone.fc = nn.Linear(self.backbone.fc.in_features, 2)\n\n    def forward(self, x):\n        return self.backbone(x)\n\n# =============================\n# 5. Training and Evaluation\n# =============================\ndef train_fn(model, loader, optimizer, criterion):\n    model.train()\n    all_preds = []\n    all_labels = []\n    for imgs, labels in loader:\n        imgs, labels = imgs.to(CFG.device), labels.to(CFG.device)\n        optimizer.zero_grad()\n        outputs = model(imgs)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n\n        preds = outputs.argmax(dim=1)\n        all_preds.extend(preds.detach().cpu().numpy())\n        all_labels.extend(labels.detach().cpu().numpy())\n\n    acc = accuracy_score(all_labels, all_preds)\n    return acc\n\n\ndef eval_fn(model, loader):\n    model.eval()\n    all_preds = []\n    all_probs = []\n    all_labels = []\n    with torch.no_grad():\n        for imgs, labels in loader:\n            imgs, labels = imgs.to(CFG.device), labels.to(CFG.device)\n            outputs = model(imgs)\n            preds = outputs.argmax(dim=1)\n            probs = torch.softmax(outputs, dim=1)[:, 1]\n\n            all_preds.extend(preds.cpu().numpy())\n            all_probs.extend(probs.cpu().numpy())\n            all_labels.extend(labels.cpu().numpy())\n\n    acc = accuracy_score(all_labels, all_preds)\n    f1 = f1_score(all_labels, all_preds)\n    kappa = cohen_kappa_score(all_labels, all_preds)\n    roc = roc_auc_score(all_labels, all_probs)\n    return acc, f1, kappa, roc\n\n# =============================\n# 6. Run everything\n# =============================\n# Prepare dataset\nfull_dataset = BrainTumorDataset(CFG.csv_file, CFG.train_folder)\ntrain_size = int(0.7 * len(full_dataset))\nval_size = int(0.15 * len(full_dataset))\ntest_size = len(full_dataset) - train_size - val_size\n\ntrain_ds, val_ds, test_ds = random_split(full_dataset, [train_size, val_size, test_size])\n\ntrain_loader = DataLoader(train_ds, batch_size=CFG.batch_size, shuffle=True)\nval_loader = DataLoader(val_ds, batch_size=CFG.batch_size, shuffle=False)\ntest_loader = DataLoader(test_ds, batch_size=CFG.batch_size, shuffle=False)\n\n# Model, optimizer, loss\nmodel = ResNetClassifier().to(CFG.device)\noptimizer = optim.Adam(model.parameters(), lr=CFG.learning_rate)\ncriterion = nn.CrossEntropyLoss()\n\n# Training loop\nfor epoch in range(CFG.num_epochs):\n    train_acc = train_fn(model, train_loader, optimizer, criterion)\n    val_acc, val_f1, val_kappa, val_roc = eval_fn(model, val_loader)\n    print(f\"Epoch {epoch+1}/{CFG.num_epochs} => Train Acc: {train_acc:.4f} | Val Acc: {val_acc:.4f} | F1: {val_f1:.4f} | Kappa: {val_kappa:.4f} | ROC-AUC: {val_roc:.4f}\")\n\n# Final test evaluation\ntest_acc, test_f1, test_kappa, test_roc = eval_fn(model, test_loader)\nprint(\"\\n=== FINAL TEST RESULTS ===\")\nprint(f\"Test Accuracy: {test_acc:.4f}\")\nprint(f\"Test F1 Score: {test_f1:.4f}\")\nprint(f\"Test Cohen's Kappa: {test_kappa:.4f}\")\nprint(f\"Test ROC AUC: {test_roc:.4f}\")\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-04-29T16:17:34.842134Z","iopub.execute_input":"2025-04-29T16:17:34.842356Z"}},"outputs":[],"execution_count":null}]}