{"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":"# 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\n\"\"\"\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\"\"\"\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":"2022-04-20T12:42:01.292609Z","iopub.execute_input":"2022-04-20T12:42:01.292926Z","iopub.status.idle":"2022-04-20T12:42:01.322153Z","shell.execute_reply.started":"2022-04-20T12:42:01.292848Z","shell.execute_reply":"2022-04-20T12:42:01.321420Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Using pytorch build a classifier modle \n******Unzip the dataset **","metadata":{}},{"cell_type":"code","source":"### Unzipping Dataset\nimport zipfile\n\nwith zipfile.ZipFile(\"../input/dogs-vs-cats/train.zip\",\"r\") as z:\n    z.extractall(\".\")\n    \nwith zipfile.ZipFile(\"../input/dogs-vs-cats/test1.zip\",\"r\") as z:\n    z.extractall(\".\")","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:01.399147Z","iopub.execute_input":"2022-04-20T12:42:01.399662Z","iopub.status.idle":"2022-04-20T12:42:18.830739Z","shell.execute_reply.started":"2022-04-20T12:42:01.399630Z","shell.execute_reply":"2022-04-20T12:42:18.830016Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Import all nescassry libraries**","metadata":{}},{"cell_type":"code","source":"import os\nimport cv2\nimport time\nimport random\nimport numpy as np\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom torch.utils.data import Dataset, DataLoader\n\nimport torchvision.transforms as T\nfrom torchvision.utils import make_grid\nfrom torchvision.models import resnet50\n\nfrom sklearn.model_selection import train_test_split\n\nfrom PIL import Image\n\nimport matplotlib.pyplot as plt\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:18.832307Z","iopub.execute_input":"2022-04-20T12:42:18.832546Z","iopub.status.idle":"2022-04-20T12:42:21.322231Z","shell.execute_reply.started":"2022-04-20T12:42:18.832512Z","shell.execute_reply":"2022-04-20T12:42:21.321517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**siplitting dataset in train and test modle**  ","metadata":{}},{"cell_type":"code","source":"DIR_TRAIN = \"../input/cats-dogs/train/train/\"\nDIR_TEST = \"../input/cats-dogs/test1/test1/\"","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:21.323659Z","iopub.execute_input":"2022-04-20T12:42:21.323897Z","iopub.status.idle":"2022-04-20T12:42:21.328503Z","shell.execute_reply.started":"2022-04-20T12:42:21.323855Z","shell.execute_reply":"2022-04-20T12:42:21.327740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Describe the formate of the data** ","metadata":{}},{"cell_type":"code","source":"imgs = os.listdir(DIR_TRAIN) \ntest_imgs = os.listdir(DIR_TEST)\n\nprint(imgs[:5])\nprint(test_imgs[:5])","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:21.330809Z","iopub.execute_input":"2022-04-20T12:42:21.331101Z","iopub.status.idle":"2022-04-20T12:42:24.074553Z","shell.execute_reply.started":"2022-04-20T12:42:21.331067Z","shell.execute_reply":"2022-04-20T12:42:24.073781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Describe the class of dog and cats**","metadata":{}},{"cell_type":"code","source":"dogs_list = [img for img in imgs if img.split(\".\")[0] == \"dog\"]\ncats_list = [img for img in imgs if img.split(\".\")[0] == \"cat\"]\n\nprint(\"No of Dogs Images: \",len(dogs_list))\nprint(\"No of Cats Images: \",len(cats_list))\n\nclass_to_int = {\"dog\" : 0, \"cat\" : 1}\nint_to_class = {0 : \"dog\", 1 : \"cat\"}","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:24.076090Z","iopub.execute_input":"2022-04-20T12:42:24.076569Z","iopub.status.idle":"2022-04-20T12:42:24.097225Z","shell.execute_reply.started":"2022-04-20T12:42:24.076529Z","shell.execute_reply":"2022-04-20T12:42:24.096406Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Transform image,Augmentation of the data using tensorflow**","metadata":{}},{"cell_type":"code","source":"def get_train_transform():\n    return T.Compose([\n        T.RandomHorizontalFlip(p=0.5),\n        T.RandomRotation(15),\n        T.RandomCrop(204),\n        T.ToTensor(),\n        T.Normalize((0, 0, 0),(1, 1, 1))\n    ])\n    \ndef get_val_transform():\n    return T.Compose([\n        T.ToTensor(),\n        T.Normalize((0, 0, 0),(1, 1, 1))\n    ])","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:24.098566Z","iopub.execute_input":"2022-04-20T12:42:24.098949Z","iopub.status.idle":"2022-04-20T12:42:24.109089Z","shell.execute_reply.started":"2022-04-20T12:42:24.098912Z","shell.execute_reply":"2022-04-20T12:42:24.108287Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**define Class for fetch image and lables ****","metadata":{}},{"cell_type":"code","source":"class CatDogDataset(Dataset):\n    \n    def __init__(self, imgs, class_to_int, mode = \"train\", transforms = None):\n        \n        super().__init__()\n        self.imgs = imgs\n        self.class_to_int = class_to_int\n        self.mode = mode\n        self.transforms = transforms\n        \n    def __getitem__(self, idx):\n        \n        image_name = self.imgs[idx]\n        \n        ### Reading, converting and normalizing image\n        #img = cv2.imread(DIR_TRAIN + image_name, cv2.IMREAD_COLOR)\n        #img = cv2.resize(img, (224,224))\n        #img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)\n        #img /= 255.\n        img = Image.open(DIR_TRAIN + image_name)\n        img = img.resize((224, 224))\n        \n        if self.mode == \"train\" or self.mode == \"val\":\n        \n            ### Preparing class label\n            label = self.class_to_int[image_name.split(\".\")[0]]\n            label = torch.tensor(label, dtype = torch.float32)\n\n            ### Apply Transforms on image\n            img = self.transforms(img)\n\n            return img, label\n        \n        elif self.mode == \"test\":\n            \n            ### Apply Transforms on image\n            img = self.transforms(img)\n\n            return img\n            \n        \n    def __len__(self):\n        return len(self.imgs)\n    ","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:24.110266Z","iopub.execute_input":"2022-04-20T12:42:24.110800Z","iopub.status.idle":"2022-04-20T12:42:24.121592Z","shell.execute_reply.started":"2022-04-20T12:42:24.110764Z","shell.execute_reply":"2022-04-20T12:42:24.120816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**siplitting trainiing and validate data** ","metadata":{}},{"cell_type":"code","source":"train_imgs, val_imgs = train_test_split(imgs, test_size = 0.25)","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:24.123016Z","iopub.execute_input":"2022-04-20T12:42:24.123546Z","iopub.status.idle":"2022-04-20T12:42:24.135956Z","shell.execute_reply.started":"2022-04-20T12:42:24.123509Z","shell.execute_reply":"2022-04-20T12:42:24.135195Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Prepare dataset for training dataset**","metadata":{}},{"cell_type":"code","source":"train_dataset = CatDogDataset(train_imgs, class_to_int, mode = \"train\", transforms = get_train_transform())\nval_dataset = CatDogDataset(val_imgs, class_to_int, mode = \"val\", transforms = get_val_transform())\ntest_dataset = CatDogDataset(test_imgs, class_to_int, mode = \"test\", transforms = get_val_transform())\n\ntrain_data_loader = DataLoader(\n    dataset = train_dataset,\n    num_workers = 4,\n    batch_size = 16,\n    shuffle = True\n)\n\nval_data_loader = DataLoader(\n    dataset = val_dataset,\n    num_workers = 4,\n    batch_size = 16,\n    shuffle = True\n)\n\ntest_data_loader = DataLoader(\n    dataset = test_dataset,\n    num_workers = 4,\n    batch_size = 16,\n    shuffle = True\n)","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:24.137596Z","iopub.execute_input":"2022-04-20T12:42:24.137820Z","iopub.status.idle":"2022-04-20T12:42:24.148945Z","shell.execute_reply.started":"2022-04-20T12:42:24.137796Z","shell.execute_reply":"2022-04-20T12:42:24.148108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Visulization of images**","metadata":{}},{"cell_type":"code","source":"for images, labels in train_data_loader:\n    \n    fig, ax = plt.subplots(figsize = (10, 10))\n    ax.set_xticks([])\n    ax.set_yticks([])\n    ax.imshow(make_grid(images, 4).permute(1,2,0))\n    break","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:24.152402Z","iopub.execute_input":"2022-04-20T12:42:24.152850Z","iopub.status.idle":"2022-04-20T12:42:25.477036Z","shell.execute_reply.started":"2022-04-20T12:42:24.152811Z","shell.execute_reply":"2022-04-20T12:42:25.476120Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**check availability of GPU**","metadata":{}},{"cell_type":"code","source":"device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')\n","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:25.478223Z","iopub.execute_input":"2022-04-20T12:42:25.478459Z","iopub.status.idle":"2022-04-20T12:42:25.534900Z","shell.execute_reply.started":"2022-04-20T12:42:25.478427Z","shell.execute_reply":"2022-04-20T12:42:25.534220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**write the function to calculate accuracy**","metadata":{}},{"cell_type":"code","source":"def accuracy(preds, trues):\n    \n    ### Converting preds to 0 or 1\n    preds = [1 if preds[i] >= 0.5 else 0 for i in range(len(preds))]\n    \n    ### Calculating accuracy by comparing predictions with true labels\n    acc = [1 if preds[i] == trues[i] else 0 for i in range(len(preds))]\n    \n    ### Summing over all correct predictions\n    acc = np.sum(acc) / len(preds)\n    \n    return (acc * 100)","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:25.536129Z","iopub.execute_input":"2022-04-20T12:42:25.536640Z","iopub.status.idle":"2022-04-20T12:42:25.548392Z","shell.execute_reply.started":"2022-04-20T12:42:25.536604Z","shell.execute_reply":"2022-04-20T12:42:25.547724Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Write a function which trains the model over one epoch**","metadata":{}},{"cell_type":"code","source":"def train_one_epoch(train_data_loader):\n    \n    ### Local Parameters\n    epoch_loss = []\n    epoch_acc = []\n    start_time = time.time()\n    \n    ###Iterating over data loader\n    for images, labels in train_data_loader:\n        \n        #Loading images and labels to device\n        images = images.to(device)\n        labels = labels.to(device)\n        labels = labels.reshape((labels.shape[0], 1)) # [N, 1] - to match with preds shape\n        \n        #Reseting Gradients\n        optimizer.zero_grad()\n        \n        #Forward\n        preds = model(images)\n        \n        #Calculating Loss\n        _loss = criterion(preds, labels)\n        loss = _loss.item()\n        epoch_loss.append(loss)\n        \n        #Calculating Accuracy\n        acc = accuracy(preds, labels)\n        epoch_acc.append(acc)\n        \n        #Backward\n        _loss.backward()\n        optimizer.step()\n    \n    ###Overall Epoch Results\n    end_time = time.time()\n    total_time = end_time - start_time\n    \n    ###Acc and Loss\n    epoch_loss = np.mean(epoch_loss)\n    epoch_acc = np.mean(epoch_acc)\n    \n    ###Storing results to logs\n    train_logs[\"loss\"].append(epoch_loss)\n    train_logs[\"accuracy\"].append(epoch_acc)\n    train_logs[\"time\"].append(total_time)\n        \n    return epoch_loss, epoch_acc, total_time","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:25.549753Z","iopub.execute_input":"2022-04-20T12:42:25.550220Z","iopub.status.idle":"2022-04-20T12:42:25.562149Z","shell.execute_reply.started":"2022-04-20T12:42:25.550182Z","shell.execute_reply":"2022-04-20T12:42:25.561433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**define a function which validates the model over one epoch**","metadata":{}},{"cell_type":"code","source":"def val_one_epoch(val_data_loader, best_val_acc):\n    \n    ### Local Parameters\n    epoch_loss = []\n    epoch_acc = []\n    start_time = time.time()\n    \n    ###Iterating over data loader\n    for images, labels in val_data_loader:\n        \n        #Loading images and labels to device\n        images = images.to(device)\n        labels = labels.to(device)\n        labels = labels.reshape((labels.shape[0], 1)) # [N, 1] - to match with preds shape\n        \n        #Forward\n        preds = model(images)\n        \n        #Calculating Loss\n        _loss = criterion(preds, labels)\n        loss = _loss.item()\n        epoch_loss.append(loss)\n        \n        #Calculating Accuracy\n        acc = accuracy(preds, labels)\n        epoch_acc.append(acc)\n    \n    ###Overall Epoch Results\n    end_time = time.time()\n    total_time = end_time - start_time\n    \n    ###Acc and Loss\n    epoch_loss = np.mean(epoch_loss)\n    epoch_acc = np.mean(epoch_acc)\n    \n    ###Storing results to logs\n    val_logs[\"loss\"].append(epoch_loss)\n    val_logs[\"accuracy\"].append(epoch_acc)\n    val_logs[\"time\"].append(total_time)\n    \n    ###Saving best model\n    if epoch_acc > best_val_acc:\n        best_val_acc = epoch_acc\n        torch.save(model.state_dict(),\"resnet50_best.pth\")\n        \n    return epoch_loss, epoch_acc, total_time, best_val_acc\n        ","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:25.563430Z","iopub.execute_input":"2022-04-20T12:42:25.563750Z","iopub.status.idle":"2022-04-20T12:42:25.575222Z","shell.execute_reply.started":"2022-04-20T12:42:25.563718Z","shell.execute_reply":"2022-04-20T12:42:25.574347Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Apply NN using restnet50**","metadata":{}},{"cell_type":"code","source":"model = resnet50(pretrained = True)\n\n# Modifying Head - classifier\n\nmodel.fc = nn.Sequential(\n    nn.Linear(2048, 1, bias = True),\n    nn.Sigmoid()\n)","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:25.576202Z","iopub.execute_input":"2022-04-20T12:42:25.578066Z","iopub.status.idle":"2022-04-20T12:42:33.634216Z","shell.execute_reply.started":"2022-04-20T12:42:25.578026Z","shell.execute_reply":"2022-04-20T12:42:33.633490Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Defining model parameters Like Optimizer, Learning rate, Loss Function, epochs:**","metadata":{}},{"cell_type":"code","source":"# Optimizer\noptimizer = torch.optim.Adam(model.parameters(), lr = 0.0001)\n\n# Learning Rate Scheduler\nlr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size = 5, gamma = 0.5)\n\n#Loss Function\ncriterion = nn.BCELoss()\n\n# Logs - Helpful for plotting after training finishes\ntrain_logs = {\"loss\" : [], \"accuracy\" : [], \"time\" : []}\nval_logs = {\"loss\" : [], \"accuracy\" : [], \"time\" : []}\n\n# Loading model to device\nmodel.to(device)\n\n# No of epochs \nepochs = 10","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:33.635602Z","iopub.execute_input":"2022-04-20T12:42:33.636028Z","iopub.status.idle":"2022-04-20T12:42:36.223107Z","shell.execute_reply.started":"2022-04-20T12:42:33.635990Z","shell.execute_reply":"2022-04-20T12:42:36.222366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Now Train the model over Training and Validation sets using 10 epochs**","metadata":{}},{"cell_type":"code","source":"best_val_acc = 0\nfor epoch in range(epochs):\n    \n    ###Training\n    loss, acc, _time = train_one_epoch(train_data_loader)\n    \n    #Print Epoch Details\n    print(\"\\nTraining\")\n    print(\"Epoch {}\".format(epoch+1))\n    print(\"Loss : {}\".format(round(loss, 4)))\n    print(\"Acc : {}\".format(round(acc, 4)))\n    print(\"Time : {}\".format(round(_time, 4)))\n    \n    ###Validation\n    loss, acc, _time, best_val_acc = val_one_epoch(val_data_loader, best_val_acc)\n    \n    #Print Epoch Details\n    print(\"\\nValidating\")\n    print(\"Epoch {}\".format(epoch+1))\n    print(\"Loss : {}\".format(round(loss, 4)))\n    print(\"Acc : {}\".format(round(acc, 4)))\n    print(\"Time : {}\".format(round(_time, 4)))\n    ","metadata":{"execution":{"iopub.status.busy":"2022-04-20T12:42:36.224443Z","iopub.execute_input":"2022-04-20T12:42:36.224677Z","iopub.status.idle":"2022-04-20T13:10:50.113461Z","shell.execute_reply.started":"2022-04-20T12:42:36.224645Z","shell.execute_reply":"2022-04-20T13:10:50.112559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Plot the accuracies and Losses For a better understanding of how the model is performed**","metadata":{}},{"cell_type":"code","source":"### Plotting Results\n\n#Loss\nplt.title(\"Loss\")\nplt.plot(np.arange(1, 11, 1), train_logs[\"loss\"], color = 'blue')\nplt.plot(np.arange(1, 11, 1), val_logs[\"loss\"], color = 'yellow')\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"Loss\")\nplt.show()\n\n#Accuracy\nplt.title(\"Accuracy\")\nplt.plot(np.arange(1, 11, 1), train_logs[\"accuracy\"], color = 'blue')\nplt.plot(np.arange(1, 11, 1), val_logs[\"accuracy\"], color = 'yellow')\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"Accuracy\")\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2022-04-20T13:10:50.115303Z","iopub.execute_input":"2022-04-20T13:10:50.115925Z","iopub.status.idle":"2022-04-20T13:10:50.481329Z","shell.execute_reply.started":"2022-04-20T13:10:50.115877Z","shell.execute_reply":"2022-04-20T13:10:50.480641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**From the above graphs, we can see that the over model performs very well and gives very good accuracy of about 98% and reduced loss to around 3%.**","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"","metadata":{}}]}