{"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":14774,"databundleVersionId":875431,"sourceType":"competition"}],"dockerImageVersionId":30840,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport torch\nimport torch.nn as nn\nimport torchvision.transforms as transforms\nfrom torchvision import models\nfrom torch.utils.data import Dataset, DataLoader\nimport timm  # For advanced models\nimport cv2\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score, f1_score, roc_auc_score\nimport torch.optim as optim\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-02-07T03:49:39.092173Z","iopub.execute_input":"2025-02-07T03:49:39.092530Z","iopub.status.idle":"2025-02-07T03:49:49.352379Z","shell.execute_reply.started":"2025-02-07T03:49:39.092503Z","shell.execute_reply":"2025-02-07T03:49:49.351556Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Define dataset path\nDATA_DIR = \"/kaggle/input/aptos2019-blindness-detection\"\n\nprint(\"Loading dataset...\")\n# Read CSV file\ndf = pd.read_csv(os.path.join(DATA_DIR, \"train.csv\"))\n\ndf[\"diagnosis\"] = df[\"diagnosis\"].astype(int)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T03:49:49.353626Z","iopub.execute_input":"2025-02-07T03:49:49.354168Z","iopub.status.idle":"2025-02-07T03:49:49.375503Z","shell.execute_reply.started":"2025-02-07T03:49:49.354136Z","shell.execute_reply":"2025-02-07T03:49:49.374862Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Splitting dataset...\")\ntrain_df, val_df = train_test_split(df, test_size=0.2, random_state=42, stratify=df[\"diagnosis\"])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T03:49:49.377389Z","iopub.execute_input":"2025-02-07T03:49:49.377615Z","iopub.status.idle":"2025-02-07T03:49:49.393466Z","shell.execute_reply.started":"2025-02-07T03:49:49.377596Z","shell.execute_reply":"2025-02-07T03:49:49.392433Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class DRDataset(Dataset):\n    def __init__(self, dataframe, data_dir, transform=None):\n        self.dataframe = dataframe\n        self.data_dir = data_dir\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.dataframe)\n\n    def __getitem__(self, idx):\n        img_name = os.path.join(self.data_dir, \"train_images\", self.dataframe.iloc[idx, 0] + \".png\")\n        image = cv2.imread(img_name)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        image = cv2.resize(image, (224, 224))\n\n        if self.transform:\n            image = self.transform(image)\n\n        label = self.dataframe.iloc[idx, 1]\n        return image, label\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T03:49:49.394397Z","iopub.execute_input":"2025-02-07T03:49:49.394649Z","iopub.status.idle":"2025-02-07T03:49:49.401030Z","shell.execute_reply.started":"2025-02-07T03:49:49.394620Z","shell.execute_reply":"2025-02-07T03:49:49.400175Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Applying transformations...\")\ntransform = transforms.Compose([\n    transforms.ToPILImage(),\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomRotation(20),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T03:49:49.401933Z","iopub.execute_input":"2025-02-07T03:49:49.402257Z","iopub.status.idle":"2025-02-07T03:49:49.414860Z","shell.execute_reply.started":"2025-02-07T03:49:49.402235Z","shell.execute_reply":"2025-02-07T03:49:49.414191Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Creating datasets and dataloaders...\")\ntrain_dataset = DRDataset(train_df, DATA_DIR, transform=transform)\nval_dataset = DRDataset(val_df, DATA_DIR, transform=transform)\n\ntrain_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=16, shuffle=False)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T03:49:49.415823Z","iopub.execute_input":"2025-02-07T03:49:49.416180Z","iopub.status.idle":"2025-02-07T03:49:49.428200Z","shell.execute_reply.started":"2025-02-07T03:49:49.416149Z","shell.execute_reply":"2025-02-07T03:49:49.427461Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Initializing models...\")\nclass DRModel(nn.Module):\n    def __init__(self, model_name):\n        super(DRModel, self).__init__()\n        self.model = timm.create_model(model_name, pretrained=True, num_classes=5)\n    \n    def forward(self, x):\n        return self.model(x)\n\n# Load best-performing models\nmodel1 = DRModel(\"swin_large_patch4_window7_224\").cuda()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T03:49:50.710484Z","iopub.execute_input":"2025-02-07T03:49:50.710791Z","iopub.status.idle":"2025-02-07T03:49:58.537515Z","shell.execute_reply.started":"2025-02-07T03:49:50.710770Z","shell.execute_reply":"2025-02-07T03:49:58.536709Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model2 = DRModel(\"tf_efficientnet_b7\").cuda()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T03:49:58.538641Z","iopub.execute_input":"2025-02-07T03:49:58.538910Z","iopub.status.idle":"2025-02-07T03:50:01.128606Z","shell.execute_reply.started":"2025-02-07T03:49:58.538879Z","shell.execute_reply":"2025-02-07T03:50:01.127581Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model3 = DRModel(\"convnext_large\").cuda()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T03:50:01.130374Z","iopub.execute_input":"2025-02-07T03:50:01.130657Z","iopub.status.idle":"2025-02-07T03:50:08.685130Z","shell.execute_reply.started":"2025-02-07T03:50:01.130637Z","shell.execute_reply":"2025-02-07T03:50:08.684380Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Starting training...\")\ndef train_model(model, train_loader, val_loader, epochs=10):\n    criterion = nn.CrossEntropyLoss()\n    optimizer = optim.Adam(model.parameters(), lr=0.0001)\n\n    for epoch in range(epochs):\n        model.train()\n        train_loss = 0\n        correct = 0\n        total = 0\n\n        for images, labels in train_loader:\n            images, labels = images.cuda(), labels.cuda()\n            optimizer.zero_grad()\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            loss.backward()\n            optimizer.step()\n\n            train_loss += loss.item()\n            _, predicted = outputs.max(1)\n            total += labels.size(0)\n            correct += predicted.eq(labels).sum().item()\n\n        print(f\"Epoch {epoch+1}, Loss: {train_loss/len(train_loader):.4f}, Accuracy: {100*correct/total:.2f}%\")\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T04:22:01.471838Z","iopub.execute_input":"2025-02-07T04:22:01.472196Z","iopub.status.idle":"2025-02-07T04:22:01.479440Z","shell.execute_reply.started":"2025-02-07T04:22:01.472168Z","shell.execute_reply":"2025-02-07T04:22:01.478393Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_model(model1, train_loader, val_loader)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T04:22:05.586872Z","iopub.execute_input":"2025-02-07T04:22:05.587257Z","iopub.status.idle":"2025-02-07T05:51:38.467286Z","shell.execute_reply.started":"2025-02-07T04:22:05.587227Z","shell.execute_reply":"2025-02-07T05:51:38.466468Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_model(model2, train_loader, val_loader)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T05:51:38.468434Z","iopub.execute_input":"2025-02-07T05:51:38.468702Z","iopub.status.idle":"2025-02-07T07:00:26.783263Z","shell.execute_reply.started":"2025-02-07T05:51:38.468681Z","shell.execute_reply":"2025-02-07T07:00:26.782250Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_model(model3, train_loader, val_loader)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T07:00:26.786078Z","iopub.execute_input":"2025-02-07T07:00:26.786364Z","iopub.status.idle":"2025-02-07T08:41:33.694395Z","shell.execute_reply.started":"2025-02-07T07:00:26.786342Z","shell.execute_reply":"2025-02-07T08:41:33.693594Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Starting adjusted weighted fusion prediction...\")\ndef weighted_fusion(models, weights, dataloader):\n    models = [m.eval() for m in models]\n    total_preds = []\n    total_labels = []\n    \n    with torch.no_grad():\n        for images, labels in dataloader:\n            images = images.cuda()\n            outputs = [m(images) for m in models]\n            fused_output = sum(w * o for w, o in zip(weights, outputs)) / sum(weights)\n            preds = torch.argmax(fused_output, dim=1).cpu().numpy()\n            total_preds.extend(preds)\n            total_labels.extend(labels.numpy())\n    \n    accuracy = accuracy_score(total_labels, total_preds)\n    f1 = f1_score(total_labels, total_preds, average='weighted')\n    print(f\"Fusion Accuracy: {accuracy:.4f}, F1-score: {f1:.4f}\")\n\n# Adjusted model weights based on performance\nweights = [0.2, 0.35, 0.45]\nweighted_fusion([model1, model2, model3], weights, val_loader)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T08:48:01.936304Z","iopub.execute_input":"2025-02-07T08:48:01.936727Z","iopub.status.idle":"2025-02-07T08:50:05.703252Z","shell.execute_reply.started":"2025-02-07T08:48:01.936698Z","shell.execute_reply":"2025-02-07T08:50:05.702342Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def test_model(model, dataloader):\n    model.eval()  # Set to evaluation mode\n    total_preds = []\n    total_labels = []\n    \n    with torch.no_grad():\n        for images, labels in dataloader:\n            images = images.cuda()\n            outputs = model(images)\n            preds = torch.argmax(outputs, dim=1).cpu().numpy()\n            total_preds.extend(preds)\n            total_labels.extend(labels.numpy())\n\n    accuracy = accuracy_score(total_labels, total_preds)\n    f1 = f1_score(total_labels, total_preds, average='weighted')\n    print(f\"Model Test Accuracy: {accuracy:.4f}, F1-score: {f1:.4f}\")\n    return accuracy, f1\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T08:51:51.894296Z","iopub.execute_input":"2025-02-07T08:51:51.894616Z","iopub.status.idle":"2025-02-07T08:51:51.900069Z","shell.execute_reply.started":"2025-02-07T08:51:51.894594Z","shell.execute_reply":"2025-02-07T08:51:51.899096Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Testing Model 1 (Swin Large)...\")\nacc1, f1_1 = test_model(model1, val_loader)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T08:52:02.887377Z","iopub.execute_input":"2025-02-07T08:52:02.887665Z","iopub.status.idle":"2025-02-07T08:53:39.362097Z","shell.execute_reply.started":"2025-02-07T08:52:02.887645Z","shell.execute_reply":"2025-02-07T08:53:39.361356Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Testing Model 2 (EfficientNet B7)...\")\nacc2, f1_2 = test_model(model2, val_loader)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T08:53:39.363045Z","iopub.execute_input":"2025-02-07T08:53:39.363409Z","iopub.status.idle":"2025-02-07T08:55:01.533418Z","shell.execute_reply.started":"2025-02-07T08:53:39.363384Z","shell.execute_reply":"2025-02-07T08:55:01.532536Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Testing Model 3 (ConvNeXt Large)...\")\nacc3, f1_3 = test_model(model3, val_loader)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T08:55:01.534767Z","iopub.execute_input":"2025-02-07T08:55:01.535024Z","iopub.status.idle":"2025-02-07T08:56:36.005676Z","shell.execute_reply.started":"2025-02-07T08:55:01.535003Z","shell.execute_reply":"2025-02-07T08:56:36.004717Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Starting updated weighted fusion prediction...\")\n\ndef weighted_fusion(models, weights, dataloader):\n    models = [m.eval() for m in models]  # Set all models to evaluation mode\n    total_preds = []\n    total_labels = []\n    \n    with torch.no_grad():\n        for images, labels in dataloader:\n            images = images.cuda()\n            outputs = [m(images) for m in models]  # Get predictions from all models\n            fused_output = sum(w * o for w, o in zip(weights, outputs)) / sum(weights)\n            preds = torch.argmax(fused_output, dim=1).cpu().numpy()\n            total_preds.extend(preds)\n            total_labels.extend(labels.numpy())\n\n    accuracy = accuracy_score(total_labels, total_preds)\n    f1 = f1_score(total_labels, total_preds, average='weighted')\n    print(f\"Fusion Accuracy: {accuracy:.4f}, F1-score: {f1:.4f}\")\n\n# **New adjusted fusion weights** based on test accuracy\nweights = [0.45, 0.20, 0.35]  \nweighted_fusion([model1, model2, model3], weights, val_loader)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T08:57:14.899498Z","iopub.execute_input":"2025-02-07T08:57:14.899840Z","iopub.status.idle":"2025-02-07T08:59:18.163338Z","shell.execute_reply.started":"2025-02-07T08:57:14.899811Z","shell.execute_reply":"2025-02-07T08:59:18.162588Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\n\n# Save individual model states and fusion weights\ntorch.save({\n    'model1_state_dict': model1.state_dict(),\n    'model2_state_dict': model2.state_dict(),\n    'model3_state_dict': model3.state_dict(),\n    'fusion_weights': weights\n}, \"/kaggle/working/weighted_fusion_model.pth\")\n\nprint(\"Weighted fusion model and weights saved successfully at /kaggle/working/weighted_fusion_model.pth\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:14:00.683700Z","iopub.execute_input":"2025-02-07T09:14:00.684030Z","iopub.status.idle":"2025-02-07T09:14:03.134857Z","shell.execute_reply.started":"2025-02-07T09:14:00.684009Z","shell.execute_reply":"2025-02-07T09:14:03.133928Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load the saved model and weights\ncheckpoint = torch.load(\"/kaggle/working/weighted_fusion_model.pth\")\n\n# Restore model states\nmodel1.load_state_dict(checkpoint['model1_state_dict'])\nmodel2.load_state_dict(checkpoint['model2_state_dict'])\nmodel3.load_state_dict(checkpoint['model3_state_dict'])\n\n# Restore fusion weights\nweights = checkpoint['fusion_weights']\n\nprint(\"Weighted fusion model and weights loaded successfully!\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:14:36.770210Z","iopub.execute_input":"2025-02-07T09:14:36.770542Z","iopub.status.idle":"2025-02-07T09:14:38.409023Z","shell.execute_reply.started":"2025-02-07T09:14:36.770501Z","shell.execute_reply":"2025-02-07T09:14:38.408221Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Save all three models\nmodel1_path = \"/kaggle/working/model1.pth\"\nmodel2_path = \"/kaggle/working/model2.pth\"\nmodel3_path = \"/kaggle/working/model3.pth\"\n\ntorch.save(model1.state_dict(), model1_path)\ntorch.save(model2.state_dict(), model2_path)\ntorch.save(model3.state_dict(), model3_path)\n\n# Download models to local computer\nfrom IPython.display import FileLink\n\ndisplay(FileLink(model1_path))\ndisplay(FileLink(model2_path))\ndisplay(FileLink(model3_path))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:21:39.048757Z","iopub.execute_input":"2025-02-07T09:21:39.049182Z","iopub.status.idle":"2025-02-07T09:21:43.952929Z","shell.execute_reply.started":"2025-02-07T09:21:39.049142Z","shell.execute_reply":"2025-02-07T09:21:43.951970Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-07T09:20:56.111693Z","iopub.execute_input":"2025-02-07T09:20:56.112058Z","iopub.status.idle":"2025-02-07T09:21:00.849889Z","shell.execute_reply.started":"2025-02-07T09:20:56.112027Z","shell.execute_reply":"2025-02-07T09:21:00.848801Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}