text: # -*- coding: utf-8 -*-
  """
  @author:XuMing(xuming624@qq.com)
  @description: 
  """
  
  import numpy as np
  import torch
  import torch.nn.functional as F
  from torch import nn
  
  
  class FlattenLayer(torch.nn.Module):
      def forward(self, x):
          return x.view(x.shape[0], -1)
  
  
  class GlobalAvgPool2d(nn.Module):
      def __init__(self):
          super().__init__()
  
      def forward(self, x):
          return F.avg_pool2d(x, kernel_size=x.size()[2:])
  
  
  def get_upsampling_weight(in_channels, out_channels, kernel_size):
      """Make a 2D bilinear kernel suitable for upsampling"""
      factor = (kernel_size + 1) // 2
      if kernel_size % 2 == 1:
          center = factor - 1
      else:
          center = factor - 0.5
      og = np.ogrid[:kernel_size, :kernel_size]
      filt = (1 - abs(og[0] - center) / factor) * (1 - abs(og[1] - center) / factor)
      weight = np.zeros((in_channels, out_channels, kernel_size, kernel_size), dtype=np.float64)
      weight[range(in_channels), range(out_channels), :, :] = filt
      return torch.from_numpy(weight).float()
  
  
  class Conv2DBatchNorm(nn.Module):
      def __init__(
              self,
              in_channels,
              n_filters,
              k_size,
              stride,
              padding,
              bias=True,
              dilation=1,
              is_batchnorm=True,
      ):
          super(Conv2DBatchNorm, self).__init__()
  
          conv_mod = nn.Conv2d(
              int(in_channels),
              int(n_filters),
              kernel_size=k_size,
              padding=padding,
              stride=stride,
              bias=bias,
              dilation=dilation,
          )
  
          if is_batchnorm:
              self.cb_unit = nn.Sequential(conv_mod, nn.BatchNorm2d(int(n_filters)))
          else:
              self.cb_unit = nn.Sequential(conv_mod)
  
      def forward(self, inputs):
          outputs = self.cb_unit(inputs)
          return outputs
  
  
  class Conv2DGroupNorm(nn.Module):
      def __init__(
              self, in_channels, n_filters, k_size, stride, padding, bias=True, dilation=1, n_groups=16
      ):
          super(Conv2DGroupNorm, self).__init__()
  
          conv_mod = nn.Conv2d(
              int(in_channels),
              int(n_filters),
              kernel_size=k_size,
              padding=padding,
              stride=stride,
              bias=bias,
              dilation=dilation,
          )
  
          self.cg_unit = nn.Sequential(conv_mod, nn.GroupNorm(n_groups, int(n_filters)))
  
      def forward(self, inputs):
          outputs = self.cg_unit(inputs)
          return outputs
  
  
  class Deconv2DBatchNorm(nn.Module):
      def __init__(self, in_channels, n_filters, k_size, stride, padding, bias=True):
          super(Deconv2DBatchNorm, self).__init__()
  
          self.dcb_unit = nn.Sequential(
              nn.ConvTranspose2d(
                  int(in_channels),
                  int(n_filters),
                  kernel_size=k_size,
                  padding=padding,
                  stride=stride,
                  bias=bias,
              ),
              nn.BatchNorm2d(int(n_filters)),
          )
  
      def forward(self, inputs):
          outputs = self.dcb_unit(inputs)
          return outputs
  
  
  class Conv2DBatchNormRelu(nn.Module):
      def __init__(
              self,
              in_channels,
              n_filters,
              k_size,
              stride,
              padding,
              bias=True,
              dilation=1,
              is_batchnorm=True,
      ):
          super(Conv2DBatchNormRelu, self).__init__()
  
          conv_mod = nn.Conv2d(
              int(in_channels),
              int(n_filters),
              kernel_size=k_size,
              padding=padding,
              stride=stride,
              bias=bias,
              dilation=dilation,
          )
  
          if is_batchnorm:
              self.cbr_unit = nn.Sequential(
                  conv_mod, nn.BatchNorm2d(int(n_filters)), nn.ReLU(inplace=True)
              )
          else:
              self.cbr_unit = nn.Sequential(conv_mod, nn.ReLU(inplace=True))
  
      def forward(self, inputs):
          outputs = self.cbr_unit(inputs)
          return outputs
  
  
  class Conv2DGroupNormRelu(nn.Module):
      def __init__(
              self, in_channels, n_filters, k_size, stride, padding, bias=True, dilation=1, n_groups=16
      ):
          super(Conv2DGroupNormRelu, self).__init__()
  
          conv_mod = nn.Conv2d(
              int(in_channels),
              int(n_filters),
              kernel_size=k_size,
              padding=padding,
              stride=stride,
              bias=bias,
              dilation=dilation,
          )
  
          self.cgr_unit = nn.Sequential(
              conv_mod, nn.GroupNorm(n_groups, int(n_filters)), nn.ReLU(inplace=True)
          )
  
      def forward(self, inputs):
          outputs = self.cgr_unit(inputs)
          return outputs
  
  
  class Deconv2DBatchNormRelu(nn.Module):
      def __init__(self, in_channels, n_filters, k_size, stride, padding, bias=True):
          super(Deconv2DBatchNormRelu, self).__init__()
  
          self.dcbr_unit = nn.Sequential(
              nn.ConvTranspose2d(
                  int(in_channels),
                  int(n_filters),
                  kernel_size=k_size,
                  padding=padding,
                  stride=stride,
                  bias=bias,
              ),
              nn.BatchNorm2d(int(n_filters)),
              nn.ReLU(inplace=True),
          )
  
      def forward(self, inputs):
          outputs = self.dcbr_unit(inputs)
          return outputs
  