YOLOv5肾脏结石CT检测实战:460张数据集训练与避坑指南
简介这份资源面向医学影像分析与目标检测方向的开发者、学生及科研人员提供CT扫描图像中肾脏与结石的YOLOv5格式检测数据集可直接用于模型训练与算法验证省去繁琐的数据清洗与格式转换环节。资源包共923个文件包含460张jpg图像、461个txt标注文件以及1个可视化py脚本和1张png预览图压缩包约16.9MB。数据按YOLOv5标准目录组织分为训练集325张图片及对应标签、验证集135张图片及对应标签图像统一为640×640分辨率RGB格式边界框标注清晰、图像完整共设肾脏与结石两个类别。配套的可视化脚本无需修改即可运行随机传入一张图片便能绘制边界框并保存至当前目录便于快速核验标注质量。目前已有132人学习关注适合作为医学影像检测项目的入门数据基础或课程实验素材。1. 从一张 640×640 的 CT 片说起这份肾脏结石数据集到底能干什么如果你正在做医学影像目标检测尤其是 CT 下的肾脏与结石识别大概率绕不开一个现实问题公开数据难找标注质量参差格式还得自己转。这份 yolov5 数据集直接给了 460 张 640×640 的 RGB 图像训练集 325 张、验证集 135 张每张图配一个同名 txt 标签类别只有两个——肾脏和结石。目录结构就是 YOLOv5 标准的那套 datasets/images/train、datasets/labels/train解压完把 data.yaml 里的路径一改就能开跑不需要你再写脚本做格式转换。它适合两类人一是想快速验证结石检测模型能不能收敛的算法工程师二是拿它当教学案例、跑通 yolov5 训练自己数据集全流程的学生或转行者。17 MB 的体量不大但边界框标注清晰、图像完整作为小样本医学检测的起点足够用。2. 拆开数据包目录结构、标签格式与可视化脚本怎么用2.1 目录结构与文件命名规律拿到压缩包解压后你会看到类似这样的层级datasets/ ├── images/ │ ├── train/ # 325 张 jpg │ └── val/ # 135 张 jpg ├── labels/ │ ├── train/ # 325 个 txt │ └── val/ # 135 个 txt └── visualize.py # 可视化脚本图像文件名带有一串哈希后缀比如Stone-704-_jpg.rf.126844d1883d78e6d1944795d8b7bf4d.jpg标签文件则是同名.txt。这种命名方式不影响训练YOLOv5 靠的是文件名主干匹配只要 images 和 labels 下的文件名主干一致就行。常见做法是保持原样不动避免批量重命名时把对应关系搞乱。如果你非要改成001.jpg、001.txt这种务必用脚本同步改两边别手动操作。2.2 标签格式与类别定义每个 txt 里一行代表一个目标格式是class_id x_center y_center width height坐标都是归一化到 0~1 之间的浮点数。这份数据只有两个类别按 YOLOv5 的惯例0对应肾脏1对应结石。你需要自己建一个data.yaml内容大致如下# data.yaml path: ./datasets # 数据集根目录 train: images/train # 训练集图像相对路径 val: images/val # 验证集图像相对路径 nc: 2 # 类别数 names: [kidney, stone] # 类别名称顺序必须与标签里的 class_id 对应这里有个容易翻车的地方names的顺序不能拍脑袋写。如果你把stone写在前面那标签里的0就变成结石了训练出来的模型会把肾脏识别成结石。验证方法很简单用可视化脚本画几张图看框上的标签文字对不对。2.3 可视化脚本的运行与参数说明包里提供了一个visualize.py随机传入一张图片就能画出边界框并保存到当前目录。常见写法是这样# visualize.py import cv2 import random import os # 配置路径 img_dir datasets/images/train label_dir datasets/labels/train class_names [kidney, stone] # 与 data.yaml 保持一致 # 随机选一张图 img_files os.listdir(img_dir) img_name random.choice(img_files) img_path os.path.join(img_dir, img_name) label_path os.path.join(label_dir, img_name.replace(.jpg, .txt)) # 读图 img cv2.imread(img_path) h, w img.shape[:2] # 读标签并画框 with open(label_path, r) as f: for line in f.readlines(): cls, xc, yc, bw, bh map(float, line.strip().split()) # 反归一化 x1 int((xc - bw / 2) * w) y1 int((yc - bh / 2) * h) x2 int((xc bw / 2) * w) y2 int((yc bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, class_names[int(cls)], (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) cv2.imwrite(vis_result.jpg, img) print(f已保存可视化结果vis_result.jpg)逻辑很直白随机抽一张图找到同名标签把归一化坐标还原成像素坐标画矩形和类别名。参数方面class_names必须和data.yaml里的names完全一致否则框上的文字会张冠李戴。cv2.rectangle的线宽和字体大小可以按自己喜好调不影响数据本身。跑完在当前目录会生成vis_result.jpg打开看一眼如果框的位置和 CT 片上的肾脏、结石对得上说明数据没问题。提示如果脚本报FileNotFoundError先检查img_dir和label_dir是不是写成了绝对路径或者当前工作目录不在数据集根目录下。用os.path.abspath打印一下实际路径最稳妥。3. 把数据喂给 YOLOv5训练配置、超参数与显存控制3.1 环境准备与依赖版本YOLOv5 对 PyTorch 和 CUDA 版本比较敏感常见做法是建一个干净的 conda 环境conda create -n yolov5_ct python3.8 conda activate yolov5_ct pip install torch1.12.1cu113 torchvision0.13.1cu113 -f https://download.pytorch.org/whl/torch_stable.html pip install -r requirements.txtrequirements.txt在 YOLOv5 仓库根目录下主要包含numpy、opencv-python、matplotlib、pyyaml、tqdm等。如果你用的是 30 系或 40 系显卡cu113 一般能覆盖。装完用python -c import torch; print(torch.cuda.is_available())验证一下输出True才算就绪。这一步翻车最多的情况是 CUDA 版本和驱动不匹配报CUDA error: no kernel image is available for execution on the device那就换对应的 cu 版本重装。3.2 修改配置文件与启动训练把数据集放到 YOLOv5 根目录下的datasets文件夹然后确认data.yaml里的path指向正确。启动训练的命令python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data data.yaml \ --weights yolov5s.pt \ --project runs/train \ --name ct_kidney_stone参数逐个说--img 640和图像原始分辨率一致不用缩放--batch 16在 8G 显存下跑 yolov5s 基本稳显存不够就降到 8--epochs 100对小数据集来说够收敛了但要注意过拟合--weights yolov5s.pt用预训练权重能加快收敛别从零开始--project和--name决定输出目录跑完在runs/train/ct_kidney_stone下能看到权重、日志和验证结果。3.3 小样本下的超参数调整与数据增强460 张图在目标检测里算小样本默认超参数可能让模型在训练集上表现很好、验证集上拉胯。我一般会改几个地方把--epochs降到 80~120 之间配合--patience 20早停验证集损失不降就停。数据增强用默认的 mosaic、HSV 抖动、随机翻转就够了别再加 cutout 之类的医学图像本身纹理就少过度增强反而引入噪声。学习率用默认的--lr0 0.01配合余弦退火如果 loss 震荡厉害降到 0.005 试试。还有一个容易被忽略的点--cache参数。数据集小加--cache ram能把图像缓存到内存每个 epoch 省几秒读取时间100 个 epoch 下来能快不少。但如果你同时跑多个实验内存可能吃紧那就用--cache disk。注意训练日志里重点看mAP0.5和mAP0.5:0.95两个指标。小数据集上 mAP0.5 能到 0.85 以上就算不错如果一直低于 0.5先回去检查标签类别对不对再考虑调参。4. 避坑与排查从标签错位到过拟合的五个血泪经验4.1 现象训练 loss 正常下降但验证集 mAP 始终为 0原因标签文件里的class_id和data.yaml的names顺序对不上或者标签路径没被正确索引到。YOLOv5 在训练前会做一次标签缓存如果缓存生成时路径错了后续都读不到标签。解决删掉datasets/labels下的*.cache文件检查data.yaml里train和val的路径是不是相对于path的。用python utils/general.py --check-labels之类的工具不同版本命令略有差异扫一遍标签确保每个 txt 至少有一行且坐标都在 0~1 之间。4.2 现象可视化脚本画出来的框位置偏移严重原因图像在保存时被裁剪或缩放但标签还是按原始尺寸归一化的。这份数据标注时应该已经统一到 640×640但如果你自己用其他工具重新保存过图像尺寸变了标签没跟着变就会偏。解决用cv2.imread读图后打印img.shape确认是(640, 640, 3)。如果不是要么把图像 resize 回 640×640要么按实际尺寸重新归一化标签。别偷懒这一步错了后面全白搭。4.3 现象训练到 50 epoch 后验证集 loss 开始上升原因小数据集过拟合。模型把训练集的噪声也学进去了泛化能力下降。解决加早停--patience 15或者把--dropout打开YOLOv5 默认关闭再或者减少模型复杂度把yolov5s换成更小的yolov5n。另外检查一下验证集和训练集是不是有重复图像如果有去重后再跑。4.4 现象显存溢出报RuntimeError: CUDA out of memory原因--batch设太大或者--img设成了 1280 之类的更大尺寸。640×640 的图用 yolov5sbatch 16 在 8G 卡上一般没事但如果你同时开了其他进程就可能爆。解决先把 batch 降到 8 或 4再不行就加--accumulate 2做梯度累积等效 batch 不变但显存占用减半。另外用nvidia-smi看看是不是有其他僵尸进程占着显存。4.5 现象推理时框出一堆重叠的肾脏框原因NMS 的--conf-thres和--iou-thres没调好。默认 conf 0.25、iou 0.45在医学图像上可能过于宽松。解决推理时加--conf-thres 0.5 --iou-thres 0.3先把低置信度的框滤掉再收紧 IoU 阈值抑制重叠。如果还是多回去看训练时是不是把--multi-scale打开了关掉再训一版。5. 进阶技巧用验证集反推标注质量与模型边界5.1 从验证集混淆矩阵看类别混淆YOLOv5 训练完会在输出目录生成confusion_matrix.png。这份数据只有两类矩阵是 2×2 的。重点看对角线如果肾脏和结石的识别准确率都高说明标注一致性好如果某一类经常被误判成另一类比如结石被大量标成肾脏那要么是标注时边界模糊要么是两类在 CT 上确实难分。我一般会把误判的图挑出来用可视化脚本重新画一遍框肉眼确认到底是标注错了还是模型没学好。5.2 用val.py做批量验证与阈值扫描训练完别只看最后一行 mAP跑一遍val.py能拿到更细的指标python val.py \ --data data.yaml \ --weights runs/train/ct_kidney_stone/weights/best.pt \ --img 640 \ --batch 8 \ --conf-thres 0.001 \ --iou-thres 0.6 \ --task val--conf-thres 0.001是为了让所有预测框都参与 mAP 计算避免低置信度但正确的框被提前滤掉。跑完看precision-recall曲线如果曲线在 recall 0.8 之后 precision 断崖下跌说明模型在高召回区间误检多实际部署时把 conf 阈值设在拐点附近就行。5.3 一个具体技巧用--save-txt导出预测结果做二次分析推理时加--save-txt会把预测框的坐标和置信度存成 txt格式和标签一样。你可以写个小脚本对比预测框和真实标签算一下每个类别的平均 IoU。如果结石的平均 IoU 明显低于肾脏说明结石的边界标注可能偏松或者结石本身在 CT 上就模糊。这个反馈能帮你决定要不要重新标注一部分数据。# compare_iou.py import os import numpy as np def xywh2xyxy(box): x, y, w, h box return [x - w/2, y - h/2, x w/2, y h/2] def iou(box1, box2): b1 xywh2xyxy(box1) b2 xywh2xyxy(box2) inter_x1 max(b1[0], b2[0]) inter_y1 max(b1[1], b2[1]) inter_x2 min(b1[2], b2[2]) inter_y2 min(b1[3], b2[3]) inter_area max(0, inter_x2 - inter_x1) * max(0, inter_y2 - inter_y1) area1 (b1[2] - b1[0]) * (b1[3] - b1[1]) area2 (b2[2] - b2[0]) * (b2[3] - b2[1]) return inter_area / (area1 area2 - inter_area 1e-6) # 读取预测和标签按类别统计平均 IoU # 这里省略文件遍历逻辑核心是逐行解析并匹配这个脚本不用写太复杂核心就是逐行读预测 txt 和标签 txt按类别分组算 IoU。跑完你会对数据质量有个量化认识比拍脑袋强。从那以后我每次拿到新数据集都强制先跑一遍可视化脚本随机抽 20 张图看框再跑一遍val.py看混淆矩阵确认没问题才开训。这个习惯帮我省了至少三次重训的时间。希望帮到你。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →