{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":39272,"databundleVersionId":4629629,"sourceType":"competition"},{"sourceId":4866520,"sourceType":"datasetVersion","datasetId":2820722}],"dockerImageVersionId":31011,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nfrom PIL import Image\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\n\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nfrom torchvision.models import efficientnet_b5, EfficientNet_B5_Weights\nfrom tqdm import tqdm","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T20:59:46.748017Z","iopub.execute_input":"2025-04-28T20:59:46.748746Z","iopub.status.idle":"2025-04-28T20:59:46.753106Z","shell.execute_reply.started":"2025-04-28T20:59:46.74872Z","shell.execute_reply":"2025-04-28T20:59:46.752358Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(f\"Using device: {device}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T20:59:56.221339Z","iopub.execute_input":"2025-04-28T20:59:56.221664Z","iopub.status.idle":"2025-04-28T20:59:56.30591Z","shell.execute_reply.started":"2025-04-28T20:59:56.22164Z","shell.execute_reply":"2025-04-28T20:59:56.305062Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data_path = '/kaggle/input/rsna-bcd-1024x512-preprocessed'\ncsv_path = '/kaggle/input/rsna-breast-cancer-detection/train.csv'\nimages_folder = os.path.join(data_path, 'train_images')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T21:00:07.588512Z","iopub.execute_input":"2025-04-28T21:00:07.588806Z","iopub.status.idle":"2025-04-28T21:00:07.592864Z","shell.execute_reply.started":"2025-04-28T21:00:07.588784Z","shell.execute_reply":"2025-04-28T21:00:07.592125Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"labels_df = pd.read_csv(csv_path)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T21:00:17.599094Z","iopub.execute_input":"2025-04-28T21:00:17.599379Z","iopub.status.idle":"2025-04-28T21:00:17.662092Z","shell.execute_reply.started":"2025-04-28T21:00:17.599358Z","shell.execute_reply":"2025-04-28T21:00:17.661477Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"labels_df['image_path'] = labels_df['patient_id'].astype(str) + '/' + labels_df['image_id'].astype(str) + '.png'\nlabels_df['image_path'] = labels_df['image_path'].apply(lambda x: os.path.join(images_folder, x))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T21:00:28.74968Z","iopub.execute_input":"2025-04-28T21:00:28.750355Z","iopub.status.idle":"2025-04-28T21:00:28.841859Z","shell.execute_reply.started":"2025-04-28T21:00:28.750327Z","shell.execute_reply":"2025-04-28T21:00:28.841065Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df, temp_df = train_test_split(labels_df, test_size=0.2, random_state=42, stratify=labels_df['cancer'])\nvalid_df, test_df = train_test_split(temp_df, test_size=0.5, random_state=42, stratify=temp_df['cancer'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T21:00:41.314664Z","iopub.execute_input":"2025-04-28T21:00:41.31519Z","iopub.status.idle":"2025-04-28T21:00:41.357812Z","shell.execute_reply.started":"2025-04-28T21:00:41.315166Z","shell.execute_reply":"2025-04-28T21:00:41.35721Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"img_size = (256, 256)\n\ntrain_transform = transforms.Compose([\n    transforms.Resize(img_size),\n    transforms.RandomHorizontalFlip(),\n    transforms.ToTensor(),\n])\n\nvalid_test_transform = transforms.Compose([\n    transforms.Resize(img_size),\n    transforms.ToTensor(),\n])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T21:00:55.069652Z","iopub.execute_input":"2025-04-28T21:00:55.070237Z","iopub.status.idle":"2025-04-28T21:00:55.074474Z","shell.execute_reply.started":"2025-04-28T21:00:55.070215Z","shell.execute_reply":"2025-04-28T21:00:55.073699Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class BreastCancerDataset(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        img_path = self.df.loc[idx, 'image_path']\n        label = self.df.loc[idx, 'cancer']\n\n        image = Image.open(img_path).convert('RGB')\n\n        if self.transform:\n            image = self.transform(image)\n\n        return image, torch.tensor(label, dtype=torch.float32)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T21:01:11.670595Z","iopub.execute_input":"2025-04-28T21:01:11.671387Z","iopub.status.idle":"2025-04-28T21:01:11.678317Z","shell.execute_reply.started":"2025-04-28T21:01:11.671359Z","shell.execute_reply":"2025-04-28T21:01:11.67751Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_dataset = BreastCancerDataset(train_df, transform=train_transform)\nvalid_dataset = BreastCancerDataset(valid_df, transform=valid_test_transform)\ntest_dataset = BreastCancerDataset(test_df, transform=valid_test_transform)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T21:01:22.744947Z","iopub.execute_input":"2025-04-28T21:01:22.745722Z","iopub.status.idle":"2025-04-28T21:01:22.757597Z","shell.execute_reply.started":"2025-04-28T21:01:22.745693Z","shell.execute_reply":"2025-04-28T21:01:22.756798Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True, num_workers=2, pin_memory=True)\nvalid_loader = DataLoader(valid_dataset, batch_size=8, shuffle=False, num_workers=2, pin_memory=True)\ntest_loader = DataLoader(test_dataset, batch_size=8, shuffle=False, num_workers=2, pin_memory=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T21:01:34.040442Z","iopub.execute_input":"2025-04-28T21:01:34.040696Z","iopub.status.idle":"2025-04-28T21:01:34.045549Z","shell.execute_reply.started":"2025-04-28T21:01:34.040678Z","shell.execute_reply":"2025-04-28T21:01:34.044712Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def show_batch(loader):\n    images, labels = next(iter(loader))\n    images = images[:8]\n    labels = labels[:8]\n\n    plt.figure(figsize=(16, 8))\n    for i in range(len(images)):\n        img = images[i].permute(1, 2, 0).numpy()\n        plt.subplot(2, 4, i + 1)\n        plt.imshow(img)\n        plt.title(f'Label: {int(labels[i].item())}')\n        plt.axis('off')\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T21:01:45.06225Z","iopub.execute_input":"2025-04-28T21:01:45.062549Z","iopub.status.idle":"2025-04-28T21:01:45.067713Z","shell.execute_reply.started":"2025-04-28T21:01:45.062525Z","shell.execute_reply":"2025-04-28T21:01:45.067Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"weights = EfficientNet_B5_Weights.IMAGENET1K_V1\nmodel = efficientnet_b5(weights=weights)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T21:01:58.357043Z","iopub.execute_input":"2025-04-28T21:01:58.357629Z","iopub.status.idle":"2025-04-28T21:01:59.992912Z","shell.execute_reply.started":"2025-04-28T21:01:58.357603Z","shell.execute_reply":"2025-04-28T21:01:59.99216Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torchvision.models import efficientnet_b5, EfficientNet_B5_Weights","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.classifier[1] = nn.Linear(in_features=model.classifier[1].in_features, out_features=1)\nmodel = model.to(device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T21:02:10.062812Z","iopub.execute_input":"2025-04-28T21:02:10.06357Z","iopub.status.idle":"2025-04-28T21:02:10.293879Z","shell.execute_reply.started":"2025-04-28T21:02:10.063538Z","shell.execute_reply":"2025-04-28T21:02:10.293089Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.classifier[1] = nn.Linear(in_features=model.classifier[1].in_features, out_features=1)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"criterion = nn.BCEWithLogitsLoss()\noptimizer = optim.Adam(model.parameters(), lr=1e-4)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T21:02:29.402574Z","iopub.execute_input":"2025-04-28T21:02:29.40286Z","iopub.status.idle":"2025-04-28T21:02:29.409131Z","shell.execute_reply.started":"2025-04-28T21:02:29.402839Z","shell.execute_reply":"2025-04-28T21:02:29.408315Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"epochs = 5\nbest_val_acc = 0.0\n\nfor epoch in range(epochs):\n    model.train()\n    running_loss = 0.0\n    pbar = tqdm(train_loader, desc=f\"Epoch {epoch+1}/{epochs}\")\n\n    for images, labels in pbar:\n        images, labels = images.to(device), labels.to(device).unsqueeze(1)\n\n        optimizer.zero_grad()\n        outputs = model(images)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item()\n        pbar.set_postfix({'loss': running_loss / (pbar.n + 1)})\n\n    avg_train_loss = running_loss / len(train_loader)\n    print(f\"Epoch [{epoch+1}/{epochs}] Training Loss: {avg_train_loss:.4f}\")\n\n    # Validation\n    model.eval()\n    correct = 0\n    total = 0\n    with torch.no_grad():\n        for images, labels in valid_loader:\n            images, labels = images.to(device), labels.to(device).unsqueeze(1)\n            outputs = model(images)\n            preds = torch.sigmoid(outputs) > 0.5\n            correct += (preds == labels).sum().item()\n            total += labels.size(0)\n    val_acc = correct / total\n    print(f\"Validation Accuracy: {val_acc:.4f}\")\n\n    # Saving Best Model\n    if val_acc > best_val_acc:\n        best_val_acc = val_acc\n        torch.save(model.state_dict(), \"best_model.pth\")\n        print(\"Best model saved!\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T21:02:51.409276Z","iopub.execute_input":"2025-04-28T21:02:51.409639Z","iopub.status.idle":"2025-04-28T22:06:42.771948Z","shell.execute_reply.started":"2025-04-28T21:02:51.409614Z","shell.execute_reply":"2025-04-28T22:06:42.770961Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"\\nTesting the Best Model...\")\nmodel.load_state_dict(torch.load(\"best_model.pth\"))\nmodel.eval()\n\ncorrect = 0\ntotal = 0","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T22:06:56.593222Z","iopub.execute_input":"2025-04-28T22:06:56.593925Z","iopub.status.idle":"2025-04-28T22:06:56.829376Z","shell.execute_reply.started":"2025-04-28T22:06:56.593896Z","shell.execute_reply":"2025-04-28T22:06:56.82886Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"with torch.no_grad():\n    for images, labels in tqdm(test_loader, desc=\"Testing\"):\n        images = images.to(device)\n        labels = labels.to(device).unsqueeze(1)\n\n        outputs = model(images)\n        preds = torch.sigmoid(outputs) > 0.5\n        correct += (preds == labels).sum().item()\n        total += labels.size(0)\n\ntest_acc = 100 * correct / total\nprint(f\"Test Accuracy: {test_acc:.2f}%\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-28T22:07:01.128331Z","iopub.execute_input":"2025-04-28T22:07:01.128877Z","iopub.status.idle":"2025-04-28T22:08:02.012265Z","shell.execute_reply.started":"2025-04-28T22:07:01.128851Z","shell.execute_reply":"2025-04-28T22:08:02.011434Z"}},"outputs":[],"execution_count":null}]}