11558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
21558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower#
31558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower# Licensed under the Apache License, Version 2.0 (the "License");
41558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower# you may not use this file except in compliance with the License.
51558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower# You may obtain a copy of the License at
61558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower#
71558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower#     http://www.apache.org/licenses/LICENSE-2.0
81558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower#
91558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower# Unless required by applicable law or agreed to in writing, software
101558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower# distributed under the License is distributed on an "AS IS" BASIS,
111558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower# See the License for the specific language governing permissions and
131558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower# limitations under the License.
141558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower# ==============================================================================
151558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower"""Losses for Gtflow Estimator and Batch Estimator."""
161558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
171558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlowerfrom __future__ import absolute_import
181558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlowerfrom __future__ import division
191558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlowerfrom __future__ import print_function
201558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
211558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlowerfrom tensorflow.python.framework import ops
221558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlowerfrom tensorflow.python.ops import array_ops
231558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlowerfrom tensorflow.python.ops import control_flow_ops
241558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlowerfrom tensorflow.python.ops import math_ops
251558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlowerfrom tensorflow.python.ops import nn
261558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
271558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
281558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlowerdef per_example_logistic_loss(labels, weights, predictions):
291558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  """Logistic loss given labels, example weights and predictions.
301558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
311558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  Args:
321558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    labels: Rank 2 (N, 1) tensor of per-example labels.
331558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    weights: Rank 2 (N, 1) tensor of per-example weights.
341558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    predictions: Rank 2 (N, 1) tensor of per-example predictions.
351558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
361558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  Returns:
371558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    loss: A Rank 2 (N, 1) tensor of per-example logistic loss.
381558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    update_op: An update operation to update the loss's internal state.
391558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  """
401558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  labels = math_ops.to_float(labels)
411558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  unweighted_loss = nn.sigmoid_cross_entropy_with_logits(
421558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower      labels=labels, logits=predictions)
431558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  return unweighted_loss * weights, control_flow_ops.no_op()
441558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
451558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
461558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower# This is classical form of Maximum entropy loss, that is twice differentiable
471558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower# (sparse_softmax_cross_entropy which is what we go for is not twice
481558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower# differentiable).
491558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlowerdef per_example_maxent_loss(labels, weights, logits, num_classes, eps=1e-15):
501558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  """Maximum entropy loss for multiclass problems.
511558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
521558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  Maximum entropy is a generalization of logistic loss for the case when more
531558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  than 2 classes are present.
541558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
551558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  Args:
561558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    labels: Rank 2 (N, 1) or Rank 1 (N) tensor of per-example labels.
571558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    weights: Rank 2 (N, 1) tensor of per-example weights.
581558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    logits: Rank 2 (N, K) tensor of per-example predictions, K - num of
591558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    classes.
601558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    num_classes: number of classes in classification task. Used to expand label
611558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    indices into one-hot encodings.
621558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    eps: tolerance, used as a minimum possible value.
631558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
641558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  Returns:
651558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    loss: A Rank 2 (N, 1) tensor of per-example maxent loss
661558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    update_op: An update operation to update the loss's internal state.
671558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  """
681558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  labels = math_ops.to_int64(labels)
691558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  # If labels are of rank 1, make them rank 2.
701558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  labels_shape = labels.get_shape()
711558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  if len(labels_shape) != 2:
721558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    labels = array_ops.expand_dims(labels, 1)
731558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  # Labels are indices of classes, convert them to one hot encodings.
741558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  target_one_hot = array_ops.one_hot(indices=labels, depth=num_classes)
751558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  labels = math_ops.reduce_sum(
761558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower      input_tensor=target_one_hot, reduction_indices=[1])
771558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  labels = math_ops.to_float(labels)
781558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
791558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  # Calculate softmax probabilities for each class.
801558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  unnormalized_probs = math_ops.exp(logits)
81b9f548d041ba8d66102c6d195e645051f1bee52fYukun Chen  normalizers = math_ops.reduce_sum(unnormalized_probs, 1, keepdims=True)
821558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  softmax_predictions = math_ops.divide(unnormalized_probs,
831558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower                                        math_ops.add(normalizers, eps))
841558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
851558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  # Pull out the probabilities for real label.
861558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  probs_for_real_class = math_ops.reduce_sum(labels * softmax_predictions, 1)
871558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
881558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  # Add handling for values near 0 and 1.
891558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  zeros = array_ops.zeros_like(probs_for_real_class, dtype=logits.dtype) + eps
901558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  one_minus_eps = array_ops.ones_like(
911558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower      probs_for_real_class, dtype=logits.dtype) - eps
921558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
931558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  # Take maximum(eps, pred)
941558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  cond = (probs_for_real_class >= eps)
951558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  probs_for_real_class = array_ops.where(cond, probs_for_real_class, zeros)
961558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
971558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  # Take minimum(1-eps, pred)
981558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  cond = (probs_for_real_class <= 1 - eps)
991558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  probs_for_real_class = array_ops.where(cond, probs_for_real_class,
1001558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower                                         one_minus_eps)
1011558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1021558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  unweighted_loss = array_ops.expand_dims(-math_ops.log(probs_for_real_class),
1031558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower                                          1)
10434a4b21f8f9dea64d3e99a97f639396f2d5556d3A. Unique TensorFlower  if weights is None:
10534a4b21f8f9dea64d3e99a97f639396f2d5556d3A. Unique TensorFlower    return unweighted_loss, control_flow_ops.no_op()
10634a4b21f8f9dea64d3e99a97f639396f2d5556d3A. Unique TensorFlower  else:
10734a4b21f8f9dea64d3e99a97f639396f2d5556d3A. Unique TensorFlower    return unweighted_loss * weights, control_flow_ops.no_op()
1081558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1091558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1101558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlowerdef per_example_squared_loss(labels, weights, predictions):
1111558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  """Squared loss given labels, example weights and predictions.
1121558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1131558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  Args:
1141558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    labels: Rank 2 (N, D) tensor of per-example labels.
1151558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    weights: Rank 2 (N, 1) tensor of per-example weights.
1161558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    predictions: Rank 2 (N, D) tensor of per-example predictions.
1171558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1181558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  Returns:
1191558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    loss: A Rank 2 (N, 1) tensor of per-example squared loss.
1201558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    update_op: An update operation to update the loss's internal state.
1211558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  """
1221558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  unweighted_loss = math_ops.reduce_sum(
123b9f548d041ba8d66102c6d195e645051f1bee52fYukun Chen      math_ops.square(predictions - labels), 1, keepdims=True)
1241558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1251558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  return unweighted_loss * weights, control_flow_ops.no_op()
1261558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1271558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1281558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlowerdef per_example_exp_loss(labels, weights, predictions, name=None, eps=0.1):
1291558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  """Exponential loss given labels, example weights and predictions.
1301558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1311558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  Note that this is only for binary classification.
1321558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  If logistic loss tries to make sure that the classifier is certain of its
1331558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  predictions, exp loss says: "as long as it got it correct, even barely, i
1341558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  don't care". Can be used on noisy data, or when you don't care about getting
1351558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  the actual probabilities from the model, just the correct label.
1361558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1371558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  The loss returns is exp(-targets*modified_predictions), where
1381558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  modified_predictions are 1 if sigmoid is >= 0.5+eps (eg we predict positive
1391558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  class), -1 if sigmoid < 0.5-eps (e.g. we predict negative class) and ax+b in
1401558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  the interval 0.5-eps, 0.5+eps, where a = 1/eps, b=1/(2eps).
1411558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1421558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  Args:
1431558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    labels: Rank 2 (N, D) tensor of per-example labels.
1441558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    weights: Rank 2 (N, 1) tensor of per-example weights.
1451558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    predictions: Rank 2 (N, D) tensor of per-example predictions.
1461558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    name: A name for the operation (optional).
1471558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    eps: For the range (0.5-eps, 0.5+eps) we set the predictions to be ax+b.
1481558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1491558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  Returns:
1501558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    loss: A Rank 2 (N, 1) tensor of per-example exp loss
1511558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    update_op: An update operation to update the loss's internal state.
1521558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  """
1531558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1541558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  def exp_with_logits(name, eps, labels=None, logits=None):
1551558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    """Computes exponential loss given `logits`.
1561558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1571558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    The loss returns is exp(-targets*modified_predictions), where
1581558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    modified_predictions are 1 if sigmoid is >= 0.5+eps (eg we predict positive
1591558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    class), -1 if sigmoid < 0.5-eps (e.g. we predict negative class) and ax+b in
1601558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    the interval 0.5-eps, 0.5+eps, where a = 1/eps, b=1/(2eps).
1611558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1621558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    Args:
1631558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower      name: A name for the operation (optional).
1641558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower      eps: For the range (0.5-eps, 0.5+eps) we set the predictions to be ax+b.
1651558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower      labels: A `Tensor` of the same type and shape as `logits`.
1661558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower      logits: A `Tensor` of type `float32` or `float64`.
1671558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1681558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    Returns:
1691558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower      A `Tensor` of the same shape as `logits` with the componentwise
1701558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower      exponential losses.
1711558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1721558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    Raises:
1731558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower      ValueError: If `logits` and `labels` do not have the same shape.
1741558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    """
1751558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    with ops.name_scope(name, "exp_loss", [logits, labels]) as name:
1761558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower      logits = ops.convert_to_tensor(logits, name="logits")
1771558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower      labels = ops.convert_to_tensor(labels, name="labels")
1781558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower      try:
1791558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower        labels.get_shape().merge_with(logits.get_shape())
1801558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower      except ValueError:
1811558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower        raise ValueError("logits and labels must have the same shape (%s vs %s)"
1821558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower                         % (logits.get_shape(), labels.get_shape()))
1831558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1841558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    # Default threshold to switch between classes
1851558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    zeros = array_ops.zeros_like(logits, dtype=logits.dtype)
1861558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    ones = array_ops.ones_like(logits, dtype=logits.dtype)
1871558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    neg_ones = -array_ops.ones_like(logits, dtype=logits.dtype)
1881558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1891558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    # Convert labels to 1 and -1
1901558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    cond_labels = (labels > zeros)
1911558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    labels_converted = array_ops.where(cond_labels, ones, neg_ones)
1921558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1931558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    # Convert predictions to 1 and -1
1941558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    # The loss we build is min(1, max(-1,ax+b))
1951558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    # where a=1/eps, b=-1/2eps.
1961558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
1971558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    a = 1.0 / eps
1981558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    b = -1.0 / 2 / eps
1991558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    probs = math_ops.sigmoid(logits)
2001558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    y = a * probs + b
2011558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    # Build max(-1, ax+b)
2021558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    cond = (y < -1)
2031558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    max_res = array_ops.where(cond, neg_ones, y)
2041558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    # Build min part
2051558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    cond = (max_res > 1)
2061558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    min_res = array_ops.where(cond, ones, max_res)
2071558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    preds_converted = min_res
2081558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower    return math_ops.exp(-preds_converted * labels_converted)
2091558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower
2101558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  labels = math_ops.to_float(labels)
2111558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  unweighted_loss = exp_with_logits(
2121558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower      name=name, eps=eps, labels=labels, logits=predictions)
2131558c10c8d07c78a58d74d0fcf53c1d2e2505d5eA. Unique TensorFlower  return unweighted_loss * weights, control_flow_ops.no_op()
214