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"]
docstr: Forward pass of the network
  self.input:
      x -- Features [B, C, N]
      pos -- Points [B, N, 3]
docstr_tok: ["Forward","pass","of","the","network","self.input",":","x","--","Features","[","B",",","C",",","N","]","pos","--","Points","[","B",",","N",",","3","]"]
code: def forward(self, *args, **kwargs):
      r"""
      Forward pass of the network
      self.input:
          x -- Features [B, C, N]
          pos -- Points [B, N, 3]
      """
      data = self.model(self.input)
      last_feature = data.x
      if self._use_category:
          cat_one_hot = (
              F.one_hot(self.category, self._num_categories)
              .float()
              .transpose(1, 2)
          )
          last_feature = torch.cat((last_feature, cat_one_hot), dim=1)
  
      self.output = (
          self.FC_layer(last_feature)
          .transpose(1, 2)
          .contiguous()
          .view((-1, self._num_classes))
      )
  
      if self._weight_classes is not None:
          self._weight_classes = self._weight_classes.to(
              self.output.device
          )
      if self.labels is not None:
          self.loss_seg = F.cross_entropy(
              self.output,
              self.labels,
              weight=self._weight_classes,
              ignore_index=IGNORE_LABEL,
          )
  
      self.data_visual = self.input
      self.data_visual.y = torch.reshape(
          self.labels, data.pos.shape[0:2]
      )
      self.data_visual.pred = torch.max(self.output, -1)[1].reshape(
          data.pos.shape[0:2]
      )
      return self.output
  
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 3 for calling the PointNet2_D obj's underlying member method code with example usage: obj.forward() and returns: self