YOLOv5(四):models/common.py 核心模块速查表
两大流程的核心关联
| 流程 | 核心依赖的 common.py 组件 | 核心目的 | 触发场景 |
|---|---|---|---|
| 模型构建 | Conv/C3/SPPF/Concat/Focus + 工具函数 | 搭建可训练/推理的网络结构 | 训练前初始化、推理前加载模型 |
| 推理部署 | AutoShape/DetectMultiBackend/Detections + 所有特征提取模块 | 端到端检测,输出可视化结果 | 实际检测任务、部署落地 |
总结
common.py 的核心逻辑是 “组件化支撑”:模型构建时提供“积木”(特征提取、维度变换模块),推理时提供“执行单元”(前向传播)和“流程封装”(预处理、结果可视化),两大流程通过 yolo.py 的网络定义和 DetectMultiBackend 的推理调度串联,最终实现从配置到检测结果的端到端闭环。
流程-模块-作用 对应表
| 核心流程 | 关键环节 | 核心模块(common.py) | 具体作用 |
|---|---|---|---|
| 一、模型构建流程(yolo.py 驱动) | 1. 输入层构建 | Focus | 压缩宽高(640→320)、提升通道数(3→12),聚合初始空间信息 |
| 2. Backbone 特征提取 | Conv、C3、BottleneckCSP | Conv:基础特征提取(Conv+BN+SiLU);C3/BottleneckCSP:深度特征提取+残差融合 | |
| 3. 多尺度特征聚合 | SPPF、SPP | 多尺度池化(SPPF效率更高),融合不同感受野特征,增强全局信息捕捉能力 | |
| 4. Neck 特征融合 | Concat、C3、Conv | Concat:跨层特征拼接(如P3/P4/P5尺度);C3:拼接后特征融合;Conv:通道调整 | |
| 5. 网络初始化 | 所有模块(Conv/C3等)+ autopad工具 | autopad:自动计算padding确保Same卷积;模块权重通过initialize_weights初始化 | |
| 二、推理部署流程(独立/yolo.py 调用) | 1. 输入预处理 | AutoShape | 兼容cv2/np/PIL/torch输入,统一执行LetterBox填充、通道转换、归一化 |
| 2. 特征提取(推理阶段) | Conv、C3、SPPF、Concat等所有特征模块 | 按网络顺序执行forward方法,输出检测头所需的多尺度特征图 | |
| 3. 多后端推理适配 | DetectMultiBackend | 兼容PyTorch/ONNX/TensorRT等10+后端,统一推理接口,屏蔽后端差异 | |
| 4. 推理加速(可选) | Conv(forward_fuse方法) | 融合Conv+BN层,减少计算步骤,提升推理速度(约10-20%) | |
| 5. 后处理与结果封装 | AutoShape、Detections | AutoShape:执行NMS、坐标缩放;Detections:封装多格式结果(xyxy/xywh) | |
| 6. 可视化与输出 | Detections | 支持打印检测信息、显示图像、保存结果、裁剪目标区域,适配部署需求 |
补充说明
- 表格按“流程→环节→模块→作用”层层对应,覆盖从网络搭建到推理落地的全链路;
- 核心模块均来自
common.py,避免遗漏关键组件; - 作用描述聚焦“核心功能”,不冗余细节,方便快速查阅模块在流程中的定位。
模块-参数-核心代码 速查表
| 模块名称 | 关键参数(含义) | 核心代码(精简版,保留关键逻辑) |
|---|---|---|
| Conv(标准卷积) | c1:输入通道数 c2:输出通道数 k:卷积核尺寸 act:是否启用SiLU激活(默认True) | python<br>def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):<br> self.conv = nn.Conv2d(c1, c2, k, s, autopad(k,p), groups=g, bias=False)<br> self.bn = nn.BatchNorm2d(c2)<br> self.act = nn.SiLU() if act else nn.Identity()<br>def forward(self, x):<br> return self.act(self.bn(self.conv(x)))<br>def forward_fuse(self, x):<br> return self.act(self.conv(x))<br> |
| C3(特征融合) | c1:输入通道数 c2:输出通道数 n:残差块数量 shortcut:是否启用残差连接(默认True) | python<br>def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):<br> c_ = int(c2*e)<br> self.cv1 = Conv(c1, c_, 1, 1)<br> self.cv2 = Conv(c1, c_, 1, 1)<br> self.cv3 = Conv(2*c_, c2, 1)<br> self.m = nn.Sequential(*(Bottleneck(c_,c_,shortcut,g) for _ in range(n)))<br>def forward(self, x):<br> return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))<br> |
| SPPF(快速多尺度池化) | c1:输入通道数 c2:输出通道数 k:池化核尺寸(默认5,等效5/9/13池化) | python<br>def __init__(self, c1, c2, k=5):<br> c_ = c1//2<br> self.cv1 = Conv(c1, c_, 1, 1)<br> self.cv2 = Conv(c_*4, c2, 1, 1)<br> self.m = nn.MaxPool2d(k, 1, k//2)<br>def forward(self, x):<br> x = self.cv1(x)<br> y1,y2,y3 = self.m(x), self.m(y1), self.m(y2)<br> return self.cv2(torch.cat([x,y1,y2,y3],1))<br> |
| Focus(维度变换) | c1:输入通道数 c2:输出通道数 k:卷积核尺寸(默认1) | python<br>def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):<br> self.conv = Conv(c1*4, c2, k, s, p, g, act)<br>def forward(self, x):<br> return self.conv(torch.cat([x[...,::2,::2], x[...,1::2,::2],<br> x[...,::2,1::2], x[...,1::2,1::2]], 1))<br> |
| GhostConv(轻量化卷积) | c1:输入通道数 c2:输出通道数 k:卷积核尺寸(默认1) | python<br>def __init__(self, c1, c2, k=1, s=1, g=1, act=True):<br> c_ = c2//2<br> self.cv1 = Conv(c1, c_, k, s, None, g, act)<br> self.cv2 = Conv(c_, c_, 5, 1, None, c_, act)<br>def forward(self, x):<br> y = self.cv1(x)<br> return torch.cat([y, self.cv2(y)], 1)<br> |
| Concat(拼接) | dimension:拼接维度(默认1=通道维度) | python<br>def __init__(self, dimension=1):<br> self.d = dimension<br>def forward(self, x):<br> return torch.cat(x, self.d)<br> |
| AutoShape(输入自适应) | conf:NMS置信度阈值(默认0.25) iou:NMS IoU阈值(默认0.45) max_det:最大检测数(默认1000) | python<br>@torch.no_grad()<br>def forward(self, imgs, size=640, augment=False, profile=False):<br> # 输入预处理:统一格式→LetterBox→BCHW→归一化<br> x = [letterbox(im, new_shape=shape1, auto=False)[0] for im in imgs]<br> x = np.stack(x,0).transpose((0,3,1,2))<br> x = torch.from_numpy(x).to(p.device).type_as(p)/255<br> # 推理+后处理<br> y = self.model(x, augment, profile)<br> y = non_max_suppression(y, self.conf, self.iou, max_det=self.max_det)<br> for i in range(n):<br> scale_coords(shape1, y[i][:, :4], shape0[i])<br> return Detections(imgs, y, files, t, self.names, x.shape)<br> |
| DetectMultiBackend(多后端推理) | weights:模型路径 device:推理设备 dnn:是否启用OpenCV DNN后端(默认False) | python<br>def __init__(self, weights='yolov5s.pt', device=None, dnn=False, data=None):<br> # 识别模型类型→初始化对应后端(PyTorch/ONNX/TRT等)<br> pt, jit, onnx, xml, engine = self.model_type(w)<br> if pt: self.model = attempt_load(weights, map_location=device)<br> elif onnx: self.session = onnxruntime.InferenceSession(w, providers=providers)<br> # 其他后端初始化...<br>def forward(self, im, augment=False, visualize=False, val=False):<br> # 不同后端推理逻辑→统一输出格式<br> return torch.tensor(y) if isinstance(y, np.ndarray) else y<br> |
| Detections(结果封装) | imgs:原始图像列表 pred:检测结果张量 names:类别名称列表 | python<br>def __init__(self, imgs, pred, files, times=(0,0,0,0), names=None, shape=None):<br> self.xyxy = pred<br> self.xywh = [xyxy2xywh(x) for x in pred]<br> self.xyxyn = [x/g for x,g in zip(self.xyxy, gn)]<br> self.t = tuple((times[i+1]-times[i])*1000/self.n for i in range(3))<br>def display(self, pprint=False, show=False, save=False, crop=False):<br> # 可视化/保存/裁剪逻辑...<br> |
速查表说明
- 聚焦
common.py中最常用的核心模块,参数仅保留关键项(忽略次要默认参数); - 核心代码精简为“关键逻辑+核心API”,去掉冗余注释和异常处理,方便快速定位核心实现;
- 按“基础模块→特征模块→工具模块→推理模块”排序,符合开发时的查询习惯;
- 适用于开发时快速查阅模块参数含义、核心逻辑,无需翻阅完整源码。
以下是 common.py 核心模块的独立调用示例代码集(基于 PyTorch,可直接复制运行,附输出说明),涵盖模块初始化、输入处理、前向传播全流程:
1. Conv(标准卷积模块)
作用:基础卷积+BN+激活,实现特征提取
import torch
from models.common import Conv # 假设已将YOLOv5的models目录加入环境变量# 1. 初始化模块:输入3通道,输出16通道,卷积核3x3,步长1
conv = Conv(c1=3, c2=16, k=3, s=1)# 2. 准备输入:模拟1张3通道、32x32的图像(BCHW格式)
x = torch.randn(1, 3, 32, 32) # 随机生成输入张量# 3. 前向传播
output = conv(x)# 4. 输出结果
print(f"输入形状: {x.shape}") # torch.Size([1, 3, 32, 32])
print(f"输出形状: {output.shape}") # torch.Size([1, 16, 32, 32])(Same卷积,尺寸不变)
2. C3(特征融合模块)
作用:通过残差块堆叠+特征拼接,增强特征表达能力
import torch
from models.common import C3, Conv # C3依赖Conv和Bottleneck# 1. 初始化模块:输入16通道,输出32通道,2个残差块,启用残差连接
c3 = C3(c1=16, c2=32, n=2, shortcut=True)# 2. 准备输入:承接Conv的输出(1,16,32,32)
x = torch.randn(1, 16, 32, 32)# 3. 前向传播
output = c3(x)# 4. 输出结果
print(f"输入形状: {x.shape}") # torch.Size([1, 16, 32, 32])
print(f"输出形状: {output.shape}") # torch.Size([1, 32, 32, 32])(通道数翻倍,尺寸不变)
3. SPPF(快速多尺度池化)
作用:通过多尺度最大池化融合不同感受野特征
import torch
from models.common import SPPF# 1. 初始化模块:输入32通道,输出64通道,池化核5x5(等效5/9/13池化)
sppf = SPPF(c1=32, c2=64, k=5)# 2. 准备输入:承接C3的输出(1,32,32,32)
x = torch.randn(1, 32, 32, 32)# 3. 前向传播
output = sppf(x)# 4. 输出结果
print(f"输入形状: {x.shape}") # torch.Size([1, 32, 32, 32])
print(f"输出形状: {output.shape}") # torch.Size([1, 64, 32, 32])(通道数翻倍,尺寸不变)
4. Focus(维度变换模块)
作用:通过切片聚合提升通道数,压缩空间尺寸
import torch
from models.common import Focus# 1. 初始化模块:输入3通道,输出12通道(3x4),卷积核3x3
focus = Focus(c1=3, c2=12, k=3)# 2. 准备输入:模拟1张3通道、64x64的图像
x = torch.randn(1, 3, 64, 64)# 3. 前向传播
output = focus(x)# 4. 输出结果
print(f"输入形状: {x.shape}") # torch.Size([1, 3, 64, 64])
print(f"输出形状: {output.shape}") # torch.Size([1, 12, 32, 32])(通道×4,尺寸÷2)
5. GhostConv(轻量化卷积)
作用:通过“主卷积+廉价操作”减少参数,实现轻量化特征提取
import torch
from models.common import GhostConv# 1. 初始化模块:输入3通道,输出16通道,卷积核3x3
ghost_conv = GhostConv(c1=3, c2=16, k=3)# 2. 准备输入:模拟1张3通道、32x32的图像
x = torch.randn(1, 3, 32, 32)# 3. 前向传播
output = ghost_conv(x)# 4. 输出结果
print(f"输入形状: {x.shape}") # torch.Size([1, 3, 32, 32])
print(f"输出形状: {output.shape}") # torch.Size([1, 16, 32, 32])(通道数达标,参数比标准Conv少)
6. Concat(特征拼接模块)
作用:在指定维度拼接多个特征图(通常用于跨尺度特征融合)
import torch
from models.common import Concat# 1. 初始化模块:在通道维度(dim=1)拼接
concat = Concat(dimension=1)# 2. 准备输入:2个同尺寸、不同通道的特征图
x1 = torch.randn(1, 16, 32, 32) # 16通道
x2 = torch.randn(1, 16, 32, 32) # 16通道# 3. 前向传播(输入需为列表)
output = concat([x1, x2])# 4. 输出结果
print(f"输入1形状: {x1.shape}, 输入2形状: {x2.shape}")
print(f"输出形状: {output.shape}") # torch.Size([1, 32, 32, 32])(通道数16+16=32)
7. AutoShape(输入自适应处理)
作用:自动兼容多格式输入(图像/视频),完成预处理+推理+后处理
import torch
from models.common import AutoShape
from PIL import Image
import numpy as np# 1. 加载模型并包装AutoShape(需替换为实际模型路径)
model = AutoShape(weights="yolov5s.pt") # 自动处理输入+推理+后处理# 2. 准备输入(支持PIL图像/np数组/torch张量,单图或批量)
img_pil = Image.open("test.jpg") # PIL图像
img_np = np.array(img_pil) # numpy数组(HWC)
img_torch = torch.from_numpy(img_np).permute(2,0,1)/255 # torch张量(CHW,归一化)# 3. 推理(自动统一格式+预处理+NMS)
results = model([img_pil, img_np, img_torch]) # 批量输入# 4. 输出结果(Detections对象,支持多种格式)
results.print() # 打印检测结果(类别、置信度、坐标)
results.save() # 保存带检测框的图像
print("检测框(xyxy格式):\n", results.xyxy) # 像素坐标
8. DetectMultiBackend(多后端推理适配)
作用:兼容PyTorch/ONNX/TensorRT等后端,统一推理接口
import torch
from models.common import DetectMultiBackend# 1. 初始化多后端模型(支持.pt/.onnx/.engine等,需替换为实际模型路径)
model = DetectMultiBackend(weights="yolov5s.onnx", # 示例:ONNX模型device=torch.device("cuda" if torch.cuda.is_available() else "cpu")
)# 2. 准备输入(需符合模型输入尺寸,如640x640)
x = torch.randn(1, 3, 640, 640).to(model.device) # 模拟输入# 3. 推理(自动适配后端,输出原始检测张量)
output = model(x)# 4. 输出结果(原始特征图或检测框,需后续NMS处理)
print(f"推理输出形状: {output.shape}") # 如 yolov5s 输出为 (1, 25200, 85)
示例说明
- 所有示例基于
torch 1.10+,需提前安装torch和 YOLOv5 依赖(pip install -r requirements.txt); - 涉及模型路径的示例(如
AutoShape/DetectMultiBackend),需替换为本地实际模型文件(可通过python train.py生成或官网下载); - 输入数据均用随机张量或示例图像,实际使用时替换为业务数据即可;
- 输出形状反映模块核心功能(如通道变换、尺寸压缩、特征拼接),便于快速验证模块正确性。
