首页/目录/全部文章

全部文章

八个专题的源码、算法与协议笔记都在这里。

笔记列表

YOLOv5 7.0:系统概述

01 系统概述

1.1 项目定位

YOLOv5 是 Ultralytics 基于 PyTorch 实现的实时视觉框架。当前源码对应 release v7.0,核心任务包括:

  • 目标检测train.pyval.pydetect.py
  • 实例分割segment/train.pysegment/val.pysegment/predict.py
  • 图像分类classify/train.pyclassify/val.pyclassify/predict.py
  • 模型导出export.py
  • 多后端推理models/common.py::DetectMultiBackend

该版本的主要发布特性是加入 YOLOv5-seg 实例分割模型。

1.2 版本与许可证

内容
版本 YOLOv5 v7.0
语言 Python
训练框架 PyTorch
许可证 GPL-3.0
Python 要求 README 声明 Python ≥ 3.7
PyTorch 要求 torch>=1.7.0

源码中的模型、脚本和文档均标注 GPL-3.0。商业产品集成前应核对许可证义务。

1.3 根目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
yolov5-7.0/
├── train.py # 检测训练
├── val.py # 检测验证
├── detect.py # 检测推理
├── export.py # 多格式导出
├── benchmarks.py # 导出格式性能/精度测试
├── hubconf.py # PyTorch Hub 入口
├── sample_detect.py # 本仓库增加的本地推理示例
├── models/
│ ├── yolo.py # Detect/Segment/模型解析
│ ├── common.py # 网络块、多后端、AutoShape
│ ├── experimental.py # 权重加载、模型集成
│ ├── tf.py # TensorFlow/Keras 对应实现
│ ├── yolov5{n,s,m,l,x}.yaml
│ ├── segment/ # 分割模型 YAML
│ └── hub/ # P6/P7/实验结构
├── utils/
│ ├── dataloaders.py # 数据集、图片/视频/流加载
│ ├── augmentations.py # Letterbox、Mosaic、几何增强
│ ├── loss.py # 检测损失与目标匹配
│ ├── general.py # NMS、坐标、检查与通用工具
│ ├── metrics.py # IoU、AP、混淆矩阵
│ ├── plots.py # 绘图与 Annotator
│ ├── torch_utils.py # 设备、EMA、DDP、优化器
│ ├── autoanchor.py # Anchor 检查与进化
│ ├── callbacks.py # 训练生命周期回调
│ ├── loggers/ # TensorBoard/ClearML/Comet/W&B
│ └── segment/ # 分割损失、数据与指标
├── data/
│ ├── coco.yaml # 数据集定义
│ ├── coco128.yaml # 小型入门数据集
│ ├── coco128-seg.yaml
│ ├── hyps/ # 训练超参数
│ └── scripts/ # 数据/权重下载脚本
├── segment/ # 分割任务入口
├── classify/ # 分类任务入口
├── requirements.txt
└── README.md

1.4 主要依赖

依赖 用途
PyTorch / torchvision 模型、训练、AMP、数据接口
OpenCV 图像与视频读写、缩放、绘图
NumPy / SciPy 数组与科学计算
PyYAML 模型、数据集、超参数配置
Pillow PIL 图像及 AutoShape 输入
matplotlib / seaborn / pandas 可视化与统计
tqdm 训练进度条
thop 参数量与 FLOPs 统计
tensorboard 训练日志

ONNX、TensorRT、OpenVINO、CoreML、TensorFlow、Paddle、Triton 等是按导出/部署目标选装的依赖。

1.5 三类任务

检测

输出每个候选框的:

1
(x, y, w, h, objectness, class scores...)

经 NMS 后成为:

1
(x1, y1, x2, y2, confidence, class_id)

实例分割

Segment 继承 Detect,除检测输出外增加:

  • 每个候选实例的 mask 系数
  • Proto 生成的共享原型掩码

预测阶段用 mask 系数线性组合原型,再裁剪到框内。

分类

ClassificationModel 可截取检测模型的 backbone,并将最后一层替换为 Classify 头。

1.6 模型规模

P5 检测模型包括:

1
yolov5n → yolov5s → yolov5m → yolov5l → yolov5x

它们主要共享拓扑,通过 YAML 中:

  • depth_multiple:缩放模块重复次数
  • width_multiple:缩放输出通道

实现从轻量到高精度的系列化。

1.7 核心设计思想

一句话概括:

用 YAML 描述网络图,parse_model() 动态创建 PyTorch 模型;用锚框三尺度头完成密集预测;训练端以 CIoU、Objectness BCE、Class BCE 联合优化;部署端通过 DetectMultiBackend 隔离不同推理运行时。

YOLOv5 7.0:系统架构

02 系统架构

2.1 分层架构

flowchart TB
  subgraph Entry["任务入口"]
    TR["train.py"]
    VA["val.py"]
    DE["detect.py"]
    EX["export.py"]
    SG["segment/*"]
    CL["classify/*"]
    HUB["hubconf.py"]
  end

  subgraph Model["模型层"]
    YAML["models/*.yaml"]
    YOLO["models/yolo.py"]
    COMMON["models/common.py"]
    EXP["models/experimental.py"]
  end

  subgraph Utility["基础设施"]
    DL["utils/dataloaders.py"]
    AUG["utils/augmentations.py"]
    LOSS["utils/loss.py"]
    GEN["utils/general.py"]
    MET["utils/metrics.py"]
    TU["utils/torch_utils.py"]
    LOG["utils/loggers/ + callbacks.py"]
  end

  subgraph Runtime["运行时"]
    TORCH["PyTorch / CUDA"]
    CV["OpenCV"]
    BACK["ONNX / TRT / OpenVINO / TFLite ..."]
  end

  Entry --> Model
  Entry --> Utility
  YAML --> YOLO
  YOLO --> COMMON
  EXP --> YOLO
  Utility --> TORCH
  Utility --> CV
  COMMON --> BACK

入口脚本负责组织流程;models/ 负责网络与推理运行时;utils/ 负责数据、增强、损失、指标和工程能力。

2.2 模型构建链

yolov5s.yamlyaml.safe_loadDetectionModelparse_modelnn.Sequential + save listBaseModel._forward_onceDetect(P3,P4,P5)

YAML 层定义

每层格式:

1
[from, number, module, args]
  • from:输入来自前一层或指定历史层
  • number:模块重复次数,受 depth_multiple 缩放
  • moduleConvC3SPPFConcatDetect
  • args:输出通道、卷积核、步长等构造参数

动态解析

models/yolo.py::parse_model()

  1. 合并 backbone + head
  2. 解析模块和字符串参数
  3. 按深度系数缩放重复数
  4. 按宽度系数缩放通道并对齐到 8
  5. 为每层附加 i/f/type/np
  6. 建立 save 列表,保留后续跳连所需输出

前向传播

BaseModel._forward_once() 顺序遍历 self.model。若 m.f != -1,就从历史输出 y 取跳连输入;只有 self.save 指定的中间层会被保留。

2.3 YOLOv5s 网络结构

640×640×3Conv /2Conv+C3 /4C3 P3/8C3 P4/16C3+SPPF P5/32上采样+Concat P4上采样+Concat P3Detect P3/8下采样+ConcatDetect P4/16下采样+ConcatDetect P5/32
  • Backbone:Conv + C3 + SPPF
  • Neck:FPN 自顶向下 + PAN 自底向上
  • Head:P3、P4、P5 三尺度 Anchor-based Detect

对 640 输入,三层网格约为 80×80、40×40、20×20。

2.4 训练数据流

data/*.yamlLoadImagesAndLabelsMosaic/MixUp/透视/HSV/翻转BGR→RGB, HWC→CHWmodel(imgs)ComputeLossAMP backwardoptimizer stepModelEMAval.runlast.pt / best.pt

train.py::train() 是流程控制中心。Rank 0 还负责日志、验证、保存和早停。

2.5 检测推理数据流

图片/视频/相机/流LoadImages/LoadStreamsLetterboxBGR→RGB, CHW, /255DetectMultiBackendnon_max_suppressionscale_boxes 回原图Annotator图片/视频/TXT/Crop

关键点:

  • 网络不是直接吃任意尺寸原图,而是先 Letterbox 到 stride 倍数。
  • 检测头输出在网络输入坐标系中。
  • scale_boxes 去掉 padding 并按比例映射回原图。

2.6 多后端架构

DetectMultiBackendPyTorch .ptTorchScriptONNX Runtime / OpenCV DNNTensorRTOpenVINOCoreMLSavedModel / PB / TFLite / EdgeTPUPaddleTriton Server

该类统一:

  • 模型格式识别
  • 设备与 FP16
  • NCHW/NHWC 转换
  • 元数据 stride/names
  • 输入输出转换为 Torch Tensor
  • 动态 TensorRT binding
  • 模型 warmup

2.7 训练并发模型

1
2
3
单 GPU/CPU: RANK=-1
DataParallel: 可用但源码明确不推荐
DDP: torch.distributed.run,每 GPU 一个进程

DDP 下:

  • 每个 Rank 使用分布式 sampler
  • 反向损失按 WORLD_SIZE 调整
  • 仅 Rank 0 做完整日志、验证和 checkpoint
  • 早停结果广播到所有 Rank

2.8 回调与日志

Callbacks 提供训练生命周期事件,例如:

1
2
3
4
5
6
7
on_pretrain_routine_start/end
on_train_start
on_train_epoch_start/end
on_train_batch_start/end
on_fit_epoch_end
on_model_save
on_train_end

Loggers 将对应方法注册为回调,使训练主循环不必绑定具体平台。TensorBoard、ClearML、Comet、W&B 等都通过该层接入。

YOLOv5 7.0:核心模块详解

03 核心模块详解

3.1 models/yolo.py

Detect

YOLOv5 检测头。主要成员:

成员 含义
nc 类别数
no = nc + 5 每个锚点的输出维度
nl 检测层数量,P5 模型通常为 3
na 每层锚点数,通常为 3
anchors 以网格单位保存的 Anchor
stride 各检测层步长
m 每层一个 1×1 输出卷积
grid 网格中心坐标
anchor_grid Anchor 的像素尺度

训练时返回三层原始张量:

1
[B, na, H, W, nc+5]

推理时解码并拼接为:

1
[B, 所有候选数, nc+5]

Segment

继承 Detect

  • Proto 从高分辨率特征产生共享 mask 原型
  • 每个候选额外预测 nm 个 mask 系数
  • 默认 nm=32npr=256

BaseModel

通用能力:

  • _forward_once():按 YAML 图执行
  • _profile_one_layer():逐层耗时/FLOPs
  • fuse():Conv+BN 融合
  • _apply():迁移 stride/grid/anchor_grid 到设备或精度

DetectionModel

职责:

  1. 读取模型 YAML
  2. 覆盖 nc 或 anchors
  3. 调用 parse_model
  4. 用 256×256 假输入推断 P3/P4/P5 stride
  5. 检查 Anchor 顺序并归一化
  6. 初始化 Detect bias

它还支持三尺度 TTA:缩放为 1、0.83、0.67,并做水平翻转后合并结果。

ClassificationModel

可从检测模型截取前若干层作为 backbone,并用 Classify 替换尾部模块。

parse_model

这是读懂 YOLOv5 模型图的核心函数:

1
2
3
4
5
6
YAML 字典
→ 缩放深度/宽度
→ 计算每层输入输出通道
→ 创建模块
→ 记录 from 索引
→ 生成 nn.Sequential 和 save list

3.2 models/common.py

基础网络块

作用
Conv Conv2d + BatchNorm + SiLU
DWConv 深度/分组卷积
Bottleneck 残差瓶颈
C3 CSP 风格双分支与瓶颈堆叠
SPPF 串行 5×5 MaxPool 快速空间金字塔
Concat 通道拼接
Proto 分割原型掩码
Classify 分类头

YOLOv5s 的主体模块是 Conv + C3 + SPPF

DetectMultiBackend

它不是网络结构,而是部署适配层。构造函数通过权重后缀判断运行时,并加载:

1
2
3
4
5
.pt / .torchscript / .onnx / .engine / .mlmodel
OpenVINO 模型目录
SavedModel / .pb / .tflite / EdgeTPU
Paddle 模型目录
Triton URL

forward() 负责:

  • PyTorch Tensor ↔ NumPy
  • NCHW ↔ NHWC
  • FP16
  • TensorRT 动态 shape/binding
  • TFLite INT8 量化与反量化
  • 统一输出为当前设备上的 Tensor

AutoShape

PyTorch Hub 的易用包装器,接受:

  • 路径/URL
  • PIL
  • NumPy
  • OpenCV 图
  • Tensor
  • 图片列表

非 Tensor 输入会自动完成三通道转换、Letterbox、BCHW、归一化、前向、NMS、坐标缩放,并返回 Detections

注意:注释明确要求 OpenCV BGR 输入先转 RGB,例如 cv2.imread(...)[..., ::-1]

Detections

封装结果展示和导出:

  • print() / show() / save()
  • crop()
  • render()
  • pandas()
  • tolist()

3.3 models/experimental.py

主要用于:

  • attempt_load():加载一个或多个 .pt
  • Conv+BN 融合
  • 模型兼容处理
  • 多模型 Ensemble

DetectMultiBackend 加载 PyTorch 权重时调用此处。

3.4 utils/dataloaders.py

推理加载器

输入
LoadImages 图片、视频、目录、glob
LoadStreams 摄像头、RTSP/RTMP/HTTP、多路流
LoadScreenshots 屏幕截图

训练加载器

LoadImagesAndLabels 负责:

  • 搜索图像和映射标签路径
  • 验证图片/标签
  • 建立 .cache
  • 矩形训练
  • RAM/磁盘缓存
  • Mosaic、MixUp、随机透视、HSV、翻转
  • 标签坐标在归一化 xywh 与像素 xyxy 间转换
  • BGR→RGB、HWC→CHW、连续内存

create_dataloader() 再包成 InfiniteDataLoader 或普通 DataLoader,并在 DDP 下使用分布式采样器。

3.5 utils/augmentations.py

关键函数:

函数/类 作用
letterbox 保持比例缩放并填充到 stride 倍数
random_perspective 旋转、平移、缩放、剪切、透视
augment_hsv HSV LUT 颜色增强
mixup 两张图与标签混合
copy_paste 分割数据复制粘贴
Albumentations 可选第三方增强包装

3.6 utils/loss.py

ComputeLoss 的组成:

1
2
3
总损失 = box gain × CIoU loss
+ obj gain × BCE objectness
+ cls gain × BCE classification

它还支持:

  • Label smoothing
  • FocalLoss
  • 各检测尺度 Objectness balance
  • Anchor 宽高比匹配
  • 相邻网格偏移匹配

3.7 utils/general.py

高频函数包括:

  • non_max_suppression
  • scale_boxes
  • xyxy2xywh / xywh2xyxy
  • check_dataset / check_file / check_img_size
  • increment_path
  • strip_optimizer
  • YAML 加载/保存

这是入口脚本最常依赖的通用工具集。

3.8 utils/metrics.py

负责:

  • box_iou
  • AP/mAP 计算
  • ap_per_class
  • 混淆矩阵
  • fitness 计算

验证脚本在 IoU 阈值 0.50 到 0.95 上判断预测正确性,输出 Precision、Recall、mAP@0.5mAP@0.5:0.95。

3.9 utils/torch_utils.py

关键工程能力:

  • select_device
  • smart_optimizer
  • smart_DDP
  • ModelEMA
  • AMP 检查
  • EarlyStopping
  • Conv+BN 融合
  • 分布式同步辅助

3.10 回调和日志

  • utils/callbacks.py::Callbacks:维护事件与动作
  • utils/loggers/__init__.py::Loggers:统一日志适配

主训练循环只触发事件,具体日志平台通过注册回调接入,实现控制流与外部服务解耦。

YOLOv5 7.0:算法流水线

04 算法流水线

4.1 检测训练

入口:train.py::main()train()

parse_optcheck_dataset加载权重/按 YAML 创建模型可选冻结层创建 train/val DataLoaderAutoAnchorEpoch/Batch 循环forwardComputeLossAMP backward + 梯度裁剪梯度累积 + optimizer.stepModelEMAval.runlast.pt / best.pt / EarlyStopping

初始化阶段

  1. 解析超参数并保存 hyp.yamlopt.yaml
  2. 检查数据集 YAML
  3. 加载预训练 checkpoint,或按 YAML 从零创建
  4. 通过 state_dict 交集迁移可匹配权重
  5. 配置冻结层、AMP、图像尺寸
  6. 创建优化器、学习率调度器、EMA
  7. 创建训练/验证 DataLoader
  8. 非恢复训练时执行 AutoAnchor

Batch 阶段

1
2
3
4
5
6
7
8
9
10
uint8 图片 → GPU → float → /255
→ Warmup 学习率和 momentum
→ 可选 Multi-scale
→ model(imgs)
→ ComputeLoss(pred, targets)
→ GradScaler.backward()
→ 累积到 nominal batch size 64
→ unscale + clip_grad_norm_(10)
→ optimizer.step()
→ EMA.update()

Epoch 结束

  • 更新 LR scheduler
  • 使用 EMA 模型验证
  • 用 P/R/mAP 组合计算 fitness
  • EarlyStopping
  • 保存 last.ptbest.pt、可选周期 checkpoint

checkpoint 不只是权重,还保存 epoch、best fitness、EMA、optimizer、运行参数、Git 信息和时间。

4.2 验证

入口:val.py::run()

加载 DetectMultiBackend 或接收训练模型create_dataloaderforwardNMSscale_boxes与 GT 按 IoU 0.50:0.95 匹配ap_per_classP / R / mAP50 / mAP50-95

验证脚本可独立运行,也可由 train.py 传入模型与 DataLoader。核心函数:

  • process_batch():按类别和 IoU 判断检测是否正确
  • ConfusionMatrix.process_batch():构建混淆矩阵
  • ap_per_class():计算 PR 曲线与 AP
  • 可选保存 TXT、JSON、混淆矩阵和样本图

COCO 数据可输出 JSON 并调用 pycocotools 做官方评估。

4.3 检测推理

入口:detect.py::run()

source判断图片/视频/流/屏幕LoadImages / LoadStreams / LoadScreenshotsLetterbox + RGB CHW + /255DetectMultiBackend.forwardNMSscale_boxes 回原图绘制框/标签/裁剪图片/MP4/TXT

关键逻辑:

  1. URL 文件先下载,实时 URL 走流加载器
  2. 根据 stride 修正 imgsz
  3. 模型 warmup
  4. 每帧预处理、前向、NMS
  5. 把网络坐标映射回 im0
  6. 输出 YOLO TXT、Crop、图片或视频
  7. 打印预处理、推理、NMS 的独立耗时

4.4 Letterbox 与坐标还原

Letterbox 不强行把原图拉伸成正方形:

1
2
3
4
原图 H×W
→ 按比例缩放
→ 两边填 114
→ 输出尺寸对齐 stride

优点是物体几何比例不变。缺点是预测框坐标处于「缩放+padding」后的坐标系,所以必须调用:

1
det[:, :4] = scale_boxes(network_shape, det[:, :4], original_shape)

4.5 NMS

utils/general.py::non_max_suppression()

  1. 用 Objectness 预筛选
  2. 计算 confidence = objectness × class_probability
  3. 从 xywh 转为 xyxy
  4. 可筛类别、支持 multi-label
  5. 按类别偏移框,或执行 class-agnostic NMS
  6. 调用 torchvision.ops.nms
  7. 限制 max_det

conf_thres 控制候选置信度,iou_thres 控制重叠框压制强度。

4.6 分割流水线

训练

segment/train.py 大体复用检测训练框架,但使用:

  • 分割 DataLoader
  • ComputeLossutils/segment/loss.py
  • mask/segment 标注
  • 检测损失 + mask 损失

推理

1
2
3
4
5
6
Segment head
→ 检测预测 + prototype masks
→ NMS
→ 候选 mask 系数 × prototype
→ 上采样/裁框
→ 绘制实例 mask 和 box

4.7 分类流水线

分类任务在 classify/

1
2
3
4
5
ImageFolder
→ 分类增强
→ ClassificationModel
→ CrossEntropy
→ top-1 / top-5

可从 YOLOv5 检测模型 backbone 构造分类模型。

4.8 导出流水线

入口:export.py::run()

.pt checkpointattempt_load + fuse构造假输入并前向TorchScriptONNXOpenVINOTensorRTCoreMLSavedModelGraphDefTFLiteEdge TPUPaddle

每种导出器由 @try_export 包装:自动记录耗时、捕获异常并返回产物。dynamichalfint8opsetsimplify 等参数只对相应格式生效。

4.9 PyTorch Hub 流程

hubconf.py 提供 yolov5n/s/m/l/xcustom

1
2
model = torch.hub.load("ultralytics/yolov5", "custom", "best.pt")
results = model(images)

Hub 默认用 AutoShape 包装,因此把预处理、NMS 和结果封装隐藏起来;追踪性能或排查坐标问题时,应回到 detect.py 的显式流程。

YOLOv5 7.0:模型损失与数据

05 模型损失与数据

5.1 YOLOv5s YAML

models/yolov5s.yaml 的关键配置:

1
2
3
4
5
6
7
nc: 80
depth_multiple: 0.33
width_multiple: 0.50
anchors:
- [10,13, 16,30, 33,23] # P3/8
- [30,61, 62,45, 59,119] # P4/16
- [116,90, 156,198, 373,326] # P5/32

模型主干:

1
2
3
4
5
6
Conv(stride=2)
→ Conv+C3
→ P3/8
→ P4/16
→ P5/32
→ SPPF

Neck 使用上采样与 Concat 构成 FPN/PAN,最后把第 17、20、23 层送入 Detect

5.2 深度和宽度缩放

parse_model() 的规则:

1
2
实际重复数 = max(round(number × depth_multiple), 1)
实际通道数 = make_divisible(channels × width_multiple, 8)

因此 n/s/m/l/x 可以复用相同类型的拓扑定义,只改变容量。

输出层通道数不能按普通 width multiple 缩放,因为其维度固定为:

1
na × (nc + 5)

5.3 C3 与 SPPF

C3

C3 是 CSP 风格模块:

  • 一支经过若干 Bottleneck
  • 一支较短旁路
  • 两支 Concat 后再卷积

它在控制计算量的同时保留梯度路径,是 YOLOv5 backbone/neck 的主体。

SPPF

SPPF 用同一个 5×5 MaxPool 串行执行三次,得到等效 5/9/13 感受野,再拼接。相对传统并行 SPP,结构更简单、速度更快。

5.4 检测头输出

P5 模型有三层输出,每层三个 Anchor。训练输出:

1
B × 3 × H × W × (nc+5)

其中:

1
2
3
4
0:2  → xy
2:4 → wh
4 → objectness
5: → class logits

640 输入、80 类时,三层形状近似:

1
2
3
[B, 3, 80, 80, 85]
[B, 3, 40, 40, 85]
[B, 3, 20, 20, 85]

候选总数:

1
3 × (80² + 40² + 20²) = 25200

5.5 推理解码

Detect.forward() 对每层:

1
2
3
xy = (sigmoid(xy) * 2 + grid) * stride
wh = (sigmoid(wh) * 2) ** 2 * anchor_grid
conf = sigmoid(conf)

grid-0.5 偏移,因此中心可预测到相邻网格附近。宽高公式将范围扩大到约 0~4 倍 Anchor。

解码结果是中心点格式 xywh;NMS 前再转换成 xyxy。

5.6 Anchor 匹配与目标构建

入口:utils/loss.py::ComputeLoss.build_targets()

输入目标每行:

1
[image_index, class, x, y, w, h]

坐标是相对图片归一化的 xywh。

目标构建步骤:

  1. 每个目标复制到每个 Anchor
  2. 按当前检测层网格尺寸缩放坐标
  3. 比较目标宽高与 Anchor 宽高比例
  4. 最大正反比例小于 anchor_t 才匹配
  5. 位于网格边缘的目标额外分配到上/下/左/右邻格
  6. 输出类别、回归框、索引和匹配 Anchor

这种一对多分配提高了正样本数量。

5.7 检测损失

Box Loss

1
lbox = mean(1 - CIoU(pred_box, target_box))

CIoU 同时考虑:

  • 重叠面积
  • 中心点距离
  • 宽高比一致性

Objectness Loss

每个网格/Anchor 都有 Objectness BCE。正样本目标值不是固定 1,而是与匹配框的 IoU 相关:

1
tobj[b, a, gj, gi] = detached IoU

P3/P4/P5 默认 balance 为 [4.0, 1.0, 0.4],用于平衡不同尺度网格数量。

Classification Loss

多类别时对类别 logits 使用 BCEWithLogitsLoss。可启用:

  • label_smoothing
  • fl_gamma > 0 的 Focal Loss

总损失

1
2
3
4
5
loss = batch_size × (
box_gain × lbox +
obj_gain × lobj +
cls_gain × lcls
)

train.py 还会按检测层数、类别数和图像尺寸调整三项 gain。

5.8 数据集格式

数据集 YAML 示例:

1
2
3
4
5
6
7
path: ../datasets/mydata
train: images/train
val: images/val
test:
names:
0: person
1: car

检测标签为每张图片对应的 .txt

1
class x_center y_center width height

四个坐标均归一化到 0~1。目录通常为:

1
2
3
4
5
mydata/
├── images/train
├── images/val
├── labels/train
└── labels/val

img2label_paths()imageslabels、扩展名 → .txt 自动映射。

5.9 数据加载与缓存

LoadImagesAndLabels

  • 扫描目录或图片清单
  • 校验图像和标签
  • 把标签、尺寸、分割多边形写入 .cache
  • 用文件 hash 和 cache version 判断缓存是否失效
  • 可把图片缓存到 RAM 或 .npy
  • 矩形训练时按宽高比排序,降低 padding

5.10 数据增强

增强分为两条互斥主路径:

读取图像"本次使用 Mosaic?"load_mosaic: 4图拼接Copy-Paste + 随机透视可选 MixUp(再加载一组 Mosaic)Letterbox随机透视/旋转/平移/缩放/剪切可选 AlbumentationsHSV上下/左右翻转BGR→RGB, HWC→CHW

Mosaic

把当前图片和三张随机图放入 2×2 大画布;load_mosaic() 内部完成 Copy-Paste(启用时)和随机透视。返回 __getitem__() 后还可与另一组 Mosaic 做 MixUp。优点:

  • 一次看到更多物体
  • 小目标更丰富
  • 减少对大 batch 的依赖

Rectangular Training

按宽高比排序,同一 batch 使用接近的矩形尺寸,可减少灰边,但会禁用 Mosaic。

DDP 下,标签缓存的首次扫描通过 torch_distributed_zero_first() 让本地 Rank 0 优先完成,其他进程随后复用,避免同时重复构建 .cache

5.11 超参数

data/hyps/hyp.scratch-low.yaml 分四组:

  • 优化:lr0/lrf/momentum/weight_decay/warmup_*
  • 损失:box/cls/obj/*_pw/fl_gamma
  • 匹配:iou_t/anchor_t
  • 增强:hsv_* / degrees / translate / scale / shear / perspective / flip* / mosaic / mixup

anchor_t 太小会减少正样本;太大会让不合适的 Anchor 也参与训练。mosaicscale 对小数据集帮助大,但过强会造成训练分布与真实场景不一致。

5.12 AutoAnchor

训练前 check_anchors() 比较数据集目标宽高和模型 Anchor。适配度差时会重新聚类/进化 Anchor。

修改输入尺寸或目标尺度分布后,应重新检查 Anchor;加载预训练权重但自定义了模型 Anchor 时,训练代码会避免迁移不兼容的 Anchor 状态。

YOLOv5 7.0:配置与使用

06 配置与使用

6.1 安装

1
2
3
4
cd /home/cp/work2/visualAlgo/YOLO/yolov5-7.0
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

PyTorch 是否带 CUDA,应按本机驱动从 PyTorch 官方安装对应版本。仅执行 requirements.txt 不保证获得正确的 CUDA wheel。

验证环境:

1
2
3
4
5
6
python - <<'PY'
import torch, cv2
print("torch:", torch.__version__)
print("cuda:", torch.cuda.is_available())
print("opencv:", cv2.__version__)
PY

6.2 权重

源码目录不等于权重包。常用权重:

1
2
3
4
5
yolov5n.pt  最小最快
yolov5s.pt 常用入门
yolov5m.pt
yolov5l.pt
yolov5x.pt 最大

传入不存在的官方权重名时,attempt_download() 会尝试下载。离线机器应提前复制 .pt

也可执行:

1
bash data/scripts/download_weights.sh

6.3 快速检测

1
2
3
4
5
6
python detect.py \
--weights yolov5s.pt \
--source data/images \
--img 640 \
--conf-thres 0.25 \
--iou-thres 0.45

结果默认写入:

1
runs/detect/exp/

常见 source:

1
2
3
4
5
6
--source image.jpg
--source images/
--source video.mp4
--source 0
--source rtsp://...
--source screen

常见选项:

1
2
3
4
5
6
7
--save-txt           # 保存 class xywh
--save-conf # TXT 追加置信度
--save-crop # 保存目标裁剪
--classes 0 2 # 只保留指定类别
--agnostic-nms # 类别无关 NMS
--half # 支持的 GPU/后端上 FP16
--vid-stride 2 # 视频隔帧

6.4 自定义数据集

目录:

1
2
3
4
5
6
7
datasets/mydata/
├── images/
│ ├── train/
│ └── val/
└── labels/
├── train/
└── val/

data/mydata.yaml

1
2
3
4
5
6
path: ../datasets/mydata
train: images/train
val: images/val
names:
0: cat
1: dog

标签:

1
0 0.512 0.480 0.200 0.350

含义为 class cx cy w h,坐标归一化。类别必须从 0 连续编号,且小于 nc

6.5 训练

迁移学习

1
2
3
4
5
6
7
python train.py \
--weights yolov5s.pt \
--data data/mydata.yaml \
--epochs 100 \
--img 640 \
--batch-size 16 \
--device 0

从零训练

1
2
3
4
5
6
python train.py \
--weights '' \
--cfg models/yolov5s.yaml \
--data data/mydata.yaml \
--hyp data/hyps/hyp.scratch-low.yaml \
--epochs 300

自动 Batch

单 GPU 可使用:

1
--batch-size -1

冻结 Backbone

1
--freeze 10

表示冻结模型前 10 层,适合小数据集初期迁移。

6.6 恢复训练

1
python train.py --resume runs/train/exp/weights/last.pt

恢复需要 last.pt 中仍包含:

  • epoch
  • optimizer
  • EMA
  • opt/hyp

训练结束时 strip_optimizer() 会移除优化器状态并转 FP16;被 strip 的部署权重不适合完整恢复。

6.7 多 GPU DDP

1
2
3
4
5
6
python -m torch.distributed.run \
--nproc_per_node 4 \
train.py \
--batch-size 64 \
--device 0,1,2,3 \
--data data/mydata.yaml

源码明确不推荐传统 DataParallel。DDP 的 batch-size 是总 batch,会按 WORLD_SIZE 分给各 GPU。

6.8 验证

1
2
3
4
5
6
python val.py \
--weights runs/train/exp/weights/best.pt \
--data data/mydata.yaml \
--img 640 \
--conf-thres 0.001 \
--iou-thres 0.6

主要输出:

  • Precision
  • Recall
  • mAP@0.5
  • mAP@0.5:0.95
  • 各类别 AP
  • 混淆矩阵和 PR 曲线(未关闭 plots 时)

验证时低 conf-thres 是为了保留完整 PR 曲线,不等同于部署阈值。

6.9 分割

1
2
3
4
5
6
7
8
9
10
11
12
13
python segment/train.py \
--model yolov5s-seg.pt \
--data data/coco128-seg.yaml \
--epochs 5 \
--img 640

python segment/val.py \
--weights yolov5s-seg.pt \
--data data/coco128-seg.yaml

python segment/predict.py \
--weights yolov5s-seg.pt \
--source data/images

6.10 分类

1
2
3
4
5
6
7
8
9
10
11
12
13
python classify/train.py \
--model yolov5s-cls.pt \
--data cifar100 \
--epochs 5 \
--img 224

python classify/val.py \
--weights yolov5s-cls.pt \
--data ../datasets/imagenet

python classify/predict.py \
--weights yolov5s-cls.pt \
--source data/images

6.11 PyTorch Hub

本地源码(以下直接传图片的写法适用于检测模型;v7.0 的分类/分割模型不会自动套用 AutoShape):

1
2
3
4
5
6
7
8
9
10
11
import torch

model = torch.hub.load(
"/home/cp/work2/visualAlgo/YOLO/yolov5-7.0",
"custom",
path="best.pt",
source="local",
)
results = model("image.jpg")
results.print()
results.save()

若输入是 OpenCV 数组,AutoShape 注释期望 RGB:

1
2
rgb = cv2.imread("image.jpg")[:, :, ::-1]
results = model(rgb)

仓库中的 sample_detect.py 是该模式的最小示例。

6.12 导出

ONNX

1
2
3
4
5
6
python export.py \
--weights best.pt \
--include onnx \
--img 640 \
--opset 12 \
--simplify

TensorRT

1
2
3
4
5
python export.py \
--weights best.pt \
--include engine \
--device 0 \
--half

OpenVINO

1
python export.py --weights best.pt --include openvino

其他 --include 格式见:

1
python export.py --help

6.13 ONNX + OpenCV DNN

1
2
3
4
python detect.py \
--weights best.onnx \
--source image.jpg \
--dnn

这会让 DetectMultiBackend 调用 cv2.dnn.readNetFromONNX(),而不是 ONNX Runtime。

6.14 常见问题

yolov5s.pt 不存在

源码没有内置权重。联网时自动下载;离线时手动放到当前目录或传绝对路径。

CUDA 不可用

检查:

1
torch.cuda.is_available()

若为 False,通常是安装了 CPU 版 PyTorch、驱动不匹配或容器没挂 GPU。

标签越界

日志出现:

1
Label class X exceeds nc=N

说明标签类别 ID 大于数据集 YAML 中类别数,或类别不是从 0 开始。

OOM

依次尝试:

  • 减小 --batch-size
  • 减小 --img
  • 使用 --batch-size -1
  • 使用更小模型
  • 关闭 cache 或改 disk

框映射不准

不要直接把网络输入坐标画到原图;必须用 scale_boxes() 消除 Letterbox 的缩放和 padding。

RK3588 NPU

.pt 默认只能走 PyTorch CPU/GPU。RK3588 NPU 通常要:

1
.pt → ONNX → RKNN → RKNN Runtime

--device 不能让 PyTorch .pt 自动运行在 RK NPU。

YOLOv5 7.0:源码文件索引

07 源码文件索引

根路径:

1
YOLO/yolov5-7.0/

7.1 任务入口

文件 关键入口 职责
train.py train, main, run 检测训练、验证、保存、超参进化
val.py run, process_batch 检测评估、AP、JSON/TXT
detect.py run 图片/视频/流检测
export.py run, export_* 多格式模型导出
benchmarks.py run 导出格式速度和精度基准
hubconf.py _create, custom, yolov5* PyTorch Hub
segment/train.py train 实例分割训练
segment/val.py run 实例分割评估
segment/predict.py run 实例分割推理
classify/train.py train 分类训练
classify/val.py run 分类评估
classify/predict.py run 分类推理

7.2 模型核心

文件/类 职责
models/yolo.py::Detect 三尺度 Anchor 检测头与推理解码
models/yolo.py::Segment Detect + Proto 实例分割头
models/yolo.py::BaseModel 通用前向、profile、fuse
models/yolo.py::DetectionModel 从 YAML 构建检测模型
models/yolo.py::ClassificationModel 分类模型或检测 backbone 改造
models/yolo.py::parse_model YAML → nn.Sequential
models/common.py::Conv Conv+BN+SiLU
models/common.py::C3 CSP 主干模块
models/common.py::SPPF 快速空间金字塔池化
models/common.py::Proto 分割原型
models/common.py::Classify 分类头
models/common.py::DetectMultiBackend 多运行时推理
models/common.py::AutoShape 自动预处理/NMS
models/common.py::Detections 结果封装
models/experimental.py::attempt_load .pt 权重/集成加载

7.3 数据与增强

文件/对象 职责
utils/dataloaders.py::create_dataloader 创建训练/验证 DataLoader
LoadImagesAndLabels 检测数据、标签、缓存、增强
LoadImages 图片/视频推理输入
LoadStreams 摄像头/网络流
LoadScreenshots 屏幕输入
InfiniteDataLoader 复用 worker 的无限迭代器
utils/augmentations.py::letterbox 等比例缩放和 padding
random_perspective 几何增强
augment_hsv HSV 增强
mixup MixUp
utils/segment/dataloaders.py 分割数据加载
utils/segment/augmentations.py 分割增强

7.4 损失与指标

文件/对象 职责
utils/loss.py::ComputeLoss CIoU + Obj BCE + Class BCE
ComputeLoss.build_targets Anchor/网格正样本匹配
BCEBlurWithLogitsLoss 缓和缺失标签影响
FocalLoss / QFocalLoss 难样本加权
utils/metrics.py::box_iou IoU 计算
ap_per_class 每类别 P/R/AP
ConfusionMatrix 混淆矩阵
utils/segment/loss.py 分割损失
utils/segment/metrics.py Mask AP

7.5 通用与 PyTorch 工具

文件 高频内容
utils/general.py NMS、坐标转换、路径/YAML/数据检查
utils/torch_utils.py 设备、AMP、DDP、EMA、优化器、早停
utils/autoanchor.py Anchor 适配度检查和进化
utils/autobatch.py 自动估算 batch size
utils/callbacks.py 生命周期事件
utils/loggers/ 日志平台适配
utils/plots.py Annotator、训练图、框绘制
utils/downloads.py 数据与权重下载

7.6 配置文件

路径 内容
models/yolov5n.yaml Nano 检测模型
models/yolov5s.yaml Small 检测模型
models/yolov5m.yaml Medium 检测模型
models/yolov5l.yaml Large 检测模型
models/yolov5x.yaml Extra Large 检测模型
models/segment/*.yaml 分割模型
models/hub/*.yaml P6/P7 与实验结构
data/*.yaml 数据集路径和类别
data/hyps/*.yaml 学习率、损失和增强超参数

7.7 检测主调用链

1
2
3
4
5
6
7
8
9
10
11
12
13
detect.py::run
→ DetectMultiBackend(...)
→ attempt_load() # .pt
→ LoadImages / LoadStreams
→ letterbox()
→ DetectMultiBackend.forward()
→ DetectionModel.forward()
→ BaseModel._forward_once()
→ Detect.forward()
→ non_max_suppression()
→ scale_boxes()
→ Annotator.box_label()
→ cv2.imwrite / VideoWriter

7.8 训练主调用链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
train.py::main
→ select_device / DDP 初始化
→ train()
→ check_dataset()
→ Model(...) = DetectionModel(...)
→ parse_model()
→ create_dataloader()
→ LoadImagesAndLabels
→ check_anchors()
→ ComputeLoss(model)
→ epoch
→ model(imgs)
→ compute_loss(pred, targets)
→ build_targets()
→ AMP backward
→ optimizer.step()
→ ModelEMA.update()
→ val.run()
→ torch.save(last/best)

7.9 验证主调用链

1
2
3
4
5
6
7
8
9
val.py::run
→ DetectMultiBackend 或传入 model
→ create_dataloader
→ forward
→ non_max_suppression
→ scale_boxes
→ process_batch
→ ap_per_class
→ P/R/mAP + confusion matrix

7.10 导出函数

export.py 主要导出器:

1
2
3
4
5
6
7
8
9
10
11
export_torchscript
export_onnx
export_openvino
export_paddle
export_coreml
export_engine
export_saved_model
export_pb
export_tflite
export_edgetpu
export_tfjs

7.11 推荐阅读顺序

  1. detect.py::run():先理解端到端推理
  2. models/yolov5s.yaml:看网络图
  3. models/yolo.py::parse_model():理解 YAML 如何变成模型
  4. BaseModel._forward_once():理解跳连执行
  5. Detect.forward():理解训练输出和推理解码差异
  6. utils/general.py::non_max_suppression():理解后处理
  7. utils/dataloaders.py::LoadImagesAndLabels:理解输入与增强
  8. utils/loss.py::ComputeLoss:理解监督信号
  9. train.py::train():最后串起 AMP、EMA、DDP、验证与保存
  10. 按需要读 segment/classify/export.py

7.12 二次开发定位

想修改的能力 优先文件
Backbone/Neck 模型 YAML + models/common.py
检测头解码 models/yolo.py::Detect
新网络模块 models/common.py + parse_model
损失函数 utils/loss.py
正样本分配 ComputeLoss.build_targets
数据增强 utils/augmentations.py、DataLoader __getitem__
NMS utils/general.py
图片/流输入 utils/dataloaders.py
训练日志 utils/callbacks.pyutils/loggers/
新导出格式 export.py + DetectMultiBackend