• 【目标检测】理论篇(3)YOLOv5实现


    Yolov5网络构架实现

    1. import torch
    2. import torch.nn as nn
    3. class SiLU(nn.Module):
    4. @staticmethod
    5. def forward(x):
    6. return x * torch.sigmoid(x)
    7. def autopad(k, p=None):
    8. if p is None:
    9. p = k // 2 if isinstance(k, int) else [x // 2 for x in k]
    10. return p
    11. class Focus(nn.Module):
    12. def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True): # ch_in, ch_out, kernel, stride, padding, groups
    13. super(Focus, self).__init__()
    14. self.conv = Conv(c1 * 4, c2, k, s, p, g, act)
    15. def forward(self, x):
    16. # 320, 320, 12 => 320, 320, 64
    17. return self.conv(
    18. # 640, 640, 3 => 320, 320, 12
    19. torch.cat(
    20. [
    21. x[..., ::2, ::2],
    22. x[..., 1::2, ::2],
    23. x[..., ::2, 1::2],
    24. x[..., 1::2, 1::2]
    25. ], 1
    26. )
    27. )
    28. class Conv(nn.Module):
    29. def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):
    30. super(Conv, self).__init__()
    31. self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False)
    32. self.bn = nn.BatchNorm2d(c2, eps=0.001, momentum=0.03)
    33. self.act = SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity())
    34. def forward(self, x):
    35. return self.act(self.bn(self.conv(x)))
    36. def fuseforward(self, x):
    37. return self.act(self.conv(x))
    38. class Bottleneck(nn.Module):
    39. # Standard bottleneck
    40. def __init__(self, c1, c2, shortcut=True, g=1, e=0.5): # ch_in, ch_out, shortcut, groups, expansion
    41. super(Bottleneck, self).__init__()
    42. c_ = int(c2 * e) # hidden channels
    43. self.cv1 = Conv(c1, c_, 1, 1)
    44. self.cv2 = Conv(c_, c2, 3, 1, g=g)
    45. self.add = shortcut and c1 == c2
    46. def forward(self, x):
    47. return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))
    48. class C3(nn.Module):
    49. # CSP Bottleneck with 3 convolutions
    50. def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansion
    51. super(C3, self).__init__()
    52. c_ = int(c2 * e) # hidden channels
    53. self.cv1 = Conv(c1, c_, 1, 1)
    54. self.cv2 = Conv(c1, c_, 1, 1)
    55. self.cv3 = Conv(2 * c_, c2, 1) # act=FReLU(c2)
    56. self.m = nn.Sequential(*[Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)])
    57. # self.m = nn.Sequential(*[CrossConv(c_, c_, 3, 1, g, 1.0, shortcut) for _ in range(n)])
    58. def forward(self, x):
    59. return self.cv3(torch.cat(
    60. (
    61. self.m(self.cv1(x)),
    62. self.cv2(x)
    63. )
    64. , dim=1))
    65. class SPP(nn.Module):
    66. # Spatial pyramid pooling layer used in YOLOv3-SPP
    67. def __init__(self, c1, c2, k=(5, 9, 13)):
    68. super(SPP, self).__init__()
    69. c_ = c1 // 2 # hidden channels
    70. self.cv1 = Conv(c1, c_, 1, 1)
    71. self.cv2 = Conv(c_ * (len(k) + 1), c2, 1, 1)
    72. self.m = nn.ModuleList([nn.MaxPool2d(kernel_size=x, stride=1, padding=x // 2) for x in k])
    73. def forward(self, x):
    74. x = self.cv1(x)
    75. return self.cv2(torch.cat([x] + [m(x) for m in self.m], 1))
    76. class CSPDarknet(nn.Module):
    77. def __init__(self, base_channels, base_depth, phi, pretrained):
    78. super().__init__()
    79. #-----------------------------------------------#
    80. # 输入图片是640, 640, 3
    81. # 初始的基本通道base_channels是64
    82. #-----------------------------------------------#
    83. #-----------------------------------------------#
    84. # 利用focus网络结构进行特征提取
    85. # 640, 640, 3 -> 320, 320, 12 -> 320, 320, 64
    86. #-----------------------------------------------#
    87. self.stem = Focus(3, base_channels, k=3)
    88. #-----------------------------------------------#
    89. # 完成卷积之后,320, 320, 64 -> 160, 160, 128
    90. # 完成CSPlayer之后,160, 160, 128 -> 160, 160, 128
    91. #-----------------------------------------------#
    92. self.dark2 = nn.Sequential(
    93. # 320, 320, 64 -> 160, 160, 128
    94. Conv(base_channels, base_channels * 2, 3, 2),
    95. # 160, 160, 128 -> 160, 160, 128
    96. C3(base_channels * 2, base_channels * 2, base_depth),
    97. )
    98. #-----------------------------------------------#
    99. # 完成卷积之后,160, 160, 128 -> 80, 80, 256
    100. # 完成CSPlayer之后,80, 80, 256 -> 80, 80, 256
    101. # 在这里引出有效特征层80, 80, 256
    102. # 进行加强特征提取网络FPN的构建
    103. #-----------------------------------------------#
    104. self.dark3 = nn.Sequential(
    105. Conv(base_channels * 2, base_channels * 4, 3, 2),
    106. C3(base_channels * 4, base_channels * 4, base_depth * 3),
    107. )
    108. #-----------------------------------------------#
    109. # 完成卷积之后,80, 80, 256 -> 40, 40, 512
    110. # 完成CSPlayer之后,40, 40, 512 -> 40, 40, 512
    111. # 在这里引出有效特征层40, 40, 512
    112. # 进行加强特征提取网络FPN的构建
    113. #-----------------------------------------------#
    114. self.dark4 = nn.Sequential(
    115. Conv(base_channels * 4, base_channels * 8, 3, 2),
    116. C3(base_channels * 8, base_channels * 8, base_depth * 3),
    117. )
    118. #-----------------------------------------------#
    119. # 完成卷积之后,40, 40, 512 -> 20, 20, 1024
    120. # 完成SPP之后,20, 20, 1024 -> 20, 20, 1024
    121. # 完成CSPlayer之后,20, 20, 1024 -> 20, 20, 1024
    122. #-----------------------------------------------#
    123. self.dark5 = nn.Sequential(
    124. Conv(base_channels * 8, base_channels * 16, 3, 2),
    125. SPP(base_channels * 16, base_channels * 16),
    126. C3(base_channels * 16, base_channels * 16, base_depth, shortcut=False),
    127. )
    128. if pretrained:
    129. url = {
    130. 's' : 'https://github.com/bubbliiiing/yolov5-pytorch/releases/download/v1.0/cspdarknet_s_backbone.pth',
    131. 'm' : 'https://github.com/bubbliiiing/yolov5-pytorch/releases/download/v1.0/cspdarknet_m_backbone.pth',
    132. 'l' : 'https://github.com/bubbliiiing/yolov5-pytorch/releases/download/v1.0/cspdarknet_l_backbone.pth',
    133. 'x' : 'https://github.com/bubbliiiing/yolov5-pytorch/releases/download/v1.0/cspdarknet_x_backbone.pth',
    134. }[phi]
    135. checkpoint = torch.hub.load_state_dict_from_url(url=url, map_location="cpu", model_dir="./model_data")
    136. self.load_state_dict(checkpoint, strict=False)
    137. print("Load weights from ", url.split('/')[-1])
    138. def forward(self, x):
    139. x = self.stem(x)
    140. x = self.dark2(x)
    141. #-----------------------------------------------#
    142. # dark3的输出为80, 80, 256,是一个有效特征层
    143. #-----------------------------------------------#
    144. x = self.dark3(x)
    145. feat1 = x
    146. #-----------------------------------------------#
    147. # dark4的输出为40, 40, 512,是一个有效特征层
    148. #-----------------------------------------------#
    149. x = self.dark4(x)
    150. feat2 = x
    151. #-----------------------------------------------#
    152. # dark5的输出为20, 20, 1024,是一个有效特征层
    153. #-----------------------------------------------#
    154. x = self.dark5(x)
    155. feat3 = x
    156. return feat1, feat2, feat3

  • 相关阅读:
    【LeetCode】一文吃透字典树(附例题)
    Matlab论文插图绘制模板第124期—三维气泡图
    【ChatGLM2-6B】在只有CPU的Linux服务器上进行部署
    成功解决OSError: [WinError 1455] 页面文件太小,无法完成操作
    IDEA下新建SpringBoot项目详细步骤
    民安智库(第三方社会评估调研公司)不同客户满意度分析方法应用场景
    物联网如何帮助企业实现环境、社会和治理目标
    git分支
    Redis学习笔记——数据类型
    安装Docker后的一些配置
  • 原文地址:https://blog.csdn.net/qq_46644680/article/details/132643815