# VinBigData 项目说明 ## 1. 文档目的 本文档用于说明本仓库中 `VinBigData Chest X-ray Abnormalities Detection` Kaggle 比赛项目的目标、组成、运行链路和复现注意事项。 该仓库本质上是一个 **以 Kaggle Notebook 为中心的比赛归档项目**,重点在于提交策略验证,而不是可直接安装和运行的标准工程包。因此,本文档的定位是: - 说明项目主线与各 notebook 的职责 - 记录关键输入、输出和依赖关系 - 为后续回看、迁移或局部复现提供导航 ## 2. 项目概述 ### 2.1 比赛任务 比赛输入为胸部 X-ray 影像,输出为 Kaggle 要求的 `PredictionString`,每 6 个值表示一条预测: `class_id score x_min y_min x_max y_max` 其中: - `0` 到 `13` 表示 14 类胸片异常 - `14` 表示 `No finding` 因此,该任务不仅是目标检测任务,还包含明显的图像级正常/异常判别需求。仓库中的方案围绕这一点构建,核心并非单一模型,而是以下组合: 1. 14 类异常检测 2. normal / abnormal 二分类 3. `No finding` 的规则化后处理 4. 多个 submission 的结果级融合 ### 2.2 仓库定位 从当前文件内容看,该项目的主要价值不在于“训练脚本工程化”,而在于保留一套完整的比赛思路: - 检测模型负责输出异常框 - 二分类模型负责判断整图是否更接近正常 - 后处理阶段决定保留框、追加 `class 14`,或直接替换为 `No finding` - 在此基础上尝试进一步 ensemble ## 3. 仓库文件说明 | 文件 | 作用 | 说明 | | --- | --- | --- | | `yolov5-chest-512.ipynb` | 主流程 notebook | 包含数据整理、fold 划分、YOLO 标签生成、检测推理、图像级分类辅助后处理 | | `vinbigdata-cxr-ad-yolov5-14-class-infer.ipynb` | 纯检测推理 | 使用训练好的 YOLOv5 权重生成检测结果并导出 `submission.csv` | | `vinbigdata-2-class-classifier-complete-pipeline.ipynb` | 二分类完整流程 | 训练 normal / abnormal 分类器,并导出 `valid_pred.csv`、`test_pred.csv` | | `ensembling-approach.ipynb` | submission 级融合 | 对多个检测 submission 做启发式融合与平均 | | `ensemble-of-best-public-notebooks.ipynb` | 轻量后处理 | 对已有 submission 再应用一次 2-class filter | | `VINBIGDATA_REVIEW.md` | 项目说明文档 | 当前文档 | ## 4. 方案架构 ### 4.1 总体流程 该项目可以概括为以下流水线: 1. 使用检测模型生成 14 类异常框 2. 使用二分类模型估计图像为 normal 的概率 3. 根据 normal 概率对检测结果做后处理 4. 必要时对多个 submission 再进行融合 可简化表示为: `Detection -> 2-class probability -> Post-process No finding -> Ensemble` 为了便于快速把握整体关系,下面补充三张结构图,分别对应总体流水线、各 notebook 职责,以及后处理决策逻辑。 **总体流水线** ```mermaid flowchart LR A[官方比赛数据
train.csv / test dicom] --> B[图像预处理数据集
256 / 512 / 1024 PNG] B --> C[yolov5-chest-512.ipynb
主检测流程] A --> C B --> D[vinbigdata-2-class-classifier-complete-pipeline.ipynb
normal / abnormal 二分类] A --> D C --> E[14 类异常检测结果] D --> F[test_pred.csv / valid_pred.csv
整图 normal 概率] E --> G[后处理逻辑
Keep / Add / Replace] F --> G G --> H[submission.csv] H --> I[ensemble-of-best-public-notebooks.ipynb
轻量 2-class 再过滤] F --> I I --> J[postprocessed submission.csv] H --> K[ensembling-approach.ipynb
多 submission 融合] J --> K K --> L[final submission.csv] ``` **Notebook 职责图** ```mermaid flowchart TD A[yolov5-chest-512.ipynb] --> A1[读取比赛数据] A --> A2[MultilabelStratifiedKFold 分 fold] A --> A3[生成 YOLO 标签] A --> A4[调用检测模型推理] A --> A5[结合整图分类做后处理] A --> A6[导出 submission.csv] B[vinbigdata-cxr-ad-yolov5-14-class-infer.ipynb] --> B1[加载 best.pt] B --> B2[运行 detect.py] B --> B3[YOLO 坐标转回比赛格式] B --> B4[纯检测 baseline submission] C[vinbigdata-2-class-classifier-complete-pipeline.ipynb] --> C1[构造 normal / abnormal 标签] C --> C2[StratifiedKFold 训练] C --> C3[导出 valid_pred.csv] C --> C4[导出 test_pred.csv] C --> C5[按阈值修正检测 submission] D[ensemble-of-best-public-notebooks.ipynb] --> D1[读取已有 submission] D --> D2[读取 2-class 概率] D --> D3[Keep / Add / Replace] E[ensembling-approach.ipynb] --> E1[读取多个 submission] E --> E2[按图片拆分 PredictionString] E --> E3[top-n 保留] E --> E4[同类框平均融合] ``` **后处理决策图** ```mermaid flowchart TD A[输入: 一张图的检测结果 + class0 概率] --> B{normal 概率阈值} B -->|p < low_threshold| C[Keep
保留检测结果] B -->|low_threshold <= p < high_threshold| D[Add
保留检测结果并追加 class 14] B -->|p >= high_threshold| E[Replace
替换为 14 1 0 0 1 1] ``` ### 4.2 检测主线 `yolov5-chest-512.ipynb` 是最接近“总控台”的 notebook。根据 notebook 中保留的代码,其主线包括: - 读取官方比赛数据与预处理后的 PNG 数据 - 将原始标注缩放到训练尺寸 - 使用 `MultilabelStratifiedKFold` 划分 5-fold - 生成 YOLO 训练目录及标签文件 - 以 512 尺度作为主要检测输入 - 调用 YOLOv5 `detect.py` 做推理 - 结合图像级分类结果生成最终 `submission.csv` 需要说明的是,该 notebook 中保留了部分历史实验痕迹,例如 EfficientDet / EfficientNet 相关配置、硬编码阈值和样本过滤列表。它更像比赛过程中的工作 notebook,而不是整理后的单一职责脚本。 ### 4.3 二分类补偿分支 `vinbigdata-2-class-classifier-complete-pipeline.ipynb` 负责训练整图二分类器,用于回答“这张图是否正常”。 其主要配置和行为包括: - 输入图像目录:`vinbigdata-chest-xray-resized-png-256x256` - 默认 backbone:`resnet18` - 5-fold `StratifiedKFold` - 训练轮数:`epoch=15` - 调度器:`CosineAnnealingWarmRestarts` - 支持 `mixup`、`label_smoothing`、`EMA` - 输出: - `valid_pred.csv` - `test_pred.csv` 该分支不负责检测框位置,只输出 normal / abnormal 概率,供后处理阶段使用。 ### 4.4 后处理策略 当前仓库中的后处理逻辑高度一致,核心思想为: 1. 若 normal 概率较低,则保留检测结果 2. 若 normal 概率处于中间区间,则保留检测结果并追加 `class 14` 3. 若 normal 概率较高,则直接替换为 `14 1 0 0 1 1` 在 `vinbigdata-2-class-classifier-complete-pipeline.ipynb` 中,保存下来的阈值示例为: - `low_threshold = 0.0` - `high_threshold = 0.976` 在 `ensemble-of-best-public-notebooks.ipynb` 中,轻量后处理版本使用: - `low_threshold = 0.0` - `high_threshold = 0.90` 这说明项目后期的主要增分手段之一,是利用二分类模型修正检测器在正常样本上的误报。 ### 4.5 多模型融合 `ensembling-approach.ipynb` 不是模型层面的联合训练,而是 **submission 级别** 的结果融合。 它的做法是: 1. 读取多个模型导出的 `PredictionString` 2. 将每个 submission 拆分成按图像组织的预测字典 3. 每个模型仅保留 top-n 预测,默认 `n=3` 4. 找出相同类别的重复预测 5. 对重复类别的分数和框坐标做平均 6. 重新拼接为新的 `submission.csv` 该方法更接近启发式 averaging,而不是标准训练期融合。 ## 5. 各 Notebook 的正式说明 ### 5.1 `yolov5-chest-512.ipynb` 用途: - 项目主流程梳理 - 训练前数据准备 - YOLO 标签生成 - 检测结果读取与后处理 - 结合图像级分类器生成最终提交 关键实现: - `split_df(...)` - 使用 `MultilabelStratifiedKFold` 做检测任务分层划分 - `Preprocess_wbf(...)` - 对训练标注做 WBF 风格整理 - `create_file(...)` - 生成 YOLO 所需目录结构和标签文件 - `Predict_process.fit(...)` - 读取 YOLO 检测结果 - 执行 NMS - 调用 `EfficientnetCus` 进行整图分类 - 根据分类概率决定最终 `PredictionString` 说明: - notebook 中提供了 YOLOv5 训练命令示例,但训练命令本身是注释状态 - 检测推理阶段调用的是外部 `best.pt` - 部分阈值和过滤列表属于比赛调参产物,保留了明显经验化特征 ### 5.2 `vinbigdata-cxr-ad-yolov5-14-class-infer.ipynb` 用途: - 以最小流程生成纯检测提交 关键行为: - 读取已训练好的 `best.pt` - 调用 `detect.py` - 使用 `img=640`、`conf=0.15`、`iou=0.4` - 保存 `txt` 和置信度 - 将 YOLO 输出转换回比赛要求的原图坐标 - 对无检测框图像填充 `14 1 0 0 1 1` 适用场景: - 快速恢复纯检测 baseline - 对比二分类后处理前后的差异 ### 5.3 `vinbigdata-2-class-classifier-complete-pipeline.ipynb` 用途: - 训练二分类器 - 导出验证集和测试集概率 - 演示如何将 2-class 结果作用到检测 submission 关键行为: - 数据标签定义为: - 无异常标注 -> normal - 有异常标注 -> abnormal - 使用 `StratifiedKFold` 保持 normal / abnormal 比例 - 导出: - `valid_pred.csv` - `test_pred.csv` - 支持最后一步 2-class filter 后处理 适用场景: - 单独复现 normal / abnormal 分支 - 为现有检测 submission 追加后处理信号 ### 5.4 `ensembling-approach.ipynb` 用途: - 对多个已有 submission 做结果融合 关键行为: - 按图像读取多个 `PredictionString` - 对每个模型保留高置信度 top-n 结果 - 对重复类别做概率和框坐标平均 - 导出新的融合 submission 适用场景: - 比较不同检测方案或不同公开 notebook 的互补性 ### 5.5 `ensemble-of-best-public-notebooks.ipynb` 用途: - 对已有 submission 快速再施加一层 2-class filter 关键行为: - 读取检测 submission - 读取 2-class 预测 csv - 按阈值执行 `Keep / Add / Replace` - 导出新的 `submission.csv` 适用场景: - 不重新训练模型,只做最后一步规则修正 ## 6. 输入、输出与依赖 ### 6.1 运行环境 该项目基于 Kaggle Notebook 环境编写,当前仓库 **不包含完整可离线执行的依赖清单和脚本封装**。大部分 notebook 默认假设以下前提成立: - 运行环境为 Kaggle - 数据、模型权重和外部代码位于 `../input/...` - 图像已提前转换为 PNG 或已存在预处理版本 ### 6.2 主要外部输入 从 notebook 中能确认的主要依赖包括: - 官方比赛数据: - `vinbigdata-chest-xray-abnormalities-detection` - 预处理图像数据: - `vinbigdata-chest-xray-resized-png-256x256` - `vinbigdata-chest-xray-resized-png-1024x1024` - `vinbigdata-512-image-dataset` 或同类 512 PNG 数据 - 测试元数据: - `vinbigdata-testmeta/test_meta.csv` - 2-class 预测结果: - `vinbigdata-2class-prediction/2-cls test pred.csv` - 或 `vinbigdata2classpred/test_pred.csv` - 外部模型/代码: - `yolov5` - 已训练检测权重 `best.pt` - 二分类模型权重 ### 6.3 主要输出 | Notebook | 主要输出 | | --- | --- | | `yolov5-chest-512.ipynb` | `submission.csv`,YOLO 标签目录 | | `vinbigdata-cxr-ad-yolov5-14-class-infer.ipynb` | `submission.csv` | | `vinbigdata-2-class-classifier-complete-pipeline.ipynb` | `valid_pred.csv`、`test_pred.csv`、后处理后的 `submission.csv` | | `ensembling-approach.ipynb` | 融合后的 `submission.csv` | | `ensemble-of-best-public-notebooks.ipynb` | 追加 2-class filter 后的 `submission.csv` | ## 7. 推荐阅读顺序 ### 7.1 理解项目主线 建议顺序: 1. `VINBIGDATA_REVIEW.md` 2. `yolov5-chest-512.ipynb` 3. `vinbigdata-2-class-classifier-complete-pipeline.ipynb` 目标: - 先理解最终提交的构成方式 - 再理解检测和二分类分别提供什么信号 ### 7.2 只恢复纯检测 baseline 建议优先阅读: 1. `vinbigdata-cxr-ad-yolov5-14-class-infer.ipynb` 2. `yolov5-chest-512.ipynb` 中的检测后处理部分 ### 7.3 只恢复后处理与提分思路 建议优先阅读: 1. `vinbigdata-2-class-classifier-complete-pipeline.ipynb` 2. `ensemble-of-best-public-notebooks.ipynb` 3. `ensembling-approach.ipynb` ## 8. 复现注意事项 ### 8.1 本仓库不是完整的本地工程 当前仓库仅保留 notebook 与说明文档,没有: - 独立的 `requirements.txt` - 统一的训练入口脚本 - 完整的本地路径配置 - 明确的最终线上提交版本记录 因此,仓库更适合做以下用途: - 回顾比赛策略 - 迁移部分 notebook 逻辑 - 抽取后处理与 ensemble 思路 不适合直接视为“一键复现实验”的标准工程。 ### 8.2 路径和参数存在 Kaggle 绑定 多数 notebook 直接写死了 `../input/...` 路径,说明原始运行环境依赖 Kaggle Dataset / Notebook Output。若迁移到本地,需要自行重建: - 原始数据目录 - 预处理 PNG 目录 - 测试元数据 - 模型权重目录 - YOLOv5 代码目录 ### 8.3 存在比赛期经验化规则 项目中保留了较多比赛调参痕迹,例如: - `list_remove` - `image_remove` - 类别特定阈值 - `No finding` 的分段规则 这些逻辑对理解历史提交有价值,但不应直接视为可泛化的医学影像检测最佳实践。 ### 8.4 最终最佳提交版本无法仅凭仓库唯一确认 从当前仓库可以清楚恢复整体方案,但无法仅凭现有文件 100% 唯一确认最终线上提交是哪一个 notebook 产物或哪个 ensemble 版本。原因包括: - 缺少 leaderboard 版本记录 - 缺少 commit 级说明 - 仓库中同时保留了多条尝试路线 ## 9. 结论 本项目的核心不是单一检测模型,而是一套围绕 VinBigData 比赛构建的提交工程: 1. 用检测模型识别 14 类异常 2. 用二分类模型判断 normal / abnormal 3. 用后处理规则显式处理 `No finding` 4. 视情况再对多个 submission 进行融合 如果只保留一个最值得回看的文件,应优先查看 `yolov5-chest-512.ipynb`;如果要理解本项目为什么能进一步提分,应重点查看 `vinbigdata-2-class-classifier-complete-pipeline.ipynb` 中的 2-class filter 流程。