layer_libs.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
  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. import os
  15. import paddle
  16. import paddle.nn as nn
  17. import paddle.nn.functional as F
  18. def SyncBatchNorm(*args, **kwargs):
  19. """In cpu environment nn.SyncBatchNorm does not have kernel so use nn.BatchNorm2D instead"""
  20. if paddle.get_device() == 'cpu' or os.environ.get('PADDLESEG_EXPORT_STAGE'):
  21. return nn.BatchNorm2D(*args, **kwargs)
  22. else:
  23. return nn.SyncBatchNorm(*args, **kwargs)
  24. class ConvBNReLU(nn.Layer):
  25. def __init__(self,
  26. in_channels,
  27. out_channels,
  28. kernel_size,
  29. padding='same',
  30. **kwargs):
  31. super().__init__()
  32. self._conv = nn.Conv2D(
  33. in_channels, out_channels, kernel_size, padding=padding, **kwargs)
  34. self._batch_norm = SyncBatchNorm(out_channels)
  35. def forward(self, x):
  36. x = self._conv(x)
  37. x = self._batch_norm(x)
  38. x = F.relu(x)
  39. return x
  40. class ConvBN(nn.Layer):
  41. def __init__(self,
  42. in_channels,
  43. out_channels,
  44. kernel_size,
  45. padding='same',
  46. **kwargs):
  47. super().__init__()
  48. self._conv = nn.Conv2D(
  49. in_channels, out_channels, kernel_size, padding=padding, **kwargs)
  50. self._batch_norm = SyncBatchNorm(out_channels)
  51. def forward(self, x):
  52. x = self._conv(x)
  53. x = self._batch_norm(x)
  54. return x
  55. class ConvReLUPool(nn.Layer):
  56. def __init__(self, in_channels, out_channels):
  57. super().__init__()
  58. self.conv = nn.Conv2D(
  59. in_channels,
  60. out_channels,
  61. kernel_size=3,
  62. stride=1,
  63. padding=1,
  64. dilation=1)
  65. def forward(self, x):
  66. x = self.conv(x)
  67. x = F.relu(x)
  68. x = F.pool2d(x, pool_size=2, pool_type="max", pool_stride=2)
  69. return x
  70. class SeparableConvBNReLU(nn.Layer):
  71. def __init__(self,
  72. in_channels,
  73. out_channels,
  74. kernel_size,
  75. padding='same',
  76. **kwargs):
  77. super().__init__()
  78. self.depthwise_conv = ConvBN(
  79. in_channels,
  80. out_channels=in_channels,
  81. kernel_size=kernel_size,
  82. padding=padding,
  83. groups=in_channels,
  84. **kwargs)
  85. self.piontwise_conv = ConvBNReLU(
  86. in_channels, out_channels, kernel_size=1, groups=1)
  87. def forward(self, x):
  88. x = self.depthwise_conv(x)
  89. x = self.piontwise_conv(x)
  90. return x
  91. class DepthwiseConvBN(nn.Layer):
  92. def __init__(self,
  93. in_channels,
  94. out_channels,
  95. kernel_size,
  96. padding='same',
  97. **kwargs):
  98. super().__init__()
  99. self.depthwise_conv = ConvBN(
  100. in_channels,
  101. out_channels=out_channels,
  102. kernel_size=kernel_size,
  103. padding=padding,
  104. groups=in_channels,
  105. **kwargs)
  106. def forward(self, x):
  107. x = self.depthwise_conv(x)
  108. return x
  109. class AuxLayer(nn.Layer):
  110. """
  111. The auxiliary layer implementation for auxiliary loss.
  112. Args:
  113. in_channels (int): The number of input channels.
  114. inter_channels (int): The intermediate channels.
  115. out_channels (int): The number of output channels, and usually it is num_classes.
  116. dropout_prob (float, optional): The drop rate. Default: 0.1.
  117. """
  118. def __init__(self,
  119. in_channels,
  120. inter_channels,
  121. out_channels,
  122. dropout_prob=0.1):
  123. super().__init__()
  124. self.conv_bn_relu = ConvBNReLU(
  125. in_channels=in_channels,
  126. out_channels=inter_channels,
  127. kernel_size=3,
  128. padding=1)
  129. self.dropout = nn.Dropout(p=dropout_prob)
  130. self.conv = nn.Conv2D(
  131. in_channels=inter_channels,
  132. out_channels=out_channels,
  133. kernel_size=1)
  134. def forward(self, x):
  135. x = self.conv_bn_relu(x)
  136. x = self.dropout(x)
  137. x = self.conv(x)
  138. return x