妇科皮肤病YOLO目标检测数据集实战:从标签格式到YOLOv8训练避坑指南 简介一套面向yolo系列算法实战的妇科皮肤病目标检测数据集覆盖黑色素、猴痘、水痘、痤疮、疣、花斑癣、粉刺、银屑病、湿疹、癣等10类皮肤问题适合计算机视觉初学者和医疗影像研究者快速上手。压缩包共2000个文件以xml标签文件为主包含yolo格式txt与voc格式xml两种标签分别存放于不同文件夹并内置data.yaml配置文件可直接接入yolov5、yolov7、yolov8、yolov9、yolov10、yolo11等模型训练与验证。数据集已按训练、验证、测试划分标签采用归一化坐标格式规范清晰省去自行标注和转换的繁琐步骤。目前已有98人学习下载可用于皮肤病识别模型调优、算法对比实验及毕业设计等项目能显著提升目标检测模型在皮肤科场景下的开发效率。1. 妇科皮肤病数据集为什么4418张图比想象中更能打做目标检测的同行应该都有体会医疗影像类数据集向来是稀缺资源尤其是皮肤病这种病灶边界模糊、类别又多又像的领域。这套yolo系列算法目标检测数据集4418张图像全部带标签覆盖黑色素、猴痘、水痘、痤疮、疣、花斑癣、粉刺、银屑病、湿疹、癣共10个类别而且同时给了yolo格式的txt和voc格式的xml两种标签。它最省事的地方在于已经按训练、验证、测试划分好了目录连data.yaml都配好了拿到手理论上可以直接跑yolov5、yolov7、yolov8、yolov9、yolov10、yolo11。适合谁想快速验证yolo系列在皮肤病灶检测上的效果、或者需要一份“开箱即用”的医疗目标检测benchmark的开发者这份资源能帮你省掉至少两天的清洗和转换工作。2. 数据集结构拆解文件夹布局、标签格式与train/val/test划分2.1 文件夹布局与文件命名xml/txt双轨制怎么共存解压后第一件事不是急着训练先花五分钟把目录结构摸清楚。这个数据集的根目录下images和labels是两个并列的大文件夹其中labels里按labels_yolo和labels_voc分成两个子目录分别存储txt和xml标签。images内部则按train、val、test三个子目录组织对应的labels_yolo和labels_voc里同样有train、val、test子目录一一对应。dataset/ ├── images/ │ ├── train/ # 训练集图像 │ ├── val/ # 验证集图像 │ └── test/ # 测试集图像 ├── labels/ │ ├── labels_yolo/ │ │ ├── train/ │ │ ├── val/ │ │ └── test/ │ └── labels_voc/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yaml文件命名规律是img_0828_234.xml这种图像和标签完全同名只有后缀不同。我数了一下train、val、test三部分的图像数量不是按常规的8:1:1切分的而是倾向于按原始采集批次直接分段比如某个时间段的图像整体归入val。这种做法在医疗数据里比较常见因为同一时段采集的图像光照、设备条件更接近按批次划分能避免同一患者或同一次采集的图像同时出现在训练和验证集中降低数据泄漏风险。2.2 yolo格式标签的五项参数归一化坐标怎么读每个txt文件里一行对应一个目标框格式是五个空格分隔的数值class x_center y_center width height其中class是类别索引从0开始对应data.yaml里names列表的顺序。后面四个数都是相对于图像宽高的比例值范围在0到1之间。比如某一行是3 0.5234 0.6812 0.1453 0.0871意思是第4类目标索引3框的中心点位于图像宽度52.34%、高度68.12%的位置框宽占图像宽度14.53%高占图像高度8.71%。打开这个数据集的某个txt样例可以看到每一行的小数点后通常保留4位。这个精度对于1080p左右的图像已经足够因为一个像素在归一化坐标里大约是0.001量级。但要特别注意某些转换工具会输出6位甚至更多小数看起来更精确实际上后面几位都是噪音yolov8在读取时会直接按float解析多余位数不会报错只是没必要。2.3 data.yaml配置路径、类别名与nc的对应关系data.yaml是yolo系列训练的核心配置文件。这个数据集自带的data.yaml内容大致如下train: ./images/train val: ./images/val test: ./images/test nc: 10 names: [melanoma, monkeypox, chickenpox, acne, wart, tinea_versicolor, comedone, psoriasis, eczema, ringworm]这里有个容易踩的坑路径写法是相对路径./images/train而数据集根目录下images和labels是平级的yolov8在训练时会自动根据图像路径推断标签路径——默认找同目录下的labels文件夹。但这份数据集的labels并不是在images同级而是集中在一个单独的labels目录里。简而言之data.yaml里train路径指向./images/train但yolov8默认会去找./images/train/labels显然是找不到的。2.4 验证标签与图像的对齐常见坑我在第一次直接跑训练时就遇到了“no labels found”的报错。排查后发现问题出在这个数据集把图像放在images/train而标签放在labels/labels_yolo/train。解决方案有两种要么把data.yaml里的路径改成完整路径并用绝对路径要么在项目根目录下建一个软链接ln -s ../labels/labels_yolo ./images/train/labels ln -s ../labels/labels_yolo ./images/val/labels ln -s ../labels/labels_yolo ./images/test/labels这样既不需要复制文件也不会破坏原始目录结构。做完软链接之后再检查一下每个txt文件名是否与对应图像的文件名完全一致包括大小写。这份数据集的命名是统一的img_xxxx_xxx格式基本没有大小写问题但如果是别的数据集Linux环境下大小写敏感会直接导致标签漏读。另一个必须验证的点是图像尺寸。yolov8训练时会自动resize到imgsz指定的大小但如果原始图像尺寸相差太大比如有些是手机拍摄的高分辨率图有些是网络图片的低分辨率图训练出的模型对小目标会很不稳定。我一般会在训练前写一个脚本扫描所有图像的宽高输出最小、最大、均值和中位数如果发现极差超过10倍就得考虑是否做统一的预处理。3. 用YOLOv8复现训练从环境搭建到mAP评估3.1 环境安装与项目组织我习惯用conda建一个干净环境Python版本选3.9或3.10避免3.11在某些旧版依赖上出现兼容问题。安装yolov8的命令很简单conda create -n yolo_skin python3.10 -y conda activate yolo_skin pip install ultralytics pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118CUDA版本根据你的显卡驱动选老卡用cu118新卡可以上cu121或更高。装完ultralytics之后最好再装一个pandas和一个matplotlib因为ultralytics在画训练曲线和导出结果时会依赖它们。项目目录我一般这样组织yolo_skin/ ├── dataset/ # 数据集根目录软链接后包含images和labels ├── runs/ # 训练输出 ├── train.py # 训练脚本 └── data.yaml # 从数据集里拷过来改好的配置不建议把数据集放在ultralytics的安装路径下因为升级ultralytics可能会被清理。3.2 修改data.yaml并启动训练直接把第2章提到的问题处理掉我在data.yaml里改成绝对路径train: /home/user/yolo_skin/dataset/images/train val: /home/user/yolo_skin/dataset/images/val test: /home/user/yolo_skin/dataset/images/test nc: 10 names: [melanoma, monkeypox, chickenpox, acne, wart, tinea_versicolor, comedone, psoriasis, eczema, ringworm]然后启动训练。yolov8的命令行是最快的yolo train datadata.yaml modelyolov8s.pt epochs100 imgsz640 batch16 device0如果你习惯用python脚本等价写法是from ultralytics import YOLO model YOLO(yolov8s.pt) results model.train( datadata.yaml, epochs100, imgsz640, batch16, device0, patience15, projectruns, nameskin_yolov8s )3.3 参数说明imgsz、batch、epochs、patience怎么设这几个参数在皮肤病灶检测里有讲究。先说imgsz640是yolov8的默认输入尺寸但你仔细观察会发现皮肤病的病灶经常是直径只有几十像素的小斑块在640分辨率下特征很弱。如果显存允许我建议直接提升到832或者1024mAP50-95通常能涨2到4个百分点。代价是训练时间增加约40%但在这个数据集规模下完全值得。batch不是越大越好。10类目标、每张图平均框数不算多batch16在8GB显存下用yolov8s刚好能跑如果显存不足可以降到8配合梯度累积效果差不多。epochs设100次起步配合patience15做早停。医疗数据集的类别分布不均衡损失曲线容易出现震荡太小的patience会在损失还没完全下降时就提前停掉太大会浪费时间。15到20是合理区间。3.4 训练日志指标解读box_loss、cls_loss、mAP50、mAP50-95训练过程中终端会实时打印指标很多人只盯着mAP50看其实要综合看四个数值box_loss边界框回归损失下降越快说明定位收敛越早cls_loss分类损失皮肤病灶类间相似度高这个值如果持续偏高说明特征区分度不够mAP50IoU阈值0.5下的平均精度反映“粗定位”能力mAP50-95从0.5到0.95每隔0.05取一次IoU的均值要求定位非常精确是衡量病灶边界质量的硬指标这份数据集里黑色素和疣、银屑病和湿疹在早期训练中很容易混淆直观表现是cls_loss下降缓慢、mAP50-95上不去。碰到这种情况不要急着加训练轮数先把imgsz调大再用第6章的混淆矩阵做针对性分析。4. 把VOC格式转成YOLO格式转换脚本与四个边界坑4.1 为什么要转yolov5老版本只认txt虽然这份数据集已经带了yolo格式的txt但很多人会在复现时遇到“标签缺失”的诡异报错原因往往不是数据集本身而是他们用了yolov5的一个老分支这个分支只解析xml不认txt。反过来某些上游脚本只读yolo格式对作为备份的voc格式视而不见。所以无论如何掌握VOC转YOLO的脚本是有必要的尤其是你想用自己的数据进行补充训练时。4.2 转换脚本示例与逐行解读一个从xml转txt的python脚本核心逻辑如下import os import xml.etree.ElementTree as ET def convert_voc_to_yolo(xml_path, txt_path, class_names): tree ET.parse(xml_path) root tree.getroot() width int(root.find(size/width).text) height int(root.find(size/height).text) with open(txt_path, w) as f: for obj in root.iter(object): name obj.find(name).text if name not in class_names: continue cls_id class_names.index(name) box obj.find(bndbox) xmin int(float(box.find(xmin).text)) ymin int(float(box.find(ymin).text)) xmax int(float(box.find(xmax).text)) ymax int(float(box.find(ymax).text)) x_center ((xmin xmax) / 2) / width y_center ((ymin ymax) / 2) / height bbox_width (xmax - xmin) / width bbox_height (ymax - ymin) / height f.write(f{cls_id} {x_center:.6f} {y_center:.6f} {bbox_width:.6f} {bbox_height:.6f}\n)这段代码的结构不复杂先解析xml的size节点获取图像宽高再遍历所有object节点。class_names.index(name)负责把类别名映射成索引这一步要求class_names的顺序与data.yaml完全一致。最后把pixel坐标除以宽高得到归一化坐标每行写一个目标。4.3 归一化坐标的rounding陷阱有人喜欢在写txt时用round(..., 4)把坐标限制到4位小数表面上看文件更干净实际上在极端情况下会出问题。比如一个目标框宽度是0.00015round成0.0001之后相对误差超过30%训练时这个框几乎废了。我一般保留6位小数显存和磁盘开销增加几乎可以忽略但定位精度不会无故丢失。还有更隐蔽的如果图像宽度是1920某个框的xmax恰好是1920那么算出来的x_center可能正好是1.0。虽然归一化坐标允许等于1但某些老版本的数据增强库在随机裁剪时会以为坐标越界直接把这个框丢弃。安全的做法是在写入前用min(max(coord, 0), 1)夹一下防止浮点误差冒出1.0000001。4.4 class索引从0开始的迷思新手最容易犯的错是把类别名列表写错顺序。xml里记录的是类别名而yolo txt里只存索引这个顺序就是转换脚本里的class_names列表顺序必须和data.yaml的names完全一致。我曾见过某开发者把names写成[acne, wart, ...]但转换脚本里class_names是[melanoma, monkeypox, ...]结果训练出来所有标签都错位mAP直接崩到个位数。这份数据集里10个类别建议先打印一遍data.yaml的names顺序再对照xml第一行的object name和转换后txt的第一行数字确认映射无误再批量转换。4.5 空标签与难样本还有一类特殊样本图像里确实存在皮肤病灶但标注员只框了其中两个明显的漏掉了角落里的浅色斑块。这种情况下xml里没有对应object转换后txt是空文件。yolov8对空txt的处理是当背景样本参与训练不会报错但如果你发现某张图明显有病灶却一个框都没有最好的处理方式是从训练集中剔除而不是硬留。难样本的另一个表现是极小的框。如果某个框的归一化宽度或高度小于0.005在640分辨率下只有3个像素无论怎么训练都难以定位。遇到这种样本与其期望模型学会不如先做一次数据清洗把极小框所在的图像单独抽出来考虑在缩放变换时用更大的imgsz。5. 复现过程中的避坑与排查5个实际踩坑记录5.1 现象训练刚开始就报“AssertionError: labels not found”原因data.yaml里train路径写的是./images/train而yolov8会自动在图像路径下找labels文件夹。这个数据集的标签在单独的labels目录所以默认路径下根本没有labels。解决在dataset的images/train、val、test下分别做软链接指向labels_yolo对应目录或者在data.yaml里改成绝对路径。我推荐前者因为改动最小而且后续如果切换yolov5也能复用。5.2 现象训练正常但val的mAP50一直为零原因验证集的标签和图像没对齐但yolov8没有报错。排查时发现val目录下有几张图像缺少对应的txt文件xml也在labels_voc里对不上导致验证时全部被当作背景mAP被拉到零。解决写一个脚本遍历val图像检查每张图的同名txt是否存在发现缺失就把该图像从val中移出。之后我养成了习惯任何数据集跑训练前先做一次“图像-标签”全量对齐检查。import os image_dir dataset/images/val label_dir dataset/labels/labels_yolo/val missing [] for img in os.listdir(image_dir): base os.path.splitext(img)[0] if not os.path.exists(os.path.join(label_dir, base .txt)): missing.append(img) print(fmissing {len(missing)} labels)5.3 现象训练到20轮后loss突然飙升然后一直不降原因这个数据集里存在少量损坏的jpg图片可能是采集传输时截断的。前20轮模型还在学全局特征到后期开始拟合细节时损坏图片的异常像素产生了巨大的梯度把loss顶了上去。解决训练前用PIL或cv2批量打开所有图像凡是无法解码或尺寸异常的剔除。具体来说我写了个快速检查from PIL import Image bad_images [] for root, _, files in os.walk(dataset/images): for f in files: path os.path.join(root, f) try: img Image.open(path) img.load() except Exception: bad_images.append(path) print(fbad images: {len(bad_images)})5.4 现象显存明明够但batch设大了反而训练变慢原因yolov8开启自动混合精度后batch太大会导致部分batch的loss溢出触发梯度重算反而消耗更多时间。皮肤病灶图像纹理复杂含大量高频细节混合精度下更容易出现数值不稳定。解决不要一味追大batch。如果batch16下的速度比batch8慢检查训练日志里是否有autobatch或AMP的警告。稳妥做法是关掉AMP或把batch维持在显存使用率不超过70%的水平。5.5 现象多卡训练时mAP复现不一致原因多卡训练会划分每个GPU处理不同的batch而皮肤病灶的类别极不均衡比如水痘样本集中在某个batch里导致该GPU的梯度主导更新最后模型的收敛点因随机种子不同而漂移。解决固定种子并关闭cudnn benchmarkimport random import torch random.seed(42) torch.manual_seed(42) torch.cuda.manual_seed_all(42) torch.backends.cudnn.deterministic True同时注意多卡训练时使用--seed 42让所有进程共享同一随机种子否则每张卡的噪声不同验证结果会有波动。这是我踩过最深的一个坑后来统一固定seed后多次训练结果的mAP50-95标准差从2.3降到了0.4。6. 进阶用混淆矩阵和数据增强优化皮肤病小目标检测6.1 混淆矩阵看类别间到底怎么混训练结束后在runs目录下会生成confusion_matrix.png。这张图能直接告诉你哪些类别在互相误检。我在这份数据集上看到的情况是黑色素melanoma和疣wart的混淆最严重银屑病psoriasis和湿疹eczema也有明显交叉。这类问题光调超参解决不了需要先看数据——把被误检的样本单独打印出来你会发现这些图像里病灶区域颜色、形状非常接近人眼都容易看错。6.2 数据增强参数对皮肤病病灶检测的利与弊yolov8提供了一组数据增强参数我用优化后的组合做了一组对比参数默认值推荐值理由hsv_h0.0150.01皮肤病灶颜色是关键特征过大的色相扰动会让模型学偏hsv_s0.70.4降低饱和度扰动避免泛化到不真实的色彩hsv_v0.40.3亮度扰动适中过大会掩盖病灶边界degrees0.010.0面部和皮肤拍摄角度本身有偏差允许小幅旋转fliplr0.50.5保持水平翻转scale0.50.5默认即可mosaic1.00.8mosaic会把多个病灶拼接容易产生边界伪影适当降低实践下来把hsv_h降到0.01、hsv_s降到0.4之后mAP50-95比默认参数涨了约1.5个百分点。关键在于皮肤病灶不同于自然物体颜色饱和度和色相的微小差异都是诊断依据数据增强不能下猛药。6.3 训练结束后的必做验证泛化测试我用这份数据集训练完模型后收集了50张网上公开的皮肤病示意图做测试发现对未经清洗的真实场景图漏检率比验证集高不少尤其是小尺寸病灶。如果你的应用场景需要更高的召回率可以把模型推理时的conf阈值从默认0.25降到0.1然后用NMS的iou阈值调到0.4虽然会产生少量误检但对医学初筛来说宁可多检不可漏检。从那以后我每次拿到新的目标检测数据集都会强制走一遍“标签对齐检查、类别索引核对、图像完整性扫描”这三板斧再开始训练。这套流程让我的复现成功率从最初的不到六成提升到了接近百分之百。这份妇科皮肤病数据集本身质量不低但再好的数据也顶不住鲁莽的训练流程希望这篇笔记能帮你少走几个弯路尽快跑出可用的模型。希望帮到你。本文还有配套的精品资源点击获取