def testMultidimensionalAcculumator(self): with self.cached_session() as sess: accumulator = stats_accumulator_ops.StatsAccumulator( stamp_token=0, gradient_shape=tensor_shape.TensorShape([]), hessian_shape=tensor_shape.TensorShape([])) with ops.control_dependencies([accumulator.initializer]): op1 = accumulator.add(stamp_token=0, partition_ids=[1, 2, 1], feature_ids=[[2, 2], [3, 0], [2, 2]], gradients=[0.1, 0.3, 0.8], hessians=[0.2, 0.4, -9]) op2 = accumulator.add(0, [2, 1], [[3, 1], [2, 2]], [0.1, 1], [0.2, -1]) with ops.control_dependencies([op1, op2]): num_updates, partition, bucket_ids, grads, hessians = accumulator.flush( stamp_token=0, next_stamp_token=1) num_updates, partition, bucket_ids, grads, hessians = sess.run( [num_updates, partition, bucket_ids, grads, hessians]) result = _AccumulatorResultToDict(partition, bucket_ids, grads, hessians) self.assertEqual(num_updates, 2) self.assertEqual(len(result), 3) # Key is partition, bucket, dimension. self.assertAllClose(result[(1, 2, 2)], [1.9, -9.8]) self.assertAllClose(result[(2, 3, 0)], [0.3, 0.4]) self.assertAllClose(result[(2, 3, 1)], [0.1, 0.2])
def testDropStaleUpdate(self): with self.cached_session() as sess: accumulator = stats_accumulator_ops.StatsAccumulator( stamp_token=0, gradient_shape=tensor_shape.TensorShape([]), hessian_shape=tensor_shape.TensorShape([])) with ops.control_dependencies([accumulator.initializer]): op1 = accumulator.add(stamp_token=0, partition_ids=[1, 2], feature_ids=[[2, 0], [3, 0]], gradients=[0.1, 0.3], hessians=[0.2, 0.4]) op2 = accumulator.add(stamp_token=-1, partition_ids=[1], feature_ids=[[2, 0]], gradients=[0.1], hessians=[0.2]) with ops.control_dependencies([op1, op2]): num_updates, partition, feature, grads, hessians = accumulator.flush( stamp_token=0, next_stamp_token=1) num_updates, partition, feature, grads, hessians = sess.run( [num_updates, partition, feature, grads, hessians]) result = _AccumulatorResultToDict(partition, feature, grads, hessians) self.assertEqual(num_updates, 1) self.assertEqual(len(result), 2) self.assertAllClose(result[(1, 2, 0)], [0.1, 0.2]) self.assertAllClose(result[(2, 3, 0)], [0.3, 0.4])
def testDeserialize(self): with self.cached_session() as sess: accumulator = stats_accumulator_ops.StatsAccumulator( stamp_token=0, gradient_shape=tensor_shape.TensorShape([]), hessian_shape=tensor_shape.TensorShape([])) with ops.control_dependencies([accumulator.initializer]): # These will be deleted due to deserialize call. op1 = accumulator.add(stamp_token=0, partition_ids=[1, 2], feature_ids=[[2, 0], [3, 1]], gradients=[0.1, 0.3], hessians=[0.2, 0.4]) with ops.control_dependencies([op1]): deserialize = (accumulator.saveable.deserialize( stamp_token=2, num_updates=3, partition_ids=[3, 4], feature_ids=[[5, 0], [6, 2]], gradients=[0.4, 0.5], hessians=[0.6, 0.7])) with ops.control_dependencies([deserialize]): num_updates, partition, feature, grads, hessians = accumulator.flush( stamp_token=2, next_stamp_token=3) num_updates, partition, feature, grads, hessians = sess.run( [num_updates, partition, feature, grads, hessians]) result = _AccumulatorResultToDict(partition, feature, grads, hessians) self.assertEqual(num_updates, 3) self.assertEqual(len(result), 2) self.assertAllClose(result[(3, 5, 0)], [0.4, 0.6]) self.assertAllClose(result[(4, 6, 2)], [0.5, 0.7])
def testMakeSummary(self): with self.cached_session() as sess: accumulator = stats_accumulator_ops.StatsAccumulator( stamp_token=0, gradient_shape=tensor_shape.TensorShape([2]), hessian_shape=tensor_shape.TensorShape([2, 2])) partition, feature, grads, hessians = accumulator._make_summary( partition_ids=[1, 2, 1], feature_ids=[[2, 0], [3, 2], [2, 0]], # Two values for gradients, gradients=[[0.1, 0.1], [0.2, 0.2], [0.10, 0.11]], # A 2x2 matrix for each hessian. hessians=[[[0.01, 0.02], [0.03, 0.04]], [[0.05, 0.06], [0.07, 0.08]], [[0.011, 0.022], [0.033, 0.044]]]) partition, feature, grads, hessians = sess.run( [partition, feature, grads, hessians]) result = _AccumulatorResultToDict(partition, feature, grads, hessians) self.assertEqual(len(result), 2) self.assertAllClose(result[(1, 2, 0)][0], [0.20, 0.21]) self.assertAllClose(result[(1, 2, 0)][1], [[0.021, 0.042], [0.063, 0.084]]) self.assertAllClose(result[(2, 3, 2)][0], [0.2, 0.2]) self.assertAllClose(result[(2, 3, 2)][1], [[0.05, 0.06], [0.07, 0.08]])
def __init__(self, l1_regularization, l2_regularization, tree_complexity_regularization, min_node_weight, feature_column_group_id, epsilon, num_quantiles, gradient_shape, hessian_shape, multiclass_strategy, init_stamp_token=0, loss_uses_sum_reduction=False, name=None): """Initialize the internal state for this split handler. Args: l1_regularization: L1 regularization applied for this split handler. l2_regularization: L2 regularization applied for this split handler. tree_complexity_regularization: Tree complexity regularization applied for this split handler. min_node_weight: Minimum sum of weights of examples in each partition to be considered for splitting. feature_column_group_id: Feature column group index. epsilon: A float, the error bound for quantile computation. num_quantiles: An int, the number of buckets to create from the histogram. gradient_shape: A TensorShape, containing shape of gradients. hessian_shape: A TensorShape, containing shape of hessians. multiclass_strategy: Strategy describing how to treat multiclass problems. init_stamp_token: A tensor containing an scalar for initial stamp of the stamped objects. loss_uses_sum_reduction: A scalar boolean tensor that specifies whether SUM or MEAN reduction was used for the loss. name: An optional handler name. """ super(InequalitySplitHandler, self).__init__( name=name, l1_regularization=l1_regularization, l2_regularization=l2_regularization, tree_complexity_regularization=tree_complexity_regularization, min_node_weight=min_node_weight, feature_column_group_id=feature_column_group_id, gradient_shape=gradient_shape, hessian_shape=hessian_shape, multiclass_strategy=multiclass_strategy, loss_uses_sum_reduction=loss_uses_sum_reduction) self._stats_accumulator = stats_accumulator_ops.StatsAccumulator( init_stamp_token, gradient_shape, hessian_shape, name="StatsAccumulator/{}".format(self._name)) # Allocate both stats accumulator and quantile accumulator on the same # device so that we can build splits with fewer RPCs. with ops.colocate_with(self._stats_accumulator.resource_handle): self._quantile_accumulator = quantile_ops.QuantileAccumulator( init_stamp_token, epsilon=epsilon, num_quantiles=num_quantiles, name="QuantileAccumulator/{}".format(self._name))
def __init__( self, sparse_int_column, l1_regularization, l2_regularization, tree_complexity_regularization, min_node_weight, feature_column_group_id, gradient_shape, hessian_shape, multiclass_strategy, init_stamp_token=0, loss_uses_sum_reduction=False, weak_learner_type=learner_pb2.LearnerConfig.NORMAL_DECISION_TREE, name=None): """Initialize the internal state for this split handler. Args: sparse_int_column: A `SparseTensor` column with int64 values associated with this handler. l1_regularization: L1 regularization applied for this split handler. l2_regularization: L2 regularization applied for this split handler. tree_complexity_regularization: Tree complexity regularization applied for this split handler. min_node_weight: Minimum sum of weights of examples in each partition to be considered for splitting. feature_column_group_id: Feature column group index. gradient_shape: A TensorShape, containing shape of gradients. hessian_shape: A TensorShape, containing shape of hessians. multiclass_strategy: Strategy describing how to treat multiclass problems. init_stamp_token: A tensor containing an scalar for initial stamp of the stamped objects. loss_uses_sum_reduction: A scalar boolean tensor that specifies whether SUM or MEAN reduction was used for the loss. weak_learner_type: Specifies the type of weak learner to use. name: An optional handler name. """ super(EqualitySplitHandler, self).__init__( l1_regularization=l1_regularization, l2_regularization=l2_regularization, tree_complexity_regularization=tree_complexity_regularization, min_node_weight=min_node_weight, feature_column_group_id=feature_column_group_id, gradient_shape=gradient_shape, hessian_shape=hessian_shape, multiclass_strategy=multiclass_strategy, loss_uses_sum_reduction=loss_uses_sum_reduction, name=name) self._stats_accumulator = stats_accumulator_ops.StatsAccumulator( init_stamp_token, gradient_shape, hessian_shape, name="StatsAccumulator/{}".format(self._name)) self._sparse_int_column = sparse_int_column self._weak_learner_type = weak_learner_type
def testSerialize(self): with self.cached_session() as sess: accumulator = stats_accumulator_ops.StatsAccumulator( stamp_token=0, gradient_shape=tensor_shape.TensorShape([2]), hessian_shape=tensor_shape.TensorShape([2, 2])) with ops.control_dependencies([accumulator.initializer]): op1 = accumulator.add( stamp_token=0, partition_ids=[1, 2], feature_ids=[[2, 0], [3, 0]], # Two values for gradients, gradients=[[0.1, 0.1], [0.2, 0.2]], # A 2x2 matrix for each hessian. hessians=[[[0.01, 0.02], [0.03, 0.04]], [[0.05, 0.06], [0.07, 0.08]]]) with ops.control_dependencies([op1]): (stamp_token, num_updates_1, partition_1, feature_1, grads_1, hessians_1) = accumulator.saveable.serialize() # Make sure that the accumulator hasn't changed during serialization. with ops.control_dependencies([stamp_token]): num_updates_2, partition_2, feature_2, grads_2, hessians_2 = ( accumulator.flush(stamp_token=0, next_stamp_token=1)) (stamp_token, num_updates_1, partition_1, feature_1, grads_1, hessians_1, num_updates_2, partition_2, feature_2, grads_2, hessians_2) = sess.run([ stamp_token, num_updates_1, partition_1, feature_1, grads_1, hessians_1, num_updates_2, partition_2, feature_2, grads_2, hessians_2 ]) result_1 = _AccumulatorResultToDict(partition_1, feature_1, grads_1, hessians_1) result_2 = _AccumulatorResultToDict(partition_2, feature_2, grads_2, hessians_2) self.assertEqual(num_updates_1, 1) self.assertEqual(num_updates_2, 1) self.assertEqual(len(result_1), 2) self.assertAllClose(result_1[(1, 2, 0)][0], [0.1, 0.1]) self.assertAllClose(result_1[(1, 2, 0)][1], [[0.01, 0.02], [0.03, 0.04]]) self.assertAllClose(result_1[(2, 3, 0)][0], [0.2, 0.2]) self.assertAllClose(result_1[(2, 3, 0)][1], [[0.05, 0.06], [0.07, 0.08]]) self.assertAllEqual(result_1[1, 2, 0][0], result_2[1, 2, 0][0]) self.assertAllEqual(result_1[1, 2, 0][1], result_2[1, 2, 0][1]) self.assertAllEqual(result_1[2, 3, 0][0], result_2[2, 3, 0][0]) self.assertAllEqual(result_1[2, 3, 0][1], result_2[2, 3, 0][1])
def testDeserialize(self): with self.cached_session() as sess: accumulator = stats_accumulator_ops.StatsAccumulator( stamp_token=0, gradient_shape=tensor_shape.TensorShape([2]), hessian_shape=tensor_shape.TensorShape([2, 2])) with ops.control_dependencies([accumulator.initializer]): # These will be deleted due to deserialize call. op1 = accumulator.add( stamp_token=0, partition_ids=[1, 2], feature_ids=[[2, 0], [3, 0]], # Two values for gradients, gradients=[[0.1, 0.1], [0.2, 0.2]], # A 2x2 matrix for each hessian. hessians=[[[0.01, 0.02], [0.03, 0.04]], [[0.05, 0.06], [0.07, 0.08]]]) with ops.control_dependencies([op1]): deserialize = accumulator.saveable.deserialize( stamp_token=2, num_updates=3, partition_ids=[3, 4], feature_ids=[[4, 0], [5, 0]], # Two values for gradients, gradients=[[0.3, 0.3], [0.5, 0.5]], # A 2x2 matrix for each hessian. hessians=[[[0.03, 0.04], [0.05, 0.06]], [[0.07, 0.08], [0.09, 0.10]]]) with ops.control_dependencies([deserialize]): num_updates, partition, feature, grads, hessians = accumulator.flush( stamp_token=2, next_stamp_token=3) num_updates, partition, feature, grads, hessians = sess.run( [num_updates, partition, feature, grads, hessians]) result = _AccumulatorResultToDict(partition, feature, grads, hessians) self.assertEqual(num_updates, 3) self.assertEqual(len(result), 2) self.assertAllClose(result[(3, 4, 0)][0], [0.3, 0.3]) self.assertAllClose(result[(3, 4, 0)][1], [[0.03, 0.04], [0.05, 0.06]]) self.assertAllClose(result[(4, 5, 0)][0], [0.5, 0.5]) self.assertAllClose(result[(4, 5, 0)][1], [[0.07, 0.08], [0.09, 0.10]])
def testMakeSummary(self): with self.cached_session() as sess: accumulator = stats_accumulator_ops.StatsAccumulator( stamp_token=0, gradient_shape=tensor_shape.TensorShape([]), hessian_shape=tensor_shape.TensorShape([])) partition, feature, grads, hessians = accumulator._make_summary( partition_ids=[1, 2, 1], feature_ids=[[2, 0], [3, 1], [2, 0]], gradients=[0.1, 0.3, 0.1], hessians=[0.2, 0.4, 0.2]) partition, feature, grads, hessians = sess.run( [partition, feature, grads, hessians]) result = _AccumulatorResultToDict(partition, feature, grads, hessians) self.assertEqual(len(result), 2) self.assertAllClose(result[(1, 2, 0)], [0.2, 0.4]) self.assertAllClose(result[(2, 3, 1)], [0.3, 0.4])
def testDropStaleUpdate(self): with self.cached_session() as sess: accumulator = stats_accumulator_ops.StatsAccumulator( stamp_token=0, gradient_shape=tensor_shape.TensorShape([2]), hessian_shape=tensor_shape.TensorShape([2, 2])) with ops.control_dependencies([accumulator.initializer]): op1 = accumulator.add( stamp_token=0, partition_ids=[1, 2], feature_ids=[[2, 5], [3, 0]], # Two values for gradients, gradients=[[0.1, 0.1], [0.2, 0.2]], # A 2x2 matrix for each hessian. hessians=[[[0.01, 0.02], [0.03, 0.04]], [[0.05, 0.06], [0.07, 0.08]]]) op2 = accumulator.add(stamp_token=-1, partition_ids=[1], feature_ids=[[2, 5]], gradients=[[0.10, 0.11]], hessians=[[[0.011, 0.022], [0.033, 0.044]]]) with ops.control_dependencies([op1, op2]): num_updates, partition, feature, grads, hessians = accumulator.flush( stamp_token=0, next_stamp_token=1) num_updates, partition, feature, grads, hessians = sess.run( [num_updates, partition, feature, grads, hessians]) result = _AccumulatorResultToDict(partition, feature, grads, hessians) self.assertEqual(num_updates, 1) self.assertEqual(len(result), 2) self.assertAllClose(result[(1, 2, 5)][0], [0.1, 0.1]) self.assertAllClose(result[(1, 2, 5)][1], [[0.01, 0.02], [0.03, 0.04]]) self.assertAllClose(result[(2, 3, 0)][0], [0.2, 0.2]) self.assertAllClose(result[(2, 3, 0)][1], [[0.05, 0.06], [0.07, 0.08]])