{"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\nfrom matplotlib import pyplot as plt\n\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\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":"2023-04-18T13:29:20.871825Z","iopub.execute_input":"2023-04-18T13:29:20.872787Z","iopub.status.idle":"2023-04-18T13:29:22.949196Z","shell.execute_reply.started":"2023-04-18T13:29:20.872749Z","shell.execute_reply":"2023-04-18T13:29:22.948051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device(\"cuda\")\ndevice","metadata":{"execution":{"iopub.status.busy":"2023-04-18T13:29:25.677887Z","iopub.execute_input":"2023-04-18T13:29:25.678595Z","iopub.status.idle":"2023-04-18T13:29:25.689941Z","shell.execute_reply.started":"2023-04-18T13:29:25.678546Z","shell.execute_reply":"2023-04-18T13:29:25.688711Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class MNISTDataset(Dataset):\n    def __init__(self, is_train:bool=True):\n        self.is_train = is_train\n        if self.is_train:\n            self.data_path = \"/kaggle/input/digit-recognizer/train.csv\"\n        else:\n            self.data_path = \"/kaggle/input/digit-recognizer/test.csv\"\n        self.image = None\n        self.label = None\n        df = pd.read_csv(self.data_path)\n        if self.is_train:\n            self.label = df[\"label\"].to_numpy().reshape(-1, 1)\n            df = df.drop(columns='label')\n        self.image = df.to_numpy().reshape(-1, 1, 28, 28) / 255\n \n    def __len__(self):\n        return len(self.image)\n    \n    def __getitem__(self, index):\n        image = torch.FloatTensor(self.image[index])\n        if self.is_train:\n            label = torch.zeros(10, dtype=torch.float)\n            label[int(self.label[index])] = 1.0\n            return image, label\n        else:\n            return image\n    \ntrain_datasets = MNISTDataset(is_train=True)\ntrain_dataloader = DataLoader(train_datasets, batch_size=100, shuffle=True)\n\ntest_datasets = MNISTDataset(is_train=False)\ntest_dataloader = DataLoader(test_datasets, batch_size=100, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2023-04-18T14:44:46.919765Z","iopub.execute_input":"2023-04-18T14:44:46.920706Z","iopub.status.idle":"2023-04-18T14:44:50.295120Z","shell.execute_reply.started":"2023-04-18T14:44:46.920651Z","shell.execute_reply":"2023-04-18T14:44:50.294040Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class SimpleCNN(nn.Module):\n    def __init__(self):\n        super(SimpleCNN, self).__init__()\n        self.seq1 = nn.Sequential(\n            nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1),\n            nn.ELU(inplace=True),\n            nn.MaxPool2d(kernel_size=2, stride=2)\n        )\n        \n        self.seq2 = nn.Sequential(\n            nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),\n            nn.ELU(inplace=True),\n            nn.MaxPool2d(kernel_size=2, stride=2)\n        )\n        \n        self.seq3 = nn.Sequential(\n            nn.Linear(7*7*64, 32, bias=True),\n            nn.ELU(inplace=True),\n            nn.Linear(32, 10, bias=True),\n            nn.ELU()\n        )\n        \n    def forward(self, x):\n        x = self.seq1(x)\n        x = self.seq2(x)\n        x = x.view(x.size(0), -1)\n        x = self.seq3(x)\n        return x\n    \nmodel = SimpleCNN()\nmodel = model.to(device)\n\ncriterion = nn.CrossEntropyLoss().to(device)\noptimizer = torch.optim.Adam(model.parameters(), lr=0.001)","metadata":{"execution":{"iopub.status.busy":"2023-04-18T14:49:05.503861Z","iopub.execute_input":"2023-04-18T14:49:05.504578Z","iopub.status.idle":"2023-04-18T14:49:05.519218Z","shell.execute_reply.started":"2023-04-18T14:49:05.504537Z","shell.execute_reply":"2023-04-18T14:49:05.518110Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = []\n\nEPOCH = 100\n\nfor epoch in range(EPOCH):\n    loss_tmp = []\n    for i, (image, label) in enumerate(train_dataloader):\n        image, label = image.to(device), label.to(device)\n        y_pred = model(image)\n        loss = criterion(y_pred, label)\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n        loss_tmp.append(loss.item())\n    history.append(np.mean(loss_tmp))\n    print(f\"\\rEPOCH: [{epoch+1}/{EPOCH}], LOSS: {history[-1]:1.6f}\", end=\"\")","metadata":{"execution":{"iopub.status.busy":"2023-04-18T14:49:07.448568Z","iopub.execute_input":"2023-04-18T14:49:07.449262Z","iopub.status.idle":"2023-04-18T14:52:56.560716Z","shell.execute_reply.started":"2023-04-18T14:49:07.449224Z","shell.execute_reply":"2023-04-18T14:52:56.559558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history, label=\"Cross Entropy Loss\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Loss\")\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-04-18T14:54:01.693072Z","iopub.execute_input":"2023-04-18T14:54:01.693788Z","iopub.status.idle":"2023-04-18T14:54:01.896656Z","shell.execute_reply.started":"2023-04-18T14:54:01.693750Z","shell.execute_reply":"2023-04-18T14:54:01.895736Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"result = []\nfor i, image in enumerate(test_dataloader):\n    image = image.to(device)\n    y_pred = model(image)\n    label_pred = torch.argmax(y_pred, dim=1)\n    result.extend(label_pred.cpu().tolist())","metadata":{"execution":{"iopub.status.busy":"2023-04-18T14:57:41.128825Z","iopub.execute_input":"2023-04-18T14:57:41.129839Z","iopub.status.idle":"2023-04-18T14:57:41.707719Z","shell.execute_reply.started":"2023-04-18T14:57:41.129800Z","shell.execute_reply":"2023-04-18T14:57:41.706656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axes = plt.subplots(5, 5, figsize=(10, 10))\n\nfor i in range(5):\n    for j in range(5):\n        idx = 5 * i + j\n        axes[i][j].imshow(test_datasets[idx][0], cmap='gray')\n        axes[i][j].set_title(result[idx])\n        axes[i][j].axis('off')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-04-18T15:00:35.560367Z","iopub.execute_input":"2023-04-18T15:00:35.561468Z","iopub.status.idle":"2023-04-18T15:00:36.310341Z","shell.execute_reply.started":"2023-04-18T15:00:35.561420Z","shell.execute_reply":"2023-04-18T15:00:36.309300Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Sample\nsample = pd.read_csv(\"/kaggle/input/digit-recognizer/sample_submission.csv\")\nsample['Label'] = result\nsample.to_csv('/kaggle/working/submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-04-18T15:10:17.026143Z","iopub.execute_input":"2023-04-18T15:10:17.026913Z","iopub.status.idle":"2023-04-18T15:10:17.081681Z","shell.execute_reply.started":"2023-04-18T15:10:17.026871Z","shell.execute_reply":"2023-04-18T15:10:17.080682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample","metadata":{"execution":{"iopub.status.busy":"2023-04-18T15:10:21.211773Z","iopub.execute_input":"2023-04-18T15:10:21.212780Z","iopub.status.idle":"2023-04-18T15:10:21.224364Z","shell.execute_reply.started":"2023-04-18T15:10:21.212741Z","shell.execute_reply":"2023-04-18T15:10:21.223066Z"},"trusted":true},"execution_count":null,"outputs":[]}]}