class_docstr: Class implementing the Perfect Tree Traversal strategy in PyTorch for tree-base models.
docstr: Args:
      tree_parameters: The parameters defining the tree structure
      max_depth: The maximum tree-depth in the model
      n_features: The number of features input to the model
      classes: The classes used for classification. None if implementing a regression model
      n_classes: The total number of used classes
docstr_tok: ["Args",":","tree_parameters",":","The","parameters","defining","the","tree","structure","max_depth",":","The","maximum","tree-depth","in","the","model","n_features",":","The","number","of","features","input","to","the","model","classes",":","The","classes","used","for","classification",".","None","if","implementing","a","regression","model","n_classes",":","The","total","number","of","used","classes"]
code: def __init__(
      self,
      logical_operator,
      tree_parameters,
      max_depth,
      n_features,
      classes,
      n_classes=None,
      extra_config={},
      **kwargs,
  ):
      """
      Args:
          tree_parameters: The parameters defining the tree structure
          max_depth: The maximum tree-depth in the model
          n_features: The number of features input to the model
          classes: The classes used for classification. None if implementing a regression model
          n_classes: The total number of used classes
      """
      # If n_classes is not provided we induce it from tree parameters. Multioutput regression targets are also treated as separate classes.
      n_classes = (
          n_classes
          if n_classes is not None
          else tree_parameters[0][6].shape[1]
      )
      super(PerfectTreeTraversalTreeImpl, self).__init__(
          logical_operator,
          tree_parameters,
          n_features,
          classes,
          n_classes,
          extra_config=extra_config,
          **kwargs,
      )
  
      # Initialize the actual model.
      self.max_tree_depth = max_depth
      self.num_trees = len(tree_parameters)
      self.n_features = n_features
  
      node_maps = [tp[0] for tp in tree_parameters]
  
      weight_0 = np.zeros((self.num_trees, 2**max_depth - 1))
      bias_0 = np.zeros(
          (self.num_trees, 2**max_depth - 1), dtype=np.float64
      )
      weight_1 = np.zeros(
          (self.num_trees, 2**max_depth, self.n_classes)
      )
  
      for i, node_map in enumerate(node_maps):
          self._get_weights_and_biases(
              node_map, max_depth, weight_0[i], weight_1[i], bias_0[i]
          )
  
      node_by_levels = [set() for _ in range(max_depth)]
      self._traverse_by_level(node_by_levels, 0, -1, max_depth)
      self.root_nodes = torch.nn.Parameter(
          torch.from_numpy(weight_0[:, 0].flatten().astype("int64"))
          .detach()
          .clone(),
          requires_grad=False,
      )
      self.root_biases = torch.nn.Parameter(
          torch.from_numpy(
              bias_0[:, 0].astype(self.tree_op_precision_dtype)
          )
          .detach()
          .clone(),
          requires_grad=False,
      )
  
      tree_indices = np.array(
          [i for i in range(0, 2 * self.num_trees, 2)]
      ).astype("int64")
      self.tree_indices = torch.nn.Parameter(
          torch.from_numpy(tree_indices).detach().clone(),
          requires_grad=False,
      )
  
      self.nodes = []
      self.biases = []
      for i in range(1, max_depth):
          nodes = torch.nn.Parameter(
              torch.from_numpy(
                  weight_0[:, list(sorted(node_by_levels[i]))]
                  .flatten()
                  .astype("int64")
              )
              .detach()
              .clone(),
              requires_grad=False,
          )
          biases = torch.nn.Parameter(
              torch.from_numpy(
                  bias_0[:, list(sorted(node_by_levels[i]))]
                  .flatten()
                  .astype(self.tree_op_precision_dtype)
              )
              .detach()
              .clone(),
              requires_grad=False,
          )
          self.nodes.append(nodes)
          self.biases.append(biases)
  
      self.nodes = torch.nn.ParameterList(self.nodes)
      self.biases = torch.nn.ParameterList(self.biases)
  
      self.leaf_nodes = torch.nn.Parameter(
          torch.from_numpy(
              weight_1.reshape((-1, self.n_classes)).astype(
                  self.tree_op_precision_dtype
              )
          )
          .detach()
          .clone(),
          requires_grad=False,
      )
  
imports: from abc import abstractmethod
  from enum import Enum
  import numpy
  import torch
  from .None import constants
  from ._physical_operator import PhysicalOperator
  from .None import _tree_commons
label_desc: Use image node_id 1 to create a new PerfectTreeTraversalTreeImpl object from inherited base classes: AbstractPyTorchTreeImpl with example: obj = PerfectTreeTraversalTreeImpl(logical_operator, tree_parameters, max_depth, n_features, classes, n_classes, extra_config)