class_docstr: This class defines a composite layer with optional components::
  
      convolution -> feature_normalization (default batch norm) -> activation -> dropout
  
  The b_initializer and b_regularizer are applied to the ConvLayer
  The w_initializer and w_regularizer are applied to the ConvLayer,
  the feature normalization layer, and the activation layer (for 'prelu')
docstr: :param padding_constant: constant applied with CONSTANT padding
docstr_tok: [":","param","padding_constant",":","constant","applied","with","CONSTANT","padding"]
code: def __init__(
      self,
      n_output_chns,
      kernel_size=3,
      stride=1,
      dilation=1,
      padding="SAME",
      with_bias=False,
      feature_normalization="batch",
      group_size=-1,
      acti_func=None,
      preactivation=False,
      w_initializer=None,
      w_regularizer=None,
      b_initializer=None,
      b_regularizer=None,
      moving_decay=0.9,
      eps=1e-5,
      padding_constant=0,
      name="conv",
  ):
      """
      :param padding_constant: constant applied with CONSTANT padding
      """
  
      self.acti_func = acti_func
      self.feature_normalization = feature_normalization
      self.group_size = group_size
      self.preactivation = preactivation
      self.layer_name = "{}".format(name)
      if self.feature_normalization != "group" and group_size > 0:
          raise ValueError(
              "You cannot have a group_size > 0 if not using group norm"
          )
      elif self.feature_normalization == "group" and group_size <= 0:
          raise ValueError(
              "You cannot have a group_size <= 0 if using group norm"
          )
  
      if self.feature_normalization == "batch":
          self.layer_name += "_bn"
      elif self.feature_normalization == "group":
          self.layer_name += "_gn"
      elif self.feature_normalization == "instance":
          self.layer_name += "_in"
      if self.acti_func is not None:
          self.layer_name += "_{}".format(self.acti_func)
      super(ConvolutionalLayer, self).__init__(name=self.layer_name)
  
      # for ConvLayer
      self.n_output_chns = n_output_chns
      self.kernel_size = kernel_size
      self.stride = stride
      self.dilation = dilation
      self.padding = padding
      self.with_bias = with_bias
      self.padding_constant = padding_constant
  
      # for BNLayer
      self.moving_decay = moving_decay
      self.eps = eps
  
      self.initializers = {
          "w": w_initializer
          if w_initializer
          else default_w_initializer(),
          "b": b_initializer
          if b_initializer
          else default_b_initializer(),
      }
  
      self.regularizers = {"w": w_regularizer, "b": b_regularizer}
  
imports: from __future__ import absolute_import, print_function
  import math
  import numpy
  import tensorflow
  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, InstanceNormLayer
  from niftynet.layer.gn import GNLayer
  from niftynet.utilities.util_common import look_up_operations
label_desc: Use image node_id 1 to create a new ConvolutionalLayer object from inherited base classes: TrainableLayer with example: obj = ConvolutionalLayer(n_output_chns, kernel_size, stride, dilation, padding, with_bias, feature_normalization, group_size, acti_func, preactivation, w_initializer, w_regularizer, b_initializer, b_regularizer, moving_decay, eps, padding_constant, name)