code: def testPerArmRewardsSparseObs(self):
      obs_spec = {
          "global": {"sport": tensor_spec.TensorSpec((), tf.string)},
          "per_arm": {
              "name": tensor_spec.TensorSpec((3,), tf.string),
              "fruit": tensor_spec.TensorSpec((3,), tf.string),
          },
      }
      columns_a = tf.feature_column.indicator_column(
          tf.feature_column.categorical_column_with_vocabulary_list(
              "name", ["bob", "george", "wanda"]
          )
      )
      columns_b = tf.feature_column.indicator_column(
          tf.feature_column.categorical_column_with_vocabulary_list(
              "fruit", ["banana", "kiwi", "pear"]
          )
      )
      columns_c = tf.feature_column.indicator_column(
          tf.feature_column.categorical_column_with_vocabulary_list(
              "sport", ["bridge", "chess", "snooker"]
          )
      )
  
      objective_networks = []
      for _ in range(3):
          objective_networks.append(
              global_and_arm_feature_network.create_feed_forward_common_tower_network(
                  observation_spec=obs_spec,
                  global_layers=(4, 3, 2),
                  arm_layers=(6, 5, 4),
                  common_layers=(7, 6, 5),
                  global_preprocessing_combiner=(
                      tf.compat.v2.keras.layers.DenseFeatures(
                          [columns_c]
                      )
                  ),
                  arm_preprocessing_combiner=tf.compat.v2.keras.layers.DenseFeatures(
                      [columns_a, columns_b]
                  ),
              )
          )
      time_step_spec = ts.time_step_spec(obs_spec)
      action_spec = tensor_spec.BoundedTensorSpec((), tf.int32, 0, 2)
      policy = greedy_multi_objective_policy.GreedyMultiObjectiveNeuralPolicy(
          time_step_spec,
          action_spec,
          self._scalarizer,
          objective_networks,
          accepts_per_arm_features=True,
          emit_policy_info=(
              policy_utilities.InfoFields.PREDICTED_REWARDS_MEAN,
              policy_utilities.InfoFields.MULTIOBJECTIVE_SCALARIZED_PREDICTED_REWARDS_MEAN,
          ),
      )
      observations = {
          "global": {"sport": tf.constant(["snooker", "chess"])},
          "per_arm": {
              "name": tf.constant(
                  [
                      ["george", "george", "george"],
                      ["bob", "bob", "bob"],
                  ]
              ),
              "fruit": tf.constant(
                  [
                      ["banana", "banana", "banana"],
                      ["kiwi", "kiwi", "kiwi"],
                  ]
              ),
          },
      }
  
      time_step = ts.restart(observations, batch_size=2)
      action_step = policy.action(time_step)
      self.assertEqual(action_step.action.shape.as_list(), [2])
      self.assertEqual(action_step.action.dtype, tf.int32)
      # Initialize all variables
      self.evaluate(
          [
              tf.compat.v1.global_variables_initializer(),
              tf.compat.v1.tables_initializer(),
          ]
      )
      action, p_info, first_arm_name_feature = self.evaluate(
          [
              action_step.action,
              action_step.info,
              observations[bandit_spec_utils.PER_ARM_FEATURE_KEY][
                  "name"
              ][0],
          ]
      )
      self.assertAllEqual(action.shape, [2])
      self.assertAllEqual(
          getattr(
              p_info, policy_utilities.InfoFields.PREDICTED_REWARDS_MEAN
          ).shape,
          [2, 3, 3],
      )
      self.assertAllEqual(
          getattr(
              p_info,
              policy_utilities.InfoFields.MULTIOBJECTIVE_SCALARIZED_PREDICTED_REWARDS_MEAN,
          ).shape,
          [2, 3],
      )
      chosen_arm_features = getattr(
          p_info, policy_utilities.InfoFields.CHOSEN_ARM_FEATURES
      )
      self.assertAllEqual(chosen_arm_features["name"].shape, [2])
      self.assertAllEqual(chosen_arm_features["fruit"].shape, [2])
      first_action = action[0]
      self.assertAllEqual(
          chosen_arm_features["name"][0],
          first_arm_name_feature[first_action],
      )
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import collections
  from typing import Dict, List, Text, Tuple
  import numpy
  import tensorflow
  from tf_agents.bandits.multi_objective import multi_objective_scalarizer
  from tf_agents.bandits.networks import global_and_arm_feature_network
  from tf_agents.bandits.networks import heteroscedastic_q_network
  from tf_agents.bandits.policies import greedy_multi_objective_neural_policy
  from tf_agents.bandits.specs import utils
  from tf_agents.networks import network
  from tf_agents.policies import utils
  from tf_agents.specs import array_spec
  from tf_agents.specs import tensor_spec
  from tf_agents.trajectories import time_step
  from tf_agents.typing import types
  from tf_agents.utils import test_utils
label_desc: Use image node_id 21 for calling the GreedyRewardPredictionPolicyTest obj's underlying member method code with example usage: obj.testPerArmRewardsSparseObs() without return types