{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","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":30786,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import gc\nimport os\nimport random\nimport warnings\nimport numpy as np\nimport pandas as pd\nfrom IPython.display import display\n\n\nimport timm\nimport torch\nimport torch.nn as nn\nimport timm\n\n\nimport torch.optim as optim\nimport torch.nn.functional as F\nfrom torch.optim.lr_scheduler import CosineAnnealingLR\n\nimport torchvision.transforms as transforms\nwarnings.filterwarnings('ignore', category=Warning)\n\n# Reclaim memory no longer in use.\ngc.collect()","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-11-21T06:13:25.059790Z","iopub.execute_input":"2024-11-21T06:13:25.060174Z","iopub.status.idle":"2024-11-21T06:13:31.773850Z","shell.execute_reply.started":"2024-11-21T06:13:25.060131Z","shell.execute_reply":"2024-11-21T06:13:31.772955Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Configuration class containing hyperparameters and settings\nclass Config:\n    seed = 42 \n    image_transform = transforms.Resize((512,512))  \n    batch_size = 16\n    num_epochs = 2\n    num_folds = 2\n\n# Set the seed for reproducibility across multiple libraries\ndef set_seed(seed):\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = True\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n    random.seed(seed)\n    \nset_seed(Config.seed)\ndef calculate_accuracy(predictions, targets):\n    predictions_binary = (predictions > 0.6).float()\n    correct = (predictions_binary == targets).float()\n    accuracy = correct.mean().item()\n    return accuracy\n# Define the 'Kullback Leibler Divergence' loss function\ndef KL_loss(p,q):\n    epsilon=10**(-15)\n    p=torch.clip(p,epsilon,1-epsilon)\n    q = nn.functional.log_softmax(q,dim=1)\n    return torch.mean(torch.sum(p*(torch.log(p)-q),dim=1))\n\n# Reclaim memory no longer in use.\ngc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T06:13:31.775200Z","iopub.execute_input":"2024-11-21T06:13:31.775474Z","iopub.status.idle":"2024-11-21T06:13:31.954818Z","shell.execute_reply.started":"2024-11-21T06:13:31.775447Z","shell.execute_reply":"2024-11-21T06:13:31.953957Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load training data\ntrain_df = pd.read_csv(\"/kaggle/input/hms-harmful-brain-activity-classification/train.csv\")\n\n# Define labels for classification\nlabels = ['seizure', 'lpd', 'gpd', 'lrda', 'grda', 'other']\n\n# Initialize an empty DataFrame for storing features\ntrain_feats = pd.DataFrame()\n\n# Aggregate votes for each label and merge into train_feats DataFrame\nfor label in labels:\n    # Group by 'spectrogram_id' and sum the votes for the current label\n    group = train_df[f'{label}_vote'].groupby(train_df['spectrogram_id']).sum()\n\n    # Create a DataFrame from the grouped data\n    label_vote_sum = pd.DataFrame({'spectrogram_id': group.index, f'{label}_vote_sum': group.values})\n\n    # Initialize train_feats with the first label or merge subsequent labels\n    if label == 'seizure':\n        train_feats = label_vote_sum\n    else:\n        train_feats = train_feats.merge(label_vote_sum, on='spectrogram_id', how='left')\n\n# Add a column to sum all votes\ntrain_feats['total_vote'] = 0\nfor label in labels:\n    train_feats['total_vote'] += train_feats[f'{label}_vote_sum']\n\n# Calculate and store the normalized vote for each label\nfor label in labels:\n    train_feats[f'{label}_vote'] = train_feats[f'{label}_vote_sum'] / train_feats['total_vote']\n\n# Select relevant columns for the training features\nchoose_cols = ['spectrogram_id']\nfor label in labels:\n    choose_cols += [f'{label}_vote']\ntrain_feats = train_feats[choose_cols]\n\n# Add a column with the path to the spectrogram files\ntrain_feats['path'] = train_feats['spectrogram_id'].apply(lambda x: \"/kaggle/input/hms-harmful-brain-activity-classification/train_spectrograms/\" + str(x) + \".parquet\")\n\n# Reclaim memory no longer in use.\ngc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T06:13:31.955768Z","iopub.execute_input":"2024-11-21T06:13:31.956021Z","iopub.status.idle":"2024-11-21T06:13:32.370910Z","shell.execute_reply.started":"2024-11-21T06:13:31.955995Z","shell.execute_reply":"2024-11-21T06:13:32.370063Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def get_batch(paths, batch_size=Config.batch_size):\n    # Set a small epsilon to avoid division by zero\n    eps = 1e-6\n\n    # Initialize a list to store batch data\n    batch_data = []\n\n    # Iterate over each path in the provided paths\n    for path in paths:\n        # Read data from parquet file\n        data = pd.read_parquet(path[0])\n\n        # Fill missing values, remove time column, and transpose\n        data = data.fillna(-1).values[:, 1:].T\n\n        # Clip values and apply logarithmic transformation\n        data = np.clip(data, np.exp(-6), np.exp(10))\n        data = np.log(data)\n\n        # Normalize the data\n        data_mean = data.mean(axis=(0, 1))\n        data_std = data.std(axis=(0, 1))\n        data = (data - data_mean) / (data_std + eps)\n\n        # Convert data to a PyTorch tensor and apply transformations\n        data_tensor = torch.unsqueeze(torch.Tensor(data), dim=0)\n        data = Config.image_transform(data_tensor)\n\n        # Append the processed data to the batch_data list\n        batch_data.append(data)\n\n    # Stack all the batch data into a single tensor\n    batch_data = torch.stack(batch_data)\n\n    # Return the batch data\n    return batch_data","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T06:13:32.372604Z","iopub.execute_input":"2024-11-21T06:13:32.372882Z","iopub.status.idle":"2024-11-21T06:13:32.379077Z","shell.execute_reply.started":"2024-11-21T06:13:32.372855Z","shell.execute_reply":"2024-11-21T06:13:32.378298Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport torch\nimport matplotlib.pyplot as plt\nimport torchvision.transforms as transforms\n\ndef visualize_image_processing(data):\n   \n    plt.figure(figsize=(20, 5))\n    \n    \n    sample = data[0, 0, :, :]  \n    \n    # Original data\n    plt.subplot(1, 3, 1)\n    plt.title('Original Data')\n    plt.imshow(sample, cmap='viridis')\n    plt.colorbar()\n    \n    # Log-transformed data\n    log_data = np.log(np.clip(sample, np.exp(-6), np.exp(10)))\n    plt.subplot(1, 3, 2)\n    plt.title('Log Transformed')\n    plt.imshow(log_data, cmap='viridis')\n    plt.colorbar()\n    \n    # Normalized data\n    eps = 1e-6\n    data_mean = log_data.mean()\n    data_std = log_data.std()\n    normalized_data = (log_data - data_mean) / (data_std + eps)\n    \n    plt.subplot(1, 3, 3)\n    plt.title('Normalized Data')\n    plt.imshow(normalized_data, cmap='viridis')\n    plt.colorbar()\n    \n    plt.tight_layout()\n    plt.show()\ntotal_idx = np.arange(len(train_feats))\nnp.random.shuffle(total_idx)\n\nfor fold in range(1):\n    test_idx = total_idx[fold * len(total_idx) // Config.num_folds:(fold + 1) * len(total_idx) // Config.num_folds]\n    train_idx = np.array([idx for idx in total_idx if idx not in test_idx])\n    \n    for idx in range(0, 3):\n        train_idx1 = train_idx[idx:idx + 3]\n        train_X1_path = train_feats[['path']].iloc[train_idx1].values\n        train_X1 = get_batch(train_X1_path, batch_size=3)\n        visualize_image_processing(train_X1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T06:13:32.379976Z","iopub.execute_input":"2024-11-21T06:13:32.380298Z","iopub.status.idle":"2024-11-21T06:13:36.191896Z","shell.execute_reply.started":"2024-11-21T06:13:32.380272Z","shell.execute_reply":"2024-11-21T06:13:36.190993Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport torch\nimport torch.optim as optim\nimport torch.nn.functional as F\nimport timm\nimport gc\nimport matplotlib.pyplot as plt\n\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\nprint(f\"Using device: {device}\")\n\ntotal_idx = np.arange(len(train_feats))\nnp.random.shuffle(total_idx)\n\ngc.collect()\n\n# Track accuracies for visualization\nall_train_losses = []\nall_test_losses = []\nall_train_accuracies = []\nall_test_accuracies = []\n\nfor fold in range(Config.num_folds):\n    test_idx = total_idx[fold * len(total_idx) // Config.num_folds:(fold + 1) * len(total_idx) // Config.num_folds]\n    train_idx = np.array([idx for idx in total_idx if idx not in test_idx])\n    \n    model = timm.create_model('efficientnet_b2', pretrained=True, num_classes=6, in_chans=1)\n    model.to(device)\n    \n    optimizer = optim.AdamW(model.parameters(), lr=0.001, betas=(0.5, 0.999), weight_decay=0.01)\n    scheduler = CosineAnnealingLR(optimizer, T_max=Config.num_epochs)\n    \n    fold_train_losses = []\n    fold_test_losses = []\n    fold_train_accuracies = []\n    fold_test_accuracies = []\n    \n    print(f\"Starting training for fold {fold + 1}\")\n    \n    for epoch in range(Config.num_epochs):\n        # Training phase\n        model.train()\n        train_loss = []\n        train_acc = []\n        \n        random_num = np.arange(len(train_idx))\n        np.random.shuffle(random_num)\n        train_idx = train_idx[random_num]\n        \n        for idx in range(0, len(train_idx), Config.batch_size):\n            optimizer.zero_grad()\n            \n            train_idx1 = train_idx[idx:idx + Config.batch_size]\n            train_X1_path = train_feats[['path']].iloc[train_idx1].values\n            train_X1 = get_batch(train_X1_path, batch_size=Config.batch_size)\n            \n            train_y1 = train_feats[['seizure_vote', 'lpd_vote', 'gpd_vote', 'lrda_vote', 'grda_vote', 'other_vote']].iloc[train_idx1].values\n            train_y1 = torch.Tensor(train_y1)\n            \n            train_pred = model(train_X1.to(device))\n            loss = KL_loss(train_y1.to(device), train_pred)\n            \n            loss.backward()\n            optimizer.step()\n            \n            train_loss.append(loss.item())\n            train_acc.append(calculate_accuracy(train_pred.cpu(), train_y1))\n        \n        epoch_train_loss = np.min(train_loss)\n        epoch_train_acc = np.max(train_acc)\n        fold_train_losses.append(epoch_train_loss)\n        fold_train_accuracies.append(epoch_train_acc)\n        \n        print(f\"Epoch {epoch + 1}: Train Loss = {epoch_train_loss:.2f}, Train Accuracy = {epoch_train_acc:.2f}\")\n        \n        scheduler.step()\n        \n        # Validation phase\n        model.eval()\n        test_loss = []\n        test_acc = []\n        \n        with torch.no_grad():\n            for idx in range(0, len(test_idx), Config.batch_size):\n                test_idx1 = test_idx[idx:idx + Config.batch_size]\n                test_X1_path = train_feats[['path']].iloc[test_idx1].values\n                test_X1 = get_batch(test_X1_path, batch_size=Config.batch_size)\n                test_y1 = train_feats[['seizure_vote', 'lpd_vote', 'gpd_vote', 'lrda_vote', 'grda_vote', 'other_vote']].iloc[test_idx1].values\n                test_y1 = torch.Tensor(test_y1)\n                \n                test_pred = model(test_X1.to(device))\n                loss = KL_loss(test_y1.to(device), test_pred)\n                \n                test_loss.append(loss.item())\n                test_acc.append(calculate_accuracy(test_pred.cpu(), test_y1))\n        \n        epoch_test_loss = np.min(test_loss)\n        epoch_test_acc = np.max(test_acc)\n        fold_test_losses.append(epoch_test_loss)\n        fold_test_accuracies.append(epoch_test_acc)\n        \n        print(f\"Epoch {epoch + 1}: Test Loss = {epoch_test_loss:.2f}, Test Accuracy = {epoch_test_acc:.2f}\")\n        \n        gc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T06:13:36.192882Z","iopub.execute_input":"2024-11-21T06:13:36.193161Z","iopub.status.idle":"2024-11-21T06:52:20.231766Z","shell.execute_reply.started":"2024-11-21T06:13:36.193134Z","shell.execute_reply":"2024-11-21T06:52:20.229976Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport torch\nimport torch.optim as optim\nimport torch.nn.functional as F\nimport timm\nimport gc\nimport matplotlib.pyplot as plt\n\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\nprint(f\"Using device: {device}\")\n\ntotal_idx = np.arange(len(train_feats))\nnp.random.shuffle(total_idx)\n\ngc.collect()\n\n# Track accuracies for visualization\nall_train_losses = []\nall_test_losses = []\nall_train_accuracies = []\nall_test_accuracies = []\n\nfor fold in range(Config.num_folds):\n    test_idx = total_idx[fold * len(total_idx) // Config.num_folds:(fold + 1) * len(total_idx) // Config.num_folds]\n    train_idx = np.array([idx for idx in total_idx if idx not in test_idx])\n    \n    model = timm.create_model('resnet34d', pretrained=True, num_classes=6, in_chans=1)\n    model.to(device)\n    \n    optimizer = optim.AdamW(model.parameters(), lr=0.001, betas=(0.5, 0.999), weight_decay=0.01)\n    scheduler = CosineAnnealingLR(optimizer, T_max=Config.num_epochs)\n    \n    fold_train_losses = []\n    fold_test_losses = []\n    fold_train_accuracies = []\n    fold_test_accuracies = []\n    \n    print(f\"Starting training for fold {fold + 1}\")\n    \n    for epoch in range(Config.num_epochs):\n        # Training phase\n        model.train()\n        train_loss = []\n        train_acc = []\n        \n        random_num = np.arange(len(train_idx))\n        np.random.shuffle(random_num)\n        train_idx = train_idx[random_num]\n        \n        for idx in range(0, len(train_idx), Config.batch_size):\n            optimizer.zero_grad()\n            \n            train_idx1 = train_idx[idx:idx + Config.batch_size]\n            train_X1_path = train_feats[['path']].iloc[train_idx1].values\n            train_X1 = get_batch(train_X1_path, batch_size=Config.batch_size)\n            \n            train_y1 = train_feats[['seizure_vote', 'lpd_vote', 'gpd_vote', 'lrda_vote', 'grda_vote', 'other_vote']].iloc[train_idx1].values\n            train_y1 = torch.Tensor(train_y1)\n            \n            train_pred = model(train_X1.to(device))\n            loss = KL_loss(train_y1.to(device), train_pred)\n            \n            loss.backward()\n            optimizer.step()\n            \n            train_loss.append(loss.item())\n            train_acc.append(calculate_accuracy(train_pred.cpu(), train_y1))\n        \n        epoch_train_loss = np.min(train_loss)\n        epoch_train_acc = np.max(train_acc)\n        fold_train_losses.append(epoch_train_loss)\n        fold_train_accuracies.append(epoch_train_acc)\n        \n        print(f\"Epoch {epoch + 1}: Train Loss = {epoch_train_loss:.2f}, Train Accuracy = {epoch_train_acc:.2f}\")\n        \n        scheduler.step()\n        \n        # Validation phase\n        model.eval()\n        test_loss = []\n        test_acc = []\n        \n        with torch.no_grad():\n            for idx in range(0, len(test_idx), Config.batch_size):\n                test_idx1 = test_idx[idx:idx + Config.batch_size]\n                test_X1_path = train_feats[['path']].iloc[test_idx1].values\n                test_X1 = get_batch(test_X1_path, batch_size=Config.batch_size)\n                test_y1 = train_feats[['seizure_vote', 'lpd_vote', 'gpd_vote', 'lrda_vote', 'grda_vote', 'other_vote']].iloc[test_idx1].values\n                test_y1 = torch.Tensor(test_y1)\n                \n                test_pred = model(test_X1.to(device))\n                loss = KL_loss(test_y1.to(device), test_pred)\n                \n                test_loss.append(loss.item())\n                test_acc.append(calculate_accuracy(test_pred.cpu(), test_y1))\n        \n        epoch_test_loss = np.min(test_loss)\n        epoch_test_acc = np.max(test_acc)\n        fold_test_losses.append(epoch_test_loss)\n        fold_test_accuracies.append(epoch_test_acc)\n        \n        print(f\"Epoch {epoch + 1}: Test Loss = {epoch_test_loss:.2f}, Test Accuracy = {epoch_test_acc:.2f}\")\n        \n        gc.collect()","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}