【YOLOv5/v7改进系列】替换骨干网络为ShuffleNetv2

一、导言

《ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design》提出了一种新的卷积神经网络(CNN)架构设计方法,并给出了一系列实用的设计指南,旨在提高模型在实际应用中的效率。其优点主要体现在以下几个方面:

  1. 直接性能指标评估:传统的CNN设计往往侧重于计算复杂度(如FLOPs)这一间接指标,而该研究主张在目标平台上直接评估模型的速度等直接性能指标。这考虑到了内存访问成本和平台特性等其他因素,从而提供了更贴近实际应用场景的性能评估方式。

  2. 实用性设计原则:通过一系列控制实验,文章得出了几条高效网络设计的实用原则,比如平衡卷积、注意分组卷积的成本、减少网络碎片化以及限制逐元素运算等,这些原则对实际设计轻量化、高效率网络具有重要指导意义。

  3. ShuffleNet V2架构:基于上述设计原则,论文介绍了一个新架构——ShuffleNet V2,该架构不仅优化了特征重用模式,类似于DenseNet在保持高精度的同时提高了效率,而且在速度与精度权衡上达到了当时最优。

  4. 详实的实验验证:作者在ImageNet 2012分类数据集上进行了广泛的消融实验,比较了不同复杂度级别的ShuffleNet V2与其他知名网络架构(如ShuffleNet V1、MobileNet V2、Xception、DenseNet)的性能。实验结果全面展示了ShuffleNet V2在速度与精度上的优越性,并通过各种配置的比较,验证了所提设计原则的有效性。

  5. 对实际问题的洞察:研究揭示了在不同任务(如图像分类与对象检测)中,网络表现排名的变化,特别是指出扩大感受野对检测任务的重要性,并据此提出了ShuffleNet V2*变体,通过增加少量FLOPs进一步提升了准确性,为未来工作指明了方向。

  6. 跨平台考虑:文档不仅关注GPU上的性能,还考虑了ARM平台的表现,显示了不同设计选择对不同硬件环境的影响,增强了设计的通用性和实用性。

综上所述,这篇文档通过提供一套面向实践的CNN设计原则和一个高效的网络架构ShuffleNet V2,对推动深度学习模型设计领域的发展做出了重要贡献,尤其是在追求高效、轻量化模型设计方面。

二、准备工作

首先在YOLOv5/v7项目文件下的models文件夹下创建新的文件shufflenetv2.py

导入如下代码

from models.common import *


def channel_shuffle(x, groups):
    batchsize, num_channels, height, width = x.data.size()
    channels_per_group = num_channels // groups

    # reshape
    x = x.view(batchsize, groups,
               channels_per_group, height, width)

    x = torch.transpose(x, 1, 2).contiguous()

    # flatten
    x = x.view(batchsize, -1, height, width)

    return x


class conv_bn_relu_maxpool(nn.Module):
    def __init__(self, c1, c2):  # ch_in, ch_out
        super(conv_bn_relu_maxpool, self).__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(c1, c2, kernel_size=3, stride=2, padding=1, bias=False),
            nn.BatchNorm2d(c2),
            nn.ReLU(inplace=True),
        )
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)

    def forward(self, x):
        return self.maxpool(self.conv(x))


class Shuffle_Block(nn.Module):
    def __init__(self, inp, oup, stride):
        super(Shuffle_Block, self).__init__()

        if not (1 <= stride <= 3):
            raise ValueError('illegal stride value')
        self.stride = stride

        branch_features = oup // 2
        assert (self.stride != 1) or (inp == branch_features << 1)

        if self.stride > 1:
            self.branch1 = nn.Sequential(
                self.depthwise_conv(inp, inp, kernel_size=3, stride=self.stride, padding=1),
                nn.BatchNorm2d(inp),
                nn.Conv2d(inp, branch_features, kernel_size=1, stride=1, padding=0, bias=False),
                nn.BatchNorm2d(branch_features),
                nn.ReLU(inplace=True),
            )

        self.branch2 = nn.Sequential(
            nn.Conv2d(inp if (self.stride > 1) else branch_features,
                      branch_features, kernel_size=1, stride=1, padding=0, bias=False),
            nn.BatchNorm2d(branch_features),
            nn.ReLU(inplace=True),
            self.depthwise_conv(branch_features, branch_features, kernel_size=3, stride=self.stride, padding=1),
            nn.BatchNorm2d(branch_features),
            nn.Conv2d(branch_features, branch_features, kernel_size=1, stride=1, padding=0, bias=False),
            nn.BatchNorm2d(branch_features),
            nn.ReLU(inplace=True),
        )

    @staticmethod
    def depthwise_conv(i, o, kernel_size, stride=1, padding=0, bias=False):
        return nn.Conv2d(i, o, kernel_size, stride, padding, bias=bias, groups=i)

    def forward(self, x):
        if self.stride == 1:
            x1, x2 = x.chunk(2, dim=1)  # 按照维度1进行split
            out = torch.cat((x1, self.branch2(x2)), dim=1)
        else:
            out = torch.cat((self.branch1(x), self.branch2(x)), dim=1)

        out = channel_shuffle(out, 2)

        return out

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

from models.shufflenetv2 import *

并搜索def parse_model(d, ch)

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

conv_bn_relu_maxpool, Shuffle_Block,  # ShuffleNetv2

三、YOLOv7-tiny改进工作

完成二后,在YOLOv5项目文件下的models文件夹下创建新的文件yolov7-tiny-shufflenetv2.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]
  # Shuffle_Block: [out, stride]
  [[ -1, 1, conv_bn_relu_maxpool, [ 32 ] ], # 0-P2/4
   [ -1, 1, Shuffle_Block, [ 128, 2 ] ],  # 1-P3/8
   [ -1, 3, Shuffle_Block, [ 128, 1 ] ],  # 2
   [ -1, 1, Shuffle_Block, [ 256, 2 ] ],  # 3-P4/16
   [ -1, 7, Shuffle_Block, [ 256, 1 ] ],  # 4
   [ -1, 1, Shuffle_Block, [ 512, 2 ] ],  # 5-P5/32
   [ -1, 3, Shuffle_Block, [ 512, 1 ] ],  # 6
  ]

# 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-15

   [-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [4, 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-25

   [-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [2, 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-35

   [-1, 1, Conv, [128, 3, 2, None, 1, nn.LeakyReLU(0.1)]],
   [[-1, 25], 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-43

   [-1, 1, Conv, [256, 3, 2, None, 1, nn.LeakyReLU(0.1)]],
   [[-1, 15], 1, Concat, [1]],

   [-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)]],  # 73-51

   [35, 1, Conv, [128, 3, 1, None, 1, nn.LeakyReLU(0.1)]],
   [43, 1, Conv, [256, 3, 1, None, 1, nn.LeakyReLU(0.1)]],
   [51, 1, Conv, [512, 3, 1, None, 1, nn.LeakyReLU(0.1)]],

   [[52,53,54], 1, IDetect, [nc, anchors]],   # Detect(P3, P4, P5)
  ]

                 from  n    params  module                                  arguments                     
  0                -1  1       928  models.shufflenetv2.conv_bn_relu_maxpool[3, 32]                       
  1                -1  1      9632  models.shufflenetv2.Shuffle_Block       [32, 128, 2]                  
  2                -1  3     27456  models.shufflenetv2.Shuffle_Block       [128, 128, 1]                 
  3                -1  1     52736  models.shufflenetv2.Shuffle_Block       [128, 256, 2]                 
  4                -1  7    242816  models.shufflenetv2.Shuffle_Block       [256, 256, 1]                 
  5                -1  1    203776  models.shufflenetv2.Shuffle_Block       [256, 512, 2]                 
  6                -1  3    404736  models.shufflenetv2.Shuffle_Block       [512, 512, 1]                 
  7                -1  1    131584  models.common.Conv                      [512, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
  8                -2  1    131584  models.common.Conv                      [512, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
  9                -1  1         0  models.common.SP                        [5]                           
 10                -2  1         0  models.common.SP                        [9]                           
 11                -3  1         0  models.common.SP                        [13]                          
 12  [-1, -2, -3, -4]  1         0  models.common.Concat                    [1]                           
 13                -1  1    262656  models.common.Conv                      [1024, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 14          [-1, -7]  1         0  models.common.Concat                    [1]                           
 15                -1  1    131584  models.common.Conv                      [512, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 16                -1  1     33024  models.common.Conv                      [256, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 17                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          
 18                 4  1     33024  models.common.Conv                      [256, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 19          [-1, -2]  1         0  models.common.Concat                    [1]                           
 20                -1  1     16512  models.common.Conv                      [256, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 21                -2  1     16512  models.common.Conv                      [256, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 22                -1  1     36992  models.common.Conv                      [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 23                -1  1     36992  models.common.Conv                      [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 24  [-1, -2, -3, -4]  1         0  models.common.Concat                    [1]                           
 25                -1  1     33024  models.common.Conv                      [256, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 26                -1  1      8320  models.common.Conv                      [128, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 27                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          
 28                 2  1      8320  models.common.Conv                      [128, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 29          [-1, -2]  1         0  models.common.Concat                    [1]                           
 30                -1  1      4160  models.common.Conv                      [128, 32, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 31                -2  1      4160  models.common.Conv                      [128, 32, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 32                -1  1      9280  models.common.Conv                      [32, 32, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 33                -1  1      9280  models.common.Conv                      [32, 32, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 34  [-1, -2, -3, -4]  1         0  models.common.Concat                    [1]                           
 35                -1  1      8320  models.common.Conv                      [128, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 36                -1  1     73984  models.common.Conv                      [64, 128, 3, 2, None, 1, LeakyReLU(negative_slope=0.1)]
 37          [-1, 25]  1         0  models.common.Concat                    [1]                           
 38                -1  1     16512  models.common.Conv                      [256, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 39                -2  1     16512  models.common.Conv                      [256, 64, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 40                -1  1     36992  models.common.Conv                      [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 41                -1  1     36992  models.common.Conv                      [64, 64, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 42  [-1, -2, -3, -4]  1         0  models.common.Concat                    [1]                           
 43                -1  1     33024  models.common.Conv                      [256, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 44                -1  1    295424  models.common.Conv                      [128, 256, 3, 2, None, 1, LeakyReLU(negative_slope=0.1)]
 45          [-1, 15]  1         0  models.common.Concat                    [1]                           
 46                -1  1     65792  models.common.Conv                      [512, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 47                -2  1     65792  models.common.Conv                      [512, 128, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 48                -1  1    147712  models.common.Conv                      [128, 128, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 49                -1  1    147712  models.common.Conv                      [128, 128, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 50  [-1, -2, -3, -4]  1         0  models.common.Concat                    [1]                           
 51                -1  1    131584  models.common.Conv                      [512, 256, 1, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 52                35  1     73984  models.common.Conv                      [64, 128, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 53                43  1    295424  models.common.Conv                      [128, 256, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 54                51  1   1180672  models.common.Conv                      [256, 512, 3, 1, None, 1, LeakyReLU(negative_slope=0.1)]
 55      [52, 53, 54]  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: 352 layers, 4492652 parameters, 4492652 gradients, 8.5 GFLOPS

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

四、YOLOv5s改进工作

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

nc: 80  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # 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
# custom backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, conv_bn_relu_maxpool, [32]], # 0-P2/4
   [-1, 1, Shuffle_Block, [128, 2]],  # 1-P3/8
   [-1, 3, Shuffle_Block, [128, 1]],  # 2
   [-1, 1, Shuffle_Block, [256, 2]],  # 3-P4/16
   [-1, 7, Shuffle_Block, [256, 1]],  # 4
   [-1, 1, Shuffle_Block, [512, 2]],  # 5-P5/32
   [-1, 3, Shuffle_Block, [512, 1]],  # 6
  ]

# YOLOv5 head
head:
  [[-1, 1, Conv, [512, 1, 1]],                        # 7
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],        # 8
   [[-1, 4], 1, Concat, [1]],  # cat backbone P4      # 9
   [-1, 1, C3, [512, False]],                         # 10

   [-1, 1, Conv, [256, 1, 1]],                       # 11
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],       # 12
   [[-1, 2], 1, Concat, [1]],  # cat backbone P3     # 13
   [-1, 1, C3, [256, False]],  # 14 (P3/8-small)     # 14

   [-1, 1, Conv, [128, 3, 2]],                      # 15
   [[-1, 11], 1, Concat, [1]],  # cat head P4       # 16
   [-1, 1, C3, [256, False]],  # 17 (P4/16-medium)  # 17

   [-1, 1, Conv, [256, 3, 2]],                      # 18
   [[-1, 7], 1, Concat, [1]],  # cat head P5        # 19
   [-1, 1, C3, [512, False]],  # 20 (P5/32-large)   # 20

   [[14, 17, 20], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

                 from  n    params  module                                  arguments                     
  0                -1  1       232  models.shufflenetv2.conv_bn_relu_maxpool[3, 8]                        
  1                -1  1       872  models.shufflenetv2.Shuffle_Block       [8, 32, 2]                    
  2                -1  1       752  models.shufflenetv2.Shuffle_Block       [32, 32, 1]                   
  3                -1  1      3968  models.shufflenetv2.Shuffle_Block       [32, 64, 2]                   
  4                -1  2      5056  models.shufflenetv2.Shuffle_Block       [64, 64, 1]                   
  5                -1  1     14080  models.shufflenetv2.Shuffle_Block       [64, 128, 2]                  
  6                -1  1      9152  models.shufflenetv2.Shuffle_Block       [128, 128, 1]                 
  7                -1  1     16640  models.common.Conv                      [128, 128, 1, 1]              
  8                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          
  9           [-1, 4]  1         0  models.common.Concat                    [1]                           
 10                -1  1     82688  models.common.C3                        [192, 128, 1, False]          
 11                -1  1      8320  models.common.Conv                      [128, 64, 1, 1]               
 12                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          
 13           [-1, 2]  1         0  models.common.Concat                    [1]                           
 14                -1  1     20864  models.common.C3                        [96, 64, 1, False]            
 15                -1  1     18496  models.common.Conv                      [64, 32, 3, 2]                
 16          [-1, 11]  1         0  models.common.Concat                    [1]                           
 17                -1  1     20864  models.common.C3                        [96, 64, 1, False]            
 18                -1  1     36992  models.common.Conv                      [64, 64, 3, 2]                
 19           [-1, 7]  1         0  models.common.Concat                    [1]                           
 20                -1  1     82688  models.common.C3                        [192, 128, 1, False]          
 21      [14, 17, 20]  1      4662  models.yolo.Detect                      [1, [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]], [64, 64, 128]]

Model Summary: 216 layers, 326326 parameters, 326326 gradients, 1.0 GFLOPs

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

五、YOLOv5n改进工作

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

nc: 80  # 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
# custom backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, conv_bn_relu_maxpool, [32]], # 0-P2/4
   [-1, 1, Shuffle_Block, [128, 2]],  # 1-P3/8
   [-1, 3, Shuffle_Block, [128, 1]],  # 2
   [-1, 1, Shuffle_Block, [256, 2]],  # 3-P4/16
   [-1, 7, Shuffle_Block, [256, 1]],  # 4
   [-1, 1, Shuffle_Block, [512, 2]],  # 5-P5/32
   [-1, 3, Shuffle_Block, [512, 1]],  # 6
  ]

# YOLOv5 head
head:
  [[-1, 1, Conv, [512, 1, 1]],                        # 7
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],        # 8
   [[-1, 4], 1, Concat, [1]],  # cat backbone P4      # 9
   [-1, 1, C3, [512, False]],                         # 10

   [-1, 1, Conv, [256, 1, 1]],                       # 11
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],       # 12
   [[-1, 2], 1, Concat, [1]],  # cat backbone P3     # 13
   [-1, 1, C3, [256, False]],  # 14 (P3/8-small)     # 14

   [-1, 1, Conv, [128, 3, 2]],                      # 15
   [[-1, 11], 1, Concat, [1]],  # cat head P4       # 16
   [-1, 1, C3, [256, False]],  # 17 (P4/16-medium)  # 17

   [-1, 1, Conv, [256, 3, 2]],                      # 18
   [[-1, 7], 1, Concat, [1]],  # cat head P5        # 19
   [-1, 1, C3, [512, False]],  # 20 (P5/32-large)   # 20

   [[14, 17, 20], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

                 from  n    params  module                                  arguments                     
  0                -1  1       464  models.shufflenetv2.conv_bn_relu_maxpool[3, 16]                       
  1                -1  1      2768  models.shufflenetv2.Shuffle_Block       [16, 64, 2]                   
  2                -1  1      2528  models.shufflenetv2.Shuffle_Block       [64, 64, 1]                   
  3                -1  1     14080  models.shufflenetv2.Shuffle_Block       [64, 128, 2]                  
  4                -1  2     18304  models.shufflenetv2.Shuffle_Block       [128, 128, 1]                 
  5                -1  1     52736  models.shufflenetv2.Shuffle_Block       [128, 256, 2]                 
  6                -1  1     34688  models.shufflenetv2.Shuffle_Block       [256, 256, 1]                 
  7                -1  1     66048  models.common.Conv                      [256, 256, 1, 1]              
  8                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          
  9           [-1, 4]  1         0  models.common.Concat                    [1]                           
 10                -1  1    329216  models.common.C3                        [384, 256, 1, False]          
 11                -1  1     33024  models.common.Conv                      [256, 128, 1, 1]              
 12                -1  1         0  torch.nn.modules.upsampling.Upsample    [None, 2, 'nearest']          
 13           [-1, 2]  1         0  models.common.Concat                    [1]                           
 14                -1  1     82688  models.common.C3                        [192, 128, 1, False]          
 15                -1  1     73856  models.common.Conv                      [128, 64, 3, 2]               
 16          [-1, 11]  1         0  models.common.Concat                    [1]                           
 17                -1  1     82688  models.common.C3                        [192, 128, 1, False]          
 18                -1  1    147712  models.common.Conv                      [128, 128, 3, 2]              
 19           [-1, 7]  1         0  models.common.Concat                    [1]                           
 20                -1  1    329216  models.common.C3                        [384, 256, 1, False]          
 21      [14, 17, 20]  1      9270  models.yolo.Detect                      [1, [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]], [128, 128, 256]]

Model Summary: 216 layers, 1279286 parameters, 1279286 gradients, 3.7 GFLOPs

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

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

  • 32
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值