{"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":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":30733,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset\nfrom torch.utils.data import DataLoader\nfrom sklearn.utils import shuffle\nfrom sklearn.preprocessing import MinMaxScaler\nfrom sklearn.model_selection import train_test_split\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\ndevice","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-07-11T01:52:40.516043Z","iopub.execute_input":"2024-07-11T01:52:40.516708Z","iopub.status.idle":"2024-07-11T01:52:45.038998Z","shell.execute_reply.started":"2024-07-11T01:52:40.516674Z","shell.execute_reply":"2024-07-11T01:52:45.038014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class MNISTData(Dataset):\n    def __init__(self, X, y):\n        self.X = X\n        self.y = y\n        \n    def __len__(self):\n        return len(self.X)\n    \n    def __getitem__(self, k):\n        return self.X[k], self.y[k]","metadata":{"execution":{"iopub.status.busy":"2024-07-11T01:52:45.040450Z","iopub.execute_input":"2024-07-11T01:52:45.041580Z","iopub.status.idle":"2024-07-11T01:52:45.047232Z","shell.execute_reply.started":"2024-07-11T01:52:45.041549Z","shell.execute_reply":"2024-07-11T01:52:45.046032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def read_data(path, with_y=True):\n    df = pd.read_csv(path)\n    \n    if with_y:\n        y = df.pop(\"label\").to_numpy()\n        y = torch.tensor(y, dtype=torch.long)\n    \n    X = df.to_numpy()\n    scaler = MinMaxScaler()\n    X = scaler.fit_transform(X)\n    X = torch.tensor(X, dtype=torch.float)\n    X = X.view(-1, 1, 28, 28)\n\n    if with_y:\n        return train_test_split(X, y, test_size=0.1, random_state=43, shuffle=True)\n    else:\n        return X","metadata":{"execution":{"iopub.status.busy":"2024-07-11T01:52:45.048635Z","iopub.execute_input":"2024-07-11T01:52:45.049011Z","iopub.status.idle":"2024-07-11T01:52:45.059015Z","shell.execute_reply.started":"2024-07-11T01:52:45.048979Z","shell.execute_reply":"2024-07-11T01:52:45.058109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train, X_test, y_train, y_test = read_data(\"../input/digit-recognizer/train.csv\")\nplt.imshow(X_train[0].cpu().view(28, 28))","metadata":{"execution":{"iopub.status.busy":"2024-07-11T01:52:45.061199Z","iopub.execute_input":"2024-07-11T01:52:45.061463Z","iopub.status.idle":"2024-07-11T01:52:49.673401Z","shell.execute_reply.started":"2024-07-11T01:52:45.061439Z","shell.execute_reply":"2024-07-11T01:52:49.672488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 64\ntrain_data = MNISTData(X_train, y_train)\ntest_data = MNISTData(X_test, y_test)\n\ntrain_loader = DataLoader(train_data, batch_size=batch_size)\ntest_loader = DataLoader(test_data, batch_size=batch_size)","metadata":{"execution":{"iopub.status.busy":"2024-07-11T01:52:49.674565Z","iopub.execute_input":"2024-07-11T01:52:49.674847Z","iopub.status.idle":"2024-07-11T01:52:49.680130Z","shell.execute_reply.started":"2024-07-11T01:52:49.674822Z","shell.execute_reply":"2024-07-11T01:52:49.679146Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CNN(nn.Module):\n    def __init__(self):\n        super(CNN, self).__init__()\n        self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)\n        self.bn1 = nn.BatchNorm2d(32)\n        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)\n        self.bn2 = nn.BatchNorm2d(64)\n        self.conv3 = nn.Conv2d(64, 128, kernel_size=3, padding=1)\n        self.bn3 = nn.BatchNorm2d(128)\n        self.dropout = nn.Dropout(0.5)\n        self.fc1 = nn.Linear(128 * 3 * 3, 256)\n        self.fc2 = nn.Linear(256, 128)\n        self.fc3 = nn.Linear(128, 10)\n\n    def forward(self, x):\n        x = F.relu(F.max_pool2d(self.bn1(self.conv1(x)), 2))\n        x = F.relu(F.max_pool2d(self.bn2(self.conv2(x)), 2))\n        x = F.relu(F.max_pool2d(self.bn3(self.conv3(x)), 2))\n        x = x.view(-1, 128 * 3 * 3)\n        x = self.dropout(F.relu(self.fc1(x)))\n        x = F.relu(self.fc2(x))\n        x = self.fc3(x)\n        return F.log_softmax(x, dim=1)","metadata":{"execution":{"iopub.status.busy":"2024-07-11T01:52:49.681268Z","iopub.execute_input":"2024-07-11T01:52:49.681548Z","iopub.status.idle":"2024-07-11T01:52:49.692044Z","shell.execute_reply.started":"2024-07-11T01:52:49.681514Z","shell.execute_reply":"2024-07-11T01:52:49.691220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = CNN().to(device)\ncriterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=0.01)","metadata":{"execution":{"iopub.status.busy":"2024-07-11T01:53:20.415199Z","iopub.execute_input":"2024-07-11T01:53:20.415911Z","iopub.status.idle":"2024-07-11T01:53:20.428653Z","shell.execute_reply.started":"2024-07-11T01:53:20.415882Z","shell.execute_reply":"2024-07-11T01:53:20.427876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for epoch in range(25):\n    for inputs, labels in train_loader:\n        inputs, labels = inputs.to(device), labels.to(device)\n        optimizer.zero_grad()\n        output = model(inputs)\n        loss = criterion(output, labels)\n        loss.backward()\n        optimizer.step()\n    print(f\"Epoch: {epoch}, Loss: {loss.item()}\")","metadata":{"execution":{"iopub.status.busy":"2024-07-11T01:53:21.555101Z","iopub.execute_input":"2024-07-11T01:53:21.555688Z","iopub.status.idle":"2024-07-11T01:54:04.380986Z","shell.execute_reply.started":"2024-07-11T01:53:21.555660Z","shell.execute_reply":"2024-07-11T01:54:04.379567Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()\nwith torch.no_grad():\n    y_hat = model(X_test.to(device))\n    error = criterion(y_hat.to(device), y_test.to(device))\nerror.item()","metadata":{"execution":{"iopub.status.busy":"2024-07-11T01:54:38.121970Z","iopub.execute_input":"2024-07-11T01:54:38.122823Z","iopub.status.idle":"2024-07-11T01:54:38.159145Z","shell.execute_reply.started":"2024-07-11T01:54:38.122791Z","shell.execute_reply":"2024-07-11T01:54:38.158237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.argmax(y_hat, dim=1)","metadata":{"execution":{"iopub.status.busy":"2024-07-11T01:54:40.767951Z","iopub.execute_input":"2024-07-11T01:54:40.768814Z","iopub.status.idle":"2024-07-11T01:54:40.801808Z","shell.execute_reply.started":"2024-07-11T01:54:40.768777Z","shell.execute_reply":"2024-07-11T01:54:40.801052Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_test","metadata":{"execution":{"iopub.status.busy":"2024-07-11T01:54:42.586363Z","iopub.execute_input":"2024-07-11T01:54:42.586769Z","iopub.status.idle":"2024-07-11T01:54:42.593513Z","shell.execute_reply.started":"2024-07-11T01:54:42.586741Z","shell.execute_reply":"2024-07-11T01:54:42.592540Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def score(y_true, y_pred):\n    return torch.sum(y_true.to(device) == y_pred.to(device)).item() / len(y_true)\n\nscore(y_test, torch.argmax(y_hat, dim=1))","metadata":{"execution":{"iopub.status.busy":"2024-07-11T01:55:02.145457Z","iopub.execute_input":"2024-07-11T01:55:02.146263Z","iopub.status.idle":"2024-07-11T01:55:02.178182Z","shell.execute_reply.started":"2024-07-11T01:55:02.146230Z","shell.execute_reply":"2024-07-11T01:55:02.177312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_sub = read_data(\"../input/digit-recognizer/test.csv\", with_y=False)\nmodel.eval()\nwith torch.no_grad():\n    y_sub = model(X_sub.to(device))\ny_sub = torch.argmax(y_sub, dim=1).cpu().numpy()\n\nimage_id = range(1, len(y_sub) + 1)\ndf_sub = pd.DataFrame({\"ImageId\": image_id, \"Label\": y_sub})\ndf_sub.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2024-07-11T01:55:29.778396Z","iopub.execute_input":"2024-07-11T01:55:29.779250Z","iopub.status.idle":"2024-07-11T01:55:31.949996Z","shell.execute_reply.started":"2024-07-11T01:55:29.779218Z","shell.execute_reply":"2024-07-11T01:55:31.949001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}