def testShapeWrong(self): with ops.Graph().as_default(): with self.assertRaisesRegex(ValueError, "Too many elements provided."): constant_op.constant_v1([1, 2, 3, 4, 5, 6, 7], shape=[5]) with self.assertRaisesRegex(TypeError, "Expected Tensor's shape"): constant_op.constant([1, 2, 3, 4, 5, 6, 7], shape=[5])
def get_empty_tensors(gradient_shape, hessian_shape): empty_hess_shape = [1] + hessian_shape.as_list() empty_grad_shape = [1] + gradient_shape.as_list() empty_gradients = constant_op.constant_v1( [], dtype=dtypes.float32, shape=empty_grad_shape) empty_hessians = constant_op.constant_v1( [], dtype=dtypes.float32, shape=empty_hess_shape) return empty_gradients, empty_hessians
def get_empty_tensors(gradient_shape, hessian_shape): empty_hess_shape = [1] + hessian_shape.as_list() empty_grad_shape = [1] + gradient_shape.as_list() empty_gradients = constant_op.constant_v1([], dtype=dtypes.float32, shape=empty_grad_shape) empty_hessians = constant_op.constant_v1([], dtype=dtypes.float32, shape=empty_hess_shape) return empty_gradients, empty_hessians
def testEmpty(self): with self.cached_session() as sess: gradients = array_ops.constant([0.2, -0.5, 1.2, 4.0]) hessians = array_ops.constant([0.12, 0.07, 0.2, 0.13]) partition_ids = [0, 0, 0, 1] indices = constant_op.constant_v1([], dtype=dtypes.int64, shape=[0, 2]) values = constant_op.constant_v1([], dtype=dtypes.int64) gradient_shape = tensor_shape.TensorShape([]) hessian_shape = tensor_shape.TensorShape([]) class_id = -1 split_handler = categorical_split_handler.EqualitySplitHandler( l1_regularization=0.1, l2_regularization=1, tree_complexity_regularization=0, min_node_weight=0, sparse_int_column=sparse_tensor.SparseTensor( indices, values, [4, 1]), feature_column_group_id=0, gradient_shape=gradient_shape, hessian_shape=hessian_shape, multiclass_strategy=learner_pb2.LearnerConfig.TREE_PER_CLASS, init_stamp_token=0) resources.initialize_resources(resources.shared_resources()).run() empty_gradients, empty_hessians = get_empty_tensors( gradient_shape, hessian_shape) example_weights = array_ops.ones([4, 1], dtypes.float32) update_1 = split_handler.update_stats_sync( 0, partition_ids, gradients, hessians, empty_gradients, empty_hessians, example_weights, is_active=array_ops.constant([True, True])) with ops.control_dependencies([update_1]): are_splits_ready, partitions, gains, splits = ( split_handler.make_splits(0, 1, class_id)) are_splits_ready, partitions, gains, splits = (sess.run( [are_splits_ready, partitions, gains, splits])) self.assertTrue(are_splits_ready) self.assertEqual(len(partitions), 0) self.assertEqual(len(gains), 0) self.assertEqual(len(splits), 0)
def dense_make_stats_update(is_active, are_buckets_ready, float_column, quantile_buckets, example_partition_ids, gradients, hessians, weights, empty_gradients, empty_hessians): """Updates the state for dense split handler.""" empty_float = constant_op.constant_v1([], dtype=dtypes.float32) quantile_values, quantile_weights = control_flow_ops.cond( is_active[1], # For the next layer, this handler is inactive. lambda: (float_column, weights), lambda: (empty_float, empty_float)) def ready_inputs_fn(): """Branch to execute when quantiles are ready.""" quantized_feature = quantile_ops.quantiles([float_column], [], [quantile_buckets], [], []) quantized_feature = math_ops.cast(quantized_feature[0], dtypes.int64) quantized_feature = array_ops.squeeze(quantized_feature, axis=0) return (example_partition_ids, quantized_feature, gradients, hessians) def not_ready_inputs_fn(): return (constant_op.constant_v1([], dtype=dtypes.int32), constant_op.constant_v1([[]], dtype=dtypes.int64, shape=[1, 2]), empty_gradients, empty_hessians) example_partition_ids, feature_ids, gradients, hessians = ( control_flow_ops.cond( math_ops.logical_and( math_ops.logical_and(are_buckets_ready, array_ops.size(quantile_buckets) > 0), is_active[0]), ready_inputs_fn, not_ready_inputs_fn)) return (quantile_values, quantile_weights, example_partition_ids, feature_ids, gradients, hessians)
def __call__(self, shape, dtype=None, partition_info=None, verify_shape=None): if dtype is None: dtype = self.dtype if verify_shape is None: verify_shape = self._verify_shape return constant_op.constant_v1( self.value, dtype=dtype, shape=shape, verify_shape=verify_shape)
def testEmpty(self): with self.cached_session() as sess: gradients = array_ops.constant([0.2, -0.5, 1.2, 4.0]) hessians = array_ops.constant([0.12, 0.07, 0.2, 0.13]) partition_ids = [0, 0, 0, 1] indices = constant_op.constant_v1([], dtype=dtypes.int64, shape=[0, 2]) values = constant_op.constant_v1([], dtype=dtypes.int64) gradient_shape = tensor_shape.scalar() hessian_shape = tensor_shape.scalar() class_id = -1 split_handler = categorical_split_handler.EqualitySplitHandler( l1_regularization=0.1, l2_regularization=1, tree_complexity_regularization=0, min_node_weight=0, sparse_int_column=sparse_tensor.SparseTensor(indices, values, [4, 1]), feature_column_group_id=0, gradient_shape=gradient_shape, hessian_shape=hessian_shape, multiclass_strategy=learner_pb2.LearnerConfig.TREE_PER_CLASS, init_stamp_token=0) resources.initialize_resources(resources.shared_resources()).run() empty_gradients, empty_hessians = get_empty_tensors( gradient_shape, hessian_shape) example_weights = array_ops.ones([4, 1], dtypes.float32) update_1 = split_handler.update_stats_sync( 0, partition_ids, gradients, hessians, empty_gradients, empty_hessians, example_weights, is_active=array_ops.constant([True, True])) with ops.control_dependencies([update_1]): are_splits_ready, partitions, gains, splits = ( split_handler.make_splits(0, 1, class_id)) are_splits_ready, partitions, gains, splits = (sess.run( [are_splits_ready, partitions, gains, splits])) self.assertTrue(are_splits_ready) self.assertEqual(len(partitions), 0) self.assertEqual(len(gains), 0) self.assertEqual(len(splits), 0)
def testShapeInconsistent(self): with ops.Graph().as_default(): c = constant_op.constant_v1([1, 2, 3, 4, 5, 6, 7], shape=[10]) self.assertEqual(c.get_shape(), [10]) with ops.Graph().as_default(): with self.assertRaisesRegex(TypeError, "Expected Tensor's shape"): c = constant_op.constant([1, 2, 3, 4, 5, 6, 7], shape=[10])
def RttConstant(value, dtype=None, shape=None, name="Const", verify_shape=False): dtype = dtype_check_and_set(dtype) value = _const_convert_to_str(value) return rtt_ts.constant( constant_op.constant_v1(value, dtype, shape, name, verify_shape))
def testShapeInconsistent(self): with ops.Graph().as_default(): c = constant_op.constant_v1([1, 2, 3, 4, 5, 6, 7], shape=[10]) self.assertEqual(c.get_shape(), [10]) with ops.Graph().as_default(): with self.assertRaisesRegexp( TypeError, "Expected Tensor's shape"): c = constant_op.constant([1, 2, 3, 4, 5, 6, 7], shape=[10])
def not_ready_inputs_fn(): return (constant_op.constant_v1([], dtype=dtypes.int32), constant_op.constant_v1([[]], dtype=dtypes.int64, shape=[1, 2]), empty_gradients, empty_hessians)
def not_active_inputs(): return (constant_op.constant([], dtype=dtypes.int32), constant_op.constant_v1([], dtype=dtypes.int64, shape=[1, 2]), empty_gradients, empty_hessians)
def quantiles_not_ready(): """The subgraph for when the quantiles are not ready.""" return (constant_op.constant_v1([], dtype=dtypes.int32), constant_op.constant_v1([], dtype=dtypes.int64, shape=[1, 2]), empty_gradients, empty_hessians)
def sparse_make_stats_update( is_active, are_buckets_ready, sparse_column_indices, sparse_column_values, sparse_column_shape, quantile_buckets, example_partition_ids, gradients, hessians, weights, empty_gradients, empty_hessians): """Updates the state for this split handler.""" def quantiles_ready(): """The subgraph for when the quantiles are ready.""" quantized_feature = quantile_ops.quantiles([], [sparse_column_values], [], [quantile_buckets], [sparse_column_indices]) quantized_feature = math_ops.cast(quantized_feature[1], dtypes.int64) quantized_feature = array_ops.squeeze(quantized_feature, axis=0) example_indices, _ = array_ops.split( sparse_column_indices, num_or_size_splits=2, axis=1) example_indices = array_ops.squeeze(example_indices, [1]) filtered_gradients = array_ops.gather(gradients, example_indices) filtered_hessians = array_ops.gather(hessians, example_indices) filtered_partition_ids = array_ops.gather(example_partition_ids, example_indices) unique_partitions, mapped_partitions = array_ops.unique( example_partition_ids) # Compute aggregate stats for each partition. # Since unsorted_segment_sum can be numerically unstable, use 64bit # operation. gradients64 = math_ops.cast(gradients, dtypes.float64) hessians64 = math_ops.cast(hessians, dtypes.float64) per_partition_gradients = math_ops.unsorted_segment_sum( gradients64, mapped_partitions, array_ops.size(unique_partitions)) per_partition_hessians = math_ops.unsorted_segment_sum( hessians64, mapped_partitions, array_ops.size(unique_partitions)) per_partition_gradients = math_ops.cast(per_partition_gradients, dtypes.float32) per_partition_hessians = math_ops.cast(per_partition_hessians, dtypes.float32) # Prepend a bias feature per partition that accumulates the stats for all # examples in that partition. bias_feature_ids = array_ops.fill( array_ops.shape(unique_partitions), _BIAS_FEATURE_ID) bias_feature_ids = math_ops.cast(bias_feature_ids, dtypes.int64) zeros = array_ops.zeros_like(bias_feature_ids) bias_feature_ids = array_ops.stack([bias_feature_ids, zeros], axis=1) partition_ids = array_ops.concat( [unique_partitions, filtered_partition_ids], 0) filtered_gradients = array_ops.concat( [per_partition_gradients, filtered_gradients], 0) filtered_hessians = array_ops.concat( [per_partition_hessians, filtered_hessians], 0) bucket_ids = array_ops.concat([bias_feature_ids, quantized_feature], 0) return partition_ids, bucket_ids, filtered_gradients, filtered_hessians def quantiles_not_ready(): """The subgraph for when the quantiles are not ready.""" return (constant_op.constant_v1([], dtype=dtypes.int32), constant_op.constant_v1([], dtype=dtypes.int64, shape=[1, 2]), empty_gradients, empty_hessians) empty_float = constant_op.constant_v1([], dtype=dtypes.float32) handler_not_active = (constant_op.constant( [], dtype=dtypes.int64, shape=[0, 2]), empty_float, constant_op.constant([0, 1], dtype=dtypes.int64), empty_float) handler_active = (sparse_column_indices, sparse_column_values, sparse_column_shape, weights) quantile_indices, quantile_values, quantile_shape, quantile_weights = ( control_flow_ops.cond(is_active[1], lambda: handler_active, lambda: handler_not_active)) example_partition_ids, feature_ids, gradients, hessians = ( control_flow_ops.cond( math_ops.logical_and(are_buckets_ready, array_ops.size(quantile_buckets) > 0), quantiles_ready, quantiles_not_ready)) return (quantile_indices, quantile_values, quantile_shape, quantile_weights, example_partition_ids, feature_ids, gradients, hessians)
def testShapeWrong(self): with ops.Graph().as_default(): with self.assertRaisesRegexp(ValueError, "Too many elements provided."): constant_op.constant_v1([1, 2, 3, 4, 5, 6, 7], shape=[5]) with self.assertRaisesRegexp(TypeError, "Expected Tensor's shape"): constant_op.constant([1, 2, 3, 4, 5, 6, 7], shape=[5])
def MpcConstant(value, dtype=None, shape=None, name="Const", verify_shape=False): dtype = dtype_check_and_set(dtype) return constant_op.constant_v1(value, dtype, shape, name, verify_shape)
def sparse_make_stats_update(is_active, are_buckets_ready, sparse_column_indices, sparse_column_values, sparse_column_shape, quantile_buckets, example_partition_ids, gradients, hessians, weights, empty_gradients, empty_hessians): """Updates the state for this split handler.""" def quantiles_ready(): """The subgraph for when the quantiles are ready.""" quantized_feature = quantile_ops.quantiles([], [sparse_column_values], [], [quantile_buckets], [sparse_column_indices]) quantized_feature = math_ops.cast(quantized_feature[1], dtypes.int64) quantized_feature = array_ops.squeeze(quantized_feature, axis=0) example_indices, _ = array_ops.split(sparse_column_indices, num_or_size_splits=2, axis=1) example_indices = array_ops.squeeze(example_indices, [1]) filtered_gradients = array_ops.gather(gradients, example_indices) filtered_hessians = array_ops.gather(hessians, example_indices) filtered_partition_ids = array_ops.gather(example_partition_ids, example_indices) unique_partitions, mapped_partitions = array_ops.unique( example_partition_ids) # Compute aggregate stats for each partition. # Since unsorted_segment_sum can be numerically unstable, use 64bit # operation. gradients64 = math_ops.cast(gradients, dtypes.float64) hessians64 = math_ops.cast(hessians, dtypes.float64) per_partition_gradients = math_ops.unsorted_segment_sum( gradients64, mapped_partitions, array_ops.size(unique_partitions)) per_partition_hessians = math_ops.unsorted_segment_sum( hessians64, mapped_partitions, array_ops.size(unique_partitions)) per_partition_gradients = math_ops.cast(per_partition_gradients, dtypes.float32) per_partition_hessians = math_ops.cast(per_partition_hessians, dtypes.float32) # Prepend a bias feature per partition that accumulates the stats for all # examples in that partition. bias_feature_ids = array_ops.fill(array_ops.shape(unique_partitions), _BIAS_FEATURE_ID) bias_feature_ids = math_ops.cast(bias_feature_ids, dtypes.int64) zeros = array_ops.zeros_like(bias_feature_ids) bias_feature_ids = array_ops.stack([bias_feature_ids, zeros], axis=1) partition_ids = array_ops.concat( [unique_partitions, filtered_partition_ids], 0) filtered_gradients = array_ops.concat( [per_partition_gradients, filtered_gradients], 0) filtered_hessians = array_ops.concat( [per_partition_hessians, filtered_hessians], 0) bucket_ids = array_ops.concat([bias_feature_ids, quantized_feature], 0) return partition_ids, bucket_ids, filtered_gradients, filtered_hessians def quantiles_not_ready(): """The subgraph for when the quantiles are not ready.""" return (constant_op.constant_v1([], dtype=dtypes.int32), constant_op.constant_v1([], dtype=dtypes.int64, shape=[1, 2]), empty_gradients, empty_hessians) empty_float = constant_op.constant_v1([], dtype=dtypes.float32) handler_not_active = (constant_op.constant([], dtype=dtypes.int64, shape=[0, 2]), empty_float, constant_op.constant([0, 1], dtype=dtypes.int64), empty_float) handler_active = (sparse_column_indices, sparse_column_values, sparse_column_shape, weights) quantile_indices, quantile_values, quantile_shape, quantile_weights = ( control_flow_ops.cond(is_active[1], lambda: handler_active, lambda: handler_not_active)) example_partition_ids, feature_ids, gradients, hessians = ( control_flow_ops.cond( math_ops.logical_and(are_buckets_ready, array_ops.size(quantile_buckets) > 0), quantiles_ready, quantiles_not_ready)) return (quantile_indices, quantile_values, quantile_shape, quantile_weights, example_partition_ids, feature_ids, gradients, hessians)