YOLOv5细胞检测实战:从目标检测原理到模型部署全流程

📅 发布时间:2026/9/1 17:45:08
YOLOv5细胞检测实战:从目标检测原理到模型部署全流程 医疗AI岗位是目前算法领域竞争最激烈的方向之一。从AI医学研究员、医疗AI算法工程师到医疗AI产品经理几乎所有岗位描述里都离不开医学影像、目标检测、模型评估这些关键词。真正进入这个领域之前多数人缺的不是医学知识而是一套能完整跑通的目标检测实战经验。用YOLOv5做细胞检测恰好是覆盖度很高的最小闭环细胞图像容易获取标注格式标准训练资源要求不高又能把环境搭建、数据准备、模型训练、效果评估和部署导出整条链路串起来。这篇文章就围绕这个案例把每一步的为什么、怎么做和常见坑讲清楚。1. 医疗AI三大岗位都在看什么能力细胞检测是公约数1.1 三类岗位的分工边界AI医学研究员、医疗AI算法工程师、医疗AI产品经理这三个岗位经常出现在同一个医疗AI项目里但很多人转岗时没有想清楚差异面试时也容易被问到“你在团队里到底承担什么职责”。为了避免“什么都会一点、什么都不深入”先明确各自的产出和判断标准。岗位核心产出典型工作技术侧重点AI医学研究员算法可行性方案、实验报告、模型评估结论文献调研、数据统计分析、设计对照实验、解释模型表现数据处理、模型原理、统计口径、可解释性医疗AI算法工程师可训练、可评估、可部署的模型和推理服务数据处理与增强、模型训练、调优、导出、接口封装、性能优化工程实现、训练链路、部署环境、日志排错医疗AI产品经理需求定义、标注规范、验收标准、交付节奏梳理临床流程、定义检测目标、组织标注、确认指标、跟进验证数据标注规范、评估口径、模型边界、风险控制三个岗位对技术的理解深度不同但有一个交集都必须看懂目标检测指标。研究员要判断模型在某个亚群上是否可靠算法工程师要回答数据格式对不对、训练是否收敛、部署能不能跑产品经理要回答检测到多少个细胞、漏检和误检是否可接受、医生复核流程怎么配合。这个交集正好可以用一个YOLOv5细胞检测项目来训练。1.2 一个YOLOv5细胞检测案例如何串起三批人如果团队刚开始做细胞检测通常的协作路径是产品经理先定义检测范围比如“识别血液涂片中的红细胞、白细胞、血小板”并明确哪些情况可以接受人工复核AI医学研究员确认公开数据或院内数据是否满足数量和质量要求给出初始的模型选型建议算法工程师负责把数据转成训练格式搭建YOLOv5环境训练出第一版模型再回到产品经理侧验收。这个流程里最容易出问题的环节是产品经理不知道算法工程师说的mAP50和临床需要的灵敏度、特异度有什么区别研究员不知道标注不一致为什么会导致模型分数虚高。所以三类岗位的人都应该动手跑一遍YOLOv5细胞检测用同一个项目理解对方的工作语言。这也是这个案例作为“公约数”的价值。2. 细胞检测为什么适合用YOLOv5作为起点2.1 目标检测要同时解决定位和分类两个问题细胞检测不是单纯的图像分类。分类任务只需要回答“这张图里有没有某种细胞”而检测任务要求把每个感兴趣的目标用矩形框标出来并同时给出类别和置信度。以YOLO格式为例一个预测结果的本质是类别索引 目标中心点坐标 目标宽高 置信度对一张病理或血液涂片图像来说YOLOv5会在多个尺度上生成大量候选框经过置信度过滤和非极大值抑制后保留最可能的目标框。理解这个流程就理解了为什么细胞检测项目里的输出文件往往包含坐标和置信度而不是只输出一个判断结论。2.2 为什么YOLOv5适合作为医疗图像检测的入门框架YOLOv5是单阶段目标检测算法中工程生态非常成熟的框架之一。它把数据加载、数据增强、训练日志、模型评估、权重导出等环节都封装成了命令行和Python脚本代码结构清晰社区资料多遇到问题也容易找到对应场景的讨论。虽然算法领域已经出现了更新版本的YOLO系列但YOLOv5在入门学习、自定义数据集适配和中小型项目落地方面仍然是不错的选择。YOLOv5提供n、s、m、l、x五个规格参数从小到大适合不同硬件条件模型参数规模适合场景YOLOv5n约1.9M边缘设备、快速验证流程YOLOv5s约7.2M学习入门、中小训练资源、时效要求高YOLOv5m约21.2M精度要求更高、硬件允许YOLOv5l约46.5M较大数据集、强GPUYOLOv5x约86.7M追求高精度、推理资源充足实际选择时不必追求最大模型。细胞检测目标较小在同样输入尺寸下模型参数大不代表一定更好还要看数据量、标注质量和硬件条件。入门阶段推荐YOLOv5s训练速度快部署压力小后续需要提升精度时再切换到更大规格。2.3 细胞检测场景的难点与YOLOv5的对应策略细胞检测相比通用物体检测有两个明显特点一是目标小且密集细胞之间经常接触甚至重叠二是染色条件、显微镜型号、切片厚度的差异会导致同一种细胞在不同图像里颜色和形态变化较大。YOLOv5的多尺度预测结构对小目标相对友好因为模型会在浅层特征图上保留更多位置信息但前提是训练数据必须覆盖这些变化。如果训练集只来自同一台显微镜的少量切片模型很容易过拟合并漏检新样本。另一个需要关注的策略是数据增强。YOLOv5内置了颜色空间扰动、平移、缩放、旋转、透视等增强参数对染色差异和位置偏移有一定抵抗效果但增强幅度过大会把细胞形状变得不真实反而影响精度。因此增强参数要结合验证集效果调整不要直接照搬默认值。3. 训练环境搭建先让官方YOLOv5能跑通再谈细胞数据3.1 先定硬件目标CPU验证流程还是GPU跑训练YOLOv5在CPU上也能运行但训练速度和推理速度都会慢很多。如果是第一次学习可以先在CPU环境用很小的图片集和少量轮数把整体流程跑通确认代码链路没有问题再切到GPU训练完整模型。这样能避免硬件问题和技术问题混在一起难以排查。常见硬件方案如下场景推荐配置说明纯CPU学习环境无特殊要求设置较小--img和--epochs先验证流程单张GPU训练显存8G~12G适合YOLOv5sbatch可设16~32医疗数据不出内网内网GPU服务器数据不能外传时不能依赖外部在线服务边缘设备部署NXP i.MX8MP、树莓派5等训练在PC/server完成部署时用ONNX等格式实际项目中训练环境建议先和试运行环境分开。训练机主要负责反复试验部署环境则要求模型体积小、推理速度快、稳定性高。二者不一定使用同一套硬件。3.2 安装PyTorch与YOLOv5依赖YOLOv5的依赖以PyTorch生态为基础。安装前要确认显卡驱动、CUDA版本、PyTorch版本三者匹配否则经常出现torch.cuda.is_available()返回False但系统日志里没有明显报错的情况。组件建议说明Python3.8~3.10具体以项目requirements.txt要求为准PyTorch1.8及以上根据机器CUDA版本安装对应版本torchvision与PyTorch版本匹配版本不匹配会在导入时报错CUDA11.x或12.x由显卡驱动决定先运行nvidia-smi确认GPU驱动较新的稳定版生产环境不要随意升级驱动获取YOLOv5源码并安装依赖git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt安装完成后先验证环境是否可用python -c import torch; print(torch.__version__, torch.cuda.is_available())如果输出中torch.cuda.is_available()为True说明GPU环境可用。如果网络受限导致依赖下载失败可以在可访问的网络环境中把依赖下载完整再离线安装不要为了简化过程随意跳过依赖否则后面训练阶段会频繁报缺失模块。3.3 跑通官方示例确认环境绑定环节环境装好之后先不要直接进入细胞数据先跑一次官方自带的图片推理确认源码、权重、推理脚本之间的调用关系正常。python detect.py --weights yolov5s.pt --source data/images/bus.jpg首次运行需要下载yolov5s.pt权重。如果网络受限可以把权重文件手动下载后放入项目根目录或weights目录再运行上述命令。正常运行后会在runs/detect/exp下生成带检测框的结果图。这一步的意义是提前暴露环境问题。比如KeyError: model通常说明权重文件损坏或下载不完整No module named torchvision说明依赖没有装全Detect() argument ch got unexpected keyword则说明源码版本和权重版本不一致。把这些问题在官方示例阶段解决后面处理细胞数据时就能减少干扰因素。4. 数据准备与标注格式模型上限在数据这层就被决定了4.1 数据集目录结构images与labels必须一一对应YOLOv5训练时默认通过目录结构查找图片和标注文件。一个典型的细胞检测数据集应该按以下结构组织blood_cell/ ├── images/ │ ├── train/ │ │ ├── cell_001.jpg │ │ ├── cell_002.jpg │ │ └── ... │ ├── val/ │ │ ├── cell_101.jpg │ │ └── ... │ └── test/ │ ├── cell_201.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── cell_001.txt │ │ ├── cell_002.txt │ │ └── ... │ ├── val/ │ │ ├── cell_101.txt │ │ └── ... │ └── test/ │ ├── cell_201.txt │ └── ... └── cell.yaml图片和标注文件必须同名同路径只是扩展名不同。例如images/train/cell_001.jpg对应labels/train/cell_001.txt。如果一张图片没有目标对象对应txt文件为空即可但不要缺失文件否则会引发标签加载警告。4.2 标注格式从Pascal VOC到YOLO txtYOLOv5的标注文件是纯文本每一行表示一个目标class x_center y_center width height其中x_center、y_center、width、height都是归一化坐标取值范围0~1不是像素坐标。类别索引必须从0开始不能从1开始。如果数据来自Pascal VOC格式的XML标注需要转换。假设XML里保存的是像素坐标x_min, y_min, x_max, y_max转换公式为x_center (x_min x_max) / 2 / image_width y_center (y_min y_max) / 2 / image_height width (x_max - x_min) / image_width height (y_max - y_min) / image_height一个常见的转换脚本思路如下import os import xml.etree.ElementTree as ET def convert_voc_to_yolo(xml_path, out_txt_path, image_width, image_height): tree ET.parse(xml_path) root tree.getroot() lines [] for obj in root.findall(object): class_name obj.find(name).text class_id class_map[class_name] bndbox obj.find(bndbox) x_min float(bndbox.find(xmin).text) y_min float(bndbox.find(ymin).text) x_max float(bndbox.find(xmax).text) y_max float(bndbox.find(ymax).text) x_center (x_min x_max) / 2 / image_width y_center (y_min y_max) / 2 / image_height w (x_max - x_min) / image_width h (y_max - y_min) / image_height lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) with open(out_txt_path, w, encodingutf-8) as f: f.write(\n.join(lines))转换完成后一定要抽查若干标注框是否正确。可以用YOLOv5提供的可视化方式也可以写一个简单脚本在原图上画出归一化框确认坐标没有出现负值、超过1、宽高为0等问题。类别名和类别ID的映射必须和后面的cell.yaml保持一致否则会出现“模型训练正常推理结果类别全错”的情况。4.3 编写cell.yaml并做一次数据校验YOLOv5通过YAML文件描述数据集位置和类别信息。以三类细胞为例path: /path/to/blood_cell train: images/train val: images/val test: images/test nc: 3 names: 0: RBC 1: WBC 2: Platelet其中path是数据集根目录绝对路径或相对路径train、val在YOLOv5项目里通常相对于path填写nc是类别总数names的索引顺序必须与标注文件里的class数值一一对应。启动训练前可以做一次数据校验确认路径和标注数量正常python train.py --data cell.yaml --epochs 1 --weights yolov5s.pt如果输出里出现Dataset not found优先检查path是否写错如果出现No labels found检查labels目录是否与images同名、标注文件是否为空。这一步虽然简单但能节省大量排错时间。5. 训练参数与超参数跑通第一轮再决定要不要调优5.1 第一个训练命令怎么下第一次训练建议优先跑通流程不要追求最终效果。命令如下python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data cell.yaml \ --weights yolov5s.pt \ --cache \ --device 0参数含义说明参数作用首次建议--img输入图片尺寸训练时会自动缩放640--batch每批样本数受显存限制16显存不足则降到8或4--epochs训练轮数100确认流程后再增加--data数据集配置文件cell.yaml--weights预训练权重yolov5s.pt--cache将数据集缓存到内存加速训练小数据集可开启--device训练设备0表示第一张GPU无GPU可省略建议第一次运行--epochs 1只验证流程能跑通第二次再跑完整训练。避免在数据格式或配置有误的情况下白白等几个小时。5.2 训练参数和超参数怎么选YOLOv5的训练效果受两方面控制一是命令行参数二是超参数文件。超参数文件通过--hyp指定默认文件是data/hyps/hyp.scratch-low.yaml。里面最关键的几项如下参数默认值含义调整影响lr00.01初始学习率过大会震荡过小收敛慢lrf0.01最终学习率为lr0*lrf配合学习率衰减策略momentum0.937SGD动量通常保持默认weight_decay0.0005权重衰减防止过拟合可结合数据量调整warmup_epochs3.0预热轮数初期学习率慢慢增大避免起步不稳定box0.05边界框损失权重对框回归精度影响大cls0.5分类损失权重类别不均衡时可提高dfl1.0分布焦点损失权重框回归细节相关hsv_h / hsv_s / hsv_v0.015 / 0.7 / 0.4颜色空间增强对染色差异大的数据有帮助scale0.5目标缩放增强过大容易改变细胞真实尺度关系对于细胞检测最常见的调优方向是当染色差异明显时适当增大hsv_v和hsv_s增强颜色扰动当小细胞漏检较多时提高输入分辨率--img 960或1280但显存和训练时间会明显上升当某一类样本很少时不要直接在命令行里强行改cls先检查数据分布是否严重失衡再考虑启用类别权重或收集更多样本。一个稳定的做法是第一轮训练全部使用默认超参数记录结果第二轮只调整一个变量比如输入尺寸或增强强度比较两轮指标。一次改多个参数会导致无法判断哪个改动产生了收益。5.3 训练日志怎么看loss、P、R、mAP训练过程中终端会输出类似以下内容Epoch GPU_mem box_loss obj_loss cls_loss Instances Size 99/99 6.93G 0.02143 0.01657 0.00738 35 640 Class Images Instances P R mAP50 all 80 641 0.935 0.901 0.952需要关注box_loss、obj_loss、cls_loss是否整体下降。轻微波动正常但连续几十轮不下降说明学习率或数据有问题。P是精确率表示预测为正例的目标里有多少是对的。R是召回率表示真实细胞里有多少被找出来。mAP50是IoU阈值0.5下的平均精度是YOLOv5最常用的综合指标。如果训练日志里R明显低于P说明漏检较多需要考虑降低置信度阈值、提高输入分辨率或补充靠近图像边缘的小细胞样本。如果P明显低于R说明误检较多需要检查标注是否准确、背景区域是否被误标为细胞。6. 评估模型mAP之外医疗场景还要看漏检和误检6.1 训练输出里有哪些文件可以分析训练结束后结果保存在runs/train/exp目录下。常见的文件及其用途如下文件作用weights/best.pt验证集指标最优的权重weights/last.pt最后一轮的权重results.png训练过程中loss、P、R、mAP曲线confusion_matrix.png混淆矩阵能看出哪些类别互相混淆PR_curve.pngPR曲线权衡不同置信度下的精确率和召回率F1_curve.pngF1分数曲线辅助选合理阈值labels.jpg标注框在图像上的分布检查是否明显异常val_batch_pred.jpg验证集预测结果直观查看漏检或误检不要只盯着一行mAP就下结论。医疗场景里一个总mAP很高的模型可能在某一类细胞上表现很差而那一类恰恰是临床最关注的。6.2 医疗场景先看Recall再看Precision在通用检测场景中很多团队习惯优先看mAP50。但在医疗AI场景漏检和误检的代价不同。通常来说漏检一个真实细胞比多画一个背景框更危险因为漏检可能影响后续诊断判断误检则可以通过医生复核流程拦截。因此评估优先级可以按这个顺序先看总体的Recall确认模型能不能把大部分真实细胞找出来。再看各类别的Recall差异找出表现最差的一类。然后结合Precision判断误检是否能接受。最后看混淆矩阵确认是否出现了类别混淆比如血小板被当成红细胞。再决定是否调整置信度阈值。置信度阈值调整可以直接在推理阶段完成。默认--conf 0.25适合快速预览如果漏检严重可以降到0.1观察如果误检太多可以提高到0.5。生产环境中阈值应该作为可配置参数暴露给产品或临床端而不是写死在代码里。6.3 用best.pt做推理验证训练完成后用验证集之外的数据做推理python detect.py \ --weights runs/train/exp/weights/best.pt \ --source ./test_images \ --conf 0.25 \ --save-txt \ --save-conf--save-txt会把每个目标的类别、坐标、置信度写入txt文件--save-conf会在txt中追加置信度。对于医疗项目建议把推理结果保存成结构化文件而不是只保存带框图片这样后面可以做统计分析、生成复查清单也能追溯模型在具体样本上的表现。如果推理结果和训练指标差距很大优先检查是否用了错误的权重文件或者输入图片与训练数据的预处理方式不一致比如图片尺寸、色彩通道、文件名映射等。7. 导出与部署从best.pt到可用的推理服务7.1 导出ONNX理解模型输出结构训练脚本生成的是PyTorch权重部署环境通常不一定安装完整PyTorch。常见的做法是把权重导出为ONNX再通过ONNX Runtime或设备端的推理引擎运行。python export.py \ --weights runs/train/exp/weights/best.pt \ --include onnx \ --opset 12导出成功后用ONNX Runtime加载模型时要注意输出shape。以输入尺寸640、3类细胞为例模型输出通常是(1, 25200, 8)。其中25200来自三个特征层上的预测框总数8表示5 类别数即中心点坐标、宽高、目标置信度和3个类别分数。实际部署时需要自己实现后处理解码预测框、过滤低置信度目标、执行非极大值抑制。不要以为导出ONNX后就能直接拿到最终检测框。这也是很多人在边缘设备上部署YOLOv5时卡住的主要原因。7.2 端侧部署的常见做法NXP i.MX8MP、树莓派5这类设备算力有限部署时通常要考虑模型轻量化。常见路径有部署方式适用设备说明ONNX Runtime CPU树莓派5、x86工控机改造成本低推理速度取决于设备和模型ONNX转TensorRTNVIDIA Jetson系列需要GPU环境支持FP16加速ONNX转量化模型带NPU的边缘设备需要使用设备厂商提供的转换工具链自研C后处理不依赖Python环境把NMS和后处理写成C降低部署依赖选择部署方案时不要只看推理框架本身还要评估后处理耗时和内存占用。有些设备上模型推理很快但后处理阶段用Python实现反而成为瓶颈。生产环境中建议把预处理、模型推理、后处理三层分离分别做性能和精度验证避免混在一起难优化。另外导出ONNX后要用验证集数据做一次精度对比不能默认导出后精度不变。FP16或INT8量化在部分设备上会导致小目标漏检明显增加尤其对细胞检测这种小目标密集场景必须重新评估后决定是否启用。8. 常见问题排查按链路找原因不要乱改参数8.1 训练阶段典型报错问题现象可能原因检查方式处理建议CUDA out of memorybatch或img太大nvidia-smi查看显存占用调小--batch、--img关闭其他程序Dataset not foundcell.yaml里的path写错打印拼接后的路径使用绝对路径并确认目录存在No labels foundlabels目录为空或图片同名不同路径对比images和labels文件数量修复目录结构确保一一对应AssertionError: Label class xxxxx exceeds nc标注类别索引大于类别数检查txt中第一列数值从0开始编号修正names顺序训练loss不降学习率过大、标注错误、数据分布异常查看tensorboard或results.png调整lr0检查标注框位置KeyError: model权重文件损坏或版本不对尝试重新下载yolov5s.pt使用与源码匹配的预训练权重8.2 推理部署阶段典型问题问题现象可能原因检查方式处理建议推理结果全部为空置信度阈值过高或类别索引错误调低--conf到0.05测试确认names顺序与训练配置一致同一目标重复多个框NMS未执行或IoU阈值设置不对查看输出框数量检查后处理NMS实现ONNX输出shape和预期不符输入尺寸或模型结构不匹配打印输出的shape确认导出的输入尺寸和预处理保持一致边缘设备推理很慢模型过大或用CPU跑大模型查看设备CPU占用和延迟换成YOLOv5n或做量化部署精度比训练低预处理不一致或量化损失对比同一张图的输出框统一resize、归一化和色域处理8.3 排查顺序遇到任何问题时建议按以下顺序排查而不是一上来就调超参数输入是否正确图片是否能正常读取是否为空图。文件路径和命名是否匹配图片与标注是否同名目录是否放在预期位置。依赖版本是否匹配PyTorch、torchvision、YOLOv5源码版本是否一致。配置是否生效修改的是否是训练实际读取的yaml文件。硬件资源是否充足显存、内存、磁盘空间。日志关键字train、val、loss、error、warning出现的位置。工具链限制某些边缘设备对算子和精度支持有限需单独验证。9. 医疗AI工程化的最佳实践与学习路线9.1 数据安全与标注质量医疗AI项目的数据管理要求高于普通项目。细胞检测数据可能来自临床或科研场景实际落地时要注意对患者信息进行脱敏不要在文件名、标注信息、输出结果里保留可识别个人身份的信息。数据读取和训练应限定在受控环境非必要不将数据复制到个人电脑或不安全的存储介质。标注规范要书面化明确每类细胞的判定标准至少安排一人标注、一人复核对分歧样本重新讨论。数据划分要考虑来源隔离不要让同一个样本的不同切片同时出现在训练集和验证集避免结果虚高。这些内容不属于算法但决定了算法指标是否可信。9.2 实验记录和模型留档细胞检测项目会反复调优。建议每个实验都记录以下信息数据版本、标注版本、模型规格、输入尺寸、batch、epochs、超参数文件、训练命令、最终P/R/mAP50、备注。这样后续对比模型时才能判断提升来自数据还是配置。模型权重也要区分层级保存每个实验保存best.pt和last.pt部署上线时保存对应的ONNX或量化模型并记录导出参数。不建议只保存一个best.pt覆盖所有历史结果否则一旦新版本指标异常无法回退到已知可靠的模型。9.3 三类岗位的学习路径建议如果是AI医学研究员跑通YOLOv5后重点补充统计口径、实验设计、数据集偏移和可解释性分析能够说清“模型为什么在这个亚群上失效”比“换一个更大的模型”更有价值。如果是医疗AI算法工程师跑通细胞检测后重点深入训练调优、数据增强、ONNX导出、C后处理、TensorRT或NPU工具链。这个岗位的竞争力来自稳定复现和工程落地能力而不是只会在notebook里跑通。如果是医疗AI产品经理跑完整个项目后需要能定义验收标准、组织标注流程、分析模型边界。比如可以设计一套“医生复核工作量”的评估方法计算漏检数和误检数对应的复核成本这比单纯追求mAP更贴近真实场景。9.4 可复用的完整检查清单阶段检查项数据集图片与标注同名同路径类别索引从0开始标注坐标归一化且在0~1之间train/val/test划分无数据泄漏数据配置cell.yaml路径正确nc与names顺序一致先用--epochs 1验证流程环境PyTorch与CUDA匹配torch.cuda.is_available()返回True官方示例能正常推理训练记录超参数和训练命令监控loss是否下降保存best和last权重注意显存占用评估查看各类别P/R/mAP50检查混淆矩阵不只看总mAP必要时调整置信度阈值部署ONNX导出后验证输出shape核对预处理一致性量化后重新评估精度后处理NMS在目标设备上验证安全合规数据脱敏权限受限标注版本留档不将数据传入不受控的外部服务医疗AI的竞争力不取决于你会调用哪个模型而取决于你能否把数据、训练、评估、部署这条链路稳定跑通并说清楚。YOLOv5细胞检测只是第一步但这一步走扎实了后面换数据集、换模型、换设备都会顺畅很多。