rf_adaptor.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. # copyright (c) 2022 PaddlePaddle Authors. All Rights Reserve.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. """
  15. This code is refer from:
  16. https://github.com/hikopensource/DAVAR-Lab-OCR/blob/main/davarocr/davar_rcg/models/connects/single_block/RFAdaptor.py
  17. """
  18. import paddle
  19. import paddle.nn as nn
  20. from paddle.nn.initializer import TruncatedNormal, Constant, Normal, KaimingNormal
  21. kaiming_init_ = KaimingNormal()
  22. zeros_ = Constant(value=0.0)
  23. ones_ = Constant(value=1.0)
  24. class S2VAdaptor(nn.Layer):
  25. """Semantic to Visual adaptation module"""
  26. def __init__(self, in_channels=512):
  27. super(S2VAdaptor, self).__init__()
  28. self.in_channels = in_channels # 512
  29. # feature strengthen module, channel attention
  30. self.channel_inter = nn.Linear(
  31. self.in_channels, self.in_channels, bias_attr=False
  32. )
  33. self.channel_bn = nn.BatchNorm1D(self.in_channels)
  34. self.channel_act = nn.ReLU()
  35. self.apply(self.init_weights)
  36. def init_weights(self, m):
  37. if isinstance(m, nn.Conv2D):
  38. kaiming_init_(m.weight)
  39. if isinstance(m, nn.Conv2D) and m.bias is not None:
  40. zeros_(m.bias)
  41. elif isinstance(m, (nn.BatchNorm, nn.BatchNorm2D, nn.BatchNorm1D)):
  42. zeros_(m.bias)
  43. ones_(m.weight)
  44. def forward(self, semantic):
  45. semantic_source = semantic # batch, channel, height, width
  46. # feature transformation
  47. semantic = semantic.squeeze(2).transpose([0, 2, 1]) # batch, width, channel
  48. channel_att = self.channel_inter(semantic) # batch, width, channel
  49. channel_att = channel_att.transpose([0, 2, 1]) # batch, channel, width
  50. channel_bn = self.channel_bn(channel_att) # batch, channel, width
  51. channel_att = self.channel_act(channel_bn) # batch, channel, width
  52. # Feature enhancement
  53. channel_output = semantic_source * channel_att.unsqueeze(
  54. -2
  55. ) # batch, channel, 1, width
  56. return channel_output
  57. class V2SAdaptor(nn.Layer):
  58. """Visual to Semantic adaptation module"""
  59. def __init__(self, in_channels=512, return_mask=False):
  60. super(V2SAdaptor, self).__init__()
  61. # parameter initialization
  62. self.in_channels = in_channels
  63. self.return_mask = return_mask
  64. # output transformation
  65. self.channel_inter = nn.Linear(
  66. self.in_channels, self.in_channels, bias_attr=False
  67. )
  68. self.channel_bn = nn.BatchNorm1D(self.in_channels)
  69. self.channel_act = nn.ReLU()
  70. def forward(self, visual):
  71. # Feature enhancement
  72. visual = visual.squeeze(2).transpose([0, 2, 1]) # batch, width, channel
  73. channel_att = self.channel_inter(visual) # batch, width, channel
  74. channel_att = channel_att.transpose([0, 2, 1]) # batch, channel, width
  75. channel_bn = self.channel_bn(channel_att) # batch, channel, width
  76. channel_att = self.channel_act(channel_bn) # batch, channel, width
  77. # size alignment
  78. channel_output = channel_att.unsqueeze(-2) # batch, width, channel
  79. if self.return_mask:
  80. return channel_output, channel_att
  81. return channel_output
  82. class RFAdaptor(nn.Layer):
  83. def __init__(self, in_channels=512, use_v2s=True, use_s2v=True, **kwargs):
  84. super(RFAdaptor, self).__init__()
  85. if use_v2s is True:
  86. self.neck_v2s = V2SAdaptor(in_channels=in_channels, **kwargs)
  87. else:
  88. self.neck_v2s = None
  89. if use_s2v is True:
  90. self.neck_s2v = S2VAdaptor(in_channels=in_channels, **kwargs)
  91. else:
  92. self.neck_s2v = None
  93. self.out_channels = in_channels
  94. def forward(self, x):
  95. visual_feature, rcg_feature = x
  96. if visual_feature is not None:
  97. (
  98. batch,
  99. source_channels,
  100. v_source_height,
  101. v_source_width,
  102. ) = visual_feature.shape
  103. visual_feature = visual_feature.reshape(
  104. [batch, source_channels, 1, v_source_height * v_source_width]
  105. )
  106. if self.neck_v2s is not None:
  107. v_rcg_feature = rcg_feature * self.neck_v2s(visual_feature)
  108. else:
  109. v_rcg_feature = rcg_feature
  110. if self.neck_s2v is not None:
  111. v_visual_feature = visual_feature + self.neck_s2v(rcg_feature)
  112. else:
  113. v_visual_feature = visual_feature
  114. if v_rcg_feature is not None:
  115. batch, source_channels, source_height, source_width = v_rcg_feature.shape
  116. v_rcg_feature = v_rcg_feature.reshape(
  117. [batch, source_channels, 1, source_height * source_width]
  118. )
  119. v_rcg_feature = v_rcg_feature.squeeze(2).transpose([0, 2, 1])
  120. return v_visual_feature, v_rcg_feature