{"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":"none","dataSources":[{"sourceId":52254,"databundleVersionId":8756537,"sourceType":"competition"},{"sourceId":6523471,"sourceType":"datasetVersion","datasetId":3771357},{"sourceId":7355410,"sourceType":"datasetVersion","datasetId":4271951},{"sourceId":7432254,"sourceType":"datasetVersion","datasetId":4325089}],"dockerImageVersionId":30635,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install nibabel","metadata":{"execution":{"iopub.status.busy":"2024-08-30T16:39:14.001155Z","iopub.execute_input":"2024-08-30T16:39:14.001707Z","iopub.status.idle":"2024-08-30T16:39:30.92978Z","shell.execute_reply.started":"2024-08-30T16:39:14.001666Z","shell.execute_reply":"2024-08-30T16:39:30.928176Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install monai","metadata":{"execution":{"iopub.status.busy":"2024-08-30T16:39:30.932182Z","iopub.execute_input":"2024-08-30T16:39:30.932596Z","iopub.status.idle":"2024-08-30T16:39:47.724472Z","shell.execute_reply.started":"2024-08-30T16:39:30.932557Z","shell.execute_reply":"2024-08-30T16:39:47.72297Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nfrom monai.networks.nets import densenet\n\nclass CustomDenseNet3DCNNClassifier(nn.Module):\n    def __init__(self, num_classes):\n        super(CustomDenseNet3DCNNClassifier, self).__init__()\n\n        # Use MONAI's DenseNet as a backbone\n        self.densenet = densenet.DenseNet264(spatial_dims=3, in_channels=1, out_channels=num_classes)\n        # Global average pooling to reduce spatial dimensions\n        self.global_avg_pooling = nn.AdaptiveAvgPool3d((1, 1, 1))\n\n    def forward(self, x):\n        # Forward pass through the DenseNet backbone\n        x = self.densenet(x)\n        print(x.shape)\n\n        # Check if the tensor has fewer than 4 dimensions\n#         if x.dim() < 4:\n#             # Add dimensions to make it at least 4-dimensional\n#             x = x.unsqueeze(-1).unsqueeze(-1).unsqueeze(-1)\n\n#         # Global average pooling\n#         x = self.global_avg_pooling(x)\n\n#         # Flatten the features\n#         x = x.view(x.size(0), -1)\n\n        return x\n\n# Define the model\nnum_classes = 14  # Adjust the number of classes based on your problem\nmodel_densenet = CustomDenseNet3DCNNClassifier(num_classes)\n\n# Move the model to the appropriate device\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel_densenet = model_densenet.to(device)\n\n# Create sample input tensors for DenseNet (modify this according to your data)\nbatch_images_densenet = torch.randn(8, 1, 128, 128, 128)  # Example input shape (1 channel for grayscale)\nbatch_images_densenet = batch_images_densenet.to(device)  # Move input tensors to device\n\n# Forward pass\nclassification_outputs_densenet = model_densenet(batch_images_densenet)\nprint(\"DenseNet Outputs:\", classification_outputs_densenet)\n","metadata":{"execution":{"iopub.status.busy":"2024-08-30T16:39:47.725973Z","iopub.execute_input":"2024-08-30T16:39:47.726383Z","iopub.status.idle":"2024-08-30T16:41:09.529212Z","shell.execute_reply.started":"2024-08-30T16:39:47.726343Z","shell.execute_reply":"2024-08-30T16:41:09.527694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport nibabel as nib\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nfrom sklearn.model_selection import KFold\nfrom sklearn import metrics\nfrom sklearn.metrics import precision_recall_fscore_support\nfrom sklearn.model_selection import train_test_split\nfrom scipy.ndimage import zoom\n\n# Custom Dataset class\nclass CustomDataset(Dataset):\n    def __init__(self, image_paths, labels, transform=None):\n        self.image_paths = image_paths\n        self.labels = labels\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.image_paths)\n\n    def __getitem__(self, idx):\n        image_path = self.image_paths[idx]\n        # Load 3D NIfTI image using nibabel\n        image = nib.load(image_path).get_fdata()\n\n        # Apply transformation if provided\n        if self.transform:\n            image = self.transform(image)\n\n        label = torch.tensor(self.labels[idx], dtype=torch.float32)\n        return image, label\n\n# Custom DenseNet model for 3D CNN classification\nclass CustomDenseNet3DCNNClassifier(nn.Module):\n    def __init__(self, num_classes):\n        super(CustomDenseNet3DCNNClassifier, self).__init__()\n        # Define your 3D CNN model here\n        # You can use Conv3D layers, pooling layers, and fully connected layers\n        self.conv1 = nn.Conv3d(1, 32, kernel_size=3, padding=1)\n        self.conv2 = nn.Conv3d(32, 64, kernel_size=3, padding=1)\n        self.fc1 = nn.Linear(64 * 16 * 16 * 16, 128)\n        self.fc2 = nn.Linear(128, num_classes)\n\n    def forward(self, x):\n        x = torch.relu(self.conv1(x))\n        x = torch.relu(self.conv2(x))\n        x = torch.flatten(x, start_dim=1)\n        x = torch.relu(self.fc1(x))\n        x = self.fc2(x)\n        return x\n\n# Function to move data to device\ndef move_data_to_device(data, device):\n    return data.to(torch.float32).to(device)\n\n# Training function\ndef train_model(model, train_loader, val_loader, num_epochs, class_optimizer, class_criterion, device, scenario):\n    print(f\"Training for Scenario {scenario}: {num_epochs} epochs\")\n    \n    for epoch in range(num_epochs):\n        model.train()\n        running_loss = 0.0\n        all_predicted_labels = []\n        all_batch_labels = []\n\n        for batch_images, batch_labels in train_loader:\n            batch_images = batch_images.to(torch.float32).to(device)\n            batch_labels = batch_labels.to(torch.float32).to(device)\n\n            # Add a singleton dimension for channels\n            batch_images = batch_images.unsqueeze(1)\n\n            # Forward pass for classification\n            classification_outputs = model(batch_images)\n            class_loss = class_criterion(classification_outputs, batch_labels)\n\n            # Backward and optimize\n            class_optimizer.zero_grad()\n            class_loss.backward()\n            class_optimizer.step()\n\n            classification_outputs = torch.sigmoid(classification_outputs)\n            predicted_labels = (classification_outputs > 0.5).float()\n\n            all_predicted_labels.append(predicted_labels.cpu().numpy())\n            all_batch_labels.append(batch_labels.cpu().numpy())\n\n        # Print training stats for each epoch\n        print(f\"Epoch {epoch+1}/{num_epochs} - Loss: {class_loss.item()}\")\n\n    print(f\"Finished training for Scenario {scenario}\")\n\n# Training configurations for each scenario\nscenarios = [\n    {'epochs': 100, 'batch_size': 16, 'learning_rate': 0.001},\n    {'epochs': 300, 'batch_size': 32, 'learning_rate': 0.01},\n    {'epochs': 500, 'batch_size': 64, 'learning_rate': 0.01},\n    {'epochs': 800, 'batch_size': 16, 'learning_rate': 0.1},\n]\n\n# Paths and settings\ncsv_file = '/kaggle/input/final-csv-abdominal/combined_and_shuffled_file (2).csv'\ndata = pd.read_csv(csv_file).head(2560)\ndata.columns = data.columns.str.strip()\n\n# Load data and prepare KFold\nkf = KFold(n_splits=4, shuffle=True, random_state=42)\nsplits = kf.split(data)\n\n# Device setup\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n\n# Loop over KFold splits\nfor fold, (train_idx, val_idx) in enumerate(splits):\n    train_data = data.iloc[train_idx]\n    val_data = data.iloc[val_idx]\n\n    train_paths = train_data['file_path'].values\n    train_labels = train_data[['bowel_healthy','bowel_injury','extravasation_healthy','extravasation_injury','kidney_healthy','kidney_low','kidney_high','liver_healthy','liver_low','liver_high','spleen_healthy','spleen_low','spleen_high','any_injury']].values\n\n    val_paths = val_data['file_path'].values\n    val_labels = val_data[['bowel_healthy','bowel_injury','extravasation_healthy','extravasation_injury','kidney_healthy','kidney_low','kidney_high','liver_healthy','liver_low','liver_high','spleen_healthy','spleen_low','spleen_high','any_injury']].values\n\n    for scenario_idx, scenario in enumerate(scenarios):\n        print(f\"Training Fold {fold+1}, Scenario {scenario_idx+1}\")\n        \n        # Adjust batch size and learning rate for each scenario\n        batch_size = scenario['batch_size']\n        learning_rate = scenario['learning_rate']\n        num_epochs = scenario['epochs']\n\n        # Define DataLoaders for training and validation\n        train_dataset = CustomDataset(train_paths, train_labels, transform=transforms.ToTensor())\n        val_dataset = CustomDataset(val_paths, val_labels, transform=transforms.ToTensor())\n\n        train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=4, drop_last=True)\n        val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False, num_workers=4)\n\n        # Instantiate the model and optimizer\n        model_class = CustomDenseNet3DCNNClassifier(num_classes=14).to(device)\n        class_optimizer = optim.Adam(model_class.parameters(), lr=learning_rate)\n        class_criterion = nn.BCEWithLogitsLoss()\n\n        # Train the model\n        train_model(model_class, train_loader, val_loader, num_epochs, class_optimizer, class_criterion, device, scenario_idx+1)\n        \n        # Save the model for each scenario\n        torch.save(model_class.state_dict(), f'/kaggle/working/densenet_scenario_{scenario_idx+1}_fold_{fold+1}.pth')\n","metadata":{"execution":{"iopub.status.busy":"2024-08-30T16:41:09.532536Z","iopub.execute_input":"2024-08-30T16:41:09.533683Z","iopub.status.idle":"2024-08-30T20:32:35.548147Z","shell.execute_reply.started":"2024-08-30T16:41:09.53363Z","shell.execute_reply":"2024-08-30T20:32:35.544683Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}