{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":31011,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport torch\nimport torchvision\nfrom torchvision import transforms, models\nfrom torch.utils.data import DataLoader, Dataset\nfrom PIL import Image\nimport pandas as pd\nimport numpy as np\nfrom sklearn.model_selection import train_test_split\nimport torch.nn as nn\nfrom tqdm import tqdm\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-05-02T18:14:58.744716Z","iopub.execute_input":"2025-05-02T18:14:58.745047Z","iopub.status.idle":"2025-05-02T18:15:07.264948Z","shell.execute_reply.started":"2025-05-02T18:14:58.745024Z","shell.execute_reply":"2025-05-02T18:15:07.264168Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class CatsDogsDataset(Dataset):\n    def __init__(self, file_paths, labels, transform=None):\n        self.file_paths = file_paths\n        self.labels = labels\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.file_paths)\n\n    def __getitem__(self, idx):\n        image = Image.open(self.file_paths[idx]).convert(\"RGB\")\n        label = self.labels[idx]\n        if self.transform:\n            image = self.transform(image)\n        return image, label\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T18:15:57.049153Z","iopub.execute_input":"2025-05-02T18:15:57.049583Z","iopub.status.idle":"2025-05-02T18:15:57.055250Z","shell.execute_reply.started":"2025-05-02T18:15:57.049559Z","shell.execute_reply":"2025-05-02T18:15:57.054438Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import zipfile\n\nzip_path = \"/kaggle/input/dogs-vs-cats/train.zip\"\nextract_path = \"/kaggle/working/train\"\n\n# Распаковка архива\nwith zipfile.ZipFile(zip_path, 'r') as zip_ref:\n    zip_ref.extractall(extract_path)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T18:15:59.668517Z","iopub.execute_input":"2025-05-02T18:15:59.668836Z","iopub.status.idle":"2025-05-02T18:16:08.555958Z","shell.execute_reply.started":"2025-05-02T18:15:59.668808Z","shell.execute_reply":"2025-05-02T18:16:08.555266Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"DATA_DIR = \"/kaggle/working/train/train\"\nall_files = [os.path.join(DATA_DIR, fname) for fname in os.listdir(DATA_DIR)]\nlabels = [1 if \"dog\" in fname else 0 for fname in os.listdir(DATA_DIR)]  # 1 = dog, 0 = cat\n\ntrain_files, val_files, train_labels, val_labels = train_test_split(all_files, labels, test_size=0.1, random_state=42)\n\ntransform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n])\n\ntrain_dataset = CatsDogsDataset(train_files, train_labels, transform=transform)\nval_dataset = CatsDogsDataset(val_files, val_labels, transform=transform)\n\ntrain_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=32, shuffle=False)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T18:16:17.792150Z","iopub.execute_input":"2025-05-02T18:16:17.792462Z","iopub.status.idle":"2025-05-02T18:16:17.856344Z","shell.execute_reply.started":"2025-05-02T18:16:17.792439Z","shell.execute_reply":"2025-05-02T18:16:17.855585Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\nmodel = models.resnet18(pretrained=True)\nmodel.fc = nn.Linear(model.fc.in_features, 2)  # 2 classes: cat, dog\nmodel = model.to(device)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T18:16:20.605854Z","iopub.execute_input":"2025-05-02T18:16:20.606138Z","iopub.status.idle":"2025-05-02T18:16:21.599916Z","shell.execute_reply.started":"2025-05-02T18:16:20.606118Z","shell.execute_reply":"2025-05-02T18:16:21.599116Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=1e-4)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T18:16:24.099886Z","iopub.execute_input":"2025-05-02T18:16:24.100179Z","iopub.status.idle":"2025-05-02T18:16:24.104574Z","shell.execute_reply.started":"2025-05-02T18:16:24.100156Z","shell.execute_reply":"2025-05-02T18:16:24.103665Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for epoch in range(5):\n    model.train()\n    running_loss = 0.0\n    correct = 0\n\n    for images, labels in tqdm(train_loader):\n        images, labels = images.to(device), labels.to(device)\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        _, preds = torch.max(outputs, 1)\n        correct += (preds == labels).sum().item()\n\n    acc = correct / len(train_dataset)\n    print(f\"Epoch {epoch+1}, Loss: {running_loss:.4f}, Accuracy: {acc:.4f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T18:16:26.708323Z","iopub.execute_input":"2025-05-02T18:16:26.708583Z","iopub.status.idle":"2025-05-02T18:27:46.062543Z","shell.execute_reply.started":"2025-05-02T18:16:26.708565Z","shell.execute_reply":"2025-05-02T18:27:46.061675Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.eval()\ncorrect = 0\n\nwith torch.no_grad():\n    for images, labels in val_loader:\n        images, labels = images.to(device), labels.to(device)\n        outputs = model(images)\n        _, preds = torch.max(outputs, 1)\n        correct += (preds == labels).sum().item()\n\nval_acc = correct / len(val_dataset)\nprint(f\"Validation Accuracy: {val_acc:.4f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T18:30:42.585492Z","iopub.execute_input":"2025-05-02T18:30:42.586327Z","iopub.status.idle":"2025-05-02T18:30:53.052544Z","shell.execute_reply.started":"2025-05-02T18:30:42.586276Z","shell.execute_reply":"2025-05-02T18:30:53.051771Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_dir = \"/kaggle/working/train/test1\"\ntest_files = [os.path.join(test_dir, fname) for fname in os.listdir(test_dir)]\ntest_ids = [int(os.path.basename(fname).split(\".\")[0]) for fname in test_files]\n\nclass TestDataset(Dataset):\n    def __init__(self, file_paths, transform=None):\n        self.file_paths = file_paths\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.file_paths)\n\n    def __getitem__(self, idx):\n        image = Image.open(self.file_paths[idx]).convert(\"RGB\")\n        if self.transform:\n            image = self.transform(image)\n        return image\n\ntest_dataset = TestDataset(test_files, transform=transform)\ntest_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)\n\nmodel.eval()\npredictions = []\n\nwith torch.no_grad():\n    for images in test_loader:\n        images = images.to(device)\n        outputs = model(images)\n        _, preds = torch.max(outputs, 1)\n        predictions.extend(preds.cpu().numpy())\n\nsubmission = pd.DataFrame({\"id\": test_ids, \"label\": predictions})\nsubmission.sort_values(\"id\", inplace=True)\nsubmission.to_csv(\"submission.csv\", index=False)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-02T18:33:15.880543Z","iopub.execute_input":"2025-05-02T18:33:15.881280Z","iopub.status.idle":"2025-05-02T18:34:07.088145Z","shell.execute_reply.started":"2025-05-02T18:33:15.881256Z","shell.execute_reply":"2025-05-02T18:34:07.087541Z"}},"outputs":[],"execution_count":null}]}