class_docstr: ### Description
      This is a generic encoder composed of
      {convolutions then downsampling} blocks followed by
      fully-connected layers.
class_docstr_tok: ["#","#","#","Description","This","is","a","generic","encoder","composed","of","{","convolutions","then","downsampling","}","blocks","followed","by","fully-connected","layers","."]
docstr: :param images: tensor, input to the network
  :param is_training: boolean, True if network is in training mode
  :return: tensor, output of the encoder branch
docstr_tok: [":","param","images",":","tensor",",","input","to","the","network",":","param","is_training",":","boolean",",","True","if","network","is","in","training","mode",":","return",":","tensor",",","output","of","the","encoder","branch"]
code: def layer_op(self, images, is_training):
      """
  
      :param images: tensor, input to the network
      :param is_training: boolean, True if network is in training mode
      :return: tensor, output of the encoder branch
      """
  
      # Define the encoding convolutional layers
      encoders_cnn = []
      encoders_downsamplers = []
      for i in range(0, len(self.conv_output_channels)):
          encoders_cnn.append(
              ConvolutionalLayer(
                  n_output_chns=self.conv_output_channels[i],
                  kernel_size=self.conv_kernel_sizes[i],
                  padding="SAME",
                  with_bias=True,
                  feature_normalization="batch",
                  w_initializer=self.initializers["w"],
                  w_regularizer=None,
                  acti_func=self.acti_func_conv[i],
                  name="encoder_conv_{}_{}".format(
                      self.conv_kernel_sizes[i],
                      self.conv_output_channels[i],
                  ),
              )
          )
          print(encoders_cnn[-1])
  
          encoders_downsamplers.append(
              ConvolutionalLayer(
                  n_output_chns=self.conv_output_channels[i],
                  kernel_size=self.conv_pooling_factors[i],
                  stride=self.conv_pooling_factors[i],
                  padding="SAME",
                  with_bias=False,
                  feature_normalization="batch",
                  w_initializer=self.initializers["w"],
                  w_regularizer=None,
                  acti_func=self.acti_func_conv[i],
                  name="encoder_downsampler_{}_{}".format(
                      self.conv_pooling_factors[i],
                      self.conv_pooling_factors[i],
                  ),
              )
          )
  
          print(encoders_downsamplers[-1])
  
      # Define the encoding fully-connected layers
      encoders_fc = []
      for i in range(0, len(self.layer_sizes_encoder)):
          encoders_fc.append(
              FullyConnectedLayer(
                  n_output_chns=self.layer_sizes_encoder[i],
                  with_bias=True,
                  feature_normalization="batch",
                  acti_func=self.acti_func_encoder[i],
                  w_initializer=self.initializers["w"],
                  w_regularizer=self.regularizers["w"],
                  name="encoder_fc_{}".format(
                      self.layer_sizes_encoder[i]
                  ),
              )
          )
          print(encoders_fc[-1])
  
      # Add Gaussian noise to the input
      if self.denoising_variance > 0 and is_training:
          flow = images + tf.random_normal(
              tf.shape(images), 0.0, self.denoising_variance
          )
      else:
          flow = images
  
      # Convolutional encoder layers
      for i in range(0, len(self.conv_output_channels)):
          flow = encoders_downsamplers[i](
              encoders_cnn[i](flow, is_training), is_training
          )
  
      # Flatten the feature maps
      flow = tf.reshape(flow, [-1, self.serialised_shape])
  
      # Fully-connected encoder layers
      for i in range(0, len(self.layer_sizes_encoder)):
          flow = encoders_fc[i](flow, is_training)
  
      return flow
  
imports: from __future__ import absolute_import, print_function, division
  import numpy
  import tensorflow
  from niftynet.layer.base_layer import TrainableLayer
  from niftynet.layer.convolution import ConvolutionalLayer
  from niftynet.layer.deconvolution import DeconvolutionalLayer
  from niftynet.layer.fully_connected import FullyConnectedLayer
  from niftynet.layer.upsample import UpSampleLayer
label_desc: Use image node_id 2 for calling the ConvEncoder obj's underlying member method code with example usage: obj.layer_op(images, is_training) and returns: flow