layer_libs.py 4.7 KB

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