class_docstr: Implementation of the ScaleBlock described in
  Fidon et al., "Scalable multimodal convolutional
      networks for brain tumour segmentation", MICCAI '17
  
  See Fig 2(a) for diagram details - SN BackEnd
class_docstr_tok: ["Implementation","of","the","ScaleBlock","described","in","Fidon","et","al.",",","``","Scalable","multimodal","convolutional","networks","for","brain","tumour","segmentation","''",",","MICCAI","'17","See","Fig","2","(","a",")","for","diagram","details","-","SN","BackEnd"]
docstr: :param input_tensor: tensor, input to the network
  :param is_training: boolean, True if network is in training mode
  :return: merged tensor after backend layers
docstr_tok: [":","param","input_tensor",":","tensor",",","input","to","the","network",":","param","is_training",":","boolean",",","True","if","network","is","in","training","mode",":","return",":","merged","tensor","after","backend","layers"]
code: def layer_op(self, input_tensor, is_training):
      """
  
      :param input_tensor: tensor, input to the network
      :param is_training: boolean, True if network is in training mode
      :return: merged tensor after backend layers
      """
      n_modality = input_tensor.shape.as_list()[-1]
      n_chns = input_tensor.shape.as_list()[-2]
      rank = input_tensor.shape.ndims
      perm = [i for i in range(rank)]
      perm[-2], perm[-1] = perm[-1], perm[-2]
  
      output_tensor = input_tensor
      for layer in range(self.n_layers):
          # modalities => feature channels
          output_tensor = tf.transpose(output_tensor, perm=perm)
          output_tensor = tf.unstack(output_tensor, axis=-1)
          for idx, tensor in enumerate(output_tensor):
              block_name = "M_F_{}_{}".format(layer, idx)
              highresblock_op = HighResBlock(
                  n_output_chns=n_modality,
                  kernels=(3, 1),
                  with_res=True,
                  w_initializer=self.initializers["w"],
                  w_regularizer=self.regularizers["w"],
                  acti_func=self.acti_func,
                  name=block_name,
              )
              output_tensor[idx] = highresblock_op(tensor, is_training)
              print(highresblock_op)
          output_tensor = tf.stack(output_tensor, axis=-1)
  
          # feature channels => modalities
          output_tensor = tf.transpose(output_tensor, perm=perm)
          output_tensor = tf.unstack(output_tensor, axis=-1)
          for idx, tensor in enumerate(output_tensor):
              block_name = "F_M_{}_{}".format(layer, idx)
              highresblock_op = HighResBlock(
                  n_output_chns=n_chns,
                  kernels=(3, 1),
                  with_res=True,
                  w_initializer=self.initializers["w"],
                  w_regularizer=self.regularizers["w"],
                  acti_func=self.acti_func,
                  name=block_name,
              )
              output_tensor[idx] = highresblock_op(tensor, is_training)
              print(highresblock_op)
          output_tensor = tf.stack(output_tensor, axis=-1)
  
      if self.func == "MAX":
          output_tensor = tf.reduce_max(output_tensor, axis=-1)
      elif self.func == "AVERAGE":
          output_tensor = tf.reduce_mean(output_tensor, axis=-1)
      return output_tensor
  
file_path: NiftyNet/niftynet/network/scalenet.py
imports: from __future__ import absolute_import, print_function, division
  import tensorflow
  from niftynet.layer.base_layer import TrainableLayer
  from niftynet.layer.convolution import ConvolutionalLayer
  from niftynet.network.base_net import BaseNet
  from niftynet.network.highres3dnet import HighRes3DNet, HighResBlock
  from niftynet.utilities.util_common import look_up_operations
label_desc: Use image node_id 2 for calling the ScaleBlock obj's underlying member method code with example usage: obj.layer_op(input_tensor, is_training) and returns: output_tensor