{"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":"gpu","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":30762,"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","execution":{"iopub.status.busy":"2024-09-16T14:50:19.656017Z","iopub.execute_input":"2024-09-16T14:50:19.656402Z","iopub.status.idle":"2024-09-16T14:50:20.052655Z","shell.execute_reply.started":"2024-09-16T14:50:19.656364Z","shell.execute_reply":"2024-09-16T14:50:20.051704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **DO NOT CHANGE ANYTHING HERE!**\n\nIf you want to change something, you should download this notebook first.\n\n## Before starting, please do this first to speed up the training process:\n1. select 'Settings'\n2. select 'Accelerator'\n3. select GPU 'GPU P100'\n\ncan only be done for Kaggle accounts that have **verified** cell phone numbers","metadata":{}},{"cell_type":"code","source":"import torch\nimport torchvision\nimport torchvision.transforms as transforms\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torchvision.datasets import ImageFolder\nfrom torchvision import models\nfrom torch.utils.data import DataLoader, random_split\n\n\nimport zipfile\nimport os\n","metadata":{"execution":{"iopub.status.busy":"2024-09-16T14:50:23.040199Z","iopub.execute_input":"2024-09-16T14:50:23.040717Z","iopub.status.idle":"2024-09-16T14:50:25.665478Z","shell.execute_reply.started":"2024-09-16T14:50:23.040678Z","shell.execute_reply":"2024-09-16T14:50:25.664695Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Unzip the Files in the Working Directory","metadata":{}},{"cell_type":"code","source":"# Unzipping the train.zip file to the working directory\nwith zipfile.ZipFile('/kaggle/input/dogs-vs-cats/train.zip', 'r') as zip_ref:\n    zip_ref.extractall('/kaggle/working/train')\n\n# Unzipping the test1.zip file to the working directory (optional if needed)\nwith zipfile.ZipFile('/kaggle/input/dogs-vs-cats/test1.zip', 'r') as zip_ref:\n    zip_ref.extractall('/kaggle/working/test')\n\n# Check if files are extracted correctly\nprint(os.listdir('/kaggle/working/train'))","metadata":{"execution":{"iopub.status.busy":"2024-09-16T14:50:28.650174Z","iopub.execute_input":"2024-09-16T14:50:28.650840Z","iopub.status.idle":"2024-09-16T14:50:39.877083Z","shell.execute_reply.started":"2024-09-16T14:50:28.650794Z","shell.execute_reply":"2024-09-16T14:50:39.876085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Data Pre-Processing and Splitting Data","metadata":{}},{"cell_type":"code","source":"# Define transformations\ntransform = transforms.Compose([\n    transforms.Resize((224, 224)),  # Resizing images to 224x224 for ResNet\n    transforms.RandomHorizontalFlip(),  # Random horizontal flip for augmentation\n    transforms.ToTensor(),  # Convert to tensor\n    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])  # Normalize as per ResNet requirements\n])","metadata":{"execution":{"iopub.status.busy":"2024-09-16T14:50:44.577612Z","iopub.execute_input":"2024-09-16T14:50:44.578043Z","iopub.status.idle":"2024-09-16T14:50:44.703911Z","shell.execute_reply.started":"2024-09-16T14:50:44.578005Z","shell.execute_reply":"2024-09-16T14:50:44.703029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Now load the dataset from the unzipped train folder\ndata_dir = '/kaggle/working/train/'\ndataset = ImageFolder(root=data_dir, transform=transform)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Split dataset into training and validation sets\ntrain_size = int(0.6 * len(dataset))\nvalid_size = int(0.2 * len(dataset))\ntest_size = len(dataset) - train_size - valid_size\n\ntrain_dataset, valid_dataset, test_dataset = random_split(dataset, [train_size, valid_size, test_size])","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create data loaders\ntrain_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)\nvalid_loader = DataLoader(valid_dataset, batch_size=32, shuffle=False)\ntest_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Define the Model and Optimizer","metadata":{}},{"cell_type":"code","source":"# Load pre-trained ResNet18 model\nmodel = models.resnet18(pretrained=True)\n\n# Modify the final layer to match binary classification (2 classes: dog and cat)\nnum_ftrs = model.fc.in_features\nmodel.fc = nn.Linear(num_ftrs, 2)  # 2 classes (dog, cat)\n\n# Move model to GPU\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel = model.to(device)\n\n# Loss function and optimizer\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)","metadata":{"execution":{"iopub.status.busy":"2024-09-16T14:52:08.063784Z","iopub.execute_input":"2024-09-16T14:52:08.064829Z","iopub.status.idle":"2024-09-16T14:52:08.933549Z","shell.execute_reply.started":"2024-09-16T14:52:08.064784Z","shell.execute_reply":"2024-09-16T14:52:08.932520Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Training Loop","metadata":{}},{"cell_type":"code","source":"num_epochs = 3  # You can adjust this number\n\nfor epoch in range(num_epochs):\n    model.train()  # Set model to training mode\n    running_loss = 0.0\n    correct = 0\n    total = 0\n    \n    for inputs, labels in train_loader:\n        inputs, labels = inputs.to(device), labels.to(device)\n        \n        optimizer.zero_grad()  # Clear gradients\n        \n        outputs = model(inputs)  # Forward pass\n        loss = criterion(outputs, labels)  # Compute loss\n        \n        loss.backward()  # Backward pass\n        optimizer.step()  # Update weights\n        \n        running_loss += loss.item()\n        _, predicted = outputs.max(1)\n        total += labels.size(0)\n        correct += predicted.eq(labels).sum().item()\n    \n    train_loss = running_loss / len(train_loader)\n    train_acc = 100 * correct / total\n\n    # Validation phase\n    model.eval()  # Set model to evaluation mode\n    valid_loss = 0.0\n    valid_correct = 0\n    valid_total = 0\n    \n    with torch.no_grad():\n        for inputs, labels in valid_loader:\n            inputs, labels = inputs.to(device), labels.to(device)\n            outputs = model(inputs)\n            loss = criterion(outputs, labels)\n            valid_loss += loss.item()\n            \n            _, predicted = outputs.max(1)\n            valid_total += labels.size(0)\n            valid_correct += predicted.eq(labels).sum().item()\n\n    valid_loss /= len(valid_loader)\n    valid_acc = 100 * valid_correct / valid_total\n\n    print(f\"Epoch {epoch+1}/{num_epochs}, Train Loss: {train_loss:.4f}, Train Acc: {train_acc:.2f}%, Valid Loss: {valid_loss:.4f}, Valid Acc: {valid_acc:.2f}%\")","metadata":{"execution":{"iopub.status.busy":"2024-09-16T14:52:24.174663Z","iopub.execute_input":"2024-09-16T14:52:24.175915Z","iopub.status.idle":"2024-09-16T14:57:12.128624Z","shell.execute_reply.started":"2024-09-16T14:52:24.175870Z","shell.execute_reply":"2024-09-16T14:57:12.127572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Testing the Model","metadata":{}},{"cell_type":"code","source":"# Test the model on the test dataset\nmodel.eval()\ntest_correct = 0\ntest_total = 0\n\nwith torch.no_grad():\n    for inputs, labels in test_loader:\n        inputs, labels = inputs.to(device), labels.to(device)\n        outputs = model(inputs)\n        _, predicted = outputs.max(1)\n        test_total += labels.size(0)\n        test_correct += predicted.eq(labels).sum().item()\n\ntest_acc = 100 * test_correct / test_total\nprint(f\"Test Accuracy: {test_acc:.2f}%\")","metadata":{"execution":{"iopub.status.busy":"2024-09-16T14:57:50.477112Z","iopub.execute_input":"2024-09-16T14:57:50.477522Z","iopub.status.idle":"2024-09-16T14:58:09.787949Z","shell.execute_reply.started":"2024-09-16T14:57:50.477483Z","shell.execute_reply":"2024-09-16T14:58:09.786986Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Save the Model","metadata":{}},{"cell_type":"code","source":"torch.save(model.state_dict(), '/kaggle/working/resnet_dogs_vs_cats.pth')","metadata":{"execution":{"iopub.status.busy":"2024-09-16T14:58:28.887734Z","iopub.execute_input":"2024-09-16T14:58:28.888610Z","iopub.status.idle":"2024-09-16T14:58:28.961350Z","shell.execute_reply.started":"2024-09-16T14:58:28.888569Z","shell.execute_reply":"2024-09-16T14:58:28.960524Z"},"trusted":true},"execution_count":null,"outputs":[]}]}