class_docstr: This class defines a composite layer with optional components::
  
    channel sparse convolution ->
    batchwise-spatial dropout ->
    batch_norm ->
    activation
  
  The b_initializer and b_regularizer are applied to
  the ChannelSparseConvLayer, the w_initializer and w_regularizer
  are applied to the ChannelSparseConvLayer, the batch normalisation
  layer, and the activation layer (for 'prelu')
class_docstr_tok: ["This","class","defines","a","composite","layer","with","optional","components",":",":","channel","sparse","convolution","-",">","batchwise-spatial","dropout","-",">","batch_norm","-",">","activation","The","b_initializer","and","b_regularizer","are","applied","to","the","ChannelSparseConvLayer",",","the","w_initializer","and","w_regularizer","are","applied","to","the","ChannelSparseConvLayer",",","the","batch","normalisation","layer",",","and","the","activation","layer","(","for","'prelu","'",")"]
code: def layer_op(
      self,
      input_tensor,
      input_mask=None,
      is_training=None,
      keep_prob=None,
  ):
      conv_layer = ChannelSparseConvLayer(
          n_output_chns=self.n_output_chns,
          kernel_size=self.kernel_size,
          stride=self.stride,
          dilation=self.dilation,
          padding=self.padding,
          with_bias=self.with_bias,
          w_initializer=self.initializers["w"],
          w_regularizer=self.regularizers["w"],
          b_initializer=self.initializers["b"],
          b_regularizer=self.regularizers["b"],
          name="conv_",
      )
      if keep_prob is not None:
          output_mask = (
              tf.to_float(
                  tf.random_shuffle(tf.range(self.n_output_chns))
              )
              < keep_prob * self.n_output_chns
          )
          n_output_ch = math.ceil(keep_prob * self.n_output_chns)
      else:
          output_mask = tf.ones([self.n_output_chns]) > 0
          n_output_ch = self.n_output_chns
  
      output_tensor = conv_layer(input_tensor, input_mask, output_mask)
      output_tensor.set_shape(
          output_tensor.shape.as_list()[:-1] + [n_output_ch]
      )
  
      if self.feature_normalization == "batch":
          if is_training is None:
              raise ValueError(
                  "For batch norm, you must set the `is_training` argument."
              )
          bn_layer = ChannelSparseBNLayer(
              self.n_output_chns,
              regularizer=self.regularizers["w"],
              moving_decay=self.moving_decay,
              eps=self.eps,
              name="bn_",
          )
          output_tensor = bn_layer(
              output_tensor, is_training, output_mask
          )
  
      if self.acti_func is not None:
          acti_layer = ActiLayer(
              func=self.acti_func,
              regularizer=self.regularizers["w"],
              name="acti_",
          )
          output_tensor = acti_layer(output_tensor)
      return output_tensor, output_mask
  
imports: from __future__ import absolute_import, print_function
  import math
  import numpy
  import tensorflow
  from tensorflow.python.training import moving_averages
  import niftynet.layer.bn
  import niftynet.layer.convolution
  import niftynet.layer.deconvolution
  from niftynet.layer import layer_util
  from niftynet.layer.activation import ActiLayer
  from niftynet.layer.base_layer import TrainableLayer
  from niftynet.layer.deconvolution import infer_output_dims
label_desc: Use image node_id 2 for calling the ChannelSparseConvolutionalLayer obj's underlying member method code with example usage: obj.layer_op(input_tensor, input_mask, is_training, keep_prob) and returns: output_tensor,  output_mask