简介:面向医学图像分类任务的肾脏结节与肿瘤识别数据包,适合需要使用YOLOv5分类分支或CNN分类网络的初学者与算法工程师。压缩包共2000个文件,以1998张JPG图像为主,辅以1个类别字典JSON和1个可视化脚本。图像按训练集2800张、验证集800张、测试集400张预先划分好并分文件夹存放,可直接加载训练;JSON中提供正常、结节、肿瘤三类标签映射,方便与分类网络对接。资源约151.5MB,目录结构清晰,还附带show脚本,运行后即可快速预览各类别样例,便于检查数据质量与分布。已有300人学习下载,适合作为医学图像分类入门练手或算法迭代的基准数据。
1. 医学图像分类资源:一份划分好、能直接喂给训练脚本的肾脏数据
医学图像分类这个任务,真正让人耗时间的往往不是模型选型,而是绕不开的数据三步曲:整理、划分、确认标签。肾脏结节与肿瘤图像识别项目一上来就要面对一堆带长尾哈希的文件名,类别字典写在哪、训练集测试集有没有分好、文件夹里混没混入脏数据,都得自己摸。这份资源把这些前置工作做完了——data 目录下分好训练集 2800 张、验证集 800 张、测试集 400 张,正常、结节、肿瘤三类,映射关系放在 json 文件里,还有 show 脚本可以直接可视化数据。适合两类人:正在做图像分类项目、需要现成医学影像数据快速跑通流程的人;想对比 YOLOv5 分类与普通 CNN 分类网络,但不想在数据整理上重复消耗时间的人。
2. 拆开数据集:三个文件夹、命名规则和类别字典 json
2.1 整体目录结构:train、valid、test 与类别子文件夹
这份资源的核心不是代码,是数据本身。解压之后,data 目录下的结构大概是这样的(少数命名以压缩包内实际为准):
data/ ├── train/ # 训练集 2800 张 │ ├── normal/ │ ├── stone/ │ └── tumor/ ├── valid/ # 验证集 800 张 │ ├── normal/ │ ├── stone/ │ └── tumor/ ├── test/ # 测试集 400 张 │ ├── normal/ │ ├── stone/ │ └── tumor/ └── classes.json # 类别字典文件这种「按类别建文件夹、图片放里面」的布局,是图像分类任务最通用的格式。训练时不需要额外标注文件,目录名本身就是标签,PyTorch 的torchvision.datasets.ImageFolder能直接读,YOLOv5 的分类分支也能直接读。三个子集相互独立,同一张图片不会同时出现在 train 和 valid 里,这是划分干净的标志,也是我判断一份数据集能不能直接用的第一步。
值得多说一句:正常、结节、肿瘤这三类在病理上有肉眼可见的差异,但灰度影像里结石和肿瘤的纹理、边缘经常很接近,这决定了这份数据的难点不在「能不能分开」,而在「边界样本能不能分对」。后面训练时你会发现,模型在正常样本上很容易达到高准确率,真正翻车的地方永远是结石和肿瘤的混淆。所以拿到手先别急着训,把类别分布和样本质量看清楚再动手。
2.2 文件名里藏着的信息:Stone-855-_jpg.rf 是怎么来的
随机抽一张文件名出来拆解:
Stone-855-_jpg.rf.1a1d5c2e18e0a98bd9b59c90d56b982d.jpgStone是这张图的原始类别标签,对应「结石」这一类;855是图片在原始采集流程里的编号;_jpg表示原图格式是 jpg;rf是 roboflow 导出的标记,说明这份数据经过 roboflow 平台的导出处理;- 末尾 32 位是哈希值,用于保证文件名唯一,重复图片靠这一段区分。
这个信息对排错很有用。比如你在训练日志里看到某个 step 报了图片读取失败,靠文件名里的编号和哈希能快速定位到具体是哪一张、属于哪个类别。另外,rf标记也提醒了一个潜在问题:roboflow 导出时偶尔会生成额外的.txt标注文件或.DS_Store之类的隐藏文件。如果训练脚本在扫描文件夹时把这些文件当成图片读,就会报解码错误。后面避坑章节我会专门说这个。
2.3 类别字典 json:动手前先把映射打出来
类别字典文件是这份资源的「说明书」,它告诉训练脚本哪一类对应哪个标签。但这里有个血泪经验:不要凭文件名脑补映射。比如你看到一堆Stone-xxx.jpg,可能会以为 json 里只有 stone 和 normal 两类,结果打开一看是三个键。所以第一步永远是把它打印出来:
import json with open("classes.json", "r", encoding="utf-8") as f: classes = json.load(f) print(classes) print(type(classes)) # dict 还是 list,键是 str 还是 int代码逻辑:读 json 文件,输出内容和类型。type(classes)这一步很关键——如果它是dict,键可能是"0"、"1"、"2"这样的字符串,也可能是"normal"、"stone"、"tumor"这样的类名;如果它是list,索引顺序就是类别顺序。两种结构在写 DataLoader 时的处理方式完全不同:dict 用键取值,list 用下标取值。
参数说明:encoding="utf-8"不能省,类别字典里如果包含中文标签(如「正常」「结节」「肿瘤」),Windows 默认编码容易读成乱码。打印出来之后,再对照 train 目录下的三个子文件夹名,确认 json 里的映射和文件夹名一一对应。这一步多花五分钟,能省掉后面类别错乱的大麻烦。我一般还会顺手统计每个类别的图片数量,做法是:
import os from collections import Counter base_dir = "data" for split in ["train", "valid", "test"]: counts = Counter() split_path = os.path.join(base_dir, split) for cls_name in os.listdir(split_path): cls_path = os.path.join(split_path, cls_name) if os.path.isdir(cls_path): counts[cls_name] = len(os.listdir(cls_path)) print(split, dict(counts))这段代码遍历 train、valid、test 三个目录,统计每个类别子文件夹下的文件数。os.listdir会把隐藏文件也算进去,所以如果发现某个类别数量异常多,优先怀疑是不是混入了临时文件。2800/800/400 的总量是摘要里给出的,但每个类别具体多少张,得跑完这段才知道。
2.4 show 脚本:可视化数据集的正确打开方式
摘要里提到资源自带 show 脚本,这个脚本的价值在于「眼见为实」。医学影像光看文件名和数量是不够的,你需要亲眼确认图片内容:类别标签和图像内容是否匹配、有没有重复图、有没有被压缩到失真的样本。
python show.py如果脚本设计成带参数的形式,也可以指定数据集根目录。脚本内部一般做三件事:遍历每个类别文件夹、抽样固定张数、用 matplotlib 拼成网格图展示。跑起来之前先确认环境里有 matplotlib 和 Pillow,缺了就装一下:
pip install matplotlib pillow常见做法是脚本会额外输出每个类别的样本数统计,方便你在没看代码的情况下快速核对数据集。如果 show 脚本跑完发现某一张图明显和其他样本不是同一个器官视角,我的建议是直接把它从数据里剔除,别留着给训练添乱。
2.5 划分比例:2800/800/400 到底合不合理
从数量看,整份数据集 4000 张,训练集占 70%、验证集占 20%、测试集占 10%,属于比较规整的划分。验证集 800 张对 3 类分类任务来说完全够用,每个类别平均能分到 260 张以上,算出来的验证准确率统计噪声不会太大。测试集 400 张作为最终评估也合理。
更关键的是三方没有交叉:验证集只用于调参过程中的中间评估,测试集从头到尾只碰一次。很多人拿数据集先跑验证集调参,调完直接把验证集当测试集报告准确率,这是评估虚高的常见来源。这份资源的 test 目录是独立的,建议你从一开始就把 test 当成「封印数据」,训练和调参阶段一眼都不看,最后跑一次就行。
3. 接到 YOLOv5 分类训练:目录要求、命令与参数
3.1 为什么选 YOLOv5 分类模式
这份数据唯一不缺的就是目录结构,这正好命中 YOLOv5 的 classify 分支。YOLOv5 检测模式要求 yaml 文件里写训练验证路径,还要求标注框;分类模式完全不同——它不需要 yaml,不需要标注框,只认文件夹路径。脚本会自动扫描--data指向的目录,把train下的子文件夹名当作类别,把valid下的子文件夹当作验证数据。
对这种没有标注框、只有类别标签的医学图像数据集来说,分类模式是最快能跑通的接入方案。相比之下,如果用普通 CNN 分类网络,你需要自己写 DataLoader、自己处理类别映射,虽然也不复杂,但多出来的工作量全在重复代码上。YOLOv5 分类分支把这一层封装好了:预训练权重、数据增强策略、训练日志、混淆矩阵可视化全都有现成的。
选型时要注意一个边界:YOLOv5 分类模式适合「整张图定一个类别」的任务。如果以后需求变成「在一张图里同时定位多个病灶」,那分类模式就撑不住了,得换检测模型。这份数据的场景是肾脏结节和肿瘤识别,从摘要描述看是整图分类,所以 YOLOv5 分类完全够用。
3.2 环境与目录准备
先把 YOLOv5 仓库拉下来,安装依赖:
git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt依赖装完,把数据集放进来。我的习惯是把整个 data 目录放进 yolov5 项目根目录下,这样命令行路径短、好排查。放外面用绝对路径也行,但注意绝对路径不能有中文,YOLOv5 对中文路径的支持一直很玄学,不测就敢用是要吃亏的。
# 把数据集放到 yolov5 目录下 cp -r /path/to/data ./data放好后确认一下目录结构:data 下面必须有 train、valid、test 三个目录,test 目录训练时用不到但建议保留原样。train 和 valid 里面的子文件夹名要和类别字典里的类名一致,不一致的话训练脚本会把多出来的文件夹当成额外类别,导致 num_classes 不是 3。
3.3 训练命令与关键参数
训练命令如下:
python classify/train.py \ --data ./data \ --model yolov5s-cls.pt \ --img 224 \ --batch 32 \ --epochs 50 \ --project runs/train-cls参数说明:
| 参数 | 建议值 | 说明 |
|---|---|---|
--data | ./data | 只接收文件夹路径,脚本自动扫 train 子目录当类别 |
--model | yolov5s-cls.pt | 分类预训练权重;显存小可换yolov5n-cls.pt |
--img | 224 | 默认值 224;想保留更多细节可加到 256 或 320 |
--batch | 32 | 8G 显存 32 起步,OOM 就降到 16 或 8 |
--epochs | 50 | 医学小数据集 50 起步,观察验证集收敛情况再调 |
--project | runs/train-cls | 日志和权重输出目录 |
这里面最容易踩坑的是--data。YOLOv5 检测模式训练时--data传 yaml 文件,分类模式只接受文件夹路径。把 yaml 路径传给分类脚本会直接报错。第二个容易踩坑的是--img:224 是 YOLOv5 分类默认值,但肾脏影像里的结节区域可能只占原图的一小部分,直接缩到 224 会把病灶细节抹掉。如果 show 脚本里看到原图分辨率普遍在 1024 以上,我建议先试 320,代价是训练时间变长,但分类准确率往往能涨几个点。
yolov5s-cls.pt是分类预训练权重,第一次运行会自动下载。如果网络不稳定导致下载失败,可以先手动下载放到项目根目录,再重新执行训练命令。权重文件不需要解压,YOLOv5 会自动加载。
3.4 训练日志与结果文件:判断训练是否正常
训练跑起来之后,看三个信号判断有没有问题:
第一,loss 曲线。YOLOv5 分类训练输出里有两个 loss:train loss 和 val loss。train loss 持续下降是正常的,但如果 val loss 降到某个点开始反弹,说明过拟合了,epochs 设太多了。
第二,准确率。分类训练会实时打印 top1 准确率,关注 val 准确率比关注 train 准确率更有意义。train 准确率接近 100% 但 val 卡在 70% 左右,典型的过拟合,解决办法是增加数据增强或减少 epochs。
第三,结果文件。训练结束后在runs/train-cls/exp目录下能看到:
runs/train-cls/exp/ ├── weights/ │ ├── best.pt # 验证集准确率最高的权重 │ └── last.pt # 最后一个 epoch 的权重 ├── results.png # loss 曲线和准确率曲线 └── confusion_matrix.png # 混淆矩阵best.pt是后面验证和部署要用的权重文件,last.pt一般用不上。results.png适合快速扫一眼训练趋势,confusion_matrix.png才是判断模型短板的关键材料——它直接告诉你哪些类别互相混淆。
4. 避坑:这份数据在训练脚本里常踩的五个问题
4.1 图片加载中断:隐藏文件与路径是元凶
现象:训练跑到一半报FileNotFoundError或者Cannot identify image file,有时候是 show 脚本漏图。
原因:两个最常见。一是数据集路径里有中文,Windows 下尤其容易出现,YOLOv5 读取路径时编码处理不好直接中断。二是文件夹里混入了隐藏文件,比如 Windows 的Thumbs.db、macOS 的.DS_Store,训练脚本扫描目录时把它们当成图片读,解码失败就崩了。
解决:先确认路径纯英文,然后把隐藏文件清一遍:
find ./data -name ".DS_Store" -delete find ./data -name "Thumbs.db" -delete清理完重新扫描目录确认图片数量没变,再启动训练。从那以后,我拿到任何数据集第一件事就是清隐藏文件。
4.2 验证准确率卡住:类别相似与 img 太小
现象:train loss 正常下降,val 准确率卡在某个值上不动,或者反复震荡。
原因:这份数据里结石和肿瘤在灰度影像上纹理接近,是天然难分的类别;再加上--img 224默认把图片缩得很小,原图里只有几十像素的细小病灶在缩放过程中直接被抹掉了。
解决:两个方向。第一,把--img从 224 提高到 320 试试,显存够就再往上加。第二,训练结束后看混淆矩阵,确认卡点是结石被误判成肿瘤,还是肿瘤被误判成正常。如果是前者,说明特征还在,只是模型分辨不够,增大 img 或加 epochs 有效;如果是后者,说明病灶细节丢了,得从预处理下手,检查是否有随机裁剪把病灶裁掉了。
4.3 类别映射错乱:json 的键不要脑补
现象:训练结束,跑预测时发现模型把「结节」的图片输出成「正常」,准确率报告完全不可用。
原因:类别字典 json 里键是"0"、"1"、"2"这样的字符串,排序后对应的类和文件夹顺序不一致;或者 json 里键是类名但顺序和 train 子目录的扫描顺序不同。我没有打印 json 就直接按文件名脑补了映射,结果真实映射和代码里写的对不上。
解决:训练前把打印 json 和统计每个类别数量的脚本各跑一遍,确认 index 到类名的映射关系。如果用的是 PyTorch 的ImageFolder,直接在dataset.classes上打印一遍,和 json 做一次比对。
4.4 测试集与验证集混用:评估虚高的陷阱
现象:报告里测试集准确率很高,换到真实场景的图片上表现明显差一截。
原因:调参过程中反复在验证集上看结果,模型已经对验证集产生了隐式拟合,也就是常说的「验证集被污染」。更糟的是有些人图省事,用验证集的效果直接充当最终测试结果,没跑专门的 test 目录。这份资源的 test 目录是独立留出来的,它就是用来避免这个问题的。
解决:训练和调参阶段只用 train 和 valid,test 目录从头到尾不打开。最终模型确定之后,拿 best.pt 在 test 上只跑一次。如果 test 结果和 valid 差很多,说明模型泛化不行,而不是 test 有问题。这个习惯我从那以后一直保持。
4.5 --data 传了 yaml:分类与检测的习惯冲突
现象:执行训练命令立刻报错,提示找不到 yaml,或者类别数不对,模型输出维度不是 3。
原因:YOLOv5 检测模式下--data指向 yaml 文件,分类模式下--data只接收文件夹路径,脚本自己扫子目录确定类别数。做了太多目标检测项目之后,手指比脑子快,把 yaml 路径传给了分类脚本。
解决:分类训练直接用文件夹路径:
python classify/train.py --data ./data --model yolov5s-cls.pt --img 224如果传的是 yaml,YOLOv5 会尝试解析 yaml 里的train字段,解析不到就直接报错。报错信息里看清楚是 data 解析阶段挂的还是模型初始化阶段挂的,前者就是路径传错了,后者才需要查模型配置。
5. 进阶验证:用混淆矩阵和 val.py 给模型把脉
5.1 在独立测试集上跑一次最终验证
训练结束,模型权重在runs/train-cls/exp/weights/best.pt。不要在验证集上反复确认结果,直接用测试集做最终验收:
python classify/val.py \ --data ./data \ --weights runs/train-cls/exp/weights/best.pt \ --img 224--data同样传文件夹路径,--weights指定 best.pt。跑完之后输出 top1 准确率和混淆矩阵图。看混淆矩阵时,重点不在主对角线数字有多大,而在非对角线数字最集中的位置——如果「结节被误判成正常」的数量明显偏高,说明模型对微小病灶不敏感;如果「正常被误判成结石」偏高,说明模型把正常组织纹理误当成了病灶信号。这两个问题对医学影像分类的影响完全不同,前者会导致漏诊,后者会导致误报,处理方向也不一样。
5.2 拿到新数据集的固定流程
做了几轮医学图像分类项目之后,我养成了拿到数据集先走三步固定流程的习惯。第一步,清隐藏文件,跑一遍 show 脚本扫图,确认图片能正常打开、类别内容没标错;第二步,打印类别字典 json,和目录结构逐一比对,确认映射关系;第三步,把 test 目录从工作视线里隔离,训练调参只用 train 和 valid,最终模型出来之前不看 test 一眼。
这套流程走到第三遍的时候,我已经不看运气了。很多数据问题表面上是训练参数不对,实际上是数据侧的脏东西在捣乱——隐藏文件、映射错乱、样本不干净。把这些前置确认做完,训练只是最后一个水到渠成的步骤。
这份资源给我最大的价值,不是省了整理数据的那半天时间,而是提供了一个干净的基线:三个目录、一个 json、一批命名规整的图片。你拿到手之后,从 show 脚本开始走一遍流程,跑通一次 YOLOv5 分类训练,再回头对比自己的数据集,就能感受到一个规整的数据集能让整个训练过程省掉多少折腾。希望帮到你。
本文还有配套的精品资源,点击获取