{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":5441,"databundleVersionId":38425,"sourceType":"competition"}],"dockerImageVersionId":30636,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Kaggle link: https://www.kaggle.com/code/lorenzozanolin/dog-vs-cats-zanolin\n\n\nW&B link: https://wandb.ai/lorenzozanolin-52/dogs_cats/table?workspace=user-lorenzozanolin-52","metadata":{}},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.status.busy":"2024-01-15T11:09:11.395578Z","iopub.execute_input":"2024-01-15T11:09:11.395839Z","iopub.status.idle":"2024-01-15T11:09:13.229933Z","shell.execute_reply.started":"2024-01-15T11:09:11.395814Z","shell.execute_reply":"2024-01-15T11:09:13.228864Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Import everything needed","metadata":{}},{"cell_type":"code","source":"import zipfile\nimport glob\nfrom PIL import Image\nimport matplotlib.pyplot as plt\n\nfrom sklearn.model_selection import train_test_split\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader, Dataset\nfrom torchvision import datasets, transforms\nnp.random.seed(0)\ntorch.manual_seed(0)\ntorch.cuda.manual_seed(0)\n\nimport wandb\nfrom kaggle_secrets import UserSecretsClient\nuser_secrets = UserSecretsClient()\nsecret_value_0 = user_secrets.get_secret(\"a\")\nwandb.login(key=secret_value_0)\nwandb.init(project='dogs_cats', save_code=True)","metadata":{"execution":{"iopub.status.busy":"2024-01-15T11:09:13.231583Z","iopub.execute_input":"2024-01-15T11:09:13.231951Z","iopub.status.idle":"2024-01-15T11:09:57.479562Z","shell.execute_reply.started":"2024-01-15T11:09:13.231926Z","shell.execute_reply":"2024-01-15T11:09:57.478646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Unzip datasets","metadata":{}},{"cell_type":"code","source":"train_dir = 'train'\ntest_dir = 'test'\nwith zipfile.ZipFile('/kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip') as train_zip:\n    train_zip.extractall('')\n    \nwith zipfile.ZipFile('/kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip') as test_zip:\n    test_zip.extractall('')\ntrain_list = glob.glob(os.path.join(train_dir,'*.jpg'))\ntest_list = glob.glob(os.path.join(test_dir, '*.jpg'))\nprint(f\"Train Data: {len(train_list)}\")\nprint(f\"Test Data: {len(test_list)}\")","metadata":{"execution":{"iopub.status.busy":"2024-01-15T11:09:57.480852Z","iopub.execute_input":"2024-01-15T11:09:57.481187Z","iopub.status.idle":"2024-01-15T11:10:16.553250Z","shell.execute_reply.started":"2024-01-15T11:09:57.481153Z","shell.execute_reply":"2024-01-15T11:10:16.552346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = [path.split('/')[-1].split('.')[0] for path in train_list]   #ground truth","metadata":{"execution":{"iopub.status.busy":"2024-01-15T11:10:16.555802Z","iopub.execute_input":"2024-01-15T11:10:16.556139Z","iopub.status.idle":"2024-01-15T11:10:17.006616Z","shell.execute_reply.started":"2024-01-15T11:10:16.556108Z","shell.execute_reply":"2024-01-15T11:10:17.005696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Plot random image with their label","metadata":{}},{"cell_type":"code","source":"random_idx = np.random.randint(1, len(train_list), size=9)\nfig, axes = plt.subplots(3, 3, figsize=(16, 12))\n\nfor idx, ax in enumerate(axes.ravel()):\n    img = Image.open(train_list[idx])\n    ax.set_title(labels[idx])\n    ax.imshow(img)","metadata":{"execution":{"iopub.status.busy":"2024-01-15T11:10:17.007753Z","iopub.execute_input":"2024-01-15T11:10:17.008063Z","iopub.status.idle":"2024-01-15T11:10:20.317395Z","shell.execute_reply.started":"2024-01-15T11:10:17.008037Z","shell.execute_reply":"2024-01-15T11:10:20.316474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Use Sklearn to split the training data","metadata":{}},{"cell_type":"code","source":"train_list, valid_list = train_test_split(train_list, \n                                          test_size=0.2,\n                                          stratify=labels,\n                                          random_state=0)","metadata":{"execution":{"iopub.status.busy":"2024-01-15T11:10:20.318621Z","iopub.execute_input":"2024-01-15T11:10:20.318972Z","iopub.status.idle":"2024-01-15T11:10:20.731374Z","shell.execute_reply.started":"2024-01-15T11:10:20.318937Z","shell.execute_reply":"2024-01-15T11:10:20.729794Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Train Data: {len(train_list)}\")\nprint(f\"Validation Data: {len(valid_list)}\")\nprint(f\"Test Data: {len(test_list)}\")","metadata":{"execution":{"iopub.status.busy":"2024-01-15T11:10:20.732977Z","iopub.execute_input":"2024-01-15T11:10:20.733372Z","iopub.status.idle":"2024-01-15T11:10:21.120514Z","shell.execute_reply.started":"2024-01-15T11:10:20.733315Z","shell.execute_reply":"2024-01-15T11:10:21.119379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train_list[0])\nprint(test_list[0])","metadata":{"execution":{"iopub.status.busy":"2024-01-15T11:10:21.121966Z","iopub.execute_input":"2024-01-15T11:10:21.122380Z","iopub.status.idle":"2024-01-15T11:10:21.528430Z","shell.execute_reply.started":"2024-01-15T11:10:21.122325Z","shell.execute_reply":"2024-01-15T11:10:21.525914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We will discuss this in more detail in a near future...","metadata":{}},{"cell_type":"code","source":"train_transforms = transforms.Compose([\n    transforms.Resize((128, 128)),\n    transforms.RandomHorizontalFlip(p=0.5),\n    transforms.RandomRotation(degrees=15),\n    transforms.ToTensor(),\n])\n\ntest_transforms = transforms.Compose([\n    transforms.Resize((128, 128)),\n    transforms.ToTensor(),\n])","metadata":{"execution":{"iopub.status.busy":"2024-01-15T11:10:21.530029Z","iopub.execute_input":"2024-01-15T11:10:21.530458Z","iopub.status.idle":"2024-01-15T11:10:21.913240Z","shell.execute_reply.started":"2024-01-15T11:10:21.530414Z","shell.execute_reply":"2024-01-15T11:10:21.912354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Define the dataset using PIL to read image","metadata":{}},{"cell_type":"code","source":"class CatsDogsDataset(Dataset):\n    def __init__(self, file_list, transform=None):\n        self.file_list = file_list\n        self.transform = transform\n        self.filelength = len(file_list)\n\n    def __len__(self):\n        return self.filelength\n\n    def __getitem__(self, idx):\n        img_path = self.file_list[idx]\n        img = Image.open(img_path)\n        img_transformed = self.transform(img)\n        label = img_path.split(\"/\")[-1].split(\".\")[0]\n        label = 1 if label == \"dog\" else 0\n        return img_transformed, label","metadata":{"execution":{"iopub.status.busy":"2024-01-15T11:10:21.916801Z","iopub.execute_input":"2024-01-15T11:10:21.917228Z","iopub.status.idle":"2024-01-15T11:10:22.269476Z","shell.execute_reply.started":"2024-01-15T11:10:21.917190Z","shell.execute_reply":"2024-01-15T11:10:22.268386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data = CatsDogsDataset(train_list, transform=train_transforms)\nvalid_data = CatsDogsDataset(valid_list, transform=test_transforms)\ntest_data = CatsDogsDataset(test_list, transform=test_transforms)","metadata":{"execution":{"iopub.status.busy":"2024-01-15T11:10:22.270742Z","iopub.execute_input":"2024-01-15T11:10:22.271091Z","iopub.status.idle":"2024-01-15T11:10:22.641222Z","shell.execute_reply.started":"2024-01-15T11:10:22.271058Z","shell.execute_reply":"2024-01-15T11:10:22.640358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Let's see what is the size of an image from the dataset","metadata":{}},{"cell_type":"code","source":"print(train_data[0][0].shape)","metadata":{"execution":{"iopub.status.busy":"2024-01-15T11:10:22.642523Z","iopub.execute_input":"2024-01-15T11:10:22.642825Z","iopub.status.idle":"2024-01-15T11:10:23.098351Z","shell.execute_reply.started":"2024-01-15T11:10:22.642799Z","shell.execute_reply":"2024-01-15T11:10:23.097502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Create dataloader, you can modify the batch size if needed","metadata":{}},{"cell_type":"code","source":"batch_size = 32\nwandb.log({'batch_size': batch_size})\ntrain_loader = DataLoader(dataset=train_data, batch_size=batch_size, shuffle=True)\nvalid_loader = DataLoader(dataset=valid_data, batch_size=batch_size, shuffle=False)\ntest_loader = DataLoader(dataset=test_data, batch_size=batch_size, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2024-01-15T11:10:23.099610Z","iopub.execute_input":"2024-01-15T11:10:23.099946Z","iopub.status.idle":"2024-01-15T11:10:23.516695Z","shell.execute_reply.started":"2024-01-15T11:10:23.099912Z","shell.execute_reply":"2024-01-15T11:10:23.515810Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torch.nn import Module\nfrom torch.nn import Conv2d\nfrom torch.nn import Linear\nfrom torch.nn import MaxPool2d\nfrom torch.nn import ReLU\nfrom torch.nn import LogSoftmax\nfrom torch.nn import Dropout\nfrom torch import flatten\n\nclass Net(nn.Module):\n    def __init__(self):\n        super(Net, self).__init__()\n        self.layer1 = nn.Sequential(\n            nn.Conv2d(3,20,kernel_size=(5,5), padding=1,stride=1),  #3 input channels, 20 out channels\n            #nn.BatchNorm2d(32),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size=(2, 2), stride=(2, 2)),\n            #nn.Dropout(0.2)\n        )\n        \n        self.layer2 = nn.Sequential(\n            nn.Conv2d(in_channels=20, out_channels=50, kernel_size=(5,5)),\n            #nn.BatchNorm2d(64),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size=(2, 2), stride=(2, 2)),\n            #nn.Dropout(0.2)\n            )\n        \n        #self.layer3 = nn.Sequential(\n        #    nn.Conv2d(64,128, kernel_size=3, padding=0, stride=1),\n        #    nn.BatchNorm2d(128),\n        #    nn.ReLU(),\n        #    nn.MaxPool2d(2),\n        #    nn.Dropout(0.2)\n        #)\n        \n        #self.layer4 = nn.Sequential(\n        #    nn.Conv2d(128,256, kernel_size=3, padding=0, stride=1),\n        #    nn.BatchNorm2d(256),\n        #    nn.ReLU(),\n        #    nn.MaxPool2d(2),\n        #    nn.Dropout(0.2)\n        #)\n        \n        \n        #self.fc1 = nn.Linear(25600,512)\n        self.fc1 = nn.Linear(in_features=42050, out_features=500)\n        self.relu = nn.ReLU()\n        #self.dropout = nn.Dropout(0.5)\n        self.fc2 = nn.Linear(in_features=500, out_features=2)\n        \n        \n    def forward(self,x):\n        out = self.layer1(x)\n        out = self.layer2(out)\n        #out = self.layer3(out)\n        #out = self.layer4(out)\n        out = out.view(out.size(0),-1)\n        out = self.relu(self.fc1(out))\n        out = self.fc2(out)\n        return out","metadata":{"execution":{"iopub.status.busy":"2024-01-15T11:10:23.517922Z","iopub.execute_input":"2024-01-15T11:10:23.518301Z","iopub.status.idle":"2024-01-15T11:10:23.867925Z","shell.execute_reply.started":"2024-01-15T11:10:23.518263Z","shell.execute_reply":"2024-01-15T11:10:23.867050Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = 'cuda' if torch.cuda.is_available() else 'cpu'\nnet = Net().to(device)\nnet.train()","metadata":{"execution":{"iopub.status.busy":"2024-01-15T11:10:23.869180Z","iopub.execute_input":"2024-01-15T11:10:23.869557Z","iopub.status.idle":"2024-01-15T11:10:24.678183Z","shell.execute_reply.started":"2024-01-15T11:10:23.869520Z","shell.execute_reply":"2024-01-15T11:10:24.677367Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lr = 0.01\n\no = 's'\n\nif o == 's':\n    optimizer = torch.optim.SGD(net.parameters(), lr=lr)\n    wandb.log({'optimizer':'SGD'})\nelif o == 'a':\n    optimizer = torch.optim.Adam(net.parameters(), lr=lr)\n    wandb.log({'optimizer':'Adam'})\n\nwandb.log({'lr': lr})\ncriterion = nn.CrossEntropyLoss()\n\nepochs = 15\nwandb.log({'epochs': epochs})\n\nfor epoch in range(epochs):\n    epoch_loss = 0\n    epoch_accuracy = 0\n    \n    train_losses = []\n    train_acc = []\n    valid_losses = []\n    valid_acc = []\n    \n    for data, label in train_loader:\n        data = data.to(device)\n        label = label.to(device)\n        \n        output = net(data)\n        loss = criterion(output, label)\n        \n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n        \n        acc = ((output.argmax(dim=1) == label).float().mean())\n        epoch_accuracy += acc/len(train_loader)\n        epoch_loss += loss/len(train_loader)\n        train_losses.append(epoch_loss)\n        train_acc.append(epoch_accuracy)\n        \n    print('Epoch : {}, train accuracy : {}, train loss : {}'.format(epoch+1, epoch_accuracy,epoch_loss))\n    \n    \n    with torch.no_grad():\n        epoch_val_accuracy=0\n        epoch_val_loss =0\n        for data, label in valid_loader:\n            data = data.to(device)\n            label = label.to(device)\n            \n            val_output = net(data)\n            val_loss = criterion(val_output,label)\n            \n            \n            acc = ((val_output.argmax(dim=1) == label).float().mean())\n            epoch_val_accuracy += acc/ len(valid_loader)\n            epoch_val_loss += val_loss/ len(valid_loader)\n            valid_losses.append(epoch_val_loss)\n            valid_acc.append(epoch_val_accuracy)\n            \n        print('Epoch : {}, val_accuracy : {}, val_loss : {}'.format(epoch+1, epoch_val_accuracy,epoch_val_loss))\n        \nwandb.log({'train_loss':train_losses[-1]})\nwandb.log({'val_loss':valid_losses[-1]})\nwandb.log({'val_accuracy':valid_acc[-1]})\nwandb.log({'train_accuracy':train_acc[-1]})","metadata":{"execution":{"iopub.status.busy":"2024-01-15T11:10:24.679448Z","iopub.execute_input":"2024-01-15T11:10:24.679774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dog_probs = []\nnet.eval()\ni=0\nwith torch.no_grad():\n    for data, _ in test_loader:\n        data = data.to(device)\n        preds = net(data)\n        preds_list = F.softmax(preds, dim=1)[:, 1].tolist()\n        dog_probs += list(zip(list(range(1+i,batch_size+1+i)), preds_list))\n        #print(preds_list)\n        i += batch_size\n        \n#dog_probs.sort(key = lambda x : int(x[0]))\n#print(dog_probs[1])\n\nidx = list(map(lambda x: x[0],dog_probs))\nprob = list(map(lambda x: x[1],dog_probs))\nfor i in range(1,len(dog_probs)):\n    submission = pd.DataFrame({'id':idx,'label':prob})\nsubmission.to_csv('submission.csv',index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}