{"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 torch\nimport torch.nn as nn","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-08T17:44:14.610993Z","iopub.execute_input":"2021-06-08T17:44:14.611459Z","iopub.status.idle":"2021-06-08T17:44:14.619684Z","shell.execute_reply.started":"2021-06-08T17:44:14.611415Z","shell.execute_reply":"2021-06-08T17:44:14.618667Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The link to the paper: `https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43022.pdf`\n\nThe salient features:\n\n1. Uses 1x1 cnn for dimensionality reduction\n\nInception net\n\n![](https://i.ytimg.com/vi/KfV8CJh7hE0/maxresdefault.jpg)","metadata":{}},{"cell_type":"markdown","source":"So it has multiple conv block and inception block lets build them one by one\n# Conv block & Inception block","metadata":{}},{"cell_type":"code","source":"class conv_block(nn.Module):\n    def __init__(self, in_channels, out_channels, **kwargs):\n        super(conv_block, self).__init__()\n        self.relu = nn.ReLU()\n        self.cnn = nn.Conv2d(in_channels, out_channels, **kwargs)\n        self.batchnorm = nn.BatchNorm2d(out_channels)\n    \n    def forward(self, x):\n        return self.relu(self.batchnorm(self.cnn(x)))","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:14.622304Z","iopub.execute_input":"2021-06-08T17:44:14.623150Z","iopub.status.idle":"2021-06-08T17:44:14.636366Z","shell.execute_reply.started":"2021-06-08T17:44:14.623106Z","shell.execute_reply":"2021-06-08T17:44:14.634829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class inception_block(nn.Module):\n    def __init__(self, in_channels, out1x1, red3x3, out3x3, red5x5, out5x5, out1x1pool):\n        super(inception_block, self).__init__()\n        \n        self.branch1 = conv_block(in_channels, out1x1, kernel_size=1)\n        \n        self.branch2 = nn.Sequential(\n            \n            conv_block(in_channels, red3x3, kernel_size=1),\n            conv_block(red3x3, out3x3, kernel_size=3, padding=1)\n        )\n        \n        self.branch3 = nn.Sequential(\n            conv_block(in_channels, red5x5, kernel_size=1),\n            conv_block(red5x5, out5x5, kernel_size=5, padding=2)\n        )\n        \n        self.branch4 = nn.Sequential(\n            nn.MaxPool2d(kernel_size=3, stride=1, padding=1),\n            conv_block(in_channels, out1x1pool, kernel_size=1)\n        )\n        \n    def forward(self, x):\n        return torch.cat([self.branch1(x), self.branch2(x), self.branch3(x), self.branch4(x)], 1)","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:15.652482Z","iopub.execute_input":"2021-06-08T17:44:15.652816Z","iopub.status.idle":"2021-06-08T17:44:15.660201Z","shell.execute_reply.started":"2021-06-08T17:44:15.652771Z","shell.execute_reply":"2021-06-08T17:44:15.659373Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"![](https://media.geeksforgeeks.org/wp-content/uploads/20200429201421/Inception-layer-by-layer.PNG)","metadata":{}},{"cell_type":"code","source":"class GoogLeNet(nn.Module):\n    def __init__(self, in_channels=3, num_classes=104):\n        super(GoogLeNet,self).__init__()\n        self.conv1 = conv_block(in_channels, 64,kernel_size=(7,7), stride=(2,2),padding=(3,3))\n        self.maxpool1 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n        self.conv2 = conv_block(64, 192, kernel_size=3, stride=1, padding=1)\n        self.maxpool2 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n        \n        self.inception3a = inception_block(192, 64, 96, 128, 16, 32, 32)\n        self.inception3b = inception_block(256, 128, 128, 192, 32, 96, 64)\n        self.maxpool3 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n        \n        self.inception4a = inception_block(480, 192, 86, 208, 16, 48, 64)\n        self.inception4b = inception_block(512, 160, 112, 224, 24, 64, 64)\n        self.inception4c = inception_block(512, 128, 128, 256, 24, 64, 64)\n        self.inception4d = inception_block(512, 112, 144, 288, 32, 64, 64)\n        self.inception4e = inception_block(528, 256, 160, 320, 32, 128, 128)\n        self.maxpool4 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n        \n        self.inception5a = inception_block(832, 256, 160, 320, 32, 128, 128)\n        self.inception5b = inception_block(832, 384, 192, 384, 48, 128, 128)\n        \n        self.avgpool = nn.AvgPool2d(kernel_size=7, stride=1)\n        self.dropout = nn.Dropout(p=0.4)\n        \n        self.fc1 = nn.Linear(1024,num_classes)\n    \n    def forward(self,x):\n        x = self.conv1(x)\n        x = self.maxpool1(x)\n        \n        x = self.conv2(x)\n        x = self.maxpool2(x)\n        \n        x = self.inception3a(x)\n        x = self.inception3b(x)\n        x = self.maxpool3(x)\n        \n        x = self.inception4a(x)\n        x = self.inception4c(x)\n        x = self.inception4d(x)\n        x = self.inception4e(x)\n        x = self.maxpool4(x)\n        \n        x = self.inception5a(x)\n        x = self.inception5b(x)\n        x = self.avgpool(x)\n        x = self.dropout(x)\n        \n        x = x.reshape(x.shape[0], -1)\n        x = self.fc1(x)\n        \n        return x\n        \n        \n        \n        \n    ","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:15.736053Z","iopub.execute_input":"2021-06-08T17:44:15.736340Z","iopub.status.idle":"2021-06-08T17:44:15.843283Z","shell.execute_reply.started":"2021-06-08T17:44:15.736311Z","shell.execute_reply":"2021-06-08T17:44:15.842270Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = GoogLeNet()","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:15.844937Z","iopub.execute_input":"2021-06-08T17:44:15.845284Z","iopub.status.idle":"2021-06-08T17:44:15.914414Z","shell.execute_reply.started":"2021-06-08T17:44:15.845242Z","shell.execute_reply":"2021-06-08T17:44:15.913612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = torch.randn(10, 3, 224,224)\ny = model(x)\ny.shape","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:15.916657Z","iopub.execute_input":"2021-06-08T17:44:15.917044Z","iopub.status.idle":"2021-06-08T17:44:17.037263Z","shell.execute_reply.started":"2021-06-08T17:44:15.917007Z","shell.execute_reply":"2021-06-08T17:44:17.036260Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nimg = Image.open('../input/104-flowers-garden-of-eden/jpeg-224x224/train/balloon flower/10108.jpeg')\nimg = np.array(img)\nimg = torch.tensor(img)\nplt.imshow(img)\nimg.shape\n","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:17.038961Z","iopub.execute_input":"2021-06-08T17:44:17.039314Z","iopub.status.idle":"2021-06-08T17:44:17.208538Z","shell.execute_reply.started":"2021-06-08T17:44:17.039278Z","shell.execute_reply":"2021-06-08T17:44:17.207509Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = img.permute(2,0,1)\nx = x.unsqueeze(0)\nx = x.float()\nprint(x.shape)\ny = model(x)\n\"output shape: \" , y.shape","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:17.209952Z","iopub.execute_input":"2021-06-08T17:44:17.210284Z","iopub.status.idle":"2021-06-08T17:44:17.370857Z","shell.execute_reply.started":"2021-06-08T17:44:17.210248Z","shell.execute_reply":"2021-06-08T17:44:17.369906Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"lets use flower dataset","metadata":{}},{"cell_type":"code","source":"from torch.utils.data import Dataset, DataLoader\nimport torchvision.transforms as transforms\n","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:17.372327Z","iopub.execute_input":"2021-06-08T17:44:17.372679Z","iopub.status.idle":"2021-06-08T17:44:17.376784Z","shell.execute_reply.started":"2021-06-08T17:44:17.372636Z","shell.execute_reply":"2021-06-08T17:44:17.375925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])\ntrain_transform = transforms.Compose([transforms.RandomResizedCrop(224),\n                                      transforms.RandomHorizontalFlip(0.5),\n                                      transforms.ToTensor(),\n                                      normalize])","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:17.378063Z","iopub.execute_input":"2021-06-08T17:44:17.378602Z","iopub.status.idle":"2021-06-08T17:44:17.387619Z","shell.execute_reply.started":"2021-06-08T17:44:17.378566Z","shell.execute_reply":"2021-06-08T17:44:17.386671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_transform = transforms.Compose([transforms.Resize(224),\n                                     transforms.ToTensor(),\n                                     normalize])","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:17.389038Z","iopub.execute_input":"2021-06-08T17:44:17.389452Z","iopub.status.idle":"2021-06-08T17:44:17.401798Z","shell.execute_reply.started":"2021-06-08T17:44:17.389416Z","shell.execute_reply":"2021-06-08T17:44:17.400952Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torchvision.datasets import ImageFolder","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:17.406108Z","iopub.execute_input":"2021-06-08T17:44:17.406436Z","iopub.status.idle":"2021-06-08T17:44:17.412098Z","shell.execute_reply.started":"2021-06-08T17:44:17.406383Z","shell.execute_reply":"2021-06-08T17:44:17.411225Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data = ImageFolder(root=\"../input/104-flowers-garden-of-eden/jpeg-224x224/train\", transform=train_transform)\n\nz,y = train_data[0]\nprint(z.shape,y)\n\nplt.imshow(z.permute(1,2,0))","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:17.415575Z","iopub.execute_input":"2021-06-08T17:44:17.416044Z","iopub.status.idle":"2021-06-08T17:44:17.716372Z","shell.execute_reply.started":"2021-06-08T17:44:17.416013Z","shell.execute_reply":"2021-06-08T17:44:17.715537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataloader = DataLoader(dataset=train_data, shuffle=True, batch_size=64)","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:17.717676Z","iopub.execute_input":"2021-06-08T17:44:17.718033Z","iopub.status.idle":"2021-06-08T17:44:17.724537Z","shell.execute_reply.started":"2021-06-08T17:44:17.717994Z","shell.execute_reply":"2021-06-08T17:44:17.723604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_data = ImageFolder(root=\"../input/104-flowers-garden-of-eden/jpeg-224x224/val\", transform=test_transform)\n\nz,y = test_data[0]\nprint(z.shape, y)\n\nplt.imshow(z.permute(1,2,0))","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:17.726341Z","iopub.execute_input":"2021-06-08T17:44:17.726607Z","iopub.status.idle":"2021-06-08T17:44:17.973089Z","shell.execute_reply.started":"2021-06-08T17:44:17.726581Z","shell.execute_reply":"2021-06-08T17:44:17.972206Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataloader = DataLoader(dataset=test_data,shuffle=True, batch_size=64)","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:17.974396Z","iopub.execute_input":"2021-06-08T17:44:17.974743Z","iopub.status.idle":"2021-06-08T17:44:17.981591Z","shell.execute_reply.started":"2021-06-08T17:44:17.974705Z","shell.execute_reply":"2021-06-08T17:44:17.980528Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_epoch = 5\nbatch_size= 64\nlearning_rate = 0.001","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:17.984428Z","iopub.execute_input":"2021-06-08T17:44:17.984698Z","iopub.status.idle":"2021-06-08T17:44:17.993683Z","shell.execute_reply.started":"2021-06-08T17:44:17.984671Z","shell.execute_reply":"2021-06-08T17:44:17.992751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"I dont want to wastetime by training from scratch so lets use pretrained model.","metadata":{}},{"cell_type":"code","source":"from torchvision.models import googlenet","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:17.995246Z","iopub.execute_input":"2021-06-08T17:44:17.995633Z","iopub.status.idle":"2021-06-08T17:44:18.003153Z","shell.execute_reply.started":"2021-06-08T17:44:17.995595Z","shell.execute_reply":"2021-06-08T17:44:18.002350Z"},"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-08T17:44:18.004594Z","iopub.execute_input":"2021-06-08T17:44:18.005028Z","iopub.status.idle":"2021-06-08T17:44:18.012706Z","shell.execute_reply.started":"2021-06-08T17:44:18.004931Z","shell.execute_reply":"2021-06-08T17:44:18.011820Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = googlenet(pretrained=True)","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:18.014315Z","iopub.execute_input":"2021-06-08T17:44:18.014717Z","iopub.status.idle":"2021-06-08T17:44:18.182123Z","shell.execute_reply.started":"2021-06-08T17:44:18.014681Z","shell.execute_reply":"2021-06-08T17:44:18.181231Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.fc = nn.Linear(in_features=1024, out_features=104)","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:18.183552Z","iopub.execute_input":"2021-06-08T17:44:18.183902Z","iopub.status.idle":"2021-06-08T17:44:18.189758Z","shell.execute_reply.started":"2021-06-08T17:44:18.183866Z","shell.execute_reply":"2021-06-08T17:44:18.188633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = model.to(device=device)","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:18.191492Z","iopub.execute_input":"2021-06-08T17:44:18.191886Z","iopub.status.idle":"2021-06-08T17:44:18.223048Z","shell.execute_reply.started":"2021-06-08T17:44:18.191848Z","shell.execute_reply":"2021-06-08T17:44:18.222287Z"},"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-08T17:44:18.224325Z","iopub.execute_input":"2021-06-08T17:44:18.224671Z","iopub.status.idle":"2021-06-08T17:44:18.233487Z","shell.execute_reply.started":"2021-06-08T17:44:18.224634Z","shell.execute_reply":"2021-06-08T17:44:18.232145Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for epoch in range(num_epoch):\n    for data, target in train_dataloader:\n        data = data.to(device=device)\n        target = target.to(device=device)\n        \n        score = model(data)\n        optimizer.zero_grad()\n        loss = loss_criterion(score,target)\n        \n        loss.backward()\n        \n        optimizer.step()\n    print(f\"for epoch {epoch}, loss: {loss}\")\n        \n        ","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:44:18.235362Z","iopub.execute_input":"2021-06-08T17:44:18.235746Z","iopub.status.idle":"2021-06-08T17:50:51.055616Z","shell.execute_reply.started":"2021-06-08T17:44:18.235709Z","shell.execute_reply":"2021-06-08T17:50:51.054786Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def check_accuracy(model, loader):\n    model.eval()\n    \n    correct_sample = 0\n    total_sample = 0\n    \n    for x, y  in loader:\n        x = x.to(device=device)\n        y = y.to(device=device)\n        \n        score = model(x)\n        \n        _, predictions = score.max(1)\n        \n        correct_sample = (y==predictions).sum()\n        total_sample = predictions.shape[0]\n    \n    model.train()\n    print(f\"Total accuracy : {float(correct_sample/total_sample)*100}\")\n    ","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:50:51.057202Z","iopub.execute_input":"2021-06-08T17:50:51.057557Z","iopub.status.idle":"2021-06-08T17:50:51.064986Z","shell.execute_reply.started":"2021-06-08T17:50:51.057516Z","shell.execute_reply":"2021-06-08T17:50:51.063941Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"check_accuracy(model, train_dataloader)","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:50:51.066274Z","iopub.execute_input":"2021-06-08T17:50:51.066632Z","iopub.status.idle":"2021-06-08T17:51:33.108427Z","shell.execute_reply.started":"2021-06-08T17:50:51.066594Z","shell.execute_reply":"2021-06-08T17:51:33.106807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"check_accuracy(model, test_dataloader)","metadata":{"execution":{"iopub.status.busy":"2021-06-08T17:51:33.109764Z","iopub.execute_input":"2021-06-08T17:51:33.110136Z","iopub.status.idle":"2021-06-08T17:52:01.071377Z","shell.execute_reply.started":"2021-06-08T17:51:33.110096Z","shell.execute_reply":"2021-06-08T17:52:01.070523Z"},"trusted":true},"execution_count":null,"outputs":[]}]}