ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

YOLO+VOC双格式脸部皮肤病数据集:从标注解析到训练实战

YOLO+VOC双格式脸部皮肤病数据集:从标注解析到训练实战 简介面向计算机视觉目标检测任务的脸部皮肤病数据集整合了粉刺、丘疹、结节、脓疱四类常见皮肤问题的矩形标注适用于医疗影像分析、皮肤病自动识别以及智能辅助诊断等场景也适合计算机视觉初学者与研究者用于训练YOLO、Faster R-CNN等主流目标检测模型。压缩包内共包含两千个文件以VOC格式的xml标注文件与YOLO格式的txt标注文件为主同时配套对应的脸部图像数据整体大小约为三十五点八九兆字节。数据集共计包含八千八百二十七个矩形标注框其中粉刺框三千八百七十五个、丘疹框三千零四十一个、脓疱框一千二百九十七个、结节框六百一十四个各类别样本量差异明显图片画面清晰且未做数据增强并提供了标准的VOC和YOLO目录结构可以直接用于模型训练与效果评估。目前已有四百九十三人学习浏览此数据集数据本身仅提供准确且合理的标注不附带训练得到的模型权重也不对精度作任何保证适合作为深度学习教学、算法竞赛以及科研项目的基础数据。 做计算机视觉这几年我接触过不少医疗相关的数据集但脸部皮肤病这一块资源一直很稀缺。大部分人能拿到的公开数据集要么是国际皮肤镜dermoscopy拍摄的放大图要么是全身皮损的远景照片真正适合做脸部局部病变检测、又带着完整检测框标注的少之又少。所以当我拿到这份1590张的YOLOVOC双格式脸部皮肤病数据集时第一反应不是又多了一个数据集而是这次终于能直接开箱训练了。它包含粉刺、脓疱、结节、丘疹四个类别覆盖了脸部皮肤问题中最常见的几种形态对想快速验证YOLO检测流程、又不想从零开始标注的人来说价值很高。这篇文章我会从数据本身、格式转换、训练配置到踩坑经验完整过一遍希望能帮你少走一些弯路。1. 先看清数据本身1590张图里到底有什么训练深度学习模型之前最忌讳的就是不看数据直接开跑。很多人在YOLO项目里翻车不是网络结构选错了而是根本不了解自己的数据集长什么样。这份数据集标注的是脸部皮肤病变目标小、背景复杂、类别之间长得像这几个特点几乎贯穿了整个训练过程。1.1 四类皮肤病变的判读逻辑数据集的四个类别分别是粉刺、脓疱、结节、丘疹。从医学角度来说它们都属于痤疮类皮损的不同表现形态但在图像上差异很大对检测算法来说是完全不同的挑战。粉刺comedone常见于T区表现为黑头或白头颜色与肤色接近边界模糊是小目标检测里最难的一类。丘疹papule直径通常小于5毫米微微隆起颜色偏红经常成片出现密集排列时很容易被模型当作同一个目标合并掉。脓疱pustule顶部有白色或黄色脓液中心高光明显对比度较高相对好检测但容易和丘疹混淆。结节nodule体积大、位置深通常直径超过5毫米数量少但特征鲜明是四类中最好识别的一类。四类病变在发病机制上同属痤疮谱系所以在标注边界和视觉外观上天然存在连续性。比如一个正在发展的结节初期可能看起来就是一颗大丘疹一颗发炎的粉刺又可能被标注成丘疹。这种类间相似性意味着模型不仅需要学会区分形状还要学会区分颜色、隆起程度、表面光泽等微妙特征。1.2 图片质量与标注的整体水平我实际解压之后发现这批图片的拍摄场景相对统一以脸部特写为主光照条件和肤色分布有一定多样性但整体比Web上随便爬来的杂乱图片干净得多。1590张图分布在四个类别上数量不是完全均匀的这在皮肤数据里很正常——结节本身就少见粉刺和丘疹才是绝大多数人脸上的常态。提示拿到任何数据集的第一步建议先把四类的标注框数量统计一遍。YOLO格式的txt文件里每个框一行写一个脚本把所有标注文件的行数按类别聚合立刻就能看出类别是否均衡、有没有标注文件为空的情况。这一步五分钟就能完成却能避免后续训练时出现严重的类别偏见。2. 为什么同时给YOLO和VOC两种格式一份数据两种用法很多公开数据集只给一种格式要么是VOC的XML要么是YOLO的txt。这份数据集两种都给看起来是好事但如果你不理解两种格式的差异直接用反而容易出问题。2.1 两种格式的核心差异VOC格式是XML文件一个标注文件对应一张图片每个目标用bndbox标签记录xmin、ymin、xmax、ymax是绝对像素坐标人可以直接读。YOLO格式是txt文件每行一个目标记录的是类别id x_center y_center width height坐标全部被归一化到0到1之间并且用的是中心点和宽高表示模型训练时读取效率高。我整理了一张对比表方便你直观理解对比维度VOC格式YOLO格式文件后缀.xml.txt坐标含义绝对像素坐标归一化中心点宽高可读性人类友好可直接查看机器友好需要换算常见配套框架Faster R-CNN、SSD等YOLO系列一个框的信息量类别名边界坐标类别编号归一化坐标说明一下YOLO格式里归一化的基准是图片的宽高公式是x_center (xmin xmax) / 2 / image_widthy_center (ymin ymax) / 2 / image_heightwidth (xmax - xmin) / image_widthheight (ymax - ymin) / image_height2.2 双格式的实际价值上游与下游的解耦训练检测模型前很多人会在标注工具和训练框架之间反复搬运数据。LabelImg默认输出VOC格式但Ultralytics YOLOv8要求YOLO格式第三方标注平台导出时又各有各的格式。一份数据同时保留VOC和YOLO相当于把数据维护和模型训练解耦了VOC格式作为人类可读的中间稿方便人工检查和修正YOLO格式作为训练的直接输入随时可以扔给模型跑。改标注时只维护一份另一个格式用脚本同步生成就行。这里也附一段我常用的VOC转YOLO脚本核心逻辑实际使用时只需要遍历XML文件、读取width和height、再按公式把四角坐标转成中心点表示即可。转换过程中务必保留原XML作为备份因为一旦txt写坏还能从XML恢复。3. 从解压到训练完整跑通YOLOv8的实际流程我建议直接把数据集按照YOLO生态的标准目录结构摆放不要自己发明目录格式这样后面无论是用Ultralytics还是其他框架都不用改代码。3.1 解压后的目录整理拿到zip压缩包后先在干净路径下解压。这里强调干净路径是因为后续训练时会遇到一个非常隐蔽的问题——路径里如果有中文、空格或过深嵌套ultralytics在读取数据集时偶发报错定位起来特别费时间。我习惯把所有数据集放在纯英文路径下比如D:/datasets/skin_disease/。推荐目录结构如下skin_disease/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── annotations/ # VOC XML文件单独存放便于人工审计 └── data.yaml如果数据集本身没有按train/val划分可以自己用脚本按8:1:1或9:0.5:0.5的比例做随机划分。注意划分时要保证同名图片和标注文件一起移动jpg的基线名要和txt/xml的基线名完全一致否则训练时找不到标注。3.2 校验标注与图片的对应关系很多人的第一版训练失败问题不是模型而是标注文件张冠李戴。YOLO训练时如果一张图片的txt缺失或文件名对不上程序通常只是跳过或者警告根本不会报错模型在缺标注的数据上默默学习最终mAP永远上不去。我在训练前习惯跑一个校验循环读取images目录下所有jpg文件逐个检查labels目录里是否存在同名txt同时检查txt里每一行的坐标是否都在0到1之间类别编号是否小于类别总数。如果发现异常直接打印文件名。import os img_dir D:/datasets/skin_disease/images/val label_dir D:/datasets/skin_disease/labels/val for img in os.listdir(img_dir): if not img.endswith(.jpg): continue name os.path.splitext(img)[0] label_path os.path.join(label_dir, name .txt) if not os.path.exists(label_path): print(f缺少标注文件: {name}) continue with open(label_path, r) as f: for line in f: parts line.strip().split() if len(parts) ! 5: print(f格式异常: {name} - {line}) continue cls_id int(parts[0]) coords list(map(float, parts[1:])) if cls_id not in [0, 1, 2, 3]: print(f类别编号越界: {name}) if any(c 0 or c 1 for c in coords): print(f坐标越界: {name} - {line})这段代码很简单但每次换新数据集我都会跑一遍能过滤掉大量低级错误。3.3 data.yaml的编写与训练参数YOLO系列的训练入口是data.yaml里面只需要写三件事训练集路径、验证集路径、类别名称列表。path: D:/datasets/skin_disease train: images/train val: images/val names: 0: comedone 1: papule 2: pustule 3: nodule注意names里的顺序必须和txt文件里的类别编号一一对应。这里最容易出问题的是编号错位——比如用labelimg标注时类别顺序可能和yaml不一致导致模型把粉刺学成了丘疹指标看起来还行实际推理一塌糊涂。训练参数方面以YOLOv8s为例我直接给一组可以跑通的基线配置yolo train modelyolov8s.pt datadata.yaml epochs120 imgsz640 batch16 patience20epochs设120配合patience20做早停防止过拟合。imgsz用640起步。脸部皮肤病目标小后面可以试960但显存占用会明显上涨。batch大小取决于显卡显存8GB显存跑yolov8s用16通常没问题6GB就降到8。4. 皮肤病检测的真正难点类间相似与目标密集训练跑通不难能收敛和能好用是两回事。皮肤病检测有三个很现实的难点你在迭代精度时必须正面处理。4.1 类间相似度的问题粉刺和丘疹、丘疹和脓疱之间视觉差异经常非常小。我在测试集上做过一次统计大部分错误预测都发生在相邻类别之间模型把大颗红丘疹识别成初期脓疱把带白点的闭合性粉刺识别成脓疱。这不是模型笨而是训练指令本身给的信息不够。提高类间区分度的方法有三个方向一是增加图像的细节分辨率也就是用更高的imgsz训练让纹理差异进入模型的视野二是做颜色归一化或对比度增强让红斑、脓点这些特征更突出三是在后处理阶段引入类别间的逻辑约束比如同一病灶框中分类置信度接近的两个类别可以按医学先验做二次修正。我试下来前两个方向效果最明显第三个实现成本高收益一般除非你后面接业务系统才值得做。4.2 小目标与密集目标的增强策略脸部皮肤病变绝大多数是小目标一张640x640的图上可能有三四十个病灶每个病灶只有十几个像素宽。YOLO底层特征图对这类目标的响应很弱所以必须从数据层面强制模型关注小目标。我常用的增强组合是mosaic mixup让模型在混合背景下学习目标边界防止过拟合。随机裁剪缩放模拟不同拍摄距离下的尺度变化。HSV扰动皮肤颜色受光照影响大适度调整色调和饱和度提升鲁棒性。小目标复制粘贴把标注框面积小于3%的小目标复制到其他图片的空白区域弥补小目标样本不足。但要注意一点mosaic在皮肤病数据上不能一直开到训练结束。final epochs关闭mosaic、改用普通增强做精调是我反复验证过的有效技巧。YOLOv8的ultralytics支持通过mosaic参数控制关闭时机在最后10个epoch关掉即可。4.3 类别不平衡与评估指标的解读前面说了结节的数量明显少于粉刺和丘疹。直接训练的话模型会倾向于把一切不确定的目标都预测为高频类别结节成了重灾区。缓解办法有几个层次首先按类别统计框数量如果平均每张图的结节框数极低可以先做简单复制或重采样。其次在loss层面关注低频类别。YOLOv8没有直接暴露类别权重但可以通过修改数据增强时的过采样策略实现类似效果。最后看评估指标时不要只看mAP0.5要逐类看AP。mAP被高频类别拉高时低频类别的低分很容易被掩盖。我习惯把四个类别的PR曲线单独打印出来节点类如果AP低于其他类很多就说明样本量已经严重拖后腿了。提示医疗相关检测的评估不能唯mAP论。宁可整体mAP低一点也要保证每个类别的recall都够高否则推理时漏检的后果比误检严重得多。5. 实操中那些容易翻车的细节最后这部分总结我在处理这份数据集时实际踩过的坑按影响程度从大到小排列。5.1 路径中的中文、空格和盘符问题压缩包的文件名经常带中文或空格解压后目录结构也没人清理。YOLO的某个模块在解析含中文的路径时在Windows系统上会因编码问题读取失败报错信息却只有一句模糊的FileNotFoundError。我排查了很久才发现是路径的问题。现在的习惯是解压后立即重命名目录为纯英文小写同时把整个数据集放到根目录级路径下避免嵌套过深影响文件读取速度。5.2 标注坐标越界与空标注文件很多公开数据集在制作时标注框会稍微超出图像边界或者因为人工误操作产生零宽高的框。这类问题在训练时不会直接报错但会让loss出现奇怪的震荡。我的做法是写一个清洗脚本把坐标小于0的改成0大于1的改成1过滤掉width或height小于0.0001的无效框然后重新写回txt。清洗后再跑一遍上面的校验脚本确认干净了才进训练。5.3 验证集划分不当导致指标虚高划分训练集和验证集时最常见的错误是把同一张脸的不同区域图片同时分进训练集和验证集。脸部皮肤数据集里常出现同一个人的多张连拍图光照和角度都接近如果不做去重验证集就形同虚设指标虚高到看起来不可思议部署到真实场景立刻露馅。稳妥的做法是先按人或者按拍摄批次进行分组划分再在组级别做train/val切分保证同一组数据不会同时出现在两边。5.4 推理时NMS阈值与类别重叠最后还有一个容易被忽略的细节因为皮损密集推理时的NMS非极大值抑制阈值如果设置得太高相邻的不同类别框会被合并掉设置得太低又会留下大量重叠框。我在实际使用中把conf设为0.25、iou设为0.45四个类别分别输出然后对同类别框做一次二次NMS。这样处理后的框和人工标注的分布最接近。从拿到这份数据集到模型在本地跑通整个过程如果流程熟悉一个周末就能搞定。核心还是那句话不要急着堆模型先把数据吃透。把标注格式、类别分布、边界条件这些基本功打扎实YOLO跑出来的效果自然差不到哪去。如果你正在做类似的医疗检测项目这套从数据校验到训练配置的流程可以直接照着用。本文还有配套的精品资源点击获取
返回列表