{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport shutil\nimport pandas as pd\nimport numpy as np\nfrom PIL import Image\nfrom pathlib import Path\nimport torch\nfrom torch import nn\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset, DataLoader, random_split\nfrom torchvision import transforms\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2023-04-17T02:05:49.080326Z","iopub.execute_input":"2023-04-17T02:05:49.080980Z","iopub.status.idle":"2023-04-17T02:05:52.293152Z","shell.execute_reply.started":"2023-04-17T02:05:49.080936Z","shell.execute_reply":"2023-04-17T02:05:52.291911Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# shutil.rmtree('/kaggle/working/train')\n# shutil.rmtree('/kaggle/working/test')","metadata":{"execution":{"iopub.status.busy":"2023-04-17T02:05:52.295103Z","iopub.execute_input":"2023-04-17T02:05:52.299834Z","iopub.status.idle":"2023-04-17T02:05:52.305468Z","shell.execute_reply.started":"2023-04-17T02:05:52.299802Z","shell.execute_reply":"2023-04-17T02:05:52.303113Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"shutil.unpack_archive('/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip',\n                      '/kaggle/working')\nshutil.unpack_archive('/kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip',\n                      '/kaggle/working')","metadata":{"execution":{"iopub.status.busy":"2023-04-17T02:05:52.306944Z","iopub.execute_input":"2023-04-17T02:05:52.308011Z","iopub.status.idle":"2023-04-17T02:06:11.358745Z","shell.execute_reply.started":"2023-04-17T02:05:52.307921Z","shell.execute_reply":"2023-04-17T02:06:11.357657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nprint(\"device: \", device)","metadata":{"execution":{"iopub.status.busy":"2023-04-17T02:06:11.361906Z","iopub.execute_input":"2023-04-17T02:06:11.363054Z","iopub.status.idle":"2023-04-17T02:06:11.429347Z","shell.execute_reply.started":"2023-04-17T02:06:11.363010Z","shell.execute_reply":"2023-04-17T02:06:11.428115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"get_label = lambda x: x.name.split('.')[0]\n\nclass get_dataset(Dataset):\n    def __init__(self, root, transform=None):\n        self.images = list(Path(root).glob('*.jpg'))\n        self.transform = transform\n    def __len__(self):\n        return len(self.images)\n    def __getitem__(self, idx):\n        img = self.images[idx]\n        label = get_label(img)\n        label = 1 if label == 'dog' else 0\n        if self.transform:\n            img = self.transform(Image.open(img))\n        return img, torch.tensor(label, dtype=torch.int64)","metadata":{"execution":{"iopub.status.busy":"2023-04-17T02:06:11.431437Z","iopub.execute_input":"2023-04-17T02:06:11.432318Z","iopub.status.idle":"2023-04-17T02:06:11.441145Z","shell.execute_reply.started":"2023-04-17T02:06:11.432276Z","shell.execute_reply":"2023-04-17T02:06:11.440150Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transforms = transforms.Compose([\n    transforms.Resize([224, 224]),  # resize the input image to a uniform size\n    transforms.ToTensor(),  # convert PIL Image or numpy.ndarray to tensor and normalize to somewhere between [0,1]\n    transforms.Normalize(   # standardized processing\n        mean=[0.485, 0.456, 0.406],\n        std=[0.229, 0.224, 0.225])\n])","metadata":{"execution":{"iopub.status.busy":"2023-04-17T02:06:11.443463Z","iopub.execute_input":"2023-04-17T02:06:11.444400Z","iopub.status.idle":"2023-04-17T02:06:11.451459Z","shell.execute_reply.started":"2023-04-17T02:06:11.444241Z","shell.execute_reply":"2023-04-17T02:06:11.450763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path = '/kaggle/working/train'\n# get dataset\ndataset = get_dataset(train_path, transform=transforms)\nprint(len(dataset))\n# splitting into train and validation\ntrain_data, valid_data = random_split(dataset, \n        lengths=[int(len(dataset)*0.8),int(len(dataset)*0.2)], \n        generator=torch.Generator().manual_seed(7))\n# print(\"train: \", len(train_data))\n# print(\"valid: \", len(valid_data))\ntrain_loader = DataLoader(train_data, batch_size=64, shuffle=True)\nvalid_loader = DataLoader(valid_data, batch_size=64)","metadata":{"execution":{"iopub.status.busy":"2023-04-17T02:06:11.453024Z","iopub.execute_input":"2023-04-17T02:06:11.453441Z","iopub.status.idle":"2023-04-17T02:06:11.686287Z","shell.execute_reply.started":"2023-04-17T02:06:11.453406Z","shell.execute_reply":"2023-04-17T02:06:11.685129Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CNN(nn.Module):\n    def __init__(self):\n        super(CNN, self).__init__()\n        self.conv1 = nn.Sequential(\n            nn.Conv2d(3, 32, 3),\n            nn.BatchNorm2d(32),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size=2)\n        )\n        self.conv2 = nn.Sequential(\n            nn.Conv2d(32, 64, 3),\n            nn.BatchNorm2d(64),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size=2)\n        )\n        self.conv3 = nn.Sequential(\n            nn.Conv2d(64, 128, 3),\n            nn.BatchNorm2d(128),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size=2)\n        )\n        self.fc1 = nn.Sequential(\n            nn.Linear(128*26*26, 512),\n            nn.BatchNorm1d(512),\n            nn.ReLU()\n        )\n        self.fc2 = nn.Linear(512, 2)\n        \n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.conv2(x)\n        x = self.conv3(x)\n        x = x.view(x.size(0), -1)\n        x = self.fc1(x)\n        x = self.fc2(x)\n        x = F.log_softmax(x, dim=1)\n        return x","metadata":{"execution":{"iopub.status.busy":"2023-04-17T02:06:11.688018Z","iopub.execute_input":"2023-04-17T02:06:11.688408Z","iopub.status.idle":"2023-04-17T02:06:11.700754Z","shell.execute_reply.started":"2023-04-17T02:06:11.688371Z","shell.execute_reply":"2023-04-17T02:06:11.699712Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = CNN()\nmodel.to(device)\nprint(model)","metadata":{"execution":{"iopub.status.busy":"2023-04-17T02:06:11.702007Z","iopub.execute_input":"2023-04-17T02:06:11.702333Z","iopub.status.idle":"2023-04-17T02:06:15.234410Z","shell.execute_reply.started":"2023-04-17T02:06:11.702306Z","shell.execute_reply":"2023-04-17T02:06:15.233178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loss_function = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=1e-3)\n\nepochs = 25\ntrain_loss_list = []\ntrain_acc_list = []\n\nfor epoch in range(epochs):\n    print(\"Epoch {} / {}\".format(epoch + 1, epochs))\n            \n    t_loss, t_corr = 0.0, 0.0\n    \n    model.train() \n    for inputs, labels in train_loader:\n        inputs = inputs.to(device)\n        labels = labels.to(device)\n        \n        preds = model(inputs)\n        loss = loss_function(preds, labels)\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n        t_loss += loss.item() * inputs.size(0)\n        t_corr += torch.sum(preds.argmax(1) == labels) \n        \n    train_loss = t_loss / len(train_loader.dataset)\n    train_acc = t_corr.cpu().numpy() / len(train_loader.dataset)\n    train_loss_list.append(train_loss)\n    train_acc_list.append(train_acc)  \n    print('Train Loss: {:.4f} Accuracy: {:.4f}%'.format(train_loss, train_acc * 100))","metadata":{"execution":{"iopub.status.busy":"2023-04-17T02:06:15.237652Z","iopub.execute_input":"2023-04-17T02:06:15.237996Z","iopub.status.idle":"2023-04-17T02:59:55.121974Z","shell.execute_reply.started":"2023-04-17T02:06:15.237968Z","shell.execute_reply":"2023-04-17T02:59:55.120777Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure()\nplt.title('Train Loss and Accuracy')\nplt.xlabel('Epoch')\nplt.ylabel('')\nplt.plot(range(1, epochs+1), np.array(train_loss_list), color='blue',\n         linestyle='-', label='Train_Loss')\nplt.plot(range(1, epochs+1), np.array(train_acc_list), color='red',\n         linestyle='-', label='Train_Accuracy')\nplt.legend()  # 凡例\nplt.show()  # 表示","metadata":{"execution":{"iopub.status.busy":"2023-04-17T02:59:55.123682Z","iopub.execute_input":"2023-04-17T02:59:55.124070Z","iopub.status.idle":"2023-04-17T02:59:55.345497Z","shell.execute_reply.started":"2023-04-17T02:59:55.124021Z","shell.execute_reply":"2023-04-17T02:59:55.344509Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"v_loss,  v_corr = 0.0, 0.0      \nmodel.eval()\nwith torch.no_grad():\n    for inputs, labels in valid_loader:\n        inputs = inputs.to(device)\n        labels = labels.to(device)\n        preds = model(inputs)\n        v_loss += loss.item() * inputs.size(0)\n        v_corr += torch.sum(preds.argmax(1) == labels)\n        \n    print('Valid Loss: {:.4f} Accuracy: {:.4f}%'.format(v_loss / len(valid_loader.dataset),\n                                                       (v_corr / len(valid_loader.dataset)) * 100))","metadata":{"execution":{"iopub.status.busy":"2023-04-17T02:59:55.346887Z","iopub.execute_input":"2023-04-17T02:59:55.347897Z","iopub.status.idle":"2023-04-17T03:00:21.774675Z","shell.execute_reply.started":"2023-04-17T02:59:55.347855Z","shell.execute_reply":"2023-04-17T03:00:21.769075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_result=[]\ntest_path = '/kaggle/working/test'\ntest_file_list = os.listdir(test_path)\nprint(test_file_list[:5])\n# get dataset\ntest_data = get_dataset(test_path, transform=transforms)\nprint(len(test_data))\ntest_loader = DataLoader(test_data, batch_size=64)\n_loss, _corr = 0.0, 0.0\nmodel.eval()\nwith torch.no_grad():\n    for inputs, labels in test_loader:\n        inputs = inputs.to(device)\n        labels = labels.to(device)\n        y = model(inputs)\n        preds = y.argmax(1)\n        y_result.extend(preds.to('cpu').detach().numpy().copy())","metadata":{"execution":{"iopub.status.busy":"2023-04-17T03:37:28.333788Z","iopub.execute_input":"2023-04-17T03:37:28.334792Z","iopub.status.idle":"2023-04-17T03:38:35.703096Z","shell.execute_reply.started":"2023-04-17T03:37:28.334739Z","shell.execute_reply":"2023-04-17T03:38:35.702035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Predict using the model\nresults = pd.DataFrame({\"ImageId\": test_file_list,\"Label\": y_result})\nresults.to_csv(\"submission.csv\",index=False)","metadata":{"execution":{"iopub.status.busy":"2023-04-17T03:39:25.003443Z","iopub.execute_input":"2023-04-17T03:39:25.004151Z","iopub.status.idle":"2023-04-17T03:39:25.032708Z","shell.execute_reply.started":"2023-04-17T03:39:25.004112Z","shell.execute_reply":"2023-04-17T03:39:25.031760Z"},"trusted":true},"execution_count":null,"outputs":[]}]}