{"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":"markdown","source":"Lets import some of the libraries immediately required.","metadata":{}},{"cell_type":"code","source":"import torch\nimport os\nimport re\n\nimport numpy as np\nfrom torch.utils.data import Dataset, DataLoader\nfrom PIL import Image\n\nimport torchvision\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-12T06:41:35.424380Z","iopub.execute_input":"2021-06-12T06:41:35.424736Z","iopub.status.idle":"2021-06-12T06:41:35.430144Z","shell.execute_reply.started":"2021-06-12T06:41:35.424704Z","shell.execute_reply":"2021-06-12T06:41:35.429291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"https://www.youtube.com/watch?v=2zptQGC-pHY&list=PLhhyoLH6IjfxkVb3Yx4mjLdwMWP5S_Hct&index=2","metadata":{}},{"cell_type":"markdown","source":"# Is data accessible ?","metadata":{}},{"cell_type":"markdown","source":"Since the dataset provided is zippped, lets unzip it first.","metadata":{}},{"cell_type":"code","source":"!unzip -qo ../input/dogs-vs-cats-redux-kernels-edition/test.zip\n!unzip -qo ../input/dogs-vs-cats-redux-kernels-edition/train.zip","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:41:37.651044Z","iopub.execute_input":"2021-06-12T06:41:37.651419Z","iopub.status.idle":"2021-06-12T06:41:48.346978Z","shell.execute_reply.started":"2021-06-12T06:41:37.651362Z","shell.execute_reply":"2021-06-12T06:41:48.345928Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Enumerating the directory we see that it has unzipped","metadata":{}},{"cell_type":"code","source":"!ls","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:41:48.348839Z","iopub.execute_input":"2021-06-12T06:41:48.349176Z","iopub.status.idle":"2021-06-12T06:41:49.045814Z","shell.execute_reply.started":"2021-06-12T06:41:48.349139Z","shell.execute_reply":"2021-06-12T06:41:49.043912Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prepping the data for the model","metadata":{}},{"cell_type":"markdown","source":"lets create a transform. A transform does exactly as it sounds it transforms the image to a form, in this case since we want the images to be of uniform size we resize it, then convert it into a tensor followed by normalise. The values I copied from other kernel. Its basically something you do.","metadata":{}},{"cell_type":"code","source":"import torchvision.transforms as transforms\n\nmy_transform = transforms.Compose([\n    transforms.Resize((224,224)),\n    transforms.ToTensor(),\n    transforms.Normalize(\n        mean=[0.485, 0.456, 0.406],\n        std=[0.229,0.224,0.225],\n    ),\n   \n])","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:41:49.048381Z","iopub.execute_input":"2021-06-12T06:41:49.048777Z","iopub.status.idle":"2021-06-12T06:41:49.060506Z","shell.execute_reply.started":"2021-06-12T06:41:49.048737Z","shell.execute_reply":"2021-06-12T06:41:49.059152Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"lets look at what is actually in the train directory, the file names have their labels in the name itself. here are 5 of the files in train directory","metadata":{}},{"cell_type":"code","source":"os.listdir(\"./train\")[:5]","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:41:49.067635Z","iopub.execute_input":"2021-06-12T06:41:49.069137Z","iopub.status.idle":"2021-06-12T06:41:49.121138Z","shell.execute_reply.started":"2021-06-12T06:41:49.069097Z","shell.execute_reply":"2021-06-12T06:41:49.117888Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Lets just check whether our transform works on individual images","metadata":{}},{"cell_type":"code","source":"img = Image.open(\"./train/cat.10366.jpg\")\nimg = my_transform(img)","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:41:49.140809Z","iopub.execute_input":"2021-06-12T06:41:49.148796Z","iopub.status.idle":"2021-06-12T06:41:49.181473Z","shell.execute_reply.started":"2021-06-12T06:41:49.148508Z","shell.execute_reply":"2021-06-12T06:41:49.179530Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## The pytorch dataset and dataloader","metadata":{}},{"cell_type":"markdown","source":"Okay now we create the dataset class. All dataset classes are supposed to have three functions, __init__ (initialiser) , __len__ (returns length of dataset) and __getitem__ (to get individual items), basically if you implement Dataset from pytorch with these three functions, you hava a pytorch Dataset.","metadata":{}},{"cell_type":"code","source":"class CatsDogsDataset(Dataset):\n    def __init__(self, rootdir, transform=my_transform, partial_data=None):\n        self.rootdir = rootdir\n        self.transform = transform\n        if partial_data is not None:\n            self.images = os.listdir(rootdir)[:partial_data]\n        else :\n            self.images = os.listdir(rootdir)\n        \n    def __len__(self):\n        return len(self.images)\n    \n    def __getitem__(self, index):\n        \n#         print(os.path.join(self.rootdir,self.images[index]))\n        img = Image.open(os.path.join(self.rootdir,self.images[index])).convert(\"RGB\")\n        \n#         image = np.array(img)\n        \n        if self.transform:\n            img = self.transform(img)\n        \n        if \"cat\" in self.images[index]:\n            label = 0\n            \n        elif \"dog\" in self.images[index]:\n            label = 1\n        else :\n            label = -1\n            \n        return img, label","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:41:49.183103Z","iopub.execute_input":"2021-06-12T06:41:49.183468Z","iopub.status.idle":"2021-06-12T06:41:49.193314Z","shell.execute_reply.started":"2021-06-12T06:41:49.183432Z","shell.execute_reply":"2021-06-12T06:41:49.192361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"lets intiatiate our dataset class.","metadata":{}},{"cell_type":"code","source":"train_dataset = CatsDogsDataset(rootdir=\"./train\", partial_data=5000) \n# train_dataset = CatsDogsDataset(rootdir=\"./train\")","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:41:49.196431Z","iopub.execute_input":"2021-06-12T06:41:49.198957Z","iopub.status.idle":"2021-06-12T06:41:49.246459Z","shell.execute_reply.started":"2021-06-12T06:41:49.198905Z","shell.execute_reply":"2021-06-12T06:41:49.245067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset.__len__()","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:41:49.254159Z","iopub.execute_input":"2021-06-12T06:41:49.257606Z","iopub.status.idle":"2021-06-12T06:41:49.271336Z","shell.execute_reply.started":"2021-06-12T06:41:49.257564Z","shell.execute_reply":"2021-06-12T06:41:49.270118Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"is it working?","metadata":{}},{"cell_type":"code","source":"x, y = train_dataset[100]\nx.shape, y","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:50.956157Z","iopub.execute_input":"2021-06-12T06:42:50.956622Z","iopub.status.idle":"2021-06-12T06:42:50.973576Z","shell.execute_reply.started":"2021-06-12T06:42:50.956531Z","shell.execute_reply":"2021-06-12T06:42:50.972275Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nplt.imshow(x.permute(1,2,0))","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:53.040208Z","iopub.execute_input":"2021-06-12T06:42:53.040555Z","iopub.status.idle":"2021-06-12T06:42:53.199305Z","shell.execute_reply.started":"2021-06-12T06:42:53.040524Z","shell.execute_reply":"2021-06-12T06:42:53.198517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"batch size decides how many of your data items are taken together in a single batch, while you apply the back propagation.","metadata":{}},{"cell_type":"markdown","source":"### Hyperparameters","metadata":{}},{"cell_type":"code","source":"batch_size = 20\nlearning_rate = 1e-4 #0.001\nnum_epochs = 1\nnum_workers = 4\npin_memory =True\ncheckpoint_file = \"checkpoint.tar\"\nweight_decay = 1e-4\n","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:41:49.398471Z","iopub.status.idle":"2021-06-12T06:41:49.401567Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Lets get the dataloader","metadata":{}},{"cell_type":"code","source":"train_dataloader = DataLoader(dataset=train_dataset, shuffle=True, batch_size=batch_size)","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:41:58.431131Z","iopub.execute_input":"2021-06-12T06:41:58.431447Z","iopub.status.idle":"2021-06-12T06:41:58.437375Z","shell.execute_reply.started":"2021-06-12T06:41:58.431417Z","shell.execute_reply":"2021-06-12T06:41:58.436403Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Okay. Now onto the model,","metadata":{}},{"cell_type":"code","source":"from torchvision.models import resnet18","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:01.422910Z","iopub.execute_input":"2021-06-12T06:42:01.423233Z","iopub.status.idle":"2021-06-12T06:42:01.427204Z","shell.execute_reply.started":"2021-06-12T06:42:01.423204Z","shell.execute_reply":"2021-06-12T06:42:01.426374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = resnet18(pretrained=True)","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:01.428988Z","iopub.execute_input":"2021-06-12T06:42:01.429504Z","iopub.status.idle":"2021-06-12T06:42:01.744768Z","shell.execute_reply.started":"2021-06-12T06:42:01.429440Z","shell.execute_reply":"2021-06-12T06:42:01.743931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for param in model.parameters():\n    param.requires_grad = False","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:01.746630Z","iopub.execute_input":"2021-06-12T06:42:01.746990Z","iopub.status.idle":"2021-06-12T06:42:01.752552Z","shell.execute_reply.started":"2021-06-12T06:42:01.746956Z","shell.execute_reply":"2021-06-12T06:42:01.751681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.nn as nn","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:01.754280Z","iopub.execute_input":"2021-06-12T06:42:01.754619Z","iopub.status.idle":"2021-06-12T06:42:01.762988Z","shell.execute_reply.started":"2021-06-12T06:42:01.754583Z","shell.execute_reply":"2021-06-12T06:42:01.762116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.fc = nn.Linear(in_features=512, out_features=2, bias=True)","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:01.764279Z","iopub.execute_input":"2021-06-12T06:42:01.764613Z","iopub.status.idle":"2021-06-12T06:42:01.772542Z","shell.execute_reply.started":"2021-06-12T06:42:01.764578Z","shell.execute_reply":"2021-06-12T06:42:01.771729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:01.773847Z","iopub.execute_input":"2021-06-12T06:42:01.774218Z","iopub.status.idle":"2021-06-12T06:42:01.781409Z","shell.execute_reply.started":"2021-06-12T06:42:01.774182Z","shell.execute_reply":"2021-06-12T06:42:01.780545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = model.to(device=device)","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:01.782631Z","iopub.execute_input":"2021-06-12T06:42:01.783215Z","iopub.status.idle":"2021-06-12T06:42:01.806718Z","shell.execute_reply.started":"2021-06-12T06:42:01.783178Z","shell.execute_reply":"2021-06-12T06:42:01.806004Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:04.346202Z","iopub.execute_input":"2021-06-12T06:42:04.346520Z","iopub.status.idle":"2021-06-12T06:42:04.352766Z","shell.execute_reply.started":"2021-06-12T06:42:04.346490Z","shell.execute_reply":"2021-06-12T06:42:04.351845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loss_criterion = torch.nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr= learning_rate)","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:04.354295Z","iopub.execute_input":"2021-06-12T06:42:04.354846Z","iopub.status.idle":"2021-06-12T06:42:04.363572Z","shell.execute_reply.started":"2021-06-12T06:42:04.354806Z","shell.execute_reply":"2021-06-12T06:42:04.362699Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm\n\nfor epoch in range(num_epochs):\n    for data, target in tqdm(train_dataloader):\n        data = data.to(device=device)\n        target = target.to(device=device)\n        \n        score = model(data)\n        \n        loss = loss_criterion(score, target)\n        optimizer.zero_grad()\n        \n        loss.backward()\n        \n        optimizer.step()\n    \n    print(f\"For epoch: {epoch} loss: {loss}\")\n        ","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:04.364966Z","iopub.execute_input":"2021-06-12T06:42:04.368151Z","iopub.status.idle":"2021-06-12T06:42:15.003810Z","shell.execute_reply.started":"2021-06-12T06:42:04.368120Z","shell.execute_reply":"2021-06-12T06:42:15.000586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def check_accuracy(model, loader):\n    model.train()\n    \n    total_correct = 0\n    total_predictions = 0\n    \n    for x, y in tqdm(loader):\n        x = x.to(device=device)\n        y = y.to(device=device)\n        \n        \n        score = model(x)\n        z, predictions = score.max(1)\n        \n#         print(f\"score shape : {score.shape} , z: {z}, predictions: {predictions}, predictions shape: {predictions.shape}\")\n        \n        total_correct = (y==predictions).sum()\n        total_predictions += predictions.shape[0]\n    \n    print(f\"Out of {total_predictions}, total correct: {total_correct} with an accuracy of {float(total_correct/total_predictions)* 100}\")","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:15.005272Z","iopub.status.idle":"2021-06-12T06:42:15.005841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"check_accuracy(model, train_dataloader)","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:15.007367Z","iopub.status.idle":"2021-06-12T06:42:15.007931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"That is bad performance , but at least it was quick, lets work on inference.\n\n# Inference!","metadata":{}},{"cell_type":"code","source":"import pandas as pd\n\nsubmission = pd.read_csv('../input/dogs-vs-cats-redux-kernels-edition/sample_submission.csv')\nsubmission.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:15.009283Z","iopub.status.idle":"2021-06-12T06:42:15.009836Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class testDataset(Dataset):\n    def __init__(self, rootdir, transform=my_transform, partial_data=None):\n        self.rootdir = rootdir\n        self.transform = transform\n        if partial_data is not None:\n            self.images = os.listdir(rootdir)[:partial_data]\n        else :\n            self.images = os.listdir(rootdir)\n        \n    def __len__(self):\n        return len(self.images)\n    \n    def __getitem__(self, index):\n        \n#         print(os.path.join(self.rootdir,self.images[index]))\n        img = Image.open(os.path.join(self.rootdir,self.images[index])).convert(\"RGB\")\n        \n#         image = np.array(img)\n        \n        if self.transform:\n            img = self.transform(img)\n        \n#         if \"cat\" in self.images[index]:\n#             label = 0\n            \n#         elif \"dog\" in self.images[index]:\n#             label = 1\n#         else :\n#             label = -1\n            \n        return img","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:15.011345Z","iopub.status.idle":"2021-06-12T06:42:15.011917Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataset = testDataset(\"./test\")","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:15.013435Z","iopub.status.idle":"2021-06-12T06:42:15.014014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(submission), test_dataset.__len__()","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:15.015446Z","iopub.status.idle":"2021-06-12T06:42:15.016015Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataloader = DataLoader(dataset=test_dataset, batch_size=1, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:15.017260Z","iopub.status.idle":"2021-06-12T06:42:15.017815Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\npredictions = []\nfor x in tqdm(test_dataloader):\n    x = x.to(device=device)\n    \n    score = model(x)\n    _, prediction = score.max(1)\n    \n    predictions.append(prediction)\n    ","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:15.019118Z","iopub.status.idle":"2021-06-12T06:42:15.019696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(predictions)","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:15.020950Z","iopub.status.idle":"2021-06-12T06:42:15.021493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission[\"label\"] = [int(x) for x in predictions]\nsubmission.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:15.022735Z","iopub.status.idle":"2021-06-12T06:42:15.023288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv(\"my_submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2021-06-12T06:42:15.024553Z","iopub.status.idle":"2021-06-12T06:42:15.025128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}