{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":34426,"databundleVersionId":3218632,"sourceType":"competition"}],"dockerImageVersionId":30683,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport random\nfrom PIL import Image\nfrom tqdm import tqdm\n\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\nimport torchvision\nfrom torchvision import transforms\nfrom torchvision.models import resnet34","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 128\nlearning_rate = 1e-4\nnum_epochs = 5\nimg_size = 224","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def set_seed(seed):\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n    np.random.seed(seed)\n    random.seed(seed)\n\n\nset_seed(42)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample = pd.read_csv('/kaggle/input/dog-vs-cat-classification/sample_submission.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cats_train_dir = '/kaggle/input/dog-vs-cat-classification/train/train/cats'\ndogs_train_dir = '/kaggle/input/dog-vs-cat-classification/train/train/dogs'\ntest_dir = '/kaggle/input/dog-vs-cat-classification/test/test'\n\ncats_train_filenames = [os.path.join(cats_train_dir, f) for f in os.listdir(cats_train_dir)]\ndogs_train_filenames = [os.path.join(dogs_train_dir, f) for f in os.listdir(dogs_train_dir)]\n\ntrain_filenames = [*cats_train_filenames, *dogs_train_filenames]\ntest_filenames = sorted([os.path.join(test_dir, f) for f in os.listdir(test_dir)])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_transforms = transforms.Compose([\n    transforms.Resize((img_size, img_size)),\n    transforms.ToTensor(),\n    transforms.Normalize(0.5, 0.5)\n])\n\ntest_transforms = transforms.Compose([\n    transforms.Resize((img_size, img_size)),\n    transforms.ToTensor(),\n    transforms.Normalize(0.5, 0.5)\n])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DogandCat(Dataset):\n    def __init__(self, filenames, transforms):\n        self.filenames = filenames\n        self.transforms = transforms\n        \n    def __len__(self):\n        return len(self.filenames)\n    \n    def __getitem__(self, idx):\n        img = Image.open(self.filenames[idx])\n        transformed_img = self.transforms(img)\n        label = 0 if self.filenames[idx].split('/')[-1].split('.')[0] == 'cat' else 1\n        return transformed_img, label","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = DogandCat(train_filenames[:20000], train_transforms)\nvalid_dataset = DogandCat(train_filenames[20000:], test_transforms)\ntest_dataset = DogandCat(test_filenames, test_transforms)\n\ntrain_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\nvalid_loader = DataLoader(valid_dataset, batch_size=batch_size, shuffle=False)\ntest_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ResNet34(nn.Module):\n    def __init__(self, num_classes):\n        super(ResNet34, self).__init__()\n        self.model = resnet34(weights='DEFAULT')\n        self.in_features = self.model.fc.in_features\n        self.model.fc = nn.Linear(self.in_features, num_classes)\n    \n    def forward(self, x):\n        x = self.model(x)\n        return x","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = 'cuda' if torch.cuda.is_available() else 'cpu'\n\nmodel = ResNet34(num_classes=2).to(device)\noptimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)\ncriterion = nn.CrossEntropyLoss().to(device)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for epoch in range(num_epochs):\n    print(\"-\"*40)\n    print(f\"Epoch: {epoch+1}\")\n    epoch_loss = 0.0\n    epoch_corrects = 0\n    model.train()\n    for batch_in, batch_out in tqdm(train_loader):\n        batch_in = batch_in.to(device)\n        batch_out = batch_out.to(device)\n        \n        y_pred = model(batch_in)\n        preds = torch.argmax(y_pred, 1)\n        loss = criterion(y_pred, batch_out)\n        \n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n        \n        epoch_loss += loss.item() * batch_in.size(0)\n        epoch_corrects += torch.sum(preds == batch_out.data)\n        \n    epoch_loss = epoch_loss / len(train_loader.dataset)\n    epoch_acc = epoch_corrects / len(train_loader.dataset)\n    \n    print(f\"train loss: {epoch_loss:.4f}\")\n    print(f\"train acc: {epoch_acc:.4f}\")\n    \n    epoch_loss = 0.0\n    epoch_corrects = 0\n    model.eval()\n    with torch.no_grad():\n        for batch_in, batch_out in tqdm(valid_loader):\n            batch_in = batch_in.to(device)\n            batch_out = batch_out.to(device)\n\n            y_pred = model(batch_in)\n            preds = torch.argmax(y_pred, 1)\n            loss = criterion(y_pred, batch_out)\n\n            epoch_loss += loss.item() * batch_in.size(0)\n            epoch_corrects += torch.sum(preds == batch_out.data)\n        \n    epoch_loss = epoch_loss / len(valid_loader.dataset)\n    epoch_acc = epoch_corrects / len(valid_loader.dataset)\n    \n    print(f\"valid loss: {epoch_loss:.4f}\")\n    print(f\"valid acc: {epoch_acc:.4f}\")\n    print(\"-\"*40)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"result = []\n\nwith torch.no_grad():\n    model.eval()\n    for batch_in, batch_out in tqdm(test_loader):\n        batch_in = batch_in.to(device)\n        batch_out = batch_out.to(device)\n        \n        y_pred = model(batch_in)\n        preds = torch.argmax(y_pred, 1)\n        result.extend(preds.cpu().numpy())\n\nsample['labels'] = result\nsample.to_csv('./predict.csv', index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Visualization \nimport matplotlib.pyplot as plt\n\nfor i in range(12):\n    plt.subplot(3, 4,i+1)\n    image = plt.imread(os.path.join(test_filenames[i]))\n    plt.imshow(image)\n    plt.axis(\"off\")\n    title = \"cat \" if int(result[i]) == 0 else 'dog'\n    plt.title(f\"label: {title}\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}