class_docstr: Abstract nD convolution layer (private, used as implementation base).
  
  This layer creates a convolution kernel that is convolved
  (actually cross-correlated) with the layer input to produce a tensor of
  outputs. It may also include a bias addition and activation function
  on the outputs. It assumes the `kernel` and/or `bias` are drawn from
  distributions.
  
  By default, the layer implements a stochastic forward pass via
  sampling from the kernel and bias posteriors,
  ```none
  outputs = f(inputs; kernel, bias), kernel, bias ~ posterior
  ```
  where f denotes the layer's calculation.
  
  The arguments permit separate specification of the surrogate posterior
  (`q(W|x)`), prior (`p(W)`), and divergence for both the `kernel` and `bias`
  distributions.
class_docstr_tok: ["Abstract","nD","convolution","layer","(","private",",","used","as","implementation","base",")",".","This","layer","creates","a","convolution","kernel","that","is","convolved","(","actually","cross-correlated",")","with","the","layer","input","to","produce","a","tensor","of","outputs",".","It","may","also","include","a","bias","addition","and","activation","function","on","the","outputs",".","It","assumes","the","`","kernel","`","and\/or","`","bias","`","are","drawn","from","distributions",".","By","default",",","the","layer","implements","a","stochastic","forward","pass","via","sampling","from","the","kernel","and","bias","posteriors",",","``","`","none","outputs","=","f","(","inputs",";","kernel",",","bias",")",",","kernel",",","bias","~","posterior","``","`","where","f","denotes","the","layer","'s","calculation",".","The","arguments","permit","separate","specification","of","the","surrogate","posterior","(","`","q","(","W|x",")","`",")",",","prior","(","`","p","(","W",")","`",")",",","and","divergence","for","both","the","`","kernel","`","and","`","bias","`","distributions","."]
code: def build(self, input_shape):
      input_shape = tf.TensorShape(input_shape)
      if self.data_format == "channels_first":
          channel_axis = 1
      else:
          channel_axis = -1
      input_dim = tf.compat.dimension_value(input_shape[channel_axis])
      if input_dim is None:
          raise ValueError(
              "The channel dimension of the inputs "
              "should be defined. Found `None`."
          )
      kernel_shape = self.kernel_size + (input_dim, self.filters)
  
      # If self.dtype is None, build weights using the default dtype.
      dtype = tf.as_dtype(self.dtype or tf_keras.backend.floatx())
  
      # Must have a posterior kernel.
      self.kernel_posterior = self.kernel_posterior_fn(
          dtype,
          kernel_shape,
          "kernel_posterior",
          self.trainable,
          self.add_variable,
      )
  
      if self.kernel_prior_fn is None:
          self.kernel_prior = None
      else:
          self.kernel_prior = self.kernel_prior_fn(
              dtype,
              kernel_shape,
              "kernel_prior",
              self.trainable,
              self.add_variable,
          )
  
      if self.bias_posterior_fn is None:
          self.bias_posterior = None
      else:
          self.bias_posterior = self.bias_posterior_fn(
              dtype,
              (self.filters,),
              "bias_posterior",
              self.trainable,
              self.add_variable,
          )
  
      if self.bias_prior_fn is None:
          self.bias_prior = None
      else:
          self.bias_prior = self.bias_prior_fn(
              dtype,
              (self.filters,),
              "bias_prior",
              self.trainable,
              self.add_variable,
          )
  
      self.input_spec = tf_keras.layers.InputSpec(
          ndim=self.rank + 2, axes={channel_axis: input_dim}
      )
      self._convolution_op = nn_ops.Convolution(
          input_shape,
          filter_shape=tf.TensorShape(kernel_shape),
          dilation_rate=self.dilation_rate,
          strides=self.strides,
          padding=self.padding.upper(),
          data_format=convert_data_format(
              self.data_format, self.rank + 2
          ),
      )
  
      self.built = True
  
imports: import tensorflow.compat.v2
  from tensorflow_probability.python import random
  from tensorflow_probability.python.distributions import independent
  from tensorflow_probability.python.distributions import kullback_leibler
  from tensorflow_probability.python.distributions import normal
  from tensorflow_probability.python.internal import docstring_util
  from tensorflow_probability.python.internal import tf_keras
  from tensorflow_probability.python.layers import util
  from tensorflow_probability.python.util.seed_stream import SeedStream
  from tensorflow.python.ops import nn_ops
label_desc: Use image node_id 2 for calling the _ConvVariational obj's underlying member method code with example usage: obj.build(input_shape) without return types