{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.12.12"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"databundleVersionId":46665,"sourceId":4117,"sourceType":"competition"},{"databundleVersionId":16474510,"datasetId":9938514,"sourceId":15545655,"sourceType":"datasetVersion"},{"sourceId":309068248,"sourceType":"kernelVersion"},{"sourceId":309102811,"sourceType":"kernelVersion"}],"dockerImageVersionId":31328,"isGpuEnabled":true,"isInternetEnabled":true,"language":"python","sourceType":"notebook"},"papermill":{"default_parameters":{},"duration":87.057825,"end_time":"2026-04-05T16:59:09.037025+00:00","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2026-04-05T16:57:41.979200+00:00","version":"2.7.0"},"widgets":{"application/vnd.jupyter.widget-state+json":{"state":{"156f3b2f60e14edb830ac3f00db3ab2c":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"1aeddaf33af04819bd4c4cc0c007ce3f":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"2353046ad72345b3ae2aabff0f276fd4":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"4854ac6d1cdb45d2b48359d815a3e4a2":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_64755f60b0f342f4be867636c4c1f033","placeholder":"​","style":"IPY_MODEL_b8048ca7207d4727ad69e1158ac95dac","tabbable":null,"tooltip":null,"value":" 340/340 [01:03&lt;00:00,  6.13it/s]"}},"49b7f2b9c9864e2d9f50f2a8f92542b5":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_1aeddaf33af04819bd4c4cc0c007ce3f","max":340,"min":0,"orientation":"horizontal","style":"IPY_MODEL_d18ac04cf14c4865979cc21b219c8632","tabbable":null,"tooltip":null,"value":340}},"4e80a9ba3de4488fafe2b7bdd7e3c9f2":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_64093857ba94452b9eb6585b601eae50","placeholder":"​","style":"IPY_MODEL_156f3b2f60e14edb830ac3f00db3ab2c","tabbable":null,"tooltip":null,"value":"Testing: 100%"}},"64093857ba94452b9eb6585b601eae50":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"64755f60b0f342f4be867636c4c1f033":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"8ee1db28f172400188e37fc697701f09":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_4e80a9ba3de4488fafe2b7bdd7e3c9f2","IPY_MODEL_49b7f2b9c9864e2d9f50f2a8f92542b5","IPY_MODEL_4854ac6d1cdb45d2b48359d815a3e4a2"],"layout":"IPY_MODEL_2353046ad72345b3ae2aabff0f276fd4","tabbable":null,"tooltip":null}},"b8048ca7207d4727ad69e1158ac95dac":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"d18ac04cf14c4865979cc21b219c8632":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}}},"version_major":2,"version_minor":0}}},"nbformat_minor":4,"nbformat":4,"cells":[{"id":"74d15b7b","cell_type":"code","source":"# ==========================================\n# THIẾT LẬP THƯ VIỆN & ĐƯỜNG DẪN\n# ==========================================\nimport os\nimport pandas as pd\nimport numpy as np\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nfrom PIL import Image\nimport timm\nfrom tqdm.notebook import tqdm","metadata":{"execution":{"iopub.execute_input":"2026-04-05T16:57:44.585396Z","iopub.status.busy":"2026-04-05T16:57:44.585107Z","iopub.status.idle":"2026-04-05T16:58:00.274278Z","shell.execute_reply":"2026-04-05T16:58:00.273599Z"},"papermill":{"duration":15.695039,"end_time":"2026-04-05T16:58:00.276282+00:00","exception":false,"start_time":"2026-04-05T16:57:44.581243+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"d1c37cca","cell_type":"code","source":"# --- CẤU HÌNH ĐƯỜNG DẪN ---\nTEST_IMG_DIR = \"/kaggle/input/datasets/trankimhuu/images-datasets-of-big2015/test_images/test_images/kaggle/working/test_images\"\nSAMPLE_SUB_PATH = \"/kaggle/input/competitions/malware-classification/sampleSubmission.csv\"\nMODEL_WEIGHTS_PATH = \"/kaggle/input/notebooks/rosetra/levit-192-ver1/best_levit_model.pth\"\nOUTPUT_SUBMISSION_PATH = \"/kaggle/working/submission_ver2.csv\"","metadata":{"execution":{"iopub.execute_input":"2026-04-05T16:58:00.281304Z","iopub.status.busy":"2026-04-05T16:58:00.280830Z","iopub.status.idle":"2026-04-05T16:58:00.285187Z","shell.execute_reply":"2026-04-05T16:58:00.284495Z"},"papermill":{"duration":0.008624,"end_time":"2026-04-05T16:58:00.286746+00:00","exception":false,"start_time":"2026-04-05T16:58:00.278122+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"c3dc70a8","cell_type":"code","source":"BATCH_SIZE = 32\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(f\"Đang sử dụng thiết bị: {device}\")","metadata":{"execution":{"iopub.execute_input":"2026-04-05T16:58:00.291182Z","iopub.status.busy":"2026-04-05T16:58:00.290896Z","iopub.status.idle":"2026-04-05T16:58:00.548395Z","shell.execute_reply":"2026-04-05T16:58:00.547334Z"},"papermill":{"duration":0.261771,"end_time":"2026-04-05T16:58:00.550134+00:00","exception":false,"start_time":"2026-04-05T16:58:00.288363+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"2d01aa7d","cell_type":"code","source":"# ==========================================\n# ĐỊNH NGHĨA LẠI KIẾN TRÚC MÔ HÌNH\n# ==========================================\n# Bắt buộc phải giống hệt kiến trúc lúc train để load được trọng số\nclass LeViT_Malware(nn.Module):\n    def __init__(self, model_name='levit_192', num_classes=9, pretrained=False):\n        super().__init__()\n        # Để pretrained=False vì ta sẽ tự load trọng số tốt nhất của mình\n        self.backbone = timm.create_model(model_name, pretrained=pretrained, num_classes=0)\n        num_features = self.backbone.num_features\n        \n        self.head = nn.Sequential(\n            nn.BatchNorm1d(num_features),\n            nn.Dropout(p=0.3),\n            nn.Linear(num_features, 512),\n            nn.GELU(),\n            nn.BatchNorm1d(512),\n            nn.Dropout(p=0.3),\n            nn.Linear(512, num_classes)\n        )\n\n    def forward(self, x):\n        features = self.backbone(x)\n        return self.head(features)","metadata":{"execution":{"iopub.execute_input":"2026-04-05T16:58:00.555794Z","iopub.status.busy":"2026-04-05T16:58:00.555052Z","iopub.status.idle":"2026-04-05T16:58:00.561283Z","shell.execute_reply":"2026-04-05T16:58:00.560360Z"},"papermill":{"duration":0.010681,"end_time":"2026-04-05T16:58:00.562882+00:00","exception":false,"start_time":"2026-04-05T16:58:00.552201+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"35fe87ef","cell_type":"code","source":"# ==========================================\n# DATASET DÀNH RIÊNG CHO TẬP TEST\n# ==========================================\nclass MalwareTestDataset(Dataset):\n    def __init__(self, sample_sub_df, img_dir, transform=None):\n        self.sample_sub_df = sample_sub_df\n        self.img_dir = img_dir\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.sample_sub_df)\n\n    def __getitem__(self, idx):\n        # Lấy Id từ file mẫu để map chính xác với ảnh\n        img_id = str(self.sample_sub_df.iloc[idx]['Id'])\n        img_name = img_id + \".png\" \n        img_path = os.path.join(self.img_dir, img_name)\n        \n        image = Image.open(img_path).convert('RGB')\n\n        if self.transform:\n            image = self.transform(image)\n\n        return image, img_id","metadata":{"execution":{"iopub.execute_input":"2026-04-05T16:58:00.567658Z","iopub.status.busy":"2026-04-05T16:58:00.567253Z","iopub.status.idle":"2026-04-05T16:58:00.573213Z","shell.execute_reply":"2026-04-05T16:58:00.572292Z"},"papermill":{"duration":0.010006,"end_time":"2026-04-05T16:58:00.574780+00:00","exception":false,"start_time":"2026-04-05T16:58:00.564774+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"58f6731e","cell_type":"code","source":"# Transform giữ nguyên như tập Validation lúc train\ntest_transform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n])","metadata":{"execution":{"iopub.execute_input":"2026-04-05T16:58:00.579205Z","iopub.status.busy":"2026-04-05T16:58:00.578975Z","iopub.status.idle":"2026-04-05T16:58:00.583251Z","shell.execute_reply":"2026-04-05T16:58:00.582601Z"},"papermill":{"duration":0.008255,"end_time":"2026-04-05T16:58:00.584725+00:00","exception":false,"start_time":"2026-04-05T16:58:00.576470+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"c1e2cad8","cell_type":"code","source":"# ==========================================\n# CHẠY SUY LUẬN (INFERENCE) VÀ LƯU CSV\n# ==========================================\ndef run_inference():\n    # 1. Đọc file sample submission\n    print(\"Đang nạp dữ liệu...\")\n    sample_sub = pd.read_csv(SAMPLE_SUB_PATH)\n    \n    # 2. Khởi tạo Dataset & DataLoader\n    test_dataset = MalwareTestDataset(sample_sub, TEST_IMG_DIR, transform=test_transform)\n    test_loader = DataLoader(test_dataset, batch_size=BATCH_SIZE, shuffle=False, num_workers=2)\n\n    # 3. Khởi tạo model và nạp trọng số\n    print(\"Đang nạp trọng số mô hình...\")\n    model = LeViT_Malware(pretrained=False).to(device)\n    \n    # Dùng weights_only=True để bảo mật và map_location để tương thích thiết bị\n    model.load_state_dict(torch.load(MODEL_WEIGHTS_PATH, map_location=device, weights_only=True))\n    \n    # CHUYỂN MÔ HÌNH SANG CHẾ ĐỘ ĐÁNH GIÁ (Tắt Dropout)\n    model.eval()\n\n    all_predictions = []\n    all_ids = []\n\n    print(\"Bắt đầu chạy dự đoán trên tập test...\")\n    # Tắt tính toán đạo hàm để giải phóng VRAM và tăng tốc\n    with torch.no_grad():\n        for images, img_ids in tqdm(test_loader, desc=\"Testing\"):\n            images = images.to(device)\n            \n            # Đưa ảnh qua mô hình để lấy Logits thô\n            logits = model(images)\n            \n            # Ép giá trị thô thành xác suất (Tổng các class = 1.0)\n            probs = F.softmax(logits, dim=1)\n            \n            # Chuyển dữ liệu từ GPU về RAM và lưu lại\n            all_predictions.extend(probs.cpu().numpy())\n            all_ids.extend(img_ids)\n\n    # 4. Đóng gói kết quả vào file CSV\n    print(\"\\nĐang tạo file submission...\")\n    # Khởi tạo DataFrame với 9 cột Prediction tương ứng 9 class\n    submission_df = pd.DataFrame(all_predictions, columns=[f'Prediction{i}' for i in range(1, 10)])\n    \n    # Chèn cột Id vào vị trí đầu tiên (index 0)\n    submission_df.insert(0, 'Id', all_ids) \n\n    # Lưu thành file .csv (Bỏ cột index mặc định của Pandas)\n    submission_df.to_csv(OUTPUT_SUBMISSION_PATH, index=False)\n    print(f\"Hoàn tất! File đã được lưu tại: {OUTPUT_SUBMISSION_PATH}\")","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.execute_input":"2026-04-05T16:58:00.589712Z","iopub.status.busy":"2026-04-05T16:58:00.589334Z","iopub.status.idle":"2026-04-05T16:58:00.597172Z","shell.execute_reply":"2026-04-05T16:58:00.596470Z"},"papermill":{"duration":0.012334,"end_time":"2026-04-05T16:58:00.598720+00:00","exception":false,"start_time":"2026-04-05T16:58:00.586386+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"19aac6ea","cell_type":"code","source":"# Kích hoạt hàm\nif __name__ == '__main__':\n    run_inference()","metadata":{"execution":{"iopub.execute_input":"2026-04-05T16:58:00.603500Z","iopub.status.busy":"2026-04-05T16:58:00.602995Z","iopub.status.idle":"2026-04-05T16:59:05.723401Z","shell.execute_reply":"2026-04-05T16:59:05.722148Z"},"papermill":{"duration":65.125007,"end_time":"2026-04-05T16:59:05.725401+00:00","exception":false,"start_time":"2026-04-05T16:58:00.600394+00:00","status":"completed"},"tags":[]},"outputs":[],"execution_count":null}]}