{"cells":[{"metadata":{"_uuid":"72ff6c12-2729-4f7f-a356-c9b64e30f1cc","_cell_guid":"2122991e-0e47-47ab-9840-c220e2e22f5a","trusted":true},"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\n#import numpy as np # linear algebra\n#import 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\n#import os\n#for dirname, _, filenames in os.walk('/kaggle/working'):\n #   for filename in filenames:\n  #      print(os.path.join(dirname, filename))\n\n# You can write up to 5GB 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","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"4d607aa9-701b-4e25-b02b-43f5978e0537","_cell_guid":"7f13e087-3cf2-44d3-b951-f2c13be5c49b","trusted":true},"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torchvision\nimport os\nfrom torchvision import transforms\nfrom PIL import Image\nimport numpy as np\nfrom tqdm import tqdm\nimport matplotlib.pyplot as plt\nfrom torch.backends import cudnn #optimizes runtime ??\nimport torch.optim as optim","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"27c879b8-113f-44cf-bce5-c0509965ef46","_cell_guid":"1d3ac8ad-1510-4bbd-bfb9-8c7ba5343d9a","trusted":true},"cell_type":"markdown","source":"# **Sample Tensor**"},{"metadata":{"_uuid":"7ce84668-cad2-44aa-9c0d-b58810b2053d","_cell_guid":"e635388d-5142-42cd-9ba1-1eb610889225","trusted":true},"cell_type":"code","source":"x = torch.rand(2,1,3,3)\nsize=torch.flatten(x, start_dim=1)\nprint(x)\nnew = x.view(-1) # -1 here will be 2. because 18/(1*3*3)=2\nprint(new)\nprint(size)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"73b7f009-6f12-41f4-bcfb-bb66ded3a2f3","_cell_guid":"fc2b346c-4dc3-4056-b6a0-0c63c71c20d4","trusted":true},"cell_type":"code","source":"\n\nimport zipfile\n\nDataset = \"train\"\n\n# Will unzip the files so that you can see them..\nwith zipfile.ZipFile(\"../input/dogs-vs-cats/\"+Dataset+\".zip\",\"r\") as z:\n    z.extractall(\".\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"77585eaa-7808-46f0-b121-1fc3988e9bce","_cell_guid":"374dbc61-7fb3-45b9-b52f-13a176eb650d","trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"4083fade-b334-4ede-9996-754e9004ce20","_cell_guid":"f284af8a-3b76-467b-aef0-0ac17f9dac4e","trusted":true},"cell_type":"code","source":"# more advanced options like dropout/batch normalization or additional transoformation techniques (random flip)\n# can be added to overcome overfitting\n# generally we can add as many layers as we want until we see overfitting in testing data and we can overcome it with\n# above mentioned methods\nclass my_net(nn.Module):\n    def __init__(self):\n        super(my_net, self).__init__()\n        self.conv1 = nn.Conv2d(3,50,5)\n        self.conv2 = nn.Conv2d(50,150,3)\n        self.conv3 = nn.Conv2d(150,300,3)\n        self.conv4 = nn.Conv2d(300, 120, 3)\n        self.fc1 = nn.Linear(3000, 1024)\n        self.fc2 = nn.Linear(1024, 512)\n        self.fc3 = nn.Linear (512, 2)\n    \n        \n    def forward(self,x): \n        # when you simply do \"net(sample)\" without calling this method explicitly, it is called because of __call__ method in nn.Module, \n        # you cannot replace name of this method because it inherits from nn.module\n        x = F.relu(self.conv1(x))\n        x = F.max_pool2d(x, kernel_size = 3, stride = 2)\n        x = F.relu(self.conv2(x))\n        x = F.max_pool2d(x, kernel_size = 3, stride = 2)\n        x = F.relu(self.conv3(x))\n        x = F.max_pool2d(x, kernel_size = 3, stride = 2)\n        x = F.relu(self.conv4(x))\n        x = F.max_pool2d(x, kernel_size = 3, stride = 2)\n        x=torch.flatten(x, start_dim=1)\n        #print(\"Required shape: \", x.shape) # to decide the input dimension of fc1\n        x = F.relu(self.fc1(x))\n        x = F.relu(self.fc2(x))\n        x = self.fc3(x)\n        return x\n\nnet = my_net()\nprint(net)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3155eb77-14c4-4f77-aa95-5bd6a16dd6b2","_cell_guid":"aba4f4be-624e-4d8d-b8d6-fb7a4b771ab5","trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8d79ed5e-f2d5-40ff-94e8-99108b71f75b","_cell_guid":"395a38f1-f2bd-4a99-8fed-de1980944eae","trusted":true},"cell_type":"code","source":"sample = torch.rand(1,3,128,128)\noutput = net(sample)\noutput.shape","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"fe8004a4-5b70-49a1-9892-ede77b58c106","_cell_guid":"20733bb9-7885-4c4e-bc63-61fb12458803","trusted":true},"cell_type":"code","source":"\nos.getcwd()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"57310f0a-a078-499a-9892-3d2706f47393","_cell_guid":"f72a966e-5fdf-4a76-87fd-f397e4fb123c","trusted":true},"cell_type":"code","source":"train_transform = transforms.Compose([\n                                      transforms.Resize(256),\n                                      #transforms.RandomCrop( 64 , padding =2) ,\n                                      #transforms.RandomHorizontalFlip(),\n                                      transforms.RandomCrop(192), # if we does not do that we will have samples with different input sizes \n                                                                  # which is not accepted by cnn\n                                      transforms.Resize(128),\n                                      transforms.ToTensor(), # Turn PIL Image to torch.Tensor\n                                      transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) \n                                      # Normalizes tensor with mean and standard deviation\n])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"985378cb-697f-4027-8e43-63019bcc2dc8","_cell_guid":"ca4ba302-d7a4-4bb4-aeec-2ba11efe8b37","trusted":true},"cell_type":"code","source":"from torch.utils.data import Dataset, DataLoader, Subset\nfrom PIL import Image\nclass MyCatsDogs(Dataset):\n    def __init__(self, root, transform = None, mode = 'train'):\n        super(MyCatsDogs, self).__init__()\n        self.root = root\n        self.transform = transform\n        self.mode = mode\n        self.images = []\n        self.labels = []\n        \n        for image in os.listdir(self.root):\n            if(image.split('.')[0].lower() == 'cat'):\n                self.labels.append(1)\n            else:\n                self.labels.append(0)\n            \n            self.images.append(image)\n    \n    \n    \n    def __len__(self):\n        return len(self.images)\n    \n    \n        \n    def split(self, start, end): # Checking if I take 20% of the data from the end for validation \n                                 # will it be balanced data?kagg\n        return self.labels[ start : end+1]\n    \n    \n    \n    def show_image(self, index): # for visualizing the image\n        \n        filename = os.path.join(self.root, self.images[index])\n        img_array = np.array(Image.open(filename))\n        plt.imshow(img_array)\n\n        \n        \n    def __getitem__(self, index):\n        img = Image.open(os.path.join(self.root, self.images[index]))\n        \n        if self.transform is not None:\n            img = self.transform(img)\n        else:\n            img = np.array(img)\n            img = img.astype('float32')\n        \n        return img, self.labels[index]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"fe742344-93be-4320-92be-6e6f1f0714a3","_cell_guid":"5b8d5a1b-e274-48a8-8778-e06204c47def","trusted":true},"cell_type":"code","source":"train_dir = './train'\nsample_object = MyCatsDogs(root=train_dir, transform = train_transform)  \nmy_array = sample_object.__getitem__(1)[0] # for returning label of the 0th element\nprint(\"result: \", my_array.shape)\nmy_split = sample_object.split(20001,25000)\nprint(\"Split: \", sum(my_split)) # = 2510 so balanced distribution\n\nsample  = sample_object.show_image(0)\nlen(sample_object)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6d29637e-d10b-499e-b71c-15b387c468f6","_cell_guid":"84ffd423-510b-467d-b53d-6e7a164da481","trusted":true},"cell_type":"code","source":"train_indexes =  [idx for idx in range(20000)]\nvalid_indexes =  [idx for idx in range(20000, 25000)]\n\ntrain_data = Subset(sample_object, train_indexes)\nvalid_data  = Subset(sample_object, valid_indexes)\n\nprint(len(train_data), len(valid_data))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5aee89c2-e652-4777-aaa1-2c4e4a2a0693","_cell_guid":"7745553c-d4a2-4dba-a070-7d9a71104a96","trusted":true},"cell_type":"code","source":"train_loader = DataLoader(train_data, batch_size = 64, shuffle=True, num_workers=4)\nvalid_loader = DataLoader(valid_data, batch_size = 64, shuffle=True, num_workers=4)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"dea71948-0d4c-412a-afb8-2bcc413b64bc","_cell_guid":"31fd5659-76f6-4e94-9239-fc0ff8fbf233","trusted":true},"cell_type":"code","source":"net = net.to('cuda')\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.SGD(net.parameters(), lr=0.01, momentum=0.9)\nscheduler = optim.lr_scheduler.MultiStepLR(optimizer, milestones = [3, 7], gamma=0.1)\nepochs = 10","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f25022f-abb3-4b94-af33-9ba273a8367e","_cell_guid":"a5b7b4b6-75b9-4fd4-b16a-79398499b799","trusted":true,"_kg_hide-output":false},"cell_type":"code","source":"cudnn.benchmark # Calling this optimizes runtime\ncurrent_step = 0\nloss_values = []\n\n# Start iterating over the epochs\nfor epoch in range(epochs):\n    print('Starting epoch {}/{}, LR = {}'.format(epoch+1, epochs, scheduler.get_lr()))\n    \n    # Iterate over the dataset\n    for images, labels in tqdm(train_loader):\n        \n    # Bring data over the device of choice\n        images = images.to('cuda')\n        labels = labels.to('cuda')\n    \n        net.train() # Sets module in training mode\n\n    # PyTorch, by default, accumulates gradients after each backward pass\n    # We need to manually set the gradients to zero before starting a new iteration\n        optimizer.zero_grad() # Zero-ing the gradients\n\n    # Forward pass to the network\n        outputs = net(images)\n    \n    # Compute loss based on output and ground truth\n        loss = criterion(outputs, labels)\n\n    # Log loss\n        if current_step % 100 == 0:\n            loss_values.append(loss.item())\n            #step_values.append(current_step)\n            print('Step {}, Loss {} , Lr {}'.format(current_step, loss.item(), scheduler.get_lr()))\n            \n      \n\n    # Compute gradients for each layer and update weights\n        loss.backward()  # backward pass: computes gradients\n        optimizer.step() # update weights based on accumulated gradients\n\n        current_step += 1\n    \n    # Step the scheduler\n    scheduler.step()\n\n    steps = [x for x in range(0, 100*len(loss_values), 100)]\n    plt.plot(steps, loss_values)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2884abc2-bafe-4283-b6f7-1ce3960ec198","_cell_guid":"78a2d3b8-0125-4e1d-8f8a-f2534b4e20d4","trusted":true},"cell_type":"code","source":"steps = [x for x in range(0, 100*len(loss_values), 100)]\n\nplt.plot(steps, loss_values)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c07fb64b-5327-4f1d-8b6f-32a4ddf359f2","_cell_guid":"70fbc097-d673-493e-8de5-30a17507ae4b","trusted":true},"cell_type":"code","source":"net = net.to('cuda') # this will bring the network to GPU if DEVICE is cuda\nnet.train(False) # Set Network to evaluation mode\n\nrunning_corrects = 0\nfor images, labels in tqdm(valid_loader):\n    \n    \n    images = images.to('cuda')\n    labels = labels.to('cuda')\n\n  # Forward Pass\n    outputs = net(images)\n\n  # Get predictions\n    _, preds = torch.max(outputs.data, 1)\n\n  # Update Corrects\n    running_corrects += torch.sum(preds == labels.data).data.item()\n\n# Calculate Accuracy\naccuracy = running_corrects / float(len(valid_data))\n\nprint('Test Accuracy: {}'.format(accuracy))","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}