{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceType":"competition","sourceId":3649,"databundleVersionId":46718}],"dockerImageVersionId":31329,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport pandas as pd\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nfrom PIL import Image","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-05-15T08:43:22.387071Z","iopub.execute_input":"2026-05-15T08:43:22.387698Z","iopub.status.idle":"2026-05-15T08:43:22.391866Z","shell.execute_reply.started":"2026-05-15T08:43:22.387666Z","shell.execute_reply":"2026-05-15T08:43:22.391163Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if not os.path.exists('./train'):\n    !7z x /kaggle/input/competitions/cifar-10/train.7z -o./ > /dev/null\n    print(\"Giải nén hoàn tất!\")\n\ndf_train = pd.read_csv('/kaggle/input/competitions/cifar-10/trainLabels.csv')\ndf_train['id'] = df_train['id'].astype(str) + '.png'\n\nclasses = ('airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')\nlabel_to_int = {name: i for i, name in enumerate(classes)}\ndf_train['label'] = df_train['label'].map(label_to_int)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-15T08:43:22.395427Z","iopub.execute_input":"2026-05-15T08:43:22.395941Z","iopub.status.idle":"2026-05-15T08:43:22.454095Z","shell.execute_reply.started":"2026-05-15T08:43:22.395915Z","shell.execute_reply":"2026-05-15T08:43:22.453496Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class SimpleCNN(nn.Module):\n    def __init__(self):\n        super(SimpleCNN, self).__init__()\n        self.features = nn.Sequential(\n            nn.Conv2d(3,32,kernel_size = 3,padding = 1),\n            nn.ReLU(),\n            nn.BatchNorm2d(32),\n            nn.MaxPool2d(2,2),\n\n            nn.Conv2d(32,64,kernel_size = 3,padding = 1),\n            nn.ReLU(),\n            nn.BatchNorm2d(64),\n            nn.MaxPool2d(2,2),\n\n            nn.Conv2d(64,128,kernel_size = 3,padding = 1),\n            nn.ReLU(),\n            nn.BatchNorm2d(128),\n            nn.MaxPool2d(2,2),\n            \n        )\n        self.classifier = nn.Sequential(\n            nn.Flatten(),\n            nn.Linear(128*4*4,512),\n            nn.ReLU(),\n            nn.Dropout(0.3),\n            nn.Linear(512,10)\n        )\n\n    def forward(self, x):\n        x = self.features(x)\n        x = self.classifier(x)\n        return x","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-15T08:43:22.455592Z","iopub.execute_input":"2026-05-15T08:43:22.456204Z","iopub.status.idle":"2026-05-15T08:43:22.462168Z","shell.execute_reply.started":"2026-05-15T08:43:22.456179Z","shell.execute_reply":"2026-05-15T08:43:22.461419Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))\n])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-15T08:43:22.463058Z","iopub.execute_input":"2026-05-15T08:43:22.463388Z","iopub.status.idle":"2026-05-15T08:43:22.477484Z","shell.execute_reply.started":"2026-05-15T08:43:22.463323Z","shell.execute_reply":"2026-05-15T08:43:22.476696Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class CIFAR10Dataset(Dataset):\n    def __init__(self, df, root, transform = None):\n        self.df, self.root, self.transform = df, root, transform\n    def __len__(self):\n        return len(self.df)\n    def __getitem__(self, idx):\n        img = Image.open(os.path.join(self.root, self.df.iloc[idx, 0]))\n        return (self.transform(img) if self.transform else img), self.df.iloc[idx, 1]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-15T08:43:22.479031Z","iopub.execute_input":"2026-05-15T08:43:22.479242Z","iopub.status.idle":"2026-05-15T08:43:22.492504Z","shell.execute_reply.started":"2026-05-15T08:43:22.479222Z","shell.execute_reply":"2026-05-15T08:43:22.491680Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel = SimpleCNN().to(device)\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr = 0.001)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-15T08:43:22.493586Z","iopub.execute_input":"2026-05-15T08:43:22.493890Z","iopub.status.idle":"2026-05-15T08:43:22.519829Z","shell.execute_reply.started":"2026-05-15T08:43:22.493857Z","shell.execute_reply":"2026-05-15T08:43:22.519215Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_set = CIFAR10Dataset(df_train, './train/', transform=transform)\ntrain_loader = DataLoader(train_set, batch_size=64, shuffle=True, num_workers=2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-15T08:43:22.520614Z","iopub.execute_input":"2026-05-15T08:43:22.520933Z","iopub.status.idle":"2026-05-15T08:43:22.527249Z","shell.execute_reply.started":"2026-05-15T08:43:22.520896Z","shell.execute_reply":"2026-05-15T08:43:22.526561Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for epoch in range(10):\n    running_loss = 0.0\n    for i, (inputs, labels) in enumerate(train_loader):\n        inputs, labels = inputs.to(device), labels.to(device)\n\n        optimizer.zero_grad()\n        outputs = model(inputs)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item()\n    print(f\"Epoch {epoch+1} - Loss: {running_loss/len(train_loader):.4f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-15T08:43:22.528202Z","iopub.execute_input":"2026-05-15T08:43:22.528491Z","iopub.status.idle":"2026-05-15T08:46:03.328825Z","shell.execute_reply.started":"2026-05-15T08:43:22.528467Z","shell.execute_reply":"2026-05-15T08:46:03.327825Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-15T08:46:03.331043Z","iopub.execute_input":"2026-05-15T08:46:03.331592Z","iopub.status.idle":"2026-05-15T08:46:03.346419Z","shell.execute_reply.started":"2026-05-15T08:46:03.331555Z","shell.execute_reply":"2026-05-15T08:46:03.345300Z"}},"outputs":[],"execution_count":null}]}