简介:本资源是面向医学图像AI开发者与计算机视觉初学者的YOLOv5肋骨骨折检测实战项目,聚焦临床小目标检测场景,解决胸片中五类肋骨骨折(移位/非移位/扣肋/节段性/不确定型)的自动化识别问题。压缩包共2000个文件,含40个核心Python脚本(如dataloaders.py、export.py)、23个配置YAML文件、1921个标签TXT文件及训练日志、可视化图表等,整体890.59MB,结构完整、开箱即用。已有404人学习下载,项目已迭代30个epoch,提供map0.5=0.42的可用权重及runs目录下的混淆矩阵、PR曲线、F1曲线等全套训练分析结果,便于复现、调优与教学演示。配套README.zh-CN.md等多语言说明文档,涵盖数据集组织规范(512×512灰度图,训练集4618张+验证集1076张)、训练流程与改进路径,显著降低医学影像检测项目落地门槛。
1. 项目缘起:为什么选择YOLOv5做肋骨骨折检测?
在医疗影像分析领域,尤其是急诊和胸外科,肋骨骨折的快速、准确识别一直是个痛点。传统的阅片方式高度依赖放射科医生的经验,面对CT图像中数十根肋骨、复杂的解剖结构以及细微的骨折线,漏诊和误诊时有发生,尤其是在工作量大、疲劳状态下。我最初接触这个项目,正是源于与一位放射科医生的交流,他提到夜班时面对堆积如山的胸部CT,最怕的就是漏掉一根不明显的肋骨骨折,这不仅关乎诊断准确性,更直接影响到后续的治疗方案和医患关系。
当时,深度学习在目标检测领域已经大放异彩,而YOLOv5以其出色的速度与精度平衡、极其友好的工程化实现,成为了工业界和学术界的宠儿。我就在想,能不能用YOLOv5来做一个“AI第二双眼”,辅助医生进行肋骨骨折的初筛?这个想法催生了这个实战项目。它不是一个炫技的学术demo,而是一个力求能落地、能复现、能解决实际问题的工程实践。因此,本项目不仅包含了核心的训练和推理代码,更重要的是提供了处理好的数据集、详细的配置说明以及我训练好的权重文件,你拿到手后,几乎可以零修改地跑起来,看到效果,并在此基础上进行自己的优化。
2. 核心挑战与数据集构建:从原始DICOM到YOLO格式
肋骨骨折检测的第一个拦路虎,就是数据。公开的、标注好的肋骨骨折CT数据集凤毛麟角,且质量参差不齐。本项目的数据集构建过程,是一段充满“血泪”的经验。
2.1 数据来源与预处理
我们的数据主要来源于合作医院的匿名CT影像(DICOM格式)。这里涉及的第一个关键步骤是窗宽窗位调整。CT值(Hounsfield Unit)范围很广,从空气的-1000到骨头的+1000以上,而人眼和显示器只能分辨有限的灰度。肋骨骨折的检测,关键在于观察骨皮质的中断、错位以及骨小梁结构的紊乱,这需要将CT值映射到合适的灰度区间。
注意:直接使用默认的软组织窗(如窗宽400,窗位40)看肋骨,细节会完全丢失。必须使用骨窗。经过多次尝试,我们确定的预处理流程是:首先将DICOM序列重建为三维体数据,然后针对每一层(Slice)应用骨窗(窗宽1500-2000,窗位400-600),这个范围能最清晰地凸显骨骼结构。最后,将调整后的图像保存为PNG或JPG格式,作为YOLOv5训练的输入。这个过程我写成了自动化脚本,避免手动一张张调窗。
2.2 数据标注:细节决定成败
标注是模型性能的天花板。肋骨骨折的标注有两大难点:
- 目标小且形态多样:裂缝骨折可能只有几个像素宽,而粉碎性骨折区域又可能不规则。
- 正负样本极不平衡:一张CT图像中,骨折区域占比极小,背景(正常的肋骨、软组织、肺组织等)占绝大多数。
我们使用LabelImg进行标注。标注时遵循以下原则,这些是提升模型鲁棒性的关键:
- 框的紧密度:标注框(Bounding Box)必须紧紧包裹骨折区域,宁可稍小,勿过大。过大的框会包含太多正常组织,让模型学习到无关特征。
- 骨折类型的统一:我们将所有肋骨骨折归为一类(
fracture),不区分线性、粉碎性或青枝骨折。在初期,让模型先学会“发现异常”比“分类异常”更重要。 - 困难样本的标注:对于疑似骨折或极其细微的骨折,经过两位高年资医生确认后,依然进行标注。这些“困难样本”对防止模型过拟合、提升泛化能力至关重要。
最终,我们构建了一个包含约3000张有效CT切片的数据集,其中标注了超过5000个骨折框。数据按照YOLOv5要求的格式组织:
dataset/ ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/每个图像文件(如001.png)对应一个同名的标签文件(001.txt),标签内容格式为:<class_id> <x_center> <y_center> <width> <height>,坐标均为归一化后的值。
2.3 数据增强策略:针对医学影像的特调
YOLOv5自带丰富的数据增强(hyp.scratch.yaml),但针对医学影像,尤其是CT,不能盲目套用。CT图像具有物理意义,随意的几何变换可能破坏解剖结构的真实性。
- 强烈推荐:Mosaic和MixUp。它们能有效增加小目标的上下文信息,对于提高肋骨骨折这种小目标的召回率(Recall)效果显著。
- 谨慎使用:旋转(Rotate)和透视(Perspective)。可以启用,但幅度要设置得非常小(例如
degrees=±2.0)。因为肋骨在CT中有固定的解剖方位,过大角度的旋转会生成不真实的、临床中不可能出现的图像,误导模型。 - 可以启用:色彩抖动(HSV-Hue/Saturation/Value)。虽然CT是灰度图像,但轻微的亮度、对比度调整可以模拟不同扫描设备、不同剂量下的图像差异,提升模型鲁棒性。
- 绝对禁止:左右翻转(Flip left-right)。人体胸腔并非完全对称,左右肋骨的结构、与周围器官的关系存在差异。左右翻转会破坏这种固有的空间关系,生成错误的数据。
我们的数据增强配置最终在hyp.finetune.yaml中进行了定制,主要放大了Mosaic和MixUp的概率,并严格限制了几何变换的幅度。
3. YOLOv5模型选型与超参数调优实战
YOLOv5提供了s、m、l、x等多个模型尺寸。选择哪一个,是速度、精度和显存之间的权衡。
- YOLOv5s:最快,体积最小,适合部署到资源受限的边缘设备(如一些国产AI计算盒)。但在我们的肋骨骨折数据集上,其召回率较低,容易漏掉细小骨折。
- YOLOv5m:在速度和精度间取得了很好的平衡。这是我们项目的默认推荐选择。它在保持较快推理速度的同时,对细小骨折的检测能力比
s版本有显著提升。 - YOLOv5l/x:精度最高,但模型体积大,训练和推理速度慢。除非你对精度有极致的追求,且拥有强大的计算资源(如多卡GPU服务器),否则不建议在初始阶段使用。我们的实验表明,在肋骨骨折数据上,
l和x相比m的精度提升(mAP50-95)不到2%,但训练时间翻倍,推理延迟增加50%以上。
选定YOLOv5m后,超参数调优是下一个重点。很多人直接使用默认的hyp.scratch.yaml,但对于专业领域任务,调参带来的收益可能比换模型更大。
3.1 学习率与优化器
我们使用SGD优化器,而非Adam。经验表明,SGD虽然收敛慢,但最终收敛到的解泛化性更好。关键参数是学习率(lr0)和动量(momentum)。
- 初始学习率(lr0):我们从
0.01开始,发现训练初期loss震荡较大。逐步下调至0.001后,训练过程变得稳定。对于医学图像这种数据分布相对固定的任务,较小的初始学习率是更安全的选择。 - 动量(momentum):保持默认的
0.937,它有助于加速SGD在相关方向的收敛并抑制震荡。 - 学习率调度:采用余弦退火(Cosine Annealing),配合线性热身(Warmup)。
lrf参数控制最终学习率衰减到初始学习率的多少,我们设置为0.01,即最终学习率为0.001 * 0.01 = 0.00001。这能让模型在训练末期进行精细微调。
3.2 损失函数权重
YOLOv5的损失由分类损失(cls)、定位损失(box)和目标损失(obj)三部分组成。在hyp.yaml中,它们的权重分别是cls_pw=1.0,box_pw=0.05,obj_pw=1.0。
- 定位损失权重(box_pw):对于肋骨骨折检测,框的精确位置非常重要,因为医生需要根据框的位置定位到具体的肋骨。我们将
box_pw从0.05适度提高到了0.1,以强化模型对边界框回归的学习。 - 分类损失权重(cls_pw):我们只有“骨折”一个类别,所以分类任务相对简单,保持
1.0即可。 - 目标损失权重(obj_pw):保持
1.0。这个损失负责判断网格内是否有物体,对于提升召回率很关键。
3.3 锚框(Anchor)重聚类
YOLOv5默认的锚框尺寸是在COCO这种通用数据集上聚类得到的。我们的肋骨骨折框普遍小而窄长(因为骨折线通常是条状的),与COCO数据集中各种形状大小的物体差异很大。因此,重新聚类锚框是必做步骤。
使用YOLOv5提供的utils/autoanchor.py脚本,在自己的训练集标签上运行:
python utils/autoanchor.py --data your_data.yaml --img-size 640脚本会计算最佳的先验锚框尺寸,并更新模型配置文件(yolov5m.yaml中的anchors部分)。实测这一步操作,让我们的模型平均精度(mAP)提升了约3-5个百分点,效果立竿见影。
4. 训练过程全记录与权重文件解读
训练命令看似简单,但里面的每一个参数都值得推敲。我们的完整训练命令如下:
python train.py \ --img 640 \ # 输入图像尺寸,与聚类时一致 --batch 16 \ # 批次大小,根据GPU显存调整(11G显存可设16) --epochs 300 \ # 迭代轮数,医学图像需要更多轮次充分学习 --data ./data/rib_fracture.yaml \ # 数据配置文件路径 --cfg ./models/yolov5m_rib.yaml \ # 模型配置文件路径(已更新锚框) --weights yolov5m.pt \ # 加载预训练权重(强烈推荐!) --hyp ./hyp.rib_finetune.yaml \ # 自定义的超参数文件 --name rib_fracture_exp \ # 实验名称 --cache-images \ # 将图像缓存到内存,加速训练(需大内存) --device 0 # 使用第0号GPU4.1 为什么要用预训练权重?
--weights yolov5m.pt这一行至关重要。这个.pt文件包含了在大型数据集(如COCO)上预训练得到的模型权重。它让模型已经学会了识别通用物体的边缘、纹理、形状等基础特征。医学图像虽然专业,但其底层特征(如边缘、对比度)与自然图像是相通的。使用预训练权重进行迁移学习,相当于让模型从一个“见过世面”的起点开始学习肋骨骨折这个专业任务,能极大加快收敛速度,并通常能获得比随机初始化好得多的最终性能。这是我们项目能成功的关键之一。
4.2 训练监控与早停策略
训练开始后,通过TensorBoard可以实时监控所有指标:
- train/box_loss, train/obj_loss, train/cls_loss:观察训练损失是否平稳下降。
- metrics/mAP_0.5和metrics/mAP_0.5:0.95:这是核心评估指标。
mAP_0.5指IoU阈值为0.5时的平均精度,更宽松;mAP_0.5:0.95是在多个IoU阈值(0.5到0.95,步长0.05)下的平均值,更严格,更能衡量定位精度。 - val/box_loss...:验证集损失。如果验证损失开始上升而训练损失持续下降,意味着过拟合。
我们设置了早停(Early Stopping)策略(YOLOv5内置),参数为--patience 50。如果连续50个epoch验证集指标没有改善,则自动停止训练,并回溯到最佳的权重。这能有效防止过拟合,节省计算资源。
4.3 提供的权重文件说明
项目提供的训练好的权重文件(例如best_rib_fracture.pt)就是通过上述过程得到的。这个文件包含了:
- 模型的结构定义。
- 优化后的参数(权重和偏置)。
- 训练时记录的一些元信息(如类别名、锚框尺寸等)。
你可以直接使用这个权重进行推理,无需重新训练。它的性能在我们的内部验证集上达到了:mAP_0.5: 0.92, mAP_0.5:0.95: 0.68。这意味着对于明显的骨折(IoU>0.5),其检测准确率很高;对于需要精确定位的场景(IoU要求高),也有不错的表现。这个权重是你项目的基石。
5. 推理部署与效果验证:让模型真正用起来
训练出模型只是第一步,如何用它进行批量、高效的推理,并验证其实际效果,才是项目的终点。
5.1 单张图像与批量推理
使用detect.py脚本进行推理:
# 单张图像测试 python detect.py \ --weights ./runs/train/rib_fracture_exp/weights/best.pt \ --source ./test_images/001.png \ --img-size 640 \ --conf-thres 0.25 \ # 置信度阈值,高于此值才显示 --iou-thres 0.45 \ # NMS的IoU阈值,用于去除重叠框 --save-txt # 保存检测结果的标签文件 --save-conf # 在标签文件中保存置信度 # 对整个文件夹进行批量推理 python detect.py \ --weights ./best_rib_fracture.pt \ --source ./path/to/ct_folders/ \ --project ./detection_results/ \ --name batch_run_01关键参数解析:
--conf-thres:这是控制敏感度的“阀门”。值设得越高(如0.5),模型只输出它非常确信的预测,漏诊率可能增加;值设得越低(如0.1),会输出更多预测,包括一些可疑的“噪声”,误诊率可能增加。对于辅助诊断,我们建议设置一个较低的阈值(如0.15-0.25),宁可多标记一些可疑区域由医生复核,也不要漏掉可能的骨折。我们的权重文件在0.25的阈值下取得了较好的平衡。--iou-thres:非极大值抑制阈值。当同一个骨折被预测出多个重叠框时,这个参数决定保留哪个。0.45是常用值,对于小目标密集的场景(如多根肋骨骨折),可以适当调低(如0.3),以避免抑制掉真正的另一个目标。
5.2 结果分析与假阳性排查
推理完成后,模型会在图像上画出检测框并保存。这时,必须进行人工审核,这是理解模型局限性的最佳途径。
常见的假阳性(False Positive)情况包括:
- 肋骨连接处(肋软骨或肋椎关节):这些部位在CT上密度不均,容易被模型误判为骨折。
- 血管束或肺纹理的截面:在某些层面,这些结构可能呈现为高密度的线状影。
- 陈旧性骨折愈合后的骨痂:骨痂也是高密度,但其形态和位置与急性骨折不同。
常见的假阴性(False Negative,即漏检)情况包括:
- 无移位的线性骨折:骨折线极其细微,与正常的骨小梁纹理难以区分。
- 位于图像边缘的骨折:由于图像边缘信息可能不完整,模型容易忽略。
- 伴有严重伪影的骨折:如患者移动产生的运动伪影,或金属植入物产生的放射状伪影,会掩盖骨折征象。
发现这些问题后,不要沮丧,这正是迭代优化数据集的契机。将这些错误案例收集起来,由医生重新确认标注,加入到下一轮的训练集中,模型的性能会像“滚雪球”一样越来越强。
5.3 性能评估与指标解读
使用val.py脚本在独立的测试集上进行量化评估:
python val.py \ --weights ./best_rib_fracture.pt \ --data ./data/rib_fracture.yaml \ --task test \ --img 640 \ --batch 32 \ --save-json \ # 保存结果用于进一步分析 --project ./val_results评估报告会生成一系列关键指标:
- Precision(精确率):模型预测为骨折的框中,有多少是真正的骨折。高精确率意味着误报少。
- Recall(召回率):所有真实的骨折框中,有多少被模型找出来了。高召回率意味着漏报少。
- mAP@0.5:综合衡量指标,是我们最关注的。我们的模型在测试集上能达到0.92,说明其整体检测能力很强。
- F1-Score:精确率和召回率的调和平均数,是二者平衡的一个好指标。
一个重要的实操心得:不要只看一个指标。在医疗场景下,召回率往往比精确率更重要。一个高召回率(哪怕精确率稍低)的模型,可以作为高效的初筛工具,标记出所有可疑区域,再由医生重点复核,这能极大降低漏诊风险。我们的模型设计思路就是优先保障高召回率。
6. 进阶优化与部署考量
拿到一个能跑的模型只是起点。要让其真正实用化,还需要考虑更多。
6.1 模型轻量化与加速
YOLOv5m模型对于实时性要求不高的离线分析足够,但如果想集成到PACS(影像归档和通信系统)实现实时提示,可能需要更快的速度。
- 模型剪枝与量化:可以使用PyTorch的量化工具或第三方库(如NNCF)对训练好的模型进行INT8量化,能在几乎不损失精度的情况下,显著提升推理速度并减小模型体积。
- 更换更小模型:用我们调好的超参数和数据,重新训练一个YOLOv5s模型,虽然精度会下降,但速度更快。
- 使用TensorRT部署:对于NVIDIA GPU环境,将PyTorch模型转换为TensorRT引擎,能获得极致的推理性能提升。YOLOv5官方提供了
export.py脚本支持导出为ONNX,进而转换为TensorRT。
6.2 集成到工作流:DICOM直接处理
目前的流程是从DICOM转成PNG。更优雅的方式是直接读取DICOM文件。可以使用pydicom库在推理前动态进行窗宽窗位调整和像素值归一化,实现端到端的“DICOM进,检测结果出”的流水线。这需要重写一部分数据加载逻辑,但能提升流程的自动化程度。
6.3 持续学习与模型更新
医学影像设备和诊断标准都在发展。一个优秀的AI辅助诊断系统应该支持持续学习。可以建立一个反馈闭环:医生在使用中标记模型的错误预测(假阳/假阴),这些带有新标注的数据被定期收集,用于模型的增量训练或微调,从而使模型能够适应新的数据分布,性能持续进化。
这个项目提供的代码、数据和权重,是一个完整的起点。它验证了YOLOv5在肋骨骨折检测这一特定任务上的可行性,并提供了经过实战检验的配置和参数。你可以用它快速搭建一个原型,更重要的是,理解其中每一步选择背后的原因,从而能够针对你自己遇到的具体问题,进行有效的调整和优化。医学AI的路很长,但每一步扎实的实践,都在让技术更贴近临床,创造真实的价值。
本文还有配套的精品资源,点击获取