{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":29653,"databundleVersionId":2420395,"sourceType":"competition"}],"dockerImageVersionId":30699,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install -q pydicom tensorflow\n\n# ✅ Imports\nimport os\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport pydicom\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import f1_score, cohen_kappa_score, roc_auc_score, roc_curve, auc\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\n\n# Load RSNA-MICCAI Dataset\nlabels_df = pd.read_csv('/kaggle/input/rsna-miccai-brain-tumor-radiogenomic-classification/train_labels.csv')\ntrain_path = '/kaggle/input/rsna-miccai-brain-tumor-radiogenomic-classification/train/'\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2025-05-07T22:34:22.148641Z","iopub.execute_input":"2025-05-07T22:34:22.149013Z","iopub.status.idle":"2025-05-07T22:34:50.081660Z","shell.execute_reply.started":"2025-05-07T22:34:22.148969Z","shell.execute_reply":"2025-05-07T22:34:50.080974Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\ndef load_image(patient_id, img_size=(128, 128)):\n    folder = os.path.join(train_path, str(patient_id).zfill(5), \"T1w\")\n    if not os.path.exists(folder): return None\n    files = sorted(os.listdir(folder))\n    if len(files) == 0: return None\n    path = os.path.join(folder, files[len(files)//2])\n    dcm = pydicom.dcmread(path)\n    img = dcm.pixel_array\n    img = cv2.resize(img, img_size)\n    img = img / 255.0\n    return np.expand_dims(img, -1)\n\nX, y = [], []\nfor _, row in labels_df.iterrows():\n    img = load_image(row['BraTS21ID'])\n    if img is not None:\n        X.append(img)\n        y.append(row['MGMT_value'])\n\nX = np.array(X)\ny = np.array(y)\n\n# === Train/Val/Test Split ===\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)\nX_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.25, stratify=y_train, random_state=42)\n","metadata":{"execution":{"iopub.status.busy":"2025-05-07T22:34:50.082884Z","iopub.execute_input":"2025-05-07T22:34:50.083201Z","iopub.status.idle":"2025-05-07T22:35:10.455611Z","shell.execute_reply.started":"2025-05-07T22:34:50.083170Z","shell.execute_reply":"2025-05-07T22:35:10.454908Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Define Swin Transformer Components\ninput_shape = (128, 128, 1)\npatch_size = 4\nembed_dim = 64\nnum_heads = 4\nwindow_size = 4\nmlp_dim = 128\ndropout_rate = 0.1\n\nclass WindowAttention(layers.Layer):\n    def __init__(self, dim, num_heads, window_size):\n        super().__init__()\n        self.dim = dim\n        self.num_heads = num_heads\n        self.window_size = window_size\n        self.scale = (dim // num_heads) ** -0.5\n        self.qkv = layers.Dense(dim * 3)\n        self.proj = layers.Dense(dim)\n\n    def call(self, x):\n        B, N, C = tf.shape(x)[0], tf.shape(x)[1], tf.shape(x)[2]\n        qkv = self.qkv(x)\n        qkv = tf.reshape(qkv, [B, N, 3, self.num_heads, C // self.num_heads])\n        qkv = tf.transpose(qkv, [2, 0, 3, 1, 4])\n        q, k, v = qkv[0], qkv[1], qkv[2]\n        attn = tf.matmul(q, k, transpose_b=True) * self.scale\n        attn = tf.nn.softmax(attn, axis=-1)\n        out = tf.matmul(attn, v)\n        out = tf.transpose(out, [0, 2, 1, 3])\n        out = tf.reshape(out, [B, N, C])\n        return self.proj(out)\n","metadata":{"execution":{"iopub.status.busy":"2025-05-07T22:35:10.457894Z","iopub.execute_input":"2025-05-07T22:35:10.458758Z","iopub.status.idle":"2025-05-07T22:35:10.466415Z","shell.execute_reply.started":"2025-05-07T22:35:10.458722Z","shell.execute_reply":"2025-05-07T22:35:10.465438Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\ndef swin_block(x, dim, num_heads, window_size, mlp_dim):\n    shortcut = x\n    x = layers.LayerNormalization(epsilon=1e-5)(x)\n    x = WindowAttention(dim, num_heads, window_size)(x)\n    x = layers.Add()([shortcut, x])\n    shortcut2 = x\n    x = layers.LayerNormalization(epsilon=1e-5)(x)\n    x = layers.Dense(mlp_dim, activation='gelu')(x)\n    x = layers.Dropout(dropout_rate)(x)\n    x = layers.Dense(dim)(x)\n    x = layers.Dropout(dropout_rate)(x)\n    return layers.Add()([shortcut2, x])\n\ndef patch_embedding(inputs, patch_size, embed_dim):\n    x = layers.Conv2D(embed_dim, kernel_size=patch_size, strides=patch_size)(inputs)\n    x = layers.Reshape((-1, embed_dim))(x)\n    return x\n\ndef build_swin_model():\n    inputs = keras.Input(shape=input_shape)\n    x = patch_embedding(inputs, patch_size, embed_dim)\n    for _ in range(2):\n        x = swin_block(x, embed_dim, num_heads, window_size, mlp_dim)\n    x = layers.LayerNormalization(epsilon=1e-5)(x)\n    x = layers.GlobalAveragePooling1D()(x)\n    x = layers.Dense(mlp_dim, activation=\"gelu\")(x)\n    x = layers.Dropout(dropout_rate)(x)\n    outputs = layers.Dense(1, activation=\"sigmoid\")(x)\n    return keras.Model(inputs, outputs)\n","metadata":{"execution":{"iopub.status.busy":"2025-05-07T22:35:10.467424Z","iopub.execute_input":"2025-05-07T22:35:10.467754Z","iopub.status.idle":"2025-05-07T22:35:10.486325Z","shell.execute_reply.started":"2025-05-07T22:35:10.467711Z","shell.execute_reply":"2025-05-07T22:35:10.485506Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Compile and Train\nswin_model = build_swin_model()\nswin_model.compile(optimizer=tf.keras.optimizers.Adam(1e-4),\n                   loss=\"binary_crossentropy\",\n                   metrics=[\"accuracy\"])\n\nearly_stop = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)\nhistory = swin_model.fit(X_train, y_train,\n                         validation_data=(X_val, y_val),\n                         epochs=30,\n                         batch_size=16,\n                         callbacks=[early_stop],\n                         verbose=1)\n","metadata":{"execution":{"iopub.status.busy":"2025-05-07T22:35:10.487175Z","iopub.execute_input":"2025-05-07T22:35:10.487411Z","iopub.status.idle":"2025-05-07T22:35:44.980650Z","shell.execute_reply.started":"2025-05-07T22:35:10.487384Z","shell.execute_reply":"2025-05-07T22:35:44.979752Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Evaluate \ntest_loss, test_acc = swin_model.evaluate(X_test, y_test, verbose=0)\ny_pred_prob = swin_model.predict(X_test)\ny_pred = (y_pred_prob > 0.5).astype(int)\n\ntrain_acc = history.history['accuracy'][-1]\nval_acc = history.history['val_accuracy'][-1]\nf1 = f1_score(y_test, y_pred)\nkappa = cohen_kappa_score(y_test, y_pred)\nroc_auc = roc_auc_score(y_test, y_pred_prob)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T22:35:44.981999Z","iopub.execute_input":"2025-05-07T22:35:44.982651Z","iopub.status.idle":"2025-05-07T22:35:46.014254Z","shell.execute_reply.started":"2025-05-07T22:35:44.982615Z","shell.execute_reply":"2025-05-07T22:35:46.013138Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(f\"Training Accuracy: {train_acc:.4f}\")\nprint(f\"Validation Accuracy: {val_acc:.4f}\")\nprint(f\"Test Accuracy: {test_acc:.4f}\")\nprint(f\"F1 Score: {f1:.4f}\")\nprint(f\"Cohen's Kappa: {kappa:.4f}\")\nprint(f\"AUC: {roc_auc:.4f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T22:35:46.015502Z","iopub.execute_input":"2025-05-07T22:35:46.015842Z","iopub.status.idle":"2025-05-07T22:35:46.021308Z","shell.execute_reply.started":"2025-05-07T22:35:46.015817Z","shell.execute_reply":"2025-05-07T22:35:46.020233Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Plots\nplt.figure(figsize=(14, 5))\nplt.subplot(1, 2, 1)\nplt.plot(history.history['accuracy'], label='Train Acc')\nplt.plot(history.history['val_accuracy'], label='Val Acc')\nplt.title('Accuracy')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.legend()\n\nplt.subplot(1, 2, 2)\nplt.plot(history.history['loss'], label='Train Loss')\nplt.plot(history.history['val_loss'], label='Val Loss')\nplt.title('Loss')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.legend()\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T22:35:46.022547Z","iopub.execute_input":"2025-05-07T22:35:46.022893Z","iopub.status.idle":"2025-05-07T22:35:46.567156Z","shell.execute_reply.started":"2025-05-07T22:35:46.022864Z","shell.execute_reply":"2025-05-07T22:35:46.566299Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fpr, tpr, _ = roc_curve(y_test, y_pred_prob)\nroc_val = auc(fpr, tpr)\nplt.figure()\nplt.plot(fpr, tpr, label=f'ROC (AUC = {roc_val:.2f})')\nplt.plot([0, 1], [0, 1], linestyle='--', color='gray')\nplt.xlabel('False Positive Rate')\nplt.ylabel('True Positive Rate')\nplt.title('ROC Curve - Swin Transformer (New Method III)')\nplt.legend()\nplt.grid()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-07T22:35:46.569257Z","iopub.execute_input":"2025-05-07T22:35:46.569508Z","iopub.status.idle":"2025-05-07T22:35:46.746156Z","shell.execute_reply.started":"2025-05-07T22:35:46.569487Z","shell.execute_reply":"2025-05-07T22:35:46.745329Z"}},"outputs":[],"execution_count":null}]}