text: import torch
  import torch.nn as nn
  import numpy as np
  import math
  
  
  def get_upsample_filter(size):
      """Make a 2D bilinear kernel suitable for upsampling"""
      factor = (size + 1) // 2
      if size % 2 == 1:
          center = factor - 1
      else:
          center = factor - 0.5
      og = np.ogrid[:size, :size]
      filter = (1 - abs(og[0] - center) / factor) * \
               (1 - abs(og[1] - center) / factor)
      return torch.from_numpy(filter).float()
  
  class small_block(nn.Module):
      def __init__(self, in_channel):
          super(small_block, self).__init__()
          self.cov_block  = nn.Sequential(
              nn.Conv2d(in_channels=in_channel, out_channels=64, kernel_size=3, stride=1, padding=1, bias=False),
              nn.LeakyReLU(0.2, inplace=True),
              nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, stride=1, padding=1, bias=False),
              nn.LeakyReLU(0.2, inplace=True),
              nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, stride=1, padding=1, bias=False),
              nn.LeakyReLU(0.2, inplace=True),
          )
      def forward(self, input):
          output=self.cov_block(input)
          return torch.cat((input,output),1)
  
  class big_block(nn.Module):
      def __init__(self):
          super(big_block,self).__init__()
          convs=[]
          for i in range(3):
              convs.append(small_block(64+64*i))
          self.conv = nn.Sequential(*convs)
          self.neck_layer = nn.Sequential(
              nn.Conv2d(in_channels=64+64*3, out_channels=64, kernel_size=1, stride=1, padding=0, bias=False),
              nn.LeakyReLU(0.2, inplace=True),
          )
          self.construct_layer = nn.Sequential(
              nn.ConvTranspose2d(in_channels=64, out_channels=64, kernel_size=4, stride=2, padding=1, bias=False),
              nn.LeakyReLU(0.2, inplace=True),
          )
      def forward(self, input):
          out=self.conv(input)
          out = self.neck_layer(out)+input
          out = self.construct_layer(out)
          return out
  
  
  class Net(nn.Module):
      def __init__(self):
          super(Net, self).__init__()
  
          self.conv_input = nn.Conv2d(in_channels=1, out_channels=64, kernel_size=3, stride=1, padding=1, bias=False)
          self.relu = nn.LeakyReLU(0.2, inplace=True)
  
          self.convt_I1 = nn.ConvTranspose2d(in_channels=1, out_channels=1, kernel_size=4, stride=2, padding=1,
                                             bias=False)
          self.convt_R1 = nn.Conv2d(in_channels=64, out_channels=1, kernel_size=3, stride=1, padding=1, bias=False)
          self.convt_F1 = self.make_layer(big_block)
  
          self.convt_I2 = nn.ConvTranspose2d(in_channels=1, out_channels=1, kernel_size=4, stride=2, padding=1,
                                             bias=False)
          self.convt_R2 = nn.Conv2d(in_channels=64, out_channels=1, kernel_size=3, stride=1, padding=1, bias=False)
          self.convt_F2 = self.make_layer(big_block)
  
          for m in self.modules():
              if isinstance(m, nn.Conv2d):
                  n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                  m.weight.data.normal_(0, math.sqrt(2. / n))
                  if m.bias is not None:
                      m.bias.data.zero_()
              if isinstance(m, nn.ConvTranspose2d):
                  c1, c2, h, w = m.weight.data.size()
                  weight = get_upsample_filter(h)
                  m.weight.data = weight.view(1, 1, h, w).repeat(c1, c2, 1, 1)
                  if m.bias is not None:
                      m.bias.data.zero_()
  
      def make_layer(self, block):
          layers = []
          layers.append(block())
          return nn.Sequential(*layers)
  
      def forward(self, x):
          out = self.relu(self.conv_input(x))
  
          convt_F1 = self.convt_F1(out)
          convt_I1 = self.convt_I1(x)
          convt_R1 = self.convt_R1(convt_F1)
          HR_2x = convt_I1 + convt_R1
  
          convt_F2 = self.convt_F2(convt_F1)
          convt_I2 = self.convt_I2(HR_2x)
          convt_R2 = self.convt_R2(convt_F2)
          HR_4x = convt_I2 + convt_R2
  
          return HR_2x, HR_4x
  
  
  class L1_Charbonnier_loss(nn.Module):
      """L1 Charbonnierloss."""
  
      def __init__(self):
          super(L1_Charbonnier_loss, self).__init__()
          self.eps = 1e-6
  
      def forward(self, X, Y):
          diff = torch.add(X, -Y)
          error = torch.sqrt(diff * diff + self.eps)
          loss = torch.sum(error)
          return loss