偏"技术报告 + 工程落地"的 YOLOv5 详细讲解。以下内容主要以 Ultralytics 官方架构文档里的 YOLOv5 v6.0/6.1 检测版 为主,因为这版最适合讲清楚检测结构、训练策略和部署链路。([Ultralytics Docs][1])
1. YOLOv5 是什么
YOLOv5 是一个 单阶段、实时、anchor-based 目标检测器。官方文档把它分成三段:Backbone 做特征提取,Neck 做多尺度特征融合,Head 输出分类、目标置信度和边框回归结果。以官方 v6.0/6.1 文档为例,它的主干是 CSPDarknet53 风格结构 ,Neck 用 SPPF + PANet ,Head 用 YOLOv3 Head。([Ultralytics Docs][1])
2. 网络结构图
用 yolov5s.yaml 的官方配置,把 YOLOv5s 画成一张简化结构图,大概是这样:([GitHub][2])
text
Input
└─ Backbone
├─ Conv(64, k=6, s=2) -> P1/2
├─ Conv(128, k=3, s=2) -> P2/4
├─ C3(128, n=3)
├─ Conv(256, k=3, s=2) -> P3/8
├─ C3(256, n=6)
├─ Conv(512, k=3, s=2) -> P4/16
├─ C3(512, n=9)
├─ Conv(1024, k=3, s=2) -> P5/32
├─ C3(1024, n=3)
└─ SPPF(1024)
└─ Neck / Head
├─ 1x1 Conv
├─ Upsample + Concat(P4) + C3
├─ 1x1 Conv
├─ Upsample + Concat(P3) + C3 -> Detect Small (P3/8)
├─ Downsample + Concat + C3 -> Detect Medium (P4/16)
├─ Downsample + Concat + C3 -> Detect Large (P5/32)
└─ Detect(P3, P4, P5)
这张图的核心意思是:先下采样提语义,再上采样融合浅层细节,最后在 3 个尺度上做检测 。官方 yolov5s.yaml 里,Backbone 和 Head 的每一层都明确写出来了,包括 Conv / C3 / SPPF / Upsample / Concat / Detect 的连接关系。([GitHub][2])
3. Backbone:为什么它提特征快
YOLOv5 的基本卷积块 Conv 实际上是 Conv + BN + Activation ,默认激活函数是 SiLU。这比"只看见一个 Conv 名字"更重要,因为它决定了训练稳定性和部署时的融合方式。([GitHub][3])
3.1 C3 模块
C3 是 YOLOv5 里最有代表性的块。源码看,它本质上是:
- 两条
1x1 Conv分支; - 其中一条走若干个
Bottleneck; - 两条分支最后
Concat; - 再过一个
1x1 Conv输出。([GitHub][3])
它的意义可以直接理解成:
- 保留一部分原始梯度流,减轻深层网络训练难度;
- 比"全通道都走重计算"更省算力;
- 在保持表达能力的同时,做了 CSP 风格的部分跨阶段连接。([GitHub][3])
3.2 SPPF 模块
SPPF 是 SPP 的加速版。源码明确写了它 等价于 SPP(k=(5, 9, 13)) ,但实现方式更快;官方文档也明确说,在 v6.0/6.1 里 SPP 被 SPPF 替代,并给出"速度提升超过 2 倍、输出保持一致"的说明。([GitHub][3])
3.3 Focus 为什么消失了
早期 YOLOv5 有 Focus,它通过切片把空间信息折叠进通道。到了 v6.0/6.1,官方把它换成了 6x6 Conv2d ,理由是更高效。这个变化很重要,因为很多旧讲解图还停留在 Focus 时代。([Ultralytics Docs][1])
4. Neck:为什么它对小目标更友好
Neck 主要做两件事:
- 自顶向下:把高层语义传给高分辨率特征;
- 自底向上:再把局部细节和语义重新聚合。([Ultralytics Docs][1])
从 yolov5s.yaml 看,它先把 P5 上采样,与 Backbone 的 P4 拼接;再继续上采样,与 Backbone 的 P3 拼接;之后再两次下采样,把这些融合特征重新汇总成 P3、P4、P5 三个检测层。这个过程就是典型的 PANet 风格多尺度特征融合。([Ultralytics Docs][1])
你可以把它理解成:
- 浅层:分辨率高,适合小目标;
- 深层:语义强,适合大目标;
- Neck:把两边优点揉在一起。([Ultralytics Docs][1])
5. Head:YOLOv5 输出
YOLOv5 的 Detect Head 是 anchor-based 的。源码里:
self.no = nc + 5,也就是每个 anchor 输出x, y, w, h, obj + classes;self.nl是检测层数;self.na是每层的 anchor 数;- 每个检测层最后用一个
1x1 Conv产生输出。([GitHub][4])
对 COCO 的 80 类来说,每个 anchor 输出就是 85 维 。源码还明确写了张量形状会被整理成 x(bs, 3, ny, nx, 85) 这样的形式。([GitHub][4])
5.1 三个检测尺度
yolov5s.yaml 里标得很清楚,YOLOv5 默认检测层是:
P3/8P4/16P5/32。([GitHub][2])
如果输入是 640×640,那么这三个特征图就是:
- 80×80
- 40×40
- 20×20。
这是直接由 stride 8/16/32 推出来的。再结合每层 3 个 anchor,总候选框数就是:
3 × (80×80 + 40×40 + 20×20) = 25200。这一点和很多导出模型里常见的 (1, 25200, 85) 输出是一致的。([GitHub][2])
5.2 边框解码为什么更稳
YOLOv5 对 box decode 做了关键改动。源码中的推理公式是:
xy = (sigmoid(xy) * 2 + grid) * stridewh = (sigmoid(wh) * 2)^2 * anchor_grid。([GitHub][4])
官方文档解释了这样做的目的:
- 中心点偏移范围从
(0, 1)扩成(-0.5, 1.5),减轻 grid sensitivity; - 宽高不再使用旧 YOLO/Darknet 里容易失控的
exp()方式,降低梯度爆炸、NaN 和训练不稳定风险。([Ultralytics Docs][1])
6. YOLOv5 的关键创新点
如果你问"YOLOv5 真正强在哪",我会把它分成 结构创新、训练创新、工程创新 三类。
6.1 结构层面
最重要的结构点有四个:
- C3/CSP 风格主干块,兼顾梯度流和计算效率。([GitHub][3])
- Focus → 6×6 Conv,让前端更高效。([Ultralytics Docs][1])
- SPP → SPPF,用更快方式获得多尺度感受野。([Ultralytics Docs][1])
- PANet 多尺度融合 + 三尺度检测头,同时照顾小中大目标。([Ultralytics Docs][1])
6.2 训练层面
官方文档列出的训练增强和策略非常全,核心包括:
- Mosaic
- Copy-Paste
- Random Affine
- MixUp
- Albumentations
- HSV Augmentation
- Random Horizontal Flip
- Multiscale Training
- AutoAnchor
- Warmup + Cosine LR
- EMA
- Mixed Precision
- Hyperparameter Evolution。([Ultralytics Docs][1])
其中最典型的是:
- Mosaic:4 张图拼成 1 张图,显著增加目标尺度和上下文多样性;
- AutoAnchor:针对你自己的数据集自动匹配更合适的 anchor;
- EMA + AMP:一个稳训练,一个提速度省显存。([Ultralytics Docs][1])
6.3 损失函数与目标分配
YOLOv5 的 loss 由三部分组成:
- 分类损失:BCE
- 目标存在性损失:BCE
- 定位损失:CIoU。([Ultralytics Docs][1])
并且三个尺度的 objectness loss 不是一视同仁,而是按 [4.0, 1.0, 0.4] 做平衡,这样小目标层不会在总损失里被淹没。([Ultralytics Docs][1])
目标分配上,官方文档还强调了两点:
- 先比较 GT 和 anchor 尺寸比;
- 满足阈值再匹配到合适网格;
- 因为中心偏移范围放宽,一个 GT 可以匹配到多个候选单元。([Ultralytics Docs][1])
7. 为什么 YOLOv5 很适合工程部署
YOLOv5 真正流行,除了精度和速度,还因为它工程闭环很完整。官方导出文档支持从 PyTorch 权重直接导出多种部署格式,包括:
- TorchScript
- ONNX
- OpenVINO
- TensorRT
- CoreML
- TensorFlow SavedModel
- PB
- TFLite
- Edge TPU
- TF.js
- PaddlePaddle。([Ultralytics Docs][5])
官方还给出经验结论:
- ONNX / OpenVINO 可带来最高约 3× CPU speedup;
- TensorRT 可带来最高约 5× GPU speedup。([Ultralytics Docs][5])
8. 实际部署怎么做
8.1 最常见导出命令
官方示例最常见的是:([Ultralytics Docs][5])
bash
python export.py --weights yolov5s.pt --include torchscript onnx
只导出 ONNX 则是:([Ultralytics Docs][5])
bash
python export.py --weights yolov5s.pt --include onnx
还可以加 --half 导出 FP16,以减小模型体积。([Ultralytics Docs][5])
8.2 官方支持的推理方式
官方文档明确给出,导出后仍可直接用 detect.py / val.py 跑多种后端,例如:
yolov5s.pt:PyTorchyolov5s.torchscript:TorchScriptyolov5s.onnx:ONNX Runtime 或 OpenCV DNNyolov5s_openvino_model:OpenVINOyolov5s.engine:TensorRTyolov5s.tflite:TFLite。([Ultralytics Docs][5])
8.3 OpenCV DNN / C++ 部署
如果你走 C++ 路线,官方文档专门有:
- OpenCV DNN inference
- C++ Inference
两个章节。官方示例流程是先导出 ONNX,再用--dnn调 OpenCV DNN:([Ultralytics Docs][5])
bash
python export.py --weights yolov5s.pt --include onnx
python detect.py --weights yolov5s.onnx --dnn
python val.py --weights yolov5s.onnx --dnn
而且官方文档还列了 OpenCV DNN C++ 和 OpenVINO C++ 示例仓库,说明这条部署链路是官方明确支持的。([Ultralytics Docs][5])
9. 部署时最容易踩的坑
这部分是工程经验总结:
第一,预处理必须对齐。
你自己写 ONNXRuntime / TensorRT / OpenCV DNN 推理时,输入缩放、padding、颜色通道顺序、归一化、坐标缩放还原必须和训练/验证链路一致,否则精度掉得很明显。
第二,后处理必须对齐。
YOLOv5 不是"网络吐出框就结束",而是还要做:
- box decode
- confidence 过滤
- NMS
尤其是你自己写 C++ 解码时,要按xy/wh的官方公式来,不要用旧 YOLOv3 的解法。这个差别会直接影响框位置和稳定性。源码和官方架构文档都能看到这一点。([GitHub][4])
第三,选对后端。
一般可以这么选:
- 纯 Python 验证:PyTorch / TorchScript
- CPU 服务:ONNX Runtime 或 OpenVINO
- NVIDIA GPU:TensorRT
- 移动端:TFLite / CoreML
- 浏览器:TF.js。([Ultralytics Docs][5])
10. 总结 YOLOv5
如果只用一句话概括:
YOLOv5 的成功,不只是"一个检测网络",而是"C3 + SPPF + PAN 多尺度融合 + 更稳的 box decode + 很强的数据增强 + 完整导出部署链路"共同构成的工程化检测体系。 这也是为什么它在工业视觉、边缘部署和自定义数据集训练里一直非常能打。([Ultralytics Docs][1])
链接:
1\]: https://docs.ultralytics.com/yolov5/tutorials/architecture_description/ "Ultralytics YOLOv5 Architecture - Ultralytics YOLO Docs" \[2\]: https://github.com/ultralytics/yolov5/blob/master/models/yolov5s.yaml "yolov5/models/yolov5s.yaml at master · ultralytics/yolov5 · GitHub" \[3\]: https://github.com/ultralytics/yolov5/blob/master/models/common.py "yolov5/models/common.py at master · ultralytics/yolov5 · GitHub" \[4\]: https://github.com/ultralytics/yolov5/blob/master/models/yolo.py "yolov5/models/yolo.py at master · ultralytics/yolov5 · GitHub" \[5\]: https://docs.ultralytics.com/yolov5/tutorials/model_export/ "TFLite, ONNX, CoreML, TensorRT Export - Ultralytics YOLO Docs"