docstr: Layer to handle batch norm training and inference
  
  Parameters
  ----------
  inputs: TensorFlow Tensor
      4d tensor of NHWC format
  batch_name: string
      Name for the batch norm layer
  init_weights: Dict of numpy arrays
      A mapping of layer names to init weights
  is_training: bool
      True if training and False if running validation; updates based on is_train from params
  epsilon: float
      Small, non-zero value added to variance to avoid divide-by-zero error
  decay: float
      Decay for the moving average
  
  
  Returns
  -------
  return: TensorFlow Tensor
      Result of batch norm layer
docstr_tok: ["Layer","to","handle","batch","norm","training","and","inference","Parameters","--","--","--","--","--","inputs",":","TensorFlow","Tensor","4d","tensor","of","NHWC","format","batch_name",":","string","Name","for","the","batch","norm","layer","init_weights",":","Dict","of","numpy","arrays","A","mapping","of","layer","names","to","init","weights","is_training",":","bool","True","if","training","and","False","if","running","validation",";","updates","based","on","is_train","from","params","epsilon",":","float","Small",",","non-zero","value","added","to","variance","to","avoid","divide-by-zero","error","decay",":","float","Decay","for","the","moving","average","Returns","--","--","--","-","return",":","TensorFlow","Tensor","Result","of","batch","norm","layer"]
code: def batch_norm_wrapper(
      self,
      inputs,
      batch_name,
      init_weights,
      is_training=True,
      epsilon=1e-05,
      decay=0.9,
  ):
      """
      Layer to handle batch norm training and inference
  
      Parameters
      ----------
      inputs: TensorFlow Tensor
          4d tensor of NHWC format
      batch_name: string
          Name for the batch norm layer
      init_weights: Dict of numpy arrays
          A mapping of layer names to init weights
      is_training: bool
          True if training and False if running validation; updates based on is_train from params
      epsilon: float
          Small, non-zero value added to variance to avoid divide-by-zero error
      decay: float
          Decay for the moving average
  
  
      Returns
      -------
      return: TensorFlow Tensor
          Result of batch norm layer
      """
      _tf = _lazy_import_tensorflow()
  
      dim_of_x = inputs.get_shape()[-1]
  
      shadow_mean = _tf.Variable(
          init_weights[batch_name + "running_mean"],
          name=batch_name + "running_mean",
          trainable=False,
      )
  
      shadow_var = _tf.Variable(
          init_weights[batch_name + "running_var"],
          name=batch_name + "running_var",
          trainable=False,
      )
      axes = list(range(len(inputs.get_shape()) - 1))
  
      # Calculate mean and variance for a batch
      batch_mean, batch_var = _tf.nn.moments(
          inputs, axes, name="moments"
      )
  
      def mean_var_update():
          with _tf.control_dependencies(
              [
                  _tf.assign(
                      shadow_mean,
                      _tf.multiply(shadow_mean, decay)
                      + _tf.multiply(batch_mean, 1.0 - decay),
                  ),
                  _tf.assign(
                      shadow_var,
                      _tf.multiply(shadow_var, decay)
                      + _tf.multiply(batch_var, 1.0 - decay),
                  ),
              ]
          ):
              return _tf.identity(batch_mean), _tf.identity(batch_var)
  
      mean, variance = _tf.cond(
          _tf.cast(is_training, _tf.bool),
          mean_var_update,
          lambda: (_tf.identity(shadow_mean), _tf.identity(shadow_var)),
      )
      beta = _tf.Variable(
          init_weights[batch_name + "beta"],
          name=batch_name + "beta",
          trainable=True,
      )  # Offset/Shift
      gamma = _tf.Variable(
          init_weights[batch_name + "gamma"],
          name=batch_name + "gamma",
          trainable=True,
      )  # Scale
  
      return _tf.nn.batch_normalization(
          inputs, mean, variance, beta, gamma, epsilon
      )
  
imports: from __future__ import print_function
  from __future__ import division
  from __future__ import absolute_import
  import numpy
  from .._tf_model import TensorFlowModel
  from turicreate._deps.minimal_package import _minimal_package_import_check
  import turicreate.toolkits._tf_utils
label_desc: Use image node_id 4 for calling the ODTensorFlowModel obj's underlying member method code with example usage: obj.batch_norm_wrapper(inputs, batch_name, init_weights, is_training, epsilon, decay) and returns: _tf, _tf,  _tf