def moments(x, axes, shift=None, name=None, keep_dims=False):
    'Calculate the mean and variance of `x`.\n\n  The mean and variance are calculated by aggregating the contents of `x`\n  across `axes`.  If `x` is 1-D and `axes = [0]` this is just the mean\n  and variance of a vector.\n\n  When using these moments for batch normalization (see\n  `tf.nn.batch_normalization`):\n    * for so-called "global normalization", used with convolutional filters with\n      shape `[batch, height, width, depth]`, pass `axes=[0, 1, 2]`.\n    * for simple batch normalization pass `axes=[0]` (batch only).\n\n  Args:\n    x: A `Tensor`.\n    axes: array of ints.  Axes along which to compute mean and\n      variance.\n    shift: A `Tensor` containing the value by which to shift the data for\n      numerical stability, or `None` if no shift is to be performed. A shift\n      close to the true mean provides the most numerically stable results.\n    keep_dims: produce moments with the same dimensionality as the input.\n    name: Name used to scope the operations that compute the moments.\n\n  Returns:\n    Two `Tensor` objects: `mean` and `variance`.\n  '
    with ops.op_scope([x, axes, shift], name, 'moments'):
        y = (math_ops.cast(x, dtypes.float32) if (x.dtype == dtypes.float16) else x)
        (counts, m_ss, v_ss, shift) = sufficient_statistics(y, axes, shift=shift, keep_dims=keep_dims, name=name)
        with ops.control_dependencies([counts, m_ss, v_ss]):
            (mean, variance) = normalize_moments(counts, m_ss, v_ss, shift, name=name)
            if (x.dtype == dtypes.float16):
                return (math_ops.cast(mean, dtypes.float16), math_ops.cast(variance, dtypes.float16))
            else:
                return (mean, variance)
Calculate the mean and variance of `x`.

The mean and variance are calculated by aggregating the contents of `x`
across `axes`.  If `x` is 1-D and `axes = [0]` this is just the mean
and variance of a vector.

When using these moments for batch normalization (see
`tf.nn.batch_normalization`):
  * for so-called "global normalization", used with convolutional filters with
    shape `[batch, height, width, depth]`, pass `axes=[0, 1, 2]`.
  * for simple batch normalization pass `axes=[0]` (batch only).

Args:
  x: A `Tensor`.
  axes: array of ints.  Axes along which to compute mean and
    variance.
  shift: A `Tensor` containing the value by which to shift the data for
    numerical stability, or `None` if no shift is to be performed. A shift
    close to the true mean provides the most numerically stable results.
  keep_dims: produce moments with the same dimensionality as the input.
  name: Name used to scope the operations that compute the moments.

Returns:
  Two `Tensor` objects: `mean` and `variance`.
def moments(x, axes, shift=None, name=None, keep_dims=False):
    'Calculate the mean and variance of `x`.\n\n  The mean and variance are calculated by aggregating the contents of `x`\n  across `axes`.  If `x` is 1-D and `axes = [0]` this is just the mean\n  and variance of a vector.\n\n  When using these moments for batch normalization (see\n  `tf.nn.batch_normalization`):\n    * for so-called "global normalization", used with convolutional filters with\n      shape `[batch, height, width, depth]`, pass `axes=[0, 1, 2]`.\n    * for simple batch normalization pass `axes=[0]` (batch only).\n\n  Args:\n    x: A `Tensor`.\n    axes: array of ints.  Axes along which to compute mean and\n      variance.\n    shift: A `Tensor` containing the value by which to shift the data for\n      numerical stability, or `None` if no shift is to be performed. A shift\n      close to the true mean provides the most numerically stable results.\n    keep_dims: produce moments with the same dimensionality as the input.\n    name: Name used to scope the operations that compute the moments.\n\n  Returns:\n    Two `Tensor` objects: `mean` and `variance`.\n  '
    with ops.op_scope([x, axes, shift], name, 'moments'):
        y = (math_ops.cast(x, dtypes.float32) if (x.dtype == dtypes.float16) else x)
        (counts, m_ss, v_ss, shift) = sufficient_statistics(y, axes, shift=shift, keep_dims=keep_dims, name=name)
        with ops.control_dependencies([counts, m_ss, v_ss]):
            (mean, variance) = normalize_moments(counts, m_ss, v_ss, shift, name=name)
            if (x.dtype == dtypes.float16):
                return (math_ops.cast(mean, dtypes.float16), math_ops.cast(variance, dtypes.float16))
            else:
                return (mean, variance)