ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

CT肺结节检测YOLO数据集:从标注格式到训练实战

2026/9/13 13:09:24 拓冰建站 浏览量
CT肺结节检测YOLO数据集:从标注格式到训练实战 简介面向医学影像与目标检测学习者的YOLO肺结节检测数据集提供5000张真实场景高质量图片涵盖丰富数据场景并使用LabelImg标注标注框质量高。压缩包内包含VOCxml、COCOjson和YOLOtxt三种格式标签分别存放于不同文件夹可直接用于YOLO系列模型训练。资源共2000个文件主要是1986个xml标签文件另有说明文档html、核心脚本py与列表txt整体大小77.56MB。除数据外附赠YOLO环境搭建与训练教程区分Linux/Windows版本、数据集划分脚本可自行划分训练集、验证集、测试集便于快速上手实践。目前已有402人学习下载适合计算机视觉初学者、医学影像研究人员及需要标准格式数据集进行算法验证的开发者使用。更多详情可参考作者博客。1. 从 5000 张 CT 切片到可训练的 YOLO 模型一份肺结节检测数据集的完整拆解医学影像 AI 落地难第一步往往不是模型选型而是数据和标注格式的统一。最近处理一个肺结节检测需求拿到这份 YOLO 肺结节目标检测数据集包含 5000 张真实 CT 影像切片且同时提供 VOC(xml)、COCO(json)、YOLO(txt) 三种标注格式外加三个数据集划分脚本和完整的 YOLO 训练教程区分 Linux 与 Windows。这套资源把「数据准备 → 格式对齐 → 数据集划分 → 模型训练」整个链路补齐了适合正在做医学影像目标检测、想快速在 YOLO 系列上跑通肺结节任务的开发者也适合课程设计、毕业设计需要真实医学数据集的学生。它不是公开数据集那种几十张演示图片而是可以实际送入训练管线、能跑出收敛曲线的完整数据包。下文从数据格式差异讲起逐步拆解划分脚本逻辑再给出训练配置与排错要点。2. 三种标注格式的底层差异VOC、COCO、YOLO 各自解决什么问题2.1 格式本质XML 树形结构 vs JSON 字典 vs 归一化文本肺结节检测的数据格式转换核心是理解三种格式对「一个目标」的表述方式差异。用 LabelImg 标注后的原始产物是 VOC 格式的 XML 文件它把图像信息宽度、高度、通道数和目标框xmin, ymin, xmax, ymax用树形节点组织。COCO 格式则是一个大型 JSON 字典包含images、annotations、categories三个顶层数组目标框以[x, y, width, height]的绝对像素值存储在 annotations 中。YOLO 格式最紧凑每行一个目标五个数字依次是class_id, x_center, y_center, width, height全部归一化到 0-1。# VOC xml 中一个目标节点的典型结构 object namenodule/name bndbox xmin102/xmin ymin203/ymin xmax158/xmax ymax267/ymax /bndbox /objectXML 的优势在于人类可读性高用文本编辑器就能检查标注框是否合理劣势是单张图片的标注信息冗余较多批量读取时需要遍历 XML 树。COCO 的 JSON 结构更适合用键值对快速索引比如想知道某张图片有哪些标注对象直接按image_id过滤即可但修改数据时要保证字典内部的一致性。YOLO 格式最省存储空间且与 Darknet 框架和 Ultralytics YOLO 的训练管线直接兼容这也是为什么 YOLOv5、YOLOv8、YOLOv9 系列都默认读取 txt 标注的原因。2.2 坐标体系转换像素绝对坐标与归一化坐标的换算逻辑数据集在 VOC 和 YOLO 格式间转换时最常出的问题在坐标计算的舍入误差。VOC 的xmin, ymin, xmax, ymax是整数像素坐标转换成 YOLO 归一化格式时必须除以图片宽高# VOC - YOLO 坐标转换核心逻辑 import os def voc_to_yolo(xml_file, img_width, img_height, output_txt): # 解析 xml 中的每个 object # 对每个标注框执行归一化计算 # x_center ((xmin xmax) / 2) / img_width # y_center ((ymin ymax) / 2) / img_height # box_width (xmax - xmin) / img_width # box_height (ymax - ymin) / img_height # 将 class_id 和四个浮点数写入 txt每行一个目标 pass注意浮点数保留位数常见做法是保留 6 位小数。保留位数太少会导致目标框在训练时产生偏移尤其是肺结节这种小目标本身可能只有十几个像素的宽高归一化后约 0.01 量级如果只保留 2 位小数信息几乎丢失。转换脚本里最好用format(coord, .6f)控制输出精度。2.3 类别映射与数据一致性检查拿到这份肺结节数据集第一步不要急着训练先做一致性校验。打开三个格式文件夹确认类别编号是否完全对齐VOC 的name标签、COCO 的 categories 数组中的id字段、YOLO txt 中每行的第一个数字三者必须指向同一个语义类别。比如肺结节在 VOC 中命名为nodule那 COCO 的 categories 里就应该有{id: 0, name: nodule}YOLO txt 中类别编号为 0。一个常见的坑是标注工具导出的 COCO 格式可能从 1 开始编号而 YOLO 训练配置要求类别从 0 开始转换时需要做偏移修正。# 统计三种格式的类别分布排查标注异常 # 统计 YOLO txt 中所有类别编号 cat labels_train/*.txt | awk {print $1} | sort | uniq -c提示训练前花十分钟做格式一致性检查能省下后面排查 loss 异常的两个小时。重点看类别编号是否连续从 0 排列以及有没有空标注文件混入训练集。3. 数据集划分脚本实战训练集、验证集、测试集的正确切分姿势3.1 脚本清单与适用场景分析压缩包中附带三个 Python 脚本功能定位各不相同。第一个「训练集、验证集划分脚本」和第二个「训练集、验证集、测试集划分脚本」分别适用二划分和三划分场景第三个「split_train_val生成ImageSets下txt文件划分脚本.py」走的是更贴近 PASCAL VOC 传统的目录组织方式。实际项目里训练集、验证集、测试集的比例通常设为 8:1:1 或 7:2:1。如果数据总量只有 5000 张选择 7:2:1 更稳妥因为验证集需要足够多的样本才能稳定评估模型在各类别上的表现尤其肺结节检测中正负样本不均衡验证集太小会导致 mAP 指标波动剧烈。3.2 按文件夹复制 vs 生成 txt 索引的两种实现三划分脚本实现的是「物理划分」策略即将图片及其对应标签文件复制进新的 train、val、test 文件夹。这种做法方便人工检查数据分布但会占用双倍磁盘空间。另一种做法是生成 train.txt、val.txt、test.txt只记录图片路径训练时由 dataloader 按列表读取资源占用小且更灵活YOLO 官方训练代码支持这种索引文件方式。# 三划分脚本核心逻辑按文件列表复制 import os, shutil, random all_imgs [f for f in os.listdir(images) if f.endswith(.jpg)] random.seed(42) # 固定随机种子保证复现 random.shuffle(all_imgs) train_ratio, val_ratio 0.7, 0.2 train_n int(len(all_imgs) * train_ratio) val_n int(len(all_imgs) * val_ratio) train_set all_imgs[:train_n] val_set all_imgs[train_n:train_n val_n] test_set all_imgs[train_n val_n:] # 对每个文件同时复制图片和同名标签文件到对应目标目录 for subset_name, file_list in [(train, train_set), (val, val_set), (test, test_set)]: os.makedirs(f{subset_name}/images, exist_okTrue) os.makedirs(f{subset_name}/labels, exist_okTrue) for img_file in file_list: shutil.copy(fimages/{img_file}, f{subset_name}/images/) label_file img_file.replace(.jpg, .txt) # 假设图片和标签同名 if os.path.exists(flabels/{label_file}): shutil.copy(flabels/{label_file}, f{subset_name}/labels/)这里的random.seed(42)是关键固定随机种子后才能保证多次划分得到完全相同的分组结果这对实验可复现性至关重要。注意在复制时只复制与图片同名的 txt 标注避免把无关文件混入训练目录。标签文件缺失时用os.path.exists判断并跳过防止脚本崩溃。3.3 划分后的体检项漏标、错标、路径不一致划分完成不等于数据准备好了。有三个体检项必须做。第一统计每张图片的标注框数量排查是不是有大量图片没有任何标注框——这些在目标检测里是纯背景样本可以保留但不宜过多否则模型会偏向预测背景。第二检查图片与标签是否一一对应用 find 命令对比文件名集合差集。# 对比 images 和 labels 目录中的文件名找出不一致项 ls images | sed s/.jpg$// | sort img_names.txt ls labels | sed s/.txt$// | sort label_names.txt diff img_names.txt label_names.txt第三检查是否有重复图片。5000 张 CT 切片来自多个患者病例医学数据中相邻切片可能高度相似甚至相同重复样本会让训练集和验证集之间存在数据泄漏导致 mAP 虚高。常见做法是计算图片的 MD5 哈希值去重md5sum images/*.jpg | sort | uniq -w 32 -d提示训练集和测试集之间的重复样本会让测试集上的 mAP 数值失去参考意义。医学影像数据尤其要注意这个坑。4. YOLO 环境搭建与训练流程从 Darknet 到 Ultralytics 的完整路径4.1 环境依赖版本选择Linux 和 Windows 各自的坑压缩包中的环境搭建教程区分了 Linux 和 Windows 两个版本。以当前主流的 Ultralytics YOLOv8 为例Linux 环境推荐 Python 3.8-3.10CUDA 版本 11.8-12.1对应 PyTorch 2.0。Windows 环境首先需要注意 CUDA 驱动版本与 PyTorch 的匹配关系——不是 CUDA 装得越高越好而是要保证显卡驱动支持目标 CUDA 版本。# Linux 环境下安装 Ultralytics YOLO conda create -n yolo python3.9 conda activate yolo pip install ultralytics torch torchvision --index-url https://download.pytorch.org/whl/cu118Windows 上的差异主要在于路径分隔符和文件权限。使用 Anaconda Prompt 执行以上命令时建议将 conda 环境创建在非系统盘避免文件权限导致的写盘失败。如果显卡是 NVIDIA 的 GTX 16 系或 RTX 20 系CUDA 11.8 比 12.1 更稳定因为部分老卡在 CUDA 12 下会出现AssertionError: CUDA out of memory的误报——实际是显存管理差异而非真正的显存不足。4.2 数据集配置文件与 YAML 写法YOLOv8 训练时通过一个 YAML 文件指定数据路径和类别映射。针对这个肺结节数据集配置如下# lung_nodule.yaml train: ./datasets/lung_nodule/train # 训练集图片目录 val: ./datasets/lung_nodule/val # 验证集图片目录 test: ./datasets/lung_nodule/test # 测试集图片目录可选 nc: 1 # 类别数量这里只有一类肺结节 names: [nodule]路径写法上注意两点第一用相对路径容易出问题训练时如果工作目录切换路径解析会失败建议写成绝对路径或用os.path.abspath转换第二在 Windows 上路径分隔符建议统一用正斜杠/避免反斜杠转义字符在 YAML 解析时出问题。4.3 训练命令与关键超参数训练启动命令在 Linux 和 Windows 上基本一致核心超参数包括imgsz、batch、epochs和patience。# 单卡训练命令 yolo detect train datalung_nodule.yaml modelyolov8n.pt epochs100 batch16 imgsz640 patience20 device0 # Windows 无 GPU 时使用 CPU 训练 yolo detect train datalung_nodule.yaml modelyolov8n.pt epochs50 batch8 imgsz640 devicecpu由于肺结节本身是小目标imgsz建议从 640 起步如果显存允许可以升到 1024小目标检测效果会有明显提升。batch大小视显存而定RTX 3060 12G 显存跑 YOLOv8n 时 batch 可以设 16如果报显存不足就减半。patience是早停参数连续 20 个 epoch 验证集 mAP 没有提升就自动停止省时间。Batch 参数对医学图像训练尤为重要CT 切片灰度图通道数虽少但输入分辨率提高后显存占用增长很快。如果单卡 batch 上不去一个折中方案是用梯度累积Ultralytics 没有直接暴露该参数需要手动在训练循环里改accumulate逻辑。4.4 模型选型建议n、s、m、l 怎么选YOLOv8 提供了 n/s/m/l/x 五个规模对应不同的参数量和推理速度。肺结节检测中由于数据量只有 5000 张不建议一上来就选 l 或 x 这两个大模型——参数越多越容易过拟合医学数据标注成本高数据增强空间有限。用 YOLOv8n 做 baseline跑通整个流程、确认 loss 正常下降后再尝试 YOLOv8s 或 YOLOv8m 提升精度。如果追求更高的检测精度也可以试试 YOLOv9 或 YOLOv11Ultralytics 的接口统一配置文件不用改。但要注意不同版本的model参数写法略有差异YOLOv9 用yolov9c.ptYOLOv11 用yolo11n.pt训练时data参数完全相同。# 切换到 YOLOv11 训练同样支持上述 yaml 配置 yolo detect train datalung_nodule.yaml modelyolo11n.pt epochs100 imgsz640 device05. 数据增强策略与验证技巧在不增加标注量的前提下提升 mAP5.1 医学影像特定的增强手段通用目标检测的数据增强如 Mosaic、MixUp在医学影像上要谨慎使用。以肺结节检测为例CT 切片的像素值分布有解剖学含义过度的颜色抖动和随机擦除可能生成不符合医学逻辑的样本。推荐优先使用以下增强组合随机水平翻转、小幅旋转、缩放平移、轻度亮度对比度调整。在 Ultralytics 中通过augmentTrue启用默认增强但建议自定义增强参数# augment.yaml 自定义增强配置训练时用 augmentaugment.yaml 覆盖默认值 hsv_h: 0.0 # 色调不变 hsv_s: 0.0 # 饱和度不变 hsv_v: 0.1 # 明度轻微调整 degrees: 10 # 旋转角度 ±10 度 translate: 0.1 # 平移比例 10% fliplr: 0.5 # 水平翻转概率 50% mosaic: 0.5 # Mosaic 概率降低防止小目标被切割CT 图像不需要色调与饱和度增强保留默认值反而会引入噪声。将 Mosaic 概率从默认的 1.0 降到 0.5是因为 Mosaic 把四张图拼在一起时会缩小目标占比肺结节原本可能只有 32x32 像素再缩小后信息几乎不可辨识。医学影像中空间变换类增强旋转、平移、翻转比颜色变换更安全。5.2 模型验证超过训练 loss 的参考指标训练完成后不要只盯着loss曲线。在目标检测任务中验证集的mAP0.5和mAP0.5:0.95才是真正的考核指标。用以下命令在测试集上评估yolo detect val datalung_nodule.yaml modelruns/detect/train/weights/best.pt评估输出中需要重点看三个数值mAP0.5反映了定位和分类的综合质量0.8 以上说明模型基本可用mAP0.5:0.95对边界框精度要求更高一般比 mAP0.5 低 10-20 个百分点属正常各别类的 Precision/Recall 单独看如果 Recall 远低于 Precision说明有大量肺结节漏检优先用降低置信度阈值的方式推理找到漏检的原因。推理时正式诊断辅助场景建议把conf设到 0.15-0.25宁可多一些误检框也不放过可能的结节yolo predict modelbest.pt sourcetest_images conf0.2 iou0.55.3 遇到 loss 不下降的排错清单训练中遇到 loss 震荡或 mAP 始终为 0按以下顺序排查第一用yolo train datalung_nodule.yaml modelyolov8n.pt epochs5跑一个极短的实验确认数据加载流程是否顺畅如果这一步报错多半是 YAML 中路径配置问题。第二检查标注框是否过小CT 切片中 10 像素以下的标注框对模型训练几乎没有贡献考虑过滤或扩大输入分辨率。第三显存充足但模型的 loss 在 3 个 epoch 内不下降将学习率从默认的 0.01 调低到 0.001看看是否缓解。第四确认类别平衡如果 5000 张图里包含大量无结节切片单类训练影响不大但多类场景就要考虑采样权重了。本文还有配套的精品资源点击获取