{"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":30673,"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":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-output":true,"execution":{"iopub.status.busy":"2024-07-02T08:56:34.981882Z","iopub.execute_input":"2024-07-02T08:56:34.982740Z","iopub.status.idle":"2024-07-02T08:56:46.206325Z","shell.execute_reply.started":"2024-07-02T08:56:34.982702Z","shell.execute_reply":"2024-07-02T08:56:46.205428Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os,random\nfrom PIL import Image\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision.transforms import transforms","metadata":{"execution":{"iopub.status.busy":"2024-07-02T08:56:46.208487Z","iopub.execute_input":"2024-07-02T08:56:46.208860Z","iopub.status.idle":"2024-07-02T08:56:52.979096Z","shell.execute_reply.started":"2024-07-02T08:56:46.208818Z","shell.execute_reply":"2024-07-02T08:56:52.978383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path = '/kaggle/working/train'\ndirs = os.listdir(train_path)\nlen(dirs)","metadata":{"execution":{"iopub.status.busy":"2024-07-02T08:56:52.980239Z","iopub.execute_input":"2024-07-02T08:56:52.980770Z","iopub.status.idle":"2024-07-02T08:56:53.002073Z","shell.execute_reply.started":"2024-07-02T08:56:52.980744Z","shell.execute_reply":"2024-07-02T08:56:53.001266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cat_paths = [path for path in dirs if path.startswith('cat')]\ndog_paths = [path for path in dirs if path.startswith('dog')]\nall_paths= cat_paths+dog_paths\n\ntrain_paths = cat_paths[2500:] + dog_paths[2500:]\nvalid_paths = cat_paths[:2500] + dog_paths[:2500]\n\nlen(cat_paths), len(dog_paths)","metadata":{"execution":{"iopub.status.busy":"2024-07-02T08:56:53.004013Z","iopub.execute_input":"2024-07-02T08:56:53.004297Z","iopub.status.idle":"2024-07-02T08:56:53.019233Z","shell.execute_reply.started":"2024-07-02T08:56:53.004273Z","shell.execute_reply":"2024-07-02T08:56:53.018338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"random.shuffle(train_paths)\nrandom.shuffle(valid_paths)","metadata":{"execution":{"iopub.status.busy":"2024-07-02T08:56:53.020145Z","iopub.execute_input":"2024-07-02T08:56:53.020455Z","iopub.status.idle":"2024-07-02T08:56:53.048837Z","shell.execute_reply.started":"2024-07-02T08:56:53.020431Z","shell.execute_reply":"2024-07-02T08:56:53.048068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cat_path = os.path.join(train_path,cat_paths[0])\ncat_image = Image.open(cat_path)\ncat_image","metadata":{"execution":{"iopub.status.busy":"2024-07-02T08:56:53.049731Z","iopub.execute_input":"2024-07-02T08:56:53.049992Z","iopub.status.idle":"2024-07-02T08:56:53.081300Z","shell.execute_reply.started":"2024-07-02T08:56:53.049969Z","shell.execute_reply":"2024-07-02T08:56:53.080540Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dog_path = os.path.join(train_path,dog_paths[0])\ndog_image = Image.open(dog_path)\ndog_image","metadata":{"execution":{"iopub.status.busy":"2024-07-02T08:56:53.082423Z","iopub.execute_input":"2024-07-02T08:56:53.082987Z","iopub.status.idle":"2024-07-02T08:56:53.144477Z","shell.execute_reply.started":"2024-07-02T08:56:53.082956Z","shell.execute_reply":"2024-07-02T08:56:53.143641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"we can see inconsistent in sizes of pictures..","metadata":{}},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.PILToTensor()\n])","metadata":{"execution":{"iopub.status.busy":"2024-07-02T08:56:53.145683Z","iopub.execute_input":"2024-07-02T08:56:53.146055Z","iopub.status.idle":"2024-07-02T08:56:53.150310Z","shell.execute_reply.started":"2024-07-02T08:56:53.146012Z","shell.execute_reply":"2024-07-02T08:56:53.149384Z"},"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    def __getitem__(self,index):\n        img = Image.open(os.path.join(train_path,self.paths[index]))\n        img = img.resize((227,227)) # as alexnet needs\n        label =self.paths[index][:3]\n        if self.transform:\n            img = self.transform(img)\n            img = img.type(torch.float32)\n    \n        return img, int(label == 'cat')\n    def __len__(self):\n        return len(self.paths)","metadata":{"execution":{"iopub.status.busy":"2024-07-02T08:56:53.151371Z","iopub.execute_input":"2024-07-02T08:56:53.151650Z","iopub.status.idle":"2024-07-02T08:56:53.160417Z","shell.execute_reply.started":"2024-07-02T08:56:53.151627Z","shell.execute_reply":"2024-07-02T08:56:53.159414Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"traindata = dataset(paths=train_paths,transform = transform)\nvaliddata = dataset(paths=valid_paths,transform = transform)\n\ntrain_loader = DataLoader(dataset = traindata,shuffle=True,batch_size=32)\nvalid_loader = DataLoader(dataset = validdata,shuffle=False,batch_size=32)","metadata":{"execution":{"iopub.status.busy":"2024-07-02T08:56:53.162852Z","iopub.execute_input":"2024-07-02T08:56:53.163180Z","iopub.status.idle":"2024-07-02T08:56:53.171923Z","shell.execute_reply.started":"2024-07-02T08:56:53.163150Z","shell.execute_reply":"2024-07-02T08:56:53.171080Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"next(iter(train_loader))[0].shape","metadata":{"execution":{"iopub.status.busy":"2024-07-02T08:57:02.421131Z","iopub.execute_input":"2024-07-02T08:57:02.421543Z","iopub.status.idle":"2024-07-02T08:57:02.614631Z","shell.execute_reply.started":"2024-07-02T08:57:02.421512Z","shell.execute_reply":"2024-07-02T08:57:02.613663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"next(iter(train_loader))[0]","metadata":{"execution":{"iopub.status.busy":"2024-07-02T08:57:02.616896Z","iopub.execute_input":"2024-07-02T08:57:02.617351Z","iopub.status.idle":"2024-07-02T08:57:02.798448Z","shell.execute_reply.started":"2024-07-02T08:57:02.617315Z","shell.execute_reply":"2024-07-02T08:57:02.797512Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"next(iter(train_loader))[1]","metadata":{"execution":{"iopub.status.busy":"2024-07-02T08:57:02.799599Z","iopub.execute_input":"2024-07-02T08:57:02.799889Z","iopub.status.idle":"2024-07-02T08:57:02.931703Z","shell.execute_reply.started":"2024-07-02T08:57:02.799864Z","shell.execute_reply":"2024-07-02T08:57:02.930770Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"traindata[0][0].shape","metadata":{"execution":{"iopub.status.busy":"2024-07-02T08:57:02.932860Z","iopub.execute_input":"2024-07-02T08:57:02.933161Z","iopub.status.idle":"2024-07-02T08:57:02.944834Z","shell.execute_reply.started":"2024-07-02T08:57:02.933134Z","shell.execute_reply":"2024-07-02T08:57:02.943946Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimage = traindata[0]\nplt.imshow(image[0].permute(2,1,0))\n\nprint(image[1])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-07-02T08:57:02.946674Z","iopub.execute_input":"2024-07-02T08:57:02.946926Z","iopub.status.idle":"2024-07-02T08:57:03.212386Z","shell.execute_reply.started":"2024-07-02T08:57:02.946904Z","shell.execute_reply":"2024-07-02T08:57:03.211442Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Build the Model","metadata":{}},{"cell_type":"code","source":"class AlexNet(nn.Module):\n    def __init__(self, num_classes):\n        super(AlexNet, self).__init__()\n        \n        self.conv1 = nn.Conv2d(3,96, kernel_size=11, stride=4)\n        self.mx1 = nn.MaxPool2d(kernel_size=3, stride=2)\n        \n        self.conv2 = nn.Conv2d(96, 256, kernel_size = 5, padding=\"same\")\n        self.mx2 = nn.MaxPool2d(kernel_size=3, stride=2)\n        \n        self.conv3 = nn.Conv2d(256, 384, kernel_size=3, padding=\"same\")\n        self.conv4 = nn.Conv2d(384, 384, kernel_size=3, padding=\"same\")\n        self.conv5 = nn.Conv2d(384, 256, kernel_size=3, padding=\"same\")\n        \n        self.mx3 = nn.MaxPool2d(kernel_size=3, stride=2)\n        \n        self.linear1 = nn.Linear(9216, 4096)\n        self.linear2 = nn.Linear(4096, 4096)        \n        self.linear3 = nn.Linear(4096, num_classes)\n        \n    def forward(self, x):\n        out = self.mx1(nn.ReLU()(self.conv1(x)))\n        out = self.mx2(nn.ReLU()(self.conv2(out)))\n        out = nn.ReLU()(self.conv3(out))\n        out = nn.ReLU()(self.conv4(out))\n        out = self.mx3(nn.ReLU()(self.conv5(out)))\n        out = nn.Flatten()(out)\n        out = nn.ReLU()(self.linear1(out))\n        out = nn.ReLU()(self.linear2(out))\n        out = self.linear3(out)\n        \n        return out\n        ","metadata":{"execution":{"iopub.status.busy":"2024-07-02T09:35:29.175463Z","iopub.execute_input":"2024-07-02T09:35:29.176250Z","iopub.status.idle":"2024-07-02T09:35:29.186900Z","shell.execute_reply.started":"2024-07-02T09:35:29.176217Z","shell.execute_reply":"2024-07-02T09:35:29.186064Z"},"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-07-02T09:35:31.391197Z","iopub.execute_input":"2024-07-02T09:35:31.391914Z","iopub.status.idle":"2024-07-02T09:35:31.397800Z","shell.execute_reply.started":"2024-07-02T09:35:31.391881Z","shell.execute_reply":"2024-07-02T09:35:31.396996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = AlexNet(num_classes=2).to(device)\nn_epochs = 10\nlr = 0.005\n\ncriterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.SGD(model.parameters(), lr = lr)","metadata":{"execution":{"iopub.status.busy":"2024-07-02T09:59:50.168019Z","iopub.execute_input":"2024-07-02T09:59:50.168667Z","iopub.status.idle":"2024-07-02T09:59:50.663376Z","shell.execute_reply.started":"2024-07-02T09:59:50.168636Z","shell.execute_reply":"2024-07-02T09:59:50.662586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(train_loader) # number of batches with size 32 each..","metadata":{"execution":{"iopub.status.busy":"2024-07-02T09:59:51.850453Z","iopub.execute_input":"2024-07-02T09:59:51.851046Z","iopub.status.idle":"2024-07-02T09:59:51.856338Z","shell.execute_reply.started":"2024-07-02T09:59:51.851003Z","shell.execute_reply":"2024-07-02T09:59:51.855508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Training and Validation helping Functions","metadata":{}},{"cell_type":"code","source":"def train_epoch():\n    epoch_loss = 0.0\n    num_batches = 0\n    with tqdm(train_loader, unit=\"batch\", leave=False) as tepoch:\n        for images, labels in tepoch:\n            images = images.to(device)\n            labels = labels.to(device)\n\n            # Forward pass\n            out = model(images)\n            loss = criterion(out, labels)\n\n            # Backward pass\n            optimizer.zero_grad()\n            loss.backward()\n            optimizer.step()\n\n            # Update epoch loss\n            epoch_loss += loss.item()\n            num_batches += 1\n\n            # Update progress bar\n            tepoch.set_postfix(loss=epoch_loss / num_batches)\n\n    return epoch_loss / num_batches\n\ndef calc_valid_loss():\n    epoch_loss = 0.0\n    num_batches = 0\n    with torch.no_grad():\n        with tqdm(valid_loader, unit=\"batch\", leave=False) as vepoch:\n            for images, labels in vepoch:\n                images = images.to(device)\n                labels = labels.to(device)\n\n                # Forward pass\n                out = model(images)\n                loss = criterion(out, labels)\n\n                # Update epoch loss\n                epoch_loss += loss.item()\n                num_batches += 1\n\n                # Update progress bar\n                vepoch.set_postfix(loss=epoch_loss / num_batches)\n\n    return epoch_loss / num_batches","metadata":{"execution":{"iopub.status.busy":"2024-07-02T09:59:52.200225Z","iopub.execute_input":"2024-07-02T09:59:52.200842Z","iopub.status.idle":"2024-07-02T09:59:52.210136Z","shell.execute_reply.started":"2024-07-02T09:59:52.200808Z","shell.execute_reply":"2024-07-02T09:59:52.209293Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_losses, valid_losses = [], []\nbest_score = float('inf') # for model check point\ntolerance = 4","metadata":{"execution":{"iopub.status.busy":"2024-07-02T09:59:53.572124Z","iopub.execute_input":"2024-07-02T09:59:53.572784Z","iopub.status.idle":"2024-07-02T09:59:53.576753Z","shell.execute_reply.started":"2024-07-02T09:59:53.572751Z","shell.execute_reply":"2024-07-02T09:59:53.575906Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Training Loop","metadata":{}},{"cell_type":"code","source":"for epoch in range(n_epochs):\n    print(f\"Epoch [{epoch+1}/{n_epochs}]\")\n    \n    # Training\n    model.train()\n    avg_train_loss = train_epoch()\n    \n    # Validation\n    model.eval()\n    avg_valid_loss = calc_valid_loss()\n    \n    train_losses.append(avg_train_loss)\n    valid_losses.append(avg_valid_loss)\n    \n    print(f\"Train Loss = {avg_train_loss:.4f}, Validation Loss = {avg_valid_loss:.4f}\")\n    \n    if avg_valid_loss < best_score:\n        best_score = avg_valid_loss\n        torch.save(model.state_dict(), f'model_best.pth')\n        tol = tolerance\n    else:\n        tol-=1\n        if tol == 0:\n            print(f'Early Stopping')\n        \n    print('='*90)","metadata":{"execution":{"iopub.status.busy":"2024-07-02T09:59:53.578287Z","iopub.execute_input":"2024-07-02T09:59:53.578562Z","iopub.status.idle":"2024-07-02T10:15:20.718459Z","shell.execute_reply.started":"2024-07-02T09:59:53.578539Z","shell.execute_reply":"2024-07-02T10:15:20.717072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_losses[:3]","metadata":{"execution":{"iopub.status.busy":"2024-07-02T10:16:17.264902Z","iopub.execute_input":"2024-07-02T10:16:17.265569Z","iopub.status.idle":"2024-07-02T10:16:17.271005Z","shell.execute_reply.started":"2024-07-02T10:16:17.265537Z","shell.execute_reply":"2024-07-02T10:16:17.270188Z"},"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(valid_losses, 'r-', label='Valid Loss')\nplt.title('Train Loss vs Validation Loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-07-02T10:16:29.693132Z","iopub.execute_input":"2024-07-02T10:16:29.693901Z","iopub.status.idle":"2024-07-02T10:16:29.965106Z","shell.execute_reply.started":"2024-07-02T10:16:29.693872Z","shell.execute_reply":"2024-07-02T10:16:29.964242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Load the Model","metadata":{}},{"cell_type":"code","source":"model = AlexNet(2).to(device)\nmodel.eval()\nmodel.load_state_dict(torch.load('/kaggle/working/model_best.pth',map_location=device))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"calc_valid_loss()","metadata":{},"execution_count":null,"outputs":[]}]}