class_docstr: PointNet2 with multi-scale grouping
  Semantic segmentation network that uses feature propogation layers
  
  Parameters
  ----------
  num_classes: int
      Number of semantics classes to predict over -- size of softmax classifier that run for each point
  input_channels: int = 6
      Number of input channels in the feature descriptor for each point.  If the point cloud is Nx9, this
      value should be 6 as in an Nx9 point cloud, 3 of the channels are xyz, and 6 are feature descriptors
  use_xyz: bool = True
      Whether or not to use the xyz position of a point as a feature
class_docstr_tok: ["PointNet2","with","multi-scale","grouping","Semantic","segmentation","network","that","uses","feature","propogation","layers","Parameters","--","--","--","--","--","num_classes",":","int","Number","of","semantics","classes","to","predict","over","--","size","of","softmax","classifier","that","run","for","each","point","input_channels",":","int","=","6","Number","of","input","channels","in","the","feature","descriptor","for","each","point",".","If","the","point","cloud","is","Nx9",",","this","value","should","be","6","as","in","an","Nx9","point","cloud",",","3","of","the","channels","are","xyz",",","and","6","are","feature","descriptors","use_xyz",":","bool","=","True","Whether","or","not","to","use","the","xyz","position","of","a","point","as","a","feature"]
code: def __init__(self, option, model_type, dataset, modules):
      # call the initialization method of UnetBasedModel
      UnetBasedModel.__init__(
          self, option, model_type, dataset, modules
      )
      self._num_classes = dataset.num_classes
      self._weight_classes = dataset.weight_classes
      self._use_category = getattr(option, "use_category", False)
      if self._use_category:
          if not dataset.class_to_segments:
              raise ValueError(
                  "The dataset needs to specify a class_to_segments property when using category information for segmentation"
              )
          self._num_categories = len(dataset.class_to_segments.keys())
          log.info(
              "Using category information for the predictions with %i categories",
              self._num_categories,
          )
      else:
          self._num_categories = 0
  
      # Last MLP
      last_mlp_opt = copy.deepcopy(option.mlp_cls)
  
      self.FC_layer = Seq()
      last_mlp_opt.nn[0] += self._num_categories
      for i in range(1, len(last_mlp_opt.nn)):
          self.FC_layer.append(
              Conv1D(
                  last_mlp_opt.nn[i - 1],
                  last_mlp_opt.nn[i],
                  bn=True,
                  bias=False,
              )
          )
      if last_mlp_opt.dropout:
          self.FC_layer.append(torch.nn.Dropout(p=last_mlp_opt.dropout))
  
      self.FC_layer.append(
          Conv1D(
              last_mlp_opt.nn[-1],
              self._num_classes,
              activation=None,
              bias=True,
              bn=False,
          )
      )
      self.loss_names = ["loss_seg"]
  
      self.visual_names = ["data_visual"]
  
file_path: torch-points3d/torch_points3d/models/segmentation/pointnet2.py
imports: import torch
  import torch.nn.functional
  from torch_geometric.data import Data
  import logging
  import copy
  from torch_points3d.modules.pointnet2 import *
  from torch_points3d.core.base_conv.dense import DenseFPModule
  from torch_points3d.models.base_architectures import UnetBasedModel
  from torch_points3d.core.common_modules.dense_modules import Conv1D
  from torch_points3d.core.common_modules.base_modules import Seq
  from .base import Segmentation_MP
  from torch_points3d.datasets.segmentation import IGNORE_LABEL
label_desc: Use image node_id 1 to create a new PointNet2_D object from inherited base classes: UnetBasedModel with example: obj = PointNet2_D(option, model_type, dataset, modules)