{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":30786,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torchvision import datasets, transforms, models\nfrom torch.utils.data import DataLoader ,Dataset\nimport os\nfrom tqdm import tqdm\nimport zipfile\nfrom PIL import Image","metadata":{"_uuid":"bc06c65e-683f-40de-9163-aa4a1b789dde","_cell_guid":"f713a7f6-f590-4cc3-8b5c-b2516ae531ea","trusted":true,"collapsed":false,"execution":{"iopub.status.busy":"2024-11-12T17:33:03.673929Z","iopub.execute_input":"2024-11-12T17:33:03.674235Z","iopub.status.idle":"2024-11-12T17:33:08.178862Z","shell.execute_reply.started":"2024-11-12T17:33:03.674203Z","shell.execute_reply":"2024-11-12T17:33:08.178066Z"},"jupyter":{"outputs_hidden":false}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Define paths for zip files and extraction directory\ntrain_zip_path = '/kaggle/input/dogs-vs-cats/train.zip'\ntest_zip_path = '/kaggle/input/dogs-vs-cats/test1.zip'\nextract_to_directory = '/kaggle/working/'","metadata":{"_uuid":"3c222717-07c8-4687-8a55-5a8355d6a7d3","_cell_guid":"0b478914-2c18-4202-982e-6735f6b2a641","trusted":true,"collapsed":false,"execution":{"iopub.status.busy":"2024-11-12T17:33:09.189914Z","iopub.execute_input":"2024-11-12T17:33:09.190819Z","iopub.status.idle":"2024-11-12T17:33:09.196611Z","shell.execute_reply.started":"2024-11-12T17:33:09.190771Z","shell.execute_reply":"2024-11-12T17:33:09.194405Z"},"jupyter":{"outputs_hidden":false}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Extract zip files\nwith zipfile.ZipFile(train_zip_path, 'r') as zip_ref:\n    zip_ref.extractall(extract_to_directory)\n\nwith zipfile.ZipFile(test_zip_path, 'r') as zip_ref:\n    zip_ref.extractall(extract_to_directory)","metadata":{"_uuid":"cfc734e5-37d2-45ec-8616-5ed9ef836766","_cell_guid":"4e4e3dfb-3e7c-436b-a013-f9aa593e686f","trusted":true,"collapsed":false,"execution":{"iopub.status.busy":"2024-11-12T17:33:10.203329Z","iopub.execute_input":"2024-11-12T17:33:10.204131Z","iopub.status.idle":"2024-11-12T17:33:24.146951Z","shell.execute_reply.started":"2024-11-12T17:33:10.204091Z","shell.execute_reply":"2024-11-12T17:33:24.145917Z"},"jupyter":{"outputs_hidden":false}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Define paths to train and test directories after extraction\ntrain_dir = '/kaggle/working/train'\ntest_dir = '/kaggle/working/test1'","metadata":{"_uuid":"78bceb94-7bd5-4c3b-bf99-434767a1f88b","_cell_guid":"b5e73d6a-6087-417c-a7ce-923f55281e9c","trusted":true,"collapsed":false,"execution":{"iopub.status.busy":"2024-11-12T17:33:24.148767Z","iopub.execute_input":"2024-11-12T17:33:24.149114Z","iopub.status.idle":"2024-11-12T17:33:24.153262Z","shell.execute_reply.started":"2024-11-12T17:33:24.149080Z","shell.execute_reply":"2024-11-12T17:33:24.152415Z"},"jupyter":{"outputs_hidden":false}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if not os.path.exists(f\"{train_dir}/cat\"):\n    os.makedirs(f\"{train_dir}/cat\")\n    os.makedirs(f\"{train_dir}/dog\")\n    for file in os.listdir(train_dir):\n        file_path = os.path.join(train_dir, file)\n        if os.path.isfile(file_path):  # Ensure it's a file, not a directory\n            if \"cat\" in file:\n                os.rename(file_path, os.path.join(train_dir, \"cat\", file))\n            elif \"dog\" in file:\n                os.rename(file_path, os.path.join(train_dir, \"dog\", file))","metadata":{"_uuid":"c67d586b-9d38-4c69-81ad-019c3a41175e","_cell_guid":"1ce1227b-8f9b-4358-9fe6-50a9b6e5a07c","trusted":true,"collapsed":false,"execution":{"iopub.status.busy":"2024-11-12T17:33:24.154409Z","iopub.execute_input":"2024-11-12T17:33:24.154764Z","iopub.status.idle":"2024-11-12T17:33:24.987388Z","shell.execute_reply.started":"2024-11-12T17:33:24.154719Z","shell.execute_reply":"2024-11-12T17:33:24.986524Z"},"jupyter":{"outputs_hidden":false}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# Define a custom dataset for the test set without subdirectories\nclass TestDataset(Dataset):\n    def __init__(self, test_dir, transform=None):\n        self.test_dir = test_dir\n        self.image_files = os.listdir(test_dir)\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.image_files)\n\n    def __getitem__(self, idx):\n        img_name = self.image_files[idx]\n        img_path = os.path.join(self.test_dir, img_name)\n        image = Image.open(img_path).convert(\"RGB\")\n        \n        if self.transform:\n            image = self.transform(image)\n        \n        return image, img_name  # Return image with filename","metadata":{"_uuid":"84e163ce-8023-4188-ade6-787d2664105f","_cell_guid":"e5e0fd4d-1f95-422f-8a95-c84c9ab7be5f","trusted":true,"collapsed":false,"execution":{"iopub.status.busy":"2024-11-12T17:33:24.989616Z","iopub.execute_input":"2024-11-12T17:33:24.990000Z","iopub.status.idle":"2024-11-12T17:33:24.996885Z","shell.execute_reply.started":"2024-11-12T17:33:24.989954Z","shell.execute_reply":"2024-11-12T17:33:24.996028Z"},"jupyter":{"outputs_hidden":false}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Data augmentation and normalization for training\n# Just normalization for validation/testing\ntransform_train = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.RandomHorizontalFlip(),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n])\n\ntransform_test = 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])","metadata":{"_uuid":"0023582d-1779-4111-9a0c-cf904fa1cd8a","_cell_guid":"9e4ee2b6-b9c3-4bb1-8773-176b50b3ef4b","trusted":true,"collapsed":false,"execution":{"iopub.status.busy":"2024-11-12T17:33:24.998110Z","iopub.execute_input":"2024-11-12T17:33:24.998505Z","iopub.status.idle":"2024-11-12T17:33:25.007244Z","shell.execute_reply.started":"2024-11-12T17:33:24.998460Z","shell.execute_reply":"2024-11-12T17:33:25.006534Z"},"jupyter":{"outputs_hidden":false}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"_uuid":"02281ec4-4ffc-48c4-83eb-c0f4d77b75e9","_cell_guid":"4cc49646-816b-45fd-bf39-9c8efef3cf0e","trusted":true,"collapsed":false,"execution":{"iopub.status.busy":"2024-11-12T17:14:55.412557Z","iopub.execute_input":"2024-11-12T17:14:55.412980Z","iopub.status.idle":"2024-11-12T17:15:17.784583Z","shell.execute_reply.started":"2024-11-12T17:14:55.412938Z","shell.execute_reply":"2024-11-12T17:15:17.783369Z"},"jupyter":{"outputs_hidden":false}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load data\ntrain_dataset = datasets.ImageFolder(root=train_dir, transform=transform_train)\ntest_dataset = TestDataset(test_dir, transform=transform_test)\n\n# Data loaders\ntrain_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)\ntest_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)","metadata":{"_uuid":"ac2cc0da-97b9-4121-ae52-fcc946761ad3","_cell_guid":"b46dba41-aee7-439f-a461-45969e0b8b1d","trusted":true,"collapsed":false,"execution":{"iopub.status.busy":"2024-11-12T17:33:47.874648Z","iopub.execute_input":"2024-11-12T17:33:47.875025Z","iopub.status.idle":"2024-11-12T17:33:47.995509Z","shell.execute_reply.started":"2024-11-12T17:33:47.874989Z","shell.execute_reply":"2024-11-12T17:33:47.994761Z"},"jupyter":{"outputs_hidden":false}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load pre-trained ResNet18 model\nmodel = models.resnet18(pretrained=True)\n\n# Freeze all layers except the last one\nfor param in model.parameters():\n    param.requires_grad = False\n\n# Modify the last fully connected layer to have 2 output classes (cats and dogs)\nmodel.fc = nn.Linear(model.fc.in_features, 2)\n\n# Move the model to GPU if available\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel = model.to(device)","metadata":{"_uuid":"9ffdc2c8-5d71-402f-aa81-235732551c6b","_cell_guid":"15f76169-987a-4537-ad03-01f5ee13cfd6","trusted":true,"collapsed":false,"execution":{"iopub.status.busy":"2024-11-12T17:34:23.583156Z","iopub.execute_input":"2024-11-12T17:34:23.583893Z","iopub.status.idle":"2024-11-12T17:34:24.451603Z","shell.execute_reply.started":"2024-11-12T17:34:23.583849Z","shell.execute_reply":"2024-11-12T17:34:24.450607Z"},"jupyter":{"outputs_hidden":false}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Loss function and optimizer\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.fc.parameters(), lr=0.001)","metadata":{"_uuid":"b3d6dc61-43e1-4e82-ae66-e89cda0711e4","_cell_guid":"a27e6cc8-d6d7-42ff-916c-6ee3721aecda","trusted":true,"collapsed":false,"execution":{"iopub.status.busy":"2024-11-12T17:34:28.709767Z","iopub.execute_input":"2024-11-12T17:34:28.710560Z","iopub.status.idle":"2024-11-12T17:34:28.716179Z","shell.execute_reply.started":"2024-11-12T17:34:28.710506Z","shell.execute_reply":"2024-11-12T17:34:28.715260Z"},"jupyter":{"outputs_hidden":false}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torch.utils.data import random_split\n\n# Split the train dataset into training and validation datasets\ntrain_size = int(0.8 * len(train_dataset))  # 80% for training\nval_size = len(train_dataset) - train_size  # Remaining 20% for validation\n\ntrain_dataset, val_dataset = random_split(train_dataset, [train_size, val_size])\n\n# Create data loaders for the validation dataset\nval_loader = DataLoader(val_dataset, batch_size=32, shuffle=False)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-12T18:02:02.568622Z","iopub.execute_input":"2024-11-12T18:02:02.569303Z","iopub.status.idle":"2024-11-12T18:02:02.576711Z","shell.execute_reply.started":"2024-11-12T18:02:02.569263Z","shell.execute_reply":"2024-11-12T18:02:02.575685Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# Train the model\nnum_epochs = 10\n\nfor epoch in range(num_epochs):\n    model.train()  # Set the model to training mode\n    running_loss = 0.0\n    correct_predictions = 0\n    total_predictions = 0\n    \n    for inputs, labels in tqdm(train_loader, desc=f\"Epoch {epoch + 1}/{num_epochs}\"):\n        inputs, labels = inputs.to(device), labels.to(device)  # Move inputs and labels to device\n\n        optimizer.zero_grad()  # Zero out the gradients\n\n        # Forward pass\n        outputs = model(inputs)\n        loss = criterion(outputs, labels)\n        \n        # Backward pass\n        loss.backward()\n        optimizer.step()\n\n        # Track loss and accuracy\n        running_loss += loss.item()\n        _, predicted = torch.max(outputs, 1)\n        correct_predictions += (predicted == labels).sum().item()\n        total_predictions += labels.size(0)\n\n    # Compute the average loss and accuracy\n    epoch_loss = running_loss / len(train_loader)\n    epoch_accuracy = 100 * correct_predictions / total_predictions\n\n    print(f\"Epoch {epoch + 1}, Loss: {epoch_loss:.4f}, Accuracy: {epoch_accuracy:.2f}%\")\n\n    # Evaluate the model on the validation set after each epoch\n    model.eval()  # Set the model to evaluation mode\n    correct_predictions = 0\n    total_predictions = 0\n\n    with torch.no_grad():  # No need to track gradients during evaluation\n        for inputs, labels in val_loader:\n            inputs = inputs.to(device)  # Move inputs to device\n            labels = labels.to(device)  # Move labels to device\n\n            # Forward pass\n            outputs = model(inputs)\n            _, predicted = torch.max(outputs, 1)\n            correct_predictions += (predicted == labels).sum().item()\n            total_predictions += labels.size(0)\n\n    val_accuracy = 100 * correct_predictions / total_predictions\n    print(f\"Validation Accuracy: {val_accuracy:.2f}%\\n\")\n\n# After training, test the model on the test set\nmodel.eval()  # Set the model to evaluation mode\ncorrect_predictions = 0\ntotal_predictions = 0\n\nwith torch.no_grad():  # No need to track gradients during evaluation\n    for inputs, _ in test_loader:  # Ignore labels\n        inputs = inputs.to(device)  # Move inputs to device\n\n        # Forward pass\n        outputs = model(inputs)\n        _, predicted = torch.max(outputs, 1)\n        # Process predictions (e.g., store them or compute metrics)\n\n# Test Accuracy (if you had labels in the test set)\n# print(f\"Test Accuracy: {test_accuracy:.2f}%\")\n","metadata":{"_uuid":"f3a0717e-2099-47d4-bf97-deccfdf7bbf1","_cell_guid":"e26d9516-0d88-4cd8-aa18-633e4be24e14","trusted":true,"collapsed":false,"execution":{"iopub.status.busy":"2024-11-12T18:02:07.826205Z","iopub.execute_input":"2024-11-12T18:02:07.826817Z","iopub.status.idle":"2024-11-12T18:04:33.897266Z","shell.execute_reply.started":"2024-11-12T18:02:07.826778Z","shell.execute_reply":"2024-11-12T18:04:33.895856Z"},"jupyter":{"outputs_hidden":false}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Save the model\ntorch.save(model.state_dict(), 'cats_vs_dogs_resnet18.pth')","metadata":{"_uuid":"5cd64e03-e4d0-478c-97a8-ed8c2a2a6563","_cell_guid":"0d193b44-ed6f-443b-b177-f4d4f4f62dd6","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-11-12T18:04:35.371068Z","iopub.execute_input":"2024-11-12T18:04:35.371453Z","iopub.status.idle":"2024-11-12T18:04:35.449996Z","shell.execute_reply.started":"2024-11-12T18:04:35.371415Z","shell.execute_reply":"2024-11-12T18:04:35.449201Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}