code: def create_feed_forward_common_tower_network(
      observation_spec: types.NestedTensorSpec,
      global_layers: Sequence[int],
      arm_layers: Sequence[int],
      common_layers: Sequence[int],
      output_dim: int = 1,
      global_preprocessing_combiner: Optional[
          Callable[..., types.Tensor]
      ] = None,
      arm_preprocessing_combiner: Optional[
          Callable[..., types.Tensor]
      ] = None,
      activation_fn: Callable[
          [types.Tensor], types.Tensor
      ] = tf.keras.activations.relu,
      name: Optional[str] = None,
  ) -> types.Network:
      """Creates a common tower network with feedforward towers.
  
      The network produced by this function can be used either in
      `GreedyRewardPredictionPolicy`, or `NeuralLinUCBPolicy`.
      In the former case, the network must have `output_dim=1`, it is going to be an
      instance of `QNetwork`, and used in the policy as a reward prediction network.
      In the latter case, the network will be an encoding network with its output
      consumed by a reward layer or a LinUCB method. The specified `output_dim` will
      be the encoding dimension.
  
      Args:
        observation_spec: A nested tensor spec containing the specs for global as
          well as per-arm observations.
        global_layers: Iterable of ints. Specifies the layers of the global tower.
        arm_layers: Iterable of ints. Specifies the layers of the arm tower.
        common_layers: Iterable of ints. Specifies the layers of the common tower.
        output_dim: The output dimension of the network. If 1, the common tower will
          be a QNetwork. Otherwise, the common tower will be an encoding network
          with the specified output dimension.
        global_preprocessing_combiner: Preprocessing combiner for global features.
        arm_preprocessing_combiner: Preprocessing combiner for the arm features.
        activation_fn: A keras activation, specifying the activation function used
          in all layers. Defaults to relu.
        name: The network name to use. Shows up in Tensorboard losses.
  
      Returns:
        A network that takes observations adhering observation_spec and outputs
        reward estimates for every action.
      """
      obs_spec_no_num_actions = _remove_num_actions_dim_from_spec(
          observation_spec
      )
      global_network = encoding_network.EncodingNetwork(
          input_tensor_spec=obs_spec_no_num_actions[
              bandit_spec_utils.GLOBAL_FEATURE_KEY
          ],
          fc_layer_params=global_layers,
          activation_fn=activation_fn,
          preprocessing_combiner=global_preprocessing_combiner,
      )
  
      arm_network = encoding_network.EncodingNetwork(
          input_tensor_spec=obs_spec_no_num_actions[
              bandit_spec_utils.PER_ARM_FEATURE_KEY
          ],
          fc_layer_params=arm_layers,
          activation_fn=activation_fn,
          preprocessing_combiner=arm_preprocessing_combiner,
      )
  
      # When `global_layers` or `arm_layers` are empty, the corresponding encoding
      # networks simply pass the inputs forward, so in such cases we get the output
      # dimensions from the respective observation specs.
      global_network_out_dim = (
          global_layers[-1]
          if global_layers
          else obs_spec_no_num_actions[
              bandit_spec_utils.GLOBAL_FEATURE_KEY
          ].shape[-1]
      )
      arm_network_out_dim = (
          arm_layers[-1]
          if arm_layers
          else obs_spec_no_num_actions[
              bandit_spec_utils.PER_ARM_FEATURE_KEY
          ].shape[-1]
      )
      common_input_spec = tensor_spec.TensorSpec(
          shape=(global_network_out_dim + arm_network_out_dim,),
          dtype=tf.float32,
      )
      if output_dim == 1:
          common_network = q_network.QNetwork(
              input_tensor_spec=common_input_spec,
              action_spec=tensor_spec.BoundedTensorSpec(
                  shape=(), minimum=0, maximum=0, dtype=tf.int32
              ),
              fc_layer_params=common_layers,
              activation_fn=activation_fn,
          )
      else:
          common_network = encoding_network.EncodingNetwork(
              input_tensor_spec=common_input_spec,
              fc_layer_params=list(common_layers) + [output_dim],
              activation_fn=activation_fn,
          )
      return GlobalAndArmCommonTowerNetwork(
          obs_spec_no_num_actions,
          global_network,
          arm_network,
          common_network,
          name=name,
      )
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from typing import Callable, Optional, Sequence, Text
  import gin
  import numpy
  import tensorflow
  from tf_agents.bandits.specs import utils
  from tf_agents.networks import encoding_network
  from tf_agents.networks import network
  from tf_agents.networks import q_network
  from tf_agents.specs import tensor_spec
  from tf_agents.typing import types
label_desc: Use image node_id 2 for calling a global function with example usage: create_feed_forward_common_tower_network(observation_spec, global_layers, arm_layers, common_layers, output_dim, global_preprocessing_combiner, arm_preprocessing_combiner, activation_fn, name) and returns: GlobalAndArmCommonTowerNetwork