{"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 PyTorch libraries\nimport torch\nimport torchvision\nimport torchvision.transforms as transforms\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.autograd import Variable\nimport torch.nn.functional as F\n\n# Other libraries we'll use\nimport numpy as np\nimport os\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\n%matplotlib inline\n\nprint(\"Libraries imported - ready to use PyTorch\", torch.__version__)","metadata":{"execution":{"iopub.status.busy":"2022-07-13T02:07:04.550786Z","iopub.execute_input":"2022-07-13T02:07:04.551190Z","iopub.status.idle":"2022-07-13T02:07:06.911852Z","shell.execute_reply.started":"2022-07-13T02:07:04.551156Z","shell.execute_reply":"2022-07-13T02:07:06.910542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_path = '/kaggle/input/image-matching-challenge-2022/train'","metadata":{"execution":{"iopub.status.busy":"2022-07-13T02:07:06.914060Z","iopub.execute_input":"2022-07-13T02:07:06.914728Z","iopub.status.idle":"2022-07-13T02:07:06.920605Z","shell.execute_reply.started":"2022-07-13T02:07:06.914688Z","shell.execute_reply":"2022-07-13T02:07:06.919353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"src = '/kaggle/input/image-matching-challenge-2022/train/brandenburg_gate/images'","metadata":{"execution":{"iopub.status.busy":"2022-07-13T02:07:06.922163Z","iopub.execute_input":"2022-07-13T02:07:06.922630Z","iopub.status.idle":"2022-07-13T02:07:06.936817Z","shell.execute_reply.started":"2022-07-13T02:07:06.922591Z","shell.execute_reply":"2022-07-13T02:07:06.935620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Get the class names\nclasses = os.listdir(src)\nclasses.sort()\nprint(len(classes), 'classes:')\nprint(classes)\n\n# Show the first image in each folder\nfig = plt.figure(figsize=(8, 12))\ni = 0\nfor sub_dir in os.listdir(src):\n    i+=1\n    img_file = os.listdir(os.path.join(src))[0]\n    img_path = os.path.join(src, img_file)\n    img = mpimg.imread(img_path)\n    a=fig.add_subplot(1, len(classes),i)\n    a.axis('off')\n    imgplot = plt.imshow(img)\n    a.set_title(img_file)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-13T02:07:06.939508Z","iopub.execute_input":"2022-07-13T02:07:06.940095Z","iopub.status.idle":"2022-07-13T02:07:44.648979Z","shell.execute_reply.started":"2022-07-13T02:07:06.940061Z","shell.execute_reply":"2022-07-13T02:07:44.647753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Initializing normalizing transform for the dataset\nnormalize_transform = torchvision.transforms.Compose([\n    torchvision.transforms.ToTensor(),\n    torchvision.transforms.Normalize(mean = (0.5, 0.5, 0.5), \n                                     std = (0.5, 0.5, 0.5))])\n\n#Downloading the CIFAR10 dataset into train and test sets\ntrain_dataset = torchvision.datasets.CIFAR10(\n    root=\"src\", train=True,\n    transform=normalize_transform,\n    download=True)\n    \ntest_dataset = torchvision.datasets.CIFAR10(\n    root=\"src\", train=False,\n    transform=normalize_transform,\n    download=True)\n\nbatch_size = 128\ntrain_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size)\ntest_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size)","metadata":{"execution":{"iopub.status.busy":"2022-07-13T02:07:44.650488Z","iopub.execute_input":"2022-07-13T02:07:44.650798Z","iopub.status.idle":"2022-07-13T02:07:53.752353Z","shell.execute_reply.started":"2022-07-13T02:07:44.650768Z","shell.execute_reply":"2022-07-13T02:07:53.751365Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Plotting 25 images from the 1st batch \ndataiter = iter(train_loader)\nimages, labels = dataiter.next()\nplt.imshow(np.transpose(torchvision.utils.make_grid(\n  images[:25], normalize=True, padding=1, nrow=5).numpy(), (1, 2, 0)))\nplt.axis('off')","metadata":{"execution":{"iopub.status.busy":"2022-07-13T02:07:53.753686Z","iopub.execute_input":"2022-07-13T02:07:53.754321Z","iopub.status.idle":"2022-07-13T02:07:53.964558Z","shell.execute_reply.started":"2022-07-13T02:07:53.754287Z","shell.execute_reply":"2022-07-13T02:07:53.963509Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n#Iterating over the training dataset and storing the target class for each sample\nclasses = []\nfor batch_idx, data in enumerate(train_loader, 0):\n    x, y = data \n    classes.extend(y.tolist())\n      \n#Calculating the unique classes and the respective counts and plotting them\nunique, counts = np.unique(classes, return_counts=True)\nnames = list(test_dataset.class_to_idx.keys())\nplt.bar(names, counts)\nplt.xlabel(\"Target Classes\")\nplt.ylabel(\"Number of training instances\")","metadata":{"execution":{"iopub.status.busy":"2022-07-13T02:07:53.965719Z","iopub.execute_input":"2022-07-13T02:07:53.966251Z","iopub.status.idle":"2022-07-13T02:08:05.995155Z","shell.execute_reply.started":"2022-07-13T02:07:53.966218Z","shell.execute_reply":"2022-07-13T02:08:05.994025Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nclass CNN(torch.nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.model = torch.nn.Sequential(\n            #Input = 3 x 32 x 32, Output = 32 x 32 x 32\n            torch.nn.Conv2d(in_channels = 3, out_channels = 32, kernel_size = 3, padding = 1), \n            torch.nn.ReLU(),\n            #Input = 32 x 32 x 32, Output = 32 x 16 x 16\n            torch.nn.MaxPool2d(kernel_size=2),\n  \n            #Input = 32 x 16 x 16, Output = 64 x 16 x 16\n            torch.nn.Conv2d(in_channels = 32, out_channels = 64, kernel_size = 3, padding = 1),\n            torch.nn.ReLU(),\n            #Input = 64 x 16 x 16, Output = 64 x 8 x 8\n            torch.nn.MaxPool2d(kernel_size=2),\n              \n            #Input = 64 x 8 x 8, Output = 64 x 8 x 8\n            torch.nn.Conv2d(in_channels = 64, out_channels = 64, kernel_size = 3, padding = 1),\n            torch.nn.ReLU(),\n            #Input = 64 x 8 x 8, Output = 64 x 4 x 4\n            torch.nn.MaxPool2d(kernel_size=2),\n  \n            torch.nn.Flatten(),\n            torch.nn.Linear(64*4*4, 512),\n            torch.nn.ReLU(),\n            torch.nn.Linear(512, 10)\n        )\n  \n    def forward(self, x):\n        return self.model(x)","metadata":{"execution":{"iopub.status.busy":"2022-07-13T02:08:05.996617Z","iopub.execute_input":"2022-07-13T02:08:05.996952Z","iopub.status.idle":"2022-07-13T02:08:06.008725Z","shell.execute_reply.started":"2022-07-13T02:08:05.996919Z","shell.execute_reply":"2022-07-13T02:08:06.007176Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Selecting the appropriate training device\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\nmodel = CNN().to(device)\n  \n#Defining the model hyper parameters\nnum_epochs = 50\nlearning_rate = 0.001\nweight_decay = 0.01\ncriterion = torch.nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=learning_rate, weight_decay=weight_decay)\n  \n#Training process begins\ntrain_loss_list = []\nfor epoch in range(num_epochs):\n    print(f'Epoch {epoch+1}/{num_epochs}:', end = ' ')\n    train_loss = 0\n      \n    #Iterating over the training dataset in batches\n    model.train()\n    for i, (images, labels) in enumerate(train_loader):\n          \n        #Extracting images and target labels for the batch being iterated\n        images = images.to(device)\n        labels = labels.to(device)\n  \n        #Calculating the model output and the cross entropy loss\n        outputs = model(images)\n        loss = criterion(outputs, labels)\n  \n        #Updating weights according to calculated loss\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n        train_loss += loss.item()\n      \n    #Printing loss for each epoch\n    train_loss_list.append(train_loss/len(train_loader))\n    print(f\"Training loss = {train_loss_list[-1]}\")   \n      \n#Plotting loss for all epochs\nplt.plot(range(1,num_epochs+1), train_loss_list)\nplt.xlabel(\"Number of epochs\")\nplt.ylabel(\"Training loss\")","metadata":{"execution":{"iopub.status.busy":"2022-07-13T02:08:06.010246Z","iopub.execute_input":"2022-07-13T02:08:06.010958Z","iopub.status.idle":"2022-07-13T06:34:52.041657Z","shell.execute_reply.started":"2022-07-13T02:08:06.010896Z","shell.execute_reply":"2022-07-13T06:34:52.039340Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ntest_acc=0\nmodel.eval()\n  \nwith torch.no_grad():\n    #Iterating over the training dataset in batches\n    for i, (images, labels) in enumerate(test_loader):\n          \n        images = images.to(device)\n        y_true = labels.to(device)\n          \n        #Calculating outputs for the batch being iterated\n        outputs = model(images)\n          \n        #Calculated prediction labels from models\n        _, y_pred = torch.max(outputs.data, 1)\n          \n        #Comparing predicted and true labels\n        test_acc += (y_pred == y_true).sum().item()\n      \n    print(f\"Test set accuracy = {100 * test_acc / len(test_dataset)} %\")","metadata":{"execution":{"iopub.status.busy":"2022-07-13T06:34:52.047296Z","iopub.execute_input":"2022-07-13T06:34:52.047735Z","iopub.status.idle":"2022-07-13T06:35:48.339798Z","shell.execute_reply.started":"2022-07-13T06:34:52.047694Z","shell.execute_reply":"2022-07-13T06:35:48.338518Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n#Generating predictions for 'num_images' amount of images from the last batch of test set\nnum_images = 10\ny_true_name = [names[y_true[idx]] for idx in range(num_images)] \ny_pred_name = [names[y_pred[idx]] for idx in range(num_images)] \n  \n#Generating the title for the plot\ntitle = f\"Actual labels: {y_true_name}, Predicted labels: {y_pred_name}\"\n  \n#Finally plotting the images with their actual and predicted labels in the title\nplt.imshow(np.transpose(torchvision.utils.make_grid(images[:num_images].cpu(), normalize=True, padding=1).numpy(), (1, 2, 0)))\nplt.title(title)\nplt.axis(\"off\")","metadata":{"execution":{"iopub.status.busy":"2022-07-13T06:35:48.341197Z","iopub.execute_input":"2022-07-13T06:35:48.341600Z","iopub.status.idle":"2022-07-13T06:35:48.508771Z","shell.execute_reply.started":"2022-07-13T06:35:48.341563Z","shell.execute_reply":"2022-07-13T06:35:48.507297Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}