class_docstr: Dense Feature Stack with Skip Layer and Downsampling
  
  - Downsampling is done through strided convolution.
  
  ---[ DenseFeatureStackBlock ]----------[ Conv ]------- Skip layer
                                    |
                                    -------------------- Downsampled Output
  
  See DenseFeatureStackBlock for more info.
docstr: :param input_tensor: tf tensor, input to the DenseFeatureStackBlock
  :param is_training: boolean, True if network is in training mode
  :param keep_prob: double, percentage of nodes to keep for drop-out
  :return: feature stack after skip convolution, feature stack after downsampling
docstr_tok: [":","param","input_tensor",":","tf","tensor",",","input","to","the","DenseFeatureStackBlock",":","param","is_training",":","boolean",",","True","if","network","is","in","training","mode",":","param","keep_prob",":","double",",","percentage","of","nodes","to","keep","for","drop-out",":","return",":","feature","stack","after","skip","convolution",",","feature","stack","after","downsampling"]
code: def layer_op(self, input_tensor, is_training=True, keep_prob=None):
      """
  
      :param input_tensor: tf tensor, input to the DenseFeatureStackBlock
      :param is_training: boolean, True if network is in training mode
      :param keep_prob: double, percentage of nodes to keep for drop-out
      :return: feature stack after skip convolution, feature stack after downsampling
      """
      # Create dense feature stack block with skip and downsample
      dfssd_block = self.create_block()
  
      # Feed input through the dense feature stack block
      feature_stack = dfssd_block.dfs_block(
          input_tensor, is_training=is_training, keep_prob=keep_prob
      )
  
      # Merge feature stack
      merged_features = tf.concat(
          feature_stack, len(input_tensor.shape) - 1
      )
  
      # Perform skip convolution
      skip_conv = dfssd_block.skip_conv(
          merged_features, is_training=is_training, keep_prob=keep_prob
      )
  
      # Downsample if needed
      down_conv = None
      if dfssd_block.down_conv is not None:
          down_conv = dfssd_block.down_conv(
              merged_features,
              is_training=is_training,
              keep_prob=keep_prob,
          )
  
      return skip_conv, down_conv
  
imports: from __future__ import absolute_import, print_function
  import tensorflow
  from niftynet.io.misc_io import image3_axial
  from niftynet.layer import layer_util
  from niftynet.layer.affine_augmentation import AffineAugmentationLayer
  from niftynet.layer.base_layer import TrainableLayer
  from niftynet.layer.bn import BNLayer
  from niftynet.layer.channel_sparse_convolution import ChannelSparseConvolutionalLayer
  from niftynet.layer.convolution import ConvolutionalLayer
  from niftynet.layer.linear_resize import LinearResizeLayer
  from niftynet.layer.downsample import DownSampleLayer
  from niftynet.network.base_net import BaseNet
  from collections import namedtuple
label_desc: Use image node_id 3 for calling the DenseFeatureStackBlockWithSkipAndDownsample obj's underlying member method code with example usage: obj.layer_op(input_tensor, is_training, keep_prob) and returns: skip_conv,  down_conv