news 2026/10/22 4:10:17

乳腺癌检测数据集实战:YOLOv5 单类别 921 张图直接训练与可视化验证

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
乳腺癌检测数据集实战:YOLOv5 单类别 921 张图直接训练与可视化验证

简介:本资源为面向医学图像目标检测的乳腺癌检测数据集,适用于深度学习入门者、医学影像算法研究者及需要开展癌症病灶检测实验的开发者。数据集按YOLOv5目录结构组织,包含训练集778张图片与778个标签文件、验证集143张图片与143个标签文件,图像统一为640×640分辨率RGB格式,标注边界框清晰完整,前景丰富,可直接投入目标检测模型训练,无需额外预处理。压缩包共1845个文件,以jpg图像、txt标注文件为主,另附1个可视化py脚本和1个png示例图,整体约12.87MB,采用7z格式打包。其中可视化脚本无需修改即可运行,随机传入一张图片便能绘制边界框并保存至当前目录,便于快速核验标注质量。目前已有1074人学习下载,适合作为乳腺癌单类别检测任务的练手数据,也可用于验证YOLO系列模型的训练与推理流程。

1. 乳腺癌检测数据集上手:1 类别 921 张图,YOLOv5 目录直接开跑

拿到一份标注好的医学图像数据集,最怕的不是模型不收敛,而是目录结构对不上、标签格式错位、可视化脚本跑不起来。这份乳腺癌检测数据集就是冲着「省掉预处理」去的:1 个类别breast cancer,训练集 778 张图配 778 个 txt 标签,验证集 143 张图配 143 个 txt 标签,压缩后只有 13 MB,图像统一 640×640 RGB,按 YOLOv5 的images/labels双目录规范存放。换句话说,解压完改一下data.yaml里的路径就能直接喂给 YOLOv5 训练,不用再写格式转换脚本。它适合两类人:一类是想快速验证医学目标检测 pipeline 的算法工程师,另一类是需要一个干净小数据集做教学或消融实验的从业者。下面按「结构长什么样 → 怎么接进训练 → 怎么可视化验证 → 坑在哪」的顺序拆一遍。

2. 目录结构与标签格式:先看清 YOLOv5 的存放约定

2.1 解压后的真实目录长什么样

这份数据按 YOLOv5 的标准布局组织,解压后核心是datasets根目录,下面挂images和labels两棵子树,各自再分train和val。文件名是 Roboflow 风格的哈希后缀,比如kkkkk_jpg.rf.3f4bbd5aa943efae5ba8b60a5d49d109.jpg,对应的标签文件把扩展名换成.txt即可,主名完全一致。这一点很关键:YOLOv5 在训练时是按「图片路径替换images为labels、扩展名换.txt」去找标签的,主名不一致就会静默丢样本。

datasets/ ├── images/ │ ├── train/ # 778 张 .jpg │ └── val/ # 143 张 .jpg └── labels/ ├── train/ # 778 个 .txt └── val/ # 143 个 .txt

先跑一条命令确认图片和标签数量是否一一对应,这是每次拿到新数据集我必做的第一件事:

# 统计图片与标签数量,两者必须相等 find datasets/images/train -name "*.jpg" | wc -l find datasets/labels/train -name "*.txt" | wc -l find datasets/images/val -name "*.jpg" | wc -l find datasets/labels/val -name "*.txt" | wc -l

四个数字应该分别是 778、778、143、143。如果标签数少于图片数,说明有图没标,训练时那些图会被当作背景负样本,直接影响召回。参数上没什么可调的,这一步纯粹是核对完整性。

2.2 单类别标签的每一行代表什么

YOLO 格式的标签是「一行一个目标」,每行 5 个字段:class_id x_center y_center width height。这份数据只有 1 个类别,所以class_id恒为0,对应data.yaml里的names: ['breast cancer']。后四个值是归一化到 0~1 的浮点数,不是像素坐标,这点新手最容易搞混。

# labels/train/kkkkk_jpg.rf.3f4bbd5aa943efae5ba8b60a5d49d109.txt 0 0.512500 0.437500 0.187500 0.225000 0 0.734375 0.609375 0.156250 0.200000

第一行读作:类别 0,框中心在图像宽 51.25%、高 43.75% 处,框宽占 18.75%、高占 22.5%。因为图像是 640×640,换算成像素就是中心 (328, 280)、宽 120、高 144。项目正文提到「每张图像均有多个类别的目标」,在单类别语境下应理解为「每张图可能有多个目标实例」,也就是一张图里出现多个病灶框,标签文件里就会有多行。写解析脚本时按行循环即可,不要假设一行。

提示:归一化坐标乘以图像宽高才是像素框,反算时记得x1 = (cx - w/2) * W,别把中心点当左上角。

2.3 为什么这份数据能省掉转换脚本

常见做法是拿到 VOC 的 XML 或 COCO 的 JSON 后,写脚本转成 YOLO txt,转换过程里坐标取整、类别映射、空标签处理都容易翻车。这份数据已经转好了,省掉的就是这一整段。代价是它把类别数锁死在 1,如果你要做多类别乳腺癌分型(比如良恶性、钙化点分开),得自己在标签里加class_id并重写data.yaml的names,这一步没有捷径。

3. 接进 YOLOv5 训练:data.yaml 与超参怎么配

3.1 写一份能直接跑的 data.yaml

YOLOv5 靠data.yaml找数据,路径写错是最常见的翻车点。相对路径是相对train.py所在目录解析的,稳妥起见我一般写绝对路径或../datasets这种明确层级。

# data/breast_cancer.yaml path: ../datasets # 数据集根目录 train: images/train # 相对 path 的训练图目录 val: images/val # 相对 path 的验证图目录 nc: 1 # 类别数,必须与标签里的 class_id 最大值+1 一致 names: ['breast cancer'] # 类别名,顺序即 class_id

nc和names长度必须相等,且names的下标要和标签里的class_id对得上。这份数据只有0,所以nc: 1。如果误写成nc: 2,模型会多出一个永远学不到正样本的类别,mAP 计算时那一类的 AP 恒为 0,把整体指标拉低,排查起来很费时间。

3.2 启动训练的命令与关键参数

数据量小(训练集 778 张),从零训不现实,标准做法是加载 COCO 预训练权重做迁移学习。下面这条命令是我在这类小数据集上的常用起点:

# 在 YOLOv5 根目录执行 python train.py \ --data data/breast_cancer.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --cache \ --project runs/train \ --name breast_exp1

逐项说明:--img 640与图像原生分辨率一致,不用缩放,省掉一次插值;--batch 16在 13 MB 数据量下显存压力很小,显存够可以拉到 32;--epochs 100是小数据集的常见区间,配合早停;--cache把图片缓存进内存,778 张 640×640 图占用不大,能明显加快每个 epoch;--weights yolov5s.pt用轻量 backbone,医学小数据集上大模型反而更容易过拟合。如果验证集 mAP 在 30 个 epoch 后还在涨,就把--epochs加到 200 再看。

3.3 训练过程中该盯哪几个指标

YOLOv5 每个 epoch 会打印box_loss、obj_loss、cls_loss和验证集的P、R、mAP@0.5、mAP@0.5:0.95。单类别任务里cls_loss意义不大(只有一类,分类分支几乎不贡献梯度),重点看obj_loss是否稳定下降、mAP@0.5是否爬升。如果box_loss下降但mAP不动,多半是标注框和预测框的尺度分布不匹配,可以检查一下标签里有没有宽高接近 0 的异常框。

# 快速排查标签异常:找出宽或高过小的框 import os, glob bad = [] for txt in glob.glob('datasets/labels/train/*.txt'): with open(txt) as f: for i, line in enumerate(f): parts = line.strip().split() if len(parts) != 5: bad.append((txt, i, '字段数不对')) continue _, _, _, w, h = map(float, parts) if w < 0.01 or h < 0.01: bad.append((txt, i, f'框过小 w={w} h={h}')) print(f'异常标签数: {len(bad)}') for b in bad[:10]: print(b)

这段脚本遍历训练标签,检查每行字段数是否为 5、归一化宽高是否过小。字段数不对通常是转换时多写了空格或漏了类别位;框过小往往是标注时误点产生的噪声框,训练前清掉能少走弯路。

4. 可视化验证:用自带脚本确认标注质量

4.1 可视化脚本怎么用

项目提供了一个可视化 py 文件,随机传入一张图就能画框并保存到当前目录,脚本无需改动。典型用法是把它放在数据集同级目录,传入图片路径:

python visualize.py --image datasets/images/train/kkkkk_jpg.rf.3f4bbd5aa943efae5ba8b60a5d49d109.jpg

脚本内部做的事是:读图 → 按同名规则找labels下的 txt → 把归一化坐标还原成像素框 → 用cv2.rectangle画框 → 保存。跑完当前目录会多出一张带框的图,肉眼确认框是否贴合病灶区域。这一步别省,医学图像里标注偏移几个像素,模型学到的就是错的定位。

4.2 自己写一个批量可视化更省事

单张看效率低,我一般改成批量抽 20 张拼图看整体标注风格:

import cv2, glob, random, os def draw(img_path, label_path): img = cv2.imread(img_path) h, w = img.shape[:2] if os.path.exists(label_path): with open(label_path) as f: for line in f: c, cx, cy, bw, bh = map(float, line.split()) x1 = int((cx - bw / 2) * w); y1 = int((cy - bh / 2) * h) x2 = int((cx + bw / 2) * w); y2 = int((cy + bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) return img imgs = random.sample(glob.glob('datasets/images/train/*.jpg'), 20) for p in imgs: lp = p.replace('images', 'labels').rsplit('.', 1)[0] + '.txt' cv2.imwrite('vis_' + os.path.basename(p), draw(p, lp))

关键点是p.replace('images', 'labels')这一步,它复刻了 YOLOv5 找标签的逻辑,能顺带验证你的目录命名是否规范。如果替换后路径不存在,说明图片和标签的主名或层级对不上,训练时同样会丢样本。抽 20 张看下来,如果框普遍偏大或偏小,就要回头质疑标注质量,而不是急着调模型。

4.3 验证集该怎么用才不浪费

143 张验证集在这份数据里承担两个角色:训练中的val用于早停和选最优权重,训练后的test用于最终评估。YOLOv5 默认用val同时做这两件事,严格来说有轻微的信息泄漏。如果要做论文级评估,常见做法是从 778 张训练集里再切一小部分做独立测试,或者对 143 张验证集做交叉验证。数据量小的时候,单次划分的指标波动会很大,多跑几个 seed 取平均更可信。

5. 避坑与排查:小数据集训练最容易踩的五个坑

5.1 现象:训练启动即报「No labels found」

原因:data.yaml里的train/val路径写错,或者images与labels层级不对应。YOLOv5 找不到标签时不会报错退出,而是把图当背景训,指标一直上不去。

解决:用第 2.1 节的find命令核对数量,再确认data.yaml的path是相对train.py还是绝对路径。最稳的是写绝对路径。

5.2 现象:mAP 长期在 0.1 以下不动

原因:多半是标签坐标没归一化,或者nc与class_id不匹配。如果标签里写的是像素坐标(比如0 328 280 120 144),模型会把它当超出图像范围的框,学不到东西。

解决:抽查几个 txt,确认后四个值都在 0~1 之间。像素坐标要除以图像宽高再写回。

5.3 现象:验证集指标远高于训练集

原因:数据量太小(验证集仅 143 张),单次评估方差大;或者训练集和验证集存在同源图像,造成近似泄漏。

解决:多跑几个 seed 看指标分布,别信单次结果。如果怀疑泄漏,检查训练集和验证集的文件主名是否有重复前缀。

5.4 现象:可视化脚本画出的框位置整体偏移

原因:脚本里把中心点坐标当成了左上角,或者宽高没除以 2。YOLO 存的是中心点 + 宽高,画框要先算x1 = cx - w/2。

解决:对照第 4.2 节的还原公式逐行核对,注意乘图像宽高和减半的顺序。

5.5 现象:训练到后期 loss 突然变 NaN

原因:学习率过高,或某个 batch 里出现了宽高为 0 的退化框,除零导致梯度爆炸。

解决:先用第 3.3 节的脚本清掉异常框,再把学习率降到--lr0 0.001重跑。小数据集上默认学习率有时偏大。

6. 进阶技巧:小数据集的增强策略与评估口径

数据只有 921 张,模型容量和增强策略的取舍直接决定最终效果。我的习惯是把增强开足但别过头:YOLOv5 默认的--mosaic 1.0对医学图像要谨慎,因为 mosaic 会把四张图拼一起,病灶的解剖上下文被破坏,可能学到伪相关。常见做法是把 mosaic 降到 0.5 甚至关掉,改用--flipud 0.5 --fliplr 0.5这类几何增强,医学图像里左右翻转是否合理取决于成像部位,乳腺图像一般可以接受水平翻转。

评估口径上,单类别检测别只看 mAP@0.5。医学场景更关心召回,漏检一个病灶的代价远大于多报一个。训练完用val.py单独跑一次,把--conf-thres调低到 0.1 看召回上限:

python val.py \ --data data/breast_cancer.yaml \ --weights runs/train/breast_exp1/weights/best.pt \ --img 640 \ --conf-thres 0.1 \ --iou-thres 0.5

--conf-thres 0.1会输出大量低置信预测,召回接近上限,用来判断「模型到底有没有能力找到病灶」;实际部署时再根据业务在 P-R 曲线上选阈值。--iou-thres 0.5是评估时判定 TP 的 IoU 门槛,医学小目标可以放宽到 0.3 看宽松口径下的表现。

参数建议值说明
mosaic0.5 或 0医学图像上下文敏感,过高破坏解剖结构
fliplr0.5水平翻转,多数乳腺成像可接受
flipud0 或 0.5垂直翻转视成像方向而定
lr00.001~0.01小数据集取小值更稳
conf-thres(评估)0.1看召回上限
iou-thres(评估)0.3~0.5小目标可放宽

还有一点血泪经验:每次改完增强或超参,先把--epochs设成 10 跑一遍冒烟测试,确认 loss 正常下降、没有 NaN,再开长训练。小数据集单次训练虽然快,但反复试错的累计时间很可观。从那以后我每次拿到新数据集,都强制先跑一遍数量核对、标签抽查、10 epoch 冒烟这三步,再谈调参。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 17:18:48

Claude Code 记忆系统源码分析:extractMemories 与 autoDream 如何协作

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/16 17:06:01

运维总监方法论:故障管理、容量规划与团队建设的实战指南

1. 这活儿根本不是技术岗&#xff0c;是决策岗干了十几年运维&#xff0c;从救火队员一路做到总监&#xff0c;我最大的感悟是&#xff1a;很多人对这个岗位的理解从一开始就偏了。大家总觉得运维总监应该是技术最牛的那个人&#xff0c;什么故障都能秒级定位&#xff0c;什么脚…

作者头像 李华
网站建设 2026/10/21 6:49:33

Codex Desktop额度耗尽导致发送键禁用的原理与绕过方案

1. 项目概述&#xff1a;一个被“静音”的发送键背后&#xff0c;到底发生了什么Codex Desktop 这个名字&#xff0c;最近在不少技术向社群里反复出现&#xff0c;不是因为新功能发布&#xff0c;而是因为一种特别“安静”的异常——用户明明已经配置好第三方中转服务&#xff…

作者头像 李华
网站建设 2026/10/15 3:55:08

EMD-KPCA-LSTM:多维时序特征分解与光伏功率预测实战

简介&#xff1a;这份压缩包提供了一套完整的EMD-KPCA-LSTM多维时间序列预测程序&#xff0c;面向光伏功率预测、回归预测等场景&#xff0c;适合具备Matlab和深度学习基础的研究者、赛题选手或相关专业学生。案例使用北半球光伏功率数据&#xff0c;以太阳辐射度、气温、气压、…

作者头像 李华
网站建设 2026/10/16 6:05:50

Clawith 深度分析报告:OpenClaw AI Agent 的 FastAPI 与 Docker 落地实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/19 0:55:44

计数DP从入门到实战:以666RPG为例详解状态设计与转移

1. 从“666RPG”这个标题说起&#xff1a;计数DP到底在算什么第一次看到“666RPG&#xff08;计数dp&#xff09;”这个标题&#xff0c;很多人会愣一下&#xff1a;RPG不是角色扮演游戏吗&#xff0c;怎么跟DP扯上关系了&#xff1f;其实这里的RPG并不是指游戏类型&#xff0c…

作者头像 李华