河北 保定 网站建设,网站改版 重新收录,网站短信验证怎么做的,2二级域名免费该文件位于/models/common.py#xff0c;提供了构建YOLOv5模型的各种基础模块#xff0c;其中包含了常用的功能模块#xff0c;如自动填充autopad函数、标准卷积层Conv、瓶颈层Bottleneck、C3、SPPF、Concat层等
参考笔记#xff1a;【YOLOv3】 源码#xff08;common.py…该文件位于/models/common.py提供了构建YOLOv5模型的各种基础模块其中包含了常用的功能模块如自动填充autopad函数、标准卷积层Conv、瓶颈层Bottleneck、C3、SPPF、Concat层等
参考笔记【YOLOv3】 源码common.py-CSDN博客 YOLOv5网络结构图 YOLOv5网络参数图 目录
1.自动填充autopad函数
2.标准卷积层Conv类
3.瓶颈层Bottleneck类
4.C3
5.SPPF
6.Concat层 1.自动填充autopad函数
该函数根据kernel_size自动计算需要填充的padding使得输入和输出尺寸一致需要注意的是使用这个自动填充函数时stride必须为1 为卷积层自动计算填充Padding保证输入和输出尺寸不变
kkernel_size
ppaddingdef autopad(k, pNone):#如果未提供p则进行自动填充if p is None:#如果k是整数计算填充为k // 2如果k是列表或其他可迭代对象计算每个元素的填充为x // 2p k // 2 if isinstance(k, int) else [x // 2 for x in k]#自动填充return p#返回计算的填充值
2.标准卷积层Conv类 YOLOv5中主要有两种卷积分别是下采样卷积、保持特征图尺寸不变的卷积
下采样卷积
YOLOv5的下采样卷积常用的是kernel_size3stride2padding1经过该下采样卷积层输出尺寸减半通道数翻倍 YOLOv5中还有一种下采样卷积是kernel_size6stride2padding2同样经过该下采样卷积层输出尺寸减半通道数翻倍但是该下采样卷积在YOLOv5中只使用了1次 保持特征图尺寸不变的卷积
YOLOv5该类卷积使用的是kernel_size1stride1padding0经过该卷积层输出尺寸不变 下图是两种卷积在Backbone中的使用 YOLOv5结构图中的CBS、ConvBNSiLU即由Conv类实现 Conv即为YOLOv5中的CBS、ConvBNSiLU模块实现
class Conv(nn.Module):#标准卷积模块def __init__(self, c1, c2, k1, s1, pNone, g1, actTrue)::params c1: in_channle:params c2: out_channel:params k: kernel_size:params s: stride:params p: padding:params g: 卷积的groups数 1就是普通的卷积 1就是深度可分离卷积,也就是分组卷积:params act: 激活函数类型 True就是SiLU() False就是不使用激活函数类型是nn.Module就使用传进来的激活函数类型super().__init__()#定义卷积层自动计算填充禁用偏置以配合批归一化层self.conv nn.Conv2d(c1, c2, k, s, autopad(k, p), groupsg, biasFalse)#定义批归一化层归一化输出self.bn nn.BatchNorm2d(c2)#定义激活函数默认为SiLUself.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)))#推理时的前向传播def forward_fuse(self, x):#直接通过卷积和激活函数省略批归一化以提高推理速度return self.act(self.conv(x))
3.瓶颈层Bottleneck类 YOLOv5网络结构中ResUnit-T、ResUnit-F即由Bottleneck实现T、F可以理解为是否开启残差连接 YOLOv5中的ResUnit-T、ResUnit-F
该类包括两个卷积层(CBS模块)和一个可选的shortcut(残差)连接如果shortcut为True且in_channelout_channel则在输出中添加原始输入实现残差连接。这样可以帮助模型在深层网络中缓解梯度消失问题提高训练稳定性和模型性能
即YOLOv5中的ResUnit组件该函数将ResUnit-T和ResUnit-F集成到一起
class Bottleneck(nn.Module):# 标准瓶颈层常用于减少参数并提高模型的计算效率def __init__(self, c1, c2, shortcutTrue, g1, e0.5):super().__init__():params c1: in_channle:params c2: out_channel:params shortcut: 是否开启残差连接如果启用则原始输入x会与经过两个卷积层之后的输出相加:params g: 卷积的groups数 1就是普通的卷积 1就是深度可分离卷积,也就是分组卷积:params e: 通道扩展比例决定第一个卷积的输出通道数。扩展比例为e则第一个卷积的输出通道数为 e * c2#根据扩展比例计算第一个卷积的输出通道数c_ int(c2 * e)# 第一个卷积层1x1卷积将输入通道数 c1 缩减到 c_减少计算量self.cv1 Conv(c1, c_, 1, 1)# 第二个卷积层3x3卷积将通道数从 c_ 恢复到 c2用于特征提取self.cv2 Conv(c_, c2, 3, 1, gg)#如果启用shortcut连接且输入和输出通道数相同c1 c2则创建shortcut连接#shortcut连接有助于缓解深层网络中的梯度消失问题self.add shortcut and c1 c2 #如果启用shortcut且输入输出通道数相同shortcut为True#前向传播def forward(self, x):#如果add为True则返回残差连接结果if self.add:return x self.cv2(self.cv1(x))#如果add为False,仅返回卷积后的输出return self.cv2(self.cv1(x))Bottleneck不是简单的类似于ResNet中的跳跃连接机制而是其增强版本其中涉及了压缩和拓展提高相应效率
跳跃连接类似于一个项目管理团队需要完成一个复杂的任务团队中有人已经有了基本的解决方案输入信息。跳跃连接就像保留了这个基本解决方案同时允许团队成员对其进行优化。如果最终的优化方案有问题原始的解决方案仍然可以用作备选
Bottleneck 进一步优化了这个过程。团队会先对已有的解决方案进行压缩处理1x1 卷积提取最重要的部分删除冗余。然后团队成员进行深入的讨论3x3 卷积生成更详细的解决方案。最终这个优化过的方案会与原始方案一起汇总形成最终输出
这种流程既节省了资源减少计算量又提高了效率保留原始信息提取更深层特征
4.C3
YOLOv5中有两种C3模块分别是C3_1_XC3_2_X其中X指的是该C3模块中有多少个ResUnit组件 C3_1_X、C3_2_X结构
C3模块该函数将C3_1_X和C3_2_X集成到一起
class C3(nn.Module):# CSPCross Stage Partial瓶颈结构带有3个卷积层def __init__(self, c1, c2, n1, shortcutTrue, g1, e0.5):super().__init__():param c1in_channel:param c2out_channel:param nn个Bottleneck模块(ResUnit组件):param shortcutBottleneck是否开启残差连接:param g:param e通道扩展比例# 根据扩展比例计算两个分支上第一个卷积层的输出通道数c_ int(c2 * e)#第一分支的1x1卷积层用于降维self.cv1 Conv(c1, c_, 1, 1)#第二分支的1x1卷积层用于降维self.cv2 Conv(c1, c_, 1, 1)#创建n个Bottleneck层(ResUnit组件)使用nn.Sequential进行顺序连接self.m nn.Sequential(*[Bottleneck(c_, c_, shortcut, g, e1.0) for _ in range(n)])#concat之后的1x1卷积层输出通道数为c2self.cv3 Conv(2 * c_, c2, 1)#前向传播过程def forward(self, x):branch_1self.m(self.cv1(x))#第一个分支的前向传播branch_2self.cv2(x)#第二个分支的前向传播return self.cv3(torch.cat((branch_1,branch_2),dim1))#两个分支拼接之后再做最后一次卷积
5.SPPF SPPF模块
class SPPF(nn.Module):def __init__(self, c1, c2, k5): # equivalent to SPP(k(5, 9, 13))super().__init__():param c1in_channel:param c2out_channel:param k最大池化层的卷积核大小默认为5#第一个卷积层的输出通道数为c1//2c_ c1 // 2#第一个卷积层self.cv1 Conv(c1, c_, 1, 1)#第二个卷积层将拼接后的通道数转换为输出通道数c2self.cv2 Conv(c_ * 4, c2, 1, 1)#最大池化层kernel_sizekstride1paddingk//2self.m nn.MaxPool2d(kernel_sizek, stride1, paddingk // 2)#前向传播def forward(self, x):x self.cv1(x)#通过第一层卷积处理输入特征图y1 self.m(x)#第一次最大池化y2 self.m(y1)#第二次最大池化y3 self.m(y2)#第三次最大池化#将原始特征图和3次池化的结果进行拼接然后通过第二层卷积进行处理return self.cv2(torch.cat([x, y1, y2,y3], 1))6.Concat层
这个类的作用是将不同层的特征图进行合并增强特征表示从而进一步提高模型的预测能力 如YOLOv5网络结构图中黄色部分Concat操作主要发生在Neck阶段配合完成YOLOv5颈部的FPNPAN流程
class Concat(nn.Module):#该类实现了沿指定维度连接多个张量的功能def __init__(self, dimension1):super().__init__():param dimension指定特征拼接的维度默认为1即在第一个维度通常是通道维度上进行特征拼接。self.d dimension #保存要连接的维度默认为1#前向传播方法执行张量连接操作def forward(self, x)::param x: x是一个张量列表存放来自不同层的特征图张量除拼接维度外特征图的其他维度需要相同return torch.cat(x, self.d)#使用torch.cat沿self.d维度连接输入的张量列表x