Add a Batch Normalization layer. Batch Normalization operation is
        defined as:

        `y = gamma * (x - mean) / sqrt(variance + epsilon) + beta`
        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 i.e., 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

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`
        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 i.e., 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 = self.spec
        nn_spec = self.nn_spec

        # Add a new layer
        spec_layer = nn_spec.layers.add()
        spec_layer.name = name
        spec_layer.input.append(input_name)
        spec_layer.output.append(output_name)

        spec_layer_params = spec_layer.batchnorm

        # Set the parameters
        spec_layer_params.channels = channels
        spec_layer_params.gamma.floatValue.extend(map(float, gamma.flatten()))
        spec_layer_params.beta.floatValue.extend(map(float, 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(map(float, mean.flatten()))
            spec_layer_params.variance.floatValue.extend(map(float, variance.flatten()))