{"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":24800,"datasetId":1042002,"databundleVersionId":1831594},{"sourceType":"datasetVersion","sourceId":1799839,"datasetId":1069682,"databundleVersionId":1837296},{"sourceType":"datasetVersion","sourceId":1800777,"datasetId":1069787,"databundleVersionId":1838236}],"dockerImageVersionId":31329,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install ultralytics","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-12T07:40:42.32204Z","iopub.execute_input":"2026-05-12T07:40:42.322402Z","iopub.status.idle":"2026-05-12T07:40:45.807037Z","shell.execute_reply.started":"2026-05-12T07:40:42.322379Z","shell.execute_reply":"2026-05-12T07:40:45.80631Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport shutil\nimport pandas as pd\nimport yaml\nfrom sklearn import model_selection\nfrom tqdm import tqdm\nfrom ultralytics import YOLO\n\n# Thiết lập các biến và thư mục làm việc (Dùng size 1024)\nsize = 1024\nWORK_DIR = '/kaggle/working/vinbigdata'\n\nTRAIN_LABELS_PATH = f'{WORK_DIR}/labels/train'\nVAL_LABELS_PATH = f'{WORK_DIR}/labels/val'\nTRAIN_IMAGES_PATH = f'{WORK_DIR}/images/train'\nVAL_IMAGES_PATH = f'{WORK_DIR}/images/val'\n\n# Tạo thư mục nếu chưa tồn tại\nfor path in [TRAIN_LABELS_PATH, VAL_LABELS_PATH, TRAIN_IMAGES_PATH, VAL_IMAGES_PATH]:\n    os.makedirs(path, exist_ok=True)\n    \nprint(\"Đã tạo xong cấu trúc thư mục!\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-05-12T07:40:45.809089Z","iopub.execute_input":"2026-05-12T07:40:45.809427Z","iopub.status.idle":"2026-05-12T07:40:49.789012Z","shell.execute_reply.started":"2026-05-12T07:40:45.809392Z","shell.execute_reply":"2026-05-12T07:40:49.787996Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Đọc dữ liệu từ file CSV gốc\ndf = pd.read_csv('/kaggle/input/competitions/vinbigdata-chest-xray-abnormalities-detection/train.csv')\n\n# BÍ QUYẾT: LOẠI BỎ CLASS 14 (No Finding) - Chỉ giữ lại ảnh có bệnh\ndf = df[df.class_id != 14].reset_index(drop=True)\n\n# Lược bỏ các cột không cần thiết (vì chúng ta sẽ dùng nhãn WBF làm sẵn)\ndf = df.drop(columns=['class_name', 'rad_id', 'x_min', 'x_max', 'y_min', 'y_max', 'class_id'])\n\n# Chia tập Train/Val (85% - 15%)\ndf_train, df_valid = model_selection.train_test_split(df, test_size=0.15, random_state=42, shuffle=True)\n\nprint(f'Số lượng ảnh Train: {len(df_train.image_id.unique())}')\nprint(f'Số lượng ảnh Validation: {len(df_valid.image_id.unique())}')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-12T07:40:49.789968Z","iopub.execute_input":"2026-05-12T07:40:49.790436Z","iopub.status.idle":"2026-05-12T07:40:49.896349Z","shell.execute_reply.started":"2026-05-12T07:40:49.790407Z","shell.execute_reply":"2026-05-12T07:40:49.895672Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport shutil\nfrom pathlib import Path\nfrom tqdm import tqdm\n\n# ==========================================\n# CELL 3: ĐỔ DỮ LIỆU BẰNG SYMLINK (BẢN DÀNH CHO ẢNH PNG)\n# ==========================================\n\n# 1. ĐƯỜNG DẪN NGUỒN (Source)\n# Trỏ thẳng vào thư mục chứa ảnh PNG của bộ dataset 1024\nTRAIN_IMG_DIR = Path('/kaggle/input/datasets/awsaf49/vinbigdata-1024-image-dataset/vinbigdata/train') \n# Dataset chứa nhãn đã WBF\nLABEL_DIR = Path('/kaggle/input/datasets/awsaf49/vinbigdata-yolo-labels-dataset/labels') \n\ntrain_ids = df_train['image_id'].unique()\nval_ids = df_valid['image_id'].unique()\n\nimg_count = 0\nlbl_count = 0\n\nfor split, ids in zip(['train', 'val'], [train_ids, val_ids]):\n    img_path = Path(f'/kaggle/working/vinbigdata/images/{split}')\n    lbl_path = Path(f'/kaggle/working/vinbigdata/labels/{split}')\n    \n    os.makedirs(img_path, exist_ok=True)\n    os.makedirs(lbl_path, exist_ok=True)\n    \n    for idx in tqdm(ids, desc=f\"Đang link tập {split}\"):\n        src_img = TRAIN_IMG_DIR / f'{idx}.png'  # ĐÃ CHỐT ĐUÔI .PNG\n        src_lbl = LABEL_DIR / f'{idx}.txt'\n        \n        # Symlink cho ảnh (Nhanh và không tốn dung lượng)\n        if src_img.exists() and not (img_path / f'{idx}.png').exists():\n            os.symlink(src_img, img_path / f'{idx}.png')\n            img_count += 1\n            \n        # Copy file text nhãn\n        if src_lbl.exists() and not (lbl_path / f'{idx}.txt').exists():\n            shutil.copy(src_lbl, lbl_path / f'{idx}.txt')\n            lbl_count += 1\n\nprint(f\"\\n=> HOÀN TẤT THỰC SỰ: Đã link {img_count} ảnh PNG và copy {lbl_count} file nhãn!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-12T07:40:49.897615Z","iopub.execute_input":"2026-05-12T07:40:49.89794Z","iopub.status.idle":"2026-05-12T07:41:00.148632Z","shell.execute_reply.started":"2026-05-12T07:40:49.897902Z","shell.execute_reply":"2026-05-12T07:41:00.147811Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Danh sách tên các loại tổn thương\nclasses = ['Aortic enlargement', 'Atelectasis', 'Calcification', 'Cardiomegaly', 'Consolidation', \n           'ILD', 'Infiltration', 'Lung Opacity', 'Nodule/Mass', 'Other lesion', 'Pleural effusion', \n           'Pleural thickening', 'Pneumothorax', 'Pulmonary fibrosis']\n\n# Thiết lập đường dẫn tuyệt đối\nyaml_data = dict(\n    path = WORK_DIR,\n    train = 'images/train',\n    val = 'images/val',\n    nc = 14,\n    names = classes\n)\n\n# Lưu thành file vinbigdata.yaml\nwith open('/kaggle/working/vinbigdata.yaml', 'w') as outfile:\n    yaml.dump(yaml_data, outfile, default_flow_style=False)\n\nprint(\"Đã tạo file cấu hình vinbigdata.yaml thành công!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-12T07:41:00.149755Z","iopub.execute_input":"2026-05-12T07:41:00.150107Z","iopub.status.idle":"2026-05-12T07:41:00.157458Z","shell.execute_reply.started":"2026-05-12T07:41:00.150061Z","shell.execute_reply":"2026-05-12T07:41:00.156887Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Tắt log weights&biases để Kernel không bị treo đòi đăng nhập\nos.environ[\"WANDB_MODE\"] = \"dryrun\"\n\n# Khởi tạo mô hình YOLO11 bản Medium (Bản thường, nhẹ và nhanh hơn bản Large)\nmodel = YOLO('yolo11m.pt')\n\nprint(\"BẮT ĐẦU HUẤN LUYỆN VỚI YOLO11 MEDIUM...\")\n\nmodel.train(\n    data='/kaggle/working/vinbigdata.yaml',\n    imgsz=1024,            # Giữ ảnh gốc lớn để không lọt lưới nốt mờ\n    epochs=75,             \n    batch=16,              # [Cải tiến] Tăng batch lên 16 vì model nhẹ hơn, giúp train nhanh hơn hẳn\n    device=0,              # Bật GPU\n    patience=20,           # Early stopping chống Overfitting\n    \n    # --- BỘ AUGMENTATION TỐI ƯU X-QUANG ---\n    mosaic=1.0,            # Ép học đa tỷ lệ\n    mixup=0.1,             # Chồng mờ các bệnh lý\n    degrees=5.0,           # Xoay nhẹ ảnh tối đa 5 độ\n    hsv_v=0.2,             # Mở rộng dải ánh sáng/độ tương phản\n    fliplr=0.0,            # BẮT BUỘC BẰNG 0 (Cấm lật ảnh ngang)\n    \n    project='/kaggle/working/runs/detect',\n    name='vin_yolo11m_1024' # Đổi tên thư mục lưu kết quả\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-05-12T07:41:00.158424Z","iopub.execute_input":"2026-05-12T07:41:00.158819Z"}},"outputs":[],"execution_count":null}]}