def make_update_ensemble_fn(self, ensemble_stamp, training_state, dropout_seed, class_id):
    'A method to create the function which updates the tree ensemble.'
    learning_rate_tuner = self._learner_config.learning_rate_tuner.WhichOneof('tuner')
    if ((learning_rate_tuner == 'fixed') or (learning_rate_tuner == 'dropout')):
        tuner = getattr(self._learner_config.learning_rate_tuner, learning_rate_tuner)
        learning_rate = tuner.learning_rate
    else:
        raise ValueError('Line search learning rate is not yet supported.')

    def _update_ensemble():
        'A method to update the tree ensemble.'
        next_ensemble_stamp = (ensemble_stamp + 1)
        (_, _, _, bias_grads, bias_hess) = training_state.bias_stats_accumulator.flush(ensemble_stamp, next_ensemble_stamp)
        are_splits_ready_list = []
        partition_ids_list = []
        gains_list = []
        split_info_list = []
        for handler in training_state.handlers:
            (are_splits_ready, partition_ids, gains, split_info) = handler.make_splits(ensemble_stamp, next_ensemble_stamp, class_id)
            are_splits_ready_list.append(are_splits_ready)
            partition_ids_list.append(partition_ids)
            gains_list.append(gains)
            split_info_list.append(split_info)
        split_sizes = array_ops.reshape(array_ops.shape_n(partition_ids_list), [len(partition_ids_list)])
        partition_ids = array_ops.concat(partition_ids_list, axis=0)
        gains = array_ops.concat(gains_list, axis=0)
        split_infos = array_ops.concat(split_info_list, axis=0)
        are_all_splits_ready = math_ops.reduce_all(array_ops.stack(are_splits_ready_list, axis=0, name='stack_handler_readiness'))

        def _center_bias_fn():
            delta_updates = array_ops.where((bias_hess > 0), ((- bias_grads) / bias_hess), array_ops.zeros_like(bias_grads))
            center_bias = training_ops.center_tree_ensemble_bias(tree_ensemble_handle=self._ensemble_handle, stamp_token=ensemble_stamp, next_stamp_token=next_ensemble_stamp, delta_updates=delta_updates, learner_config=self._learner_config_serialized)
            return training_state.continue_centering.assign(center_bias)

        def _grow_ensemble_ready_fn():
            sizes = array_ops.unstack(split_sizes)
            partition_ids_list = list(array_ops.split(partition_ids, sizes, axis=0))
            if (self._learner_config.weak_learner_type == learner_pb2.LearnerConfig.OBLIVIOUS_DECISION_TREE):
                sizes = len(training_state.handlers)
            gains_list = list(array_ops.split(gains, sizes, axis=0))
            split_info_list = list(array_ops.split(split_infos, sizes, axis=0))
            return training_ops.grow_tree_ensemble(tree_ensemble_handle=self._ensemble_handle, stamp_token=ensemble_stamp, next_stamp_token=next_ensemble_stamp, learning_rate=learning_rate, partition_ids=partition_ids_list, gains=gains_list, splits=split_info_list, learner_config=self._learner_config_serialized, dropout_seed=dropout_seed, center_bias=self._center_bias, max_tree_depth=self._max_tree_depth, weak_learner_type=self._learner_config.weak_learner_type)

        def _grow_ensemble_not_ready_fn():
            return training_ops.grow_tree_ensemble(tree_ensemble_handle=self._ensemble_handle, stamp_token=ensemble_stamp, next_stamp_token=next_ensemble_stamp, learning_rate=0, partition_ids=[], gains=[], splits=[], learner_config=self._learner_config_serialized, dropout_seed=dropout_seed, center_bias=self._center_bias, max_tree_depth=self._max_tree_depth, weak_learner_type=self._learner_config.weak_learner_type)

        def _grow_ensemble_fn():
            return control_flow_ops.cond(are_all_splits_ready, _grow_ensemble_ready_fn, _grow_ensemble_not_ready_fn)
        update_ops = [are_all_splits_ready]
        if self._center_bias:
            update_model = control_flow_ops.cond(training_state.continue_centering, _center_bias_fn, _grow_ensemble_fn)
        else:
            update_model = _grow_ensemble_fn()
        update_ops.append(update_model)
        with ops.control_dependencies([update_model]):
            stats = training_ops.tree_ensemble_stats(self._ensemble_handle, stamp_token=next_ensemble_stamp)
            update_ops.append(self._finalized_trees.assign(stats.num_trees))
            update_ops.append(self._attempted_trees.assign(stats.attempted_trees))
            update_ops.append(training_state.num_layers.assign(stats.num_layers))
            update_ops.append(training_state.active_tree.assign(stats.active_tree))
            update_ops.append(training_state.active_layer.assign(stats.active_layer))
        update_ops.extend(training_state.steps_accumulator.flush(ensemble_stamp, next_ensemble_stamp))
        return control_flow_ops.group(*update_ops, name='update_ensemble')
    return _update_ensemble
A method to create the function which updates the tree ensemble.
def make_update_ensemble_fn(self, ensemble_stamp, training_state, dropout_seed, class_id):
    
    learning_rate_tuner = self._learner_config.learning_rate_tuner.WhichOneof('tuner')
    if ((learning_rate_tuner == 'fixed') or (learning_rate_tuner == 'dropout')):
        tuner = getattr(self._learner_config.learning_rate_tuner, learning_rate_tuner)
        learning_rate = tuner.learning_rate
    else:
        raise ValueError('Line search learning rate is not yet supported.')

    def _update_ensemble():
        'A method to update the tree ensemble.'
        next_ensemble_stamp = (ensemble_stamp + 1)
        (_, _, _, bias_grads, bias_hess) = training_state.bias_stats_accumulator.flush(ensemble_stamp, next_ensemble_stamp)
        are_splits_ready_list = []
        partition_ids_list = []
        gains_list = []
        split_info_list = []
        for handler in training_state.handlers:
            (are_splits_ready, partition_ids, gains, split_info) = handler.make_splits(ensemble_stamp, next_ensemble_stamp, class_id)
            are_splits_ready_list.append(are_splits_ready)
            partition_ids_list.append(partition_ids)
            gains_list.append(gains)
            split_info_list.append(split_info)
        split_sizes = array_ops.reshape(array_ops.shape_n(partition_ids_list), [len(partition_ids_list)])
        partition_ids = array_ops.concat(partition_ids_list, axis=0)
        gains = array_ops.concat(gains_list, axis=0)
        split_infos = array_ops.concat(split_info_list, axis=0)
        are_all_splits_ready = math_ops.reduce_all(array_ops.stack(are_splits_ready_list, axis=0, name='stack_handler_readiness'))

        def _center_bias_fn():
            delta_updates = array_ops.where((bias_hess > 0), ((- bias_grads) / bias_hess), array_ops.zeros_like(bias_grads))
            center_bias = training_ops.center_tree_ensemble_bias(tree_ensemble_handle=self._ensemble_handle, stamp_token=ensemble_stamp, next_stamp_token=next_ensemble_stamp, delta_updates=delta_updates, learner_config=self._learner_config_serialized)
            return training_state.continue_centering.assign(center_bias)

        def _grow_ensemble_ready_fn():
            sizes = array_ops.unstack(split_sizes)
            partition_ids_list = list(array_ops.split(partition_ids, sizes, axis=0))
            if (self._learner_config.weak_learner_type == learner_pb2.LearnerConfig.OBLIVIOUS_DECISION_TREE):
                sizes = len(training_state.handlers)
            gains_list = list(array_ops.split(gains, sizes, axis=0))
            split_info_list = list(array_ops.split(split_infos, sizes, axis=0))
            return training_ops.grow_tree_ensemble(tree_ensemble_handle=self._ensemble_handle, stamp_token=ensemble_stamp, next_stamp_token=next_ensemble_stamp, learning_rate=learning_rate, partition_ids=partition_ids_list, gains=gains_list, splits=split_info_list, learner_config=self._learner_config_serialized, dropout_seed=dropout_seed, center_bias=self._center_bias, max_tree_depth=self._max_tree_depth, weak_learner_type=self._learner_config.weak_learner_type)

        def _grow_ensemble_not_ready_fn():
            return training_ops.grow_tree_ensemble(tree_ensemble_handle=self._ensemble_handle, stamp_token=ensemble_stamp, next_stamp_token=next_ensemble_stamp, learning_rate=0, partition_ids=[], gains=[], splits=[], learner_config=self._learner_config_serialized, dropout_seed=dropout_seed, center_bias=self._center_bias, max_tree_depth=self._max_tree_depth, weak_learner_type=self._learner_config.weak_learner_type)

        def _grow_ensemble_fn():
            return control_flow_ops.cond(are_all_splits_ready, _grow_ensemble_ready_fn, _grow_ensemble_not_ready_fn)
        update_ops = [are_all_splits_ready]
        if self._center_bias:
            update_model = control_flow_ops.cond(training_state.continue_centering, _center_bias_fn, _grow_ensemble_fn)
        else:
            update_model = _grow_ensemble_fn()
        update_ops.append(update_model)
        with ops.control_dependencies([update_model]):
            stats = training_ops.tree_ensemble_stats(self._ensemble_handle, stamp_token=next_ensemble_stamp)
            update_ops.append(self._finalized_trees.assign(stats.num_trees))
            update_ops.append(self._attempted_trees.assign(stats.attempted_trees))
            update_ops.append(training_state.num_layers.assign(stats.num_layers))
            update_ops.append(training_state.active_tree.assign(stats.active_tree))
            update_ops.append(training_state.active_layer.assign(stats.active_layer))
        update_ops.extend(training_state.steps_accumulator.flush(ensemble_stamp, next_ensemble_stamp))
        return control_flow_ops.group(*update_ops, name='update_ensemble')
    return _update_ensemble