retinaface_net.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. import torch
  2. import torch.nn as nn
  3. import torch.nn.functional as F
  4. def conv_bn(inp, oup, stride=1, leaky=0):
  5. return nn.Sequential(
  6. nn.Conv2d(inp, oup, 3, stride, 1, bias=False),
  7. nn.BatchNorm2d(oup),
  8. nn.LeakyReLU(negative_slope=leaky, inplace=True),
  9. )
  10. def conv_bn_no_relu(inp, oup, stride):
  11. return nn.Sequential(
  12. nn.Conv2d(inp, oup, 3, stride, 1, bias=False),
  13. nn.BatchNorm2d(oup),
  14. )
  15. def conv_bn1X1(inp, oup, stride, leaky=0):
  16. return nn.Sequential(
  17. nn.Conv2d(inp, oup, 1, stride, padding=0, bias=False),
  18. nn.BatchNorm2d(oup),
  19. nn.LeakyReLU(negative_slope=leaky, inplace=True),
  20. )
  21. def conv_dw(inp, oup, stride, leaky=0.1):
  22. return nn.Sequential(
  23. nn.Conv2d(inp, inp, 3, stride, 1, groups=inp, bias=False),
  24. nn.BatchNorm2d(inp),
  25. nn.LeakyReLU(negative_slope=leaky, inplace=True),
  26. nn.Conv2d(inp, oup, 1, 1, 0, bias=False),
  27. nn.BatchNorm2d(oup),
  28. nn.LeakyReLU(negative_slope=leaky, inplace=True),
  29. )
  30. class SSH(nn.Module):
  31. def __init__(self, in_channel, out_channel):
  32. super(SSH, self).__init__()
  33. assert out_channel % 4 == 0
  34. leaky = 0
  35. if out_channel <= 64:
  36. leaky = 0.1
  37. self.conv3X3 = conv_bn_no_relu(in_channel, out_channel // 2, stride=1)
  38. self.conv5X5_1 = conv_bn(in_channel, out_channel // 4, stride=1, leaky=leaky)
  39. self.conv5X5_2 = conv_bn_no_relu(out_channel // 4, out_channel // 4, stride=1)
  40. self.conv7X7_2 = conv_bn(
  41. out_channel // 4, out_channel // 4, stride=1, leaky=leaky
  42. )
  43. self.conv7x7_3 = conv_bn_no_relu(out_channel // 4, out_channel // 4, stride=1)
  44. def forward(self, input):
  45. conv3X3 = self.conv3X3(input)
  46. conv5X5_1 = self.conv5X5_1(input)
  47. conv5X5 = self.conv5X5_2(conv5X5_1)
  48. conv7X7_2 = self.conv7X7_2(conv5X5_1)
  49. conv7X7 = self.conv7x7_3(conv7X7_2)
  50. out = torch.cat([conv3X3, conv5X5, conv7X7], dim=1)
  51. out = F.relu(out)
  52. return out
  53. class FPN(nn.Module):
  54. def __init__(self, in_channels_list, out_channels):
  55. super(FPN, self).__init__()
  56. leaky = 0
  57. if out_channels <= 64:
  58. leaky = 0.1
  59. self.output1 = conv_bn1X1(
  60. in_channels_list[0], out_channels, stride=1, leaky=leaky
  61. )
  62. self.output2 = conv_bn1X1(
  63. in_channels_list[1], out_channels, stride=1, leaky=leaky
  64. )
  65. self.output3 = conv_bn1X1(
  66. in_channels_list[2], out_channels, stride=1, leaky=leaky
  67. )
  68. self.merge1 = conv_bn(out_channels, out_channels, leaky=leaky)
  69. self.merge2 = conv_bn(out_channels, out_channels, leaky=leaky)
  70. def forward(self, input):
  71. # names = list(input.keys())
  72. # input = list(input.values())
  73. output1 = self.output1(input[0])
  74. output2 = self.output2(input[1])
  75. output3 = self.output3(input[2])
  76. up3 = F.interpolate(
  77. output3, size=[output2.size(2), output2.size(3)], mode="nearest"
  78. )
  79. output2 = output2 + up3
  80. output2 = self.merge2(output2)
  81. up2 = F.interpolate(
  82. output2, size=[output1.size(2), output1.size(3)], mode="nearest"
  83. )
  84. output1 = output1 + up2
  85. output1 = self.merge1(output1)
  86. out = [output1, output2, output3]
  87. return out
  88. class MobileNetV1(nn.Module):
  89. def __init__(self):
  90. super(MobileNetV1, self).__init__()
  91. self.stage1 = nn.Sequential(
  92. conv_bn(3, 8, 2, leaky=0.1), # 3
  93. conv_dw(8, 16, 1), # 7
  94. conv_dw(16, 32, 2), # 11
  95. conv_dw(32, 32, 1), # 19
  96. conv_dw(32, 64, 2), # 27
  97. conv_dw(64, 64, 1), # 43
  98. )
  99. self.stage2 = nn.Sequential(
  100. conv_dw(64, 128, 2), # 43 + 16 = 59
  101. conv_dw(128, 128, 1), # 59 + 32 = 91
  102. conv_dw(128, 128, 1), # 91 + 32 = 123
  103. conv_dw(128, 128, 1), # 123 + 32 = 155
  104. conv_dw(128, 128, 1), # 155 + 32 = 187
  105. conv_dw(128, 128, 1), # 187 + 32 = 219
  106. )
  107. self.stage3 = nn.Sequential(
  108. conv_dw(128, 256, 2), # 219 +3 2 = 241
  109. conv_dw(256, 256, 1), # 241 + 64 = 301
  110. )
  111. self.avg = nn.AdaptiveAvgPool2d((1, 1))
  112. self.fc = nn.Linear(256, 1000)
  113. def forward(self, x):
  114. x = self.stage1(x)
  115. x = self.stage2(x)
  116. x = self.stage3(x)
  117. x = self.avg(x)
  118. # x = self.model(x)
  119. x = x.view(-1, 256)
  120. x = self.fc(x)
  121. return x
  122. class ClassHead(nn.Module):
  123. def __init__(self, inchannels=512, num_anchors=3):
  124. super(ClassHead, self).__init__()
  125. self.num_anchors = num_anchors
  126. self.conv1x1 = nn.Conv2d(
  127. inchannels, self.num_anchors * 2, kernel_size=(1, 1), stride=1, padding=0
  128. )
  129. def forward(self, x):
  130. out = self.conv1x1(x)
  131. out = out.permute(0, 2, 3, 1).contiguous()
  132. return out.view(out.shape[0], -1, 2)
  133. class BboxHead(nn.Module):
  134. def __init__(self, inchannels=512, num_anchors=3):
  135. super(BboxHead, self).__init__()
  136. self.conv1x1 = nn.Conv2d(
  137. inchannels, num_anchors * 4, kernel_size=(1, 1), stride=1, padding=0
  138. )
  139. def forward(self, x):
  140. out = self.conv1x1(x)
  141. out = out.permute(0, 2, 3, 1).contiguous()
  142. return out.view(out.shape[0], -1, 4)
  143. class LandmarkHead(nn.Module):
  144. def __init__(self, inchannels=512, num_anchors=3):
  145. super(LandmarkHead, self).__init__()
  146. self.conv1x1 = nn.Conv2d(
  147. inchannels, num_anchors * 10, kernel_size=(1, 1), stride=1, padding=0
  148. )
  149. def forward(self, x):
  150. out = self.conv1x1(x)
  151. out = out.permute(0, 2, 3, 1).contiguous()
  152. return out.view(out.shape[0], -1, 10)
  153. def make_class_head(fpn_num=3, inchannels=64, anchor_num=2):
  154. classhead = nn.ModuleList()
  155. for i in range(fpn_num):
  156. classhead.append(ClassHead(inchannels, anchor_num))
  157. return classhead
  158. def make_bbox_head(fpn_num=3, inchannels=64, anchor_num=2):
  159. bboxhead = nn.ModuleList()
  160. for i in range(fpn_num):
  161. bboxhead.append(BboxHead(inchannels, anchor_num))
  162. return bboxhead
  163. def make_landmark_head(fpn_num=3, inchannels=64, anchor_num=2):
  164. landmarkhead = nn.ModuleList()
  165. for i in range(fpn_num):
  166. landmarkhead.append(LandmarkHead(inchannels, anchor_num))
  167. return landmarkhead