import torch


def scale_batch_per_example(tensor):
  """Scale batch of tensors to range (0, 1)

  Scaling is done by taking the minimum and maximum per channel and example

  Parameters
  ----------
  tensor : torch.Tensor or torch.autograd.Variable
    Tensor of shape BxCxHxW
  """
  b, c, h, w = tensor.shape
  out = tensor.view(b, c, h * w)  # Reshape so that we only need one min/max op
  out = out - torch.min(out, dim=-1, keepdim=True)[0]
  out = out / torch.max(out, dim=-1, keepdim=True)[0]
  return out.clamp(0., 1.).view(b, c, h, w)