code: import torch
  from torch import nn
  from torchvision.models.vgg import vgg16
  
  
  class GeneratorLoss_NEW(nn.Module):
      def __init__(self):
          super(GeneratorLoss_NEW, self).__init__()
          vgg = vgg16(pretrained=True)
          # loss_network = nn.Sequential(*list(vgg.features)[:31]).eval()
          loss_network = nn.Sequential(*list(vgg.features)[:35]).eval()
          for param in loss_network.parameters():
              param.requires_grad = False
          self.loss_network = loss_network
          self.mse_loss = nn.MSELoss()
          self.tv_loss = TVLoss()
          self.charbonnier_loss = L1_Charbonnier_loss()
  
      def forward(self, out_labels, out_images, target_images):
          # Adversarial Loss
          adversarial_loss = torch.mean(1 - out_labels)
          # Perception Loss
          # perception_loss = self.mse_loss(self.loss_network(out_images), self.loss_network(target_images))
          perception_loss = self.charbonnier_loss(self.loss_network(out_images), self.loss_network(target_images))
          # Image Loss
          # image_loss = self.mse_loss(out_images, target_images)
          image_loss = self.charbonnier_loss(out_images, target_images)
          # TV Loss
          tv_loss = self.tv_loss(out_images)
          return image_loss + 0.001 * adversarial_loss + 0.006 * perception_loss + 2e-8 * tv_loss
  
  
  class TVLoss(nn.Module):
      def __init__(self, tv_loss_weight=1):
          super(TVLoss, self).__init__()
          self.tv_loss_weight = tv_loss_weight
  
      def forward(self, x):
          batch_size = x.size()[0]
          h_x = x.size()[2]
          w_x = x.size()[3]
          count_h = self.tensor_size(x[:, :, 1:, :])
          count_w = self.tensor_size(x[:, :, :, 1:])
          h_tv = torch.pow((x[:, :, 1:, :] - x[:, :, :h_x - 1, :]), 2).sum()
          w_tv = torch.pow((x[:, :, :, 1:] - x[:, :, :, :w_x - 1]), 2).sum()
          return self.tv_loss_weight * 2 * (h_tv / count_h + w_tv / count_w) / batch_size
  
      @staticmethod
      def tensor_size(t):
          return t.size()[1] * t.size()[2] * t.size()[3]
  
  
  class L1_Charbonnier_loss(torch.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.mean(error)
          return loss
  
  
  if __name__ == "__main__":
      g_loss = GeneratorLoss_NEW()
      print(g_loss)
  
apis: torch.nn.MSELoss torch.add torch.sqrt torch.mean torch.pow