{"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":74704,"databundleVersionId":8152167,"sourceType":"competition"}],"dockerImageVersionId":30698,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"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":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-04-18T23:56:02.966447Z","iopub.execute_input":"2024-04-18T23:56:02.966854Z","iopub.status.idle":"2024-04-18T23:56:04.583258Z","shell.execute_reply.started":"2024-04-18T23:56:02.966823Z","shell.execute_reply":"2024-04-18T23:56:04.581723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torchvision\nfrom torchvision import datasets, transforms\nfrom tqdm import tqdm","metadata":{"execution":{"iopub.status.busy":"2024-04-19T04:41:25.987781Z","iopub.execute_input":"2024-04-19T04:41:25.988194Z","iopub.status.idle":"2024-04-19T04:41:25.993985Z","shell.execute_reply.started":"2024-04-19T04:41:25.988163Z","shell.execute_reply":"2024-04-19T04:41:25.992741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dir = \"/kaggle/input/ece379k-hw4-flower-classification-24spring/train\"\ntest_dir = \"/kaggle/input/ece379k-hw4-flower-classification-24spring/test\"","metadata":{"execution":{"iopub.status.busy":"2024-04-19T04:41:26.861299Z","iopub.execute_input":"2024-04-19T04:41:26.861667Z","iopub.status.idle":"2024-04-19T04:41:26.866184Z","shell.execute_reply.started":"2024-04-19T04:41:26.861639Z","shell.execute_reply":"2024-04-19T04:41:26.865198Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"full_dataset = datasets.ImageFolder(train_dir, transforms.Compose([transforms.Resize(size=(256,256)), transforms.ToTensor()]))\n\ntrain_size = int(len(full_dataset) * 0.8)\n\ntrain_dataset, val_dataset = torch.utils.data.random_split(full_dataset, [train_size, len(full_dataset)-train_size])\n\ntrain_loader = torch.utils.data.DataLoader(train_dataset, batch_size=16, shuffle=True)","metadata":{"execution":{"iopub.status.busy":"2024-04-19T04:41:27.626173Z","iopub.execute_input":"2024-04-19T04:41:27.626868Z","iopub.status.idle":"2024-04-19T04:41:27.878038Z","shell.execute_reply.started":"2024-04-19T04:41:27.626839Z","shell.execute_reply":"2024-04-19T04:41:27.877253Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class resnet(nn.Module):\n    def __init__(self):\n        super(resnet, self).__init__()\n        self.resnet = torchvision.models.resnet50(pretrained=True)\n        self.resnet.fc = nn.Linear(self.resnet.fc.in_features, 5)\n\n    def forward(self, x):\n        return self.resnet(x)","metadata":{"execution":{"iopub.status.busy":"2024-04-19T04:44:22.733992Z","iopub.execute_input":"2024-04-19T04:44:22.734613Z","iopub.status.idle":"2024-04-19T04:44:22.740620Z","shell.execute_reply.started":"2024-04-19T04:44:22.734578Z","shell.execute_reply":"2024-04-19T04:44:22.739593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = \"cuda\" if torch.cuda.is_available() else \"cpu\"","metadata":{"execution":{"iopub.status.busy":"2024-04-19T04:44:23.861189Z","iopub.execute_input":"2024-04-19T04:44:23.861974Z","iopub.status.idle":"2024-04-19T04:44:23.865943Z","shell.execute_reply.started":"2024-04-19T04:44:23.861944Z","shell.execute_reply":"2024-04-19T04:44:23.864968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = resnet()\nmodel.to(device)\nloss_fn = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters())","metadata":{"execution":{"iopub.status.busy":"2024-04-19T04:44:39.757952Z","iopub.execute_input":"2024-04-19T04:44:39.758578Z","iopub.status.idle":"2024-04-19T04:44:40.345500Z","shell.execute_reply.started":"2024-04-19T04:44:39.758547Z","shell.execute_reply":"2024-04-19T04:44:40.344489Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 10\nmodel","metadata":{"execution":{"iopub.status.busy":"2024-04-19T04:44:43.348203Z","iopub.execute_input":"2024-04-19T04:44:43.348934Z","iopub.status.idle":"2024-04-19T04:44:43.356902Z","shell.execute_reply.started":"2024-04-19T04:44:43.348898Z","shell.execute_reply":"2024-04-19T04:44:43.356013Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for epoch in range(epochs):\n    for i, data in tqdm(enumerate(train_loader), total=len(train_loader)):\n        inputs, labels = data\n        inputs = inputs.to(device)\n        labels = labels.to(device)\n        optimizer.zero_grad()\n        outputs = model(inputs)\n        loss = loss_fn(outputs, labels)\n        loss.backward()\n        optimizer.step()\n\n        if i % 100 == 0:\n            print(f\"epoch {epoch}, batch {i}, loss {loss.item()}\")","metadata":{"execution":{"iopub.status.busy":"2024-04-19T04:41:55.832216Z","iopub.execute_input":"2024-04-19T04:41:55.832590Z","iopub.status.idle":"2024-04-19T04:42:12.210688Z","shell.execute_reply.started":"2024-04-19T04:41:55.832561Z","shell.execute_reply":"2024-04-19T04:42:12.209205Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# test on validation set\nval_loader = torch.utils.data.DataLoader(val_dataset, batch_size=16, shuffle=True)\n\ncorrect = 0\n\nfor i, data in tqdm(enumerate(val_loader), total=len(val_loader)):\n\n    inputs, labels = data\n    inputs = inputs.to(device)\n    labels = labels.to(device)\n    outputs = model(inputs)\n    _, predicted = torch.max(outputs, 1)\n    correct += (predicted == labels).sum().item()\n\nprint(f\"accuracy on validation set: {correct/len(val_dataset)}\")\n\n","metadata":{"execution":{"iopub.status.busy":"2024-04-19T04:07:51.408462Z","iopub.execute_input":"2024-04-19T04:07:51.409184Z","iopub.status.idle":"2024-04-19T04:08:00.192542Z","shell.execute_reply.started":"2024-04-19T04:07:51.409155Z","shell.execute_reply":"2024-04-19T04:08:00.191725Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport os\n\nfrom PIL import Image\n\nclass ImageDataset(torch.utils.data.Dataset):\n    def __init__(self, img_dir, transform=None):\n        self.img_dir = img_dir\n        self.img_names = os.listdir(img_dir)\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.img_names)\n\n    def __getitem__(self, idx):\n        img_path = os.path.join(self.img_dir, self.img_names[idx])\n        image = Image.open(img_path).convert('RGB')\n        if self.transform:\n            image = self.transform(image)\n        return image, self.img_names[idx]\n","metadata":{"execution":{"iopub.status.busy":"2024-04-19T04:18:06.936734Z","iopub.execute_input":"2024-04-19T04:18:06.937559Z","iopub.status.idle":"2024-04-19T04:18:06.944697Z","shell.execute_reply.started":"2024-04-19T04:18:06.937527Z","shell.execute_reply":"2024-04-19T04:18:06.943608Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# save as csv for predictions on test set\nclasses = ['daisy', 'dandelion', 'rose', 'sunflower','tulip']\n\ntest_dataset = ImageDataset(test_dir, transforms.Compose([transforms.Resize(size=(256,256)), transforms.ToTensor()]))\n    \ntest_loader = torch.utils.data.DataLoader(test_dataset, batch_size=1, shuffle=False)\n\nmodel.eval()\n\npredictions = []\n\nfor i, data in tqdm(enumerate(test_loader), total=len(test_loader)):\n    inputs, labels = data\n    inputs = inputs.to(device)\n    outputs = model(inputs)\n    _, predicted = torch.max(outputs, 1)\n    \n    for i in range(len(predicted)):\n        predictions.append((labels[i], classes[predicted[i].item()]))\n\n\ndf = pd.DataFrame(predictions, columns=[\"Id\", \"Category\"])\n\ndf.to_csv(\"flower_predictions.csv\", index=False)\n\n","metadata":{"execution":{"iopub.status.busy":"2024-04-19T04:29:56.475026Z","iopub.execute_input":"2024-04-19T04:29:56.475662Z","iopub.status.idle":"2024-04-19T04:29:59.921037Z","shell.execute_reply.started":"2024-04-19T04:29:56.475630Z","shell.execute_reply":"2024-04-19T04:29:59.920103Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"full_dataset.class_to_idx","metadata":{"execution":{"iopub.status.busy":"2024-04-19T04:22:57.535266Z","iopub.execute_input":"2024-04-19T04:22:57.535896Z","iopub.status.idle":"2024-04-19T04:22:57.541957Z","shell.execute_reply.started":"2024-04-19T04:22:57.535868Z","shell.execute_reply":"2024-04-19T04:22:57.541061Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}