class_docstr: implementation of HighRes3DNet:
    Li et al., "On the compactness, efficiency, and representation of 3D
    convolutional networks: Brain parcellation as a pretext task", IPMI '17
  
    ### Building blocks
  
    {   }       -  Residual connections: see He et al. "Deep residual learning for
                                                        image recognition", in CVPR '16
  
    [CONV]      -  Convolutional layer in form: Activation(Convolution(X))
                   where X = input tensor or output of previous layer
  
                   and Activation is a function which includes:
  
                      a) Batch-Norm
                      b) Activation Function (ReLu, PreLu, Sigmoid, Tanh etc.)
                      c) Drop-out layer by sampling random variables from a Bernouilli distribution
                         if p < 1
  
    [CONV*]      - Convolutional layer with no activation function
  
    (r)[D-CONV(d)] - Convolutional layer with dilated convolutions with blocks in
                   pre-activation mode: D-Convolution(Activation(X))
                   see He et al., "Identity Mappings in Deep Residual Networks", ECCV '16
  
                   dilation factor = d
                   D-CONV(2) : dilated convolution with dilation factor 2
  
                   repeat factor = r
                   e.g.
                   (2)[D-CONV(d)]     : 2 dilated convolutional layers in a row [D-CONV] -> [D-CONV]
                   { (2)[D-CONV(d)] } : 2 dilated convolutional layers within residual block
  
  ### Diagram
  
  INPUT --> [CONV] --> { (3)[D-CONV(1)] } --> { (3)[D-CONV(2)] } --> { (3)[D-CONV(4)] } -> [CONV*] -> Loss
  
  ### Constraints
  - Input image size should be divisible by 8
class_docstr_tok: ["implementation","of","HighRes3DNet",":","Li","et","al.",",","``","On","the","compactness",",","efficiency",",","and","representation","of","3D","convolutional","networks",":","Brain","parcellation","as","a","pretext","task","''",",","IPMI","'17","#","#","#","Building","blocks","{","}","-","Residual","connections",":","see","He","et","al",".","``","Deep","residual","learning","for","image","recognition","''",",","in","CVPR","'16","[","CONV","]","-","Convolutional","layer","in","form",":","Activation","(","Convolution","(","X",")",")","where","X","=","input","tensor","or","output","of","previous","layer","and","Activation","is","a","function","which","includes",":","a",")","Batch-Norm","b",")","Activation","Function","(","ReLu",",","PreLu",",","Sigmoid",",","Tanh","etc",".",")","c",")","Drop-out","layer","by","sampling","random","variables","from","a","Bernouilli","distribution","if","p","<","1","[","CONV","*","]","-","Convolutional","layer","with","no","activation","function","(","r",")","[","D-CONV","(","d",")","]","-","Convolutional","layer","with","dilated","convolutions","with","blocks","in","pre-activation","mode",":","D-Convolution","(","Activation","(","X",")",")","see","He","et","al.",",","``","Identity","Mappings","in","Deep","Residual","Networks","''",",","ECCV","'16","dilation","factor","=","d","D-CONV","(","2",")",":","dilated","convolution","with","dilation","factor","2","repeat","factor","=","r","e.g",".","(","2",")","[","D-CONV","(","d",")","]",":","2","dilated","convolutional","layers","in","a","row","[","D-CONV","]","-",">","[","D-CONV","]","{","(","2",")","[","D-CONV","(","d",")","]","}",":","2","dilated","convolutional","layers","within","residual","block","#","#","#","Diagram","INPUT","--",">","[","CONV","]","--",">","{","(","3",")","[","D-CONV","(","1",")","]","}","--",">","{","(","3",")","[","D-CONV","(","2",")","]","}","--",">","{","(","3",")","[","D-CONV","(","4",")","]","}","-",">","[","CONV","*","]","-",">","Loss","#","#","#","Constraints","-","Input","image","size","should","be","divisible","by","8"]
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: int, index of the layer to return as output
  :param unused_kwargs:
  :return: output of layer indicated by layer_id
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",":","int",",","index","of","the","layer","to","return","as","output",":","param","unused_kwargs",":",":","return",":","output","of","layer","indicated","by","layer_id"]
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: int, index of the layer to return as output
      :param unused_kwargs:
      :return: output of layer indicated by layer_id
      """
      assert layer_util.check_spatial_dims(images, lambda x: x % 8 == 0)
      # go through self.layers, create an instance of each layer
      # and plugin data
      layer_instances = []
  
      ### first convolution layer
      params = self.layers[0]
      first_conv_layer = ConvolutionalLayer(
          n_output_chns=params["n_features"],
          kernel_size=params["kernel_size"],
          acti_func=self.acti_func,
          w_initializer=self.initializers["w"],
          w_regularizer=self.regularizers["w"],
          name=params["name"],
      )
      flow = first_conv_layer(images, is_training)
      layer_instances.append((first_conv_layer, flow))
  
      ### resblocks, all kernels dilated by 1 (normal convolution)
      params = self.layers[1]
      with DilatedTensor(flow, dilation_factor=1) as dilated:
          for j in range(params["repeat"]):
              res_block = HighResBlock(
                  params["n_features"],
                  params["kernels"],
                  acti_func=self.acti_func,
                  w_initializer=self.initializers["w"],
                  w_regularizer=self.regularizers["w"],
                  name="%s_%d" % (params["name"], j),
              )
              dilated.tensor = res_block(dilated.tensor, is_training)
              layer_instances.append((res_block, dilated.tensor))
      flow = dilated.tensor
  
      ### resblocks, all kernels dilated by 2
      params = self.layers[2]
      with DilatedTensor(flow, dilation_factor=2) as dilated:
          for j in range(params["repeat"]):
              res_block = HighResBlock(
                  params["n_features"],
                  params["kernels"],
                  acti_func=self.acti_func,
                  w_initializer=self.initializers["w"],
                  w_regularizer=self.regularizers["w"],
                  name="%s_%d" % (params["name"], j),
              )
              dilated.tensor = res_block(dilated.tensor, is_training)
              layer_instances.append((res_block, dilated.tensor))
      flow = dilated.tensor
  
      ### resblocks, all kernels dilated by 4
      params = self.layers[3]
      with DilatedTensor(flow, dilation_factor=4) as dilated:
          for j in range(params["repeat"]):
              res_block = HighResBlock(
                  params["n_features"],
                  params["kernels"],
                  acti_func=self.acti_func,
                  w_initializer=self.initializers["w"],
                  w_regularizer=self.regularizers["w"],
                  name="%s_%d" % (params["name"], j),
              )
              dilated.tensor = res_block(dilated.tensor, is_training)
              layer_instances.append((res_block, dilated.tensor))
      flow = dilated.tensor
  
      ### 1x1x1 convolution layer
      params = self.layers[4]
      fc_layer = ConvolutionalLayer(
          n_output_chns=params["n_features"],
          kernel_size=params["kernel_size"],
          acti_func=self.acti_func,
          w_initializer=self.initializers["w"],
          w_regularizer=self.regularizers["w"],
          name=params["name"],
      )
      flow = fc_layer(flow, is_training)
      layer_instances.append((fc_layer, flow))
  
      ### 1x1x1 convolution layer
      params = self.layers[5]
      fc_layer = ConvolutionalLayer(
          n_output_chns=params["n_features"],
          kernel_size=params["kernel_size"],
          acti_func=None,
          w_initializer=self.initializers["w"],
          w_regularizer=self.regularizers["w"],
          name=params["name"],
      )
      flow = fc_layer(flow, is_training)
      layer_instances.append((fc_layer, flow))
  
      # set training properties
      if is_training:
          self._print(layer_instances)
          return layer_instances[-1][1]
      return layer_instances[layer_id][1]
  
file_path: NiftyNet/niftynet/network/highres3dnet.py
imports: from __future__ import absolute_import, print_function
  from six.moves import range
  from niftynet.layer import layer_util
  from niftynet.layer.activation import ActiLayer
  from niftynet.layer.base_layer import TrainableLayer
  from niftynet.layer.bn import BNLayer
  from niftynet.layer.convolution import ConvLayer, ConvolutionalLayer
  from niftynet.layer.dilatedcontext import DilatedTensor
  from niftynet.layer.elementwise import ElementwiseLayer
  from niftynet.network.base_net import BaseNet
label_desc: Use image node_id 2 for calling the HighRes3DNet obj's underlying member method code with example usage: obj.layer_op(images, is_training, layer_id) and returns: layer_instances, layer_instances