class_docstr: ### Description
      This is a denoising, convolutional, variational autoencoder (VAE),
      composed of a sequence of {convolutions then downsampling} blocks,
      followed by a sequence of fully-connected layers,
      followed by a sequence of {transpose convolutions then upsampling} blocks.
      See Auto-Encoding Variational Bayes, Kingma & Welling, 2014.
      2DO: share the fully-connected parameters
      between the mean and logvar decoders.
  
  ### Building Blocks
  [ENCODER]               - See ConvEncoder class below
  [GAUSSIAN SAMPLER]      - See GaussianSampler class below
  [DECODER]               - See ConvDecoder class below
  
  ### Diagram
  
  INPUT --> [ENCODER] --> [GAUSSIAN SAMPLER] --> [FCDEC] ---> [DECODER] for means --- OUTPUTS
                                                      |                               |
                                                      ------> [DECODER] for logvars ---
  
  ### Constraints
class_docstr_tok: ["#","#","#","Description","This","is","a","denoising",",","convolutional",",","variational","autoencoder","(","VAE",")",",","composed","of","a","sequence","of","{","convolutions","then","downsampling","}","blocks",",","followed","by","a","sequence","of","fully-connected","layers",",","followed","by","a","sequence","of","{","transpose","convolutions","then","upsampling","}","blocks",".","See","Auto-Encoding","Variational","Bayes",",","Kingma","&","Welling",",","2014",".","2DO",":","share","the","fully-connected","parameters","between","the","mean","and","logvar","decoders",".","#","#","#","Building","Blocks","[","ENCODER","]","-","See","ConvEncoder","class","below","[","GAUSSIAN","SAMPLER","]","-","See","GaussianSampler","class","below","[","DECODER","]","-","See","ConvDecoder","class","below","#","#","#","Diagram","INPUT","--",">","[","ENCODER","]","--",">","[","GAUSSIAN","SAMPLER","]","--",">","[","FCDEC","]","--","-",">","[","DECODER","]","for","means","--","-","OUTPUTS","|","|","--","--","--",">","[","DECODER","]","for","logvars","--","-","#","#","#","Constraints"]
docstr: :param w_initializer: weight initialisation for network
  :param w_regularizer: weight regularisation for network
  :param b_initializer: bias initialisation for network
  :param b_regularizer: bias regularisation for network
  :param name: layer name
docstr_tok: [":","param","w_initializer",":","weight","initialisation","for","network",":","param","w_regularizer",":","weight","regularisation","for","network",":","param","b_initializer",":","bias","initialisation","for","network",":","param","b_regularizer",":","bias","regularisation","for","network",":","param","name",":","layer","name"]
code: def __init__(
      self,
      w_initializer=None,
      w_regularizer=None,
      b_initializer=None,
      b_regularizer=None,
      name="VAE",
  ):
      """
  
      :param w_initializer: weight initialisation for network
      :param w_regularizer: weight regularisation for network
      :param b_initializer: bias initialisation for network
      :param b_regularizer: bias regularisation for network
      :param name: layer name
      """
  
      super(VAE, self).__init__(name=name)
  
      # The following options completely specify the model.
      # Note that the network need not be symmetric!
  
      # 1) Denoising
      # NOTES: If (and only if) 'denoising_variance' is
      # greater than zero, Gaussian noise with zero mean
      # and 'denoising_variance' variance is added to the input.
      self.denoising_variance = 0.001
  
      # 2) The convolutional layers
      # NOTES: the ith element of 'conv_pooling_factors' is
      # the amount of pooling in the ith layer
      # (along all spatial dimensions).
      # CONSTRAINTS: All four lists must be the same length.
      self.conv_output_channels = [32, 64, 96]
      self.conv_kernel_sizes = [3, 3, 3]
      self.conv_pooling_factors = [2, 2, 2]
      self.acti_func_conv = ["selu", "selu", "selu"]
  
      # 3) The fully-connected layers
      # NOTES: If 'layer_sizes_decoder_shared' is empty then
      #  the data means and log variances are predicted
      # (separately) directly from the approximate sample
      # from the posterior. Otherwise, this sample is passed
      # through fully-connected layers of size
      # 'layer_sizes_decoder_shared', with respective activation
      # functions 'acti_func_decoder_shared'.
      # CONSTRAINTS:
      #   'layer_sizes_encoder' and 'acti_func_encoder'
      #   must have equal length.
      #   'acti_func_decoder' must be one element longer than
      #   'layer_sizes_decoder', because the final
      #   element of 'acti_func_decoder' is the activation function
      #   of the final fully-connected layer (which is added to the
      #   network automatically, and whose dimensionality equals
      #  that of the input to the fully-connected layers).
  
      self.layer_sizes_encoder = [256, 128]
      self.acti_func_encoder = ["selu", "selu"]
      self.number_of_latent_variables = 64
      self.number_of_samples_from_posterior = 100
      self.layer_sizes_decoder_shared = [128]
      self.acti_func_decoder_shared = ["selu"]
      self.layer_sizes_decoder = self.layer_sizes_encoder[::-1]
      self.acti_func_decoder = self.acti_func_encoder[::-1] + ["selu"]
  
      # 4) The transpose convolutional layers (for predicting means)
      # NOTES: 'upsampling_mode' determines how the feature maps
      #  in the decoding layers are upsampled.
      # The options are,
      # 1. 'DECONV' (recommended):
      #     kernel shape is HxWxDxChannelsInxChannelsOut,
      # 2. 'CHANNELWISE_DECONV':
      #     kernel shape is HxWxDx1x1,
      # 3. 'REPLICATE':
      #     no parameters.
      # CONSTRAINTS:
      #     'trans_conv_output_channels_means' is one element
      #     shorter than 'trans_conv_kernel_sizes_means',
      #     'trans_conv_unpooling_factors_means', and
      #     'trans_conv_unpooling_factors_means'
      #     because the final element of
      #     'trans_conv_output_channels_means' must be
      #     the number of channels in the input,
      #     and this is added to the list automatically.
      self.trans_conv_output_channels_means = self.conv_output_channels[
          -2::-1
      ]
      self.trans_conv_kernel_sizes_means = self.conv_kernel_sizes[::-1]
      self.trans_conv_unpooling_factors_means = (
          self.conv_pooling_factors[::-1]
      )
      self.acti_func_trans_conv_means = self.acti_func_conv[-2::-1] + [
          "sigmoid"
      ]
      self.upsampling_mode_means = "DECONV"
  
      # 5) The transpose convolutional layers
      #     (for predicting (log) variances)
      # CONSTRAINTS:
      #     same as for the mean-predicting layers above.
      self.trans_conv_output_channels_logvars = (
          self.trans_conv_output_channels_means
      )
      self.trans_conv_kernel_sizes_logvars = (
          self.trans_conv_kernel_sizes_means
      )
      self.trans_conv_unpooling_factors_logvars = (
          self.trans_conv_unpooling_factors_means
      )
      self.acti_func_trans_conv_logvars = self.acti_func_conv[
          -2::-1
      ] + [None]
      self.upsampling_mode_logvars = self.upsampling_mode_means
  
      # 6) Clip logvars to avoid infs & nans
      # NOTES: variance = exp(logvars),
      # so we must keep logvars within reasonable limits.
      self.logvars_upper_bound = 50
      self.logvars_lower_bound = -self.logvars_upper_bound
  
      self.initializers = {"w": w_initializer, "b": b_initializer}
      self.regularizers = {"w": w_regularizer, "b": b_regularizer}
  
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 1 to create a new VAE object from inherited base classes: TrainableLayer with example: obj = VAE(w_initializer, w_regularizer, b_initializer, b_regularizer, name)