{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"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":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":30918,"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\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:20:07.816666Z","iopub.execute_input":"2025-03-18T12:20:07.817085Z","iopub.status.idle":"2025-03-18T12:20:08.171544Z","shell.execute_reply.started":"2025-03-18T12:20:07.817044Z","shell.execute_reply":"2025-03-18T12:20:08.170592Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader\nfrom torchvision import datasets, transforms\nimport matplotlib.pyplot as plt\nfrom torch.utils.data import DataLoader, TensorDataset\nfrom sklearn.model_selection import train_test_split\nfrom tqdm.auto import tqdm","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:20:08.172854Z","iopub.execute_input":"2025-03-18T12:20:08.173384Z","iopub.status.idle":"2025-03-18T12:20:13.245924Z","shell.execute_reply.started":"2025-03-18T12:20:08.173348Z","shell.execute_reply":"2025-03-18T12:20:13.244991Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = 'cuda' if torch.cuda.is_available() else 'cpu'\ndevice","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:20:13.247761Z","iopub.execute_input":"2025-03-18T12:20:13.248276Z","iopub.status.idle":"2025-03-18T12:20:13.335099Z","shell.execute_reply.started":"2025-03-18T12:20:13.248242Z","shell.execute_reply":"2025-03-18T12:20:13.334354Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')\n\ndata.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:20:13.336499Z","iopub.execute_input":"2025-03-18T12:20:13.336823Z","iopub.status.idle":"2025-03-18T12:20:16.029304Z","shell.execute_reply.started":"2025-03-18T12:20:13.336790Z","shell.execute_reply":"2025-03-18T12:20:16.028497Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from collections import Counter\n\nCounter(data.iloc[:, 0])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:20:16.030278Z","iopub.execute_input":"2025-03-18T12:20:16.030615Z","iopub.status.idle":"2025-03-18T12:20:16.041551Z","shell.execute_reply.started":"2025-03-18T12:20:16.030581Z","shell.execute_reply":"2025-03-18T12:20:16.040794Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_data_path = '/kaggle/input/digit-recognizer/test.csv'\ntest_data = pd.read_csv(test_data_path)\n\ntest_data.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:20:16.042358Z","iopub.execute_input":"2025-03-18T12:20:16.042689Z","iopub.status.idle":"2025-03-18T12:20:17.570305Z","shell.execute_reply.started":"2025-03-18T12:20:16.042654Z","shell.execute_reply":"2025-03-18T12:20:17.569395Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.imshow(np.array(data.iloc[1, 1:].values).reshape((28, 28)), cmap='gray')\nplt.axis('off')\nplt.title(data.iloc[1, 0])\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:20:17.571274Z","iopub.execute_input":"2025-03-18T12:20:17.571593Z","iopub.status.idle":"2025-03-18T12:20:17.739932Z","shell.execute_reply.started":"2025-03-18T12:20:17.571560Z","shell.execute_reply":"2025-03-18T12:20:17.739016Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X = data.iloc[:, 1:].values.reshape(-1, 28, 28).astype('float32') / 255.0\ny = data.iloc[:, 0].values.astype('int64')\n\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=42)\n\nX_train_tensor = torch.tensor(X_train).unsqueeze(1).to(device)\nX_test_tensor = torch.tensor(X_test).unsqueeze(1).to(device)\ny_train_tensor = torch.tensor(y_train).to(device)\ny_test_tensor = torch.tensor(y_test).to(device)\n\ntrain_dataset = TensorDataset(X_train_tensor, y_train_tensor)\ntest_dataset = TensorDataset(X_test_tensor, y_test_tensor)\n\ntrain_val_transforms = transforms.Compose([\n    transforms.Resize((28, 28)),\n    transforms.ToTensor()\n])\n\ntest_transforms = transforms.Compose([\n    transforms.Resize((28, 28)),\n    transforms.ToTensor()\n])\n\ntrain_dataloader = DataLoader(train_dataset, batch_size=64, shuffle=True)\ntest_dataloader = DataLoader(test_dataset, batch_size=64, shuffle=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:20:17.742159Z","iopub.execute_input":"2025-03-18T12:20:17.742420Z","iopub.status.idle":"2025-03-18T12:20:18.471230Z","shell.execute_reply.started":"2025-03-18T12:20:17.742399Z","shell.execute_reply":"2025-03-18T12:20:18.470020Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class ModelTorchMnist(nn.Module):\n    def __init__(self):\n        super().__init__()\n        \n        self.conv_block = nn.Sequential(\n            nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1),\n            nn.BatchNorm2d(32),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),\n            nn.BatchNorm2d(64),\n            nn.ReLU(inplace=True),\n            nn.MaxPool2d(kernel_size=2, stride=2),\n            nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),\n            nn.BatchNorm2d(128),\n            nn.ReLU(inplace=True),\n            nn.MaxPool2d(kernel_size=2, stride=2) \n        )\n        \n        self.linear_block = nn.Sequential(\n            nn.Dropout(p=0.5),\n            nn.Linear(128*7*7, 256),\n            nn.BatchNorm1d(256),\n            nn.ReLU(inplace=True),\n            nn.Dropout(0.5),\n            nn.Linear(256, 64),\n            nn.BatchNorm1d(64),\n            nn.ReLU(inplace=True),\n            nn.Dropout(0.5),\n            nn.Linear(64, 10)\n        )\n\n    def forward(self, x):\n        x = self.conv_block(x)\n        x = x.view(x.size(0), -1)\n        x = self.linear_block(x)\n        return x","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:24:59.784396Z","iopub.execute_input":"2025-03-18T12:24:59.784737Z","iopub.status.idle":"2025-03-18T12:24:59.792070Z","shell.execute_reply.started":"2025-03-18T12:24:59.784710Z","shell.execute_reply":"2025-03-18T12:24:59.791283Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_torch_mnist = ModelTorchMnist().to(device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:25:00.145386Z","iopub.execute_input":"2025-03-18T12:25:00.145728Z","iopub.status.idle":"2025-03-18T12:25:00.172687Z","shell.execute_reply.started":"2025-03-18T12:25:00.145702Z","shell.execute_reply":"2025-03-18T12:25:00.172048Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"NUM_EPOCHS = 15\n\nloss_fn = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(params=model_torch_mnist.parameters(), lr=0.001)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:25:00.487619Z","iopub.execute_input":"2025-03-18T12:25:00.487882Z","iopub.status.idle":"2025-03-18T12:25:00.492428Z","shell.execute_reply.started":"2025-03-18T12:25:00.487861Z","shell.execute_reply":"2025-03-18T12:25:00.491680Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_losses = []\ntrain_accuracies = []\ntest_losses = []\ntest_accuracies = []\n\nfor epoch in tqdm(range(NUM_EPOCHS)):\n  model_torch_mnist.train()\n\n  train_loss, train_acc = 0, 0\n\n  for batch, (X, y) in enumerate(train_dataloader):\n    X, y = X.to(device), y.to(device)\n\n    y_pred = model_torch_mnist(X)\n\n    loss = loss_fn(y_pred, y)\n    train_loss += loss.item()\n\n\n    optimizer.zero_grad()\n\n    loss.backward()\n\n    optimizer.step()\n\n    y_pred_class = torch.argmax(torch.softmax(y_pred, dim=1), dim=1)\n    train_acc += (y_pred_class == y).sum().item() / len(y_pred)\n\n  # Тест\n\n  model_torch_mnist.eval()\n\n  test_loss, test_acc = 0, 0\n\n  with torch.inference_mode():\n    for batch, (X, y) in enumerate(test_dataloader):\n      X, y = X.to(device), y.to(device)\n\n      test_pred_logits = model_torch_mnist(X)\n\n      loss = loss_fn(test_pred_logits, y)\n      test_loss += loss.item()\n\n      test_pred_labels = test_pred_logits.argmax(dim=1)\n      test_acc += ((test_pred_labels == y).sum().item() / len(test_pred_labels))\n\n  train_loss = train_loss / len(train_dataloader)\n  train_acc = train_acc / len(train_dataloader)\n\n  test_loss = test_loss / len(test_dataloader)\n  test_acc = test_acc / len(test_dataloader)\n\n  train_losses.append(train_loss)\n  train_accuracies.append(train_acc)\n  test_losses.append(test_loss)\n  test_accuracies.append(test_acc)\n\n  print(\n      f\"Epoch: {epoch + 1} | \"\n      f\"train_loss: {train_loss:.4f} | \"\n      f\"train_acc: {train_acc:.4f} | \"\n      f\"test_loss: {test_loss:.4f} | \"\n      f\"test_acc: {test_acc:.4f}\"\n  )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:25:00.773227Z","iopub.execute_input":"2025-03-18T12:25:00.773513Z","iopub.status.idle":"2025-03-18T12:26:14.231064Z","shell.execute_reply.started":"2025-03-18T12:25:00.773478Z","shell.execute_reply":"2025-03-18T12:26:14.229980Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"epochs = range(1, NUM_EPOCHS + 1)\n\nplt.figure(figsize=(14, 6))\n\nplt.subplot(1, 2, 1)\nplt.plot(epochs, train_losses, label='Train Loss')\nplt.plot(epochs, test_losses, label='Test Loss')\nplt.title('Loss Over Epochs')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\n\nplt.subplot(1, 2, 2)\nplt.plot(epochs, train_accuracies, label='Train Accuracy')\nplt.plot(epochs, test_accuracies, label='Test Accuracy')\nplt.title('Accuracy Over Epochs')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:26:16.329090Z","iopub.execute_input":"2025-03-18T12:26:16.329404Z","iopub.status.idle":"2025-03-18T12:26:16.802080Z","shell.execute_reply.started":"2025-03-18T12:26:16.329382Z","shell.execute_reply":"2025-03-18T12:26:16.801130Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train_tensor[0].shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:26:20.587662Z","iopub.execute_input":"2025-03-18T12:26:20.587953Z","iopub.status.idle":"2025-03-18T12:26:20.593405Z","shell.execute_reply.started":"2025-03-18T12:26:20.587931Z","shell.execute_reply":"2025-03-18T12:26:20.592671Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_test = test_data.values.astype('float32') / 255.0\nX_test_tensor = torch.tensor(X_test).unsqueeze(1).to(device)\n\n\nmodel_torch_mnist.eval()\npredictions = []\n\nwith torch.inference_mode():\n    for X_batch in X_test_tensor:\n        X_batch = X_batch.reshape(1, 1, 28, 28)\n        test_pred_logits = model_torch_mnist(X_batch.to(device))\n        test_pred_labels = torch.argmax(test_pred_logits, dim=1)\n        predictions.extend(test_pred_labels.cpu().numpy())\n\nsubmission = pd.DataFrame({'ImageId': list(range(1, len(predictions) + 1)), 'Label': predictions})\nsubmission_path = '/kaggle/working/submission.csv'\nsubmission.to_csv(submission_path, index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:26:20.747139Z","iopub.execute_input":"2025-03-18T12:26:20.747405Z","iopub.status.idle":"2025-03-18T12:26:44.255353Z","shell.execute_reply.started":"2025-03-18T12:26:20.747384Z","shell.execute_reply":"2025-03-18T12:26:44.254613Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"size = len(predictions) - 1\nplt.figure(figsize=(16, 8))\n\nfor i in range(5):\n    plt.subplot(1, 5,  i + 1)\n    # idx = np.random.randint(0, size)\n    image_class = predictions[i]\n    img = test_data.iloc[i, :].values.reshape((28, 28))\n    plt.imshow(img, cmap='bone')\n    plt.title(image_class)\n    plt.axis('off')\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:26:44.256615Z","iopub.execute_input":"2025-03-18T12:26:44.256925Z","iopub.status.idle":"2025-03-18T12:26:44.582932Z","shell.execute_reply.started":"2025-03-18T12:26:44.256894Z","shell.execute_reply":"2025-03-18T12:26:44.582139Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submit = pd.read_csv('/kaggle/input/digit-recognizer/sample_submission.csv')\n\nsubmit.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:26:44.584768Z","iopub.execute_input":"2025-03-18T12:26:44.585022Z","iopub.status.idle":"2025-03-18T12:26:44.598535Z","shell.execute_reply.started":"2025-03-18T12:26:44.585003Z","shell.execute_reply":"2025-03-18T12:26:44.597781Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sub = pd.read_csv('/kaggle/working/submission.csv')\nsub.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:26:44.599521Z","iopub.execute_input":"2025-03-18T12:26:44.599800Z","iopub.status.idle":"2025-03-18T12:26:44.611318Z","shell.execute_reply.started":"2025-03-18T12:26:44.599778Z","shell.execute_reply":"2025-03-18T12:26:44.610636Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submit.shape, sub.shape, test_data.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T12:26:44.612034Z","iopub.execute_input":"2025-03-18T12:26:44.612328Z","iopub.status.idle":"2025-03-18T12:26:44.617108Z","shell.execute_reply.started":"2025-03-18T12:26:44.612305Z","shell.execute_reply":"2025-03-18T12:26:44.616446Z"}},"outputs":[],"execution_count":null}]}