code: def project_to_ball(tensors, radius, norm_type, epsilon=1e-6):
      """Projects batched tensors to a ball with the given radius in the given norm.
  
      For each example in the batch, its global norm (across all tensors) will be
      clipped to the given raidus. If its global norm is already smaller or equal to
      the given radius, its values won't be changed.
  
      Only L-infinity and L2 norms are currently supported.
  
      Args:
        tensors: A (nested) collection of batched tensors to project to the given
          ball. The first dimension of each tensor is the batch size and must all be
          equal.
        radius: the radius of the ball.
        norm_type: One of `nsl.configs.NormType`. Currently L1 norm is not
          supported.
        epsilon: Used to avoid division by 0.
  
      Returns:
        A collection of tensors in the same structure as the input, projected to the
        given ball.
      """
      if norm_type not in {
          configs.NormType.INFINITY,
          configs.NormType.L2,
      }:
          raise NotImplementedError(
              "Only L2 and L-infinity norms are implemented."
          )
      if norm_type == configs.NormType.INFINITY:
          clip = lambda tensor: tf.clip_by_value(
              tensor, -radius, radius
          )
          return tf.nest.map_structure(clip, tensors)
      if norm_type == configs.NormType.L2:
  
          def squared_global_norm(tensor):
              """Calculate squared sum of elements for a tensor."""
              target_axes = list(range(1, len(tensor.get_shape())))
              return tf.reduce_sum(
                  input_tensor=tf.square(tensor), axis=target_axes
              )
  
          tensor_list = tf.nest.flatten(tensors)
          norms = list(map(squared_global_norm, tensor_list))
          global_norm = tf.sqrt(
              tf.maximum(tf.add_n(norms), epsilon**2)
          )
          scale = tf.where(
              global_norm <= radius,
              tf.ones_like(global_norm),
              radius / global_norm,
          )
  
          def clip_to_norm(tensor):
              """For each sample, clip the tensor to the ball if necessary."""
              shaped_scale = _expand_to_rank(
                  scale, len(tensor.get_shape())
              )
              return shaped_scale * tensor
  
          return tf.nest.map_structure(clip_to_norm, tensors)
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import neural_structured_learning.configs
  import six
  import tensorflow
label_desc: Use image node_id 4 for calling a global function with example usage: project_to_ball(tensors, radius, norm_type, epsilon) and returns: tf, tf, tf, unknown