{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":59093,"databundleVersionId":7469972,"sourceType":"competition"}],"dockerImageVersionId":30919,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:09:32.523605Z","iopub.execute_input":"2025-03-19T14:09:32.523944Z","iopub.status.idle":"2025-03-19T14:10:42.202213Z","shell.execute_reply.started":"2025-03-19T14:09:32.523901Z","shell.execute_reply":"2025-03-19T14:10:42.201323Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install efficientnet_pytorch","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:10:42.203243Z","iopub.execute_input":"2025-03-19T14:10:42.203717Z","iopub.status.idle":"2025-03-19T14:10:50.627984Z","shell.execute_reply.started":"2025-03-19T14:10:42.203683Z","shell.execute_reply":"2025-03-19T14:10:50.627131Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader, Dataset, random_split\nfrom torchvision import datasets, models, transforms\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\nimport warnings\nimport time\nimport cv2\nwarnings.filterwarnings('ignore')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:10:50.629601Z","iopub.execute_input":"2025-03-19T14:10:50.629864Z","iopub.status.idle":"2025-03-19T14:11:01.147585Z","shell.execute_reply.started":"2025-03-19T14:10:50.629839Z","shell.execute_reply":"2025-03-19T14:11:01.146921Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"start_time = time.time()\nBASE_DIR = \"/kaggle/input/hms-harmful-brain-activity-classification/\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:11:01.148696Z","iopub.execute_input":"2025-03-19T14:11:01.149078Z","iopub.status.idle":"2025-03-19T14:11:01.152426Z","shell.execute_reply.started":"2025-03-19T14:11:01.149044Z","shell.execute_reply":"2025-03-19T14:11:01.151709Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"brain_activities = ['Seizure', 'GPD', 'LRDA', 'Other', 'GRDA', 'LPD']\nactivity_mapping = {activity: idx for idx, activity in enumerate(brain_activities)}","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:11:01.153145Z","iopub.execute_input":"2025-03-19T14:11:01.153333Z","iopub.status.idle":"2025-03-19T14:11:01.187082Z","shell.execute_reply.started":"2025-03-19T14:11:01.153316Z","shell.execute_reply":"2025-03-19T14:11:01.186444Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = pd.read_csv(f\"{BASE_DIR}train.csv\")\n\ndf_toy = df.sample(frac=0.2, random_state=42)\n# Split 80% Train, 20% Temp (Validation + Test)\ntrain_df, temp_df = train_test_split(df_toy, test_size=0.4, random_state=42)\n\n# Split 10% Validation, 10% Test from Temp\nval_df, test_df = train_test_split(temp_df, test_size=0.5, random_state=42)\n\n# Save to CSV\ntrain_df.to_csv(\"train.csv\", index=False)\nval_df.to_csv(\"validation.csv\", index=False)\ntest_df.to_csv(\"test.csv\", index=False)\n\nprint(\"Splitting done! Train:\", len(train_df), \"Val:\", len(val_df), \"Test:\", len(test_df))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:12:58.853933Z","iopub.execute_input":"2025-03-19T14:12:58.854280Z","iopub.status.idle":"2025-03-19T14:12:59.004575Z","shell.execute_reply.started":"2025-03-19T14:12:58.854254Z","shell.execute_reply":"2025-03-19T14:12:59.003833Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class ChunkedBrainActivityDataset(Dataset):\n    def __init__(self, csv_file, base_dir, activity_mapping,md):\n        self.df = csv_file\n        self.base_dir = base_dir\n        self.activity_mapping = activity_mapping\n        self.resize_transform = transforms.Resize((224, 224))\n        self.md = md\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        spect_id, label, offset = self.df.iloc[idx][[\"spectrogram_id\", \"expert_consensus\", \"spectrogram_label_offset_seconds\"]]\n\n        temp_df = pd.read_parquet(f'{self.base_dir}/train_spectrograms/{spect_id}.parquet')\n        temp_df.drop(['time'], axis=1, inplace=True)\n\n        start = int(offset) // 2\n        temp_df = temp_df[start:start+300]\n        temp_df = np.log1p(temp_df)\n        temp_df /= temp_df.max()\n        temp_arr = np.nan_to_num(temp_df.to_numpy(), nan=1e-4)\n\n        # Use OpenCV to apply a colormap and convert to RGB\n        temp_arr_uint8 = np.uint8(255 * temp_arr)\n        rgb_image = cv2.applyColorMap(temp_arr_uint8, cv2.COLORMAP_JET)\n\n        # Normalize to [0, 1] and convert to tensor\n        rgb_image = rgb_image.astype(np.float32) / 255.0\n        rgb_image_tensor = torch.tensor(rgb_image).permute(2, 0, 1)  # (C, H, W)\n        rgb_image_tensor = self.resize_transform(rgb_image_tensor)\n            \n        y = self.activity_mapping[label]\n        y_tensor = torch.nn.functional.one_hot(torch.tensor(y, dtype=torch.long), num_classes=6).float()\n        \n        return rgb_image_tensor, y_tensor","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:13:00.067825Z","iopub.execute_input":"2025-03-19T14:13:00.068165Z","iopub.status.idle":"2025-03-19T14:13:00.074964Z","shell.execute_reply.started":"2025-03-19T14:13:00.068138Z","shell.execute_reply":"2025-03-19T14:13:00.074087Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Now create DataLoader with the chunked dataset\n# chunk_size = 1000  # Adjust chunk size according to memory constraints\n\ntrain_dataset = ChunkedBrainActivityDataset(csv_file=train_df, base_dir=BASE_DIR, activity_mapping=activity_mapping,md = \"lr\")\nval_dataset = ChunkedBrainActivityDataset(csv_file=val_df, base_dir=BASE_DIR, activity_mapping=activity_mapping,md = \"lr\")\ntest_dataset = ChunkedBrainActivityDataset(csv_file=test_df, base_dir=BASE_DIR, activity_mapping=activity_mapping,md = \"lr\")\n\ntrain_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, num_workers= 2, pin_memory=True, prefetch_factor=2)\nval_loader = DataLoader(val_dataset, batch_size=64, shuffle=False, num_workers= 2, pin_memory=True, prefetch_factor=2)\ntest_loader = DataLoader(test_dataset, batch_size=64, shuffle=False, num_workers= 2, pin_memory=True, prefetch_factor=2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:13:01.273510Z","iopub.execute_input":"2025-03-19T14:13:01.273818Z","iopub.status.idle":"2025-03-19T14:13:01.279391Z","shell.execute_reply.started":"2025-03-19T14:13:01.273790Z","shell.execute_reply":"2025-03-19T14:13:01.278590Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\n\nclass VAE(nn.Module):\n    def __init__(self, latent_dim=32):\n        super(VAE, self).__init__()\n        self.latent_dim = latent_dim\n        \n        # Encoder\n        self.encoder = nn.Sequential(\n            nn.Conv2d(3, 32, kernel_size=4, stride=2, padding=1),  # (224,224) → (112,112)\n            nn.ReLU(),\n            nn.Conv2d(32, 64, kernel_size=4, stride=2, padding=1),  # (112,112) → (56,56)\n            nn.ReLU(),\n            nn.Conv2d(64, 128, kernel_size=4, stride=2, padding=1),  # (56,56) → (28,28)\n            nn.ReLU(),\n            nn.Flatten()\n        )\n        \n        self.fc_mu = nn.Linear(128 * 28 * 28, latent_dim)  # Mean\n        self.fc_logvar = nn.Linear(128 * 28 * 28, latent_dim)  # Log-variance\n        \n        # Decoder\n        self.decoder_input = nn.Linear(latent_dim, 128 * 28 * 28)\n        self.decoder = nn.Sequential(\n            nn.ConvTranspose2d(128, 64, kernel_size=4, stride=2, padding=1),  # (28,28) → (56,56)\n            nn.ReLU(),\n            nn.ConvTranspose2d(64, 32, kernel_size=4, stride=2, padding=1),  # (56,56) → (112,112)\n            nn.ReLU(),\n            nn.ConvTranspose2d(32, 3, kernel_size=4, stride=2, padding=1),  # (112,112) → (224,224)\n            nn.Sigmoid()\n        )\n\n    def reparameterize(self, mu, logvar):\n        \"\"\"Reparameterization trick\"\"\"\n        std = torch.exp(0.5 * logvar)\n        eps = torch.randn_like(std)\n        return mu + eps * std\n\n    def forward(self, x):\n        x = self.encoder(x)\n        mu, logvar = self.fc_mu(x), self.fc_logvar(x)\n        z = self.reparameterize(mu, logvar)\n        \n        x = self.decoder_input(z).view(-1, 128, 28, 28)\n        recon_x = self.decoder(x)\n        \n        return recon_x, mu, logvar\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:13:04.757829Z","iopub.execute_input":"2025-03-19T14:13:04.758214Z","iopub.status.idle":"2025-03-19T14:13:04.768251Z","shell.execute_reply.started":"2025-03-19T14:13:04.758177Z","shell.execute_reply":"2025-03-19T14:13:04.767208Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Training setup\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nvae = VAE(latent_dim=32).to(device)\noptimizer = optim.Adam(vae.parameters(), lr=0.001)\n\ndef vae_loss(recon_x, x, mu, logvar):\n    \"\"\"VAE loss: reconstruction loss + KL divergence\"\"\"\n    recon_loss = F.mse_loss(recon_x, x, reduction='sum')\n    kl_div = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())\n    return recon_loss + kl_div\n\n# Training loop\nnum_epochs = 10\nfor epoch in range(num_epochs):\n    vae.train()\n    total_loss = 0\n\n    for images, _ in train_loader:\n        images = images.to(device)\n        optimizer.zero_grad()\n        \n        recon_x, mu, logvar = vae(images)\n        loss = vae_loss(recon_x, images, mu, logvar)\n        \n        loss.backward()\n        optimizer.step()\n        total_loss += loss.item()\n\n    print(f\"Epoch {epoch+1}/{num_epochs}, Loss: {total_loss / len(train_loader.dataset)}\")\n\n# Save trained VAE model\ntorch.save(vae.state_dict(), \"/kaggle/working/vae_model.pth\")\nprint(\"VAE Model Saved!\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:21:28.854613Z","iopub.execute_input":"2025-03-19T14:21:28.855005Z","iopub.status.idle":"2025-03-19T14:21:29.073373Z","shell.execute_reply.started":"2025-03-19T14:21:28.854972Z","shell.execute_reply":"2025-03-19T14:21:29.072380Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load trained VAE model\nvae.load_state_dict(torch.load(\"/kaggle/working/vae_model.pth\", map_location=device))\nvae.eval()\n\n# Function to get encoded features\ndef extract_latent_features(dataloader, model, device):\n    model.to(device)\n    features, labels = [], []\n\n    with torch.no_grad():\n        for images, targets in tqdm(dataloader, desc=\"Extracting Features\"):\n            images = images.to(device)\n            targets = targets.cpu().numpy()\n\n            _, mu, _ = model(images)  # Extract mean vector as features\n            encoded_features = mu.cpu().numpy()\n\n            features.append(encoded_features)\n            labels.append(targets)\n\n    features = np.vstack(features)\n    labels = np.vstack(labels)\n    return features, labels\n\n# Extract features for train, validation, and test sets\nX_train, y_train = extract_latent_features(train_loader, vae, device)\nX_val, y_val = extract_latent_features(val_loader, vae, device)\nX_test, y_test = extract_latent_features(test_loader, vae, device)\n\n# Convert one-hot labels to class indices\ny_train = np.argmax(y_train, axis=1)\ny_val = np.argmax(y_val, axis=1)\ny_test = np.argmax(y_test, axis=1)\n\n# Save extracted features\nnp.save(\"vae_train_features.npy\", X_train)\nnp.save(\"vae_train_labels.npy\", y_train)\nnp.save(\"vae_val_features.npy\", X_val)\nnp.save(\"vae_val_labels.npy\", y_val)\nnp.save(\"vae_test_features.npy\", X_test)\nnp.save(\"vae_test_labels.npy\", y_test)\nprint(\"Feature Extraction Done!\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:16:21.467948Z","iopub.execute_input":"2025-03-19T14:16:21.468291Z","iopub.status.idle":"2025-03-19T14:16:50.149963Z","shell.execute_reply.started":"2025-03-19T14:16:21.468252Z","shell.execute_reply":"2025-03-19T14:16:50.148697Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.linear_model import LogisticRegression\nfrom sklearn.metrics import accuracy_score, classification_report\n\n# Load extracted features\nX_train = np.load(\"vae_train_features.npy\")\ny_train = np.load(\"vae_train_labels.npy\")\nX_val = np.load(\"vae_val_features.npy\")\ny_val = np.load(\"vae_val_labels.npy\")\n\nX_test = np.load(\"vae_test_features.npy\")\ny_test = np.load(\"vae_test_labels.npy\")\n\n# Train logistic regression\nlr_model = LogisticRegression(max_iter=1000)\nlr_model.fit(X_train, y_train)\n\n# Evaluate on validation set\ny_val_pred = lr_model.predict(X_val)\nprint(\"Validation Accuracy:\", accuracy_score(y_val, y_val_pred))\nprint(classification_report(y_val, y_val_pred, target_names=brain_activities))\n\n# Evaluate on test set\ny_test_pred = lr_model.predict(X_test)\nprint(\"Test Accuracy:\", accuracy_score(y_test, y_test_pred))\nprint(classification_report(y_test, y_test_pred, target_names=brain_activities))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-19T14:17:28.209665Z","iopub.execute_input":"2025-03-19T14:17:28.210070Z","iopub.status.idle":"2025-03-19T14:17:28.589038Z","shell.execute_reply.started":"2025-03-19T14:17:28.210037Z","shell.execute_reply":"2025-03-19T14:17:28.588147Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}