{"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":"# 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\n# for 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":"2022-09-26T02:20:59.954796Z","iopub.execute_input":"2022-09-26T02:20:59.956097Z","iopub.status.idle":"2022-09-26T02:20:59.990506Z","shell.execute_reply.started":"2022-09-26T02:20:59.955977Z","shell.execute_reply":"2022-09-26T02:20:59.988978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import random\nimport torch\nimport torchvision\nimport PIL\nimport torchvision.transforms as transforms\nfrom tqdm import tqdm","metadata":{"execution":{"iopub.status.busy":"2022-09-26T02:20:59.995206Z","iopub.execute_input":"2022-09-26T02:20:59.995621Z","iopub.status.idle":"2022-09-26T02:21:02.619469Z","shell.execute_reply.started":"2022-09-26T02:20:59.995581Z","shell.execute_reply":"2022-09-26T02:21:02.617697Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def seed_everything(seed=42):\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = True\n\nseed_everything()","metadata":{"execution":{"iopub.status.busy":"2022-09-26T02:21:02.627341Z","iopub.execute_input":"2022-09-26T02:21:02.638301Z","iopub.status.idle":"2022-09-26T02:21:02.673018Z","shell.execute_reply.started":"2022-09-26T02:21:02.638240Z","shell.execute_reply":"2022-09-26T02:21:02.669661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## DataLoader 구현 -> 모델(VGG16)구현 -> 학습 -> 평가","metadata":{}},{"cell_type":"markdown","source":"# DataLoader","metadata":{}},{"cell_type":"code","source":"class Dataset(torch.utils.data.Dataset):\n    \n    def __init__(self, split, rootpath, transform, label_map):\n        super(Dataset, self).__init__()\n        \n        self.split = split.upper()\n        self.rootpath = rootpath\n        self.transform = transform\n        self.label_map = label_map\n        \n        self.image_list = []\n        self.label_list = []\n        \n        if self.split == 'TRAIN':\n            classes = os.listdir(os.path.join(self.rootpath, self.split))\n            for cls in classes:\n                self.image_list.extend(os.listdir(os.path.join(self.rootpath, self.split, cls)))\n                self.label_list.extend(np.full(len(os.listdir(os.path.join(self.rootpath, self.split, cls))), cls))\n                                       \n        elif self.split == 'TEST':\n            self.image_list.extend(os.listdir(os.path.join(self.rootpath, self.split)))\n            self.image_list.sort()\n            \n    def __len__(self):\n        return len(self.image_list)\n    \n    def __getitem__(self, index):\n        if self.split == 'TRAIN':\n            img = PIL.Image.open(os.path.join(self.rootpath, self.split, self.label_list[index], self.image_list[index]))\n            img.convert('RGB')\n            img = self.transform(img)\n            return img, self.label_map[self.label_list[index]]\n        \n        elif self.split == 'TEST':\n            img = PIL.Image.open(os.path.join(self.rootpath, self.split, self.image_list[index]))\n            img.convert('RGB')\n            img = self.transform(img)\n            return img","metadata":{"execution":{"iopub.status.busy":"2022-09-26T02:21:02.699245Z","iopub.execute_input":"2022-09-26T02:21:02.704016Z","iopub.status.idle":"2022-09-26T02:21:02.754719Z","shell.execute_reply.started":"2022-09-26T02:21:02.703967Z","shell.execute_reply":"2022-09-26T02:21:02.750307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Resize((224,224)),\n    transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))\n])\n\nlabel_map = { \"buildings\" : 0, \"forest\" : 1, \"glacier\" : 2, \"mountain\" : 3, \"sea\" : 4, \"street\" : 5}","metadata":{"execution":{"iopub.status.busy":"2022-09-26T02:21:02.773929Z","iopub.execute_input":"2022-09-26T02:21:02.775536Z","iopub.status.idle":"2022-09-26T02:21:02.821896Z","shell.execute_reply.started":"2022-09-26T02:21:02.775488Z","shell.execute_reply":"2022-09-26T02:21:02.820190Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = Dataset(split='TRAIN', rootpath='../input/2022-rcv-2nd-urp-vgg16', transform=transform, label_map=label_map)\ntest_dataset = Dataset(split='TEST', rootpath='../input/2022-rcv-2nd-urp-vgg16', transform=transform, label_map=label_map)\n\ntrain_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=64, shuffle=True, drop_last=True, num_workers=2)\ntest_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=64, shuffle=False, num_workers=2)","metadata":{"execution":{"iopub.status.busy":"2022-09-26T02:21:02.838556Z","iopub.execute_input":"2022-09-26T02:21:02.848217Z","iopub.status.idle":"2022-09-26T02:21:03.839243Z","shell.execute_reply.started":"2022-09-26T02:21:02.845100Z","shell.execute_reply":"2022-09-26T02:21:03.836294Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model - VGG16","metadata":{}},{"cell_type":"code","source":"class VGG16(torch.nn.Module):\n    def __init__(self, pretrained, n_classes):\n        super(VGG16, self).__init__()\n        self.pretrained = pretrained\n        self.n_classes = n_classes\n        \n        self.conv1_1 = torch.nn.Conv2d(in_channels=3, out_channels=64, kernel_size=(3,3), stride=1, padding=1)\n        self.conv1_2 = torch.nn.Conv2d(in_channels=64, out_channels=64, kernel_size=(3,3), stride=1, padding=1)\n        \n        self.conv2_1 = torch.nn.Conv2d(in_channels=64, out_channels=128, kernel_size=(3,3), stride=1, padding=1)\n        self.conv2_2 = torch.nn.Conv2d(in_channels=128, out_channels=128, kernel_size=(3,3), stride=1, padding=1)\n        \n        self.conv3_1 = torch.nn.Conv2d(in_channels=128, out_channels=256, kernel_size=(3,3), stride=1, padding=1)\n        self.conv3_2 = torch.nn.Conv2d(in_channels=256, out_channels=256, kernel_size=(3,3), stride=1, padding=1)\n        self.conv3_3 = torch.nn.Conv2d(in_channels=256, out_channels=256, kernel_size=(3,3), stride=1, padding=1)\n        \n        self.conv4_1 = torch.nn.Conv2d(in_channels=256, out_channels=512, kernel_size=(3,3), stride=1, padding=1)\n        self.conv4_2 = torch.nn.Conv2d(in_channels=512, out_channels=512, kernel_size=(3,3), stride=1, padding=1)\n        self.conv4_3 = torch.nn.Conv2d(in_channels=512, out_channels=512, kernel_size=(3,3), stride=1, padding=1)\n        \n        self.conv5_1 = torch.nn.Conv2d(in_channels=512, out_channels=512, kernel_size=(3,3), stride=1, padding=1)\n        self.conv5_2 = torch.nn.Conv2d(in_channels=512, out_channels=512, kernel_size=(3,3), stride=1, padding=1)\n        self.conv5_3 = torch.nn.Conv2d(in_channels=512, out_channels=512, kernel_size=(3,3), stride=1, padding=1)\n        \n        self.fc1 = torch.nn.Linear(in_features = 7*7*512, out_features=4096, bias=True)\n        self.fc2 = torch.nn.Linear(in_features = 4096, out_features=4096, bias=True)\n        self.fc3 = torch.nn.Linear(in_features = 4096, out_features=self.n_classes, bias=True)\n        \n        self.activation = torch.nn.ReLU()\n        self.pool = torch.nn.MaxPool2d(kernel_size = 2, stride = 2)\n        self.dropout = torch.nn.Dropout(p=0.5)\n        \n        self.weight_init()\n        \n    def weight_init(self):\n        if self.pretrained:\n            state_dict = self.state_dict()\n            param_names = list(state_dict.keys())\n\n            pretrained_state_dict = torchvision.models.vgg16(pretrained=True).state_dict()\n            pretrained_param_names = list(pretrained_state_dict.keys())\n\n            for i, name in enumerate(param_names[:-2]):\n                state_dict[name] = pretrained_state_dict[pretrained_param_names[i]]\n\n            self.load_state_dict(state_dict)\n            print(\"Weight Init Finished\")\n        \n    \n    def forward(self, x):\n        out = self.activation(self.conv1_1(x))\n        out = self.activation(self.conv1_2(out))\n        out = self.pool(out)\n        \n        out = self.activation(self.conv2_1(out))\n        out = self.activation(self.conv2_2(out))\n        out = self.pool(out)\n        \n        out = self.activation(self.conv3_1(out))\n        out = self.activation(self.conv3_2(out))\n        out = self.activation(self.conv3_3(out))\n        out = self.pool(out)\n        \n        out = self.activation(self.conv4_1(out))\n        out = self.activation(self.conv4_2(out))\n        out = self.activation(self.conv4_3(out))\n        out = self.pool(out)\n        \n        out = self.activation(self.conv5_1(out))\n        out = self.activation(self.conv5_2(out))\n        out = self.activation(self.conv5_3(out))\n        out = self.pool(out)\n        \n        out = out.view(-1, out.shape[1]*out.shape[2]*out.shape[3])\n        \n        out = self.dropout(self.activation(self.fc1(out)))\n        out = self.dropout(self.activation(self.fc2(out)))\n        out = self.fc3(out)\n        \n        return out","metadata":{"execution":{"iopub.status.busy":"2022-09-26T02:21:03.841160Z","iopub.execute_input":"2022-09-26T02:21:03.841594Z","iopub.status.idle":"2022-09-26T02:21:03.880483Z","shell.execute_reply.started":"2022-09-26T02:21:03.841551Z","shell.execute_reply":"2022-09-26T02:21:03.878611Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = VGG16(pretrained = True, n_classes =6)","metadata":{"execution":{"iopub.status.busy":"2022-09-26T02:21:03.882298Z","iopub.execute_input":"2022-09-26T02:21:03.882904Z","iopub.status.idle":"2022-09-26T02:21:25.580023Z","shell.execute_reply.started":"2022-09-26T02:21:03.882857Z","shell.execute_reply":"2022-09-26T02:21:25.578702Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train","metadata":{}},{"cell_type":"code","source":"loss = torch.nn.CrossEntropyLoss()\noptim = torch.optim.SGD(model.parameters(),lr=0.001,momentum=0.9)\nepochs = 3\nmodel.train()\nmodel = model.cuda()","metadata":{"execution":{"iopub.status.busy":"2022-09-26T02:21:25.582304Z","iopub.execute_input":"2022-09-26T02:21:25.583355Z","iopub.status.idle":"2022-09-26T02:21:29.892562Z","shell.execute_reply.started":"2022-09-26T02:21:25.583311Z","shell.execute_reply":"2022-09-26T02:21:29.891117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for epoch in range(epochs):\n    epoch_acc = 0\n    epoch_loss = 0\n    for x, y in tqdm(train_loader):\n        x = torch.FloatTensor(x).cuda()\n        y = torch.LongTensor(y).cuda()\n        \n        out = model(x)\n        cost = loss(out, y)\n        \n        optim.zero_grad()\n        cost.backward()\n        optim.step()\n        \n        hypothesis = torch.nn.functional.softmax(out, dim=1)\n        pred = torch.argmax(hypothesis, dim=1)\n        \n        correct_pred = (pred == y)\n        \n        epoch_loss += cost.item()\n        epoch_acc += correct_pred.sum()\n    \n    if epoch%1 == 0:\n        print(\"epoch : {} loss : {} acc : {}\".format(epoch+1, epoch_loss, epoch_acc / len(train_loader.dataset)))\n        ","metadata":{"execution":{"iopub.status.busy":"2022-09-26T02:21:29.898249Z","iopub.execute_input":"2022-09-26T02:21:29.898579Z","iopub.status.idle":"2022-09-26T02:27:02.837364Z","shell.execute_reply.started":"2022-09-26T02:21:29.898548Z","shell.execute_reply":"2022-09-26T02:27:02.835569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Evaluate","metadata":{}},{"cell_type":"code","source":"model.eval()\npred_list = []\n\nwith torch.no_grad():\n    for x in tqdm(test_loader):\n        x = x.cuda()\n        out = model(x)\n        \n        hypothesis = torch.nn.functional.softmax(out, dim=1)\n        pred = torch.argmax(hypothesis, dim=1)\n        pred_list.extend(pred.cpu().numpy())","metadata":{"execution":{"iopub.status.busy":"2022-09-26T02:27:02.839714Z","iopub.execute_input":"2022-09-26T02:27:02.841243Z","iopub.status.idle":"2022-09-26T02:27:19.757487Z","shell.execute_reply.started":"2022-09-26T02:27:02.841191Z","shell.execute_reply":"2022-09-26T02:27:19.754898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rev_map = {v : k for k, v in label_map.items()}\nrev_map","metadata":{"execution":{"iopub.status.busy":"2022-09-26T02:27:19.760005Z","iopub.execute_input":"2022-09-26T02:27:19.760521Z","iopub.status.idle":"2022-09-26T02:27:19.773996Z","shell.execute_reply.started":"2022-09-26T02:27:19.760459Z","shell.execute_reply":"2022-09-26T02:27:19.772260Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"final_pred = []\n\nfor i in range(len(pred_list)):\n    final_pred.append(rev_map[pred_list[i]])\n    \nfinal_pred","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2022-09-26T02:27:19.776429Z","iopub.execute_input":"2022-09-26T02:27:19.776889Z","iopub.status.idle":"2022-09-26T02:27:19.812625Z","shell.execute_reply.started":"2022-09-26T02:27:19.776838Z","shell.execute_reply":"2022-09-26T02:27:19.811271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit = pd.read_csv('../input/2022-rcv-2nd-urp-vgg16/sample-submission.csv')\nsubmit['label'] = final_pred\nsubmit.to_csv('baseline.csv', index = False)","metadata":{"execution":{"iopub.status.busy":"2022-09-26T02:27:57.030562Z","iopub.execute_input":"2022-09-26T02:27:57.030992Z","iopub.status.idle":"2022-09-26T02:27:57.064562Z","shell.execute_reply.started":"2022-09-26T02:27:57.030961Z","shell.execute_reply":"2022-09-26T02:27:57.063264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}