{"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":"# !unzip --qq ../input/dogs-vs-cats/train.zip -d .\n# !unzip -qq ../input/dogs-vs-cats/test1.zip -d .","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-10-18T12:00:11.192803Z","iopub.status.idle":"2021-10-18T12:00:11.193236Z","shell.execute_reply.started":"2021-10-18T12:00:11.19299Z","shell.execute_reply":"2021-10-18T12:00:11.19301Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"1. **Import modules**","metadata":{}},{"cell_type":"code","source":"import os\nimport re\nfrom PIL import Image\nimport numpy as np\nimport torch\nfrom torch.utils.data import DataLoader\nfrom torchvision import models\nimport torch.nn as nn\nimport torchvision.transforms as transforms\nimport torch.optim as optim\nfrom sklearn.metrics import accuracy_score\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nimport cv2\nfrom tqdm import tqdm","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:14.552894Z","iopub.execute_input":"2021-10-18T12:00:14.553174Z","iopub.status.idle":"2021-10-18T12:00:14.558898Z","shell.execute_reply.started":"2021-10-18T12:00:14.553145Z","shell.execute_reply":"2021-10-18T12:00:14.558171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"2. **Data**","metadata":{}},{"cell_type":"code","source":"class dogVScat(DataLoader):\n    def __init__(self, dir_img=\"./train\", transform=None):\n        super(dogVScat, self).__init__(self)\n        self.dir_img = dir_img\n        self.transform = transform\n        self.images = os.listdir(dir_img)\n        self.images.sort(key=lambda x: int(re.findall(r\"\\d+\", x)[0]))\n        \n    def __len__(self):\n        return len(self.images)\n    \n    def __getitem__(self, index):\n        if self.dir_img == './train':\n            img_name = self.images[index]\n            image = cv2.imread(os.path.join(self.dir_img,img_name))\n            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n            if self.transform is not None:\n                image = self.transform(image=image)[\"image\"]\n\n            if \"cat\" in img_name:\n                label = 0\n\n            if \"dog\" in img_name:\n                label = 1\n\n            return image, label\n        if self.dir_img == './test1':\n            img_name = self.images[index]\n            image = cv2.imread(os.path.join(self.dir_img,img_name))\n            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n            if self.transform is not None:\n                image = self.transform(image=image)[\"image\"]\n\n            return image, -1","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:18.175352Z","iopub.execute_input":"2021-10-18T12:00:18.175872Z","iopub.status.idle":"2021-10-18T12:00:18.185551Z","shell.execute_reply.started":"2021-10-18T12:00:18.175836Z","shell.execute_reply":"2021-10-18T12:00:18.184649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create a compose transforms to transform all the images to a \n# unique size (448, 448) and convert the type of the input to Tensor\ntrans = A.Compose([\n                            A.Resize(width=448, height=448),\n                            A.RandomCrop(width=320, height=320),\n                            A.Rotate(limit=40, p=0.9, border_mode=cv2.BORDER_CONSTANT),\n                            A.HorizontalFlip(p=0.5),\n                            A.VerticalFlip(p=0.1),\n                            A.RGBShift(r_shift_limit=25, g_shift_limit=25, b_shift_limit=25, p=0.9),\n                            A.OneOf([\n                                A.Blur(blur_limit=3, p=0.5),\n                                A.ColorJitter(p=0.5),\n                            ], p=1.0),\n                            ToTensorV2()\n])\n","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:20.77136Z","iopub.execute_input":"2021-10-18T12:00:20.771617Z","iopub.status.idle":"2021-10-18T12:00:20.778288Z","shell.execute_reply.started":"2021-10-18T12:00:20.771591Z","shell.execute_reply":"2021-10-18T12:00:20.777399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trans_test = A.Compose([\n                            A.Resize(width=448, height=448),\n                             ToTensorV2()\n])\n","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:23.444809Z","iopub.execute_input":"2021-10-18T12:00:23.445058Z","iopub.status.idle":"2021-10-18T12:00:23.453292Z","shell.execute_reply.started":"2021-10-18T12:00:23.445032Z","shell.execute_reply":"2021-10-18T12:00:23.452454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_set = dogVScat(dir_img=\"./train\",transform=trans)\ntest_set = dogVScat(dir_img=\"./test1\",transform=trans_test)","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:24.271784Z","iopub.execute_input":"2021-10-18T12:00:24.272049Z","iopub.status.idle":"2021-10-18T12:00:24.372676Z","shell.execute_reply.started":"2021-10-18T12:00:24.272022Z","shell.execute_reply":"2021-10-18T12:00:24.37204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# show image\ndef show_img(idx):\n    image, label = train_set[idx]\n    plt.imshow(image.numpy().transpose(1, 2, 0))\n    plt.axis(\"off\")\n    plt.title(f\"Class: {label}\")\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:25.694502Z","iopub.execute_input":"2021-10-18T12:00:25.695059Z","iopub.status.idle":"2021-10-18T12:00:25.700388Z","shell.execute_reply.started":"2021-10-18T12:00:25.695022Z","shell.execute_reply":"2021-10-18T12:00:25.699361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = 'cuda' if torch.cuda.is_available else 'cpu'\n# hyperparameters\nLearning_rate = 0.001\nbatch_size = 8\nnum_epochs = 50","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:27.239705Z","iopub.execute_input":"2021-10-18T12:00:27.239959Z","iopub.status.idle":"2021-10-18T12:00:27.244245Z","shell.execute_reply.started":"2021-10-18T12:00:27.239931Z","shell.execute_reply":"2021-10-18T12:00:27.243294Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# create the DataLoader object \ntrain_loader = DataLoader(dataset=train_set, batch_size=batch_size, shuffle=True)\ntest_loader = DataLoader(dataset=test_set, batch_size=batch_size, shuffle=True)","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:28.465659Z","iopub.execute_input":"2021-10-18T12:00:28.465898Z","iopub.status.idle":"2021-10-18T12:00:28.470653Z","shell.execute_reply.started":"2021-10-18T12:00:28.465871Z","shell.execute_reply":"2021-10-18T12:00:28.469977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Identity(nn.Module):\n    def __init__(self):\n        super(Identity, self).__init__()\n    def forword(self, x):\n        return x\n        ","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:29.704155Z","iopub.execute_input":"2021-10-18T12:00:29.704609Z","iopub.status.idle":"2021-10-18T12:00:29.709289Z","shell.execute_reply.started":"2021-10-18T12:00:29.704572Z","shell.execute_reply":"2021-10-18T12:00:29.708438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load and edit the resnet50 model\n\n\nmodel = models.resnet50(pretrained=True)\nfor parm in model.parameters():\n    parm.requires_grad = False\n# model.avgpool = Identity()\nmodel.fc = nn.Linear(in_features=2048, out_features=1)\nmodel.to(device)\n","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:31.20059Z","iopub.execute_input":"2021-10-18T12:00:31.201167Z","iopub.status.idle":"2021-10-18T12:00:31.859901Z","shell.execute_reply.started":"2021-10-18T12:00:31.201128Z","shell.execute_reply":"2021-10-18T12:00:31.859029Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_one_epoch(loader, model, loss_fn, optimizer):\n    \"\"\"\n\n    :param loader: the dataloader object with the dataset catvsdog\n    :param model: model\n    :param loss_fn: the loss function Cross entropy\n    :param optimizer: the adam optimizer\n    \"\"\"\n    loop = tqdm(loader, leave=True)\n\n    for batch_idx, (data, targets) in enumerate(loop):\n        data = data.float()\n        data = data.to(device=device)\n        targets = targets.to(device=device)\n\n        # forward\n        scores = model(data)\n        targets = targets.type_as(scores)\n        targets.resize_(scores.shape[0], 1)\n        loss = loss_fn(scores, targets)\n        # backward\n        optimizer.zero_grad()\n        loss.backward()\n\n        # gradient descent or adam step\n        optimizer.step()","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:35.074117Z","iopub.execute_input":"2021-10-18T12:00:35.074845Z","iopub.status.idle":"2021-10-18T12:00:35.082921Z","shell.execute_reply.started":"2021-10-18T12:00:35.074809Z","shell.execute_reply":"2021-10-18T12:00:35.080534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def check_accuracy(\n    loader, model, loss_fn, input_shape=None, toggle_eval=True, print_accuracy=True\n):\n    \"\"\"\n    Check accuracy of model on data from loader\n    \"\"\"\n    if toggle_eval:\n        model.eval()\n    device = next(model.parameters()).device\n    num_correct = 0\n    num_samples = 0\n    y_preds = []\n    y_true = []\n    with torch.no_grad():\n        for x, y in loader:\n            x = x.to(device=device)\n            y = y.to(device=device)\n            if input_shape:\n                x = x.reshape(x.shape[0], *input_shape)\n            scores = model(x)\n            predictions = torch.sigmoid(scores) > 0.5\n            y_preds.append(torch.clip(torch.sigmoid(scores), 0.005, 0.995).cpu().numpy())\n            y_true.append(y.cpu().numpy())\n            num_correct += (predictions.squeeze(1) == y).sum()\n            num_samples += predictions.size(0)\n\n    accuracy = num_correct / num_samples\n\n    if toggle_eval:\n        model.train()\n\n    if print_accuracy:\n        print(f\"Accuracy: {accuracy * 100:.2f}%\")\n    return accuracy","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:36.840871Z","iopub.execute_input":"2021-10-18T12:00:36.841178Z","iopub.status.idle":"2021-10-18T12:00:36.85117Z","shell.execute_reply.started":"2021-10-18T12:00:36.841137Z","shell.execute_reply":"2021-10-18T12:00:36.849616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_submission (file, model, loader,input_shape=None):\n    df = pd.read_csv(file)\n    df = df.set_index('id')\n    df['label'] = df['label'].map({0:-1,}, na_action=None)\n    model.eval()\n    device = next(model.parameters()).device\n    y_preds = []\n    i=0\n    with torch.no_grad():\n        for x, y in tqdm(loader):\n            x = x.to(device=device)\n            if input_shape:\n                x = x.reshape(x.shape[0], *input_shape)\n            scores = model(x)\n            predictions = int(torch.sigmoid(scores) > 0.5)\n            i = i+1\n            df.loc[i]['label'] = predictions\n    df.to_csv(\"submussion.csv\",index=True)\n    model.train()\n\n    return df","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:38.785756Z","iopub.execute_input":"2021-10-18T12:00:38.78601Z","iopub.status.idle":"2021-10-18T12:00:38.793141Z","shell.execute_reply.started":"2021-10-18T12:00:38.785983Z","shell.execute_reply":"2021-10-18T12:00:38.792446Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loss_fn = nn.BCEWithLogitsLoss()\noptimizer = optim.Adam(model.parameters(), lr=Learning_rate)","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:41.647529Z","iopub.execute_input":"2021-10-18T12:00:41.647791Z","iopub.status.idle":"2021-10-18T12:00:41.655483Z","shell.execute_reply.started":"2021-10-18T12:00:41.647765Z","shell.execute_reply":"2021-10-18T12:00:41.654649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for _ in range(num_epochs):\n    train_one_epoch(train_loader, model, loss_fn, optimizer)","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:43.18421Z","iopub.execute_input":"2021-10-18T12:00:43.184766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# check_accuracy(loader=test_loader, model=model ,loss_fn=loss_fn ,input_shape=None, toggle_eval=True, print_accuracy=True)","metadata":{"execution":{"iopub.status.busy":"2021-10-18T12:00:11.224363Z","iopub.status.idle":"2021-10-18T12:00:11.225082Z","shell.execute_reply.started":"2021-10-18T12:00:11.224828Z","shell.execute_reply":"2021-10-18T12:00:11.224851Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = get_submission(file='../input/dogs-vs-cats/sampleSubmission.csv', model=model, loader=test_loader)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}}]}