{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceType":"competition","sourceId":4117,"databundleVersionId":46665,"isSourceIdPinned":false},{"sourceType":"kernelVersion","sourceId":314083412,"isSourceIdPinned":false}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport os\nimport shutil\nimport gc\nimport subprocess\nfrom PIL import Image\nimport tensorflow as tf\n\n# ==============================================================================\n# 1. CẤU HÌNH ĐƯỜNG DẪN \n# ==============================================================================\nMODEL_PATH = '/kaggle/input/notebooks/solitudeshu/malware-classification-train-resnet50/malware_resnet50.keras'\n\n# Dữ liệu đầu vào từ cuộc thi\nTEST_ARCHIVE_PATH = '/kaggle/input/competitions/malware-classification/test.7z'\nSAMPLE_SUB_PATH = '/kaggle/input/competitions/malware-classification/sampleSubmission.csv'\n\n# Thư mục làm việc tạm thời\nTEST_IMAGE_DIR = '/kaggle/working/test_images_png'\nTEMP_BUFFER_DIR = '/kaggle/working/temp_extract'\nCHUNK_SIZE = 200  # Số lượng file xử lý mỗi đợt để tối ưu RAM/Disk\n\n# ==============================================================================\n# 2. CÁC HÀM BỔ TRỢ \n# ==============================================================================\ndef convert_hex_to_image(raw_content):\n    \"\"\"Chuyển đổi nội dung file .bytes thành mảng ảnh 224x224.\"\"\"\n    lines = raw_content.split('\\n')\n    byte_list = []\n    for line in lines:\n        if len(line) < 10: continue\n        hex_str = line[9:] # Bỏ cột địa chỉ bộ nhớ\n        parts = hex_str.split()\n        for p in parts:\n            if p == '??':\n                byte_list.append(0)\n            else:\n                try:\n                    byte_list.append(int(p, 16))\n                except ValueError:\n                    pass\n    \n    if not byte_list:\n        return np.zeros((224, 224), dtype=np.uint8)\n\n    arr = np.array(byte_list, dtype=np.uint8)\n    width = int(np.ceil(len(arr) ** 0.5))\n    padded_arr = np.pad(arr, (0, width*width - len(arr)), mode='constant')\n    img_matrix = padded_arr.reshape((width, width))\n    \n    # Resize về kích thước ResNet50 yêu cầu\n    img = Image.fromarray(img_matrix)\n    return np.array(img.resize((224, 224), Image.BILINEAR))\n\ndef preprocess_image(file_id):\n    \"\"\"Hàm nạp và tiền xử lý ảnh cho tf.data pipeline.\"\"\"\n    img_path = os.path.join(TEST_IMAGE_DIR, f\"{file_id.numpy().decode('utf-8')}.png\")\n    img = tf.io.read_file(img_path)\n    img = tf.image.decode_png(img, channels=3)\n    img = tf.image.resize(img, [224, 224])\n    return tf.keras.applications.resnet50.preprocess_input(img)\n\n# ==============================================================================\n# 3. QUY TRÌNH XỬ LÝ TEST SET (Giải nén -> PNG)\n# ==============================================================================\ndf_sample = pd.read_csv(SAMPLE_SUB_PATH)\ntest_ids = df_sample['Id'].tolist()\n\nos.makedirs(TEST_IMAGE_DIR, exist_ok=True)\nprint(f\"Bắt đầu chuyển đổi {len(test_ids)} file test sang ảnh PNG...\")\n\nfor i in range(0, len(test_ids), CHUNK_SIZE):\n    chunk = test_ids[i : i + CHUNK_SIZE]\n    os.makedirs(TEMP_BUFFER_DIR, exist_ok=True)\n    \n    # Tạo danh sách file cần giải nén cho 7-Zip\n    list_file = '/kaggle/working/temp_list.txt'\n    with open(list_file, 'w') as f:\n        for fid in chunk:\n            f.write(f\"test/{fid}.bytes\\n\")\n    \n    # Giải nén bằng 7z (Native command)\n    subprocess.run([\"7z\", \"e\", TEST_ARCHIVE_PATH, f\"-o{TEMP_BUFFER_DIR}\", f\"@{list_file}\", \"-y\", \"-bsp0\", \"-bso0\"], check=True)\n    \n    # Chuyển đổi từng file bytes thành PNG\n    for fid in chunk:\n        path = os.path.join(TEMP_BUFFER_DIR, f\"{fid}.bytes\")\n        if os.path.exists(path) and os.path.getsize(path) > 0:\n            with open(path, 'r', encoding='utf-8', errors='ignore') as f_in:\n                content = f_in.read()\n            img_arr = convert_hex_to_image(content)\n            Image.fromarray(img_arr).convert('RGB').save(os.path.join(TEST_IMAGE_DIR, f\"{fid}.png\"))\n    \n    # Dọn dẹp sau mỗi chunk\n    shutil.rmtree(TEMP_BUFFER_DIR)\n    os.remove(list_file)\n    gc.collect()\n    \n    if (i // CHUNK_SIZE) % 5 == 0:\n        print(f\"Đã xử lý: {i + len(chunk)}/{len(test_ids)}\")\n\nprint(\"Hoàn tất tạo ảnh PNG cho tập Test.\")\n\n# ==============================================================================\n# 4. LOAD MODEL & DỰ ĐOÁN\n# ==============================================================================\nmodel = tf.keras.models.load_model(MODEL_PATH)\n\n# Xây dựng tf.data pipeline để dự đoán tốc độ cao\ntest_ds = tf.data.Dataset.from_tensor_slices(test_ids)\ntest_ds = test_ds.map(lambda x: tf.py_function(preprocess_image, [x], tf.float32), \n                      num_parallel_calls=tf.data.AUTOTUNE)\ntest_ds = test_ds.batch(32).prefetch(tf.data.AUTOTUNE)\n\nprint(\"Đang thực hiện dự đoán xác suất...\")\ny_probs = model.predict(test_ds, verbose=1)\n\n# ==============================================================================\n# 5. TẠO FILE SUBMISSION\n# ==============================================================================\n# Tên các cột: Id, Prediction1, ..., Prediction9\ncolumns = [f'Prediction{i}' for i in range(1, 10)]\nsubmission_df = pd.DataFrame(y_probs, columns=columns)\nsubmission_df.insert(0, 'Id', test_ids)\n\nfinal_csv = 'submission_resnet50.csv'\nsubmission_df.to_csv(final_csv, index=False)\nshutil.rmtree(TEST_IMAGE_DIR)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null}]}