code: def _make_gam_score_fn(
      context_hidden_units,
      example_hidden_units,
      activation_fn=tf.nn.relu,
      dropout=None,
      batch_norm=False,
      batch_norm_moment=0.999,
  ):
      """Returns a scoring fn that outputs a score per example."""
      activation_fn = activation_fn or tf.nn.relu
  
      def _scoring_fn(context_features, example_features, mode):
          """Defines the scoring fn for GAM.
  
          Args:
            context_features: (dict) A mapping from context feature names to dense 2-D
              Tensors of shape [batch_size, ...].
            example_features: (dict) A mapping from example feature names to dense 3-D
              Tensors of shape [batch_size, list_size, ...].
            mode: (`tf.estimator.ModeKeys`) TRAIN, EVAL, or PREDICT.
  
          Returns:
            A Tensor of shape [batch_size, 1] containing per-example scores.
          """
  
          # Input layer.
          example_feature_names = sorted(list(example_features.keys()))
          context_feature_names = sorted(list(context_features.keys()))
          with tf.compat.v1.name_scope("input_layer"):
              example_input = [
                  (
                      name,
                      tf.compat.v1.layers.flatten(
                          example_features[name]
                      ),
                  )
                  for name in sorted(list(example_feature_names))
              ]
              context_input = [
                  (
                      name,
                      tf.compat.v1.layers.flatten(
                          context_features[name]
                      ),
                  )
                  for name in sorted(list(context_feature_names))
              ]
  
          is_training = mode == tf_estimator.ModeKeys.TRAIN
  
          # Construct a tower for each example feature.  Each tower outputs a
          # scalar value as the sub-score.  All sub-scores are
          # [batch_size * list_size, 1]-shaped tensors and are stored in
          # `sub_logits_list` as a `feature_num`-sized list.
          with tf.compat.v1.name_scope("example_feature_towers"):
              sub_logits_list = []
              for name, input_layer in example_input:
                  with tf.compat.v1.name_scope("{}_tower".format(name)):
                      cur_layer = input_layer
                      if batch_norm:
                          cur_layer = (
                              tf.compat.v1.layers.batch_normalization(
                                  cur_layer,
                                  training=is_training,
                                  momentum=batch_norm_moment,
                              )
                          )
                      sub_logits = _feed_forward_network(
                          cur_layer,
                          map(int, example_hidden_units),
                          output_units=1,
                          activation_fn=activation_fn,
                          batch_norm=batch_norm,
                          batch_norm_moment=batch_norm_moment,
                          dropout=dropout,
                          is_training=is_training,
                      )
                      sub_logits = tf.identity(
                          sub_logits,
                          name="{}_{}".format(name, _SUBSCORE_POSTFIX),
                      )
                      sub_logits_list.append(sub_logits)
  
          # Construct a tower for each context feature.  Each tower outputs a
          # weighting vector of `feature_num`-dim where `feature_num` is the number
          # of example features.  All the vectors are
          # [batch_size * list_size, feature_num] tensors and are stored in
          # `sub_weights_list` with length of number of context feature.
          sub_weights_list = []
          if context_input:
              # Construct a tower per context features.
              with tf.compat.v1.name_scope("context_feature_towers"):
                  feature_num = len(sub_logits_list)
                  for name, input_layer in context_input:
                      with tf.compat.v1.name_scope(
                          "{}_tower".format(name)
                      ):
                          cur_layer = input_layer
                          if batch_norm:
                              cur_layer = tf.compat.v1.layers.batch_normalization(
                                  cur_layer,
                                  training=is_training,
                                  momentum=batch_norm_moment,
                              )
                          sub_weights = _feed_forward_network(
                              cur_layer,
                              map(int, context_hidden_units),
                              output_units=feature_num,
                              activation_fn=activation_fn,
                              batch_norm=batch_norm,
                              batch_norm_moment=batch_norm_moment,
                              dropout=dropout,
                              is_training=is_training,
                          )
                          sub_weights = tf.math.softmax(
                              sub_weights,
                              name="{}_{}".format(
                                  name, _SUBWEIGHT_POSTFIX
                              ),
                          )
                          sub_weights_list.append(sub_weights)
  
          # Construct an additive model from the outputs of all example feature towers
          # `sub_logits_list` weighted by outputs of all context feature towers
          # `sub_weights_list`.  If no context features are provided, the outputs will
          # simply be the sum of `sub_logits_list`.
          if sub_weights_list:
              sub_logits = tf.concat(sub_logits_list, axis=-1)
              feature_weights = tf.math.add_n(sub_weights_list)
              logits = tf.math.reduce_sum(
                  input_tensor=sub_logits * feature_weights, axis=-1
              )
          else:
              logits = tf.math.add_n(sub_logits_list)
  
          tf.compat.v1.summary.scalar(
              "logits_mean", tf.reduce_mean(input_tensor=logits)
          )
          return logits
  
      return _scoring_fn
  
imports: import tensorflow
  from tensorflow import estimator
  from tensorflow.python.util import function_utils
  from tensorflow_ranking.python import feature
  from tensorflow_ranking.python import head
  from tensorflow_ranking.python import losses
  from tensorflow_ranking.python import metrics
  from tensorflow_ranking.python import model
  from tensorflow_ranking.python import utils
label_desc: Use image node_id 7 for calling a global function with example usage: _make_gam_score_fn(context_hidden_units, example_hidden_units, activation_fn, dropout, batch_norm, batch_norm_moment) and returns: _scoring_fn, logits