{"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":"import os\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nimport pydicom\n\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import models, transforms\n\nfrom sklearn.metrics import accuracy_score, f1_score, cohen_kappa_score, roc_auc_score, roc_curve\n\n# ========== CONFIGURATION ==========\nDATA_DIR = \"/kaggle/input/rsna-miccai-brain-tumor-radiogenomic-classification\"\nTRAIN_DIR = os.path.join(DATA_DIR, \"train\")\nLABELS_CSV = os.path.join(DATA_DIR, \"train_labels.csv\")\nDEVICE = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nEPOCHS = 3\nBATCH_SIZE = 8\n\n# ========== LOAD LABELS ==========\nlabels_df = pd.read_csv(LABELS_CSV)\nlabels_df[\"BraTS21ID\"] = labels_df[\"BraTS21ID\"].astype(str).str.zfill(5)\n\n# ========== DATASET ==========\nclass BrainMRIDataset(Dataset):\n    def __init__(self, patient_ids, labels, root_dir, transform=None):\n        self.patient_ids = patient_ids\n        self.labels = labels\n        self.root_dir = root_dir\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.patient_ids)\n\n    def __getitem__(self, idx):\n        patient_id = self.patient_ids[idx]\n        label = self.labels[idx]\n\n        flair_dir = os.path.join(self.root_dir, patient_id, \"FLAIR\")\n        flair_files = sorted([f for f in os.listdir(flair_dir) if f.endswith(\".dcm\")])\n        mid_file = flair_files[len(flair_files) // 2]\n        dcm_path = os.path.join(flair_dir, mid_file)\n\n        dcm = pydicom.dcmread(dcm_path)\n        img = dcm.pixel_array\n        img = Image.fromarray(img).convert(\"RGB\")\n\n        if self.transform:\n            img = self.transform(img)\n\n        return img, torch.tensor(label, dtype=torch.float32)\n\n# ========== TRANSFORMS ==========\ntransform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n    transforms.Normalize([0.485, 0.456, 0.406],\n                         [0.229, 0.224, 0.225])\n])\n\n# ========== DATA SPLIT ==========\nsubset_df = labels_df.sample(n=300, random_state=42).reset_index(drop=True)\ntrain_df = subset_df.sample(frac=0.7, random_state=42)\ntemp_df = subset_df.drop(train_df.index)\nval_df = temp_df.sample(frac=0.5, random_state=42)\ntest_df = temp_df.drop(val_df.index)\n\ntrain_ds = BrainMRIDataset(train_df[\"BraTS21ID\"].tolist(), train_df[\"MGMT_value\"].tolist(), TRAIN_DIR, transform)\nval_ds = BrainMRIDataset(val_df[\"BraTS21ID\"].tolist(), val_df[\"MGMT_value\"].tolist(), TRAIN_DIR, transform)\ntest_ds = BrainMRIDataset(test_df[\"BraTS21ID\"].tolist(), test_df[\"MGMT_value\"].tolist(), TRAIN_DIR, transform)\n\ntrain_loader = DataLoader(train_ds, batch_size=BATCH_SIZE, shuffle=True)\nval_loader = DataLoader(val_ds, batch_size=BATCH_SIZE, shuffle=False)\ntest_loader = DataLoader(test_ds, batch_size=BATCH_SIZE, shuffle=False)\n\n# ========== MODEL ==========\nmodel = models.efficientnet_b0(pretrained=True)\nmodel.classifier[1] = nn.Linear(model.classifier[1].in_features, 1)\nmodel = model.to(DEVICE)\n\n# ========== TRAIN ==========\ncriterion = nn.BCEWithLogitsLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=1e-4)\n\nfor epoch in range(EPOCHS):\n    model.train()\n    running_loss = 0.0\n    for imgs, labels in train_loader:\n        imgs, labels = imgs.to(DEVICE), labels.unsqueeze(1).to(DEVICE)\n        outputs = model(imgs)\n        loss = criterion(outputs, labels)\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n        running_loss += loss.item()\n    avg_loss = running_loss / len(train_loader)\n    print(f\"Epoch [{epoch+1}/{EPOCHS}] - Loss: {avg_loss:.4f}\")\n\n# ========== EVALUATION ==========\ndef evaluate(loader):\n    model.eval()\n    y_true, y_pred, y_prob = [], [], []\n    with torch.no_grad():\n        for imgs, labels in loader:\n            imgs = imgs.to(DEVICE)\n            outputs = model(imgs)\n            probs = torch.sigmoid(outputs).cpu().numpy()\n            preds = (probs > 0.5).astype(int).flatten()\n            y_true.extend(labels.numpy())\n            y_pred.extend(preds)\n            y_prob.extend(probs.flatten())\n    acc = accuracy_score(y_true, y_pred)\n    f1 = f1_score(y_true, y_pred)\n    kappa = cohen_kappa_score(y_true, y_pred)\n    auc = roc_auc_score(y_true, y_prob)\n    return acc, f1, kappa, auc, y_true, y_prob\n\nval_results = evaluate(val_loader)\ntest_results = evaluate(test_loader)\n\nprint(f\"\\nValidation - Accuracy: {val_results[0]:.4f}, F1: {val_results[1]:.4f}, Kappa: {val_results[2]:.4f}, AUC: {val_results[3]:.4f}\")\nprint(f\"Test      - Accuracy: {test_results[0]:.4f}, F1: {test_results[1]:.4f}, Kappa: {test_results[2]:.4f}, AUC: {test_results[3]:.4f}\")\n\n# ========== ROC CURVE ==========\nfpr, tpr, _ = roc_curve(test_results[4], test_results[5])\nplt.figure()\nplt.plot(fpr, tpr, label='ROC Curve')\nplt.xlabel('False Positive Rate')\nplt.ylabel('True Positive Rate')\nplt.title('Test ROC Curve')\nplt.legend()\nplt.grid()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T20:22:49.421183Z","iopub.execute_input":"2025-05-07T20:22:49.421497Z","iopub.status.idle":"2025-05-07T20:24:35.837611Z","shell.execute_reply.started":"2025-05-07T20:22:49.421477Z","shell.execute_reply":"2025-05-07T20:24:35.836677Z"}},"outputs":[],"execution_count":null}]}