{"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":"none","dataSources":[{"sourceId":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":30587,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport pandas as pd\nfrom torch.utils.data import DataLoader, TensorDataset, random_split\n\ndata = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')\nX = torch.tensor(data.drop('label', axis=1).values, dtype=torch.float32) / 255.0\ny = torch.tensor(data['label'].values, dtype=torch.long)\n\ndataset = TensorDataset(X, y)\ntrain_size = int(0.8 * len(dataset))\nval_size = len(dataset) - train_size\ntrain_dataset, val_dataset = random_split(dataset, [train_size, val_size])\n\ntrain_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=64, shuffle=False)\n\nclass MLP(nn.Module):\n    def __init__(self):\n        super(MLP, self).__init__()\n        self.network = nn.Sequential(\n            nn.Linear(784, 512),\n            nn.ReLU(),\n            nn.Linear(512, 256),\n            nn.ReLU(),\n            nn.Linear(256, 10)\n        )\n\n    def forward(self, x):\n        return self.network(x)\n\nmodel = MLP()\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)\n\nepochs = 10\n\nfor epoch in range(epochs):\n    model.train()\n    train_loss = 0.0\n    correct_train = 0\n    total_train = 0\n    \n    for images, labels in train_loader:\n        outputs = model(images)\n        loss = criterion(outputs, labels)\n        \n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n        \n        train_loss += loss.item()\n        _, predicted = torch.max(outputs.data, 1)\n        total_train += labels.size(0)\n        correct_train += (predicted == labels).sum().item()\n    \n    model.eval()\n    val_loss = 0.0\n    correct_val = 0\n    total_val = 0\n    \n    with torch.no_grad():\n        for images, labels in val_loader:\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            val_loss += loss.item()\n            _, predicted = torch.max(outputs.data, 1)\n            total_val += labels.size(0)\n            correct_val += (predicted == labels).sum().item()\n            \n    print(f\"Epoch [{epoch+1}/{epochs}]\")\n    print(f\"  Train Loss: {train_loss/len(train_loader):.4f} | Train Acc: {100 * correct_train/total_train:.2f}%\")\n    print(f\"  Val Loss:   {val_loss/len(val_loader):.4f} | Val Acc:   {100 * correct_val/total_val:.2f}%\")\n    print(\"-\" * 30)\n\nprint(\"Training Finished.\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-02-15T09:57:27.010207Z","iopub.execute_input":"2026-02-15T09:57:27.010884Z","iopub.status.idle":"2026-02-15T09:58:08.083314Z","shell.execute_reply.started":"2026-02-15T09:57:27.010853Z","shell.execute_reply":"2026-02-15T09:58:08.081265Z"}},"outputs":[],"execution_count":null}]}