ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

直肠息肉病变检测数据集VOC+YOLO格式解析与YOLO训练实战

直肠息肉病变检测数据集VOC+YOLO格式解析与YOLO训练实战 简介直肠息肉病变检测数据集包含10725张内镜图像并提供Pascal VOC与YOLO两种格式的标注文件覆盖息肉、出血、气泡、食管炎、器械和误检6个临床常见类别的目标框总标注框数达20580个。数据已按标准目录整理可直接用于目标检测模型训练、验证与微调适合医学影像AI、内镜辅助诊断等方向的研究者与算法工程师。压缩包共2000个文件以xml标注文件与txt格式标签为主内含对应jpg图片整体大小440.12MB使用labelImg工具完成标注各类别框数从2801到4608不等有利于深入分析多类别均衡性及困难样本挖掘。目前已有320人学习。该数据集类别设置贴近真实内镜场景正负样本分布清晰可用于消化道病变检测实验、模型效果对比、迁移学习及论文复现能帮助使用者节省数据采集与清洗时间快速搭建起自己的检测流程与评估体系。1. 这个数据集到底是什么为什么值得关注拿到“直肠息肉病变检测数据集VOCYOLO格式10725张6类别.7z”这个压缩包第一反应是这不是普通的目标检测demo数据而是一份面向消化道内镜影像的医疗AI基础资产。它包含了10725张真实内镜图像标注了6个与直肠息肉病变相关的类别同时提供VOC和YOLO两种目标检测标注格式整体打包为7z压缩文件。先说清楚它解决什么问题。做医疗影像目标检测最卡脖子的往往不是模型结构而是数据。公开可用的息肉检测数据集数量少、类别单一、标注格式各异很多团队为了一份干净数据要花几周做清洗和格式转换。这份数据集把“分类—标注—格式”一次补齐10725张图解决了“量”的问题6个类别覆盖了常见病变类型VOC和YOLO双格式则省去了最枯燥的标注转换环节。适合动手搞检测模型的学生、刚入场医疗AI的工程师、以及需要快速验证算法的研究组。再说6个类别。标题没有展开说明具体哪6类但结合临床常见分类推测大概率覆盖了增生性息肉、腺瘤性息肉可能细分为管状腺瘤、绒毛状腺瘤等、锯齿状病变、炎症性息肉以及腺癌等典型类型。注意这只是背景知识的合理推测解压后第一时间打开classes.txt或data.yaml以里面的实际标注为准。医疗数据最忌讳先入为主类别名称对不上会让你后面整个训练流程白跑。关于规模10725张在医疗影像AI领域属于什么水平横向对比一下很多公开的医学检测数据集集中在几千张的量级上万张且带6类精细标注的并不多。这个体量足够训练一个可以跑通验证流程的YOLO模型作为预训练基础或学术论文实验也够用。但要清楚一点医疗场景的规模重点从来不是“绝对数量”而是“病变多样性”和“标注一致性”。同一类息肉在不同内镜设备、不同光照条件、不同医生操作习惯下视觉差异非常大。所以拿到数据后先别急着训练花时间做统计分析才是正经事。2. 数据集结构和格式深度拆解2.1 目录结构与文件组织7z压缩包解压后目录通常是这类结构rectal_polyp_dataset/ ├── images/ │ ├── train/ │ │ ├── 000001.jpg │ │ ├── 000002.jpg │ │ └── ... │ ├── val/ │ └── test/ ├── annotations/ │ ├── voc/ │ │ ├── 000001.xml │ │ ├── 000002.xml │ │ └── ... │ └── yolo/ │ ├── 000001.txt │ ├── 000002.txt │ └── ... ├── classes.txt └── data.yaml当然实际命名可能有差异有的数据会把VOC的xml和YOLO的txt分开放也有的把images和annotations混在一起。拿到手先跑一条tree命令把结构梳理清楚别急着写代码。这里有个容易踩的坑YOLO格式的训练通常要求“图像和同名txt标注文件放在同一个目录或者通过data.yaml里的路径字段分别指定”。如果你发现images目录下面没有对应的txt文件那就需要自己在yaml配置里分别指向images和labels两个根目录ultralytics支持这种写法path: /path/to/rectal_polyp_dataset train: images/train val: images/val nc: 6 names: [class0, class1, class2, class3, class4, class5]names列表的顺序非常关键。YOLO格式的txt文件里每一行开头的数字是类别索引这个索引直接对应names数组的位置。如果数据集自带的classes.txt顺序和你写的names不一致那整个训练就是白忙。2.2 VOC标注格式解析PASCAL VOC格式是目标检测领域最经典的标注格式之一核心是一个XML文件对应一张图片。里面记录了图像路径、尺寸、通道数以及每一个目标的类别名称和边界框坐标annotation folderimages/folder filename000001.jpg/filename size width1920/width height1080/height depth3/depth /size object nameadenomatous_polyp/name bndbox xmin320/xmin ymin240/ymin xmax780/xmax ymax690/ymax /bndbox /object /annotationVOC的坐标是绝对值单位是像素不依赖图像尺寸。好处是对人类阅读极其友好用标注工具打开就能直接对应坏处是训练前往往要转换成相对坐标或归一化坐标。而且XML文件携带了path、folder等无关信息不同标注工具的细节差异很大实际解析时不能假设字段一定存在。用Python读取VOC标注非常容易我习惯用xml.etree.ElementTree不需要额外依赖import xml.etree.ElementTree as ET def parse_voc(xml_path): tree ET.parse(xml_path) root tree.getroot() size root.find(size) img_w int(size.find(width).text) img_h int(size.find(height).text) objects [] for obj in root.iter(object): name obj.find(name).text bndbox obj.find(bndbox) xmin float(bndbox.find(xmin).text) ymin float(bndbox.find(ymin).text) xmax float(bndbox.find(xmax).text) ymax float(bndbox.find(ymax).text) objects.append({ name: name, bbox: [xmin, ymin, xmax, ymax] }) return img_w, img_h, objects2.3 YOLO标注格式解析YOLO格式是目前yolo系列训练框架的标准输入格式。每一张图片对应一个同名txt文件每行代表一个目标格式为class_id x_center y_center width height注意这5个数全部是归一化后的相对值范围通常在0到1之间。x_center和y_center是边界框中心点的相对坐标width和height是框的宽高除以图像宽高。归一化的目的是让标注与图像分辨率解耦训练时无论模型喂入640x640还是1280x1280坐标系都保持一致。把VOC转YOLO就是小学四则运算x_center (xmin xmax) / 2 / img_w y_center (ymin ymax) / 2 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h反过来把YOLO转VOC也不难xmin (x_center - w / 2) * img_w ymin (y_center - h / 2) * img_h xmax (x_center w / 2) * img_w ymax (y_center h / 2) * img_h这里有个很隐蔽的坑YOLO格式要求类别索引是0到nc-1的整数。如果classes.txt里第一行是“adenomatous_polyp”那它的索引就是0。假如你沿用VOC里的字符串名称去匹配而不先做编码映射解读出来的每一行类别都是错的。3. 数据集的准备与预处理实战3.1 解压与目录规划7z格式压缩率高但跨平台解压稍微有点讲究。Linux环境先确保装了p7zipsudo apt update sudo apt install -y p7zip-full 7z x 直肠息肉病变检测数据集VOCYOLO格式10725张6类别.7zWindows下直接用7-Zip或Bandizip右键解压基本没坑。解压之后我强烈建议先做两件事第一用脚本统计每个类别的目标数量看看是否存在极端不均衡第二随机抽样20个图把标注框画上去人工确认检查VOC和YOLO两套标注是否对同一张图描述一致。这两步看似简单但能筛掉80%以上后续训练阶段的低级问题。花了半小时做数据体检比后面训练三天发现metric崩了再回头查数据要划算得多。3.2 标注文件读取与检查脚本我习惯把数据检查写成一个小脚本每次拿到新数据集先跑一遍。核心是确认三件事图片能正常打开、尺寸和标注尺寸匹配、边界框没有越界。import os from PIL import Image def check_yolo_labels(img_dir, label_dir): issues [] for img_name in os.listdir(img_dir): if not img_name.endswith(.jpg): continue stem os.path.splitext(img_name)[0] img_path os.path.join(img_dir, img_name) label_path os.path.join(label_dir, stem .txt) with Image.open(img_path) as im: w, h im.size if not os.path.exists(label_path): issues.append((img_name, missing label)) continue with open(label_path, r) as f: lines f.read().strip().splitlines() for line in lines: parts line.split() cls_id int(parts[0]) xc, yc, bw, bh map(float, parts[1:]) xmin (xc - bw / 2) * w ymin (yc - bh / 2) * h xmax (xc bw / 2) * w ymax (yc bh / 2) * h if xmin 0 or ymin 0 or xmax w or ymax h: issues.append((img_name, box out of range, line)) return issues越界是很常见的问题通常出现在标注对象紧贴图像边缘时也有一部分是格式转换过程中浮点精度丢失造成的。越界框在训练中会干扰anchor匹配导致检测头收敛异常必须处理掉或裁剪进图像范围内。3.3 数据集划分与增强策略如果压缩包里面没有划分train/val/test那就要自己做。常规划分是7:2:1随机打乱后切分。但医疗数据场景里有个额外的注意点如果同一病人有连续多张内镜图像直接随机划分容易造成数据泄露训练和验证集里出现相似度极高的画面验证指标虚高。这个数据集发布方如果已经做了序列去重那就直接用如果没有你只能根据文件名前缀和图片内容先粗略聚类再划分。划分脚本可以这样写import os, random, shutil random.seed(42) img_dir images/all train_dir images/train val_dir images/val os.makedirs(train_dir, exist_okTrue) os.makedirs(val_dir, exist_okTrue) imgs [f for f in os.listdir(img_dir) if f.endswith(.jpg)] random.shuffle(imgs) n len(imgs) train_imgs imgs[:int(n * 0.7)] val_imgs imgs[int(n * 0.7):int(n * 0.9)] for f in train_imgs: shutil.move(os.path.join(img_dir, f), os.path.join(train_dir, f)) for f in val_imgs: shutil.move(os.path.join(img_dir, f), os.path.join(val_dir, f))数据增强方面内镜图像有其特殊性。常规的随机翻转、平移、缩放、颜色抖动都可以用但要注意不要做过于剧烈的几何扰动因为息肉在真实内镜画面中的尺度、旋转角度都有生理约束旋转超过30度基本脱离实际。推荐的增强组合是水平翻转概率0.5、轻微缩放0.8到1.2倍、HSV色域微调饱和度±20%、轻微噪声。4. 基于YOLOv8的训练与评估4.1 环境与配置文件这个数据集既然直接提供YOLO格式最方便的路线就是用它跑ultralytics的YOLOv8或YOLO11。pip install ultralytics然后准备一个data.yaml。注意路径最好填绝对路径训练时相对路径容易因为工作目录不对而报错找不到图片path: /data/rectal_polyp_dataset train: images/train val: images/val test: images/test nc: 6 names: [hyperplastic_polyp, tubular_adenoma, villous_adenoma, sessile_serrated_lesion, inflammatory_polyp, adenocarcinoma]names的顺序一定和classes.txt保持一致。这也是为什么我前面反复强调先打开classes.txt看一眼越早确认越省事。4.2 训练策略与关键参数训练命令一句话能启动yolo detect train datadata.yaml modelyolov8n.pt epochs150 imgsz640 batch16 patience30但参数值得再抠一抠。医疗检测里病变区域往往在图像中占比很小属于典型的小目标问题。如果有条件imgsz提高到960甚至1280对小息肉检出有明显帮助。代价是显存占用大增AMD RX 580这种8GB级别显卡跑640输入都吃力更别说960了老老实实用yolov8n配合batch8。学习率方面用默认值0.01起步问题不大。如果出现loss震荡或nan优先把lr降到0.001再检查标签是否有异常值。预训练权重选择yolov8n.pt还是yolov8s.pt取决于你的算力和对精度的要求。n最快但精度一般s在医疗数据上通常能比n高出2到3个点的mAP代价是训练时间大约翻倍。类别不平衡是这个数据集需要留心的核心问题。如果统计发现前两个类别占了80%的目标模型很容易偏向高频类别。对策有三个一是使用带权重的损失函数二是对低频类别做过采样三是在评估时多关注per-class AP而不是只看整体mAP。ultralytics默认输出每个类别的AP这是最直接的观察入口。4.3 评估指标与部署建议训练完成后官方命令直接出指标yolo detect val modelruns/detect/train/weights/best.pt datadata.yaml重点看mAP50和mAP50-95。医疗检测场景中mAP50-95比单一阈值下的mAP50更有参考价值因为它要求模型在不同IoU阈值下都有稳定输出更能反映框的定位精度。如果mAP50尚可但mAP50-95偏低说明框的定位不够准常见原因是标注框本身边界模糊、训练时在坐标回归上欠拟合。这种情况下可以尝试多训练一些epoch或者检查数据增强是否过于剧烈。推理部署就相当简单了yolo detect predict modelbest.pt sourcetest.jpg conf0.25 iou0.5医疗场景的置信度阈值要谨慎设置。偏低的conf比如0.1会输出很多低置信度框漏检少但误检多偏高的conf比如0.5则相反。实际使用中建议在验证集上画conf-threshold曲线找一个precision和recall平衡的点。5. 实际踩坑记录与避坑清单5.1 常见问题速查表跑数据集训练时最容易撞上的问题我整理成一张表现象可能原因解决办法训练时loss直接nan学习率过大、标签出现越界或nan降低lr至0.001检查txt标注内容一个epoch训练极慢图像分辨率过大、batch过大降低imgsz减小batch开启半精度验证集某类AP为0该类别样本过少或标注错误检查该类的样本数量和质量考虑过采样框的位置偏得离谱类别id与names顺序错位核对classes.txt与data.yaml的names顺序CUDA out of memorybatch或imgsz超显存减小batch或使用梯度累积策略训练集loss很低验证集很差过拟合增加数据增强使用patience早停关于显存还提一嘴AMD显卡。YOLOv8的官方实现主要面向NVIDIA生态RX 580跑起来默认用CPU或需额外配置DirectML分支别指望开箱即用。5.2 关于医疗数据集的几点提醒使用这份数据集有几件技术之外但非常重要的事必须说清楚。第一医疗数据涉及患者隐私和伦理合规。数据集发布方如果明确开源可用那在授权范围内做科研和学术验证没有问题但如果发布信息模糊先找发布文档确认授权条款不要默认可以商用。数据训练出的模型只应作为辅助研究工具不能直接作为临床诊断依据更不能替代医生判断。第二类别定义以标注文档为准不要套用自己经验里的病理分类。不同团队对这6类的定义粒度可能不同标注标准不同会直接影响模型的边界学习。第三内镜图像具有明显的数据域特征不同厂商设备、不同分辨率、不同光照条件都可能造成domain gap。用这份数据集训练的模型换到另一批内镜图片上性能大概率会显著下降。这并不代表训练有问题而是医疗影像的常见现象。缓解办法是后续用新场景数据做fine-tune或者使用域适应技术。最后再分享一个偏实践的小技巧拿到压缩包后不要修改原始标注文件的字段顺序不管是VOC的XML还是YOLO的txt都原样保留。很多转换脚本对格式是敏感的一个不起眼的空格差异可能让解析器读错字段而且这种错非常难查。做个备份目录原始数据永远不动所有预处理都写脚本生成新目录这样无论后面哪里出了问题都能快速定位是不是转换过程引入的bug。我在实际整理这类数据时还有一个习惯把每个类别的样本数、平均目标数量、平均框面积占比先统计出来画个图贴到项目文档里。这个看似简单的动作在写论文和向团队汇报数据质量时能省大量口舌也能帮自己快速发现数据分布异常。做医疗AI数据整理和模型训练至少是五五开的时间投入别觉得画框、检查、统计是杂活这恰恰是整个项目最有价值的地基。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进