code: def adaptive_clipping_fn(
      std_factor=2.0,
      decay=0.95,
      static_max_norm=None,
      global_step=None,
      report_summary=False,
      epsilon=1e-8,
      name=None,
  ):
      """Adapt the clipping value using statistics on the norms.
  
      Implement adaptive gradient as presented in section 3.2.1 of
      https://arxiv.org/abs/1412.1602.
  
      Keeps a moving average of the mean and std of the log(norm) of the gradient.
      If the norm exceeds `exp(mean + std_factor*std)` then all gradients will be
      rescaled such that the global norm becomes `exp(mean)`.
  
      Args:
        std_factor: Python scaler (or tensor). `max_norm = exp(mean +
          std_factor*std)`
        decay: The smoothing factor of the moving averages.
        static_max_norm: If provided, will threshold the norm to this value as an
          extra safety.
        global_step: Optional global_step. If provided, `decay = decay*n/(n+1)`.
          This provides a quicker adaptation of the mean for the first steps.
        report_summary: If `True`, will add histogram summaries of the `max_norm`.
        epsilon: Small value chosen to avoid zero variance.
        name: The name for this operation is used to scope operations and summaries.
  
      Returns:
        A function for applying gradient clipping.
      """
  
      def gradient_clipping(grads_and_vars):
          """Internal function for adaptive clipping."""
          grads, variables = zip(*grads_and_vars)
  
          norm = clip_ops.global_norm(grads)
  
          max_norm, log_mean = _adaptive_max_norm(
              norm, std_factor, decay, global_step, epsilon, name
          )
  
          # reports the max gradient norm for debugging
          if report_summary:
              summary.scalar(
                  "global_norm/adaptive_max_gradient_norm", max_norm
              )
  
          # factor will be 1. if norm is smaller than max_norm
          factor = array_ops.where(
              norm < max_norm,
              array_ops.ones_like(norm),
              math_ops.exp(log_mean) / norm,
          )
  
          if static_max_norm is not None:
              factor = math_ops.minimum(static_max_norm / norm, factor)
  
          # apply factor
          clipped_grads = []
          for grad in grads:
              if grad is None:
                  clipped_grads.append(None)
              elif isinstance(grad, ops.IndexedSlices):
                  clipped_grads.append(
                      ops.IndexedSlices(
                          grad.values * factor,
                          grad.indices,
                          grad.dense_shape,
                      )
                  )
              else:
                  clipped_grads.append(grad * factor)
  
          return list(zip(clipped_grads, variables))
  
      return gradient_clipping
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import six
  from ..None import contrib_framework
  from tensorflow.python.framework import dtypes
  from tensorflow.python.framework import ops
  from tensorflow.python.ops import array_ops
  from tensorflow.python.ops import clip_ops
  from tensorflow.python.ops import control_flow_ops
  from tensorflow.python.ops import init_ops
  from tensorflow.python.ops import math_ops
  from tensorflow.python.ops import random_ops
  from tensorflow.python.ops import variable_scope
  from tensorflow.python.ops import variables
  from tensorflow.python.summary import summary
  from tensorflow.python.training import moving_averages
  from tensorflow.python.training import optimizer
  from tensorflow.python.training import training
label_desc: Use image node_id 4 for calling a global function with example usage: adaptive_clipping_fn(std_factor, decay, static_max_norm, global_step, report_summary, epsilon, name) and returns: gradient_clipping, list