{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","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":30761,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torchvision\nimport torchvision.transforms as transforms\nfrom torch.utils.data import DataLoader, Dataset\nimport matplotlib.pyplot as plt\nimport seaborn as sns \nimport numpy as np\nimport pandas as pd","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:35.135233Z","iopub.execute_input":"2024-10-20T07:31:35.135725Z","iopub.status.idle":"2024-10-20T07:31:39.530542Z","shell.execute_reply.started":"2024-10-20T07:31:35.135681Z","shell.execute_reply":"2024-10-20T07:31:39.529268Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:39.532338Z","iopub.execute_input":"2024-10-20T07:31:39.532815Z","iopub.status.idle":"2024-10-20T07:31:39.538504Z","shell.execute_reply.started":"2024-10-20T07:31:39.532779Z","shell.execute_reply":"2024-10-20T07:31:39.537262Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(device)","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:39.539822Z","iopub.execute_input":"2024-10-20T07:31:39.540649Z","iopub.status.idle":"2024-10-20T07:31:39.557083Z","shell.execute_reply.started":"2024-10-20T07:31:39.540606Z","shell.execute_reply":"2024-10-20T07:31:39.555809Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CustomMNISTDataset(Dataset):\n    def __init__(self, csv_file,transform=None, is_test=False):\n        self.data_frame=pd.read_csv(csv_file)\n        self.transform=transform\n        self.is_test= is_test\n\n    def __len__(self):\n        return len(self.data_frame)\n\n    def __getitem__(self, index):\n        item = self.data_frame.iloc[index]\n\n        if self.is_test:\n            image = item.values.reshape(28, 28).astype(np.uint8)\n            label = None \n        else:\n            image = item[1 :].values.reshape(28, 28).astype(np.uint8)\n            label = item.iloc[0]\n      \n        image= transforms.ToPILImage()(image)\n\n        if self.transform is not None:\n            image = self.transform(image)\n\n        if self.is_test:\n            return image\n        else:\n            return image, label","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:39.558551Z","iopub.execute_input":"2024-10-20T07:31:39.559353Z","iopub.status.idle":"2024-10-20T07:31:39.570858Z","shell.execute_reply.started":"2024-10-20T07:31:39.559298Z","shell.execute_reply":"2024-10-20T07:31:39.569651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.RandomRotation(15),\n    transforms.ToTensor(),\n    transforms.Normalize((0.5,), (0.5,))\n])","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:39.574089Z","iopub.execute_input":"2024-10-20T07:31:39.574561Z","iopub.status.idle":"2024-10-20T07:31:39.584715Z","shell.execute_reply.started":"2024-10-20T07:31:39.574510Z","shell.execute_reply":"2024-10-20T07:31:39.583633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = CustomMNISTDataset(csv_file='/kaggle/input/digit-recognizer/train.csv' , transform=transform, is_test= False)\ntest_dataset = CustomMNISTDataset(csv_file='/kaggle/input/digit-recognizer/test.csv' , transform=transform, is_test= True)","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:39.586373Z","iopub.execute_input":"2024-10-20T07:31:39.586745Z","iopub.status.idle":"2024-10-20T07:31:45.097131Z","shell.execute_reply.started":"2024-10-20T07:31:39.586686Z","shell.execute_reply":"2024-10-20T07:31:45.095920Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Kiểm tra kích thước của các DataFrame huấn luyện và kiểm tra\nprint('Train Size: ' + str(len(train_dataset)) + ', Test Size: ' + str(len(test_dataset)))","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:45.098593Z","iopub.execute_input":"2024-10-20T07:31:45.099092Z","iopub.status.idle":"2024-10-20T07:31:45.105071Z","shell.execute_reply.started":"2024-10-20T07:31:45.099023Z","shell.execute_reply":"2024-10-20T07:31:45.104007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset[1]","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:45.106551Z","iopub.execute_input":"2024-10-20T07:31:45.106909Z","iopub.status.idle":"2024-10-20T07:31:45.263608Z","shell.execute_reply.started":"2024-10-20T07:31:45.106872Z","shell.execute_reply":"2024-10-20T07:31:45.262530Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load the training and test datasets\ntrain_df = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')\ntest_df = pd.read_csv('/kaggle/input/digit-recognizer/test.csv')\ndata = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:45.264793Z","iopub.execute_input":"2024-10-20T07:31:45.265133Z","iopub.status.idle":"2024-10-20T07:31:51.654250Z","shell.execute_reply.started":"2024-10-20T07:31:45.265098Z","shell.execute_reply":"2024-10-20T07:31:51.653229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Kiểm tra dữ liêu**","metadata":{}},{"cell_type":"code","source":"print(data.info())","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:51.655465Z","iopub.execute_input":"2024-10-20T07:31:51.655782Z","iopub.status.idle":"2024-10-20T07:31:51.717758Z","shell.execute_reply.started":"2024-10-20T07:31:51.655749Z","shell.execute_reply":"2024-10-20T07:31:51.716697Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Mô tả dữ liệu**","metadata":{}},{"cell_type":"markdown","source":"Hiển thị 5 dòng đầu tiên của DataFrame","metadata":{}},{"cell_type":"code","source":"print(data.head())","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:51.718988Z","iopub.execute_input":"2024-10-20T07:31:51.719346Z","iopub.status.idle":"2024-10-20T07:31:51.742979Z","shell.execute_reply.started":"2024-10-20T07:31:51.719309Z","shell.execute_reply":"2024-10-20T07:31:51.731853Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"description = data.describe()\nprint(description)","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:51.744861Z","iopub.execute_input":"2024-10-20T07:31:51.745798Z","iopub.status.idle":"2024-10-20T07:31:53.911425Z","shell.execute_reply.started":"2024-10-20T07:31:51.745755Z","shell.execute_reply":"2024-10-20T07:31:53.910280Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Kiểm tra giá trị rỗng**","metadata":{}},{"cell_type":"code","source":"# Check for missing values in the training dataset\nnum_missing_train = train_df.isnull().sum().sum()\nprint(f\"Number of missing values in training dataset: {num_missing_train}\")\n\n# Check for missing values in the test dataset\nnum_missing_test = test_df.isnull().sum().sum()\nprint(f\"Number of missing values in test dataset: {num_missing_test}\")","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:53.912826Z","iopub.execute_input":"2024-10-20T07:31:53.913224Z","iopub.status.idle":"2024-10-20T07:31:53.967622Z","shell.execute_reply.started":"2024-10-20T07:31:53.913175Z","shell.execute_reply":"2024-10-20T07:31:53.966464Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Tạo các DataLoader**","metadata":{}},{"cell_type":"code","source":"batch_size = 64\ntrain_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True, num_workers=2)\ntest_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False, num_workers=2)","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:53.971373Z","iopub.execute_input":"2024-10-20T07:31:53.971787Z","iopub.status.idle":"2024-10-20T07:31:53.978117Z","shell.execute_reply.started":"2024-10-20T07:31:53.971746Z","shell.execute_reply":"2024-10-20T07:31:53.976724Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train = train_df.drop(columns=['label']).values\ny_train = train_df['label'].values","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:53.979480Z","iopub.execute_input":"2024-10-20T07:31:53.979930Z","iopub.status.idle":"2024-10-20T07:31:54.075158Z","shell.execute_reply.started":"2024-10-20T07:31:53.979878Z","shell.execute_reply":"2024-10-20T07:31:54.073914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Hãy kiểm tra xem nhãn (target) có được cân bằng không.\n# Điều này có nghĩa là mười danh mục trong nhãn\n# Được đại diện gần như bằng nhau trong dữ liệu\n\nax = sns.countplot(x=y_train, color='#4895EE')\nax.set(\n    title='Target distribution is balanced? Yes!',\n    xlabel='Label'\n)\n# Số lượng mẫu dự kiến cho một phân phối lớp cân bằng là 42000/10 = 4200\n\n_ = ax.axhline(y=4200, color='#12086F', linestyle='--')\n\n# Vì các lớp mục tiêu được cân bằng, chúng ta không cần lo lắng về các phương pháp lấy mẫu và sai lệch trong mô hình của chúng ta.","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:54.076461Z","iopub.execute_input":"2024-10-20T07:31:54.076814Z","iopub.status.idle":"2024-10-20T07:31:54.412703Z","shell.execute_reply.started":"2024-10-20T07:31:54.076776Z","shell.execute_reply":"2024-10-20T07:31:54.411554Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Hình dung sự phân bố của các giá trị pixel\nax = sns.histplot(x=X_train.flatten(), color='#4895EE')\n_ = ax.set(title='Pixel Value Histogram', xlabel='Pixel Value')\n\n# Kết quả sau khi hiển thị 5 dòng đầu tiên của DataFrame, chúng ta có thể thấy, giá trị 0 đại diện cho nền (background)\n# và các giá trị >0 đại diện cho các chữ số trong hình ảnh","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:31:54.414328Z","iopub.execute_input":"2024-10-20T07:31:54.414887Z","iopub.status.idle":"2024-10-20T07:32:05.093315Z","shell.execute_reply.started":"2024-10-20T07:31:54.414833Z","shell.execute_reply":"2024-10-20T07:32:05.092157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Kiểm tra xem nhãn (target) có được cân bằng không.\n# Điều này có nghĩa là mười danh mục trong nhãn\n# Được đại diện gần như bằng nhau trong dữ liệu\n\nax = sns.countplot(x=y_train, color='#4895EE')\nax.set(\n    title='Target distribution is balanced? Yes!',\n    xlabel='Label'\n)\n# Số lượng mẫu dự kiến cho một phân phối lớp cân bằng là 42000/10 = 4200\n\n_ = ax.axhline(y=4200, color='#12086F', linestyle='--')\n\n# Vì các lớp mục tiêu được cân bằng, chúng ta không cần lo lắng về các phương pháp lấy mẫu và sai lệch trong mô hình của chúng ta.","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:32:05.094786Z","iopub.execute_input":"2024-10-20T07:32:05.095266Z","iopub.status.idle":"2024-10-20T07:32:05.512921Z","shell.execute_reply.started":"2024-10-20T07:32:05.095222Z","shell.execute_reply":"2024-10-20T07:32:05.511747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Tiếp theo,chúng ta trực quan hóa một hình ảnh từ mỗi lớp.\n# Chúng ta sẽ sử dụng hàm 'imshow' của thư viện matplotlib.\n\nfig, axs = plt.subplots(nrows=2, ncols=5, figsize=(10,5))\n\nfor i in range(10):\n    idx = np.where(y_train==i)[0][2]\n    img = axs[int(i >= 5), i%5].imshow(\n        X=X_train[idx].reshape(28, 28),\n        cmap='Blues'\n    )\n    img.axes.get_yaxis().set_visible(False)\n    img.axes.get_xaxis().set_visible(False)\n    img.axes.set_title(f'Label: {i}')","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:32:05.514476Z","iopub.execute_input":"2024-10-20T07:32:05.514904Z","iopub.status.idle":"2024-10-20T07:32:05.981333Z","shell.execute_reply.started":"2024-10-20T07:32:05.514864Z","shell.execute_reply":"2024-10-20T07:32:05.979806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for example_data, example_labels in train_loader:\n    example_image = example_data[0]\n    print(\"Input Size:\", example_data.size())\n\n    example_image_numpy = example_image.permute(1, 2, 0).numpy()\n\n    plt.imshow(example_image_numpy)\n    plt.title(f\"Lable: {example_labels[0]}\")\n    plt.show()\n\n    break","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:32:05.982839Z","iopub.execute_input":"2024-10-20T07:32:05.983230Z","iopub.status.idle":"2024-10-20T07:32:06.440226Z","shell.execute_reply.started":"2024-10-20T07:32:05.983192Z","shell.execute_reply":"2024-10-20T07:32:06.438911Z"},"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.conv1 = nn.Conv2d(in_channels = 1, out_channels=32, kernel_size =3, stride = 1, padding = 1)\n        self.relu = nn.ReLU()\n        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.conv2 = nn.Conv2d(in_channels = 32, out_channels=64, kernel_size =3, stride = 1, padding = 1)\n        self.conv3 = nn.Conv2d(in_channels = 64, out_channels=128, kernel_size =3, stride = 1, padding = 1)\n        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)\n\n        #((Width-kernel_size + 2 * Padding ) / Stride) + 1\n        #(28-3+2*1)/1+1, (28-3+2*1)/1+1(28-3+2*1)/1+1 = 14\n\n        self.fc1 = nn.Linear(128 * 7 * 7, 128)\n        self.dropout = nn.Dropout(0.5)\n        self.fc2 = nn.Linear(128, 20)\n        self.fc3 = nn.Linear(20, 10)\n\n    def forward(self, x):\n\n        x = self.conv1(x)\n        x = self.relu(x)\n        x = self.pool(x)\n        x = self.conv2(x)\n        x = self.relu(x)\n        x = self.conv3(x)\n        x = self.pool(x)\n\n        x_size = x.size(1) * x.size(2) * x.size(3)\n\n        x = x.view(-1, x_size)\n        x = self.fc1(x)\n        x = self.relu(x)\n        x = self.fc2(x)\n        x = self.fc3(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:32:06.441854Z","iopub.execute_input":"2024-10-20T07:32:06.442257Z","iopub.status.idle":"2024-10-20T07:32:06.453691Z","shell.execute_reply.started":"2024-10-20T07:32:06.442215Z","shell.execute_reply":"2024-10-20T07:32:06.452578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = SimpleCNN().to(device)\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:32:06.455338Z","iopub.execute_input":"2024-10-20T07:32:06.455795Z","iopub.status.idle":"2024-10-20T07:32:06.490665Z","shell.execute_reply.started":"2024-10-20T07:32:06.455750Z","shell.execute_reply":"2024-10-20T07:32:06.489621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_epochs = 100\nrunning_loss = 0.0\n\nfor epoch in range(num_epochs):\n    for i, data in enumerate(train_loader, 0):\n        inputs, labels = data\n        inputs, labels = inputs.to(device), labels.to(device)\n\n        optimizer.zero_grad()\n\n        outputs = model(inputs.float())\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item()\n\n        if i % 100 == 99:\n            print(f\"[{epoch + 1}, {i + 1}] Loss: {running_loss / 100:.3f}\")\n            running_loss = 0.0\nprint(\"Training finished\")","metadata":{"execution":{"iopub.status.busy":"2024-10-20T07:32:06.491935Z","iopub.execute_input":"2024-10-20T07:32:06.492325Z","iopub.status.idle":"2024-10-20T09:31:10.504877Z","shell.execute_reply.started":"2024-10-20T07:32:06.492286Z","shell.execute_reply":"2024-10-20T09:31:10.502402Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()\npredictions = []\n\nwith torch.no_grad():\n    for data in test_loader:\n        data = data.to(device)\n        \n        outputs = model(data)\n        _,predicted = torch.max(outputs.data, 1)\n        predictions.extend(predicted.cpu().tolist())\n\nsubmission = pd.DataFrame({\n    \"ImageId\": range(1, len(predictions) + 1),\n    \"Label\": predictions \n})\nsubmission.to_csv('predictiongroup4.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-10-20T09:31:10.507777Z","iopub.execute_input":"2024-10-20T09:31:10.508263Z","iopub.status.idle":"2024-10-20T09:31:34.224829Z","shell.execute_reply.started":"2024-10-20T09:31:10.508211Z","shell.execute_reply":"2024-10-20T09:31:34.223346Z"},"trusted":true},"execution_count":null,"outputs":[]}]}