【YOLOv5/v7改进系列】引入YOLOv9的RepNCSPELAN4

一、导言

YOLOv9的几个主要创新点:

  1. Programmable Gradient Information (PGI):

    • PGI是一种机制,用于应对深度网络中实现多目标所需要的多种变化。
    • PGI提供完整的输入信息来计算目标函数,从而获得可靠的梯度信息以更新网络权重。
    • PGI可以自由选择适合目标任务的损失函数,克服了掩模建模遇到的问题。
    • PGI机制适用于不同大小的深度神经网络,并且比仅适用于非常深的神经网络的深度监督机制更为通用。
  2. Generalized Efficient Layer Aggregation Network (GELAN):

    • GELAN是一种基于传统卷积运算符设计的轻量级网络架构,相较于基于深度可分离卷积的设计,GELAN实现了更好的参数利用率。
    • GELAN的设计同时考虑了参数数量、计算复杂度、准确率和推理速度。
    • GELAN允许用户根据不同的推理设备选择合适的计算模块。
  3. 理论分析:

    • 作者们从可逆函数的角度对现有的深度神经网络架构进行了理论分析,通过这个过程成功解释了许多过去难以解释的现象。
    • 基于这种分析,设计了PGI和辅助可逆分支。
  4. 适用性:

    • PGI解决了深度监督只能应用于极深神经网络架构的问题,从而使新的轻量级架构能够在日常生活中真正应用。
    • PGI能有效处理信息瓶颈和信息断裂等问题,并全面提高不同规模模型的准确性。
    • 结合PGI和GELAN,YOLOv9在MS COCO数据集上的目标检测性能超越了现有实时目标检测器的所有方面。
  5. 实证研究:

    • 通过消融实验验证了PGI对于主干网络和颈部网络的影响。
    • 实验结果显示,在不同大小的模型上,PGI都能有效地提升模型性能。

综上所述,YOLOv9通过引入PGI和GELAN这两项创新,在轻量化、效率和准确性方面取得了显著的进步,特别是在信息传递和梯度计算方面有着独特的优势。

二、准备工作

首先在YOLOv5/v7的models文件夹下新建文件repncspelan4.py,导入如下代码

from models.common import *# https://arxiv.org/pdf/2402.13616
class RepConvN(nn.Module):"""RepConv is a basic rep-style block, including training and deploy statusThis code is based on https://github.com/DingXiaoH/RepVGG/blob/main/repvgg.py"""default_act = nn.LeakyReLU()  # default activationdef __init__(self, c1, c2, k=3, s=1, p=1, g=1, d=1, act=True, bn=False, deploy=False):super().__init__()assert k == 3 and p == 1self.g = gself.c1 = c1self.c2 = c2self.act = self.default_act if act is True else act if isinstance(act, nn.Module) else nn.Identity()self.bn = Noneself.conv1 = Conv(c1, c2, k, s, p=p, g=g, act=False)self.conv2 = Conv(c1, c2, 1, s, p=(p - k // 2), g=g, act=False)def forward_fuse(self, x):"""Forward process"""return self.act(self.conv(x))def forward(self, x):"""Forward process"""id_out = 0 if self.bn is None else self.bn(x)return self.act(self.conv1(x) + self.conv2(x) + id_out)def get_equivalent_kernel_bias(self):kernel3x3, bias3x3 = self._fuse_bn_tensor(self.conv1)kernel1x1, bias1x1 = self._fuse_bn_tensor(self.conv2)kernelid, biasid = self._fuse_bn_tensor(self.bn)return kernel3x3 + self._pad_1x1_to_3x3_tensor(kernel1x1) + kernelid, bias3x3 + bias1x1 + biasiddef _avg_to_3x3_tensor(self, avgp):channels = self.c1groups = self.gkernel_size = avgp.kernel_sizeinput_dim = channels // groupsk = torch.zeros((channels, input_dim, kernel_size, kernel_size))k[np.arange(channels), np.tile(np.arange(input_dim), groups), :, :] = 1.0 / kernel_size ** 2return kdef _pad_1x1_to_3x3_tensor(self, kernel1x1):if kernel1x1 is None:return 0else:return torch.nn.functional.pad(kernel1x1, [1, 1, 1, 1])def _fuse_bn_tensor(self, branch):if branch is None:return 0, 0if isinstance(branch, Conv):kernel = branch.conv.weightrunning_mean = branch.bn.running_meanrunning_var = branch.bn.running_vargamma = branch.bn.weightbeta = branch.bn.biaseps = branch.bn.epselif isinstance(branch, nn.BatchNorm2d):if not hasattr(self, 'id_tensor'):input_dim = self.c1 // self.gkernel_value = np.zeros((self.c1, input_dim, 3, 3), dtype=np.float32)for i in range(self.c1):kernel_value[i, i % input_dim, 1, 1] = 1self.id_tensor = torch.from_numpy(kernel_value).to(branch.weight.device)kernel = self.id_tensorrunning_mean = branch.running_meanrunning_var = branch.running_vargamma = branch.weightbeta = branch.biaseps = branch.epsstd = (running_var + eps).sqrt()t = (gamma / std).reshape(-1, 1, 1, 1)return kernel * t, beta - running_mean * gamma / stddef fuse_convs(self):if hasattr(self, 'conv'):returnkernel, bias = self.get_equivalent_kernel_bias()self.conv = nn.Conv2d(in_channels=self.conv1.conv.in_channels,out_channels=self.conv1.conv.out_channels,kernel_size=self.conv1.conv.kernel_size,stride=self.conv1.conv.stride,padding=self.conv1.conv.padding,dilation=self.conv1.conv.dilation,groups=self.conv1.conv.groups,bias=True).requires_grad_(False)self.conv.weight.data = kernelself.conv.bias.data = biasfor para in self.parameters():para.detach_()self.__delattr__('conv1')self.__delattr__('conv2')if hasattr(self, 'nm'):self.__delattr__('nm')if hasattr(self, 'bn'):self.__delattr__('bn')if hasattr(self, 'id_tensor'):self.__delattr__('id_tensor')class RepNBottleneck(nn.Module):# Standard bottleneckdef __init__(self, c1, c2, shortcut=True, g=1, k=(3, 3), e=0.5):  # ch_in, ch_out, shortcut, kernels, groups, expandsuper().__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = RepConvN(c1, c_, k[0], 1)self.cv2 = Conv(c_, c2, k[1], 1, g=g)self.add = shortcut and c1 == c2def forward(self, x):return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))class RepNCSP(nn.Module):# CSP Bottleneck with 3 convolutionsdef __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansionsuper().__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = Conv(c1, c_, 1, 1)self.cv2 = Conv(c1, c_, 1, 1)self.cv3 = Conv(2 * c_, c2, 1)  # optional act=FReLU(c2)self.m = nn.Sequential(*(RepNBottleneck(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)), 1))class RepNCSPELAN4(nn.Module):# csp-elandef __init__(self, c1, c2, c3, c4, c5=1):  # ch_in, ch_out, number, shortcut, groups, expansionsuper().__init__()self.c = c3 // 2self.cv1 = Conv(c1, c3, 1, 1)self.cv2 = nn.Sequential(RepNCSP(c3 // 2, c4, c5), Conv(c4, c4, 3, 1))self.cv3 = nn.Sequential(RepNCSP(c4, c4, c5), Conv(c4, c4, 3, 1))self.cv4 = Conv(c3 + (2 * c4), c2, 1, 1)def forward(self, x):y = list(self.cv1(x).chunk(2, 1))y.extend((m(y[-1])) for m in [self.cv2, self.cv3])return self.cv4(torch.cat(y, 1))def forward_split(self, x):y = list(self.cv1(x).split((self.c, self.c), 1))y.extend(m(y[-1]) for m in [self.cv2, self.cv3])return self.cv4(torch.cat(y, 1))

其次在在YOLOv5/v7项目文件下的models/yolo.py中在文件首部添加代码

from models.repncspelan4 import RepNCSPELAN4

并搜索def parse_model(d, ch)

定位到如下行添加以下代码

RepNCSPELAN4,

三、YOLOv7-tiny改进工作

完成二后,在YOLOv7项目文件下的models文件夹下创建新的文件yolov7-tiny-repncspelan4.yaml,导入如下代码。

# parameters
nc: 80  # number of classes
depth_multiple: 1.0  # model depth multiple
width_multiple: 1.0  # layer channel multiple# anchors
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# yolov7-tiny backbone
backbone:# [from, number, module, args] c2, k=1, s=1, p=None, g=1, act=True[[-1, 1, Conv, [32, 3, 2, None, 1, nn.LeakyReLU(0.1)]],  # 0-P1/2[-1, 1, Conv, [64, 3, 2, None, 1, nn.LeakyReLU(0.1)]],  # 1-P2/4[-1, 1, Conv, [32, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-2, 1, Conv, [32, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, Conv, [32, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, Conv, [32, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[[-1, -2, -3, -4], 1, Concat, [1]],[-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]],  # 7[-1, 1, MP, []],  # 8-P3/8[-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-2, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[[-1, -2, -3, -4], 1, Concat, [1]],[-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]],  # 14[-1, 1, MP, []],  # 15-P4/16[-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-2, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, Conv, [128, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, Conv, [128, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[[-1, -2, -3, -4], 1, Concat, [1]],[-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]],  # 21[-1, 1, MP, []],  # 22-P5/32[-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-2, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, Conv, [256, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, Conv, [256, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[[-1, -2, -3, -4], 1, Concat, [1]],[-1, 1, Conv, [512, 1, 1, None, 1, nn.LeakyReLU(0.1)]],  # 28]# yolov7-tiny head
head:[[-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-2, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, SP, [5]],[-2, 1, SP, [9]],[-3, 1, SP, [13]],[[-1, -2, -3, -4], 1, Concat, [1]],[-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[[-1, -7], 1, Concat, [1]],[-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]],  # 37[-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[21, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # route backbone P4[[-1, -2], 1, Concat, [1]],[-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-2, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[[-1, -2, -3, -4], 1, Concat, [1]],[-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]],  # 47[-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[14, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # route backbone P3[[-1, -2], 1, Concat, [1]],[-1, 1, Conv, [32, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-2, 1, Conv, [32, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, Conv, [32, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, Conv, [32, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[[-1, -2, -3, -4], 1, Concat, [1]],[-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]],  # 57[-1, 1, Conv, [128, 3, 2, None, 1, nn.LeakyReLU(0.1)]],[[-1, 47], 1, Concat, [1]],[-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-2, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[[-1, -2, -3, -4], 1, Concat, [1]],[-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]],  # 65[-1, 1, Conv, [256, 3, 2, None, 1, nn.LeakyReLU(0.1)]],[[-1, 37], 1, Concat, [1]], # 67[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]],# 68[57, 1, Conv, [128, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[65, 1, Conv, [256, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[68, 1, Conv, [512, 3, 1, None, 1, nn.LeakyReLU(0.1)]],[[69,70,71], 1, IDetect, [nc, anchors]],   # Detect(P3, P4, P5)]
from  n    params  module                                  arguments                     0                -1  1       928  models.common.Conv                      [3, 32, 3, 2, None, 1, LeakyReLU(negative_slope=0.1)]1                -1  1     18560  models.common.Conv                      [32, 64, 3, 2, None, 1, LeakyReLU(negative_slope=0.1)]2                -1  1      2112  models.common.Conv                      [64, 32, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]3                -2  1      2112  models.common.Conv                      [64, 32, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]4                -1  1      9280  models.common.Conv                      [32, 32, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]5                -1  1      9280  models.common.Conv                      [32, 32, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]6  [-1, -2, -3, -4]  1         0  models.common.Concat                    [1]                           7                -1  1      8320  models.common.Conv                      [128, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]8                -1  1         0  models.common.MP                        []                            9                -1  1      4224  models.common.Conv                      [64, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]10                -2  1      4224  models.common.Conv                      [64, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]11                -1  1     36992  models.common.Conv                      [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]12                -1  1     36992  models.common.Conv                      [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]13  [-1, -2, -3, -4]  1         0  models.common.Concat                    [1]                           14                -1  1     33024  models.common.Conv                      [256, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]15                -1  1         0  models.common.MP                        []                            16                -1  1     16640  models.common.Conv                      [128, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]17                -2  1     16640  models.common.Conv                      [128, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]18                -1  1    147712  models.common.Conv                      [128, 128, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]19                -1  1    147712  models.common.Conv                      [128, 128, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]20  [-1, -2, -3, -4]  1         0  models.common.Concat                    [1]                           21                -1  1    131584  models.common.Conv                      [512, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]22                -1  1         0  models.common.MP                        []                            23                -1  1     66048  models.common.Conv                      [256, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]24                -2  1     66048  models.common.Conv                      [256, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]25                -1  1    590336  models.common.Conv                      [256, 256, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]26                -1  1    590336  models.common.Conv                      [256, 256, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]27  [-1, -2, -3, -4]  1         0  models.common.Concat                    [1]                           28                -1  1    525312  models.common.Conv                      [1024, 512, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]29                -1  1    131584  models.common.Conv                      [512, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]30                -2  1    131584  models.common.Conv                      [512, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]31                -1  1         0  models.common.SP                        [5]                           32                -2  1         0  models.common.SP                        [9]                           33                -3  1         0  models.common.SP                        [13]                          34  [-1, -2, -3, -4]  1         0  models.common.Concat                    [1]                           35                -1  1    262656  models.common.Conv                      [1024, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]36          [-1, -7]  1         0  models.common.Concat                    [1]                           37                -1  1    131584  models.common.Conv                      [512, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]38                -1  1     33024  models.common.Conv                      [256, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]39                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          40                21  1     33024  models.common.Conv                      [256, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]41          [-1, -2]  1         0  models.common.Concat                    [1]                           42                -1  1     16512  models.common.Conv                      [256, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]43                -2  1     16512  models.common.Conv                      [256, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]44                -1  1     36992  models.common.Conv                      [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]45                -1  1     36992  models.common.Conv                      [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]46  [-1, -2, -3, -4]  1         0  models.common.Concat                    [1]                           47                -1  1     33024  models.common.Conv                      [256, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]48                -1  1      8320  models.common.Conv                      [128, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]49                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          50                14  1      8320  models.common.Conv                      [128, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]51          [-1, -2]  1         0  models.common.Concat                    [1]                           52                -1  1      4160  models.common.Conv                      [128, 32, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]53                -2  1      4160  models.common.Conv                      [128, 32, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]54                -1  1      9280  models.common.Conv                      [32, 32, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]55                -1  1      9280  models.common.Conv                      [32, 32, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]56  [-1, -2, -3, -4]  1         0  models.common.Concat                    [1]                           57                -1  1      8320  models.common.Conv                      [128, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]58                -1  1     73984  models.common.Conv                      [64, 128, 3, 2, None, 1, LeakyReLU(negative_slope=0.1)]59          [-1, 47]  1         0  models.common.Concat                    [1]                           60                -1  1     16512  models.common.Conv                      [256, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]61                -2  1     16512  models.common.Conv                      [256, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]62                -1  1     36992  models.common.Conv                      [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]63                -1  1     36992  models.common.Conv                      [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]64  [-1, -2, -3, -4]  1         0  models.common.Concat                    [1]                           65                -1  1     33024  models.common.Conv                      [256, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]66                -1  1    295424  models.common.Conv                      [128, 256, 3, 2, None, 1, LeakyReLU(negative_slope=0.1)]67          [-1, 37]  1         0  models.common.Concat                    [1]                           68                -1  1    262016  models.repncspelan4.RepNCSPELAN4        [512, 256, 128, 64, 1]        69                57  1     73984  models.common.Conv                      [64, 128, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]70                65  1    295424  models.common.Conv                      [128, 256, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]71                68  1   1180672  models.common.Conv                      [256, 512, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]72      [69, 70, 71]  1     17132  models.yolo.IDetect                     [1, [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]], [128, 256, 512]]Model Summary: 318 layers, 5718412 parameters, 5718412 gradients, 12.9 GFLOPS

运行后若打印出如上文本代表改进成功。

四、YOLOv5s改进工作

完成二后,在YOLOv5项目文件下的models文件夹下创建新的文件yolov5s-repncspelan4.yaml,导入如下代码。

# Parameters
nc: 1  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.25  # layer channel multiple
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# YOLOv5 v6.0 backbone
backbone:# [from, number, module, args][[-1, 1, Conv, [64, 6, 2, 2]],  # 0-P1/2[-1, 1, Conv, [128, 3, 2]],  # 1-P2/4[-1, 3, C3, [128]],[-1, 1, Conv, [256, 3, 2]],  # 3-P3/8[-1, 6, C3, [256]],[-1, 1, Conv, [512, 3, 2]],  # 5-P4/16[-1, 9, C3, [512]],[-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32[-1, 3, C3, [1024]],[-1, 1, SPPF, [1024, 5]],  # 9]# YOLOv5 v6.0 head
head:[[-1, 1, Conv, [512, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 6], 1, Concat, [1]],  # cat backbone P4[-1, 3, C3, [512, False]],  # 13[-1, 1, Conv, [256, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 4], 1, Concat, [1]],  # cat backbone P3[-1, 3, C3, [256, False]],  # 17 (P3/8-small)[-1, 1, Conv, [256, 3, 2]],[[-1, 14], 1, Concat, [1]],  # cat head P4[-1, 3, C3, [512, False]],  # 20 (P4/16-medium)[-1, 1, Conv, [512, 3, 2]],[[-1, 10], 1, Concat, [1]],  # cat head P5[-1, 1, RepNCSPELAN4, [1024, 512, 256, 1]],  # 23 (P5/32-large)[[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)]
from  n    params  module                                  arguments                     0                -1  1      3520  models.common.Conv                      [3, 32, 6, 2, 2]              1                -1  1     18560  models.common.Conv                      [32, 64, 3, 2]                2                -1  1     18816  models.common.C3                        [64, 64, 1]                   3                -1  1     73984  models.common.Conv                      [64, 128, 3, 2]               4                -1  2    115712  models.common.C3                        [128, 128, 2]                 5                -1  1    295424  models.common.Conv                      [128, 256, 3, 2]              6                -1  3    625152  models.common.C3                        [256, 256, 3]                 7                -1  1   1180672  models.common.Conv                      [256, 512, 3, 2]              8                -1  1   1182720  models.common.C3                        [512, 512, 1]                 9                -1  1    656896  models.common.SPPF                      [512, 512, 5]                 10                -1  1    131584  models.common.Conv                      [512, 256, 1, 1]              11                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          12           [-1, 6]  1         0  models.common.Concat                    [1]                           13                -1  1    361984  models.common.C3                        [512, 256, 1, False]          14                -1  1     33024  models.common.Conv                      [256, 128, 1, 1]              15                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          16           [-1, 4]  1         0  models.common.Concat                    [1]                           17                -1  1     90880  models.common.C3                        [256, 128, 1, False]          18                -1  1    147712  models.common.Conv                      [128, 128, 3, 2]              19          [-1, 14]  1         0  models.common.Concat                    [1]                           20                -1  1    296448  models.common.C3                        [256, 256, 1, False]          21                -1  1    590336  models.common.Conv                      [256, 256, 3, 2]              22          [-1, 10]  1         0  models.common.Concat                    [1]                           23                -1  1   2857472  models.repncspelan4.RepNCSPELAN4        [512, 512, 512, 256, 1]       24      [17, 20, 23]  1     16182  models.yolo.Detect                      [1, [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]], [128, 256, 512]]Model Summary: 323 layers, 8697078 parameters, 8697078 gradients, 17.3 GFLOPs

运行后若打印出如上文本代表改进成功。

五、YOLOv5n改进工作

完成二后,在YOLOv5项目文件下的models文件夹下创建新的文件yolov5n-repncspelan4.yaml,导入如下代码。

# Parameters
nc: 1  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.25  # layer channel multiple
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# YOLOv5 v6.0 backbone
backbone:# [from, number, module, args][[-1, 1, Conv, [64, 6, 2, 2]],  # 0-P1/2[-1, 1, Conv, [128, 3, 2]],  # 1-P2/4[-1, 3, C3, [128]],[-1, 1, Conv, [256, 3, 2]],  # 3-P3/8[-1, 6, C3, [256]],[-1, 1, Conv, [512, 3, 2]],  # 5-P4/16[-1, 9, C3, [512]],[-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32[-1, 3, C3, [1024]],[-1, 1, SPPF, [1024, 5]],  # 9]# YOLOv5 v6.0 head
head:[[-1, 1, Conv, [512, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 6], 1, Concat, [1]],  # cat backbone P4[-1, 3, C3, [512, False]],  # 13[-1, 1, Conv, [256, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 4], 1, Concat, [1]],  # cat backbone P3[-1, 3, C3, [256, False]],  # 17 (P3/8-small)[-1, 1, Conv, [256, 3, 2]],[[-1, 14], 1, Concat, [1]],  # cat head P4[-1, 3, C3, [512, False]],  # 20 (P4/16-medium)[-1, 1, Conv, [512, 3, 2]],[[-1, 10], 1, Concat, [1]],  # cat head P5[-1, 1, RepNCSPELAN4, [1024, 512, 256, 1]],  # 23 (P5/32-large)[[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)]
from  n    params  module                                  arguments                     0                -1  1      1760  models.common.Conv                      [3, 16, 6, 2, 2]              1                -1  1      4672  models.common.Conv                      [16, 32, 3, 2]                2                -1  1      4800  models.common.C3                        [32, 32, 1]                   3                -1  1     18560  models.common.Conv                      [32, 64, 3, 2]                4                -1  2     29184  models.common.C3                        [64, 64, 2]                   5                -1  1     73984  models.common.Conv                      [64, 128, 3, 2]               6                -1  3    156928  models.common.C3                        [128, 128, 3]                 7                -1  1    295424  models.common.Conv                      [128, 256, 3, 2]              8                -1  1    296448  models.common.C3                        [256, 256, 1]                 9                -1  1    164608  models.common.SPPF                      [256, 256, 5]                 10                -1  1     33024  models.common.Conv                      [256, 128, 1, 1]              11                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          12           [-1, 6]  1         0  models.common.Concat                    [1]                           13                -1  1     90880  models.common.C3                        [256, 128, 1, False]          14                -1  1      8320  models.common.Conv                      [128, 64, 1, 1]               15                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          16           [-1, 4]  1         0  models.common.Concat                    [1]                           17                -1  1     22912  models.common.C3                        [128, 64, 1, False]           18                -1  1     36992  models.common.Conv                      [64, 64, 3, 2]                19          [-1, 14]  1         0  models.common.Concat                    [1]                           20                -1  1     74496  models.common.C3                        [128, 128, 1, False]          21                -1  1    147712  models.common.Conv                      [128, 128, 3, 2]              22          [-1, 10]  1         0  models.common.Concat                    [1]                           23                -1  1   2463744  models.repncspelan4.RepNCSPELAN4        [256, 256, 512, 256, 1]       24      [17, 20, 23]  1      8118  models.yolo.Detect                      [1, [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]], [64, 128, 256]]Model Summary: 323 layers, 3932566 parameters, 3932566 gradients, 6.0 GFLOPs
六、RepNCSPELAN4的优点

RepNCSPELAN4 是一个复合模块,结合了CSP (Cross Stage Partial Networks) 和 ELAN (Efficient Layer Aggregation Network) 的设计理念,旨在构建一个高效且参数利用率高的网络结构。下面是 RepNCSPELAN4 模块的一些关键优点:

1. 参数利用率高
  • RepNCSPELAN4 使用了两个 RepNCSP 模块,它们通过将输入通道分割成两部分并分别处理,然后将结果合并,这种方式能够更高效地利用通道信息。
  • RepNCSP 内部使用了 RepNBottleneck,这是一种基于可重复卷积的瓶颈结构,它可以在训练时学习到更复杂的特征表示,而在部署时简化为单一的卷积层,减少了计算量。
2. 计算效率
  • 通过使用 RepConvN 和 RepNBottleneck,模块能够在不牺牲精度的情况下减少前向传播的时间成本。
  • RepConvN 可以在训练阶段使用多个卷积核,而在部署阶段转换为一个等效的单个卷积核,这提高了推理速度。
3. 深度与宽度的灵活配置
  • RepNCSPELAN4 支持通道分割和并行处理,这意味着可以通过调整通道数和重复的 RepNCSP 层数来适应不同的计算资源和任务需求。
  • 通过调整 c5 参数(即 RepNCSP 中的重复次数),可以根据需要增加或减少模块的深度。
4. 特征融合
  • RepNCSPELAN4 在其 forward 方法中将输入通道分成两个部分,并分别通过 RepNCSP 处理,最后再合并。这样的设计有助于更好地聚合多尺度特征,增强模型对不同大小目标的识别能力。
5. 易于扩展
  • 该模块易于集成到更大的网络结构中,例如作为骨干网络的一部分,或者作为头部网络中的组件。
6. 训练和部署的一致性
  • 由于 RepConvN 在训练和部署阶段表现的一致性,使得整个网络更容易优化并且避免了在不同阶段之间切换带来的性能损失。
7. 灵活的前向传播模式
  • 提供了 forward_split 方法,这为开发者提供了更多的灵活性,可以在需要时使用不同的通道分割策略。

通过这些设计特点,RepNCSPELAN4 能够在保持高精度的同时,实现高效的计算性能,使其成为实时目标检测任务的理想选择。

七、注意

第二步在YOLOv5/v7的models文件夹下新建文件repncspelan4.py的激活函数是YOLOv7-tiny的LeakyReLU,

    default_act = nn.LeakyReLU()  # default activation

使用YOLOv7、YOLOv5时需要更改为SiLU()

    default_act = nn.SiLU()

运行后打印如上代码说明改进成功。

更多文章产出中,主打简洁和准确,欢迎关注我,共同探讨!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/877215.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TCP/IP协议——使用Socket套接字实现

目录 Socket 使用Socket实现TCP客户端和服务器的过程 使用Socket搭建TCP服务器 线程优化 向客户端发送消息 连接的断开 客户端主动断开 服务端主动断开 服务器完整的程序 使用Socket编写客户端程序连接TCP服务器 Socket Socket是一种网络通信协议,它允许…

x-cmd pkg | yazi - 超快终端文件管理器

目录 简介快速入门功能特点竞品和相关项目进一步阅读 简介 yazi 是由 github.com/sxyazi 用 Rust 开发的终端文件管理器,支持预览文本文件、pdf 文件、图像、视频,内置代码高亮功能。在内部,它使用 Tokio 作为其异步运行时,以非阻…

【Vue3】watch 监视多种类型数据

【Vue3】watch 监视多种类型数据 背景简介开发环境开发步骤及源码 背景 随着年龄的增长,很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来,技术出身的人总是很难放下一些执念,遂将这些知识整理成文,以纪念曾经努力学习奋斗…

大数据-53 Kafka 基本架构核心概念 Producer Consumer Broker Topic Partition Offset 基础概念了解

点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…

实战:Zookeeper 简介和单点部署ZooKeeper

Zookeeper 简介 ZooKeeper是一个开源的分布式协调服务,它是Apache软件基金会下的一个项目,旨在解决分布式系统中的协调和管理问题。以下是ZooKeeper的详细简介: 一、基本定义 ZooKeeper是一个分布式的、开放源码的分布式应用程序协调服务&a…

系统架构师考点--系统架构设计(下)

大家好。今天总结一下系统架构设计的最后一部分知识点。 一、软件系统的质量属性 软件系统的质量属性 软件系统的质量属性可分为开发期质量属性和运行期质量属性2个部分。 1、开发期质量属性主要指在软件开发阶段所关注的质量属性,主要包含6个方面: …

C++ 关键字与库函数 学习总结

sizeof与strlen 含义 sizeof:是一个操作符,用于计算数据类型或变量的大小(以字节为单位)。在编译时求值strlen: 是一个函数,用于计算字符串的长度(不包括终止符 \0)。在运行时求值不…

【Code】Street-Gaussian代码复现笔记

文章目录 1. EnvironmentBug 1 2. TrainingBug 2Bug 3 1. Environment Follow the original instructions, conda create --name street-gaussians-ns -y python3.8 conda activate street-gaussians-ns pip install --upgrade pippip install torch2.1.2cu118 torchvision0.…

bugku-web-ctf-变量1

<?php error_reporting(0); include "flag1.php"; highlight_file(__file__); if(isset($_GET[args])){$args $_GET[args];if(!preg_match("/^\w$/",$args)){die("args error!");}eval("var_dump($$args);"); } ?> error_r…

扩展------正向代理和反向代理怎么理解?

今天看博客园&#xff0c;突然看到正向代理和反向代理&#xff0c;发现自己还不会就稍微研究了一下。 正向代理----(看做是服务员) 当我们进饭店吃饭&#xff0c;我们不可能会直接去后厨叫厨师给我们做菜&#xff0c;而是通过服务员去通知&#xff0c;这个就叫做正向代理。 再…

当年很流行,现在已经淘汰的Java技术,请不要学了!【建议收藏】

在Java技术的发展历程中&#xff0c;确实有一些曾经流行但现在已经被淘汰或不再推荐使用的技术。了解这些技术可以帮助你避免学习过时的知识&#xff0c;从而更高效地提升自己的技能。 以下是一些曾经流行但现在已经不太推荐学习的Java技术&#xff1a; 1. Servlet 2.x&#x…

AI作图接口要怎么调用呢?

一、什么是AI作图&#xff1f; 基于AI大模型的深度学习算法和大规模的图像数据训练&#xff0c;输入图片和关键词&#xff0c;可生成独特及富有创意的山水风格图片。 二、AI作图使用场景有哪些呢&#xff1f; 1.广告与营销&#xff1a; 为产品制作吸引人的宣传海报、广告图片…

git拉完代码总是自动创建一个新的节点

git拉完代码&#xff0c;总是自动生成弹出这个信息 然后还会在git上面留下一个节点&#xff0c;这个节点没啥用&#xff0c;显示着感觉有点碍事。 而且后续的git push 之后&#xff0c;会覆盖掉自己的git commit 的提示&#xff0c;其他人cr代码的时候看到的是 解决方法&#…

vite + postcss 安装配置

安装 npm install postcss-pxtorem --save-dev配置postcss.config.js 新建 postcss.config.js export default {plugins: {postcss-pxtorem: {rootValue: 16, // 根元素大小&#xff0c;用于转换rem的基准值unitPrecision: 5, // rem的小数位数propList: [*], // 需要转换的…

A股两市继续低开,缩量震荡前行!

今天的A股&#xff0c;让人心情极度炸裂&#xff0c;你们知道是为什么吗&#xff1f;盘面上出现2个重要信号&#xff0c;一起来看看&#xff1a; 1、今天两市低开&#xff0c;让人心情极度炸裂。 2、盘面上出现2个重要信号&#xff1a;一是为了迎接今日上证权益指数问世&#x…

LeetCode刷题笔记第682题:棒球比赛

LeetCode刷题笔记第682题&#xff1a;棒球比赛 题目&#xff1a; 想法&#xff1a; 遍历输入的列表&#xff0c;按照规则将分数和操作依次进行&#xff0c;存储在新建的列表中&#xff0c;最终输出列表中的元素和&#xff0c;代码如下&#xff1a; class Solution:def calPo…

妈吖,看过这个大厂的oracle主键自增,我的信心暴增!信创,国产数据库也能行。

创作不易 只因热爱!! 热衷分享&#xff0c;一起成长! “你的鼓励就是我努力付出的动力” 1.数据库oracle自增主键字段思维导图 在Oracle数据库中&#xff0c;可以通过创建序列&#xff08;SEQUENCE&#xff09;来实现自增功能。但也可以不在数据库中实现&#xff0c;而是通过程…

【Stable Diffusion】(基础篇六)—— embedding

embedding 本系列博客笔记主要参考B站nenly同学的视频教程&#xff0c;传送门&#xff1a;B站第一套系统的AI绘画课&#xff01;零基础学会Stable Diffusion&#xff0c;这绝对是你看过的最容易上手的AI绘画教程 | SD WebUI 保姆级攻略_哔哩哔哩_bilibili 除了大模型和VAE之外…

RewardBench:Evaluating Reward Models for Language Modeling

Leaderboard&#xff1a; https://hf.co/spaces/allenai/reward-bench Code&#xff1a; https://github.com/allenai/reward-bench Dataset&#xff1a; https://hf.co/datasets/allenai/reward-bench 在人类偏好的强化学习&#xff08;RLHF&#xff09;过程中&#xff0c;奖励…

Centos7重装系统保留数据安装方式记录

一、选择手动配置分区 二、选择/分区以后&#xff0c;输入挂载点/&#xff0c;选择标准分区&#xff0c;勾选重新格式化&#xff0c;单击更新设置。这样重装的时候&#xff0c;就格式化/分区内的数据。 三、选择swap分区&#xff0c;勾选重新格式化&#xff0c;单击更新设置…