{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":30698,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"'!unzip \"/kaggle/input/dogs-vs-cats/train.zip\"'","metadata":{"execution":{"iopub.status.busy":"2024-05-16T18:02:30.949814Z","iopub.execute_input":"2024-05-16T18:02:30.951036Z","iopub.status.idle":"2024-05-16T18:02:30.958860Z","shell.execute_reply.started":"2024-05-16T18:02:30.950986Z","shell.execute_reply":"2024-05-16T18:02:30.957896Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport torch\nimport os\nimport random\nimport torch.nn as nn\nfrom PIL import Image\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision.transforms import transforms","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-05-16T18:02:33.324587Z","iopub.execute_input":"2024-05-16T18:02:33.324973Z","iopub.status.idle":"2024-05-16T18:02:39.457430Z","shell.execute_reply.started":"2024-05-16T18:02:33.324930Z","shell.execute_reply":"2024-05-16T18:02:39.456535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path = \"/kaggle/working/train\"\ndirs = os.listdir(train_path)\n\nrandom.shuffle(dirs)\ntrain_paths = dirs[5000:] \nval_paths = dirs[:5000] ","metadata":{"execution":{"iopub.status.busy":"2024-05-16T18:02:39.459087Z","iopub.execute_input":"2024-05-16T18:02:39.459713Z","iopub.status.idle":"2024-05-16T18:02:39.505842Z","shell.execute_reply.started":"2024-05-16T18:02:39.459685Z","shell.execute_reply":"2024-05-16T18:02:39.504635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class dataset(Dataset):\n    def __init__(self, paths, transform = None) :\n        self.paths = paths\n        self.transform = transform\n        \n    \n    def __getitem__(self, index):\n        full_path = os.path.join(train_path, self.paths[index])\n        img = Image.open(full_path)\n        img = img.resize((224, 224))\n        label = self.paths[index][:3]\n        \n        if self.transform:\n            img = self.transform(img)\n            img = img.type(torch.float32)/255 \n            \n        return img, int(label == \"cat\")\n    \n    def __len__(self):\n        return len(self.paths)","metadata":{"execution":{"iopub.status.busy":"2024-05-16T18:02:39.507118Z","iopub.execute_input":"2024-05-16T18:02:39.507393Z","iopub.status.idle":"2024-05-16T18:02:39.515642Z","shell.execute_reply.started":"2024-05-16T18:02:39.507369Z","shell.execute_reply":"2024-05-16T18:02:39.514468Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.PILToTensor(),\n])","metadata":{"execution":{"iopub.status.busy":"2024-05-16T18:02:39.518735Z","iopub.execute_input":"2024-05-16T18:02:39.519619Z","iopub.status.idle":"2024-05-16T18:02:39.527977Z","shell.execute_reply.started":"2024-05-16T18:02:39.519586Z","shell.execute_reply":"2024-05-16T18:02:39.525800Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data = dataset(train_paths, transform)\nval_data = dataset(val_paths, transform)","metadata":{"execution":{"iopub.status.busy":"2024-05-16T18:02:39.529281Z","iopub.execute_input":"2024-05-16T18:02:39.529616Z","iopub.status.idle":"2024-05-16T18:02:39.538742Z","shell.execute_reply.started":"2024-05-16T18:02:39.529587Z","shell.execute_reply":"2024-05-16T18:02:39.537397Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_loader = DataLoader(train_data, shuffle = True, batch_size = 32)\nval_loader = DataLoader(val_data, shuffle = False, batch_size = 32)","metadata":{"execution":{"iopub.status.busy":"2024-05-16T18:02:39.540235Z","iopub.execute_input":"2024-05-16T18:02:39.540498Z","iopub.status.idle":"2024-05-16T18:02:39.551122Z","shell.execute_reply.started":"2024-05-16T18:02:39.540476Z","shell.execute_reply":"2024-05-16T18:02:39.548410Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ConvBlock(nn.Module):\n    def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, bias=True):\n        super(ConvBlock, self).__init__()\n        \n        self.Conv_layer = nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size, stride = stride, padding=padding, bias=bias)\n        self.batchnorm2d = nn.BatchNorm2d(out_channels)\n        self.relu = nn.ReLU()\n        \n    def forward(self, x):\n        return self.relu(self.batchnorm2d(self.Conv_layer(x)))","metadata":{"execution":{"iopub.status.busy":"2024-05-16T18:02:39.552409Z","iopub.execute_input":"2024-05-16T18:02:39.552688Z","iopub.status.idle":"2024-05-16T18:02:39.562989Z","shell.execute_reply.started":"2024-05-16T18:02:39.552664Z","shell.execute_reply":"2024-05-16T18:02:39.562018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class InceptionBlock(nn.Module):\n    def __init__(self, in_channels, output_1x1, reduc_3x3, output_3x3, reduc_5x5, output5x5, out_1x1_mxpooling):\n        super(InceptionBlock, self).__init__()\n        \n        self.branch1 = ConvBlock(in_channels, output_1x1, kernel_size=1)\n        \n        self.branch2 = nn.Sequential(ConvBlock(in_channels, reduc_3x3, kernel_size=1), ConvBlock(reduc_3x3, output_3x3, kernel_size=3, stride=1, padding=1))\n        \n        self.branch3 = nn.Sequential(ConvBlock(in_channels, reduc_5x5, kernel_size=1), ConvBlock(reduc_5x5, output5x5, kernel_size=5, stride=1, padding=2))\n        \n        self.branch4 = nn.Sequential(nn.MaxPool2d(kernel_size=3, stride=1, padding=1), ConvBlock(in_channels, out_1x1_mxpooling, kernel_size=1, stride=1))\n        \n    def forward(self, x):\n        return torch.cat([self.branch1(x), self.branch2(x), self.branch3(x), self.branch4(x)], dim=1)","metadata":{"execution":{"iopub.status.busy":"2024-05-16T18:02:39.564056Z","iopub.execute_input":"2024-05-16T18:02:39.564287Z","iopub.status.idle":"2024-05-16T18:02:39.574723Z","shell.execute_reply.started":"2024-05-16T18:02:39.564266Z","shell.execute_reply":"2024-05-16T18:02:39.573926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Auxiliary(nn.Module):\n    def __init__(self, in_channels, num_classes):\n        super(Auxiliary, self).__init__()\n        \n        self.avg = nn.AvgPool2d(kernel_size=5, stride=3)\n        self.conv1 = ConvBlock(in_channels, 128, kernel_size=1)\n        \n        self.flatten = nn.Flatten()\n        \n        self.fc1 = nn.Linear(2048, 1024)\n        self.fc2 = nn.Linear(1024, num_classes)\n        \n        self.dropout = nn.Dropout(.7)\n        \n    def forward(self, x):\n        x = self.avg(x)\n        x = self.conv1(x)\n        \n        x = self.flatten(x)\n        \n        x = nn.ReLU()(self.fc1(x))\n        x = self.dropout(x)\n        x = self.fc2(x)\n        \n        return x     ","metadata":{"execution":{"iopub.status.busy":"2024-05-16T18:02:39.575613Z","iopub.execute_input":"2024-05-16T18:02:39.575841Z","iopub.status.idle":"2024-05-16T18:02:39.587852Z","shell.execute_reply.started":"2024-05-16T18:02:39.575821Z","shell.execute_reply":"2024-05-16T18:02:39.587123Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Inception(nn.Module):\n    def __init__(self, num_classes):\n        super(Inception, self).__init__()\n        \n        self.conv1 = ConvBlock(3, 64, kernel_size=7, stride=2)\n        self.conv2 = ConvBlock(64, 192, kernel_size=3, stride=1)\n        \n        self.inception3a = InceptionBlock(192, 64, 96, 128, 16, 32, 32)\n        self.inception3b = InceptionBlock(256, 128, 128, 192, 32, 96, 64)\n        self.inception4a = InceptionBlock(480, 192, 96, 208, 16, 48, 64)\n        self.inception4b = InceptionBlock(512, 160, 112, 224, 24, 64, 64)\n        self.inception4c = InceptionBlock(512, 128, 128, 256, 24, 64, 64)\n        self.inception4d = InceptionBlock(512, 112, 144, 288, 32, 64, 64)\n        self.inception4e = InceptionBlock(528, 256, 160, 320, 32, 128, 128)\n        self.inception5a = InceptionBlock(832, 256, 160, 320, 32, 128, 128)\n        self.inception5b = InceptionBlock(832, 384, 192, 384, 48, 128, 128)\n        \n        self.mx = nn.MaxPool2d(kernel_size=3, stride =2, padding=1)\n        self.avg = nn.AvgPool2d(kernel_size=7, stride =1)\n        \n        self.dropout = nn.Dropout(.4)\n        self.linear1 = nn.Linear(1024, 1000)\n        self.linear2 = nn.Linear(1000, num_classes)\n        \n        self.aux_1 = Auxiliary(in_channels = 512, num_classes = num_classes)\n        self.aux_2 = Auxiliary(in_channels = 528, num_classes = num_classes)\n\n    def forward(self, x):\n        \n        x = self.conv1(x)\n        x = self.mx(x)\n        \n        x = self.conv2(x)\n        x = self.mx(x)        \n        \n        x = self.inception3a(x)\n        x = self.inception3b(x)\n        x = self.mx(x)\n        x = self.inception4a(x)\n        \n        if self.training:\n            aux1 = self.aux_1(x)\n            \n        x = self.inception4b(x)\n        x = self.inception4c(x)\n        x = self.inception4d(x)\n        \n        if self.training:\n            aux2 = self.aux_2(x)\n            \n        x = self.inception4e(x)\n        x = self.mx(x)\n        x = self.inception5a(x)\n        x = self.inception5b(x)\n        x = self.avg(x)\n        \n        x = nn.Flatten()(x)\n        x = self.dropout(x)\n        x = nn.ReLU()(self.linear1(x))\n        \n        x = self.linear2(x)\n        \n        if self.training:\n            return x ,aux1, aux2\n        else:\n            return x","metadata":{"execution":{"iopub.status.busy":"2024-05-16T18:02:39.811065Z","iopub.execute_input":"2024-05-16T18:02:39.811416Z","iopub.status.idle":"2024-05-16T18:02:39.828645Z","shell.execute_reply.started":"2024-05-16T18:02:39.811389Z","shell.execute_reply":"2024-05-16T18:02:39.827702Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda' if torch.cuda.is_available() else \"cpu\")\ndevice","metadata":{"execution":{"iopub.status.busy":"2024-05-16T18:02:39.830624Z","iopub.execute_input":"2024-05-16T18:02:39.831227Z","iopub.status.idle":"2024-05-16T18:02:39.869393Z","shell.execute_reply.started":"2024-05-16T18:02:39.831192Z","shell.execute_reply":"2024-05-16T18:02:39.868363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = Inception(2).to(device)\n\nepochs = 10\nlr = .005\ncriterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=lr)","metadata":{"execution":{"iopub.status.busy":"2024-05-16T18:02:39.870491Z","iopub.execute_input":"2024-05-16T18:02:39.870835Z","iopub.status.idle":"2024-05-16T18:02:40.231395Z","shell.execute_reply.started":"2024-05-16T18:02:39.870802Z","shell.execute_reply":"2024-05-16T18:02:40.230573Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_loss_history = []\nval_loss_history = []\nbest_score = float(\"inf\")\ntol = 0\n\n\ndef train_epoch():\n    epoch_loss = 0\n    for i, (images, labels) in enumerate(train_loader):\n        \n        images = images.to(device)\n        labels = labels.to(device)\n        \n        # forward pass\n        out, aux1, aux2 = model(images)\n        \n        loss_out = criterion(out, labels)\n        aux1_loss = criterion(aux1, labels)\n        aux2_loss = criterion(aux2, labels)\n        loss = loss_out + .3*(aux1_loss + aux2_loss)\n        epoch_loss += loss\n        \n        # backward pass\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n        \n        if(i%100 ==0):\n            print(f\"   step[{i+1} / {len(train_loader)}]\")\n    return epoch_loss / len(train_loader)\n\ndef get_val_loss():\n    epoch_loss = 0\n    with torch.no_grad():\n        for i, (images, labels) in enumerate(val_loader):\n\n            images = images.to(device)\n            labels = labels.to(device)\n\n            # forward pass\n            out = model(images)\n            loss = criterion(out, labels)\n            epoch_loss += loss\n            \n    return epoch_loss / len(val_loader)\n\nfor epoch in range(epochs):\n    print(f\"epoch {epoch+1}:\")\n    \n    model.train(True)\n    avg_train_epoch_loss = train_epoch()\n    \n    model.eval()\n    avg_val_epoch_loss = get_val_loss()\n    \n    if(avg_val_epoch_loss < best_score):\n        best_score = avg_val_epoch_loss\n        torch.save(model.state_dict(), f\"model_{epoch+1}\")\n    else:\n        tol += 1\n        if(tol == 4):\n            break\n    \n    \n    train_loss_history.append(avg_train_epoch_loss)\n    val_loss_history.append(avg_val_epoch_loss)\n    \n    \n    print(f\"epoch: {epoch+1} --- avg_train_loss = {avg_train_epoch_loss} --- avg_val_loss = {avg_val_epoch_loss}\") \n    print(\"#\"*100)","metadata":{"execution":{"iopub.status.busy":"2024-05-16T18:02:40.233416Z","iopub.execute_input":"2024-05-16T18:02:40.233787Z","iopub.status.idle":"2024-05-16T18:23:28.629681Z","shell.execute_reply.started":"2024-05-16T18:02:40.233753Z","shell.execute_reply":"2024-05-16T18:23:28.628629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_losses = [ x.item() for x in train_loss_history]\nval_losses = [ x.item() for x in val_loss_history]","metadata":{"execution":{"iopub.status.busy":"2024-05-16T18:23:28.631226Z","iopub.execute_input":"2024-05-16T18:23:28.631528Z","iopub.status.idle":"2024-05-16T18:23:28.637246Z","shell.execute_reply.started":"2024-05-16T18:23:28.631501Z","shell.execute_reply":"2024-05-16T18:23:28.636246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nplt.plot(train_losses, \"b--\", label = \"Train_loss\")\nplt.plot(val_losses, \"r-\", label = \"Val_loss\")\nplt.title(\"Train VS Val\")\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-16T18:23:28.638248Z","iopub.execute_input":"2024-05-16T18:23:28.638516Z","iopub.status.idle":"2024-05-16T18:23:28.965063Z","shell.execute_reply.started":"2024-05-16T18:23:28.638495Z","shell.execute_reply":"2024-05-16T18:23:28.964154Z"},"trusted":true},"execution_count":null,"outputs":[]}]}