class_docstr: ### Description
      implementation of V-Net:
        Milletari et al., "V-Net: Fully convolutional neural networks for
        volumetric medical image segmentation", 3DV '16
  
  ### Building Blocks
  (n)[dBLOCK]        - Downsampling VNet block with n conv layers (kernel size = 5,
                          with residual connections, activation = relu as default)
                          followed by downsampling conv layer (kernel size = 2,
                          stride = 2) + final activation
  (n)[uBLOCK]         - Upsampling VNet block with n conv layers (kernel size = 5,
                          with residual connections, activation = relu as default)
                          followed by deconv layer (kernel size = 2,
                          stride = 2) + final activation
  (n)[sBLOCK]         - VNet block with n conv layers (kernel size = 5,
                          with residual connections, activation = relu as default)
                          followed by 1x1x1 conv layer (kernel size = 1,
                          stride = 1) + final activation
  
  ### Diagram
  
  INPUT  -->  (1)[dBLOCK] - - - - - - - - - - - - - - - - (1)[sBLOCK] --> OUTPUT
                  |                                             |
                 (2)[dBLOCK] - - - - - - - - - - - - (2)[uBLOCK]
                      |                                   |
                      (3)[dBLOCK]  - - - - - - - (3)[uBLOCK]
                          |                           |
                          (3)[dBLOCK]  - - - (3)[uBLOCK]
                              |                   |
                              ----(3)[uBLOCk] ----
  
  
  ### Constraints
   - Input size should be divisible by 8
   - Input should be either 2D or 3D
class_docstr_tok: ["#","#","#","Description","implementation","of","V-Net",":","Milletari","et","al.",",","``","V-Net",":","Fully","convolutional","neural","networks","for","volumetric","medical","image","segmentation","''",",","3DV","'16","#","#","#","Building","Blocks","(","n",")","[","dBLOCK","]","-","Downsampling","VNet","block","with","n","conv","layers","(","kernel","size","=","5",",","with","residual","connections",",","activation","=","relu","as","default",")","followed","by","downsampling","conv","layer","(","kernel","size","=","2",",","stride","=","2",")","+","final","activation","(","n",")","[","uBLOCK","]","-","Upsampling","VNet","block","with","n","conv","layers","(","kernel","size","=","5",",","with","residual","connections",",","activation","=","relu","as","default",")","followed","by","deconv","layer","(","kernel","size","=","2",",","stride","=","2",")","+","final","activation","(","n",")","[","sBLOCK","]","-","VNet","block","with","n","conv","layers","(","kernel","size","=","5",",","with","residual","connections",",","activation","=","relu","as","default",")","followed","by","1x1x1","conv","layer","(","kernel","size","=","1",",","stride","=","1",")","+","final","activation","#","#","#","Diagram","INPUT","--",">","(","1",")","[","dBLOCK","]","-","-","-","-","-","-","-","-","-","-","-","-","-","-","-","-","(","1",")","[","sBLOCK","]","--",">","OUTPUT","|","|","(","2",")","[","dBLOCK","]","-","-","-","-","-","-","-","-","-","-","-","-","(","2",")","[","uBLOCK","]","|","|","(","3",")","[","dBLOCK","]","-","-","-","-","-","-","-","(","3",")","[","uBLOCK","]","|","|","(","3",")","[","dBLOCK","]","-","-","-","(","3",")","[","uBLOCK","]","|","|","--","--","(","3",")","[","uBLOCk","]","--","--","#","#","#","Constraints","-","Input","size","should","be","divisible","by","8","-","Input","should","be","either","2D","or","3D"]
docstr: :param images: tensor to input to the network. Size has to be divisible by 8
  :param is_training:  boolean, True if network is in training mode
  :param layer_id: not in use
  :param unused_kwargs: other conditional arguments, not in use
  :return: tensor, network output
docstr_tok: [":","param","images",":","tensor","to","input","to","the","network",".","Size","has","to","be","divisible","by","8",":","param","is_training",":","boolean",",","True","if","network","is","in","training","mode",":","param","layer_id",":","not","in","use",":","param","unused_kwargs",":","other","conditional","arguments",",","not","in","use",":","return",":","tensor",",","network","output"]
code: def layer_op(
      self, images, is_training=True, layer_id=-1, **unused_kwargs
  ):
      """
  
      :param images: tensor to input to the network. Size has to be divisible by 8
      :param is_training:  boolean, True if network is in training mode
      :param layer_id: not in use
      :param unused_kwargs: other conditional arguments, not in use
      :return: tensor, network output
      """
      assert layer_util.check_spatial_dims(images, lambda x: x % 8 == 0)
  
      if layer_util.infer_spatial_rank(images) == 2:
          padded_images = tf.tile(images, [1, 1, 1, self.n_features[0]])
      elif layer_util.infer_spatial_rank(images) == 3:
          padded_images = tf.tile(
              images, [1, 1, 1, 1, self.n_features[0]]
          )
      else:
          raise ValueError(
              "not supported spatial rank of the input image"
          )
      # downsampling  blocks
      res_1, down_1 = VNetBlock(
          "DOWNSAMPLE",
          1,
          self.n_features[0],
          self.n_features[1],
          w_initializer=self.initializers["w"],
          w_regularizer=self.regularizers["w"],
          acti_func=self.acti_func,
          name="L1",
      )(images, padded_images)
      res_2, down_2 = VNetBlock(
          "DOWNSAMPLE",
          2,
          self.n_features[1],
          self.n_features[2],
          w_initializer=self.initializers["w"],
          w_regularizer=self.regularizers["w"],
          acti_func=self.acti_func,
          name="L2",
      )(down_1, down_1)
      res_3, down_3 = VNetBlock(
          "DOWNSAMPLE",
          3,
          self.n_features[2],
          self.n_features[3],
          w_initializer=self.initializers["w"],
          w_regularizer=self.regularizers["w"],
          acti_func=self.acti_func,
          name="L3",
      )(down_2, down_2)
      res_4, down_4 = VNetBlock(
          "DOWNSAMPLE",
          3,
          self.n_features[3],
          self.n_features[4],
          acti_func=self.acti_func,
          name="L4",
      )(down_3, down_3)
      # upsampling blocks
      _, up_4 = VNetBlock(
          "UPSAMPLE",
          3,
          self.n_features[4],
          self.n_features[4],
          w_initializer=self.initializers["w"],
          w_regularizer=self.regularizers["w"],
          acti_func=self.acti_func,
          name="V_",
      )(down_4, down_4)
      concat_r4 = ElementwiseLayer("CONCAT")(up_4, res_4)
      _, up_3 = VNetBlock(
          "UPSAMPLE",
          3,
          self.n_features[4],
          self.n_features[3],
          w_initializer=self.initializers["w"],
          w_regularizer=self.regularizers["w"],
          acti_func=self.acti_func,
          name="R4",
      )(concat_r4, up_4)
      concat_r3 = ElementwiseLayer("CONCAT")(up_3, res_3)
      _, up_2 = VNetBlock(
          "UPSAMPLE",
          3,
          self.n_features[3],
          self.n_features[2],
          w_initializer=self.initializers["w"],
          w_regularizer=self.regularizers["w"],
          acti_func=self.acti_func,
          name="R3",
      )(concat_r3, up_3)
      concat_r2 = ElementwiseLayer("CONCAT")(up_2, res_2)
      _, up_1 = VNetBlock(
          "UPSAMPLE",
          2,
          self.n_features[2],
          self.n_features[1],
          w_initializer=self.initializers["w"],
          w_regularizer=self.regularizers["w"],
          acti_func=self.acti_func,
          name="R2",
      )(concat_r2, up_2)
      # final class score
      concat_r1 = ElementwiseLayer("CONCAT")(up_1, res_1)
      _, output_tensor = VNetBlock(
          "SAME",
          1,
          self.n_features[1],
          self.num_classes,
          w_initializer=self.initializers["w"],
          w_regularizer=self.regularizers["w"],
          b_initializer=self.initializers["b"],
          b_regularizer=self.regularizers["b"],
          acti_func=self.acti_func,
          name="R1",
      )(concat_r1, up_1)
      return output_tensor
  
file_path: NiftyNet/niftynet/network/vnet.py
imports: from __future__ import absolute_import, print_function
  import tensorflow
  from niftynet.layer import layer_util
  from niftynet.layer.activation import ActiLayer
  from niftynet.layer.base_layer import TrainableLayer
  from niftynet.layer.convolution import ConvLayer
  from niftynet.layer.deconvolution import DeconvLayer
  from niftynet.layer.elementwise import ElementwiseLayer
  from niftynet.network.base_net import BaseNet
  from niftynet.utilities.util_common import look_up_operations
label_desc: Use image node_id 2 for calling the VNet obj's underlying member method code with example usage: obj.layer_op(images, is_training, layer_id) and returns: output_tensor