code: def BatchRenorm(
      x,
      rmax,
      dmax,
      *,
      momentum=0.9,
      epsilon=1e-5,
      center=True,
      scale=True,
      gamma_initializer=None,
      data_format="channels_last",
  ):
      """
      Batch Renormalization layer, as described in the paper:
      `Batch Renormalization: Towards Reducing Minibatch Dependence in Batch-Normalized Models
      <https://arxiv.org/abs/1702.03275>`_.
      This implementation is a wrapper around `tf.layers.batch_normalization`.
  
      Args:
          x (tf.Tensor): a NHWC or NC tensor.
          rmax, dmax (tf.Tensor): a scalar tensor, the maximum allowed corrections.
          decay (float): decay rate of moving average.
          epsilon (float): epsilon to avoid divide-by-zero.
          use_scale, use_bias (bool): whether to use the extra affine transformation or not.
  
      Returns:
          tf.Tensor: a tensor named ``output`` with the same shape of x.
  
      Variable Names:
  
      * ``beta``: the bias term.
      * ``gamma``: the scale term. Input will be transformed by ``x * gamma + beta``.
      * ``moving_mean, renorm_mean, renorm_mean_weight``: See TF documentation.
      * ``moving_variance, renorm_stddev, renorm_stddev_weight``: See TF documentation.
      """
  
      shape = x.get_shape().as_list()
      ndims = len(shape)
      assert ndims in [2, 4]
      if ndims == 2:
          data_format = "channels_first"
  
      ctx = get_current_tower_context()
      coll_bk = backup_collection([tf.GraphKeys.UPDATE_OPS])
      layer = tf.layers.BatchNormalization(
          axis=1 if data_format == "channels_first" else 3,
          momentum=momentum,
          epsilon=epsilon,
          center=center,
          scale=scale,
          renorm=True,
          renorm_clipping={
              "rmin": 1.0 / rmax,
              "rmax": rmax,
              "dmax": dmax,
          },
          renorm_momentum=0.99,
          gamma_initializer=gamma_initializer,
          fused=False,
          _reuse=tf.get_variable_scope().reuse,
      )
      xn = layer.apply(
          x, training=ctx.is_training, scope=tf.get_variable_scope()
      )
  
      if ctx.is_main_training_tower:
          for v in layer.non_trainable_variables:
              if isinstance(v, tf.Variable):
                  tf.add_to_collection(tf.GraphKeys.MODEL_VARIABLES, v)
      else:
          # only run UPDATE_OPS in the first tower
          restore_collection(coll_bk)
  
      if ndims == 2:
          xn = tf.squeeze(xn, [1, 2])
      ret = tf.identity(xn, name="output")
  
      # TODO not sure whether to add moving_mean/moving_var to VH now
      vh = ret.variables = VariableHolder()
      if scale:
          vh.gamma = layer.gamma
      if center:
          vh.beta = layer.beta
      return ret
  
file_path: tensorpack/tensorpack/models/batch_norm.py
imports: import re
  from ..compat import tfv1
  from tensorflow.python.training import moving_averages
  from ..tfutils.collection import backup_collection, restore_collection
  from ..tfutils.common import get_tf_version_tuple
  from ..tfutils.tower import get_current_tower_context
  from ..utils import logger
  from ..utils.argtools import get_data_format, log_once
  from .common import VariableHolder, layer_register
  from .tflayer import convert_to_tflayer_args, rename_get_variable
  from .utils import disable_autograph
label_desc: Use image node_id 5 for calling a global function with example usage: BatchRenorm(x, rmax, dmax) and returns: ret