code: def bidirectional_rnn(
      incoming,
      rnncell_fw,
      rnncell_bw,
      return_seq=False,
      return_states=False,
      initial_state_fw=None,
      initial_state_bw=None,
      dynamic=False,
      scope=None,
      name="BiRNN",
  ):
      """Bidirectional RNN.
  
      Build a bidirectional recurrent neural network, it requires 2 RNN Cells
      to process sequence in forward and backward order. Any RNN Cell can be
      used i.e. SimpleRNN, LSTM, GRU... with its own parameters. But the two
      cells number of units must match.
  
      Input:
          3-D Tensor Layer [samples, timesteps, input dim].
  
      Output:
          if `return_seq`: 3-D Tensor [samples, timesteps, output dim].
          else: 2-D Tensor Layer [samples, output dim].
  
      Arguments:
          incoming: `Tensor`. The incoming Tensor.
          rnncell_fw: `RNNCell`. The RNN Cell to use for foward computation.
          rnncell_bw: `RNNCell`. The RNN Cell to use for backward computation.
          return_seq: `bool`. If True, returns the full sequence instead of
              last sequence output only.
          return_states: `bool`. If True, returns a tuple with output and
              states: (output, states).
          initial_state_fw: `Tensor`. An initial state for the forward RNN.
              This must be a tensor of appropriate type and shape [batch_size
              x cell.state_size].
          initial_state_bw: `Tensor`. An initial state for the backward RNN.
              This must be a tensor of appropriate type and shape [batch_size
              x cell.state_size].
          dynamic: `bool`. If True, dynamic computation is performed. It will not
              compute RNN steps above the sequence length. Note that because TF
              requires to feed sequences of same length, 0 is used as a mask.
              So a sequence padded with 0 at the end must be provided. When
              computation is performed, it will stop when it meets a step with
              a value of 0.
          scope: `str`. Define this layer scope (optional). A scope can be
              used to share variables between layers. Note that scope will
              override name.
          name: `str`. A name for this layer (optional).
  
      """
      assert (
          rnncell_fw._num_units == rnncell_bw._num_units
      ), "RNN Cells number of units must match!"
  
      sequence_length = None
      if dynamic:
          sequence_length = retrieve_seq_length_op(
              incoming
              if isinstance(incoming, tf.Tensor)
              else tf.stack(incoming)
          )
  
      input_shape = utils.get_incoming_shape(incoming)
  
      with tf.variable_scope(
          scope, default_name=name, values=[incoming]
      ) as scope:
          name = scope.name
  
          # TODO: DropoutWrapper
  
          inference = incoming
          # If a tensor given, convert it to a per timestep list
          if type(inference) not in [list, np.array]:
              ndim = len(input_shape)
              assert ndim >= 3, "Input dim should be at least 3."
              axes = [1, 0] + list(range(2, ndim))
              inference = tf.transpose(inference, (axes))
              inference = tf.unstack(inference)
  
          outputs, states_fw, states_bw = _brnn(
              rnncell_fw,
              rnncell_bw,
              inference,
              initial_state_fw=initial_state_fw,
              initial_state_bw=initial_state_bw,
              sequence_length=sequence_length,
              dtype=tf.float32,
          )
  
          c = tf.GraphKeys.LAYER_VARIABLES + "/" + scope.name
          for v in [
              rnncell_fw.W,
              rnncell_fw.b,
              rnncell_bw.W,
              rnncell_bw.b,
          ]:
              if hasattr(v, "__len__"):
                  for var in v:
                      tf.add_to_collection(c, var)
              else:
                  tf.add_to_collection(c, v)
  
          # Track activations.
          tf.add_to_collection(tf.GraphKeys.ACTIVATIONS, outputs[-1])
  
      if dynamic:
          if return_seq:
              o = tf.stack(outputs, 1)
          else:
              outputs = tf.transpose(tf.stack(outputs), [1, 0, 2])
              o = advanced_indexing_op(outputs, sequence_length)
      else:
          o = tf.stack(outputs, 1) if return_seq else outputs[-1]
  
      sfw = states_fw
      sbw = states_bw
  
      # Track output tensor.
      tf.add_to_collection(tf.GraphKeys.LAYER_TENSOR + "/" + name, o)
  
      return (o, sfw, sbw) if return_states else o
  
imports: from __future__ import division, print_function, absolute_import
  import logging
  import numpy
  import tensorflow.compat.v1
  from tensorflow.python.ops import array_ops
  from tensorflow.python.util.nest import is_sequence
  from ..None import config
  from ..None import utils
  from ..None import activations
  from ..None import initializations
  from ..None import variables
  from .normalization import batch_normalization
label_desc: Use image node_id 5 for calling a global function with example usage: bidirectional_rnn(incoming, rnncell_fw, rnncell_bw, return_seq, return_states, initial_state_fw, initial_state_bw, dynamic, scope, name) and returns: unknown