{"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":5441,"databundleVersionId":38425,"sourceType":"competition"}],"dockerImageVersionId":31040,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-06-24T17:37:27.138080Z","iopub.execute_input":"2025-06-24T17:37:27.138680Z","iopub.status.idle":"2025-06-24T17:37:27.961788Z","shell.execute_reply.started":"2025-06-24T17:37:27.138653Z","shell.execute_reply":"2025-06-24T17:37:27.961109Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from zipfile import ZipFile\nimport torch\n\nwith ZipFile(\"/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip\", 'r') as zip:\n    zip.extractall()\n\nwith ZipFile(\"/kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip\", 'r') as zip:\n    zip.extractall()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T17:37:27.963081Z","iopub.execute_input":"2025-06-24T17:37:27.963722Z","iopub.status.idle":"2025-06-24T17:37:43.072639Z","shell.execute_reply.started":"2025-06-24T17:37:27.963700Z","shell.execute_reply":"2025-06-24T17:37:43.071794Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\ndevice","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T17:37:43.073556Z","iopub.execute_input":"2025-06-24T17:37:43.074288Z","iopub.status.idle":"2025-06-24T17:37:43.144243Z","shell.execute_reply.started":"2025-06-24T17:37:43.074266Z","shell.execute_reply":"2025-06-24T17:37:43.143481Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from PIL import Image\nimport os, glob\n\ntrain_folder_path = \"/kaggle/working/train\"\ntest_folder_path = \"/kaggle/working/test\"\n\ntrain_files = [f for f in os.listdir(train_folder_path) if f.endswith('.jpg')]\ntest_files = [f for f in os.listdir(test_folder_path) if f.endswith('.jpg')]\n\ntrain_images = []\n\nfor image_path in train_files:\n    image = Image.open(os.path.join(train_folder_path, image_path))\n    image = image.resize((100, 100))\n    train_images.append(torch.tensor(np.array(image)).float().to(device).permute(2, 0, 1) / 255)\n\nall_images_train = glob.glob(os.path.join(train_folder_path, \"*.jpg\"))\ntrain_labels = [1.0 if \"dog\" in os.path.basename(p) else 0.0 for p in all_images_train]\n\ntest_images = []\n\nfor image_path in test_files:\n    image = Image.open(os.path.join(test_folder_path, image_path))\n    image = image.resize((100, 100))\n    test_images.append(torch.tensor(np.array(image)).float().to(device).permute(2, 0, 1) / 255)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T17:37:43.146301Z","iopub.execute_input":"2025-06-24T17:37:43.146538Z","iopub.status.idle":"2025-06-24T17:39:17.793847Z","shell.execute_reply.started":"2025-06-24T17:37:43.146521Z","shell.execute_reply":"2025-06-24T17:39:17.793213Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\nX, y = train_images, torch.tensor(train_labels).long().to(device)\n\nX_train, X_test, y_train, y_test = train_test_split(X, y)\n\nprint(\"Train class counts:\", torch.bincount(y_train.long()))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T17:39:17.794540Z","iopub.execute_input":"2025-06-24T17:39:17.794727Z","iopub.status.idle":"2025-06-24T17:39:19.034835Z","shell.execute_reply.started":"2025-06-24T17:39:17.794711Z","shell.execute_reply":"2025-06-24T17:39:19.033937Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nfrom torch import nn\nfrom torch.utils.data import Dataset\nfrom torch.utils.data import DataLoader\nimport torchvision\n\nclass CatsAndDogs(Dataset):\n    def __init__(self, x, y):\n        self.imgs = x\n        self.labels = y\n        \n    def __len__(self):\n        return len(self.imgs)\n\n    def __getitem__(self, idx):\n        # transform = torchvision.transforms.Compose([\n        #     torchvision.transforms.ToTensor()\n        # ])\n        img = self.imgs[idx]\n        label = self.labels[idx]\n        # label = torch.tensor(label).float()\n        # img = transform(img)\n        return img, label\n\ntraining_data = CatsAndDogs(X_train, y_train)\ntest_data = CatsAndDogs(X_test, y_test)\n\nbatch_size = 16\ntrain_dataloader = DataLoader(training_data, batch_size=batch_size, shuffle=True)\ntest_dataloader = DataLoader(test_data, batch_size=batch_size, shuffle=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T17:39:19.035687Z","iopub.execute_input":"2025-06-24T17:39:19.036018Z","iopub.status.idle":"2025-06-24T17:39:20.955048Z","shell.execute_reply.started":"2025-06-24T17:39:19.036001Z","shell.execute_reply":"2025-06-24T17:39:20.954292Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"cnt = 0\n\nfor idx, (inputs, labels) in enumerate(train_dataloader):\n    if cnt < 1:\n        print(labels.view(-1, 1) )\n    cnt += 1","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T17:39:20.955803Z","iopub.execute_input":"2025-06-24T17:39:20.956136Z","iopub.status.idle":"2025-06-24T17:39:21.793608Z","shell.execute_reply.started":"2025-06-24T17:39:20.956118Z","shell.execute_reply":"2025-06-24T17:39:21.793019Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch.nn as nn\nfrom torchvision.models import resnet50, ResNet50_Weights\n\nmodel = resnet50(weights=ResNet50_Weights.IMAGENET1K_V2)\nmodel.fc = nn.Linear(2048, 1)\nmodel = model.to(device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T17:39:21.794434Z","iopub.execute_input":"2025-06-24T17:39:21.794667Z","iopub.status.idle":"2025-06-24T17:39:22.823130Z","shell.execute_reply.started":"2025-06-24T17:39:21.794649Z","shell.execute_reply":"2025-06-24T17:39:22.822562Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(model)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T18:17:37.317235Z","iopub.execute_input":"2025-06-24T18:17:37.317830Z","iopub.status.idle":"2025-06-24T18:17:37.323046Z","shell.execute_reply.started":"2025-06-24T18:17:37.317804Z","shell.execute_reply":"2025-06-24T18:17:37.322184Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"loss_fn = nn.BCEWithLogitsLoss()\noptimizer = torch.optim.AdamW(model.parameters(), lr=0.01)\n\nepochs = 12\nmodel.train()\n\nfor epoch in range(epochs):\n    running_loss = 0.0\n    correct = 0\n    total = 0\n\n    print(f\"\\nEpoch: {epoch + 1}\\n\")\n\n    for idx, (inputs, labels) in enumerate(train_dataloader):\n        inputs = inputs.to(device)\n        labels = labels.float().to(device).view(-1, 1)  # shape [B, 1]\n\n        optimizer.zero_grad()\n        logits = model(inputs)                 # shape [B, 1]\n        probs = torch.sigmoid(logits)          # apply sigmoid\n        loss = loss_fn(logits, labels)\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item()\n\n        # Binary prediction (threshold at 0.5)\n        predicted = (probs > 0.5).float()\n        correct += (predicted == labels).sum().item()\n        total += labels.size(0)\n\n    avg_loss = running_loss / len(train_dataloader)\n    accuracy = (correct / total) * 100\n\n    print(f\"Loss: {avg_loss:.4f} | Accuracy: {accuracy:.2f}%\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T17:39:22.823908Z","iopub.execute_input":"2025-06-24T17:39:22.824127Z","iopub.status.idle":"2025-06-24T17:49:06.857220Z","shell.execute_reply.started":"2025-06-24T17:39:22.824110Z","shell.execute_reply":"2025-06-24T17:49:06.856259Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.eval()\npredictions = []\n\nwith torch.no_grad():\n    for batch in test_dataloader:\n        outputs = model(batch[0])\n        probs = torch.sigmoid(outputs) \n        \n        predicted = (probs > 0.5).float()\n        correct += (predicted == labels).sum().item()\n        total += labels.size(0)\n\n    print(f\"Test Accuracy: {correct / total:.2%}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T17:49:06.859619Z","iopub.execute_input":"2025-06-24T17:49:06.859854Z","iopub.status.idle":"2025-06-24T17:49:28.275104Z","shell.execute_reply.started":"2025-06-24T17:49:06.859835Z","shell.execute_reply":"2025-06-24T17:49:28.274399Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torch.utils.data import DataLoader, TensorDataset\n\n# Assume test_images is a list of tensors with shape [3, H, W]\n# Stack into a batch tensor of shape [N, 3, H, W]\ntest_tensor = torch.stack(test_images)  # [N, C, H, W]\ntest_dataset = TensorDataset(test_tensor)\ntest_loader = DataLoader(test_dataset, batch_size=32)  # adjust batch size as needed\n\nmodel.eval()\npredictions = []\n\nwith torch.no_grad():\n    for (batch,) in test_loader:\n        batch = batch.to(device)\n        outputs = model(batch)\n        outputs = torch.sigmoid(outputs)\n        predictions.extend(outputs.cpu())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T17:49:28.275874Z","iopub.execute_input":"2025-06-24T17:49:28.276063Z","iopub.status.idle":"2025-06-24T17:49:34.186162Z","shell.execute_reply.started":"2025-06-24T17:49:28.276048Z","shell.execute_reply":"2025-06-24T17:49:34.185504Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"outputs = []\n\nfor pred in predictions:\n    outputs.append(float(pred))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T18:10:31.190128Z","iopub.execute_input":"2025-06-24T18:10:31.190890Z","iopub.status.idle":"2025-06-24T18:10:31.202548Z","shell.execute_reply.started":"2025-06-24T18:10:31.190864Z","shell.execute_reply":"2025-06-24T18:10:31.201795Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.read_csv(\"/kaggle/input/dogs-vs-cats-redux-kernels-edition/sample_submission.csv\")\n\nsubmission[\"label\"] = outputs\nsubmission.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T18:11:56.950720Z","iopub.execute_input":"2025-06-24T18:11:56.951373Z","iopub.status.idle":"2025-06-24T18:11:56.987184Z","shell.execute_reply.started":"2025-06-24T18:11:56.951327Z","shell.execute_reply":"2025-06-24T18:11:56.986480Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = pd.read_csv(\"/kaggle/working/submission.csv\")\ndf","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T18:11:57.630912Z","iopub.execute_input":"2025-06-24T18:11:57.631791Z","iopub.status.idle":"2025-06-24T18:11:57.647637Z","shell.execute_reply.started":"2025-06-24T18:11:57.631764Z","shell.execute_reply":"2025-06-24T18:11:57.646838Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}