{"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":14774,"databundleVersionId":875431,"sourceType":"competition"}],"dockerImageVersionId":30839,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# Import necessary libraries\nimport os\nimport torch\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score, roc_curve\nfrom torchvision import transforms\nfrom torch.utils.data import DataLoader\nfrom timm import create_model\nfrom torchvision.datasets import VisionDataset\nfrom PIL import Image\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-29T07:46:30.80571Z","iopub.execute_input":"2025-01-29T07:46:30.806116Z","iopub.status.idle":"2025-01-29T07:46:41.182241Z","shell.execute_reply.started":"2025-01-29T07:46:30.806081Z","shell.execute_reply":"2025-01-29T07:46:41.181274Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Define dataset paths (adjust for Kaggle environment)\ndataset_path = \"/kaggle/input/aptos2019-blindness-detection\"  # Change as per dataset name\ntrain_images_path = os.path.join(dataset_path, \"train_images\")\ntest_images_path = os.path.join(dataset_path, \"test_images\")\ntrain_csv_path = os.path.join(dataset_path, \"train.csv\")\ntest_csv_path = os.path.join(dataset_path, \"test.csv\")\n\n# Load the CSV files\ntrain_df = pd.read_csv(train_csv_path)\ntest_df = pd.read_csv(test_csv_path)\n\n# Print dataset information\nprint(f\"Number of training samples: {len(train_df)}\")\nprint(f\"Number of test samples: {len(test_df)}\")\nprint(f\"Training classes: {train_df['diagnosis'].unique()}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-29T07:46:49.015518Z","iopub.execute_input":"2025-01-29T07:46:49.015905Z","iopub.status.idle":"2025-01-29T07:46:49.034046Z","shell.execute_reply.started":"2025-01-29T07:46:49.01585Z","shell.execute_reply":"2025-01-29T07:46:49.032892Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Data preprocessing\ntransform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n])\n\n# Create custom dataset for APTOS\nclass APTOSDataset(VisionDataset):\n    def __init__(self, df, images_dir, transform=None):\n        super(APTOSDataset, self).__init__(images_dir, transform=transform)\n        self.df = df\n        self.images_dir = images_dir\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        img_name = self.df.iloc[idx, 0] + \".png\"  # Image file name\n        img_path = os.path.join(self.images_dir, img_name)\n        image = Image.open(img_path).convert(\"RGB\")\n        label = self.df.iloc[idx, 1]  # Diagnosis label\n\n        if self.transform:\n            image = self.transform(image)\n\n        return image, label\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-29T07:46:51.735885Z","iopub.execute_input":"2025-01-29T07:46:51.736271Z","iopub.status.idle":"2025-01-29T07:46:51.744132Z","shell.execute_reply.started":"2025-01-29T07:46:51.736243Z","shell.execute_reply":"2025-01-29T07:46:51.743012Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Prepare datasets and dataloaders\ntrain_dataset = APTOSDataset(train_df, train_images_path, transform=transform)\ntrain_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)\n\n# Placeholder validation set (split from train_df if necessary)\nval_dataset = APTOSDataset(train_df.sample(frac=0.2, random_state=42), train_images_path, transform=transform)\nval_loader = DataLoader(val_dataset, batch_size=32, shuffle=False)\n\n# Print dataset details\nprint(f\"Train Dataset Size: {len(train_dataset)}\")\nprint(f\"Validation Dataset Size: {len(val_dataset)}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-29T07:46:54.559093Z","iopub.execute_input":"2025-01-29T07:46:54.559441Z","iopub.status.idle":"2025-01-29T07:46:54.57446Z","shell.execute_reply.started":"2025-01-29T07:46:54.559414Z","shell.execute_reply":"2025-01-29T07:46:54.573501Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load pretrained Vision Transformer (ViT)\nnum_classes = train_df['diagnosis'].nunique()\nvit_model = create_model('vit_base_patch16_224', pretrained=True)\nvit_model.head = torch.nn.Linear(vit_model.head.in_features, num_classes)\n\n# Move model to GPU if available\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nvit_model = vit_model.to(device)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-29T07:46:57.454107Z","iopub.execute_input":"2025-01-29T07:46:57.454448Z","iopub.status.idle":"2025-01-29T07:47:02.030239Z","shell.execute_reply.started":"2025-01-29T07:46:57.454421Z","shell.execute_reply":"2025-01-29T07:47:02.029055Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load pretrained Swin Transformer\nswin_model = create_model('swin_base_patch4_window7_224', pretrained=True)\nswin_model.head = torch.nn.Linear(swin_model.head.in_features, num_classes)\n\n# Move model to GPU\nswin_model = swin_model.to(device)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-29T07:47:04.056337Z","iopub.execute_input":"2025-01-29T07:47:04.056689Z","iopub.status.idle":"2025-01-29T07:47:08.703973Z","shell.execute_reply.started":"2025-01-29T07:47:04.056662Z","shell.execute_reply":"2025-01-29T07:47:08.702842Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Define loss and optimizer for both models\ncriterion = torch.nn.CrossEntropyLoss()\n\n# Optimizers for ViT and Swin\nvit_optimizer = torch.optim.Adam(vit_model.parameters(), lr=1e-4)\nswin_optimizer = torch.optim.Adam(swin_model.parameters(), lr=1e-4)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-29T07:47:10.04404Z","iopub.execute_input":"2025-01-29T07:47:10.044395Z","iopub.status.idle":"2025-01-29T07:47:10.052199Z","shell.execute_reply.started":"2025-01-29T07:47:10.044367Z","shell.execute_reply":"2025-01-29T07:47:10.050901Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Define training function\ndef train_model(model, dataloader, optimizer, criterion, device):\n    model.train()\n    total_loss = 0\n    for images, labels in dataloader:\n        images, labels = images.to(device), labels.to(device)\n        optimizer.zero_grad()\n        outputs = model(images)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n        total_loss += loss.item()\n    return total_loss / len(dataloader)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-29T07:47:13.408308Z","iopub.execute_input":"2025-01-29T07:47:13.408696Z","iopub.status.idle":"2025-01-29T07:47:13.414521Z","shell.execute_reply.started":"2025-01-29T07:47:13.40866Z","shell.execute_reply":"2025-01-29T07:47:13.413163Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Define evaluation function\ndef evaluate_model(model, dataloader, criterion, device):\n    model.eval()\n    y_true, y_pred, y_proba = [], [], []\n    total_loss = 0\n    with torch.no_grad():\n        for images, labels in dataloader:\n            images, labels = images.to(device), labels.to(device)\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            total_loss += loss.item()\n            y_true.extend(labels.cpu().numpy())\n            y_pred.extend(outputs.argmax(dim=1).cpu().numpy())\n            y_proba.extend(torch.softmax(outputs, dim=1).cpu().numpy())\n    return total_loss / len(dataloader), y_true, y_pred, y_proba\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-29T07:47:18.298761Z","iopub.execute_input":"2025-01-29T07:47:18.299182Z","iopub.status.idle":"2025-01-29T07:47:18.305632Z","shell.execute_reply.started":"2025-01-29T07:47:18.299145Z","shell.execute_reply":"2025-01-29T07:47:18.304539Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Metrics calculation\ndef calculate_metrics(y_true, y_pred, y_proba):\n    accuracy = accuracy_score(y_true, y_pred)\n    precision = precision_score(y_true, y_pred, average='weighted')\n    recall = recall_score(y_true, y_pred, average='weighted')\n    f1 = f1_score(y_true, y_pred, average='weighted')\n    auc = roc_auc_score(y_true, y_proba, multi_class='ovr')\n    print(f\"Accuracy: {accuracy:.4f}\")\n    print(f\"Precision: {precision:.4f}\")\n    print(f\"Recall: {recall:.4f}\")\n    print(f\"F1 Score: {f1:.4f}\")\n    print(f\"AUC-ROC: {auc:.4f}\")\n    return accuracy, precision, recall, f1, auc\n\n# Plot ROC curve\ndef plot_roc_curve(y_true, y_proba):\n    fpr, tpr = {}, {}\n    for i in range(len(set(y_true))):\n        binary_true = [1 if label == i else 0 for label in y_true]\n        binary_proba = [prob[i] for prob in y_proba]\n        fpr[i], tpr[i], _ = roc_curve(binary_true, binary_proba)\n        plt.plot(fpr[i], tpr[i], label=f'Class {i}')\n    plt.xlabel('False Positive Rate')\n    plt.ylabel('True Positive Rate')\n    plt.title('ROC Curve')\n    plt.legend()\n    plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-29T07:47:21.17901Z","iopub.execute_input":"2025-01-29T07:47:21.179343Z","iopub.status.idle":"2025-01-29T07:47:21.18743Z","shell.execute_reply.started":"2025-01-29T07:47:21.179317Z","shell.execute_reply":"2025-01-29T07:47:21.185912Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Train the Vision Transformer (ViT)\nprint(\"Training Vision Transformer...\")\nvit_train_loss = train_model(vit_model, train_loader, vit_optimizer, criterion, device)\nprint(f\"ViT Training Loss: {vit_train_loss:.4f}\")\n\n# Evaluate the Vision Transformer (ViT)\nprint(\"Evaluating Vision Transformer...\")\nvit_val_loss, vit_y_true, vit_y_pred, vit_y_proba = evaluate_model(vit_model, val_loader, criterion, device)\nprint(f\"ViT Validation Loss: {vit_val_loss:.4f}\")\n\n# Metrics and ROC for ViT\nprint(\"\\nViT Metrics:\")\nvit_metrics = calculate_metrics(vit_y_true, vit_y_pred, vit_y_proba)\nplot_roc_curve(vit_y_true, vit_y_proba)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-29T05:53:12.222719Z","iopub.execute_input":"2025-01-29T05:53:12.223071Z","iopub.status.idle":"2025-01-29T07:05:11.868633Z","shell.execute_reply.started":"2025-01-29T05:53:12.223032Z","shell.execute_reply":"2025-01-29T07:05:11.867334Z"},"_kg_hide-input":false},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def train_model(model, dataloader, optimizer, criterion, device):\n    model.train()\n    total_loss = 0\n    for images, labels in dataloader:\n        images, labels = images.to(device), labels.to(device)\n\n        # Print the shapes for debugging\n        print(f\"Labels shape: {labels.shape}\")  # Expecting (batch_size,)\n        \n        outputs = model(images)\n        \n        # Print the shape of the model output for debugging\n        print(f\"Outputs shape: {outputs.shape}\")  # Expecting (batch_size, num_classes)\n\n        # Check if the model outputs 4D tensor (common in segmentation tasks)\n        if len(outputs.shape) == 4:  \n            outputs = outputs.view(outputs.size(0), -1)  # Flatten to (batch_size, num_classes)\n            print(f\"Flattened outputs shape: {outputs.shape}\")\n\n        # Ensure labels are of the right shape: (batch_size,)\n        if len(labels.shape) != 1:\n            print(f\"Warning: Labels should be 1D, but found shape: {labels.shape}\")\n            labels = labels.squeeze()  # Remove extra dimensions if needed\n\n        # Calculate loss\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n        total_loss += loss.item()\n\n    return total_loss / len(dataloader)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-29T07:52:20.728511Z","iopub.execute_input":"2025-01-29T07:52:20.728866Z","iopub.status.idle":"2025-01-29T07:52:20.735826Z","shell.execute_reply.started":"2025-01-29T07:52:20.728836Z","shell.execute_reply":"2025-01-29T07:52:20.734594Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def evaluate_model(model, dataloader, criterion, device):\n    model.eval()\n    total_loss = 0\n    y_true = []\n    y_pred = []\n    y_proba = []\n\n    with torch.no_grad():\n        for images, labels in dataloader:\n            images, labels = images.to(device), labels.to(device)\n\n            # Ensure labels are 1D by flattening them\n            if len(labels.shape) > 1:\n                labels = labels.view(-1)  # Flatten to 1D if necessary\n\n            outputs = model(images)\n\n            # Check shapes of outputs and labels\n            print(f\"Labels shape: {labels.shape}\")\n            print(f\"Outputs shape: {outputs.shape}\")\n\n            # Ensure the outputs are in the shape (batch_size, num_classes)\n            # For classification tasks, cross_entropy expects outputs of shape (batch_size, num_classes)\n\n            # Calculate the loss\n            loss = criterion(outputs, labels)\n            total_loss += loss.item()\n\n            # For classification tasks, use argmax to get predicted classes\n            _, preds = torch.max(outputs, 1)\n            y_true.extend(labels.cpu().numpy())\n            y_pred.extend(preds.cpu().numpy())\n\n            # For probabilities (use softmax for multi-class classification)\n            y_proba.extend(torch.softmax(outputs, dim=1)[:, 1].cpu().numpy())  # Modify this for multi-class if needed\n\n    return total_loss / len(dataloader), y_true, y_pred, y_proba\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-29T09:20:45.271617Z","iopub.execute_input":"2025-01-29T09:20:45.272008Z","iopub.status.idle":"2025-01-29T09:20:45.280292Z","shell.execute_reply.started":"2025-01-29T09:20:45.271979Z","shell.execute_reply":"2025-01-29T09:20:45.278981Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Train the Swin Transformer\n# print(\"Training Swin Transformer...\")\n# swin_train_loss = train_model(swin_model, train_loader, swin_optimizer, criterion, device)\n# print(f\"Swin Training Loss: {swin_train_loss:.4f}\")\n\n# Evaluate the Swin Transformer\nprint(\"Evaluating Swin Transformer...\")\nswin_val_loss, swin_y_true, swin_y_pred, swin_y_proba = evaluate_model(swin_model, val_loader, criterion, device)\nprint(f\"Swin Validation Loss: {swin_val_loss:.4f}\")\n\n# Metrics and ROC for Swin\nprint(\"\\nSwin Metrics:\")\nswin_metrics = calculate_metrics(swin_y_true, swin_y_pred, swin_y_proba)\nplot_roc_curve(swin_y_true, swin_y_proba)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-29T09:20:47.955357Z","iopub.execute_input":"2025-01-29T09:20:47.955701Z","iopub.status.idle":"2025-01-29T09:21:07.560068Z","shell.execute_reply.started":"2025-01-29T09:20:47.955672Z","shell.execute_reply":"2025-01-29T09:21:07.558545Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}