code: def softmax(input_,
              labels=None,
              name=PROVIDED,
              loss_weight=None,
              per_example_weights=None):
    
    if labels is not None:
      # Cache the current layer because we only want softmax to change the head.
      full = input_.as_layer()
      return SoftmaxResult(input_.softmax_activation(),
                           full.cross_entropy(
                               labels,
                               name=name,
                               loss_weight=loss_weight,
                               per_example_weights=per_example_weights))
    else:
      return SoftmaxResult(input_.softmax_activation(), None)
docs: Applies softmax and if labels is not None, then it also adds a loss.
  
    Args:
      input_: A rank 2 Tensor or a Pretty Tensor holding the logits.
      labels: The target labels to learn as a float tensor.  Use None to not
        include a training loss.
      name: The optional name.
      loss_weight: A scalar multiplier for the loss.
      per_example_weights: A Tensor with a weight per example.
    Returns:
      A tuple of the a handle to softmax and a handle to the loss tensor.
    Raises:
      ValueError: If the datatype is wrong.