def add_batchnorm(
        self,
        name,
        channels,
        gamma,
        beta,
        mean=None,
        variance=None,
        input_name="data",
        output_name="out",
        compute_mean_var=False,
        instance_normalization=False,
        epsilon=1e-5,
    ):
        """
        Add a batch normalization layer. Batch normalization operation is
        defined as:

        ``y = gamma * (x - mean) / sqrt(variance + epsilon) + beta``

        Refer to the ``BatchnormLayerParams`` message in the specification
        (NeuralNetwork.proto) for more details.

        Parameters
        ----------
        name: str
            The name of this layer.
        channels: int
            Number of channels of the input blob.
        gamma: numpy.array
            Values of gamma. Must be numpy array of shape ``(channels, )``.
        beta: numpy.array
            Values of beta. Must be numpy array of shape ``(channels, )``.
        mean: numpy.array
            Means of the input blob on each channel. Must be numpy array of shape ``(channels, )``.
        variance:
            Variances of the input blob on each channel. Must be numpy array of shape ``(channels, )``.
        input_name: str
            The input blob name of this layer.
        output_name: str
            The output blob name of this layer.
        compute_mean_var: bool
            Set to ``True`` if mean and variance is to be computed from the input data.
        instance_normalization: bool
            Set compute_mean_var and this to ``True`` to perform
            instance normalization. That is, mean and variance are computed
            from the single input instance.
        epsilon: float
            Value of epsilon. Defaults to ``1e-5`` if not specified.

        See Also
        --------
        add_convolution, add_pooling, add_inner_product
        """
        spec_layer = self._add_generic_layer(name, [input_name], [output_name])
        spec_layer_params = spec_layer.batchnorm

        # Set the parameters
        spec_layer_params.channels = channels
        spec_layer_params.gamma.floatValue.extend(gamma.flatten())
        spec_layer_params.beta.floatValue.extend(beta.flatten())
        spec_layer_params.epsilon = epsilon
        spec_layer_params.computeMeanVar = compute_mean_var
        spec_layer_params.instanceNormalization = instance_normalization

        if compute_mean_var:
            if not instance_normalization:
                raise NotImplementedError(
                    "Batch-instance norm is currently not supported"
                )

        if not compute_mean_var:
            spec_layer_params.mean.floatValue.extend(mean.flatten())
            spec_layer_params.variance.floatValue.extend(variance.flatten())

        return spec_layer

        Add a batch normalization layer. Batch normalization operation is
        defined as:

        ``y = gamma * (x - mean) / sqrt(variance + epsilon) + beta``

        Refer to the ``BatchnormLayerParams`` message in the specification
        (NeuralNetwork.proto) for more details.

        Parameters
        ----------
        name: str
            The name of this layer.
        channels: int
            Number of channels of the input blob.
        gamma: numpy.array
            Values of gamma. Must be numpy array of shape ``(channels, )``.
        beta: numpy.array
            Values of beta. Must be numpy array of shape ``(channels, )``.
        mean: numpy.array
            Means of the input blob on each channel. Must be numpy array of shape ``(channels, )``.
        variance:
            Variances of the input blob on each channel. Must be numpy array of shape ``(channels, )``.
        input_name: str
            The input blob name of this layer.
        output_name: str
            The output blob name of this layer.
        compute_mean_var: bool
            Set to ``True`` if mean and variance is to be computed from the input data.
        instance_normalization: bool
            Set compute_mean_var and this to ``True`` to perform
            instance normalization. That is, mean and variance are computed
            from the single input instance.
        epsilon: float
            Value of epsilon. Defaults to ``1e-5`` if not specified.

        See Also
        --------
        add_convolution, add_pooling, add_inner_product
        
coremltools/models/neural_network/builder.py