code: def apply_nn(self, input):
      # inputs = self.compute_scales(input)
      outputs = []
      for i in range(len(self.grid_size)):
          self.unet.set_grid_size(self.grid_size[i])
          out = self.unet(input.clone())
          out.x = out.x / (
              torch.norm(out.x, p=2, dim=1, keepdim=True) + 1e-20
          )
          outputs.append(out)
      x = torch.cat([o.x for o in outputs], 1)
      out_feat = self.FC_layer(x)
      if self.normalize_feature:
          out_feat = out_feat / (
              torch.norm(out_feat, p=2, dim=1, keepdim=True) + 1e-20
          )
      return out_feat, outputs
  
imports: import torch
  import torch.nn
  from torch.nn import LeakyReLU, Linear, Sequential
  from torch_geometric.nn.pool.consecutive import consecutive_cluster
  from torch_geometric.nn import voxel_grid
  from torch_geometric.data import Batch
  from torch_scatter import scatter_max, scatter_mean
  from torch_points3d.applications.sparseconv3d import SparseConv3d
  from torch_points3d.core.common_modules import FastBatchNorm1d, Seq
  from torch_points3d.core.common_modules import MLP
  from torch_points3d.models.registration.base import FragmentBaseModel
label_desc: Use image node_id 3 for calling the MS_SparseConv3d_Shared obj's underlying member method code with example usage: obj.apply_nn(input) and returns: out_feat,  outputs