当前位置:   article > 正文

Yolov5改进算法之添加Res2Net模块_yolov5 res2net

yolov5 res2net

目录

1. Res2Net介绍

1.1 Res2Net的背景和动机

1.2 Res2Net的基本概念

2. YOLOV5添加Res2Net模块


 

Res2Net(Residual Resolution Network)是一种用于图像处理和计算机视觉任务的深度卷积神经网络架构。它旨在解决传统的ResNet(Residual Network)存在的问题,如对不同尺度和分辨率特征的建模不足以及网络深度受限的问题。Res2Net通过引入多分支的结构和逐级增加的分辨率来提高网络的表达能力,从而在各种视觉任务中取得了显著的性能提升。

1. Res2Net介绍

1.1 Res2Net的背景和动机

ResNet是一种非常成功的深度卷积神经网络,但它存在一些问题。其中最重要的问题之一是对不同尺度和分辨率特征的建模不足。传统的ResNet块只使用单一的残差连接来传递信息,这意味着网络可能无法有效地捕获不同层次的特征。

Res2Net的动机是通过引入多分支结构和逐级增加的分辨率来提高网络的表达能力。这使得网络能够更好地处理多尺度和多分辨率的特征,从而提高了其在各种计算机视觉任务中的性能。

1.2 Res2Net的基本概念

ResNet中的基本构建块,即残差块(Residual Block)。一个典型的残差块包含两个主要分支:一个跳跃连接(Identity Shortcut)和一个经过多个卷积层的主路径。跳跃连接用于绕过一些卷积层,以确保梯度能够顺畅地传播。

Res2Net的核心思想是将多个分支的信息融合在一个残差块中,以提高网络对不同分辨率的特征的表达能力。具体来说,Res2Net引入了多尺度子网络(Multi-Scale Sub-Networks)来处理不同分辨率的特征,然后将它们的输出级联在一起。这种级联结构允许网络同时学习低分辨率和高分辨率的特征表示,从而提高了网络的感知能力。

Res2Net的核心结构是一个多分支的残差块,每个分支都有自己的卷积层,负责处理不同分辨率的特征。这些分支的输出级联在一起,以获得最终的块输出。多个这样的块可以构建成深层网络,以处理更复杂的任务。

Res2Net的工作原理在前向传播过程中如下:

  1. 输入特征首先经过一个初始卷积层,用于提取低级别的特征表示。
  2. 接下来,输入特征被送入多个Res2Net块。每个块都包含多个分支,每个分支处理不同分辨率的特征。
  3. 每个分支内部包含卷积层、激活函数和规范化层等,用于提取和调整特征。
  4. 分支的输出级联在一起,形成块的最终输出。
  5. 这个块的输出可以传递到下一个块,也可以连接到网络的其他部分。

如下图:

db3fa43d2c3b4834ad09d6963cdbdd44.png

2. YOLOV5添加Res2Net模块

在models/common.py文件中增加以下模块:

  1. class Bottle2neck(nn.Module):
  2. expansion = 1
  3. def __init__(self, inplanes, planes, shortcut, baseWidth=26, scale=4):
  4. """ Constructor
  5. Args:
  6. inplanes: input channel dimensionality
  7. planes: output channel dimensionality
  8. baseWidth: basic width of conv3x3
  9. scale: number of scale.
  10. """
  11. super(Bottle2neck, self).__init__()
  12. width = int(math.floor(planes * (baseWidth / 64.0)))
  13. self.conv1 = Conv(inplanes, width * scale, k=1)
  14. if scale == 1:
  15. self.nums = 1
  16. else:
  17. self.nums = scale - 1
  18. convs = []
  19. for i in range(self.nums):
  20. convs.append(Conv(width, width, k=3))
  21. self.convs = nn.ModuleList(convs)
  22. self.conv3 = Conv(width * scale, planes * self.expansion, k=1, act=False)
  23. self.silu = nn.SiLU(inplace=True)
  24. self.scale = scale
  25. self.width = width
  26. self.shortcut = shortcut
  27. def forward(self, x):
  28. if self.shortcut:
  29. residual = x
  30. out = self.conv1(x)
  31. spx = torch.split(out, self.width, 1)
  32. for i in range(self.nums):
  33. if i == 0:
  34. sp = spx[i]
  35. else:
  36. sp = sp + spx[i]
  37. sp = self.convs[i](sp)
  38. if i == 0:
  39. out = sp
  40. else:
  41. out = torch.cat((out, sp), 1)
  42. if self.scale != 1:
  43. out = torch.cat((out, spx[self.nums]), 1)
  44. out = self.conv3(out)
  45. print(out.shape)
  46. if self.shortcut:
  47. out += residual
  48. out = self.silu(out)
  49. return out
  50. class C3_Res2Block(C3):
  51. # CSP Bottleneck with 3 convolutions
  52. def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansion
  53. super().__init__(c1, c2, n, shortcut, g, e)
  54. c_ = int(c2 * e) # hidden channels
  55. self.m = nn.Sequential(*(Bottle2neck(c_, c_, shortcut) for _ in range(n)))

在models/yolo.py文件下里的parse_model函数将类名加入进去,如下图:

6d84167536844b19a7a57e1704e35c30.png

创建添加Res2Net模块的YOLOv5的yaml配置文件 

  1. # Parameters
  2. nc: 80 # number of classes
  3. depth_multiple: 0.33 # model depth multiple
  4. width_multiple: 0.50 # layer channel multiple
  5. anchors:
  6. - [10,13, 16,30, 33,23] # P3/8
  7. - [30,61, 62,45, 59,119] # P4/16
  8. - [116,90, 156,198, 373,326] # P5/32
  9. # YOLOv5 v6.0 backbone
  10. backbone:
  11. # [from, number, module, args]
  12. [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2
  13. [-1, 1, Conv, [128, 3, 2]], # 1-P2/4
  14. [-1, 3, C3_Res2Block, [128]],
  15. [-1, 1, Conv, [256, 3, 2]], # 3-P3/8
  16. [-1, 6, C3_Res2Block, [256]],
  17. [-1, 1, Conv, [512, 3, 2]], # 5-P4/16
  18. [-1, 9, C3_Res2Block, [512]],
  19. [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
  20. [-1, 3, C3_Res2Block, [1024]],
  21. [-1, 1, SPPF, [1024, 5]], # 9
  22. ]
  23. # YOLOv5 v6.0 head
  24. head:
  25. [[-1, 1, Conv, [512, 1, 1]],
  26. [-1, 1, nn.Upsample, [None, 2, 'nearest']],
  27. [[-1, 6], 1, Concat, [1]], # cat backbone P4
  28. [-1, 3, C3_Res2Block, [512, False]], # 13
  29. [-1, 1, Conv, [256, 1, 1]],
  30. [-1, 1, nn.Upsample, [None, 2, 'nearest']],
  31. [[-1, 4], 1, Concat, [1]], # cat backbone P3
  32. [-1, 3, C3_Res2Block, [256, False]], # 17 (P3/8-small)
  33. [-1, 1, Conv, [256, 3, 2]],
  34. [[-1, 14], 1, Concat, [1]], # cat head P4
  35. [-1, 3, C3_Res2Block, [512, False]], # 20 (P4/16-medium)
  36. [-1, 1, Conv, [512, 3, 2]],
  37. [[-1, 10], 1, Concat, [1]], # cat head P5
  38. [-1, 3, C3_Res2Block, [1024, False]], # 23 (P5/32-large)
  39. [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
  40. ]

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/93972
推荐阅读
相关标签
  

闽ICP备14008679号