YOLO模型核心组件详解
1.autopad函数
def autopad(k, p=None): # kernel, padding if p is None: p = k // 2 if isinstance(k, int) else [x // 2 for x in k] # auto-pad return p功能:自动计算padding值,确保卷积后尺寸不变(SAME卷积)
原理:当p为None时,自动计算为kernel size的一半
2.Conv类(标准卷积模块)
class Conv(nn.Module): def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True): super().__init__() self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False) self.bn = nn.BatchNorm2d(c2) self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity()) def forward(self, x): return self.act(self.bn(self.conv(x)))参数说明:
c1: 输入通道数
c2: 输出通道数
k: 卷积核大小
s: 步长
g: 分组卷积数
act: 是否使用激活函数
结构:Conv → BatchNorm → SiLU激活函数
特点:使用SiLU激活函数(Sigmoid-weighted Linear Unit),比ReLU更平滑
3.Bottleneck类(瓶颈块)
class Bottleneck(nn.Module): def __init__(self, c1, c2, shortcut=True, g=1, e=0.5): super().__init__() c_ = int(c2 * e) # hidden channels self.cv1 = Conv(c1, c_, 1, 1) # 1×1卷积降维 self.cv2 = Conv(c_, c2, 3, 1, g=g) # 3×3卷积 self.add = shortcut and c1 == c2 # 残差连接开关 def forward(self, x): return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))功能:实现残差连接的瓶颈结构
结构:
1×1卷积:降低通道数(c2×e)
3×3卷积:特征提取
残差连接:当输入输出通道相同时添加跳跃连接
优势:减少参数量,缓解梯度消失
4.C3类(CSP Bottleneck with 3 convolutions)
class C3(nn.Module): def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): super().__init__() c_ = int(c2 * e) # hidden channels self.cv1 = Conv(c1, c_, 1, 1) # 第一个1×1卷积 self.cv2 = Conv(c1, c_, 1, 1) # 第二个1×1卷积 self.cv3 = Conv(2 * c_, c2, 1) # 最终融合卷积 self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n))) def forward(self, x): return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), dim=1))CSP(Cross Stage Partial)结构:
将输入分为两路:一路经过多个Bottleneck,一路直接传递
两路concatenate后用1×1卷积融合
优势:平衡计算效率和准确性,减少内存占用