text: # Utilities for CoMix
  import os
  import random
  import torch
  import torch.backends.cudnn as cudnn
  import torch.nn.functional as F
  from torch.autograd import Variable
  from models import *
  import torchvision
  import params
  
  
  def print_line():
      print('-'*100)
  
  
  def make_variable(tensor, gpu_id=0, volatile=False):
      if torch.cuda.is_available():
          tensor = tensor.cuda()
      return Variable(tensor, volatile=volatile)
  
  
  def make_cuda(tensor, gpu_id):
      if torch.cuda.is_available():
          tensor = tensor.cuda()
      return tensor
  
  
  def denormalize(x, std, mean):
      """Invert normalization, and then convert array into image."""
      out = x * std + mean
      return out.clamp(0, 1)
  
  def init_weights(layer):
      """Init weights for layers w.r.t. the original paper."""
      layer_name = layer.__class__.__name__
      if layer_name.find("Conv") != -1:
          layer.weight.data.normal_(0.0, 0.02)
      elif layer_name.find("BatchNorm") != -1:
          layer.weight.data.normal_(1.0, 0.02)
          layer.bias.data.fill_(0)
  
  def init_random_seed(manual_seed):
      """Init random seed."""
      seed = None
      if manual_seed is None:
          seed = random.randint(1, 10000)
      else:
          seed = manual_seed
      print("use random seed: {}".format(seed))
      random.seed(seed)
      torch.manual_seed(seed)
      if torch.cuda.is_available():
          torch.cuda.manual_seed_all(seed)
  
  def save_model(net, filename):
      """Save trained model."""
      if not os.path.exists(params.model_root):
          os.makedirs(params.model_root)
      torch.save(net.state_dict(),
                 os.path.join(params.model_root, filename))
      print("save pretrained model to: {}".format(
          os.path.join(params.model_root, filename)))
  