text: # Copyright (c) SenseTime. All Rights Reserved.
  
  from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from __future__ import unicode_literals
  
  import torch
  import torch.nn.functional as F
  
  
  def get_cls_loss(pred, label, select):
      if len(select.size()) == 0 or \
              select.size() == torch.Size([0]):
          return 0
      pred = torch.index_select(pred, 0, select)
      label = torch.index_select(label, 0, select)
      return F.nll_loss(pred, label)
  
  
  def select_cross_entropy_loss(pred, label):
      pred = pred.view(-1, 2)
      label = label.view(-1)
      pos = label.data.eq(1).nonzero().squeeze().cuda()
      neg = label.data.eq(0).nonzero().squeeze().cuda()
      loss_pos = get_cls_loss(pred, label, pos)
      loss_neg = get_cls_loss(pred, label, neg)
      return loss_pos * 0.5 + loss_neg * 0.5
  
  
  def weight_l1_loss(pred_loc, label_loc, loss_weight):
      b, _, sh, sw = pred_loc.size()
      pred_loc = pred_loc.view(b, 4, -1, sh, sw) # torch.Size([28, 4, 5, 25, 25])
      diff = (pred_loc - label_loc).abs()
      diff = diff.sum(dim=1).view(b, -1, sh, sw)
      loss = diff * loss_weight
      return loss.sum().div(b)
  