尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
YOLOv5训练X光肺病数据集:从Roboflow格式到工程落地全记录
简介面向医学影像分析与深度学习检测场景这套X光片肺病数据集包含800张原始胸片及对应标注覆盖细菌性肺炎、新冠病毒、正常肺、结核、病毒性肺炎五类适合用于训练YOLOv5等目标检测模型帮助研究者快速搭建肺病辅助诊断原型。压缩包共1601个文件由800个jpg图像、800个txt标签文件及1个yaml配置组成txt按YOLO格式记录目标类别与边界框坐标yaml定义类别名称与路径数据组织规范可直接接入训练流程。资源整体约25.51MB已有410人学习。对于初学者可省去采集与标注环节直接用于模型训练、验证与论文实验对研究者也可作为多分类肺病检测的基准数据补充。1. 这包 X 光片肺病数据集到底能不能直接喂给 YOLOv5做医学影像目标检测的人最烦的不是模型调参而是数据集的“脏”。标签错位、格式不统一、类别分布离谱这些坑能让人在数据预处理上消耗掉比训练多三倍的时间。我拿到这包X光片肺病数据集时第一反应是先验证它是不是“开箱即用”800张原始图片已用YOLOv5格式标记覆盖细菌性肺炎、新冠病毒、正常肺、结核、病毒性肺炎五个类别并且文件带有明显的Roboflow导出特征。这意味着坐标系已经归一化、标签和图片一一对应、分类名已经写进配置——理论上解压后改一下路径就能启动训练。这篇笔记就是我从拆包到跑通全流程的记录目录结构怎么认、YOLOv5的标签格式长什么样、训练参数怎么设、哪些坑我替你先踩了。适合谁看正在做肺病分类或检测课题的学生、刚接触YOLOv5想拿真实数据集练手的开发者、以及需要快速验证检测方案可行性的算法工程师。2. 先拆包Roboflow 导出结构和 YOLOv5 标签格式的对应关系2.1 文件命名里藏的信息.rf. 后缀与数据来源解压后你会看到一堆类似1_coronavirus-420-_jpg.rf.9a9483366b10e7935eac8e4bd2b7a0ab.jpg的文件。这个命名格式是 Roboflow 导出的典型特征。拆解一下1_coronavirus-420-_jpg是原始文件名和类别提示.rf.后面那串哈希值是 Roboflow 为每个样本生成的唯一 ID用来保证导出后文件名在各类别间不冲突。如果你用脚本重新整理数据集这个哈希 ID 可以当作主键用避免重命名时把训练集和验证集的对应关系搞丢。文件名里的Normal_test-3-、Normal_val-27-这类前缀还暗示了 Roboflow 切片时的原始划分逻辑——test、val、train 的痕迹在文件名里就有后面整理目录时可以据此二次校验。这给我们的第一个实操启示不要一上来就自己重命名文件先保留原始命名跑通一次训练确认数据和标签匹配再做任何美化操作。我见过太多人第一个小时就花在写重命名脚本上结果脚本边界条件写错训练时一堆 no labels 报错得不偿失。2.2 labels 目录与 txt 标签格式详解Roboflow 导出 YOLOv5 格式时图片和标签是分目录存放的。典型结构是dataset/ ├── train/ │ ├── images/ │ │ └── 1_coronavirus-420-_jpg.rf.9a9483366b10e7935eac8e4bd2b7a0ab.jpg │ └── labels/ │ └── 1_coronavirus-420-_jpg.rf.9a9483366b10e7935eac8e4bd2b7a0ab.txt ├── valid/ │ ├── images/ │ └── labels/ └── data.yaml每个.txt标签文件里一行对应一个标注框格式是class_id center_x center_y width height注意坐标全部是归一化的取值范围 0~1不是像素值。这是 YOLOv5 训练硬性要求如果你的原始数据是像素坐标Pascal VOC 或 LabelMe 导出必须先除以图片宽高做归一化否则 loss 直接飞掉模型什么都学不到。我自己写过一个最小转换脚本逻辑大概长这样import os from PIL import Image def voc_to_yolo(txt_path, img_path, out_path, class_map): # 读取图片尺寸用于归一化 w, h Image.open(img_path).size with open(txt_path, r) as f: lines f.readlines() out_lines [] for line in lines: # VOC格式: xmin ymin xmax ymax class_name parts line.strip().split() if len(parts) ! 5: continue xmin, ymin, xmax, ymax map(float, parts[:4]) class_name parts[4] cls_id class_map[class_name] # 中心点和宽高都按像素转归一化 cx (xmin xmax) / 2 / w cy (ymin ymax) / 2 / h bw (xmax - xmin) / w bh (ymax - ymin) / h out_lines.append(f{cls_id} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}\n) with open(out_path, w) as f: f.writelines(out_lines) # 用法把VOC格式txt转为YOLO格式 # class_map 决定类别ID要和 data.yaml 里的顺序严格一致逻辑说明这个函数的核心工作是把 VOC 的左上右下坐标转成中心点加宽高的归一化表示。前四步换算缺一不可——中心点 X 是左右取平均再除以宽中心点 Y 是上下取平均再除以高宽高直接做差后除以对应尺寸。参数说明class_map必须手动维护比如{bacterial_pneumonia: 0, coronavirus: 1, normal: 2, tuberculosis: 3, viral_pneumonia: 4}这个顺序要和data.yaml里的names列表一一对应。顺序错了训练照样跑但推理结果是乱的这种错误最阴。2.3 data.yaml 配置与五分类映射data.yaml是整个数据集的配置文件YOLOv5 训练时第一个读的就是它。内容大致是train: ../dataset/train/images val: ../dataset/valid/images nc: 5 names: [bacterial_pneumonia, coronavirus, normal, tuberculosis, viral_pneumonia]我的建议是拿到手先手动改train和val为绝对路径或项目相对路径不要用 Roboflow 导出时的默认相对路径。这个文件里最容易翻车的坑是nc与names长度不一致——Roboflow 偶尔会因为在标注时删过类别导致 names 列表里残留了空类别。你可以在终端里快速验证python -c import yaml; dyaml.safe_load(open(data.yaml)); print(nc:, d[nc]); print(names:, d[names]); print(count match:, d[nc]len(d[names]))如果输出count match: False说明你的数据配置有问题训练时类别数会错位。正常情况下这包数据集的nc是 5对应摘要里说的五类。我每次训练前都强制自己跑一遍这段检查脚本——花十秒省三小时。3. 把数据集跑进 YOLOv5环境配置、训练命令与参数选择3.1 环境版本对照与 conda 快速安装YOLOv5 对 PyTorch 版本有隐性要求。我常用的组合是 Python 3.9 PyTorch 1.13 CUDA 11.7这个组合跑官方仓库的 requirements 基本不踩坑。如果 CUDA 版本不对会报AssertionError: CUDA unavailable之类的问题。conda create -n yolo5 python3.9 -y conda activate yolo5 pip install torch1.13.1cu117 torchvision0.14.1cu117 --extra-index-url https://download.pytorch.org/whl/cu117 git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt逻辑说明先建独立环境避免污染已有环境然后按 CUDA 版本安装对应 PyTorch 轮子最后拉最新 YOLOv5 仓库并安装依赖。参数说明https://download.pytorch.org/whl/cu117是指定 PyTorch 版本与 CUDA 版本的配套来源requirements.txt里包含 opencv-python、pandas、matplotlib 等依赖如果安装失败通常是 numpy 版本冲突手动pip install numpy1.23.5能解决大多数这类问题。3.2 目录挂载与路径检查训练前把数据集目录和 YOLOv5 仓库放到同一层级比如project/ ├── yolov5/ ├── dataset/ │ ├── train/ │ ├── valid/ │ ├── data.yaml然后确认数据集里有没有 test 目录。Roboflow 导出时通常会包含 test 集但 YOLOv5 的 train.py 只认 train 和 valtest 不会被读取。所以你要么忽略 test要么把 test 并进 val 增强验证集多样性。对 800 张图的小数据集我更建议把 test 合并进 val——验证集大一点mAP 指标参考性更强。# 在项目根目录运行检查图片和标签数量是否匹配 python -c import os for split in [train, valid]: imgs os.listdir(fdataset/{split}/images) labels os.listdir(fdataset/{split}/labels) img_names {x.split(.)[0] for x in imgs if x.endswith(.jpg)} label_names {x.split(.)[0] for x in labels if x.endswith(.txt)} print(split, images:, len(img_names), labels:, len(label_names)) print(missing labels:, len(img_names - label_names)) 如果missing labels不为 0说明有图片没有对应标注YOLOv5 会忽略这些图片但会打印 warning不影响整体训练但会白白浪费样本。我一般会把这些孤儿图片挑出来单独检查看是不是标注时漏了。3.3 训练命令参数解读imgsz、batch、epochs 与类别权重训练命令我实际用的是这一条python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data ../dataset/data.yaml \ --cfg models/yolov5s.yaml \ --weights yolov5s.pt \ --workers 4 \ --name chest_xray_run关键参数逐个说明--img 640输入图片统一缩放到 640×640。X 光片长宽比通常接近 1:1直接缩放不会造成严重形变。如果你的显卡显存有限降到 512 也可以但小目标比如早期病灶会丢失细节。--batch 16批量大小取决于显存。我用 8G 显存跑 640 输入batch 16 是上限再大会 out of memory。如果显存不足优先降 batch不要降 img。--epochs 100800 张图的数据量100 轮是起步。医学影像特征差异大一般 60 轮后 mAP 才稳定。早停机制可以在 val 指标连续 20 轮不涨时自动截断省训练时间。--cfg models/yolov5s.yamls 是 small 版本适合小数据集速度快、不容易过拟合。如果你发现欠拟合明显训练集 mAP 都很低换 m 或 l 版本前先检查标注质量而不是盲目加大模型。--weights yolov5s.pt用 COCO 预训练权重做迁移学习初始化。这个很重要——医学影像虽然和自然图像差异大但底层纹理特征迁移仍然有效。不要用--weights 从零训练小数据集会收敛得很慢。另外--weights指定预训练权重后类别数不匹配不会报错。YOLOv5 会忽略预训练权重中与当前模型输出层形状不一致的部分只迁移 backbone 层。这是官方行为不算 bug。3.4 类不平衡问题这包数据里谁多谁少从文件名初步估算coronavirus 类别的样本量明显多于结核和正常肺。这种不平衡在小数据集上会导致模型偏好头部类别。两个处理手段第一个手段是类别权重。在训练命令里加--cls 0.7--cls控制分类 loss 的权重系数。默认是 0.5当你发现少数类别 recall 明显偏低时可以加大到 0.7~1.0代价是定位精度可能轻微下降因为模型更努力区分类别而不是精修框。第二个手段是数据增强。YOLOv5 内置的 mosaic 增强会把四张图拼成一张相当于扩大了少数类别的有效样本量。--hyp hyp.scratch-low.yaml里mosaic: 1.0是默认开启的。对小数据集我建议保留默认增强强度不要盲目加大hsv_h、hsv_s——X 光片是灰度图颜色抖动对灰度图几乎无效反而浪费算力。4. 训练与推理避坑四类常见翻车现场4.1 现象一训练开始后 loss 一直是 NaNLoss 输出显示nan训练无法继续。常见原因有两个学习率设置过高或标签坐标越界。YOLOv5 默认学习率是 0.01配合 SGD 优化器一般不会爆。优先检查标签文件——用文本编辑器打开任意一个 txt如果坐标值大于 1 或小于 0说明归一化步骤出了问题。解决写个脚本过滤所有标签文件中越界的坐标并把对应图片移出数据集或者重新检查转换逻辑。python -c import os for split in [train, valid]: label_dir fdataset/{split}/labels for name in os.listdir(label_dir): with open(os.path.join(label_dir, name)) as f: lines f.readlines() for line in lines: parts line.strip().split() if len(parts) 5: vals list(map(float, parts[1:])) if not all(0 v 1 for v in vals): print(bad:, name, line.strip()) 4.2 现象二valid 集的 mAP 是 0但训练 loss 在下降训练集和验证集表现严重脱节。我复盘过这类问题最常见的原因是目录读取错误——data.yaml 里val路径指到了空目录或不存在目录YOLOv5 不会报错只会默默把验证集当作空集对待于是 mAP 恒为 0。解决用--exist-ok重新指定验证集路径训练前手动打印yaml.safe_load确认 val 路径存在且图片数量不为 0。这属于路径问题不是模型问题改配置就解决了。4.3 现象三训练时报错 exit code 135这类错误通常是 OOM显存不足或系统内存不足。YOLOv5 的 dataloader 会一次性缓存图片到内存800 张 640×640 的图片大约需要 1GB 内存但如果同时开--workers 8内存会被打满。解决把--workers降到 4 或 2显存不足时同时降低 batch。如果你用 Windowsworkers 大于 0 还会触发 DataLoader 的 spawn 模式问题这时必须保证训练入口是if __name__ __main__包裹否则会无限递归报错。4.4 现象四推理时识别出的类别顺序和真实类别对不上训练时data.yaml里 names 顺序是[bacterial_pneumonia, coronavirus, normal, tuberculosis, viral_pneumonia]推理脚本里如果单独新建了一个类别列表顺序写错就会导致模型输出索引 0 被认为是 normal但实际 0 对应的是 bacterial_pneumonia。解决推理时直接yaml.safe_load载入 data.yaml用它的 names 列表做映射不要手写第二遍。这类问题最难排查但也是最容易预防的——统一走配置不硬编码。5. 模型验证与进阶检查看到置信度之外的信息5.1 误判模式分析哪些类别容易混淆训练完成后用val.py生成混淆矩阵。对于这个数据集常见的混淆对是「病毒性肺炎」与「细菌性肺炎」——两者在 X 光片上的磨玻璃影和实变影存在重叠区域即使有经验的放射科医生也会借助临床指标辅助判断。另一个高频混淆是「正常肺」被误判为「早期结核」因为早期结核病灶在 X 光片上可能只是一小片模糊影和纹理噪声几乎无法区分。我的做法是把混淆矩阵导出后挑出错误样本逐张看重点观察标注框的位置是否合理。比如结核误判为正常很多时候不是因为模型烂而是因为标注框只框住了病灶的一小部分模型学到的是一个局部纹理而不是完整的病灶语义。5.2 用滑窗推理看模型对大片 X 光片的真实表现800 张原图中很多是单张肺部正位片推理时整图缩放 640 后用一次前向可以覆盖完整肺部结构。但如果你打算把模型接到真实 PACS 流程里面对的片子可能是 3000×3000 甚至更大的原始 DICOM 转出的 JPG直接缩放会导致小病灶在 resize 过程中直接丢失。我一般会跑一遍滑窗推理验证边界import cv2 import torch from PIL import Image def slide_infer(model, img_path, window640, stride320): img cv2.imread(img_path) h, w img.shape[:2] dets [] for y in range(0, h - window 1, stride): for x in range(0, w - window 1, stride): crop img[y:ywindow, x:xwindow] crop_rgb cv2.cvtColor(crop, cv2.COLOR_BGR2RGB) result model(crop_rgb, sizewindow) for box in result.xyxy[0]: x1, y1, x2, y2, conf, cls box.cpu().numpy() dets.append((x x1, y y1, x x2, y y2, conf, cls)) return dets逻辑说明滑窗把大图拆成若干个 640×640 窗口重叠区用 320 的步长保证目标跨窗口时至少在一个窗口内完整呈现。窗口检测结果还原到原图坐标时要加上窗口偏移量(x, y)。参数说明window640要和训练时的--img 640保持一致stride320是窗口步长越小重叠越多、检测越稳但耗时越长。医学影像病灶通常不会恰好停在窗口边界所以重叠步长是必须的——如果步长等于窗口大小跨窗口目标会被切断漏检率显著上升。5.3 置信度阈值调整的两个回合实际使用时conf-thres默认是 0.25iou-thres是 0.45。但医学场景的漏诊代价远高于误报代价也就是宁可多标一个可疑区域让医生二次确认也不要漏掉一个病灶。第一回合跑一遍验证集按类别统计置信度分布。少数类别比如结核如果置信度中位数已经低于 0.25说明模型对这类样本本身就缺乏自信强行调低阈值只会引入大量噪声。第二回合把阈值调到 0.15重新跑val.py看召回率的提升幅度。如果提升很小说明问题不在阈值而在特征学习不足回到数据增强或加训练轮次。这一步是最容易忽略的环节很多项目合成后拿默认阈值就交付实际部署到含噪声的临床影像上漏检率会比验证集高出一大截。从那以后我每次调模型都强制自己走一遍滑窗和阈值敏感度分析确认在低置信度区间内模型输出是否仍保持稳定。X 光肺病检测的落地点不在训练指标有多漂亮而在真实读片场景里能不能帮医生少漏一个病灶——把数据、模型、推理链路都吃透才能离这个目标更近一点。希望这篇拆包笔记能帮你在自己的数据集上少折腾几个小时。本文还有配套的精品资源点击获取
RELATED

相关推荐

从39.7%到0%:知网AIGC检测降AI率完整实操指南

从39.7%到0%:知网AIGC检测降AI率完整实操指南

前阵子有个朋友抱着笔记本电脑来找我,说学校的预审系统给他论文标了一个数字:知网AIGC检测率39.7%。学院要求降到10%以下才能送审,他连续折腾了快两周,同义词替换、调整语序、把中文翻成英文再翻回来,能用的土办法都试…

📅 2026/9/28 5:25:55
Flutter纯Dart库鸿蒙适配实践:以checkdigit校验库为例

Flutter纯Dart库鸿蒙适配实践:以checkdigit校验库为例

最近把一套 Flutter 项目整体迁到鸿蒙上,过程中遇到checkdigit这个库,倒是让我对“Flutter 三方库鸿蒙化适配”这件事有了不少新认识。这个东西本身很小,就是做各类识别码校验的,ISBN、IMEI、身份证号、信用卡号、Luhn 校验码一套…

📅 2026/9/28 5:25:55
支付宝手机网站支付前端怎么做图解步骤全解析

支付宝手机网站支付前端怎么做图解步骤全解析

支付宝手机网站支付前端怎么做图解步骤全解析 网站做好了没人访问,这大概是很多站长和开发者最头疼的事。尤其是当你花了几万块做了个商城,结果用户到了付款环节,要么页面卡死,要么支付跳转白屏,流量全漏了。很多人搜【支付宝手机网站支付前端怎么做】,…

📅 2026/9/28 5:25:55
MORE NEWS

更多资讯

📰

转向语句讲解

目录 概述: 一.break语句: 1).用于跳出循环: 2).用于跳出switch语句: 注意事项: 二.continue 1).对于do while循环与while循环 2).对于for循环: 3&a…

📰

关键字 typedef 用法详细解析

一 . typedef:1.什么是typedeftypedef 是C语言中的一个关键字,它的作用是给一个已经存在的类型起一个别名。typedef 可以为基本数据类型、自定义数据类型(结构体、共用体、枚举类型)、数组和指针定义简洁的类型名称。一旦用户在程…

📰

#define和#、##、@#解析:

目录 前言: 1.什么是预处理: 2.#define是什么: 一.关于#define: 1).#define 的标识符定义: 2).#define 的函数定义: 3)#define 的续行操作: 4)#define…

📰

NewsBlur 自托管部署与 MCP 智能体接入完整指南:从 Docker Compose 到 AI 阅读助手

后端前端社交人工智能 【免费下载链接】NewsBlur NewsBlur is a personal news reader that brings people together to talk about the world. A new sound of an old instrument. 项目地址: https://gitcode.com/gh_mirrors/ne/NewsBlur 点击查看 免费下载 本文基…

📰

Markdown开发VSCode插件推荐:用TaoToken统一Key打通AI写作与预览链路

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

📰

广州二手房价预测:数据清洗、特征工程与模型调参全解析

简介:这是一份面向数据分析学习者与房地产研究爱好者的广州市二手房价预测实践资源,包含广州市二手房交易数据集和完整的Python建模代码,围绕价格预测任务演示了从数据清洗、特征工程到模型训练评估的典型流程。压缩包共19个文件,…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬