资讯详情 宫颈癌YOLOv5检测数据集:从数据校验到训练评估全指南
📅 2026/10/9 18:32:53
简介面向计算机视觉目标检测方向的研究者与学习者这套宫颈癌YOLOv5检测数据集已按标准YOLOv5目录结构整理包含独立训练集与验证集可直接用于目标检测模型训练无需额外格式转换。数据按datasets目录划分训练集与验证集训练集含816张图片及对应的816个txt标签验证集含216张图片及对应的216个txt标签统一使用单一类别cancer组织标注。图像均为640×640高分辨率RGB图片病灶目标尺寸较小、边界框标注清晰且图像完整尤其适合小目标检测相关算法的调试、消融实验对比与模型效果评估。资源共2000个文件主要包含1083个txt标签文件、916张jpeg图像与1个可视化py脚本压缩包约180.22MB随包附带可视化脚本无需修改即可直接运行随机传入一张图片就能自动绘制边界框并保存至当前目录便于快速查验标注质量。目前已有29人学习下载适合需要直接开展YOLO系列模型训练与推理验证的中高级开发者使用。1. 高质量宫颈癌YOLOv5检测数据集一份可以直接喂给模型的标注资产做宫颈癌辅助筛查相关的目标检测最难的不是模型选型而是数据。一张病理切片或TCT图像上病变区域与正常组织交织标注要由有经验的病理医生完成普通标注工很难上手。所以当我看到「高质量宫颈癌YOLOv5检测数据集包含完整训练与验证集、YOLO数据集」这个选题时第一反应是这解决了从业者最痛的环节。它把“从原始图像到可训练数据”之间最耗时、最容易出错的几步——标注、格式转换、训练集与验证集切分——全部提前做掉了拿到手可以直接按YOLOv5的标准流程开工。这个数据集适合三类人第一次接触医学目标检测、想用现成数据跑通全流程的初学者正在做宫颈癌辅助诊断方案、需要前期验证模型可行性的算法工程师以及想评估YOLOv5在细胞学图像上到底能到多少精度的研究者。数据本身就是资产但前提是你要会验收、会配置、会训练、会看指标而不是拿到文件夹就开始敲命令。下面四件事我建议按顺序做先查数据、再训练、再排雷、最后用评估指标判断能不能落地。2. 看清数据集家底目录结构、YOLO标注格式与完整性校验2.1 可训练数据资产的三个基本盘目录、标签、映射表一份能直接训练的YOLO格式数据集基本盘是三件事图片目录、标签目录、类别映射文件。常见做法是images目录下按train和val存放图片labels目录下按同样的子目录结构存放同名txt文件txt里每一行对应一个目标框。拿到的数据集只要长成这样就说明已经把格式转换和训练验证集切分都替你做掉了。我一般会先看一眼根目录是否有data.yaml或者类似的yaml文件它声明了路径、类别数量和类别名字。下面是一个典型的YOLOv5数据集目录布局cervical_yolo/ ├── images │ ├── train │ │ ├── 001.jpg │ │ └── ... │ └── val │ ├── 101.jpg │ └── ... ├── labels │ ├── train │ │ ├── 001.txt │ │ └── ... │ └── val │ ├── 101.txt │ └── ... └── data.yaml注意一个细节labels下的txt和images下的jpg必须保持同名只是扩展名不同。YOLO训练时是按文件名前缀去匹配图片与标签的前缀对不上那一张图就等于没标注会被静默跳过。很多训练结果虚低第一步就栽在这里。标签txt每一行的格式是固定的类别ID、归一化后的中心点x坐标、中心点y坐标、归一化后的框宽、框高。比如下面这一行2 0.5248 0.4719 0.4920 0.6322含义是类别ID为2目标中心位于图片宽度的52.48%处、高度的47.19%处目标宽度和高度分别占整幅图片的49.2%和63.22%。所有坐标都是0到1之间的浮点数不需要去换算像素。要转成像素坐标就是乘以图片的宽和高这个转换在可视化或精确计算面积时经常会用到。2.2 用30行脚本完成标签格式快检拿到数据第一步不是训练是写脚本检查完整性。这是踩过坑之后养成的习惯。一个数据集声称完整不代表真的完整可能是某一次转换脚本把一批标签漏掉了或者某个txt里混入了空行、坐标越界。这类问题在训练阶段不会报错只会让Loss曲线变得诡异。下面这个脚本做两件事检查图片是否有对应标签检查标签内容是否合法。import os import glob img_dir images/train label_dir labels/train imgs sorted(glob.glob(os.path.join(img_dir, *.[jp][pn]g))) missing 0 for img in imgs: stem os.path.splitext(os.path.basename(img))[0] label os.path.join(label_dir, stem .txt) if not os.path.exists(label): missing 1 print([missing], label) print(ftotal images: {len(imgs)}, missing labels: {missing}) bad_lines 0 for label_path in glob.glob(os.path.join(label_dir, *.txt)): with open(label_path, r) as f: lines f.read().strip().splitlines() for line in lines: parts list(map(float, line.split())) if len(parts) ! 5: bad_lines 1 print([bad format], label_path, line) continue cls, x, y, w, h parts if not (0 x 1 and 0 y 1 and 0 w 1 and 0 h 1): bad_lines 1 print([out of range], label_path, line) print(fbad lines: {bad_lines})这段逻辑很简单先按扩展名匹配jpg和png图片找同名txt再逐行解析标签检查是否有5个数值、坐标是否归一化在合法区间。参数上唯一可能需要改的是*.[jp][pn]g这个通配如果数据集里有bmp格式就把它扩进去。运行完后如果missing或bad_lines不是0先用脚本修坚决不要带着脏数据训练这个时间省不得。对验证集目录也跑一遍train和val都要干净。2.3 把标注框可视化看一遍别急着开训格式检查通过只能说明文件齐全不能说明标注框画得准。我建议训练前把所有验证集图片的标注框绘制出来拼成一张大图人工过一遍。这一步能看到很多脚本查不出的事比如标注框是套在病变核心区域还是把一大片正常组织都框进去了。import os import cv2 import glob img_dir images/val label_dir labels/val out_dir debug_vis os.makedirs(out_dir, exist_okTrue) for img_path in sorted(glob.glob(os.path.join(img_dir, *.[jp][pn]g))): stem os.path.splitext(os.path.basename(img_path))[0] label_path os.path.join(label_dir, stem .txt) img cv2.imread(img_path) h, w img.shape[:2] if not os.path.exists(label_path): continue with open(label_path, r) as f: for line in f.read().strip().splitlines(): parts list(map(float, line.split())) if len(parts) ! 5: continue cls, x, y, bw, bh parts x1 int((x - bw / 2) * w) y1 int((y - bh / 2) * h) x2 int((x bw / 2) * w) y2 int((y bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2) cv2.putText(img, str(int(cls)), (x1, max(0, y1 - 5)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) out_path os.path.join(out_dir, stem .jpg) cv2.imwrite(out_path, img) print(saved, out_path)这里把归一化坐标乘回图像宽高得到像素坐标之后用OpenCV画矩形和类别编号。主要参数是画框线宽2像素文字放在框左上角外侧避免遮挡目标区域。输出到debug_vis目录之后挑30到50张图拼网格看重点看两类问题类别编号是否和实际病变区域一致框是否贴合目标边界。这一步花10分钟能省掉后面训练完才发现数据标注口径不对的后悔药。3. 跑通YOLOv5训练从data.yaml到命令行里的5个关键超参3.1 编写data.yaml路径、类别ID与names的一一对应YOLOv5训练时通过--data参数指定数据配置文件这个文件决定了模型去哪里读图片和标签。如果数据集没有附带data.yaml这一步必须自己做。yaml内容不多但每个字段都牵一发动全身。path: /home/user/datasets/cervical_yolo train: images/train val: images/val nc: 3 names: 0: LSIL 1: HSIL 2: SCCpath建议写成绝对路径。train和val是相对于path的子目录路径不要写成/home/user/datasets/cervical_yolo/images/train这样带完整前缀的写法否则换机器或移动数据集目录时会全部失效。nc是类别总数names是0到nc-1的类别列表。这里最容易搞错的是类别ID的对齐。txt文件里第一个数字是类别ID它是names列表的下标。也就是说txt里出现0代表LSIL出现1代表HSIL出现2代表SCC。如果数据集标注时类别编号从1开始或者names顺序不对训练出来的模型预测类别会整体错位指标却不一定会低得很明显属于比较难排查的问题。提示拿到数据后先统计所有txt里出现过的类别ID确认最大值等于nc-1且无跳号再开始训练。3.2 启动训练一个适合医学小目标的基准命令数据验收没有问题之后训练命令其实很固定。我一般用YOLOv5s作为起步模型而不是直接上YOLOv5x。原因很简单医学图像数据量通常不大小模型更容易收敛训练速度快迭代成本低等验证集mAP跑不动了再换大模型提升上限。python train.py --img 640 --batch 16 --epochs 100 \ --data cervical.yaml --weights yolov5s.pt \ --cache ram --amp --patience 15 \ --hyp hyp.scratch-low.yaml每个参数仔细说一下。--img 640是输入分辨率YOLOv5会把训练图片统一缩放到这个尺寸。对细胞学图像来说640只是起步值如果病灶区域很小建议直接上960这个后面会展开。--batch 16是要根据显存调的显存不够就降到8batch过小会影响BatchNorm统计量所以8到32之间比较合适不要为了显存硬压到2。--epochs 100是个相对稳妥的初始值配合--patience 15做早停连续15个epoch验证指标不上升就自动停止。--weights yolov5s.pt是加载COCO预训练权重做迁移学习。虽然COCO没有医学图像类别但骨干网络学到的纹理和边缘特征可以迁移到病理图像上医学小数据集上效果比从头训练明显好。--amp开启混合精度训练显存占用能低30%左右精度损失极小。最后一个--hyp hyp.scratch-low.yaml是数据增强策略这个文件降低了Mosaic与MixUp的增强强度对医学图像很重要——过度增强可能生成组织纹理不真实的样本让模型学偏。3.3 读懂训练日志与loss曲线让epochs不再靠感觉训练过程中终端会持续输出类似下面的日志不要只看有没有报错要会看趋势Epoch 50/100: box_loss0.042, cls_loss0.011, dfl_loss0.98, P0.71, R0.65, mAP.50.73, mAP.5:.950.41box_loss是框回归损失数值越低说明预测框与标注框越贴合cls_loss是分类损失P和R分别是精度与召回率mAP.5是IoU阈值0.5下的平均精度医学检测里它是个偏宽松的指标mAP.5:.95是COCO风格指标对不同IoU阈值取平均对定位精度的要求更苛刻数值通常比mAP.5低15到20个百分点这个差距是正常的。看日志时重点判断两件事验证集的召回率是否在持续上涨训练集损失和验证集损失的差距是否越拉越大。如果R长期在0.5以下而P很高说明模型漏检严重。对宫颈癌筛查场景漏检比误检更危险后续调参优先保R。如果训练损失一路下降而验证损失在第40个epoch开始反弹就是过拟合信号早停或加大数据增强能缓解。4. 避坑指南训练宫颈癌YOLOv5时最常翻车的5个问题4.1 标签与图片没对上号训练集悄悄丢失样本现象训练日志里显示图片数比预期少很多或者验证时某些类别的AP始终为0但可视化发现标签文件明明存在。原因最常见的两种情况一是文件名有前缀差异比如图片叫001_a.jpg而标签叫001.jpgYOLO按完全匹配的前缀找标签二是某次切分脚本把部分子目录漏复制了train图片比标签多出几百张。解决用前面2.2节的完整性校验脚本先跑train再跑val把missing标签的图片全部列出来。然后再写一个反向检查找labels目录下没有对应图片的txt如果有说明标签是孤儿文件直接移走。处理完后再跑一遍统计数据确认图片数等于标签数再训练。这一步是免费的血泪经验别跳过。4.2 类别编号从1开始模型把LSIL学成了HSIL现象训练一切正常loss正常下降mAP也还可以但推理时模型输出的类别标签和医生标注完全对不上低级别病变被识别成高级别病变。原因标注工具和转换脚本之间的类别编号约定不一致。很多标注工具内部从1开始计数而YOLO要求从0开始。如果原始转换脚本没有把ID减1所有类别就会整体偏移一位模型学到的是错位的映射关系。解决训练前写一个统计脚本把所有标签文件里的类别ID汇总成集合看看实际有哪些值。如果ID最大值大于nc-1或者ID有跳号就对全部标签做一次批量修正。修正时保留一份备份把txt里第一列的数字按照映射关系替换再重新校验一遍分布。这个坑最阴的地方在于指标不一定会崩因为模型确实学会了“把某类纹理分类成某个固定编号”只是编号对应的名字是错的。4.3 小病灶被下采样吃掉漏检集中在最小尺寸类别现象结论是HSIL的AP比LSIL高很多小尺寸目标的召回率显著偏低模型原样输出一张图像里尺寸很小的核团时几乎全部漏掉。原因宫颈细胞学图像里早期病变的核心特征就是局部细胞团的形态变化这些区域在整张图里可能只占几十乘几十个像素。把图缩放到640分辨率后特征信息被下采样抹掉了再强的网络也没法从模糊像素里找回细节。Mosaic增强把四张图拼到一起训练又会进一步缩小每个目标的实际尺寸。解决把--img从640调到960甚至1280对显存的要求会显著上升batch对应降下来。如果显存撑不住另一个方案是先把完整的大图切成小块patch每个patch单独训练和推理推理时再按位置拼回完整结果。切patch要带重叠区域否则目标正好在切缝处时会被截断后续检测困难。这个方向是典型的以算力换精度但对小目标确实有效。4.4 同一病例被拆进训练和验证mAP虚高现象验证集mAP高达0.9以上但把模型拿到新采集的病例上测试效果明显变差仿佛换了一批数据。原因医学图像通常按病例存储同一病例的多张图像有强相似性。如果切分训练验证集时是按图片随机洗牌而不是按病例分桶同一个患者的部分图片会出现在训练集另一部分出现在验证集。模型等于提前“见过”验证病人了验证mAP虚高是必然的。解决拿到数据集先确认切分方式。如果数据集已经按病例隔离切分可以直接使用如果不是重新按病例维度组织一个患者的所有图像必须全部进训练集或全部进验证集不允许跨集合。更严格的方案是同时按病例和数据来源做分层保证不同医院或不同批次的样本在验证集中有覆盖这样评估结果才对真实场景有参考价值。4.5 标注边界过松模型学会框住整个区域而不是病变核团现象模型得到的mAP不低但输出的框明显比实际目标大一圈IoU在0.5阈值下还能接受一旦把评估阈值提高到0.75mAP直接断崖式下跌。原因标注规范不统一。部分标注人员倾向于把整个上皮区域或整片可疑区都画进框里而严格的标准应该只框住明确的病变核团。模型学习时接收到的是模糊边界预测框自然随之放宽定位精度上不去。解决在2.3可视化阶段就要发现这个问题。解决办法是统一标注边界规范目标框必须紧贴病变核团外缘不能包含周边正常组织同一个类别的最小目标也要独立标注不要合并成一个大框。如果数据集中已经存在大量松框可以在预处理阶段计算每个框的宽高与对应目标实际轮廓的匹配度挑出偏差大的样本重新标注或剔除。质量不足的标注宁可删掉一部分也不要带进去训练。5. 评估比训练更重要mAP之外还要看混淆矩阵与临床可用性5.1 用val.py输出一套完整指标训练完成后第一件事是回到命令行跑一次标准验证而不是直接拿训练日志里的最大值当最终结论。YOLOv5自带val.py脚本输出比训练过程更完整的结果。python val.py --data cervical.yaml \ --weights runs/train/exp/weights/best.pt \ --conf-thres 0.25 --iou-thres 0.5 --img 960这里--conf-thres 0.25是置信度阈值低于这个分数的预测框会被丢掉调高它会提升精度但降低召回--iou-thres 0.5是判断预测框与标注框是否匹配的IoU阈值这是NMS阶段和mAP计算时使用的匹配标准。--img 960要与训练时的输入尺寸保持一致否则评估结果和训练指标不可比。运行结束后会输出一张results.png和一份confusion_matrix.png保存到根目录或runs/val路径下。不要只看终端打印的mAP就完事这是比较危险的习惯。5.2 每类单独算AP别用总体mAP掩盖短板总体mAP是所有类别AP的均值很容易被强类别带高。对于宫颈癌检测LSIL、HSIL和SCC三个类别的临床意义完全不同漏掉一个HSIL和漏掉一个SCC的后果不一样。至少要单独看每一类的AP和召回率。指标作用这一类数据集的观察重点mAP.5整体精度高于0.9时怀疑数据泄漏需要排查验证集独立性mAP.5:.95定位精度医学小目标通常比.5低15%以上属正常现象AP_LSIL低度病变检测最容易与其他两类混淆关注与HSIL的互混情况AP_HSIL高度病变检测筛查场景里召回率比精度更重要漏检不可接受AP_SCC鳞癌检测样本量通常最小AP波动大看置信区间更稳从混淆矩阵里重点看LSIL被预测成HSIL的比例以及反向混淆。两者在细胞形态上有连续性边界本来就不明确如果混淆比例超过20%就要考虑是否为标注时分类标准不一致导致的。可以用一个简单办法辅助判断把混淆样本的图像和对应标注全部可视化请有经验的医生或标注人员帮忙回看区分到底是模型学错了还是标注本身标错。5.3 针对宫颈癌筛查场景怎么理解假阴性与假阳性医学场景的评估逻辑和通用目标检测有本质差别。通用检测里precision和recall是两个对等的指标但在宫颈癌筛查里假阴性意味着阳性病例被漏掉患者可能错失早期干预窗口假阳性虽然会带来不必要的复核但至少还有医生兜底。所以调参方向要偏向召回率必要时牺牲一些精度。做法上推理时把--conf-thres从0.25降到0.1或0.15会捡回一批低置信度的可疑目标代价是假阳性增加。这个阈值不是拍脑袋要看验证集上recall曲线在什么阈值附近开始饱和。另一个做法是采用更严格的IoU评估阈值比如把--iou-thres提到0.75再看定位精度这样能反映出模型在真实切片上是否够用。最终给医生的输出应该带位置与置信度把低置信度目标单独列一份“需复核”清单比统一屏蔽掉更负责。如果数据集附带验证集就按规定使用如果还想再严格一点可以从中再留出一部分当盲测集只做最后一轮最终评估不要反复在同一个验证集上调参否则验证集指标也会逐渐失真。评估到最后问自己一句这个模型敢不敢放进辅助诊断流程里跑一批新数据如果不敢前面的训练就还没收尾。6. 继续挖精度难例挖掘、增强策略与TTA推理的进阶路线6.1 难例挖掘把你的漏检喂回训练集基础流程跑通后最有效的提升手段不是换大模型而是难例挖掘。用当前best.pt对训练集做一轮推理把置信度低于0.2的预测框和漏检区域剪出来人工复查这些样本的标签。如果发现漏标补标后把这些图像加大采样权重重新混入训练。循环两轮比盲目增加epochs的效果更明显。这个思路的本质是让模型把注意力放在它最不擅长的困难样本上。6.2 TTA和patch推理稳住小目标与边界目标推理阶段可以开启TTA在推理时对同一张图做多尺度缩放和翻转再合并结果。召回率通常能提升两个点左右代价是推理时长成倍增加。对显存不足或超大图像切patch推理是更实用方案将大图切成512或640的patch每个patch重叠100像素推理后按坐标合并再做NMS。这样可以保住小目标细节也避免目标横跨切缝时被切断是目前应对超高分辨率病理图像的常用手段。我自己第一次训练宫颈癌检测模型时只顾着盯mAP数字涨得高不高结果模型交付给评估方试跑后反馈是漏检太多才发现自己忽略了recall和混淆矩阵那一刻是比较懊悔的。后来每次迭代我都强制自己先看单类AP与混淆矩阵再决定是否收工毕竟筛查场景里漏一个病人不只是指标低几个点的问题。这个习惯保住了后面几次项目的验收效果。希望帮到你。本文还有配套的精品资源点击获取