class_docstr: Implementation of a trainable bilateral filter layer as proposed in the corresponding publication.
  All filter parameters can be trained data-driven. The spatial filter kernels x, y, and z determine
  image smoothing whereas the color parameter specifies the amount of edge preservation.
  Can run on 1D, 2D, or 3D tensors (on top of Batch and Channel dimensions).
  
  See:
      F. Wagner, et al., Ultralow-parameter denoising: Trainable bilateral filter layers in
      computed tomography, Medical Physics (2022), https://doi.org/10.1002/mp.15718
  
  Args:
      input: input tensor to be filtered.
      spatial_sigma: tuple (sigma_x, sigma_y, sigma_z) initializing the trainable standard
          deviations of the spatial filter kernels. Tuple length must equal the number of
          spatial input dimensions.
      color_sigma: trainable standard deviation of the intensity range kernel. This filter
          parameter determines the degree of edge preservation.
  
  Returns:
      output (torch.Tensor): filtered tensor.
class_docstr_tok: ["Implementation","of","a","trainable","bilateral","filter","layer","as","proposed","in","the","corresponding","publication",".","All","filter","parameters","can","be","trained","data-driven",".","The","spatial","filter","kernels","x",",","y",",","and","z","determine","image","smoothing","whereas","the","color","parameter","specifies","the","amount","of","edge","preservation",".","Can","run","on","1D",",","2D",",","or","3D","tensors","(","on","top","of","Batch","and","Channel","dimensions",")",".","See",":","F.","Wagner",",","et","al.",",","Ultralow-parameter","denoising",":","Trainable","bilateral","filter","layers","in","computed","tomography",",","Medical","Physics","(","2022",")",",","https",":","\/\/doi.org\/10.1002\/mp.15718","Args",":","input",":","input","tensor","to","be","filtered",".","spatial_sigma",":","tuple","(","sigma_x",",","sigma_y",",","sigma_z",")","initializing","the","trainable","standard","deviations","of","the","spatial","filter","kernels",".","Tuple","length","must","equal","the","number","of","spatial","input","dimensions",".","color_sigma",":","trainable","standard","deviation","of","the","intensity","range","kernel",".","This","filter","parameter","determines","the","degree","of","edge","preservation",".","Returns",":","output","(","torch.Tensor",")",":","filtered","tensor","."]
code: def __init__(self, spatial_sigma, color_sigma):
      super().__init__()
  
      if isinstance(spatial_sigma, float):
          spatial_sigma = [spatial_sigma, spatial_sigma, spatial_sigma]
          self.len_spatial_sigma = 3
      elif len(spatial_sigma) == 1:
          spatial_sigma = [spatial_sigma[0], 0.01, 0.01]
          self.len_spatial_sigma = 1
      elif len(spatial_sigma) == 2:
          spatial_sigma = [spatial_sigma[0], spatial_sigma[1], 0.01]
          self.len_spatial_sigma = 2
      elif len(spatial_sigma) == 3:
          spatial_sigma = [
              spatial_sigma[0],
              spatial_sigma[1],
              spatial_sigma[2],
          ]
          self.len_spatial_sigma = 3
      else:
          raise ValueError(
              f"len(spatial_sigma) {spatial_sigma} must match number of spatial dims {self.ken_spatial_sigma}."
          )
  
      # Register sigmas as trainable parameters.
      self.sigma_x = torch.nn.Parameter(torch.tensor(spatial_sigma[0]))
      self.sigma_y = torch.nn.Parameter(torch.tensor(spatial_sigma[1]))
      self.sigma_z = torch.nn.Parameter(torch.tensor(spatial_sigma[2]))
      self.sigma_color = torch.nn.Parameter(torch.tensor(color_sigma))
  
imports: from __future__ import annotations
  import torch
  from monai.utils.module import optional_import
label_desc: Use image node_id 1 to create a new TrainableBilateralFilter object from inherited base classes: torch.nn with example: obj = TrainableBilateralFilter(spatial_sigma, color_sigma)