简介:本资源为面向皮肤疾病检测的YOLO系列目标检测数据集,适合医学图像识别方向的算法学习者与研究人员使用,可解决白癜风、皮炎、黄褐斑三类皮肤病灶的检测训练与验证需求。压缩包共334个文件,包含111张jpg图像、111个txt标签、111个xml标签及1个data.yaml配置文件,整体约4MB,已按训练与验证划分完毕,可直接投入模型训练。标签同时提供YOLO格式与VOC格式两套,YOLO格式采用归一化中心点与宽高比例,便于适配yolov5、yolov8、yolov9、yolov7、yolov10及yolo11等主流算法。目前已有160人学习下载,读者可借助该数据集快速搭建皮肤病灶检测实验,验证模型在小样本医学图像上的表现,并对比不同YOLO版本的检测精度与推理效率,为后续调参与改进提供可靠基线。
1. 111 张皮肤镜图像带标签:这份 YOLO 数据集到底能跑出什么
手上有一批皮肤疾病图像,想快速验证一个检测想法,却卡在标注和格式转换上——这大概是很多做医学图像方向的人都会遇到的局面。这份资源就是冲这个场景来的:111 张皮肤镜图像,覆盖白癜风、皮炎、黄褐斑三类皮肤问题,每张图都配好了标注,YOLO 格式的 txt 和 VOC 格式的 xml 各存一份,还附带了划分好的数据集配置 data.yaml。它不解决“模型精度能不能上临床”这种问题,它解决的是“我今晚能不能把训练脚本跑起来、明天能不能看到第一版检测结果”。适合两类人:一类是刚接触 YOLO 目标检测、想拿真实医学图像练手的新手;另一类是有自己的算法框架、需要一个干净小数据集做消融或流程验证的熟手。111 张这个量级,别指望训出生产级模型,但用来打通“数据加载→训练→验证→推理”整条链路,足够了。
2. 数据集结构与 YOLO 标签格式:先看懂再动手
2.1 目录组织与两种标签格式的取舍
拿到压缩包解压后,常见做法是看到 images 和 labels 两个主目录,labels 下面再分 YOLO 格式和 VOC 格式两个子文件夹。YOLO 格式每个 txt 对应一张图,VOC 格式每个 xml 对应一张图。这里有个选型问题:如果你用 YOLOv5 到 YOLO11 这一系,直接走 txt;如果你要接 MMDetection 或者某些老检测框架,xml 更省事。两种格式表达的是同一批标注框,只是坐标系和存储方式不同。
YOLO 格式每行是<class> <x_center> <y_center> <width> <height>,五个值空格分隔。class 是从 0 开始的类别索引,后四个都是归一化到 0 到 1 的比例值,不是像素。这一点新手最容易翻车:把像素坐标直接写进去,训练时 loss 不降,框全飘到图像角落。VOC 格式则是绝对像素坐标,xmin、ymin、xmax、ymax,外加类别名。两种格式之间可以互转,但转换时归一化那一步必须用对应图像的真实宽高,不能拍脑袋填 640。
三类皮肤问题在标注上有个现实差异:白癜风通常边界相对清晰,黄褐斑往往弥散、边界模糊,皮炎可能呈现多区域分布。这直接影响你后面看标注框时的心理预期——黄褐斑的框可能偏大、偏松,不是标注质量问题,是病灶本身特性决定的。
2.2 data.yaml 配置与类别映射
data.yaml 是 YOLO 系列训练的入口配置,结构一般长这样:
# data.yaml 典型结构,路径按你实际解压位置改 path: ./skin_dataset # 数据集根目录 train: images/train # 训练集图像相对路径 val: images/val # 验证集图像相对路径 nc: 3 # 类别数 names: # 类别名,顺序必须和标签里的 class 索引一致 0: vitiligo # 白癜风 1: dermatitis # 皮炎 2: chloasma # 黄褐斑这里的关键参数是 nc 和 names 的对应关系。names 里 0 号必须是标签里 class=0 的那个类别,顺序错一位,模型学到的就是错位的语义。我一般会先抽三张图,用脚本把 txt 里的 class 值读出来,和 names 对一遍再开训。path 字段在 YOLOv8 之后支持相对路径,但如果你在别的目录下执行训练命令,相对路径的基准是 data.yaml 所在位置,不是你的当前工作目录,这个细节坑过不少人。
提示:如果解压后发现 train 和 val 的划分比例和你想的不一样,别急着重新分。先看 data.yaml 里指向的目录实际有多少张图,111 张的体量,常见划分是 8:2 或 7:3,验证集太小会导致指标抖动大,这是数据量决定的,不是配置错误。
2.3 用脚本核对标签完整性
在开训之前,花两分钟跑一个核对脚本,比训到一半发现标签缺失要划算得多。下面这段读 images 目录,检查每张图有没有对应的 txt,并统计每个类别的框数量:
import os from pathlib import Path from collections import Counter img_dir = Path("./skin_dataset/images/train") lbl_dir = Path("./skin_dataset/labels/train") # YOLO 格式标签目录 missing, class_counter = [], Counter() for img_path in img_dir.glob("*.jpg"): lbl_path = lbl_dir / (img_path.stem + ".txt") if not lbl_path.exists(): missing.append(img_path.name) continue with open(lbl_path) as f: for line in f: line = line.strip() if line: cls = int(line.split()[0]) class_counter[cls] += 1 print("缺失标签的图:", missing) print("各类别框数量:", dict(class_counter))逻辑很直白:遍历训练集图像,按同名规则找 txt,找不到就记下来;找到就逐行读 class 索引并计数。参数上唯一要改的是 img_dir 和 lbl_dir 的路径,以及图像后缀——如果你的图是 png,glob 里换成 *.png。跑完看两个输出:missing 为空说明配对完整;class_counter 里三个类别的数量如果严重不均衡,比如某一类只有个位数框,那训练时这一类基本学不动,得考虑过采样或者调 loss 权重。111 张的规模下,类别不均衡是常态,提前知道比事后调参强。
3. 从零跑通 YOLOv8 训练:命令、参数与验证
3.1 环境准备与依赖版本
YOLOv8 及之后的版本统一走 ultralytics 这个包,安装比早期 YOLOv5 的 requirements 方式干净很多。我一般用 conda 起一个干净环境,避免和已有的 torch 版本打架:
conda create -n skin_yolo python=3.10 -y conda activate skin_yolo pip install ultralytics装完 ultralytics 会自动带上匹配的 torch 和 torchvision。这里有个版本边界要注意:YOLOv8 和 YOLO11 用同一套 API,YOLOv5 则是另一套仓库和命令行风格,别把 v5 的--img-size参数直接套到 v8 上,v8 里叫imgsz。如果你要跑 YOLOv9 或 v10,部分实现还在 ultralytics 的迭代分支里,建议先确认你装的版本支持哪个模型权重名,别拿着 yolov9.yaml 去一个只认 yolov8 的环境里跑。
验证环境是否就绪,一行命令就够:
yolo checks它会打印 torch 版本、CUDA 是否可用、以及当前 ultralytics 版本。CUDA 不可用的话训练会退回 CPU,111 张图在 CPU 上跑 100 轮大概要几十分钟到一小时,能忍但没必要,检查一下显卡驱动和 torch 的 CUDA 版本是否匹配。
3.2 训练命令与关键参数含义
数据配置和标签都核对过之后,训练命令本身很短:
yolo detect train \ data=./skin_dataset/data.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=8 \ lr0=0.01 \ patience=20 \ project=./runs_skin \ name=exp1逐项说参数。model=yolov8n.pt 用的是 nano 版预训练权重,111 张图这个量级,n 版足够,用 l 版反而容易过拟合。epochs=100 配合 patience=20,意思是验证指标 20 轮不提升就早停,小数据集上早停能省不少时间。imgsz=640 是默认输入尺寸,皮肤镜图像如果原始分辨率远大于 640,缩下来会丢细节,可以试 800 或 1024,但显存占用会涨。batch=8 是保守值,显存够可以往上加,不够就降到 4。lr0=0.01 是初始学习率,小数据集上如果 loss 震荡厉害,降到 0.001 试试。
训练过程中重点盯三个输出:box_loss、cls_loss 和 mAP50。box_loss 管框的位置,cls_loss 管分类,两个都降才是正常收敛。如果 box_loss 降但 cls_loss 不降,多半是类别标签有问题;如果两个都不降,先怀疑标签格式。mAP50 在 111 张的验证集上波动会比较大,别因为某一轮掉了就慌,看趋势。
3.3 验证与推理:确认模型真的学到了东西
训练完,权重默认存在 runs_skin/exp1/weights/best.pt。验证命令:
yolo detect val \ model=./runs_skin/exp1/weights/best.pt \ data=./skin_dataset/data.yaml \ imgsz=640它会输出每类的 precision、recall、mAP50 和 mAP50-95。小数据集上 mAP50 能到 0.5 以上就算这个流程跑通了,别拿它和公开大数据的指标比。推理单张图:
yolo detect predict \ model=./runs_skin/exp1/weights/best.pt \ source=./skin_dataset/images/val \ conf=0.25 \ save=Trueconf=0.25 是置信度阈值,低于这个值的框不输出。皮肤病灶边界模糊,阈值调高会漏检,调低会多出一堆重叠框,0.25 到 0.4 之间试几档,看哪个在你关心的类别上表现稳。结果图默认存到 runs/detect/predict 下,打开看框的位置和类别标签对不对,这一步比看指标数字更直观。
4. 避坑与排查:小数据集训练最容易翻车的五件事
4.1 现象:训练启动就报 “No labels found”
原因通常是 data.yaml 里的 train/val 路径写错,或者 labels 目录结构和 YOLO 预期的不一致。YOLO 默认按 images 和 labels 平行目录找标签,如果你的 txt 和 jpg 混在同一个文件夹,它就找不到。解决:确认目录是 images/train 配 labels/train 这种平行结构,路径在 data.yaml 里用相对路径时,基准是 yaml 文件所在目录。
4.2 现象:loss 一直是 nan 或者不下降
先查标签里的归一化值有没有超出 0 到 1。VOC 转 YOLO 时如果忘了除以图像宽高,坐标会是几百的像素值,模型直接崩。用 2.3 的核对脚本加一行判断,把 x_center 或 width 大于 1 的行打出来。另一个可能是学习率太大,lr0 从 0.01 降到 0.001 再试。
4.3 现象:某一类完全检测不出来
111 张图里如果某一类只有十几甚至几个框,模型学不到足够特征。先看 2.3 脚本输出的类别计数,确认不是标签 class 索引写错导致这一类根本没被标注。如果确实是样本少,常见做法是对这一类做离线增强,把图翻转、旋转、调亮度后连同标签一起复制几份,或者训练时用 copy_paste 这类增强策略。
4.4 现象:验证集 mAP 忽高忽低
验证集太小是主因。111 张按 8:2 分,验证集只有 20 多张,指标抖动是数学上的必然。别频繁根据单轮 mAP 调参,看多轮平滑后的趋势。如果一定要更稳的评估,可以做 k 折交叉验证,但小数据集上成本收益要自己权衡。
4.5 现象:推理时框的位置整体偏移
多半是训练和推理的 imgsz 不一致,或者图像在预处理时被拉伸而非等比例缩放。YOLO 默认做 letterbox 等比例填充,如果你自己写推理脚本时直接 resize 到 640x640,宽高比变了,框自然偏。解决:推理时也用 ultralytics 的 predict 接口,或者自己实现 letterbox 并正确反算坐标。
5. 小数据集的进阶玩法:增强、冻结与交叉验证
111 张图想榨出更多信息,光靠默认训练不够。我一般会做三件事。第一是开更强的增强,在训练命令里加augment=True并调hsv_h、hsv_s、flipud、fliplr这些参数,皮肤图像对颜色敏感,hsv_h 别调太大,0.015 左右,翻转可以放心开。第二是冻结主干先训几轮再解冻,用freeze=10冻结前 10 层,让小数据集先适配分类头,再整体微调,能缓解过拟合。第三是做一次 5 折交叉验证,把 111 张分成 5 份轮流做验证,虽然训练时间翻 5 倍,但得到的指标比单次划分可信得多,尤其你要拿这个结果写报告或做对比实验时。
验证模型有没有真的学到病灶特征,而不是记住了图像背景,有个土办法:把验证集里某张图的病灶区域裁掉,换成纯色块,再推理一次。如果模型还在原位置输出高置信度框,说明它学的是背景纹理而非病灶。这个测试不严谨,但能快速暴露问题。另一个习惯是每次改完 data.yaml 或标签,先跑 1 个 epoch 看 loss 有没有正常起步,再开完整训练。从那以后我每次拿到新数据集,都强制先跑核对脚本和单轮冒烟测试,再动正式训练命令。希望帮到你。
本文还有配套的精品资源,点击获取