layers_2d.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. """
  2. 通用基础层(2D)。
  3. """
  4. from collections import OrderedDict
  5. import torch
  6. import torch.nn as nn
  7. from timm.layers.drop import DropPath
  8. from timm.layers.mlp import Mlp
  9. from timm.layers.squeeze_excite import SqueezeExcite
  10. from timm.layers.weight_init import trunc_normal_
  11. class Scale(nn.Module):
  12. def __init__(self, dims, init_scale=1.0):
  13. super().__init__()
  14. self.weight = nn.Parameter(torch.ones(*dims) * init_scale)
  15. def forward(self, x):
  16. return self.weight * x
  17. class Residual(nn.Module):
  18. def __init__(self, module, drop=0.0):
  19. super().__init__()
  20. self.module = module
  21. self.drop = drop
  22. def forward(self, x):
  23. if self.training and self.drop > 0.0:
  24. keep = torch.rand(x.size(0), 1, 1, 1, device=x.device)
  25. keep = keep.ge_(self.drop).div(1.0 - self.drop).detach()
  26. return x + self.module(x) * keep
  27. return x + self.module(x)
  28. class FFN2d(nn.Module):
  29. def __init__(self, embed_dim, hidden_dim):
  30. super().__init__()
  31. self.mlp = Mlp(
  32. in_features=embed_dim,
  33. hidden_features=hidden_dim,
  34. out_features=embed_dim,
  35. act_layer=nn.ReLU,
  36. use_conv=True,
  37. bias=False,
  38. )
  39. for m in self.mlp.modules():
  40. if isinstance(m, nn.BatchNorm2d) and m.num_features == embed_dim:
  41. nn.init.constant_(m.weight, 0.0)
  42. nn.init.constant_(m.bias, 0.0)
  43. def forward(self, x):
  44. return self.mlp(x)
  45. class BNLinear1d(nn.Sequential):
  46. def __init__(self, in_features, out_features, bias=True, std=0.02):
  47. bn = nn.BatchNorm1d(in_features)
  48. linear = nn.Linear(in_features, out_features, bias=bias)
  49. trunc_normal_(linear.weight, std=std)
  50. if bias:
  51. nn.init.constant_(linear.bias, 0)
  52. super().__init__(OrderedDict([("bn", bn), ("linear", linear)]))
  53. def _resolve_group_count(num_channels: int, preferred_groups: int = 8) -> int:
  54. groups = min(preferred_groups, num_channels)
  55. while groups > 1 and num_channels % groups != 0:
  56. groups -= 1
  57. return groups
  58. class Conv2dGN(nn.Sequential):
  59. def __init__(
  60. self,
  61. in_channels,
  62. out_channels,
  63. kernel_size=1,
  64. stride=1,
  65. padding=0,
  66. dilation=1,
  67. groups=1,
  68. bn_weight_init=1.0,
  69. ):
  70. conv = nn.Conv2d(
  71. in_channels,
  72. out_channels,
  73. kernel_size,
  74. stride,
  75. padding,
  76. dilation,
  77. groups,
  78. bias=False,
  79. )
  80. gn = nn.GroupNorm(_resolve_group_count(out_channels), out_channels)
  81. nn.init.constant_(gn.weight, bn_weight_init)
  82. nn.init.constant_(gn.bias, 0)
  83. super().__init__(OrderedDict([("conv", conv), ("gn", gn)]))
  84. class DWConv2dGNReLU(nn.Sequential):
  85. def __init__(self, in_channels, out_channels, kernel_size=3, bn_weight_init=1.0):
  86. super().__init__(
  87. OrderedDict(
  88. [
  89. (
  90. "dwconv3x3",
  91. nn.Conv2d(
  92. in_channels,
  93. in_channels,
  94. kernel_size,
  95. 1,
  96. kernel_size // 2,
  97. groups=in_channels,
  98. bias=False,
  99. ),
  100. ),
  101. ("gn1", nn.GroupNorm(_resolve_group_count(in_channels), in_channels)),
  102. ("relu", nn.ReLU(inplace=True)),
  103. (
  104. "dwconv1x1",
  105. nn.Conv2d(
  106. in_channels,
  107. out_channels,
  108. 1,
  109. 1,
  110. 0,
  111. groups=in_channels,
  112. bias=False,
  113. ),
  114. ),
  115. ("gn2", nn.GroupNorm(_resolve_group_count(out_channels), out_channels)),
  116. ]
  117. )
  118. )
  119. for gn_name in ["gn1", "gn2"]:
  120. gn = getattr(self, gn_name)
  121. nn.init.constant_(gn.weight, bn_weight_init)
  122. nn.init.constant_(gn.bias, 0)
  123. class PatchMerging2d(nn.Module):
  124. def __init__(self, dim, out_dim):
  125. super().__init__()
  126. hidden_dim = int(dim * 4)
  127. self.conv1 = Conv2dGN(dim, hidden_dim, 1, 1, 0)
  128. self.act = nn.ReLU(inplace=True)
  129. self.conv2 = Conv2dGN(hidden_dim, hidden_dim, 3, 2, 1, groups=hidden_dim)
  130. self.se = SqueezeExcite(hidden_dim, rd_ratio=0.25)
  131. self.conv3 = Conv2dGN(hidden_dim, out_dim, 1, 1, 0)
  132. def forward(self, x):
  133. return self.conv3(self.se(self.act(self.conv2(self.act(self.conv1(x))))))