예제 #1
0
 def test_loss_fn_arg_invalid(self):
   def _loss_fn(labels, logits, name=None):
     del labels, logits, name  # Unused
   with self.assertRaisesRegexp(
       ValueError,
       r'loss_fn has unexpected args: \[\'name\'\]'):
     head_lib.multi_label_head(n_classes=3, loss_fn=_loss_fn)
예제 #2
0
 def test_loss_fn_arg_logits_missing(self):
   def _loss_fn(labels):
     del labels  # unused
   with self.assertRaisesRegexp(
       ValueError,
       r'loss_fn must contain argument: logits\. '
       r'Given arguments: \(\'labels\',\)'):
     head_lib.multi_label_head(n_classes=3, loss_fn=_loss_fn)
예제 #3
0
 def test_head_weights_wrong_size(self):
   head1 = head_lib.multi_label_head(n_classes=2, name='head1')
   head2 = head_lib.multi_label_head(n_classes=3, name='head2')
   with self.assertRaisesRegexp(
       ValueError,
       r'heads and head_weights must have the same size\. '
       r'Given len\(heads\): 2. Given len\(head_weights\): 1\.'):
     multi_head_lib.multi_head([head1, head2], head_weights=[1.])
예제 #4
0
 def test_invalid_loss_reduction(self):
   with self.assertRaisesRegexp(
       ValueError, r'Invalid loss_reduction: invalid_loss_reduction'):
     head_lib.multi_label_head(
         n_classes=3, loss_reduction='invalid_loss_reduction')
   with self.assertRaisesRegexp(
       ValueError, r'Invalid loss_reduction: none'):
     head_lib.multi_label_head(
         n_classes=3, loss_reduction=losses.Reduction.NONE)
예제 #5
0
  def test_predict_two_heads_logits_tensor(self):
    """Tests predict with logits as Tensor."""
    head1 = head_lib.multi_label_head(n_classes=2, name='head1')
    head2 = head_lib.multi_label_head(n_classes=3, name='head2')
    multi_head = multi_head_lib.multi_head([head1, head2])

    logits = np.array(
        [[-1., 1., 2., -2., 2.], [-1.5, 1., -3., 2., -2.]], dtype=np.float32)
    expected_logits1 = np.array([[-1., 1.], [-1.5, 1.]], dtype=np.float32)
    expected_logits2 = np.array([[2., -2., 2.], [-3., 2., -2.]],
                                dtype=np.float32)
    expected_probabilities = {
        'head1': _sigmoid(expected_logits1),
        'head2': _sigmoid(expected_logits2),
    }

    spec = multi_head.create_estimator_spec(
        features={'x': np.array(((42,),), dtype=np.int32)},
        mode=model_fn.ModeKeys.PREDICT,
        logits=logits)

    self.assertItemsEqual(
        (_DEFAULT_SERVING_KEY, 'head1', 'classification/head1', 'predict/head1',
         'head2', 'classification/head2', 'predict/head2'),
        spec.export_outputs.keys())

    # Assert predictions and export_outputs.
    with self.test_session() as sess:
      _initialize_variables(self, spec.scaffold)
      self.assertIsNone(spec.scaffold.summary_op)
      predictions = sess.run(spec.predictions)
      self.assertAllClose(
          expected_logits1,
          predictions[('head1', prediction_keys.PredictionKeys.LOGITS)])
      self.assertAllClose(
          expected_logits2,
          predictions[('head2', prediction_keys.PredictionKeys.LOGITS)])
      self.assertAllClose(
          expected_probabilities['head1'],
          predictions[('head1', prediction_keys.PredictionKeys.PROBABILITIES)])
      self.assertAllClose(
          expected_probabilities['head2'],
          predictions[('head2', prediction_keys.PredictionKeys.PROBABILITIES)])

      self.assertAllClose(
          expected_probabilities['head1'],
          sess.run(spec.export_outputs[_DEFAULT_SERVING_KEY].scores))
      self.assertAllClose(
          expected_probabilities['head1'],
          sess.run(spec.export_outputs['head1'].scores))
      self.assertAllClose(
          expected_probabilities['head2'],
          sess.run(spec.export_outputs['head2'].scores))
예제 #6
0
  def test_predict_two_heads_logits_tensor(self):
    """Tests predict with logits as Tensor."""
    head1 = head_lib.multi_label_head(n_classes=2, name='head1')
    head2 = head_lib.multi_label_head(n_classes=3, name='head2')
    multi_head = multi_head_lib.multi_head([head1, head2])

    logits = np.array(
        [[-1., 1., 2., -2., 2.], [-1.5, 1., -3., 2., -2.]], dtype=np.float32)
    expected_logits1 = np.array([[-1., 1.], [-1.5, 1.]], dtype=np.float32)
    expected_logits2 = np.array([[2., -2., 2.], [-3., 2., -2.]],
                                dtype=np.float32)
    expected_probabilities = {
        'head1': _sigmoid(expected_logits1),
        'head2': _sigmoid(expected_logits2),
    }

    spec = multi_head.create_estimator_spec(
        features={'x': np.array(((42,),), dtype=np.int32)},
        mode=model_fn.ModeKeys.PREDICT,
        logits=logits)

    self.assertItemsEqual(
        (_DEFAULT_SERVING_KEY, 'predict', 'head1', 'classification/head1',
         'predict/head1', 'head2', 'classification/head2', 'predict/head2'),
        spec.export_outputs.keys())

    # Assert predictions and export_outputs.
    with self.test_session() as sess:
      _initialize_variables(self, spec.scaffold)
      self.assertIsNone(spec.scaffold.summary_op)
      predictions = sess.run(spec.predictions)
      self.assertAllClose(
          expected_logits1,
          predictions[('head1', prediction_keys.PredictionKeys.LOGITS)])
      self.assertAllClose(
          expected_logits2,
          predictions[('head2', prediction_keys.PredictionKeys.LOGITS)])
      self.assertAllClose(
          expected_probabilities['head1'],
          predictions[('head1', prediction_keys.PredictionKeys.PROBABILITIES)])
      self.assertAllClose(
          expected_probabilities['head2'],
          predictions[('head2', prediction_keys.PredictionKeys.PROBABILITIES)])

      self.assertAllClose(
          expected_probabilities['head1'],
          sess.run(spec.export_outputs[_DEFAULT_SERVING_KEY].scores))
      self.assertAllClose(
          expected_probabilities['head1'],
          sess.run(spec.export_outputs['head1'].scores))
      self.assertAllClose(
          expected_probabilities['head2'],
          sess.run(spec.export_outputs['head2'].scores))
예제 #7
0
    def test_train_create_loss_two_heads_with_weights(self):
        # Use different example weighting for each head weighting.
        weights1 = np.array([[1.], [2.]], dtype=np.float32)
        weights2 = np.array([[2.], [3.]])
        head1 = head_lib.multi_label_head(n_classes=2,
                                          name='head1',
                                          weight_column='weights1')
        head2 = head_lib.multi_label_head(n_classes=3,
                                          name='head2',
                                          weight_column='weights2')
        multi_head = multi_head_lib.multi_head([head1, head2],
                                               head_weights=[1., 2.])

        logits = {
            'head1':
            np.array([[-10., 10.], [-15., 10.]], dtype=np.float32),
            'head2':
            np.array([[20., -20., 20.], [-30., 20., -20.]], dtype=np.float32),
        }
        labels = {
            'head1': np.array([[1, 0], [1, 1]], dtype=np.int64),
            'head2': np.array([[0, 1, 0], [1, 1, 0]], dtype=np.int64),
        }
        weighted_sum_loss, example_weight_sum, _ = multi_head.create_loss(
            features={
                'x': np.array(((42, ), ), dtype=np.int32),
                'weights1': weights1,
                'weights2': weights2
            },
            mode=model_fn.ModeKeys.TRAIN,
            logits=logits,
            labels=labels)
        tol = 1e-3
        with self.test_session():
            # loss of the first head is [[(10 + 10) / 2], [(15 + 0) / 2]]
            # = [10, 7.5]
            # weighted_sum_loss = 1 * 10 + 2 * 7.5 = 25
            # loss of the second head is [[(20 + 20 + 20) / 3], [(30 + 0 + 0) / 3]]
            # = [20, 10]
            # weighted_sum_loss = 2 * 20 + 3 * 10 = 70
            # head-weighted merge = 1 * 25 + 2 * 70 = 165
            self.assertAllClose(165,
                                weighted_sum_loss.eval(),
                                rtol=tol,
                                atol=tol)
            # example_weight_sum = 1 * (1 + 2) + 2 * (2 + 3) = 13
            self.assertAllClose(13.,
                                example_weight_sum.eval(),
                                rtol=tol,
                                atol=tol)
예제 #8
0
  def test_train_create_loss_two_heads_with_weights(self):
    # Use different example weighting for each head weighting.
    weights1 = np.array([[1.], [2.]], dtype=np.float32)
    weights2 = np.array([[2.], [3.]])
    head1 = head_lib.multi_label_head(n_classes=2, name='head1',
                                      weight_column='weights1')
    head2 = head_lib.multi_label_head(n_classes=3, name='head2',
                                      weight_column='weights2')
    multi_head = multi_head_lib.multi_head(
        [head1, head2], head_weights=[1., 2.])

    logits = {
        'head1': np.array([[-10., 10.], [-15., 10.]], dtype=np.float32),
        'head2': np.array([[20., -20., 20.], [-30., 20., -20.]],
                          dtype=np.float32),
    }
    labels = {
        'head1': np.array([[1, 0], [1, 1]], dtype=np.int64),
        'head2': np.array([[0, 1, 0], [1, 1, 0]], dtype=np.int64),
    }
    training_loss, unreduced_losses, weights, _ = multi_head.create_loss(
        features={
            'x': np.array(((42,),), dtype=np.int32),
            'weights1': weights1,
            'weights2': weights2
        },
        mode=model_fn.ModeKeys.TRAIN,
        logits=logits,
        labels=labels)
    tol = 1e-3
    with self.cached_session():
      # loss of the first head is [[(10 + 10) / 2], [(15 + 0) / 2]]
      # = [10, 7.5]
      # training_loss = (1 * 10 + 2 * 7.5) / 2 = 12.5
      # head-weighted unreduced_loss = 1 * [10, 7.5]
      self.assertAllClose(
          [[10.], [7.5]], unreduced_losses['head1'].eval(), rtol=tol, atol=tol)
      # loss of the second head is [[(20 + 20 + 20) / 3], [(30 + 0 + 0) / 3]]
      # = [20, 10]
      # training_loss = (2 * 20 + 3 * 10) / 2 = 35
      # head-weighted unreduced_loss = 2 * [20, 10]
      self.assertAllClose(
          [[40.], [20.]], unreduced_losses['head2'].eval(), rtol=tol, atol=tol)
      # head-weighted training_loss = 1 * 12.5 + 2 * 35 = 82.5
      self.assertAllClose(82.5, training_loss.eval(), rtol=tol, atol=tol)
      # head-weighted example weights
      self.assertAllClose(
          [[1.], [2.]], weights['head1'].eval(), rtol=tol, atol=tol)
      self.assertAllClose(
          [[4.], [6.]], weights['head2'].eval(), rtol=tol, atol=tol)
예제 #9
0
  def test_train_create_loss_two_heads_with_weights(self):
    # Use different example weighting for each head weighting.
    weights1 = np.array([[1.], [2.]], dtype=np.float32)
    weights2 = np.array([[2.], [3.]])
    head1 = head_lib.multi_label_head(n_classes=2, name='head1',
                                      weight_column='weights1')
    head2 = head_lib.multi_label_head(n_classes=3, name='head2',
                                      weight_column='weights2')
    multi_head = multi_head_lib.multi_head(
        [head1, head2], head_weights=[1., 2.])

    logits = {
        'head1': np.array([[-10., 10.], [-15., 10.]], dtype=np.float32),
        'head2': np.array([[20., -20., 20.], [-30., 20., -20.]],
                          dtype=np.float32),
    }
    labels = {
        'head1': np.array([[1, 0], [1, 1]], dtype=np.int64),
        'head2': np.array([[0, 1, 0], [1, 1, 0]], dtype=np.int64),
    }
    training_loss, unreduced_losses, weights, _ = multi_head.create_loss(
        features={
            'x': np.array(((42,),), dtype=np.int32),
            'weights1': weights1,
            'weights2': weights2
        },
        mode=model_fn.ModeKeys.TRAIN,
        logits=logits,
        labels=labels)
    tol = 1e-3
    with self.test_session():
      # loss of the first head is [[(10 + 10) / 2], [(15 + 0) / 2]]
      # = [10, 7.5]
      # training_loss = (1 * 10 + 2 * 7.5) / 2 = 12.5
      # head-weighted unreduced_loss = 1 * [10, 7.5]
      self.assertAllClose(
          [[10.], [7.5]], unreduced_losses['head1'].eval(), rtol=tol, atol=tol)
      # loss of the second head is [[(20 + 20 + 20) / 3], [(30 + 0 + 0) / 3]]
      # = [20, 10]
      # training_loss = (2 * 20 + 3 * 10) / 2 = 35
      # head-weighted unreduced_loss = 2 * [20, 10]
      self.assertAllClose(
          [[40.], [20.]], unreduced_losses['head2'].eval(), rtol=tol, atol=tol)
      # head-weighted training_loss = 1 * 12.5 + 2 * 35 = 82.5
      self.assertAllClose(82.5, training_loss.eval(), rtol=tol, atol=tol)
      # head-weighted example weights
      self.assertAllClose(
          [[1.], [2.]], weights['head1'].eval(), rtol=tol, atol=tol)
      self.assertAllClose(
          [[4.], [6.]], weights['head2'].eval(), rtol=tol, atol=tol)
예제 #10
0
  def test_multi_dim_weights_wrong_outer_dim(self):
    """Logits and labels of shape [2, 2, 3], weights [2, 2, 3]."""
    head = head_lib.multi_label_head(n_classes=3, weight_column='weights')

    logits = np.array([[[-10., 10., -10.], [10., -10., 10.]],
                       [[-12., 12., -12.], [12., -12., 12.]]], dtype=np.float32)
    labels = np.array([[[1, 0, 0], [1, 0, 0]],
                       [[0, 1, 1], [0, 1, 1]]], dtype=np.int64)
    weights = np.array([[[1., 1., 1.], [1.5, 1.5, 1.5]],
                        [[2., 2., 2.], [2.5, 2.5, 2.5]]], dtype=np.float32)
    weights_placeholder = array_ops.placeholder(dtype=dtypes.float32)
    def _train_op_fn(loss):
      del loss
      return control_flow_ops.no_op()

    spec = head.create_estimator_spec(
        features={'weights': weights_placeholder},
        mode=model_fn.ModeKeys.TRAIN,
        logits=logits,
        labels=labels,
        train_op_fn=_train_op_fn)
    with self.test_session():
      _initialize_variables(self, monitored_session.Scaffold())
      with self.assertRaisesRegexp(
          errors.InvalidArgumentError,
          r'\[logits_shape: \] \[2 2 3\] \[weights_shape: \] \[2 2 3\]'):
        spec.loss.eval({weights_placeholder: weights})
예제 #11
0
  def test_multi_dim_weighted_train(self):
    """Logits and labels of shape [2, 2, 3], weights [2, 2]."""
    head = head_lib.multi_label_head(n_classes=3, weight_column='weights')

    logits = np.array([[[-10., 10., -10.], [10., -10., 10.]],
                       [[-12., 12., -12.], [12., -12., 12.]]], dtype=np.float32)
    labels = np.array([[[1, 0, 0], [1, 0, 0]],
                       [[0, 1, 1], [0, 1, 1]]], dtype=np.int64)
    weights = np.array([[1., 1.5], [2., 2.5]], dtype=np.float32)
    # loss = [[10 + 10 + 0, 0 + 0 + 10], [0 + 0 + 12, 12 + 12 + 0]] / 3
    #      = [[20/3, 10/3], [4, 8]]
    # weighted_sum_loss = 1*20/3 + 1.5*10/3 + 2*4 + 2.5*8 = 39.6667
    expected_loss = 39.6667
    expected_train_result = 'my_train_op'
    def _train_op_fn(loss):
      return string_ops.string_join(
          [constant_op.constant(expected_train_result),
           string_ops.as_string(loss, precision=3)])

    spec = head.create_estimator_spec(
        features={'weights': weights},
        mode=model_fn.ModeKeys.TRAIN,
        logits=logits,
        labels=labels,
        train_op_fn=_train_op_fn)

    atol = 1.e-3
    with self.test_session() as sess:
      _initialize_variables(self, monitored_session.Scaffold())
      loss, train_result = sess.run((spec.loss, spec.train_op))
      self.assertAllClose(expected_loss, loss, atol=atol)
      self.assertEqual(
          six.b('{0:s}{1:.3f}'.format(expected_train_result, expected_loss)),
          train_result)
예제 #12
0
  def test_multi_dim_weighted_train_create_loss(self):
    """Logits and labels of shape [2, 2, 3], weights [2, 2]."""
    head = head_lib.multi_label_head(n_classes=3, weight_column='weights')

    logits = np.array([[[-10., 10., -10.], [10., -10., 10.]],
                       [[-12., 12., -12.], [12., -12., 12.]]], dtype=np.float32)
    labels = np.array([[[1, 0, 0], [1, 0, 0]],
                       [[0, 1, 1], [0, 1, 1]]], dtype=np.int64)
    weights = np.array([[1., 1.5], [2., 2.5]], dtype=np.float32)
    # unreduced_loss =
    #     [[10 + 10 + 0, 0 + 0 + 10], [0 + 0 + 12, 12 + 12 + 0]] / 3
    #   = [[20/3, 10/3], [4, 8]]
    expected_unreduced_loss = [[[20./3.], [10./3.]], [[4.], [8.]]]
    # weights are reshaped to [2, 2, 1] to match logits.
    expected_weights = [[[1.], [1.5]], [[2.], [2.5]]]
    # weighted_sum_loss = 1*20/3 + 1.5*10/3 + 2*4 + 2.5*8 = 39.6667
    expected_training_loss = 39.6667
    training_loss, unreduced_loss, actual_weights, _ = head.create_loss(
        features={'weights': weights},
        mode=model_fn.ModeKeys.TRAIN,
        logits=logits,
        labels=labels)
    atol = 1.e-3
    with self.test_session():
      _initialize_variables(self, monitored_session.Scaffold())
      self.assertAllClose(
          expected_training_loss, training_loss.eval(), atol=atol)
      self.assertAllClose(
          expected_unreduced_loss, unreduced_loss.eval(), atol=atol)
      self.assertAllClose(expected_weights, actual_weights.eval())
예제 #13
0
  def test_train_create_loss_loss_reduction(self):
    """Tests head.create_loss with loss_reduction."""
    n_classes = 2
    head = head_lib.multi_label_head(
        n_classes, weight_column='example_weights',
        loss_reduction=losses.Reduction.SUM_BY_NONZERO_WEIGHTS)

    logits = np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)
    labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
    weights = np.array([[1.], [2.]], dtype=np.float32)
    # loss = labels * -log(sigmoid(logits)) +
    #        (1 - labels) * -log(1 - sigmoid(logits))
    # For large logits, this is approximated as:
    # loss = labels * (logits < 0) * (-logits) +
    #        (1 - labels) * (logits > 0) * logits
    expected_unreduced_loss = [[(10. + 10.) / 2.], [(15. + 0.) / 2.]]
    expected_weights = [[1.], [2.]]
    expected_training_loss = (1. * (10. + 10.) / 2. + 2. * (15. + 0.) / 2.) / 2.
    training_loss, unreduced_loss, actual_weights, _ = head.create_loss(
        features={
            'x': np.array(((42,),), dtype=np.int32),
            'example_weights': weights
        },
        mode=model_fn.ModeKeys.TRAIN,
        logits=logits,
        labels=labels)
    with self.test_session():
      _initialize_variables(self, monitored_session.Scaffold())
      self.assertAllClose(
          expected_training_loss, training_loss.eval(), atol=1e-4)
      self.assertAllClose(
          expected_unreduced_loss, unreduced_loss.eval(), atol=1e-4)
      self.assertAllClose(expected_weights, actual_weights.eval())
예제 #14
0
 def test_eval_with_regularization_losses(self):
   n_classes = 2
   head = head_lib.multi_label_head(
       n_classes, loss_reduction=losses.Reduction.SUM_OVER_BATCH_SIZE)
   logits = np.array([[-1., 1.], [-1.5, 1.5]], dtype=np.float32)
   labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
   regularization_losses = [1.5, 0.5]
   expected_regularization_loss = 2.
   # unregularized_loss = sum(
   #     labels * -log(sigmoid(logits)) +
   #     (1 - labels) * -log(1 - sigmoid(logits))) / batch_size
   expected_unregularized_loss = np.sum(
       _sigmoid_cross_entropy(labels=labels, logits=logits)) / 2.
   expected_regularized_loss = (
       expected_unregularized_loss + expected_regularization_loss)
   keys = metric_keys.MetricKeys
   expected_metrics = {
       keys.LOSS_MEAN: expected_unregularized_loss,
       keys.LOSS_REGULARIZATION: expected_regularization_loss,
       # auc and auc_pr cannot be reliably calculated for only 4 samples, but
       # this assert tests that the algorithm remains consistent.
       keys.AUC: 0.3333,
       keys.AUC_PR: 0.7639,
   }
   self._test_eval(
       head=head,
       logits=logits,
       labels=labels,
       expected_loss=expected_regularized_loss,
       expected_metrics=expected_metrics,
       regularization_losses=regularization_losses)
예제 #15
0
  def test_multi_dim_weighted_eval(self):
    """Logits and labels of shape [2, 2, 3], weights [2, 2]."""
    head = head_lib.multi_label_head(n_classes=3, weight_column='weights')

    logits = np.array([[[-10., 10., -10.], [10., -10., 10.]],
                       [[-12., 12., -12.], [12., -12., 12.]]], dtype=np.float32)
    labels = np.array([[[1, 0, 0], [1, 0, 0]],
                       [[0, 1, 1], [0, 1, 1]]], dtype=np.int64)
    weights = np.array([[1., 1.5], [2., 2.5]], dtype=np.float32)
    # loss = [[10 + 10 + 0, 0 + 0 + 10], [0 + 0 + 12, 12 + 12 + 0]] / 3
    #      = [[20/3, 10/3], [4, 8]]
    # weighted_sum_loss = 1*20/3 + 1.5*10/3 + 2*4 + 2.5*8 = 39.6667
    expected_loss = 39.6667
    keys = metric_keys.MetricKeys
    expected_metrics = {
        keys.LOSS_MEAN: expected_loss / np.sum(weights),
        # auc and auc_pr cannot be reliably calculated for only 4 samples, but
        # this assert tests that the algorithm remains consistent.
        keys.AUC: 0.4977,
        keys.AUC_PR: 0.6645,
    }
    self._test_eval(
        head=head,
        features={'weights': weights},
        logits=logits,
        labels=labels,
        expected_loss=expected_loss,
        expected_metrics=expected_metrics)
예제 #16
0
  def test_predict(self):
    n_classes = 4
    head = head_lib.multi_label_head(n_classes)
    self.assertEqual(n_classes, head.logits_dimension)

    logits = np.array(
        [[0., 1., 2., -1.], [-1., -2., -3., 1.]], dtype=np.float32)
    expected_probabilities = _sigmoid(logits)

    spec = head.create_estimator_spec(
        features={'x': np.array(((42,),), dtype=np.int32)},
        mode=model_fn.ModeKeys.PREDICT,
        logits=logits)

    self.assertItemsEqual(
        ('', _DEFAULT_SERVING_KEY), spec.export_outputs.keys())

    # Assert predictions and export_outputs.
    with self.test_session() as sess:
      _initialize_variables(self, spec.scaffold)
      self.assertIsNone(spec.scaffold.summary_op)
      predictions = sess.run(spec.predictions)
      self.assertAllClose(logits,
                          predictions[prediction_keys.PredictionKeys.LOGITS])
      self.assertAllClose(
          expected_probabilities,
          predictions[prediction_keys.PredictionKeys.PROBABILITIES])

      self.assertAllClose(
          expected_probabilities,
          sess.run(spec.export_outputs[_DEFAULT_SERVING_KEY].scores))
예제 #17
0
 def test_eval(self):
   n_classes = 2
   head = head_lib.multi_label_head(n_classes)
   logits = np.array([[-1., 1.], [-1.5, 1.5]], dtype=np.float32)
   labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
   # loss = labels * -log(sigmoid(logits)) +
   #        (1 - labels) * -log(1 - sigmoid(logits))
   # Sum over examples, divide by batch_size.
   expected_loss = 0.5 * np.sum(
       _sigmoid_cross_entropy(labels=labels, logits=logits))
   keys = metric_keys.MetricKeys
   expected_metrics = {
       # Average loss over examples.
       keys.LOSS_MEAN: expected_loss,
       # auc and auc_pr cannot be reliably calculated for only 4 samples, but
       # this assert tests that the algorithm remains consistent.
       keys.AUC: 0.3333,
       keys.AUC_PR: 0.7639,
   }
   self._test_eval(
       head=head,
       logits=logits,
       labels=labels,
       expected_loss=expected_loss,
       expected_metrics=expected_metrics)
예제 #18
0
  def test_predict(self):
    n_classes = 4
    head = head_lib.multi_label_head(n_classes)
    self.assertEqual(n_classes, head.logits_dimension)

    logits = np.array(
        [[0., 1., 2., -1.], [-1., -2., -3., 1.]], dtype=np.float32)
    expected_probabilities = _sigmoid(logits)

    spec = head.create_estimator_spec(
        features={'x': np.array(((42,),), dtype=np.int32)},
        mode=model_fn.ModeKeys.PREDICT,
        logits=logits)

    self.assertItemsEqual(
        ('', _DEFAULT_SERVING_KEY), spec.export_outputs.keys())

    # Assert predictions and export_outputs.
    with self.test_session() as sess:
      _initialize_variables(self, spec.scaffold)
      self.assertIsNone(spec.scaffold.summary_op)
      predictions = sess.run(spec.predictions)
      self.assertAllClose(logits,
                          predictions[prediction_keys.PredictionKeys.LOGITS])
      self.assertAllClose(
          expected_probabilities,
          predictions[prediction_keys.PredictionKeys.PROBABILITIES])

      self.assertAllClose(
          expected_probabilities,
          sess.run(spec.export_outputs[_DEFAULT_SERVING_KEY].scores))
예제 #19
0
  def test_train_with_optimizer(self):
    head = head_lib.multi_label_head(n_classes=2)
    logits = np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)
    labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
    # For large logits, sigmoid cross entropy loss is approximated as:
    # loss = labels * (logits < 0) * (-logits) +
    #        (1 - labels) * (logits > 0) * logits =>
    # expected_unweighted_loss = [[10., 10.], [15., 0.]]
    # Average over classes, sum over weights.
    expected_loss = 17.5
    expected_train_result = 'my_train_op'

    class _Optimizer(object):

      def minimize(self, loss, global_step):
        del global_step
        return string_ops.string_join(
            [constant_op.constant(expected_train_result),
             string_ops.as_string(loss, precision=3)])

    spec = head.create_estimator_spec(
        features={'x': np.array(((42,),), dtype=np.int32)},
        mode=model_fn.ModeKeys.TRAIN,
        logits=logits,
        labels=labels,
        optimizer=_Optimizer())

    tol = 1e-3
    with self.test_session() as sess:
      _initialize_variables(self, spec.scaffold)
      loss, train_result = sess.run((spec.loss, spec.train_op))
      self.assertAllClose(expected_loss, loss, rtol=tol, atol=tol)
      self.assertEqual(
          six.b('{0:s}{1:.3f}'.format(expected_train_result, expected_loss)),
          train_result)
예제 #20
0
  def test_eval_create_loss_large_logits(self):
    """Tests head.create_loss for eval mode and large logits."""
    n_classes = 2
    head = head_lib.multi_label_head(n_classes)

    logits = np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)
    labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
    # loss = labels * -log(sigmoid(logits)) +
    #        (1 - labels) * -log(1 - sigmoid(logits))
    # For large logits, this is approximated as:
    # loss = labels * (logits < 0) * (-logits) +
    #        (1 - labels) * (logits > 0) * logits
    expected_weighted_sum_loss = np.sum(
        np.array([[(10. + 10.) / 2.], [(15. + 0.) / 2.]], dtype=np.float32))
    actual_weighted_sum_loss = head.create_loss(
        features={'x': np.array(((42,),), dtype=np.int32)},
        mode=model_fn.ModeKeys.EVAL,
        logits=logits,
        labels=labels)[0]
    with self.test_session():
      _initialize_variables(self, monitored_session.Scaffold())
      self.assertAllClose(
          expected_weighted_sum_loss,
          actual_weighted_sum_loss.eval(),
          atol=1e-4)
예제 #21
0
    def test_train_with_weights(self):
        n_classes = 2
        head = head_lib.multi_label_head(n_classes,
                                         weight_column='label_weights')

        logits = np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)
        labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
        # For large logits, sigmoid cross entropy loss is approximated as:
        # loss = labels * (logits < 0) * (-logits) +
        #        (1 - labels) * (logits > 0) * logits =>
        # expected_unweighted_loss = [[10., 10.], [15., 0.]]
        # Average over classes, weighted sum over examples.
        expected_loss = 25.
        expected_train_result = 'my_train_op'

        def _train_op_fn(loss):
            return string_ops.string_join([
                constant_op.constant(expected_train_result),
                string_ops.as_string(loss, precision=3)
            ])

        spec = head.create_estimator_spec(features={
            'x':
            np.array([[41], [42]], dtype=np.int32),
            'label_weights':
            np.array([[1.], [2.]], dtype=np.float32),
        },
                                          mode=model_fn.ModeKeys.TRAIN,
                                          logits=logits,
                                          labels=labels,
                                          train_op_fn=_train_op_fn)

        self.assertIsNotNone(spec.loss)
        self.assertEqual({}, spec.eval_metric_ops)
        self.assertIsNotNone(spec.train_op)
        self.assertIsNone(spec.export_outputs)
        _assert_no_hooks(self, spec)

        # Assert predictions, loss, train_op, and summaries.
        tol = 1e-3
        with self.test_session() as sess:
            _initialize_variables(self, spec.scaffold)
            self.assertIsNotNone(spec.scaffold.summary_op)
            loss, train_result, summary_str = sess.run(
                (spec.loss, spec.train_op, spec.scaffold.summary_op))
            self.assertAllClose(expected_loss, loss, rtol=tol, atol=tol)
            self.assertEqual(
                six.b('{0:s}{1:.3f}'.format(expected_train_result,
                                            expected_loss)), train_result)
            _assert_simple_summaries(
                self,
                {
                    metric_keys.MetricKeys.LOSS:
                    expected_loss,
                    # Average loss over weighted examples.
                    metric_keys.MetricKeys.LOSS_MEAN:
                    expected_loss / 3,
                },
                summary_str,
                tol)
예제 #22
0
  def test_eval_create_loss_sparse_labels(self):
    """Tests head.create_loss for eval mode and sparse labels."""
    n_classes = 2
    head = head_lib.multi_label_head(n_classes)

    logits = np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)
    labels = sparse_tensor.SparseTensor(
        values=[0, 0, 1],
        indices=[[0, 0], [1, 0], [1, 1]],
        dense_shape=[2, 2])
    expected_labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
    # loss = labels * -log(sigmoid(logits)) +
    #        (1 - labels) * -log(1 - sigmoid(logits))
    # For large logits, this is approximated as:
    # loss = labels * (logits < 0) * (-logits) +
    #        (1 - labels) * (logits > 0) * logits
    expected_unweighted_loss = np.array(
        [[10., 10.], [15., 0.]], dtype=np.float32)
    actual_unweighted_loss, actual_labels = head.create_loss(
        features={'x': np.array(((42,),), dtype=np.int32)},
        mode=model_fn.ModeKeys.EVAL,
        logits=logits,
        labels=labels)
    with self.test_session():
      _initialize_variables(self, monitored_session.Scaffold())
      self.assertAllEqual(expected_labels, actual_labels.eval())
      self.assertAllClose(
          expected_unweighted_loss, actual_unweighted_loss.eval(), atol=1e-4)
예제 #23
0
  def test_multi_dim_weighted_eval(self):
    """Logits and labels of shape [2, 2, 3], weights [2, 2]."""
    head = head_lib.multi_label_head(n_classes=3, weight_column='weights')

    logits = np.array([[[-10., 10., -10.], [10., -10., 10.]],
                       [[-12., 12., -12.], [12., -12., 12.]]], dtype=np.float32)
    labels = np.array([[[1, 0, 0], [1, 0, 0]],
                       [[0, 1, 1], [0, 1, 1]]], dtype=np.int64)
    weights = np.array([[1., 1.5], [2., 2.5]], dtype=np.float32)
    # loss = [[10 + 10 + 0, 0 + 0 + 10], [0 + 0 + 12, 12 + 12 + 0]] / 3
    #      = [[20/3, 10/3], [4, 8]]
    # weighted_sum_loss = 1*20/3 + 1.5*10/3 + 2*4 + 2.5*8 = 39.6667
    expected_loss = 39.6667
    keys = metric_keys.MetricKeys
    expected_metrics = {
        keys.LOSS_MEAN: expected_loss / np.sum(weights),
        # auc and auc_pr cannot be reliably calculated for only 4 samples, but
        # this assert tests that the algorithm remains consistent.
        keys.AUC: 0.4977,
        keys.AUC_PR: 0.6645,
    }
    self._test_eval(
        head=head,
        features={'weights': weights},
        logits=logits,
        labels=labels,
        expected_loss=expected_loss,
        expected_metrics=expected_metrics)
예제 #24
0
    def test_eval_create_loss_large_logits(self):
        """Tests head.create_loss for eval mode and large logits."""
        n_classes = 2
        head = head_lib.multi_label_head(n_classes)

        logits = np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)
        labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
        # loss = labels * -log(sigmoid(logits)) +
        #        (1 - labels) * -log(1 - sigmoid(logits))
        # For large logits, this is approximated as:
        # loss = labels * (logits < 0) * (-logits) +
        #        (1 - labels) * (logits > 0) * logits
        expected_weighted_sum_loss = np.sum(
            np.array([[(10. + 10.) / 2.], [(15. + 0.) / 2.]],
                     dtype=np.float32))
        actual_weighted_sum_loss = head.create_loss(
            features={'x': np.array(((42, ), ), dtype=np.int32)},
            mode=model_fn.ModeKeys.EVAL,
            logits=logits,
            labels=labels)[0]
        with self.test_session():
            _initialize_variables(self, monitored_session.Scaffold())
            self.assertAllClose(expected_weighted_sum_loss,
                                actual_weighted_sum_loss.eval(),
                                atol=1e-4)
예제 #25
0
  def test_multi_dim_weighted_train_create_loss(self):
    """Logits and labels of shape [2, 2, 3], weights [2, 2]."""
    head = head_lib.multi_label_head(n_classes=3, weight_column='weights')

    logits = np.array([[[-10., 10., -10.], [10., -10., 10.]],
                       [[-12., 12., -12.], [12., -12., 12.]]], dtype=np.float32)
    labels = np.array([[[1, 0, 0], [1, 0, 0]],
                       [[0, 1, 1], [0, 1, 1]]], dtype=np.int64)
    weights = np.array([[1., 1.5], [2., 2.5]], dtype=np.float32)
    # unreduced_loss =
    #     [[10 + 10 + 0, 0 + 0 + 10], [0 + 0 + 12, 12 + 12 + 0]] / 3
    #   = [[20/3, 10/3], [4, 8]]
    expected_unreduced_loss = [[[20./3.], [10./3.]], [[4.], [8.]]]
    # weights are reshaped to [2, 2, 1] to match logits.
    expected_weights = [[[1.], [1.5]], [[2.], [2.5]]]
    # weighted_sum_loss = 1*20/3 + 1.5*10/3 + 2*4 + 2.5*8 = 39.6667
    expected_training_loss = 39.6667
    training_loss, unreduced_loss, actual_weights, _ = head.create_loss(
        features={'weights': weights},
        mode=model_fn.ModeKeys.TRAIN,
        logits=logits,
        labels=labels)
    atol = 1.e-3
    with self.test_session():
      _initialize_variables(self, monitored_session.Scaffold())
      self.assertAllClose(
          expected_training_loss, training_loss.eval(), atol=atol)
      self.assertAllClose(
          expected_unreduced_loss, unreduced_loss.eval(), atol=atol)
      self.assertAllClose(expected_weights, actual_weights.eval())
예제 #26
0
    def test_eval_create_loss_labels_wrong_shape(self):
        """Tests head.create_loss for eval mode when labels has the wrong shape."""
        n_classes = 2
        head = head_lib.multi_label_head(n_classes)

        logits = np.array([[-1., 1.], [-1.5, 1.]], dtype=np.float32)
        labels_placeholder = array_ops.placeholder(dtype=dtypes.int64)
        actual_weighted_sum_loss = head.create_loss(
            features={'x': np.array(((42, ), ), dtype=np.int32)},
            mode=model_fn.ModeKeys.EVAL,
            logits=logits,
            labels=labels_placeholder)[0]
        with self.test_session():
            _initialize_variables(self, monitored_session.Scaffold())
            with self.assertRaisesRegexp(
                    errors.InvalidArgumentError,
                    r'labels shape must be \[batch_size, 2\]\. Given: \] \[2 1\]'
            ):
                actual_weighted_sum_loss.eval(
                    {labels_placeholder: np.array([[1], [1]], dtype=np.int64)})
            with self.assertRaisesRegexp(
                    errors.InvalidArgumentError,
                    r'labels shape must be \[batch_size, 2\]\. Given: \] \[2\]'
            ):
                actual_weighted_sum_loss.eval(
                    {labels_placeholder: np.array([1, 1], dtype=np.int64)})
예제 #27
0
  def test_multi_dim_weighted_train(self):
    """Logits and labels of shape [2, 2, 3], weights [2, 2]."""
    head = head_lib.multi_label_head(n_classes=3, weight_column='weights')

    logits = np.array([[[-10., 10., -10.], [10., -10., 10.]],
                       [[-12., 12., -12.], [12., -12., 12.]]], dtype=np.float32)
    labels = np.array([[[1, 0, 0], [1, 0, 0]],
                       [[0, 1, 1], [0, 1, 1]]], dtype=np.int64)
    weights = np.array([[1., 1.5], [2., 2.5]], dtype=np.float32)
    # loss = [[10 + 10 + 0, 0 + 0 + 10], [0 + 0 + 12, 12 + 12 + 0]] / 3
    #      = [[20/3, 10/3], [4, 8]]
    # weighted_sum_loss = 1*20/3 + 1.5*10/3 + 2*4 + 2.5*8 = 39.6667
    expected_loss = 39.6667
    expected_train_result = 'my_train_op'
    def _train_op_fn(loss):
      return string_ops.string_join(
          [constant_op.constant(expected_train_result),
           string_ops.as_string(loss, precision=3)])

    spec = head.create_estimator_spec(
        features={'weights': weights},
        mode=model_fn.ModeKeys.TRAIN,
        logits=logits,
        labels=labels,
        train_op_fn=_train_op_fn)

    atol = 1.e-3
    with self.test_session() as sess:
      _initialize_variables(self, monitored_session.Scaffold())
      loss, train_result = sess.run((spec.loss, spec.train_op))
      self.assertAllClose(expected_loss, loss, atol=atol)
      self.assertEqual(
          six.b('{0:s}{1:.3f}'.format(expected_train_result, expected_loss)),
          train_result)
예제 #28
0
 def test_eval_with_regularization_losses(self):
   n_classes = 2
   head = head_lib.multi_label_head(
       n_classes, loss_reduction=losses.Reduction.SUM_OVER_BATCH_SIZE)
   logits = np.array([[-1., 1.], [-1.5, 1.5]], dtype=np.float32)
   labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
   regularization_losses = [1.5, 0.5]
   expected_regularization_loss = 2.
   # unregularized_loss = sum(
   #     labels * -log(sigmoid(logits)) +
   #     (1 - labels) * -log(1 - sigmoid(logits))) / batch_size
   expected_unregularized_loss = np.sum(
       _sigmoid_cross_entropy(labels=labels, logits=logits)) / 2.
   expected_regularized_loss = (
       expected_unregularized_loss + expected_regularization_loss)
   keys = metric_keys.MetricKeys
   expected_metrics = {
       keys.LOSS_MEAN: expected_unregularized_loss,
       keys.LOSS_REGULARIZATION: expected_regularization_loss,
       # auc and auc_pr cannot be reliably calculated for only 4 samples, but
       # this assert tests that the algorithm remains consistent.
       keys.AUC: 0.3333,
       keys.AUC_PR: 0.5972,
   }
   self._test_eval(
       head=head,
       logits=logits,
       labels=labels,
       expected_loss=expected_regularized_loss,
       expected_metrics=expected_metrics,
       regularization_losses=regularization_losses)
예제 #29
0
    def test_eval_create_loss_loss_fn(self):
        """Tests head.create_loss for eval mode and custom loss_fn."""
        loss = np.array([[1.], [2.]], dtype=np.float32)
        logits_input = np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)
        labels_input = np.array([[1, 0], [1, 1]], dtype=np.int64)

        def _loss_fn(labels, logits):
            check_labels = control_flow_ops.Assert(math_ops.reduce_all(
                math_ops.equal(labels, labels_input)),
                                                   data=[labels])
            check_logits = control_flow_ops.Assert(math_ops.reduce_all(
                math_ops.equal(logits, logits_input)),
                                                   data=[logits])
            with ops.control_dependencies([check_labels, check_logits]):
                return constant_op.constant(loss)

        head = head_lib.multi_label_head(n_classes=2, loss_fn=_loss_fn)

        actual_weighted_sum_loss = head.create_loss(
            features={'x': np.array(((42, ), ), dtype=np.int32)},
            mode=model_fn.ModeKeys.EVAL,
            logits=logits_input,
            labels=labels_input)[0]
        with self.test_session():
            _initialize_variables(self, monitored_session.Scaffold())
            self.assertAllClose(np.sum(loss), actual_weighted_sum_loss.eval())
예제 #30
0
 def test_eval(self):
     n_classes = 2
     head = head_lib.multi_label_head(n_classes)
     logits = np.array([[-1., 1.], [-1.5, 1.5]], dtype=np.float32)
     labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
     # loss = labels * -log(sigmoid(logits)) +
     #        (1 - labels) * -log(1 - sigmoid(logits))
     # Sum over examples.
     expected_loss = np.sum(
         _sigmoid_cross_entropy(labels=labels, logits=logits))
     keys = metric_keys.MetricKeys
     expected_metrics = {
         # Average loss over examples.
         keys.LOSS_MEAN:
         expected_loss / 2,
         # auc and auc_pr cannot be reliably calculated for only 4 samples, but
         # this assert tests that the algorithm remains consistent.
         keys.AUC:
         0.3333,
         keys.AUC_PR:
         0.7639,
     }
     self._test_eval(head=head,
                     logits=logits,
                     labels=labels,
                     expected_loss=expected_loss,
                     expected_metrics=expected_metrics)
예제 #31
0
 def test_eval_with_label_vocabulary(self):
     n_classes = 2
     head = head_lib.multi_label_head(n_classes,
                                      label_vocabulary=['class0', 'class1'])
     logits = np.array([[-1., 1.], [-1.5, 1.5]], dtype=np.float32)
     # Equivalent to multi_hot = [[1, 0], [1, 1]]
     labels = sparse_tensor.SparseTensor(
         values=['class0', 'class0', 'class1'],
         indices=[[0, 0], [1, 0], [1, 1]],
         dense_shape=[2, 2])
     labels_multi_hot = np.array([[1, 0], [1, 1]], dtype=np.int64)
     # loss = labels * -log(sigmoid(logits)) +
     #        (1 - labels) * -log(1 - sigmoid(logits))
     # Sum over examples.
     expected_loss = (np.sum(
         _sigmoid_cross_entropy(labels=labels_multi_hot, logits=logits)))
     keys = metric_keys.MetricKeys
     expected_metrics = {
         # Average loss over examples.
         keys.LOSS_MEAN:
         expected_loss / 2,
         # auc and auc_pr cannot be reliably calculated for only 4 samples, but
         # this assert tests that the algorithm remains consistent.
         keys.AUC:
         0.3333,
         keys.AUC_PR:
         0.7639,
     }
     self._test_eval(head=head,
                     logits=logits,
                     labels=labels,
                     expected_loss=expected_loss,
                     expected_metrics=expected_metrics)
예제 #32
0
    def test_train_create_loss_large_logits(self):
        """Tests head.create_loss for train mode and large logits."""
        n_classes = 2
        head = head_lib.multi_label_head(n_classes,
                                         weight_column='label_weights')

        logits = np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)
        labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
        weights = np.array([[1.], [2.]], dtype=np.float32)
        # loss = labels * -log(sigmoid(logits)) +
        #        (1 - labels) * -log(1 - sigmoid(logits))
        # For large logits, this is approximated as:
        # loss = labels * (logits < 0) * (-logits) +
        #        (1 - labels) * (logits > 0) * logits
        expected_weighted_sum_loss = np.sum(
            np.array([[1. * (10. + 10.) / 2.], [2. * (15. + 0.) / 2.]],
                     dtype=np.float32))
        expected_example_weight_sum = 1. + 2.
        actual_weighted_sum_loss, actual_example_weight_sum, _ = head.create_loss(
            features={
                'x': np.array(((42, ), ), dtype=np.int32),
                'label_weights': weights
            },
            mode=model_fn.ModeKeys.TRAIN,
            logits=logits,
            labels=labels)
        with self.test_session():
            _initialize_variables(self, monitored_session.Scaffold())
            self.assertAllClose(expected_weighted_sum_loss,
                                actual_weighted_sum_loss.eval(),
                                atol=1e-4)
            self.assertAllClose(expected_example_weight_sum,
                                actual_example_weight_sum.eval(),
                                atol=1e-4)
예제 #33
0
    def test_weight_should_not_impact_prediction(self):
        n_classes = 4
        head = head_lib.multi_label_head(n_classes,
                                         weight_column='label_weights')
        self.assertEqual(n_classes, head.logits_dimension)

        logits = np.array([[0., 1., 2., -1.], [-1., -2., -3., 1.]],
                          dtype=np.float32)
        expected_probabilities = _sigmoid(logits)

        weights_2x1 = [[1.], [2.]]
        spec = head.create_estimator_spec(features={
            'x':
            np.array(((42, ), ), dtype=np.int32),
            'label_weights':
            weights_2x1,
        },
                                          mode=model_fn.ModeKeys.PREDICT,
                                          logits=logits)

        # Assert predictions and export_outputs.
        with self.test_session() as sess:
            _initialize_variables(self, spec.scaffold)
            self.assertIsNone(spec.scaffold.summary_op)
            predictions = sess.run(spec.predictions)
            self.assertAllClose(
                logits, predictions[prediction_keys.PredictionKeys.LOGITS])
            self.assertAllClose(
                expected_probabilities,
                predictions[prediction_keys.PredictionKeys.PROBABILITIES])
예제 #34
0
 def test_eval_with_label_vocabulary(self):
   n_classes = 2
   head = head_lib.multi_label_head(
       n_classes, label_vocabulary=['class0', 'class1'])
   logits = np.array([[-1., 1.], [-1.5, 1.5]], dtype=np.float32)
   # Equivalent to multi_hot = [[1, 0], [1, 1]]
   labels = sparse_tensor.SparseTensor(
       values=['class0', 'class0', 'class1'],
       indices=[[0, 0], [1, 0], [1, 1]],
       dense_shape=[2, 2])
   labels_multi_hot = np.array([[1, 0], [1, 1]], dtype=np.int64)
   # loss = labels * -log(sigmoid(logits)) +
   #        (1 - labels) * -log(1 - sigmoid(logits))
   # Sum over examples.
   expected_loss = (
       np.sum(_sigmoid_cross_entropy(labels=labels_multi_hot, logits=logits))
   )
   keys = metric_keys.MetricKeys
   expected_metrics = {
       # Average loss over examples.
       keys.LOSS_MEAN: expected_loss / 2,
       # auc and auc_pr cannot be reliably calculated for only 4 samples, but
       # this assert tests that the algorithm remains consistent.
       keys.AUC: 0.3333,
       keys.AUC_PR: 0.7639,
   }
   self._test_eval(
       head=head,
       logits=logits,
       labels=labels,
       expected_loss=expected_loss,
       expected_metrics=expected_metrics)
예제 #35
0
  def test_eval_create_loss_labels_wrong_shape(self):
    """Tests head.create_loss for eval mode when labels has the wrong shape."""
    n_classes = 2
    head = head_lib.multi_label_head(n_classes)

    logits = np.array([[-1., 1.], [-1.5, 1.]], dtype=np.float32)
    labels_placeholder = array_ops.placeholder(dtype=dtypes.int64)
    actual_training_loss = head.create_loss(
        features={'x': np.array(((42,),), dtype=np.int32)},
        mode=model_fn.ModeKeys.EVAL,
        logits=logits,
        labels=labels_placeholder)[0]
    with self.test_session():
      _initialize_variables(self, monitored_session.Scaffold())
      with self.assertRaisesRegexp(
          errors.InvalidArgumentError,
          r'\[expected_labels_shape: \] \[2 2\] \[labels_shape: \] \[2 1\]'):
        actual_training_loss.eval({
            labels_placeholder: np.array([[1], [1]], dtype=np.int64)
        })
      with self.assertRaisesRegexp(
          errors.InvalidArgumentError,
          r'labels shape must be \[D0, D1, ... DN, 2\]\..*'
          r'\[Received shape: \] \[2\]'):
        actual_training_loss.eval({
            labels_placeholder: np.array([1, 1], dtype=np.int64)
        })
예제 #36
0
  def test_train_create_loss_loss_reduction(self):
    """Tests head.create_loss with loss_reduction."""
    n_classes = 2
    head = head_lib.multi_label_head(
        n_classes, weight_column='example_weights',
        loss_reduction=losses.Reduction.SUM_BY_NONZERO_WEIGHTS)

    logits = np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)
    labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
    weights = np.array([[1.], [2.]], dtype=np.float32)
    # loss = labels * -log(sigmoid(logits)) +
    #        (1 - labels) * -log(1 - sigmoid(logits))
    # For large logits, this is approximated as:
    # loss = labels * (logits < 0) * (-logits) +
    #        (1 - labels) * (logits > 0) * logits
    expected_unreduced_loss = [[(10. + 10.) / 2.], [(15. + 0.) / 2.]]
    expected_weights = [[1.], [2.]]
    expected_training_loss = (1. * (10. + 10.) / 2. + 2. * (15. + 0.) / 2.) / 2.
    training_loss, unreduced_loss, actual_weights, _ = head.create_loss(
        features={
            'x': np.array(((42,),), dtype=np.int32),
            'example_weights': weights
        },
        mode=model_fn.ModeKeys.TRAIN,
        logits=logits,
        labels=labels)
    with self.test_session():
      _initialize_variables(self, monitored_session.Scaffold())
      self.assertAllClose(
          expected_training_loss, training_loss.eval(), atol=1e-4)
      self.assertAllClose(
          expected_unreduced_loss, unreduced_loss.eval(), atol=1e-4)
      self.assertAllClose(expected_weights, actual_weights.eval())
예제 #37
0
  def test_multi_dim_weights_wrong_outer_dim(self):
    """Logits and labels of shape [2, 2, 3], weights [2, 2, 3]."""
    head = head_lib.multi_label_head(n_classes=3, weight_column='weights')

    logits = np.array([[[-10., 10., -10.], [10., -10., 10.]],
                       [[-12., 12., -12.], [12., -12., 12.]]], dtype=np.float32)
    labels = np.array([[[1, 0, 0], [1, 0, 0]],
                       [[0, 1, 1], [0, 1, 1]]], dtype=np.int64)
    weights = np.array([[[1., 1., 1.], [1.5, 1.5, 1.5]],
                        [[2., 2., 2.], [2.5, 2.5, 2.5]]], dtype=np.float32)
    weights_placeholder = array_ops.placeholder(dtype=dtypes.float32)
    def _train_op_fn(loss):
      del loss
      return control_flow_ops.no_op()

    spec = head.create_estimator_spec(
        features={'weights': weights_placeholder},
        mode=model_fn.ModeKeys.TRAIN,
        logits=logits,
        labels=labels,
        train_op_fn=_train_op_fn)
    with self.test_session():
      _initialize_variables(self, monitored_session.Scaffold())
      with self.assertRaisesRegexp(
          errors.InvalidArgumentError,
          r'\[logits_shape: \] \[2 2 3\] \[weights_shape: \] \[2 2 3\]'):
        spec.loss.eval({weights_placeholder: weights})
예제 #38
0
  def test_weight_should_not_impact_prediction(self):
    n_classes = 4
    head = head_lib.multi_label_head(n_classes, weight_column='example_weights')
    self.assertEqual(n_classes, head.logits_dimension)

    logits = np.array(
        [[0., 1., 2., -1.], [-1., -2., -3., 1.]], dtype=np.float32)
    expected_probabilities = _sigmoid(logits)

    weights_2x1 = [[1.], [2.]]
    spec = head.create_estimator_spec(
        features={
            'x': np.array(((42,),), dtype=np.int32),
            'example_weights': weights_2x1,
        },
        mode=model_fn.ModeKeys.PREDICT,
        logits=logits)

    # Assert predictions and export_outputs.
    with self.test_session() as sess:
      _initialize_variables(self, spec.scaffold)
      self.assertIsNone(spec.scaffold.summary_op)
      predictions = sess.run(spec.predictions)
      self.assertAllClose(logits,
                          predictions[prediction_keys.PredictionKeys.LOGITS])
      self.assertAllClose(
          expected_probabilities,
          predictions[prediction_keys.PredictionKeys.PROBABILITIES])
예제 #39
0
  def test_train_create_loss_logits_tensor(self):
    """Tests create_loss with logits Tensor."""
    weights1 = np.array([[1.], [2.]], dtype=np.float32)
    weights2 = np.array([[2.], [3.]])
    head1 = head_lib.multi_label_head(n_classes=2, name='head1',
                                      weight_column='weights1')
    head2 = head_lib.multi_label_head(n_classes=3, name='head2',
                                      weight_column='weights2')
    multi_head = multi_head_lib.multi_head(
        [head1, head2], head_weights=[1., 2.])

    logits = np.array([[-10., 10., 20., -20., 20.],
                       [-15., 10., -30., 20., -20.]], dtype=np.float32)
    labels = {
        'head1': np.array([[1, 0], [1, 1]], dtype=np.int64),
        'head2': np.array([[0, 1, 0], [1, 1, 0]], dtype=np.int64),
    }
    training_loss, unreduced_losses, weights, _ = multi_head.create_loss(
        features={
            'x': np.array(((42,),), dtype=np.int32),
            'weights1': weights1,
            'weights2': weights2
        },
        mode=model_fn.ModeKeys.TRAIN,
        logits=logits,
        labels=labels)
    tol = 1e-3
    with self.test_session():
      # loss of the first head is [[(10 + 10) / 2], [(15 + 0) / 2]]
      # = [10, 7.5]
      # training_loss = 1 * 10 + 2 * 7.5 = 25
      # head-weighted unreduced_loss = 1 * [10, 7.5]
      self.assertAllClose(
          [[10.], [7.5]], unreduced_losses['head1'].eval(), rtol=tol, atol=tol)
      # loss of the second head is [[(20 + 20 + 20) / 3], [(30 + 0 + 0) / 3]]
      # = [20, 10]
      # training_loss = 2 * 20 + 3 * 10 = 70
      # head-weighted unreduced_loss = 2 * [20, 10]
      self.assertAllClose(
          [[40.], [20.]], unreduced_losses['head2'].eval(), rtol=tol, atol=tol)
      # head-weighted training_loss = 1 * 25 + 2 * 70 = 165
      self.assertAllClose(165, training_loss.eval(), rtol=tol, atol=tol)
      # head-weighted example weights
      self.assertAllClose(
          [[1.], [2.]], weights['head1'].eval(), rtol=tol, atol=tol)
      self.assertAllClose(
          [[4.], [6.]], weights['head2'].eval(), rtol=tol, atol=tol)
예제 #40
0
  def test_eval_with_weights(self):
    n_classes = 2
    head = head_lib.multi_label_head(n_classes, weight_column='example_weights')

    logits = np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)
    labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
    # For large logits, sigmoid cross entropy loss is approximated as:
    # loss = labels * (logits < 0) * (-logits) +
    #        (1 - labels) * (logits > 0) * logits =>
    # expected_unweighted_loss = [[10., 10.], [15., 0.]]
    # Average over classes, weighted sum over examples, divide by batch_size.
    # loss = ( 1 * (10 + 10) / 2 + 2 * (15 + 0) / 2) / 2
    expected_loss = 12.5

    spec = head.create_estimator_spec(
        features={
            'x': np.array([[41], [42]], dtype=np.int32),
            'example_weights': np.array([[1.], [2.]], dtype=np.float32),
        },
        mode=model_fn.ModeKeys.EVAL,
        logits=logits,
        labels=labels)

    keys = metric_keys.MetricKeys
    expected_metrics = {
        # Average loss over weighted examples (denominator is sum(weights)).
        keys.LOSS_MEAN: expected_loss * (2. / 3.),
        # auc and auc_pr cannot be reliably calculated for only 4 samples, but
        # this assert tests that the algorithm remains consistent.
        keys.AUC: 0.2000,
        keys.AUC_PR: 0.7833,
    }

    # Assert spec contains expected tensors.
    self.assertIsNotNone(spec.loss)
    self.assertItemsEqual(expected_metrics.keys(), spec.eval_metric_ops.keys())
    self.assertIsNone(spec.train_op)
    self.assertIsNone(spec.export_outputs)
    _assert_no_hooks(self, spec)

    # Assert predictions, loss, and metrics.
    tol = 1e-3
    with self.test_session() as sess:
      _initialize_variables(self, spec.scaffold)
      self.assertIsNone(spec.scaffold.summary_op)
      value_ops = {k: spec.eval_metric_ops[k][0] for k in spec.eval_metric_ops}
      update_ops = {k: spec.eval_metric_ops[k][1] for k in spec.eval_metric_ops}
      loss, metrics = sess.run((spec.loss, update_ops))
      self.assertAllClose(expected_loss, loss, rtol=tol, atol=tol)
      # Check results of both update (in `metrics`) and value ops.
      self.assertAllClose(expected_metrics, metrics, rtol=tol, atol=tol)
      self.assertAllClose(
          expected_metrics, {k: value_ops[k].eval() for k in value_ops},
          rtol=tol,
          atol=tol)
예제 #41
0
  def test_eval_labels_none(self):
    """Tests that error is raised when labels is None."""
    head = head_lib.multi_label_head(n_classes=2)

    with self.assertRaisesRegexp(
        ValueError, r'You must provide a labels Tensor\. Given: None\.'):
      head.create_estimator_spec(
          features={'x': np.array(((42,),), dtype=np.int32)},
          mode=model_fn.ModeKeys.EVAL,
          logits=np.array([[-10., 10.], [-15., 10.]], dtype=np.float32),
          labels=None)
예제 #42
0
  def test_eval_labels_none(self):
    """Tests that error is raised when labels is None."""
    head = head_lib.multi_label_head(n_classes=2)

    with self.assertRaisesRegexp(
        ValueError, r'You must provide a labels Tensor\. Given: None\.'):
      head.create_estimator_spec(
          features={'x': np.array(((42,),), dtype=np.int32)},
          mode=model_fn.ModeKeys.EVAL,
          logits=np.array([[-10., 10.], [-15., 10.]], dtype=np.float32),
          labels=None)
예제 #43
0
  def test_eval_with_weights(self):
    n_classes = 2
    head = head_lib.multi_label_head(n_classes, weight_column='label_weights')

    logits = np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)
    labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
    # For large logits, sigmoid cross entropy loss is approximated as:
    # loss = labels * (logits < 0) * (-logits) +
    #        (1 - labels) * (logits > 0) * logits =>
    # expected_unweighted_loss = [[10., 10.], [15., 0.]]
    # Average over classes, weighted sum over examples.
    expected_loss = 25.

    spec = head.create_estimator_spec(
        features={
            'x': np.array([[41], [42]], dtype=np.int32),
            'label_weights': np.array([[1.], [2.]], dtype=np.float32),
        },
        mode=model_fn.ModeKeys.EVAL,
        logits=logits,
        labels=labels)

    keys = metric_keys.MetricKeys
    expected_metrics = {
        # Average loss over weighted examples.
        keys.LOSS_MEAN: expected_loss / 3,
        # auc and auc_pr cannot be reliably calculated for only 4 samples, but
        # this assert tests that the algorithm remains consistent.
        keys.AUC: 0.2000,
        keys.AUC_PR: 0.7833,
    }

    # Assert spec contains expected tensors.
    self.assertIsNotNone(spec.loss)
    self.assertItemsEqual(expected_metrics.keys(), spec.eval_metric_ops.keys())
    self.assertIsNone(spec.train_op)
    self.assertIsNone(spec.export_outputs)
    _assert_no_hooks(self, spec)

    # Assert predictions, loss, and metrics.
    tol = 1e-3
    with self.test_session() as sess:
      _initialize_variables(self, spec.scaffold)
      self.assertIsNone(spec.scaffold.summary_op)
      value_ops = {k: spec.eval_metric_ops[k][0] for k in spec.eval_metric_ops}
      update_ops = {k: spec.eval_metric_ops[k][1] for k in spec.eval_metric_ops}
      loss, metrics = sess.run((spec.loss, update_ops))
      self.assertAllClose(expected_loss, loss, rtol=tol, atol=tol)
      # Check results of both update (in `metrics`) and value ops.
      self.assertAllClose(expected_metrics, metrics, rtol=tol, atol=tol)
      self.assertAllClose(
          expected_metrics, {k: value_ops[k].eval() for k in value_ops},
          rtol=tol,
          atol=tol)
예제 #44
0
  def test_train_create_loss_two_heads_with_weights(self):
    # Use different example weighting for each head weighting.
    weights1 = np.array([[1.], [2.]], dtype=np.float32)
    weights2 = np.array([[2.], [3.]])
    head1 = head_lib.multi_label_head(n_classes=2, name='head1',
                                      weight_column='weights1')
    head2 = head_lib.multi_label_head(n_classes=3, name='head2',
                                      weight_column='weights2')
    multi_head = multi_head_lib.multi_head(
        [head1, head2], head_weights=[1., 2.])

    logits = {
        'head1': np.array([[-10., 10.], [-15., 10.]], dtype=np.float32),
        'head2': np.array([[20., -20., 20.], [-30., 20., -20.]],
                          dtype=np.float32),
    }
    labels = {
        'head1': np.array([[1, 0], [1, 1]], dtype=np.int64),
        'head2': np.array([[0, 1, 0], [1, 1, 0]], dtype=np.int64),
    }
    weighted_sum_loss, example_weight_sum, _ = multi_head.create_loss(
        features={
            'x': np.array(((42,),), dtype=np.int32),
            'weights1': weights1,
            'weights2': weights2
        },
        mode=model_fn.ModeKeys.TRAIN,
        logits=logits,
        labels=labels)
    tol = 1e-3
    with self.test_session():
      # loss of the first head is [[(10 + 10) / 2], [(15 + 0) / 2]]
      # = [10, 7.5]
      # weighted_sum_loss = 1 * 10 + 2 * 7.5 = 25
      # loss of the second head is [[(20 + 20 + 20) / 3], [(30 + 0 + 0) / 3]]
      # = [20, 10]
      # weighted_sum_loss = 2 * 20 + 3 * 10 = 70
      # head-weighted merge = 1 * 25 + 2 * 70 = 165
      self.assertAllClose(165, weighted_sum_loss.eval(), rtol=tol, atol=tol)
      # example_weight_sum = 1 * (1 + 2) + 2 * (2 + 3) = 13
      self.assertAllClose(13., example_weight_sum.eval(), rtol=tol, atol=tol)
예제 #45
0
 def test_train(self):
   head = head_lib.multi_label_head(n_classes=2)
   logits = np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)
   labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
   # For large logits, sigmoid cross entropy loss is approximated as:
   # loss = labels * (logits < 0) * (-logits) +
   #        (1 - labels) * (logits > 0) * logits =>
   # expected_unweighted_loss = [[10., 10.], [15., 0.]]
   # Average over classes, sum over weights.
   expected_loss = 17.5
   self._test_train(
       head=head, logits=logits, labels=labels, expected_loss=expected_loss)
예제 #46
0
 def test_train(self):
   head = head_lib.multi_label_head(n_classes=2)
   logits = np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)
   labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
   # For large logits, sigmoid cross entropy loss is approximated as:
   # loss = labels * (logits < 0) * (-logits) +
   #        (1 - labels) * (logits > 0) * logits =>
   # expected_unweighted_loss = [[10., 10.], [15., 0.]]
   # Average over classes, sum over weights.
   expected_loss = 17.5
   self._test_train(
       head=head, logits=logits, labels=labels, expected_loss=expected_loss)
예제 #47
0
  def test_eval(self):
    n_classes = 2
    head = head_lib.multi_label_head(n_classes)

    logits = np.array([[-1., 1.], [-1.5, 1.5]], dtype=np.float32)
    labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
    # loss = labels * -log(sigmoid(logits)) +
    #        (1 - labels) * -log(1 - sigmoid(logits))
    # Average over classes, and sum over examples.
    expected_loss = (
        np.sum(_sigmoid_cross_entropy(labels=labels, logits=logits)) / n_classes
    )

    spec = head.create_estimator_spec(
        features={'x': np.array(((42,),), dtype=np.int32)},
        mode=model_fn.ModeKeys.EVAL,
        logits=logits,
        labels=labels)

    keys = metric_keys.MetricKeys
    expected_metrics = {
        # Average loss over examples.
        keys.LOSS_MEAN: expected_loss / 2,
        # auc and auc_pr cannot be reliably calculated for only 4 samples, but
        # this assert tests that the algorithm remains consistent.
        keys.AUC: 0.3333,
        keys.AUC_PR: 0.7639,
    }

    # Assert spec contains expected tensors.
    self.assertIsNotNone(spec.loss)
    self.assertItemsEqual(expected_metrics.keys(), spec.eval_metric_ops.keys())
    self.assertIsNone(spec.train_op)
    self.assertIsNone(spec.export_outputs)
    _assert_no_hooks(self, spec)

    # Assert predictions, loss, and metrics.
    tol = 1e-3
    with self.test_session() as sess:
      _initialize_variables(self, spec.scaffold)
      self.assertIsNone(spec.scaffold.summary_op)
      value_ops = {k: spec.eval_metric_ops[k][0] for k in spec.eval_metric_ops}
      update_ops = {k: spec.eval_metric_ops[k][1] for k in spec.eval_metric_ops}
      loss, metrics = sess.run((spec.loss, update_ops))
      self.assertAllClose(expected_loss, loss, rtol=tol, atol=tol)
      # Check results of both update (in `metrics`) and value ops.
      self.assertAllClose(expected_metrics, metrics, rtol=tol, atol=tol)
      self.assertAllClose(
          expected_metrics, {k: value_ops[k].eval() for k in value_ops},
          rtol=tol,
          atol=tol)
예제 #48
0
    def test_train_one_head(self):
        head1 = head_lib.multi_label_head(n_classes=2, name='head1')
        multi_head = multi_head_lib.multi_head([head1])

        logits = {
            'head1': np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)
        }
        labels = {'head1': np.array([[1, 0], [1, 1]], dtype=np.int64)}
        # For large logits, sigmoid cross entropy loss is approximated as:
        # loss = labels * (logits < 0) * (-logits) +
        #        (1 - labels) * (logits > 0) * logits =>
        # expected_unweighted_loss = [[10., 10.], [15., 0.]]
        # loss = ( (10 + 10) / 2 + (15 + 0) / 2 ) / 2 = 8.75
        expected_loss = 8.75
        expected_train_result = 'my_train_op'

        def _train_op_fn(loss):
            return string_ops.string_join([
                constant_op.constant(expected_train_result),
                string_ops.as_string(loss, precision=3)
            ])

        spec = multi_head.create_estimator_spec(
            features={'x': np.array(((42, ), ), dtype=np.int32)},
            mode=model_fn.ModeKeys.TRAIN,
            logits=logits,
            labels=labels,
            train_op_fn=_train_op_fn)

        self.assertIsNotNone(spec.loss)
        self.assertEqual({}, spec.eval_metric_ops)
        self.assertIsNotNone(spec.train_op)
        self.assertIsNone(spec.export_outputs)
        _assert_no_hooks(self, spec)

        # Assert predictions, loss, train_op, and summaries.
        tol = 1e-3
        with self.cached_session() as sess:
            _initialize_variables(self, spec.scaffold)
            self.assertIsNotNone(spec.scaffold.summary_op)
            loss, train_result, summary_str = sess.run(
                (spec.loss, spec.train_op, spec.scaffold.summary_op))
            self.assertAllClose(expected_loss, loss, rtol=tol, atol=tol)
            self.assertEqual(
                six.b('{0:s}{1:.3f}'.format(expected_train_result,
                                            expected_loss)), train_result)
            _assert_simple_summaries(
                self, {
                    metric_keys.MetricKeys.LOSS: expected_loss,
                    metric_keys.MetricKeys.LOSS + '/head1': expected_loss,
                }, summary_str, tol)
예제 #49
0
  def test_train_create_loss_one_head(self):
    head1 = head_lib.multi_label_head(n_classes=2, name='head1')
    multi_head = multi_head_lib.multi_head([head1])

    logits = {'head1': np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)}
    labels = {'head1': np.array([[1, 0], [1, 1]], dtype=np.int64)}
    with self.assertRaisesRegexp(
        NotImplementedError,
        r'create_loss not yet implemented for MultiHead\.'):
      multi_head.create_loss(
          features={'x': np.array(((42,),), dtype=np.int32)},
          mode=model_fn.ModeKeys.TRAIN,
          logits=logits,
          labels=labels)
예제 #50
0
  def test_train_create_loss_two_heads_with_weights(self):
    head1 = head_lib.multi_label_head(n_classes=2, name='head1')
    head2 = head_lib.multi_label_head(n_classes=3, name='head2')
    multi_head = multi_head_lib.multi_head(
        [head1, head2], head_weights=[1., 2.])

    logits = {
        'head1': np.array([[-10., 10.], [-15., 10.]], dtype=np.float32),
        'head2': np.array([[20., -20., 20.], [-30., 20., -20.]],
                          dtype=np.float32),
    }
    labels = {
        'head1': np.array([[1, 0], [1, 1]], dtype=np.int64),
        'head2': np.array([[0, 1, 0], [1, 1, 0]], dtype=np.int64),
    }
    with self.assertRaisesRegexp(
        NotImplementedError,
        r'create_loss not yet implemented for MultiHead\.'):
      multi_head.create_loss(
          features={'x': np.array(((42,),), dtype=np.int32)},
          mode=model_fn.ModeKeys.TRAIN,
          logits=logits,
          labels=labels)
예제 #51
0
    def test_eval_with_thresholds(self):
        n_classes = 2
        thresholds = [0.25, 0.5, 0.75]
        head = head_lib.multi_label_head(n_classes, thresholds=thresholds)

        logits = np.array([[-1., 1.], [-1.5, 1.5]], dtype=np.float32)
        labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
        # loss = labels * -log(sigmoid(logits)) +
        #        (1 - labels) * -log(1 - sigmoid(logits))
        # Average over classes, and sum over examples.
        expected_loss = (
            np.sum(_sigmoid_cross_entropy(labels=labels, logits=logits)) /
            n_classes)

        keys = metric_keys.MetricKeys
        expected_metrics = {
            # Average loss over examples.
            keys.LOSS_MEAN:
            expected_loss / 2,
            # auc and auc_pr cannot be reliably calculated for only 4 samples, but
            # this assert tests that the algorithm remains consistent.
            keys.AUC:
            0.3333,
            keys.AUC_PR:
            0.7639,
            keys.ACCURACY_AT_THRESHOLD % thresholds[0]:
            2. / 4.,
            keys.PRECISION_AT_THRESHOLD % thresholds[0]:
            2. / 3.,
            keys.RECALL_AT_THRESHOLD % thresholds[0]:
            2. / 3.,
            keys.ACCURACY_AT_THRESHOLD % thresholds[1]:
            1. / 4.,
            keys.PRECISION_AT_THRESHOLD % thresholds[1]:
            1. / 2.,
            keys.RECALL_AT_THRESHOLD % thresholds[1]:
            1. / 3.,
            keys.ACCURACY_AT_THRESHOLD % thresholds[2]:
            2. / 4.,
            keys.PRECISION_AT_THRESHOLD % thresholds[2]:
            1. / 1.,
            keys.RECALL_AT_THRESHOLD % thresholds[2]:
            1. / 3.,
        }

        self._test_eval(head=head,
                        logits=logits,
                        labels=labels,
                        expected_loss=expected_loss,
                        expected_metrics=expected_metrics)
예제 #52
0
  def test_train_with_weights(self):
    n_classes = 2
    head = head_lib.multi_label_head(n_classes, weight_column='example_weights')

    logits = np.array([[-10., 10.], [-15., 10.]], dtype=np.float32)
    labels = np.array([[1, 0], [1, 1]], dtype=np.int64)
    # For large logits, sigmoid cross entropy loss is approximated as:
    # loss = labels * (logits < 0) * (-logits) +
    #        (1 - labels) * (logits > 0) * logits =>
    # expected_unweighted_loss = [[10., 10.], [15., 0.]]
    # Average over classes, weighted sum over examples.
    expected_loss = 25.
    expected_train_result = 'my_train_op'
    def _train_op_fn(loss):
      return string_ops.string_join(
          [constant_op.constant(expected_train_result),
           string_ops.as_string(loss, precision=3)])

    spec = head.create_estimator_spec(
        features={
            'x': np.array([[41], [42]], dtype=np.int32),
            'example_weights': np.array([[1.], [2.]], dtype=np.float32),
        },
        mode=model_fn.ModeKeys.TRAIN,
        logits=logits,
        labels=labels,
        train_op_fn=_train_op_fn)

    self.assertIsNotNone(spec.loss)
    self.assertEqual({}, spec.eval_metric_ops)
    self.assertIsNotNone(spec.train_op)
    self.assertIsNone(spec.export_outputs)
    _assert_no_hooks(self, spec)

    # Assert predictions, loss, train_op, and summaries.
    tol = 1e-3
    with self.test_session() as sess:
      _initialize_variables(self, spec.scaffold)
      self.assertIsNotNone(spec.scaffold.summary_op)
      loss, train_result, summary_str = sess.run((spec.loss, spec.train_op,
                                                  spec.scaffold.summary_op))
      self.assertAllClose(expected_loss, loss, rtol=tol, atol=tol)
      self.assertEqual(
          six.b('{0:s}{1:.3f}'.format(expected_train_result, expected_loss)),
          train_result)
      _assert_simple_summaries(self, {
          metric_keys.MetricKeys.LOSS: expected_loss,
          # Average loss over weighted examples.
          metric_keys.MetricKeys.LOSS_MEAN: expected_loss / 3,
      }, summary_str, tol)
예제 #53
0
    def test_train_create_loss_two_heads_with_weights(self):
        head1 = head_lib.multi_label_head(n_classes=2, name='head1')
        head2 = head_lib.multi_label_head(n_classes=3, name='head2')
        multi_head = multi_head_lib.multi_head([head1, head2],
                                               head_weights=[1., 2.])

        logits = {
            'head1':
            np.array([[-10., 10.], [-15., 10.]], dtype=np.float32),
            'head2':
            np.array([[20., -20., 20.], [-30., 20., -20.]], dtype=np.float32),
        }
        labels = {
            'head1': np.array([[1, 0], [1, 1]], dtype=np.int64),
            'head2': np.array([[0, 1, 0], [1, 1, 0]], dtype=np.int64),
        }
        with self.assertRaisesRegexp(
                NotImplementedError,
                r'create_loss not yet implemented for MultiHead\.'):
            multi_head.create_loss(
                features={'x': np.array(((42, ), ), dtype=np.int32)},
                mode=model_fn.ModeKeys.TRAIN,
                logits=logits,
                labels=labels)
예제 #54
0
  def test_eval_tpu(self):
    head1 = head_lib.multi_label_head(n_classes=2, name='head1')
    head2 = head_lib.multi_label_head(n_classes=3, name='head2')
    multi_head = multi_head_lib.multi_head(
        [head1, head2], head_weights=[1., 2.])

    logits = {
        'head1': np.array([[-10., 10.], [-15., 10.]], dtype=np.float32),
        'head2': np.array([[20., -20., 20.], [-30., 20., -20.]],
                          dtype=np.float32),
    }
    labels = {
        'head1': np.array([[1, 0], [1, 1]], dtype=np.int64),
        'head2': np.array([[0, 1, 0], [1, 1, 0]], dtype=np.int64),
    }

    with self.assertRaisesRegexp(
        NotImplementedError,
        r'TPU evaluation is not implemented for multi_head\.'):
      multi_head._create_tpu_estimator_spec(
          features={'x': np.array(((42,),), dtype=np.int32)},
          mode=model_fn.ModeKeys.EVAL,
          logits=logits,
          labels=labels)
예제 #55
0
  def test_train_labels_none(self):
    """Tests that error is raised when labels is None."""
    head = head_lib.multi_label_head(n_classes=2)
    def _no_op_train_fn(loss):
      del loss
      return control_flow_ops.no_op()

    with self.assertRaisesRegexp(
        ValueError, r'You must provide a labels Tensor\. Given: None\.'):
      head.create_estimator_spec(
          features={'x': np.array(((42,),), dtype=np.int32)},
          mode=model_fn.ModeKeys.TRAIN,
          logits=np.array([[-10., 10.], [-15., 10.]], dtype=np.float32),
          labels=None,
          train_op_fn=_no_op_train_fn)
예제 #56
0
  def test_train_labels_none(self):
    """Tests that error is raised when labels is None."""
    head = head_lib.multi_label_head(n_classes=2)
    def _no_op_train_fn(loss):
      del loss
      return control_flow_ops.no_op()

    with self.assertRaisesRegexp(
        ValueError, r'You must provide a labels Tensor\. Given: None\.'):
      head.create_estimator_spec(
          features={'x': np.array(((42,),), dtype=np.int32)},
          mode=model_fn.ModeKeys.TRAIN,
          logits=np.array([[-10., 10.], [-15., 10.]], dtype=np.float32),
          labels=None,
          train_op_fn=_no_op_train_fn)