def test_make_mean_squared_loss_fn(self):
        scores = [[0.2, 0.5, 0.3], [0.2, 0.3, 0.5]]
        labels = [[0., 0., 1.], [0., 0., 1.]]
        weights = [[2.], [1.]]
        weights_feature_name = 'weights'
        features = {weights_feature_name: weights}
        with self.cached_session():
            loss_fn_simple = ranking_losses.make_loss_fn(
                ranking_losses.RankingLossKey.MEAN_SQUARED_LOSS)
            self.assertAlmostEqual(
                loss_fn_simple(labels, scores, features).eval(),
                (_mean_squared_error(labels[0], scores[0]) +
                 _mean_squared_error(labels[1], scores[1])) / 6.,
                places=5)

            loss_fn_weighted = ranking_losses.make_loss_fn(
                ranking_losses.RankingLossKey.MEAN_SQUARED_LOSS,
                weights_feature_name=weights_feature_name)
            self.assertAlmostEqual(
                loss_fn_weighted(labels, scores, features).eval(),
                (_mean_squared_error(labels[0], scores[0]) * 2.0 +
                 _mean_squared_error(labels[1], scores[1])) / 6.,
                places=5)

            # Test loss reduction method.
            # Two reduction methods should return different loss values.
            loss_fn_1 = ranking_losses.make_loss_fn(
                ranking_losses.RankingLossKey.MEAN_SQUARED_LOSS,
                reduction=core_losses.Reduction.SUM)
            loss_fn_2 = ranking_losses.make_loss_fn(
                ranking_losses.RankingLossKey.MEAN_SQUARED_LOSS,
                reduction=core_losses.Reduction.MEAN)
            self.assertNotAlmostEqual(
                loss_fn_1(labels, scores, features).eval(),
                loss_fn_2(labels, scores, features).eval())
    def test_make_softmax_loss_fn(self):
        scores = [[1., 3., 2.], [1., 2., 3.]]
        labels = [[0., 0., 1.], [0., 0., 2.]]
        weights = [[2.], [1.]]
        weights_feature_name = 'weights'
        features = {weights_feature_name: weights}
        with self.cached_session():
            loss_fn_simple = ranking_losses.make_loss_fn(
                ranking_losses.RankingLossKey.SOFTMAX_LOSS)
            self.assertAlmostEqual(
                loss_fn_simple(labels, scores, features).eval(),
                -(math.log(_softmax(scores[0])[2]) +
                  math.log(_softmax(scores[1])[2]) * 2.) / 2.,
                places=5)

            loss_fn_weighted = ranking_losses.make_loss_fn(
                ranking_losses.RankingLossKey.SOFTMAX_LOSS,
                weights_feature_name=weights_feature_name)
            self.assertAlmostEqual(
                loss_fn_weighted(labels, scores, features).eval(),
                -(math.log(_softmax(scores[0])[2]) * 2. +
                  math.log(_softmax(scores[1])[2]) * 2. * 1.) / 2.,
                places=5)

            # Test loss reduction method.
            # Two reduction methods should return different loss values.
            loss_fn_1 = ranking_losses.make_loss_fn(
                ranking_losses.RankingLossKey.SOFTMAX_LOSS,
                reduction=core_losses.Reduction.SUM)
            loss_fn_2 = ranking_losses.make_loss_fn(
                ranking_losses.RankingLossKey.SOFTMAX_LOSS,
                reduction=core_losses.Reduction.MEAN)
            self.assertNotAlmostEqual(
                loss_fn_1(labels, scores, features).eval(),
                loss_fn_2(labels, scores, features).eval())
Example #3
0
    def compute_ranking_loss(self):
        self.loss_fn = losses.make_loss_fn('pairwise_logistic_loss', lambda_weight=losses.create_ndcg_lambda_weight(), name='ranking_loss_fn')
        self.ranking_loss = self.loss_fn(self.labels, self.grades, None)
        
        with tf.name_scope('l2') as scope:
            l2_cost = tf.zeros([])
            for var in tf.trainable_variables():
                l2_cost += tf.nn.l2_loss(var)

        self.cost = tf.identity(self.ranking_loss + self.opts.l2_weight * l2_cost, name="cost")
    def test_make_list_mle_loss_fn(self):
        scores = [[0., ln(3), ln(2)], [0., ln(2), ln(3)]]
        labels = [[0., 0., 1.], [0., 0., 2.]]
        weights = [[2.], [1.]]
        weights_feature_name = 'weights'
        features = {weights_feature_name: weights}
        with self.cached_session():
            loss_fn_simple = ranking_losses.make_loss_fn(
                ranking_losses.RankingLossKey.LIST_MLE_LOSS, seed=1)
            self.assertAlmostEqual(
                loss_fn_simple(labels, scores, features).eval(),
                -((ln(2. / (2 + 3 + 1)) + ln(3. / (3 + 1)) + ln(1. / 1)) +
                  (ln(3. / (3 + 2 + 1)) + ln(2. / (2 + 1)) + ln(1. / 1))) / 2,
                places=5)

            loss_fn_weighted = ranking_losses.make_loss_fn(
                ranking_losses.RankingLossKey.LIST_MLE_LOSS,
                weights_feature_name=weights_feature_name,
                seed=1)
            self.assertAlmostEqual(
                loss_fn_weighted(labels, scores, features).eval(),
                -(2 * (ln(2. / (2 + 3 + 1)) + ln(3. /
                                                 (3 + 1)) + ln(1. / 1)) + 1 *
                  (ln(3. / (3 + 2 + 1)) + ln(2. / (2 + 1)) + ln(1. / 1))) / 2,
                places=5)

            # Test loss reduction method.
            # Two reduction methods should return different loss values.
            loss_fn_1 = ranking_losses.make_loss_fn(
                ranking_losses.RankingLossKey.LIST_MLE_LOSS,
                reduction=core_losses.Reduction.SUM)
            loss_fn_2 = ranking_losses.make_loss_fn(
                ranking_losses.RankingLossKey.LIST_MLE_LOSS,
                reduction=core_losses.Reduction.MEAN)
            self.assertNotAlmostEqual(
                loss_fn_1(labels, scores, features).eval(),
                loss_fn_2(labels, scores, features).eval())
Example #5
0
 def setUp(self):
     super(GroupwiseRankingEstimatorTest, self).setUp()
     ops.reset_default_graph()
     self._model_dir = test.get_temp_dir()
     gfile.MakeDirs(self._model_dir)
     model_fn = model.make_groupwise_ranking_fn(
         _group_score_fn,
         group_size=2,
         transform_fn=feature.make_identity_transform_fn(
             ['context', 'weight']),
         ranking_head=head.create_ranking_head(
             loss_fn=losses.make_loss_fn(
                 losses.RankingLossKey.PAIRWISE_HINGE_LOSS,
                 weights_feature_name='weight'),
             optimizer=training.AdagradOptimizer(learning_rate=0.1)))
     self._estimator = estimator.Estimator(model_fn, self._model_dir)
    def test_make_loss_fn(self):
        scores = [[0.2, 0.5, 0.3], [0.2, 0.3, 0.5]]
        labels = [[0., 0., 1.], [0., 0., 1.]]
        weights = [[2.], [1.]]
        weights_feature_name = 'weights'
        features = {weights_feature_name: weights}
        with self.cached_session():
            pairwise_hinge_loss = ranking_losses._pairwise_hinge_loss(
                labels, scores).eval()
            pairwise_hinge_loss_weighted = ranking_losses._pairwise_hinge_loss(
                labels, scores, weights=weights).eval()
            mean_squared_loss = ranking_losses._mean_squared_loss(
                labels, scores).eval()
            mean_squared_loss_weighted = ranking_losses._mean_squared_loss(
                labels, scores, weights=weights).eval()

            loss_keys = [
                ranking_losses.RankingLossKey.PAIRWISE_HINGE_LOSS,
                ranking_losses.RankingLossKey.MEAN_SQUARED_LOSS
            ]
            loss_fn_simple = ranking_losses.make_loss_fn(loss_keys)
            self.assertAlmostEqual(loss_fn_simple(labels, scores,
                                                  features).eval(),
                                   pairwise_hinge_loss + mean_squared_loss,
                                   places=5)

            # With weighted examples.
            loss_fn_weighted_example = ranking_losses.make_loss_fn(
                loss_keys, weights_feature_name=weights_feature_name)
            self.assertAlmostEqual(
                loss_fn_weighted_example(labels, scores, features).eval(),
                pairwise_hinge_loss_weighted + mean_squared_loss_weighted,
                places=5)

            # With both weighted loss and weighted examples.
            loss_weights = [3., 2.]
            weighted_loss_fn_weighted_example = ranking_losses.make_loss_fn(
                loss_keys,
                loss_weights,
                weights_feature_name=weights_feature_name)
            self.assertAlmostEqual(
                weighted_loss_fn_weighted_example(labels, scores,
                                                  features).eval(),
                pairwise_hinge_loss_weighted * loss_weights[0] +
                mean_squared_loss_weighted * loss_weights[1],
                places=5)

            # Test loss reduction method.
            # Two reduction methods should return different loss values.
            loss_fn_1 = ranking_losses.make_loss_fn(
                loss_keys, reduction=core_losses.Reduction.SUM)
            loss_fn_2 = ranking_losses.make_loss_fn(
                loss_keys, reduction=core_losses.Reduction.MEAN)
            self.assertNotAlmostEqual(
                loss_fn_1(labels, scores, features).eval(),
                loss_fn_2(labels, scores, features).eval())

            # Test invalid inputs.
            with self.assertRaisesRegexp(
                    ValueError, r'loss_keys cannot be None or empty.'):
                ranking_losses.make_loss_fn([])

            with self.assertRaisesRegexp(
                    ValueError, r'loss_keys cannot be None or empty.'):
                ranking_losses.make_loss_fn('')

            with self.assertRaisesRegexp(
                    ValueError,
                    r'loss_keys and loss_weights must have the same size.'):
                ranking_losses.make_loss_fn(loss_keys, [2.0])

            invalid_loss_fn = ranking_losses.make_loss_fn(['invalid_key'])
            with self.assertRaisesRegexp(ValueError,
                                         r'Invalid loss_key: invalid_key.'):
                invalid_loss_fn(labels, scores, features).eval()
    def _check_make_pairwise_loss(self, loss_key):
        """Helper function to test `make_loss_fn`."""
        scores = [[1., 3., 2.], [1., 2., 3.]]
        labels = [[0., 0., 1.], [0., 0., 2.]]
        listwise_weights = [[2.], [1.]]
        listwise_weights_expanded = [[2.] * 3, [1.] * 3]
        itemwise_weights = [[2., 3., 4.], [1., 1., 1.]]
        default_weights = [1.] * 3
        weights_feature_name = 'weights'
        list_size = 3.
        features = {}

        loss_fn = ranking_losses.make_loss_fn(loss_key)
        with self.cached_session():
            # Individual lists.
            self.assertAlmostEqual(loss_fn([labels[0]], [scores[0]],
                                           features).eval(),
                                   _batch_aggregation([
                                       _pairwise_loss(labels[0], scores[0],
                                                      default_weights,
                                                      loss_key)
                                   ]),
                                   places=5)
            self.assertAlmostEqual(loss_fn([labels[1]], [scores[1]],
                                           features).eval(),
                                   _batch_aggregation([
                                       _pairwise_loss(labels[1], scores[1],
                                                      default_weights,
                                                      loss_key)
                                   ]),
                                   places=5)

            # Itemwise weights.
            loss_fn = ranking_losses.make_loss_fn(
                loss_key, weights_feature_name=weights_feature_name)
            features[weights_feature_name] = [itemwise_weights[0]]
            self.assertAlmostEqual(loss_fn([labels[0]], [scores[0]],
                                           features).eval(),
                                   _batch_aggregation([
                                       _pairwise_loss(labels[0], scores[0],
                                                      itemwise_weights[0],
                                                      loss_key)
                                   ]),
                                   places=5)

            features[weights_feature_name] = [itemwise_weights[1]]
            self.assertAlmostEqual(loss_fn([labels[1]], [scores[1]],
                                           features).eval(),
                                   _batch_aggregation([
                                       _pairwise_loss(labels[1], scores[1],
                                                      itemwise_weights[1],
                                                      loss_key)
                                   ]),
                                   places=5)

            # Multiple lists.
            features[weights_feature_name] = listwise_weights
            self.assertAlmostEqual(
                loss_fn(labels, scores, features).eval(),
                _batch_aggregation([
                    _pairwise_loss(labels[0], scores[0],
                                   listwise_weights_expanded[0], loss_key),
                    _pairwise_loss(labels[1], scores[1],
                                   listwise_weights_expanded[1], loss_key)
                ]),
                places=5)

            # Test LambdaWeight.
            lambda_weight = ranking_losses.DCGLambdaWeight(
                rank_discount_fn=lambda r: 1. / math_ops.log1p(r),
                smooth_fraction=1.)
            loss_fn = ranking_losses.make_loss_fn(
                loss_key,
                weights_feature_name=weights_feature_name,
                lambda_weight=lambda_weight)
            self.assertAlmostEqual(
                loss_fn(labels, scores, features).eval(),
                _batch_aggregation([
                    _pairwise_loss(labels[0],
                                   scores[0],
                                   listwise_weights_expanded[0],
                                   loss_key,
                                   rank_discount_form='LOG'),
                    _pairwise_loss(labels[1],
                                   scores[1],
                                   listwise_weights_expanded[1],
                                   loss_key,
                                   rank_discount_form='LOG')
                ]) * list_size,
                places=5)

            # Test loss reduction method.
            # Two reduction methods should return different loss values.
            loss_fn_1 = ranking_losses.make_loss_fn(
                loss_key, reduction=core_losses.Reduction.SUM)
            loss_fn_2 = ranking_losses.make_loss_fn(
                loss_key, reduction=core_losses.Reduction.MEAN)
            self.assertNotAlmostEqual(
                loss_fn_1(labels, scores, features).eval(),
                loss_fn_2(labels, scores, features).eval())