{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":14774,"databundleVersionId":875431,"sourceType":"competition"}],"dockerImageVersionId":31154,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nprint(os.listdir(\"/kaggle/input/aptos2019-blindness-detection\"))\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-11-01T05:34:52.275119Z","iopub.execute_input":"2025-11-01T05:34:52.275382Z","iopub.status.idle":"2025-11-01T05:34:52.283908Z","shell.execute_reply.started":"2025-11-01T05:34:52.275339Z","shell.execute_reply":"2025-11-01T05:34:52.283134Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms, models\nfrom PIL import Image\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score, f1_score, recall_score, precision_score\nfrom tqdm import tqdm\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(\"Using device:\", device)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-01T05:35:38.149816Z","iopub.execute_input":"2025-11-01T05:35:38.150352Z","iopub.status.idle":"2025-11-01T05:35:45.715168Z","shell.execute_reply.started":"2025-11-01T05:35:38.150327Z","shell.execute_reply":"2025-11-01T05:35:45.714303Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"DATA_DIR = \"/kaggle/input/aptos2019-blindness-detection\"\ntrain_df = pd.read_csv(os.path.join(DATA_DIR, \"train.csv\"))\ntrain_df['image_path'] = train_df['id_code'].apply(lambda x: os.path.join(DATA_DIR, \"train_images\", f\"{x}.png\"))\ntrain_df.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-01T05:36:40.404550Z","iopub.execute_input":"2025-11-01T05:36:40.405049Z","iopub.status.idle":"2025-11-01T05:36:40.447239Z","shell.execute_reply.started":"2025-11-01T05:36:40.405028Z","shell.execute_reply":"2025-11-01T05:36:40.446670Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ntrain_df, val_df = train_test_split(train_df, test_size=0.2, stratify=train_df['diagnosis'], random_state=42)\nprint(\"Train size:\", len(train_df), \"Validation size:\", len(val_df))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-01T05:37:07.746049Z","iopub.execute_input":"2025-11-01T05:37:07.746574Z","iopub.status.idle":"2025-11-01T05:37:07.760285Z","shell.execute_reply.started":"2025-11-01T05:37:07.746552Z","shell.execute_reply":"2025-11-01T05:37:07.759720Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"IMG_SIZE = 224\n\ntrain_transform = transforms.Compose([\n    transforms.Resize((IMG_SIZE, IMG_SIZE)),\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomRotation(15),\n    transforms.ToTensor(),\n    transforms.Normalize([0.485, 0.456, 0.406],\n                         [0.229, 0.224, 0.225])\n])\n\nval_transform = transforms.Compose([\n    transforms.Resize((IMG_SIZE, IMG_SIZE)),\n    transforms.ToTensor(),\n    transforms.Normalize([0.485, 0.456, 0.406],\n                         [0.229, 0.224, 0.225])\n])\n\nclass RetinopathyDataset(Dataset):\n    def __init__(self, df, transform=None):\n        self.df = df.reset_index(drop=True)\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        row = self.df.iloc[idx]\n        img = Image.open(row['image_path']).convert(\"RGB\")\n        label = int(row['diagnosis'])\n        if self.transform:\n            img = self.transform(img)\n        return img, label\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-01T05:38:23.949513Z","iopub.execute_input":"2025-11-01T05:38:23.950188Z","iopub.status.idle":"2025-11-01T05:38:23.956254Z","shell.execute_reply.started":"2025-11-01T05:38:23.950165Z","shell.execute_reply":"2025-11-01T05:38:23.955470Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"BATCH_SIZE = 16\ntrain_ds = RetinopathyDataset(train_df, transform=train_transform)\nval_ds = RetinopathyDataset(val_df, transform=val_transform)\ntrain_loader = DataLoader(train_ds, batch_size=BATCH_SIZE, shuffle=True, num_workers=2)\nval_loader = DataLoader(val_ds, batch_size=BATCH_SIZE, shuffle=False, num_workers=2)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-01T05:38:45.427745Z","iopub.execute_input":"2025-11-01T05:38:45.428277Z","iopub.status.idle":"2025-11-01T05:38:45.434088Z","shell.execute_reply.started":"2025-11-01T05:38:45.428255Z","shell.execute_reply":"2025-11-01T05:38:45.433463Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def get_model(name):\n    if name == \"vgg16\":\n        model = models.vgg16(pretrained=True)\n        for p in model.features.parameters(): p.requires_grad = False\n        model.classifier[6] = nn.Linear(4096, 5)\n    elif name == \"alexnet\":\n        model = models.alexnet(pretrained=True)\n        for p in model.features.parameters(): p.requires_grad = False\n        model.classifier[6] = nn.Linear(4096, 5)\n    elif name == \"resnet50\":\n        model = models.resnet50(pretrained=True)\n        for p in model.parameters(): p.requires_grad = False\n        model.fc = nn.Linear(model.fc.in_features, 5)\n    else:\n        raise ValueError(\"Unknown model name\")\n    return model.to(device)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-01T05:38:58.130160Z","iopub.execute_input":"2025-11-01T05:38:58.130571Z","iopub.status.idle":"2025-11-01T05:38:58.137684Z","shell.execute_reply.started":"2025-11-01T05:38:58.130548Z","shell.execute_reply":"2025-11-01T05:38:58.136613Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def train_and_eval(model_name, epochs=3):\n    model = get_model(model_name)\n    criterion = nn.CrossEntropyLoss()\n    optimizer = optim.Adam(filter(lambda p: p.requires_grad, model.parameters()), lr=1e-3)\n    \n    for epoch in range(epochs):\n        model.train()\n        running_loss = 0\n        for imgs, labels in tqdm(train_loader, desc=f\"Training {model_name} (Epoch {epoch+1})\"):\n            imgs, labels = imgs.to(device), labels.to(device)\n            optimizer.zero_grad()\n            outputs = model(imgs)\n            loss = criterion(outputs, labels)\n            loss.backward()\n            optimizer.step()\n            running_loss += loss.item()\n        print(f\"Epoch {epoch+1}: Loss={running_loss/len(train_loader):.4f}\")\n    \n    model.eval()\n    preds, truths = [], []\n    with torch.no_grad():\n        for imgs, labels in tqdm(val_loader, desc=f\"Validating {model_name}\"):\n            imgs = imgs.to(device)\n            outputs = model(imgs)\n            preds.extend(outputs.argmax(1).cpu().numpy())\n            truths.extend(labels.numpy())\n\n    acc = accuracy_score(truths, preds)\n    f1 = f1_score(truths, preds, average='weighted')\n    recall = recall_score(truths, preds, average='weighted')\n    precision = precision_score(truths, preds, average='weighted')\n    \n    print(f\"\\n{model_name.upper()} Results —\")\n    print(f\"Accuracy:  {acc:.4f}\")\n    print(f\"F1 Score:  {f1:.4f}\")\n    print(f\"Recall:    {recall:.4f}\")\n    print(f\"Precision: {precision:.4f}\")\n    \n    return acc, f1, recall, precision\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-01T05:39:25.068632Z","iopub.execute_input":"2025-11-01T05:39:25.069541Z","iopub.status.idle":"2025-11-01T05:39:25.076705Z","shell.execute_reply.started":"2025-11-01T05:39:25.069517Z","shell.execute_reply":"2025-11-01T05:39:25.075961Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"results = {}\nfor name in [\"vgg16\", \"alexnet\", \"resnet50\"]:\n    acc, f1, rec, prec = train_and_eval(name, epochs=3)\n    results[name] = [acc, f1, rec, prec]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-01T05:40:12.778808Z","iopub.execute_input":"2025-11-01T05:40:12.779600Z","iopub.status.idle":"2025-11-01T06:09:41.168972Z","shell.execute_reply.started":"2025-11-01T05:40:12.779568Z","shell.execute_reply":"2025-11-01T06:09:41.167912Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"results_df = pd.DataFrame(results, index=[\"Accuracy\",\"F1 Score\",\"Recall\",\"Precision\"]).T\nresults_df\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-01T06:13:53.648922Z","iopub.execute_input":"2025-11-01T06:13:53.649230Z","iopub.status.idle":"2025-11-01T06:13:53.661020Z","shell.execute_reply.started":"2025-11-01T06:13:53.649201Z","shell.execute_reply":"2025-11-01T06:13:53.660400Z"}},"outputs":[],"execution_count":null}]}