YOLOv5 细胞检测和 YOLOv4 交通标志识别,这两套项目放在一起研究,比单独跑通一个 Demo 有价值得多。原因很简单:它们覆盖了目标检测从数据集准备、模型训练到部署上线的完整闭环,而且应用场景差异很大。一个处理显微镜图像里的密集小目标,一个处理自然道路场景中的交通标志。这个组合很适合深度学习入门者、计算机视觉课程设计、实训项目和毕业设计的参考主线。
最值得看的点不是模型本身有多新,而是两套项目如何围绕不同的数据形态、检测任务和部署环境,做出对应的训练配置和处理方案。下面按实际落地顺序拆一遍,包括环境、数据、训练、部署和排错,照着做基本能复现完整流程。
1. 先判断这两套项目到底解决什么问题
1.1 YOLOv5 细胞检测:本质是医学图像里的目标检测
细胞检测的任务很简单:给定一张显微镜图像,算法要输出图像里每个细胞的类别和位置边界框。比如区分红细胞、白细胞、血小板,同时给出它们在图像中的坐标。
这个任务和通用物体检测有区别。医学图像里的细胞往往数量多、尺寸小、互相重叠,背景又复杂。很多细胞在图像里只有几十个像素大小,属于典型的小目标检测。小目标检测对模型下采样倍数、训练图片尺寸、锚框设置都很敏感。
YOLOv5 在细胞检测里被用得多的原因是生态成熟。代码结构清晰,训练脚本、评估脚本、导出脚本都齐全,社区资料多。遇到问题搜一下基本能找到类似案例,这对学习和做项目都很重要。
1.2 YOLOv4 交通标志识别:检测和分类是两个层次
交通标志识别实际上包含两种子任务。第一种是检测,也就是在摄像头画面中找到标志的位置,输出边界框。第二种是分类,也就是判断这个标志是限速、禁止通行、转弯还是其他类型。
很多初学者把这两个任务混在一起,代码里面容易出问题。YOLOv4 做的是检测加分类的联合任务,模型同时输出位置和类别。交通标志场景的特点是小目标多、标志尺度差异大、光照变化明显、存在遮挡和倾斜。这些都会影响训练数据准备和参数调整。
YOLOv4 和 YOLOv5 放在一起学的价值在于:它们代表了目标检测的两条不同技术路线。YOLOv4 常见于 Darknet 框架实现,YOLOv5 使用 PyTorch 实现。两个框架的配置文件、训练命令、预训练权重格式都不一样,但检测原理相通。把两套项目都跑通,对目标检测的理解会比只跑一个框架深很多。
1.3 两套项目串起来学,比单独学更划算
两套项目放在一起,有几个天然重合点可以复用:
- 数据集格式可以统一成 YOLO 格式的 txt 标注文件。
- 训练评估指标都是 mAP、Precision、Recall。
- 模型导出和部署思路基本一致,只是后端框架不同。
- 调参逻辑相同,锚框、批量大小、学习率、图像尺寸这些参数在两个模型里都会用到。
所以建议学习顺序是:先跑通 YOLOv5 细胞检测,因为 PyTorch 环境更容易搭;再转到 YOLOv4 交通标志,重点理解 Darknet 配置和数据格式转换。这样由易到难,不容易被环境问题劝退。
2. 环境准备:先确认机器和依赖,再谈训练
2.1 硬件条件怎么判断
训练目标检测模型,第一位是显卡,第二位是显存,内存和硬盘也有影响。
如果你用的是 NVIDIA 显卡,走 CUDA 加速是最顺的。GTX 1060 6GB 以上、RTX 2060、RTX 3060、RTX 4060 这些常见显卡都能跑 YOLOv5 和 YOLOv4 的入门训练。显存 6GB 到 8GB 适合跑 YOLOv5s 这种小模型,图片尺寸 640 左右,批量大小控制在 8 到 16。
网上经常有人问 AMD RX 580 能不能跑 YOLO。这里说清楚:RX 580 是 AMD 显卡,不支持 CUDA。CUDA 是 NVIDIA 专属的并行计算平台,AMD 卡跑不了。AMD 显卡要走 ROCm 或 OpenCL 路线,配置难度明显更大,很多 Windows 环境下的深度学习库对 ROCm 支持也不如 CUDA 完善。所以如果你手头是 RX 580,学习阶段建议先用 CPU 跑小规模训练,或者换一台有 NVIDIA 显卡的机器。低配能跑的结论不等于适合训练,这个问题要分清。
纯 CPU 训练不是不行,但速度慢很多。YOLOv5s 在 CPU 上训练一个几百张图片的小数据集,可能一跑就是几小时甚至更久。如果只是做演示和学习,可以把图片尺寸降到 320,批量大小降到 4,减少训练轮数。
2.2 软件依赖配置:分两条线
YOLOv5 的依赖配置比较简单,核心是 Python、PyTorch、OpenCV。官方仓库里有一个 requirements.txt 文件,里面列出了所有依赖包。安装时注意 PyTorch 版本要和 CUDA 版本匹配。先安装 PyTorch,再安装其他依赖,顺序不要反。
YOLOv4 常见实现是 AlexeyAB 的 Darknet 版本,需要编译 C 源码。Windows 下编译 Darknet 建议用 Visual Studio,Linux 下需要安装 CMake 和 OpenCV。Darknet 编译好之后,训练、测试、导出权重都用命令行完成,不依赖 Python,但后续做数据转换和结果可视化还是需要 Python。
建议环境版本统一,Python 3.8 到 3.10 之间,PyTorch 1.10 到 2.x 都可以。不要一开始就上最新的 Python 3.13,很多视觉库的预编译包可能还没跟上。
2.3 环境验证顺序
不管哪套项目,先做最小环境验证,再跑完整训练。验证顺序是:
- 确认显卡驱动正常,用
nvidia-smi查看 CUDA 版本。 - 确认 PyTorch 能调用 GPU,打印
torch.cuda.is_available()。 - 用官方自带的图片跑一次推理,确认模型能正常加载。
- 再创建自己的数据集,进入训练流程。
这样做的原因很实际:环境问题是最容易卡住人的环节,但也是最好定位的。先排除环境,后面训练报错时就能专注于模型参数和数据问题。
3. 数据集准备:标注格式、目录结构和数据增强
3.1 细胞数据集怎么准备
公开的血细胞检测数据集比较常见的是 BCCD 这种用于血细胞计数和检测的数据集,里面包含红细胞、白细胞、血小板等类别。原始标注格式一般是 Pascal VOC 的 XML,或者是带类别和坐标的 CSV。如果你拿到的数据是 VOC 格式,需要转成 YOLO 格式才能给 YOLOv5 训练。
YOLO 标注格式是一个 txt 文件,每行代表一个目标,内容是类别编号 中心点x 中心点y 宽度 高度,所有坐标都归一化到 0 到 1 之间。转换逻辑不复杂,但要注意坐标系原点是图像左上角。
目录结构建议按 YOLOv5 官方要求的格式组织:
dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── data.yamldata.yaml 里写清楚类别数量和类别名称,以及训练集、验证集图片路径。这里最容易踩的坑是路径写错,YAML 文件里的路径要和你实际的绝对路径或相对路径完全一致,否则训练时会报找不到图片的错误。
3.2 交通标志数据集怎么选择
交通标志检测常用的公开数据集有 TT100K,这是清华大学和腾讯合作发布的交通标志数据集,包含大量自然场景下的交通标志图像和边界框标注。另外还有 GTSRB,但 GTSRB 更多用于分类任务,做检测时要注意它的标注形式是否满足需求。KITTI 是自动驾驶领域很著名的数据集,里面也有交通参与者相关的标注,但交通标志数量不算集中。
选择数据集时先明确任务边界:做检测就找带边界框标注的数据集,做分类就找只有类别标签的数据集。不要拿着分类数据集硬做检测,标注缺失会让训练无从下手。
TT100K 的数据量较大,完整训练对显存和时间都有要求。建议先抽取一个子集,比如几百张训练图、几十张验证图,先跑通流程,再考虑全量训练。
3.3 数据增强和样本不均衡
医疗图像和交通场景都存在样本不均衡问题。细胞检测里,血小板可能比红细胞少很多;交通标志里,限速标志可能比施工标志多得多。如果直接训练,模型会对多数类过拟合,少数类召回率很低。
YOLOv5 自带数据增强,包括随机翻转、缩放、色彩抖动、马赛克增强等。默认配置对入门够用,但遇到类别不均衡时,需要额外处理:
- 统计每个类别的样本数量,先看清不均衡程度。
- 不均衡不严重时,可以通过增大图片尺寸、增加训练轮数来缓解。
- 不均衡严重时,考虑对少数类做复制增强,或者调整损失函数里的类别权重。
- 不要盲目追求增加数据集数量,先把标注质量和训练验证集划分做好。
数据准备阶段直接决定训练质量。如果标注坐标偏移、类别标签错误、图像和标注不匹配,再好的模型参数也救不回来。
4. 训练 YOLOv5 细胞检测模型
4.1 配置文件和数据文件
YOLOv5 训练前需要准备两个配置文件:一个是数据集配置文件data.yaml,一个是模型结构配置文件,比如yolov5s.yaml、yolov5m.yaml。
模型结构配置里最关键的两个参数是nc和anchors。nc是类别数量,必须和你的数据集一致。如果数据里有 3 类细胞,就写 3。anchors是锚框尺寸,每个数据集的最优锚框可能不同。YOLOv5 训练时会自动使用遗传算法重新计算锚框,前提是你在训练命令里不要关闭这个功能。
数据集配置文件示例:
train: /path/to/dataset/images/train val: /path/to/dataset/images/val nc: 3 names: ['RBC', 'WBC', 'Platelets']4.2 训练命令与核心参数
YOLOv5 训练命令基本格式是:
python train.py --img 640 --batch 16 --epochs 100 --data cell.yaml --weights yolov5s.pt参数含义如下:
--img:训练图片尺寸,正方形输入。尺寸越大,小目标越容易保留,但显存占用成倍增加。--batch:批量大小。显存不够就调小,调小后学习率可能需要相应调整。--epochs:训练轮数。先跑 50 轮看曲线,再决定是否增加到 100 轮以上。--weights:预训练权重。使用 COCO 预训练权重做迁移学习,能显著加快收敛,尤其适合数据量不大的医学图像项目。--device:指定使用哪张 GPU,单卡写 0,多卡写 0,1。
第一次训练时我会建议先用小规格跑一轮完整流程:图片尺寸 416,批量大小 8,训练轮数 30 到 50,确认数据读取、模型前向、损失计算、权重保存都正常,再放大参数做正式训练。这样能避免一上来就把显存打满,结果跑了两小时发现数据路径有问题。
4.3 损失函数和训练曲线怎么判断
YOLOv5 的损失由三部分组成:边界框回归损失、置信度损失、分类损失。训练时会输出box_loss、obj_loss、cls_loss等指标。这些数值在训练过程中总体下降是正常的,但不要只看 loss 值,要结合验证集指标判断。
判断模型好坏看三个指标:
- Precision:预测为正的样本里,真正正确的比例。
- Recall:所有正样本里,被正确找出来的比例。
- mAP50:IoU 阈值 0.5 下的平均精度均值,是目标检测最常用的综合指标。
细胞检测任务里,漏检比误检往往更严重。如果一个细胞没检测出来,可能直接影响后续计数和诊断分析。所以调参时可以适当偏向召回率,必要时降低置信度阈值。
4.4 训练完怎么验证
训练结束后,模型权重保存在runs/train/exp/weights/目录下。best.pt是验证集表现最好的权重,last.pt是最后一轮保存的权重。一般使用best.pt做推理验证。
推理命令:
python detect.py --weights runs/train/exp/weights/best.pt --source test_image.jpg --conf 0.25--conf是置信度阈值。默认 0.25 在一般情况下够用。如果细胞目标很小且密集,可以降到 0.1 到 0.15,代价是可能出现更多误检。验证时先看边界框是否贴合目标、类别是否准确,再统计检测数量和人工标注数量是否接近。
5. 训练 YOLOv4 交通标志识别模型
5.1 Darknet 编译和配置文件
YOLOv4 的经典实现是 Darknet。编译之前先确保系统里有 CMake、OpenCV 和适配的编译器。Linux 下可以直接用 make 编译,Windows 下用 Visual Studio 打开工程文件编译。
Darknet 的模型配置写在 cfg 文件中,比如yolov4.cfg。训练前需要修改几处关键参数:
classes:类别数量,修改为交通标志的类别数。filters:每个检测层前的卷积层 filter 数量,计算公式是(classes + 5) * 3。batch和subdivisions:batch 是总批量,subdivisions 是把一个 batch 分成多少份送进显卡,显存不够时调大 subdivisions。max_batches:最大迭代次数。一个常见经验是类别数乘以 2000,比如 10 类就设 20000。steps:学习率衰减的节点,一般设在max_batches的 80% 和 90% 位置。
修改 cfg 时最容易出错的是 filters 算错。改完 classes 忘了改 filters,训练时会报通道数不匹配的错误。
5.2 数据格式转换和训练命令
Darknet 训练需要三类文件:
- 图片文件,jpg 格式。
- 标注文件,txt 格式,内容和 YOLOv5 一样。
- 一个
train.txt文件,每行写一张图片的完整路径。
还要准备两个文件:obj.names存放类别名称,obj.data告诉 Darknet 各类文件的位置。
训练命令:
./darknet detector train data/obj.data cfg/yolov4.cfg yolov4.conv.137yolov4.conv.137是预训练权重,下载后放在项目目录里。它是特征提取部分的预训练权重,不包含检测头,专用于迁移学习。
训练过程中 Darknet 会周期性保存权重,默认会保存多个版本。观察输出日志里的avg_loss,这个值总体下降说明训练正常。如果训练过程中 loss 波动特别大,先检查学习率设置和 batch 大小。
5.3 YOLOv4 训练常见问题
交通标志数据集的天然特点是小目标极多。一张 1920x1080 的图片里,标志可能只占几十像素。YOLOv4 输入尺寸默认是 416 或 608,小目标信息在下采样过程中容易丢失。
针对这个问题有几种处理方式:
- 增大输入尺寸,比如把
width和height改成 608 甚至 736,显存够就尽量大。 - 检查数据里小目标的比例,如果很多目标宽度小于 32 像素,说明小目标问题很严重。
- 合理设置 anchors,用 YOLOv4 自带的聚类工具重新计算数据集的锚框,不要沿用 COCO 的默认锚框。
另外注意 YOLOv4 官方预训练权重是基于 COCO 数据集的,直接用于交通标志类别时,前 80 个类别概率计算会有影响。只要正确修改了 classes 和 filters,检测头会重新初始化,这是正常现象。
6. 部署:把权重文件变成可用服务
6.1 YOLOv5 的推理和模型导出
训练完成后的best.pt可以直接用来推理。单独写一个推理脚本比每次用 detect.py 更方便,特别适合要接入业务系统的场景。
推理流程可以拆成四步:读取图片、预处理(缩放和归一化)、模型推理、后处理(非极大值抑制)。YOLOv5 的官方仓库已经封装了这些逻辑,你只需要加载模型并传入图片。
如果想部署到生产环境,通常需要把 PyTorch 权重导出为 ONNX 格式:
python export.py --weights best.pt --include onnx导出的 ONNX 模型可以用 ONNX Runtime 加载,不再依赖 PyTorch,部署体积更小,推理速度也更快。如果目标设备是 NVIDIA GPU 且要更低延迟,可以进一步导出为 TensorRT 引擎,但 TensorRT 版本和显卡驱动耦合较强,配置成本更高。
6.2 YOLOv4 的部署思路
YOLOv4 的 Darknet 权重是.weights文件。部署方式有几种:
- 直接用 Darknet 命令行推理,适合原型验证。
- 把 Darknet 权重转换为 ONNX 模型,再接入 ONNX Runtime。
- 在嵌入式设备上用 TensorRT 或 OpenCV DNN 模块加载模型。
OpenCV DNN 模块是很多人在没有 GPU 环境时的选择。代码里通过cv2.dnn.readNetFromDarknet加载 cfg 和 weights,缺点是推理速度不如 TensorRT,但对入门和演示足够。
6.3 封装成 Web 服务
两个模型最终都可以封装成 HTTP 接口。常用的方案是 FastAPI 或 Flask,流程是:
- 服务启动时加载模型到内存。
- 接收到图片请求后,交给推理函数处理。
- 返回 JSON 格式的检测结果,包含目标的类别、置信度和边界框坐标。
用 FastAPI 有一个好处,它自带接口文档,方便前端联调和测试。写接口时要注意请求体大小限制,一般图片用 base64 编码传输,或者用文件上传方式。
一个简单的处理逻辑:
def predict(image_bytes): image = decode_image(image_bytes) results = model(image) boxes = results.pandas().xyxy[0].to_dict(orient="records") return boxes实际项目中还要加上超时控制、并发限制、异常处理。不要只把模型加载出来就不管了,图片损坏、超大尺寸、空请求都会导致接口异常。
6.4 用 Docker 做部署
如果不想在每台服务器上重复配置环境,可以用 Docker 打包整个服务。镜像里装好 Python、依赖库、模型权重和推理代码,启动容器后把端口映射出来就能访问。
Docker 部署的注意点:
- 镜像体积会比较大,尤其是包含 CUDA 依赖的镜像。
- 模型权重文件不要打进镜像里的临时层,建议通过挂载目录加载,方便更新。
- 容器内 GPU 使用需要额外配置,不同 Docker 版本的 GPU 支持方式不一样。
第一次构建镜像时先不用 GPU 版,用 CPU 版跑通接口;确认功能正常后再切换到 GPU 版,这样排查问题会简单很多。
7. 最容易翻车的几个点和排查顺序
7.1 报错先看日志,不要急着改参数
两套项目训练时都可能遇到各种报错。遇到报错,先按这个顺序排查:
- 看错误信息本身,是路径错误、显存不足、依赖缺失还是数据格式问题。
- 确认输入图片能否被正常读取,图片损坏或格式不对会导致训练中途中断。
- 确认标注文件和图片文件名一一对应。多了一张标注或漏了一张标注,训练时会报找不到对象的异常。
- 确认依赖版本和官方要求一致,尤其是 PyTorch、OpenCV、NumPy 的版本。
- 最后再检查模型配置参数,比如类别数、filters、batch size。
有个容易忽略的地方:训练中断时保存的权重不是最佳权重,恢复训练时要注意续跑命令是否写了正确的前权重路径。
7.2 资源占用和卡顿问题
训练时不要只看显卡显存,还要观察内存和 CPU 使用。数据读取和图像增强在 CPU 端执行,CPU 如果打满,显卡可能在等待数据,利用率上不去。这种情况在细胞检测里常见,因为显微镜图像尺寸大,预处理成本高。
YOLOv5 可以通过调整 workers 参数控制数据加载线程数。workers 太小,数据加载跟不上;workers 太大,内存占用飙升甚至卡死。经验值是 4 到 8,具体看 CPU 核数。
另外训练时建议把输出日志写到一个文件,方便事后排查。日志里能看每个 epoch 的平均 loss、验证集精度、学习率变化。没有日志,等训练跑了很久后想复盘会非常被动。
7.3 功能边界和合理预期
很多问题看起来像模型能力不足,实际上边界没把握好。
细胞检测模型是在特定显微镜设备、特定放大倍数、特定染色方式下训练的。换了一个设备或染色方案,检测效果可能急剧下降。这不是模型 bug,是数据分布变了。
交通标志模型也有类似问题。某个数据集的标志样式带有国家地区特色,换了场景后原有类别定义可能不适用。部署到真实环境前,应该先收集一小批真实场景图片做测试,用真实数据验证模型表现,而不是只信验证集指标。
还有一点要提醒:深度学习项目不是训练跑完就结束的。细胞检测要考虑计数误差评估,交通标志识别要考虑多帧视频里的时序一致性。这些扩展方向和部署质量紧密相关,做项目前先想清楚验收标准,比盲目堆训练参数更有用。
7.4 两套项目跑完之后怎么继续深入
如果两套项目都完整跑通了,下一步可以根据自己的方向做扩展:
- 把 YOLOv5 升级到 YOLOv8,代码结构和配置方式略有差异,但数据格式完全兼容。
- 尝试用 TensorRT 对导出的 ONNX 模型做加速,比较不同精度的推理速度。
- 在部署服务里加入队列机制,支持批量图片异步处理。
- 把目标检测结果接入可视化系统,比如 Web 前端标记识别结果。
训练和部署流程是相通的。细胞检测和交通标志识别只是两个具体场景,真正沉淀下来的是数据转换、模型训练、参数调优和部署排错的方法。后续换任何新数据集,流程都可以复用。