code: def batch_norm(
      x: Union[tf.Tensor, tf.Variable],
      mean: Union[tf.Tensor, tf.Variable],
      variance: Union[tf.Tensor, tf.Variable],
      /,
      *,
      scale: Optional[Union[tf.Tensor, tf.Variable]] = None,
      offset: Optional[Union[tf.Tensor, tf.Variable]] = None,
      training: Optional[bool] = False,
      eps: Optional[float] = 1e-5,
      momentum: Optional[float] = 1e-1,
      data_format: Optional[str] = "NSC",
      out: Optional[
          Tuple[
              Union[tf.Tensor, tf.Variable],
              Union[tf.Tensor, tf.Variable],
              Union[tf.Tensor, tf.Variable],
          ]
      ] = None,
  ) -> Tuple[
      Union[tf.Tensor, tf.Variable],
      Union[tf.Tensor, tf.Variable],
      Union[tf.Tensor, tf.Variable],
  ]:
      xdims = len(x.shape)
      if data_format == "NCS":
          x = tf.transpose(x, perm=(0, *range(2, xdims), 1))
  
      runningmean = mean
      runningvariance = variance
      if training:
          n = (
              tf.size(x)
              if xdims == 1
              else tf.divide(tf.size(x), tf.shape(x)[-1])
          )
          n = tf.cast(n, x.dtype) if n.dtype != x.dtype else n
          dims = (0, *range(1, xdims - 1))
          mean = tf.math.reduce_mean(x, axis=dims)
          variance = tf.math.reduce_variance(x, axis=dims)
          runningmean = (1 - momentum) * runningmean + momentum * mean
          runningvariance = (
              1 - momentum
          ) * runningvariance + momentum * variance * n / (n - 1)
  
      inv = 1.0 / tf.math.sqrt(variance + eps)
      offset = 0 if offset is None else offset
      if scale is not None:
          inv = tf.math.multiply(inv, scale)
      xnormalized = tf.math.add(tf.math.multiply(x, inv), offset)
      xnormalized = tf.math.subtract(
          xnormalized, tf.math.multiply(mean, inv)
      )
      # the above approach is faster than tf.nn.batch_normalization
  
      if data_format == "NCS":
          xnormalized = tf.transpose(
              xnormalized, perm=(0, xdims - 1, *range(1, xdims - 1))
          )
  
      return xnormalized, runningmean, runningvariance
  
file_path: ivy/ivy/functional/backends/tensorflow/experimental/norms.py
imports: import tensorflow
  from typing import Literal, Union, Optional, Tuple
  from ivy.func_wrapper import with_supported_dtypes, with_unsupported_dtypes
  from .None import backend_version
  import math
label_desc: Use image node_id 4 for calling a global function with example usage: batch_norm() and returns: xnormalized,  runningmean,  runningvariance