ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

YOLOv5细胞检测与YOLOv4交通标志识别:从数据标注到部署全流程实战

YOLOv5细胞检测与YOLOv4交通标志识别:从数据标注到部署全流程实战 这次我们来看两套非常典型的深度学习目标检测实战项目一套用 YOLOv5 做细胞检测另一套用 YOLOv4 做交通标志识别。两套项目都覆盖了数据集准备、模型训练、效果验证和部署上线的完整流程特别适合正在学习 YOLO 系列算法、想自己完整跑通一个检测任务的读者。先回答一个很多人关心的问题这两套项目难不难YOLOv5 和 YOLOv4 都属于成熟的开源目标检测框架网上资料多、复现案例多、踩坑记录也多。相比从零手写网络结构这两套项目的核心工作量其实集中在三块数据集的获取与标注、训练参数调整、模型导出与接口部署。它们能帮你把“算法原理”和“工程落地”串起来而不是停留在跑通一个 demo 的阶段。本文会把两套项目的实操路径分开讲先讲 YOLOv5 细胞检测的数据组织和训练命令再讲 YOLOv4 交通标志识别的 Darknet 环境配置和训练流程最后统一给出部署到 API 服务、摄像头实时检测和批量推理的方案。如果你想从零开始接触 YOLO 实战这篇文章可以直接作为操作清单来用。1. 核心能力速览能力项项目一YOLOv5 细胞检测项目二YOLOv4 交通标志识别任务类型目标检测目标检测适用模型YOLOv5s / YOLOv5m 等YOLOv4 或 YOLOv4-tiny检测目标细胞个体、细胞团块限速、停止、人行横道等交通标志数据集格式YOLO txt 格式 data.yamlVOC / YOLO txt 格式均可训练框架PyTorchDarknetGPU 需求建议 4GB 以上显存建议 4GB 以上显存CPU 推理可以运行速度偏慢可以运行YOLOv4-tiny 更流畅部署方式ONNX / TorchScript / API 服务Darknet 原生权重 / ONNX / API 服务批量任务支持遍历目录推理支持遍历目录推理适合读者有 PyTorch 基础关注精度关注老硬件兼容性和速度从能力速览可以看出两套项目其实是一个互补关系YOLOv5 代码更友好、训练生态更现代适合做精细检测YOLOv4 配合 Darknet 在 CPU 和低端显卡上更灵活适合做资源受限场景的验证。实际工作中很多人会先跑通 YOLOv5再回去对比 YOLOv4 的速度和部署差异。2. 项目一YOLOv5 细胞检测实战2.1 任务定义与数据集准备细胞检测的目标是在显微镜图像中定位每一个细胞并给出矩形框。这个任务看起来简单实际有两个难点细胞尺寸小、细胞密度高容易漏检背景中有杂质和染色噪声容易误检。YOLOv5 在这类中小目标场景下表现不错主要因为它有 Mosaic 数据增强和多尺度训练机制可以增加模型对小目标的敏感性。数据集先解决“有没有”的问题再解决“干不干净”的问题。建议按两种方式准备使用公开生物影像数据集优先选择已经带有 COCO 或 YOLO 格式标注的版本省去自己标注的时间。使用实验室自有图像自己用标注工具生成标注文件。需要注意的是细胞检测如果涉及医学研究或临床辅助要确认数据来源授权不能随意抓取未脱敏的病理图像。如果只是学习算法流程公开的细胞数据集已经足够。2.2 YOLOv5 数据集目录组织YOLOv5 约定了一种固定的数据集目录结构。以细胞检测为例目录可以这样组织datasets/cell_detection/ ├── images/ │ ├── train/ │ │ ├── cell_001.jpg │ │ ├── cell_002.jpg │ └── val/ │ ├── cell_100.jpg │ ├── cell_101.jpg └── labels/ ├── train/ │ ├── cell_001.txt │ ├── cell_002.txt └── val/ ├── cell_100.txt ├── cell_101.txtlabels 目录下每个 txt 文件与 images 下的图片一一对应文件名相同后缀不同。每个 txt 的每一行代表一个目标框格式为class_id x_center y_center width height这里 x_center、y_center、width、height 都是归一化坐标取值 0 到 1。比如一张 1000x1000 的图片中一个细胞框左上角在 (200, 300)宽 100高 80那么 class_id 对应的归一化结果是0 0.25 0.34 0.10 0.082.3 数据标注与格式转换如果自己标注推荐使用 labelImg 或 Label Studio。labelImg 可以直接保存为 YOLO 格式省去后续转换。Label Studio 支持团队协作输出格式需要再转换一次。一组常用的坐标转换逻辑如下假设原始标注是 VOC 格式的 x_min、y_min、x_max、y_max图片宽为 img_w高为 img_h则x_center (x_min x_max) / 2 / img_w y_center (y_min y_max) / 2 / img_h width (x_max - x_min) / img_w height (y_max - y_min) / img_h转换之后要注意检查边界值。如果归一化后坐标略小于 0 或略大于 1可以做一个 clip 操作避免训练时报错或边框异常。2.4 修改 data.yaml 与模型配置YOLOv5 训练前需要一个 data.yaml 文件内容大致如下train: datasets/cell_detection/images/train val: datasets/cell_detection/images/val nc: 1 names: [cell]这里 nc 是类别数names 是类别名称。如果还想加“背景”“杂质”等负样本标注要在标注阶段就把这些类别加进去不能在训练时临时改名字。模型方面一般情况下先选 YOLOv5s显存压力小训练速度快精度也够用于学习。如果检测效果不理想再换 YOLOv5m 或调大输入图像尺寸。2.5 训练命令与超参数YOLOv5 训练命令是一个典型的一行式命令python train.py \ --data datasets/cell_detection/data.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --device 0几个关键参数--img 640输入图像短边缩放到 640。细胞图像如果原始分辨率较大可以尝试 960 或 1280小目标识别通常会变好但显存占用会明显上升。--batch 16显存不够就降到 8 或 4优先保证训练不爆显存。--epochs 100数据集小时 100 轮足够配合早停机制可以提前结束。--device 0使用第一块 GPU。CPU 训练太慢不太建议用大模型在 CPU 上长时间训练。训练过程中会生成 runs/train/exp 目录里面包括权重文件、TensorBoard 日志和每轮的验证结果图片。2.6 训练结果评估与推理测试训练完成后先看 runs/train/exp/ 下的 results.csv 或 TensorBoard 曲线。重点观察 mAP0.5 和 mAP0.5:0.95 两个指标。mAP0.5 达到 0.9 以上对细胞检测来说已经可以用mAP0.5:0.95 越高说明框的定位越准。用训练好的权重做推理python detect.py \ --weights runs/train/exp/weights/best.pt \ --source datasets/cell_detection/images/val \ --conf 0.25 \ --iou 0.45 \ --save-txt--save-txt会输出检测结果的坐标文件方便后续做批量统计比如统计一张图里的细胞数量。2.7 模型导出与部署YOLOv5 自带导出脚本可以导出 ONNX、TorchScript、TensorRT 等格式python export.py --weights runs/train/exp/weights/best.pt --include onnxONNX 模型可以接到 OpenCV DNN、ONNX Runtime 或 API 服务里摆脱 PyTorch 运行环境的限制。TorchScript 则适合嵌入 PyTorch 环境中的服务。具体导出后的推理结果需要通过 ONNX Runtime 或 OpenCV 再次验证防止某些算子导出后行为不一致。3. 项目二YOLOv4 交通标志识别实战3.1 交通标志检测的技术要点交通标志属于尺寸小、类别多、色彩信息明显的目标。与细胞检测相比它的检测难点在野外环境拍摄距离远导致标志占比小逆光、雨雪、遮挡让特征不稳定。YOLOv4 用了 CSPDarknet53 骨干网络和 PANet 颈部结构在中等分辨率输入下对这类目标有较强适应能力。如果你在低算力设备上部署比如树莓派或老款 CPU 主机可以考虑 YOLOv4-tiny。它牺牲了一部分精度但推理速度比完整版 YOLOv4 快很多。交通标志类别通常在 10 到 40 类之间tiny 版本也有实际应用价值。3.2 数据集准备与选择交通标志识别有比较成熟的公开数据集比如德国交通标志检测数据集 GTSDB、中国交通标志数据集 CCTSDB 等。使用公开数据集时注意两点一是确认许可协议是否允许商用和修改二是关注标注格式有的数据集是 VOC xml有的是 txt需要统一转换。以 GTSDB 为例标注包含 43 个类别。实际训练时你可以根据自己的任务重新聚合类别比如只保留限速标志、禁令标志、警告标志三大类。类别越少训练难度越低但模型能区分的细节也会变少。3.3 Darknet 环境准备YOLOv4 常用 AlexeyAB 的 Darknet 分支训练。Linux 下编译最省心Windows 下也可以用 CMake 编译或者直接下载别人编译好的可用版本。编译前确保系统有 NVIDIA 驱动和 CUDA。没有 GPU 的环境也能编译仅 CPU 版本但训练速度会非常慢。Ubuntu 系统下一套简化编译流程git clone https://github.com/AlexeyAB/darknet.git cd darknet sed -i s/GPU0/GPU1/ Makefile sed -i s/CUDNN0/CUDNN1/ Makefile make -j4编译结束后运行./darknet detector test cfg/coco.data cfg/yolov4.cfg yolov4.weights data/dog.jpg验证是否安装成功。3.4 YOLOv4 训练配置文件YOLOv4 的训练配置分为三类文件数据配置文件、类别名称文件、网络结构文件。数据配置文件 data/traffic.data 大致如下classes 43 train data/traffic/train.txt valid data/traffic/val.txt names data/traffic/traffic.names backup backup/traffictrain.txt 和 val.txt 是图片路径列表每行一张图片Darknet 会在相同路径下寻找同名的 txt 标注文件。traffic.names 每行一个类别名speed_limit_30 speed_limit_50 stop yield ...网络结构文件需要重点修改因为 YOLOv4 的输出层通道数由类别数决定。找到 cfg/yolov4.cfg 中所有[convolutional]且filters255的层把它们改为filters(classes 5) * 3。同时把每个[yolo]层的 classes 改成实际类别数。如果 classes43则 filters 应该改成(43 5) * 3 144。3.5 训练命令与监控下载 YOLOv4 官方预训练卷积权重 conv.137然后开始训练./darknet detector train data/traffic.data cfg/yolov4-traffic.cfg conv.137 -dont_show -map-map会在每个验证周期结束后计算 mAP方便远程观察是否收敛。训练中每隔 100 轮会保存一个 weights 文件存放到 backup 目录。如果显存不够可以把 cfg 文件里的 batch 从 64 改成 32 或 16subdivisions 调高到 16 或 32这样能显著降低单次前向的内存占用代价是训练速度变慢。3.6 测试与部署训练完成后用 backup 目录下最后的 weights 做测试./darknet detector test data/traffic.data cfg/yolov4-traffic.cfg backup/yolov4-traffic_final.weights data/test.jpgYOLOv4 的原生权重不能直接被 OpenCV DNN 使用需要先转换成 ONNX 或 TensorRT。如果目标平台是 Jetson 系列设备TensorRT 是更好的选择。对于普通 x86 服务器转 ONNX 后用 ONNX Runtime 推理更通用。4. YOLOv5 与 YOLOv4 技术对比对比维度YOLOv5YOLOv4代码生态PyTorch结构清晰上手快DarknetC 语言编译略繁琐训练便捷度自带增强、日志、导出脚本需要手动配置文件名与路径精度中小目标场景有优势中等目标、通用场景表现稳定速度与模型尺寸相关完整版偏重tiny 版轻量部署兼容ONNX/TorchScript/TensorRTdarknet 权重转 ONNX/TensorRT 步骤略多适合场景快速原型、科研实验、中小目标检测低算力设备、老显卡、嵌入式验证如果只选一个项目先做建议先做 YOLOv5 细胞检测因为 PyTorch 生态对新手更友好遇到问题更好搜资料。YOLOv4 交通标志识别可以放在第二个练手项目主要用来理解 Darknet 训练流程和传统部署链路。5. 模型部署与 API 服务5.1 离线批量推理脚本训练得到的模型不能只停留在命令行测试阶段。实际使用中更常见的需求是批量推理比如一次性处理一个文件夹里的几百张细胞图像输出每张图的检测结果。下面给出一个基于 YOLOv5 官方 detect.py 的批量思路python detect.py \ --weights runs/train/exp/weights/best.pt \ --source datasets/cell_detection/images/val \ --project outputs/cell_result \ --save-txt \ --save-conf输出结果会保存到 outputs/cell_result/exp/ 目录其中 labels 子目录保存每个目标的坐标和置信度。对于 YOLOv4 的批量推理可以写一个循环脚本逐个调用 Darknet 命令也可以把 darknet 封装成 Python 调用。从工程效率上讲尽快把模型转成 ONNX然后用 ONNX Runtime 写推理脚本比反复调用 darknet 子进程更可控。5.2 FastAPI 部署接口无论是细胞检测还是交通标志识别最后都可以封装成一个 HTTP 接口。用 FastAPI 加 ONNX Runtime 可以快速搭出一个检测服务。下面是一个通用模板import io from fastapi import FastAPI, UploadFile import numpy as np import cv2 import onnxruntime as ort from PIL import Image app FastAPI() session ort.InferenceSession(best.onnx, providers[CUDAExecutionProvider, CPUExecutionProvider]) def preprocess(image: np.ndarray, size: int 640) - np.ndarray: h, w image.shape[:2] scale min(size / h, size / w) new_w, new_h int(w * scale), int(h * scale) resized cv2.resize(image, (new_w, new_h)) canvas np.full((size, size, 3), 114, dtypenp.uint8) canvas[:new_h, :new_w] resized img canvas[:, :, ::-1].transpose(2, 0, 1) img np.ascontiguousarray(img, dtypenp.float32) img / 255.0 return img[None, ...], scale app.post(/detect) async def detect(file: UploadFile): data await file.read() image np.array(Image.open(io.BytesIO(data)).convert(RGB)) img, scale preprocess(image) outputs session.run(None, {session.get_inputs()[0].name: img}) # 这里需要根据模型输出格式解析 boxes、scores、classes return {outputs_shape: [o.shape for o in outputs]} if __name__ __main__: import uvicorn uvicorn.run(app, host0.0.0.0, port8000)注意ONNX 的输出解析因导出版本略有不同上述代码只展示请求接收和预处理流程实际解析逻辑要对照导出的输出节点来写。调用接口时可以用 curl 测试curl -X POST http://127.0.0.1:8000/detect -F filetest.jpg这种部署方式的最大好处是模型运行与业务代码解耦。前端、单片机、自动化脚本都只通过 HTTP 调用检测能力不需要关心底层推理框架。5.3 摄像头实时检测实时检测相对复杂重点不在模型推理而在帧读取和显示。一个通用结构是OpenCV 读取摄像头帧 → 缩放后送入模型 → 解析结果 → 在原图上绘制矩形框 → 显示或推流。YOLOv5 的 detect.py 已经支持摄像头输入传入--source 0即可调用默认摄像头。YOLOv4 可以运行./darknet detector demo命令。实际项目中要注意视频帧率是否稳定、推理耗时是否超过帧间隔、缓冲区是否会堆积这几个指标比单帧精度更容易影响体验。5.4 TensorRT 加速如果你需要更低的推理延迟TensorRT 是常见选择。具体做法是先把 PyTorch 或 Darknet 权重导出为 ONNX再通过 trtexec 构建 TensorRT 引擎trtexec --onnxbest.onnx --saveEnginebest.engine --fp16这里没有给出精确的显存占用和耗时对比因为不同显卡、不同分辨率差异很大。实际优化时应该在同一台设备上分别测 ONNX Runtime 和 TensorRT 的耗时再判断是否值得增加这一层编译复杂度。6. 资源占用与性能观察方法6.1 观察工具训练时用nvidia-smi查看 GPU 显存和利用率nvidia-smi -l 2-l 2表示每两秒刷新一次。还可以在 YOLOv5 训练时开启 TensorBoard 监控损失曲线和显存曲线。Darknet 训练没有自带图形界面主要靠日志中的 avg loss 判断收敛情况。6.2 影响显存的关键参数输入分辨率640 到 1280显存占用近似平方增长。batch sizebatch 越大显存占用越高。模型复杂度YOLOv5s 比 YOLOv5x 显存占用低很多YOLOv4-tiny 比 YOLOv4 低很多。数据增强Mosaic 和 mixup 会临时增加计算图对显存也有影响。6.3 降低显存占用的通用策略训练阶段显存不足时优先降低 batch size其次是降低输入分辨率最后再考虑换轻量模型。推理阶段可以用 FP16 量化或 TensorRT 压缩引擎但要注意量化后精度下降是否在可接受范围内。CPU 推理不是不能用而是速度差距很大。如果只是接口演示或低并发场景CPU 跑 YOLOv4-tiny 或 YOLOv5s 也可以接受。并发量上来以后还是要回到 GPU 推理。7. 常见问题与排查方法问题现象可能原因排查方式解决方案训练 loss 一直不下降数据标注错误、学习率过高检查标注框是否错位查看 loss 曲线重新标注有问题图片降低学习率检测不到目标置信度阈值过高、训练类别不全降低 conf查看错误样本增加训练数据调整 conf 阈值边框位置偏大或偏小标注转格式时归一化出错可视化标注结果修正坐标转换脚本显存不足batch、分辨率、模型过大nvidia-smi 查看占用降低 batch、降低 img 尺寸、换轻量模型Darknet 编译失败CUDA 版本与显卡驱动不匹配检查 nvcc -V 和 nvidia-smi安装匹配版本或改用 CMake 编译ONNX 导出后推理结果不一致部分算子不支持或预处理不一致用同一张图对比 PyTorch 与 ONNX 输出修正预处理逻辑升级导出库版本API 请求超时模型推理较慢或并发过高查看服务日志和请求耗时增加超时时间使用队列串行化任务批量任务卡在中间图片某张损坏图片导致推理崩溃增加异常捕获记录失败文件跳过异常文件单独重跑失败列表8. 最佳实践、合规提醒与后续扩展工程上先按下面几条思路推进第一次练手时数据集不用大每类 200 到 500 张即可先把流程跑通。保存一套最小可运行配置包括训练命令、数据路径、模型参数方便复现。模型文件、输入素材、输出结果分目录管理不要全部堆在默认目录。批量推理要加日志记录哪些图片成功、哪些失败、耗时多少。接口服务默认只监听 127.0.0.1需要外部访问时再修改绑定地址并考虑鉴权。使用公开数据集前确认授权协议特别是商用场景。合规方面需要单独提醒细胞检测相关模型如果用于医疗辅助必须经过专业验证文章中的实验只适合算法学习和科研验证不能直接作为临床诊断依据交通标志识别如果用于辅助驾驶研究需要遵守相关测试法规不能直接替代驾驶员判断。涉及隐私数据、人脸、车牌等敏感信息时要先完成匿名化处理并确认数据来源合法。后续扩展方向可以从三个角度切入一是把 YOLOv5 细胞检测升级为实例分割统计细胞面积和数量二是给交通标志识别接入跟踪算法比如 DeepSORT在视频流中稳定标志 ID三是把两个模型都做成 ONNX 或 TensorRT 服务统一接到同一个检测平台。跑完两套项目后你会发现数据集工程和部署链路才是花时间最多的地方模型结构本身反而是最成熟的部分。如果你正在找工作或做毕业设计建议优先把 YOLOv5 细胞检测做完再把 YOLOv4 交通标志作为对比实验加进去形成“同一类任务、两个模型、两条部署链路”的完整项目经历。这套组合既能体现算法理解也能体现工程能力建议收藏备用。
返回列表