code: def atrous_conv_2d(
      incoming,
      nb_filter,
      filter_size,
      rate=1,
      padding="same",
      activation="linear",
      bias=True,
      weights_init="uniform_scaling",
      bias_init="zeros",
      regularizer=None,
      weight_decay=0.001,
      trainable=True,
      restore=True,
      reuse=False,
      scope=None,
      name="AtrousConv2D",
  ):
      """Atrous Convolution 2D.
  
      (a.k.a. convolution with holes or dilated convolution).
  
      Computes a 2-D atrous convolution, also known as convolution with holes or
      dilated convolution, given 4-D value and filters tensors. If the rate
      parameter is equal to one, it performs regular 2-D convolution. If the rate
      parameter is greater than one, it performs convolution with holes, sampling
      the input values every rate pixels in the height and width dimensions. This
      is equivalent to convolving the input with a set of upsampled filters,
      produced by inserting rate - 1 zeros between two consecutive values of the
      filters along the height and width dimensions, hence the name atrous
      convolution or convolution with holes (the French word trous means holes
      in English).
  
      More specifically
      ```
      output[b, i, j, k] = sum_{di, dj, q} filters[di, dj, q, k] *
          value[b, i + rate * di, j + rate * dj, q]
      ```
  
      Atrous convolution allows us to explicitly control how densely to compute
      feature responses in fully convolutional networks. Used in conjunction
      with bilinear interpolation, it offers an alternative to conv2d_transpose
      in dense prediction tasks such as semantic image segmentation,
      optical flow computation, or depth estimation. It also allows us to
      effectively enlarge the field of view of filters without increasing the
      number of parameters or the amount of computation.
  
      Input:
          4-D Tensor [batch, height, width, in_channels].
  
      Output:
          4-D Tensor [batch, new height, new width, nb_filter].
  
      Arguments:
          incoming: `Tensor`. Incoming 4-D Tensor.
          nb_filter: `int`. The number of convolutional filters.
          filter_size: `int` or `list of int`. Size of filters.
          rate: `int`.  A positive int32. The stride with which we sample input
              values across the height and width dimensions. Equivalently, the
              rate by which we upsample the filter values by inserting zeros
              across the height and width dimensions. In the literature, the
              same parameter is sometimes called input `stride` or `dilation`.
          padding: `str` from `"same", "valid"`. Padding algo to use.
              Default: 'same'.
          activation: `str` (name) or `function` (returning a `Tensor`) or None.
              Activation applied to this layer (see tflearn.activations).
              Default: 'linear'.
          bias: `bool`. If True, a bias is used.
          weights_init: `str` (name) or `Tensor`. Weights initialization.
              (see tflearn.initializations) Default: 'truncated_normal'.
          bias_init: `str` (name) or `Tensor`. Bias initialization.
              (see tflearn.initializations) Default: 'zeros'.
          regularizer: `str` (name) or `Tensor`. Add a regularizer to this
              layer weights (see tflearn.regularizers). Default: None.
          weight_decay: `float`. Regularizer decay parameter. Default: 0.001.
          trainable: `bool`. If True, weights will be trainable.
          restore: `bool`. If True, this layer weights will be restored when
              loading a model.
          reuse: `bool`. If True and 'scope' is provided, this layer variables
              will be reused (shared).
          scope: `str`. Define this layer scope (optional). A scope can be
              used to share variables between layers. Note that scope will
              override name.
          name: A name for this layer (optional). Default: 'Conv2D'.
  
      Attributes:
          scope: `Scope`. This layer scope.
          W: `Variable`. Variable representing filter weights.
          b: `Variable`. Variable representing biases.
  
      """
      input_shape = utils.get_incoming_shape(incoming)
      assert (
          len(input_shape) == 4
      ), "Incoming Tensor shape must be 4-D, not %d-D" % len(
          input_shape
      )
      filter_size = utils.autoformat_filter_conv2d(
          filter_size, input_shape[-1], nb_filter
      )
      padding = utils.autoformat_padding(padding)
  
      with tf.variable_scope(
          scope, default_name=name, values=[incoming], reuse=reuse
      ) as scope:
          name = scope.name
  
          W_init = weights_init
          if isinstance(weights_init, str):
              W_init = initializations.get(weights_init)()
          elif type(W_init) in [tf.Tensor, np.ndarray, list]:
              filter_size = None
          W_regul = None
          if regularizer is not None:
              W_regul = lambda x: regularizers.get(regularizer)(
                  x, weight_decay
              )
          W = vs.variable(
              "W",
              shape=filter_size,
              regularizer=W_regul,
              initializer=W_init,
              trainable=trainable,
              restore=restore,
          )
  
          # Track per layer variables
          tf.add_to_collection(
              tf.GraphKeys.LAYER_VARIABLES + "/" + name, W
          )
  
          b = None
          if bias:
              b_shape = [nb_filter]
              if isinstance(bias_init, str):
                  bias_init = initializations.get(bias_init)()
              elif type(bias_init) in [tf.Tensor, np.ndarray, list]:
                  b_shape = None
              b = vs.variable(
                  "b",
                  shape=b_shape,
                  initializer=bias_init,
                  trainable=trainable,
                  restore=restore,
              )
              # Track per layer variables
              tf.add_to_collection(
                  tf.GraphKeys.LAYER_VARIABLES + "/" + name, b
              )
  
          inference = tf.nn.atrous_conv2d(incoming, W, rate, padding)
          if b is not None:
              inference = tf.nn.bias_add(inference, b)
  
          if activation:
              if isinstance(activation, str):
                  inference = activations.get(activation)(inference)
              elif hasattr(activation, "__call__"):
                  inference = activation(inference)
              else:
                  raise ValueError("Invalid Activation.")
  
          # Track activations.
          tf.add_to_collection(tf.GraphKeys.ACTIVATIONS, inference)
  
      # Add attributes to Tensor to easy access weights.
      inference.scope = scope
      inference.W = W
      inference.b = b
  
      # Track output tensor.
      tf.add_to_collection(
          tf.GraphKeys.LAYER_TENSOR + "/" + name, inference
      )
  
      return inference
  
imports: from __future__ import division, print_function, absolute_import
  import tensorflow.compat.v1
  import numpy
  from math import ceil
  import tflearn
  from ..None import variables
  from ..None import activations
  from ..None import initializations
  from ..None import regularizers
  from ..None import utils
  from ..layers.normalization import batch_normalization
label_desc: Use image node_id 3 for calling a global function with example usage: atrous_conv_2d(incoming, nb_filter, filter_size, rate, padding, activation, bias, weights_init, bias_init, regularizer, weight_decay, trainable, restore, reuse, scope, name) and returns: inference