class_docstr: This class defines a layer implementing CRFAsRNN described in [1] using
  a bilateral and a spatial kernel as in [2].
  Essentially, this layer smooths its input based on a distance in a feature
  space comprising spatial and feature dimensions.
  High-dimensional Gaussian filtering adapted from [3].
  
  [1] Zheng et al., https://arxiv.org/abs/1502.03240
  [2] Krahenbuhl and Koltun, https://arxiv.org/pdf/1210.5644.pdf
  [3] Adam et al., https://graphics.stanford.edu/papers/permutohedral/
class_docstr_tok: ["This","class","defines","a","layer","implementing","CRFAsRNN","described","in","[","1","]","using","a","bilateral","and","a","spatial","kernel","as","in","[","2","]",".","Essentially",",","this","layer","smooths","its","input","based","on","a","distance","in","a","feature","space","comprising","spatial","and","feature","dimensions",".","High-dimensional","Gaussian","filtering","adapted","from","[","3","]",".","[","1","]","Zheng","et","al.",",","https",":","\/\/arxiv.org\/abs\/1502.03240","[","2","]","Krahenbuhl","and","Koltun",",","https",":","\/\/arxiv.org\/pdf\/1210.5644.pdf","[","3","]","Adam","et","al.",",","https",":","\/\/graphics.stanford.edu\/papers\/permutohedral\/"]
docstr: Compute `T` iterations of mean field update given a dense CRF.
  
  This layer maintains trainable CRF model parameters
  (a compatibility function and `m` kernel weights).
  
  :param I: feature maps used in the dense pairwise term of CRF
  :param U: activation maps used in the unary term of CRF (before softmax)
  :return: Maximum a posteriori labeling (before softmax)
docstr_tok: ["Compute","`","T","`","iterations","of","mean","field","update","given","a","dense","CRF",".","This","layer","maintains","trainable","CRF","model","parameters","(","a","compatibility","function","and","`","m","`","kernel","weights",")",".",":","param","I",":","feature","maps","used","in","the","dense","pairwise","term","of","CRF",":","param","U",":","activation","maps","used","in","the","unary","term","of","CRF","(","before","softmax",")",":","return",":","Maximum","a","posteriori","labeling","(","before","softmax",")"]
code: def layer_op(self, I, U):
      """
      Compute `T` iterations of mean field update given a dense CRF.
  
      This layer maintains trainable CRF model parameters
      (a compatibility function and `m` kernel weights).
  
      :param I: feature maps used in the dense pairwise term of CRF
      :param U: activation maps used in the unary term of CRF (before softmax)
      :return: Maximum a posteriori labeling (before softmax)
      """
  
      spatial_rank = infer_spatial_rank(U)
      all_shape = U.shape.as_list()
      batch_size, spatial_shape, n_ch = (
          all_shape[0],
          all_shape[1:-1],
          all_shape[-1],
      )
      n_feat = I.shape.as_list()[-1]
      if self._aspect_ratio is None:
          self._aspect_ratio = [1.0] * spatial_rank
      self._aspect_ratio = expand_spatial_params(
          self._aspect_ratio, spatial_rank, float
      )
  
      # constructing the scaled regular grid
      spatial_grid = tf.meshgrid(
          *[
              np.arange(i, dtype=np.float32) * a
              for i, a in zip(spatial_shape, self._aspect_ratio)
          ],
          indexing="ij",
      )
      spatial_coords = tf.stack(spatial_grid[::-1], spatial_rank)
      spatial_coords = tf.tile(
          tf.expand_dims(spatial_coords, 0),
          [batch_size] + [1] * spatial_rank + [1],
      )
  
      # concatenating spatial coordinates and features
      # (and squeeze spatially)
      # for the bilateral kernel
      bilateral_coords = tf.reshape(
          tf.concat([spatial_coords / self._alpha, I / self._beta], -1),
          [batch_size, -1, n_feat + spatial_rank],
      )
      # for the spatial kernel
      spatial_coords = tf.reshape(
          spatial_coords / self._gamma, [batch_size, -1, spatial_rank]
      )
  
      # Build permutohedral structures for smoothing
      permutohedrals = [
          permutohedral_prepare(coords)
          for coords in (bilateral_coords, spatial_coords)
      ]
  
      # squeeze the spatial shapes and recover them in the end
      U = tf.reshape(U, [batch_size, -1, n_ch])
      n_voxels = U.shape.as_list()[1]
      # normalisation factor
      norms = []
      for idx, permutohedral in enumerate(permutohedrals):
          spatial_norm = _permutohedral_gen(
              permutohedral,
              tf.ones((batch_size, n_voxels, 1)),
              "spatial_norms" + str(idx),
          )
          spatial_norm.set_shape([batch_size, n_voxels, 1])
          spatial_norm = 1.0 / tf.sqrt(spatial_norm + 1e-20)
          norms.append(spatial_norm)
  
      # trainable compatibility matrix mu (initialised as identity * -1)
      mu_shape = [n_ch, n_ch]
      if self._mu_init is None:
          self._mu_init = -np.eye(n_ch)
      self._mu_init = np.reshape(self._mu_init, mu_shape)
      mu = tf.get_variable(
          "Compatibility",
          initializer=tf.constant(self._mu_init, dtype=tf.float32),
      )
  
      # trainable kernel weights
      weight_shape = [n_ch]
      if self._w_init is None:
          self._w_init = [np.ones(n_ch), np.ones(n_ch)]
      self._w_init = [
          np.reshape(_w, weight_shape) for _w in self._w_init
      ]
      kernel_weights = [
          tf.get_variable(
              "FilterWeights{}".format(idx),
              initializer=tf.constant(
                  self._w_init[idx], dtype=tf.float32
              ),
          )
          for idx, k in enumerate(permutohedrals)
      ]
  
      H1 = U
      for t in range(self._T):
          H1 = ftheta(
              U,
              H1,
              permutohedrals,
              mu,
              kernel_weights,
              norms,
              name="{}{}".format(self.name, t),
          )
      return tf.reshape(H1, all_shape)
  
file_path: NiftyNet/niftynet/layer/crf.py
imports: from __future__ import absolute_import, print_function
  import numpy
  import tensorflow
  from niftynet.layer.base_layer import TrainableLayer
  from niftynet.layer.layer_util import infer_spatial_rank, expand_spatial_params
label_desc: Use image node_id 2 for calling the CRFAsRNNLayer obj's underlying member method code with example usage: obj.layer_op(I, U) and returns: tf