# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # TODO: define statistical functions of a tensor __all__ = [ #'mean', #'reduce_mean', 'std', 'var' ] import numpy as np from ..fluid.layer_helper import LayerHelper from ..fluid.framework import in_dygraph_mode from ..fluid import layers from .search import where from ..fluid.data_feeder import convert_dtype, check_variable_and_dtype, check_type, check_dtype def var(input, axis=None, keepdim=False, unbiased=True, out=None, name=None): """ Computes the variance of the input Variable's elements along the specified axis. Args: input (Variable): The input Variable to be computed variance, with data type float32 and float64 supported. axis (list|int, optional): The axis along which the variance is computed. If `None`, compute the variance over all elements of :attr:`input` and return a Variable with a single element, otherwise it must be in the range :math:`[-rank(input), rank(input))`. If :math:`axis[i] < 0`, the axis to compute is :math:`rank(input) + axis[i]`. keepdim (bool, optional): Whether to reserve the reduced dimensions in the output Variable. The dimensions in :attr:`axis` will be squeezed and the result Variable will have :attr:`len(axis)` fewer dimensions than the :attr:`input` unless :attr:`keepdim` is true, default False. unbiased (bool, optional): Whether to compute variance via the unbiased estimator, in which the divisor used in the computation is :math:`N - 1`, where :math:`N` represents the number of elements along :attr:`axis`, otherwise the divisor is :math:`N`. Default True. out (Variable, optional): Alternate output Variable to store the result variance. Default None. name (str, optional): The name for this layer. Normally there is no need for user to set this property. For more information, please refer to :ref:`api_guide_Name`. Default None. Returns: Variable: The result variance with the same dtype as :attr:`input`. If :attr:`out = None`, returns a new Variable containing the variance, otherwise returns a reference to the output Variable. Examples: .. code-block:: python import numpy as np import paddle import paddle.fluid.dygraph as dg a = np.array([[1.0, 2.0], [3.0, 4.0]]).astype("float32") with dg.guard(): data = dg.to_variable(a) variance = paddle.var(data, axis=[1]) print(variance.numpy()) # [0.5 0.5] """ dtype = convert_dtype(input.dtype) if dtype not in ["float32", "float64"]: raise ValueError("Layer tensor.var() only supports floating-point " "dtypes, but received {}.".format(dtype)) rank = len(input.shape) axes = axis if axis != None and axis != [] else range(rank) axes = [e if e >= 0 else e + rank for e in axes] inp_shape = input.shape if in_dygraph_mode() else layers.shape(input) mean = layers.reduce_mean(input, dim=axis, keep_dim=True, name=name) tmp = layers.reduce_mean( (input - mean)**2, dim=axis, keep_dim=keepdim, name=name) if unbiased: n = 1 for i in axes: n *= inp_shape[i] if not in_dygraph_mode(): n = layers.cast(n, dtype) zero_const = layers.fill_constant(shape=[1], dtype=dtype, value=0.0) factor = where(n > 1.0, n / (n - 1.0), zero_const) else: factor = n / (n - 1.0) if n > 1.0 else 0.0 tmp *= factor if out: layers.assign(input=tmp, output=out) return out else: return tmp def std(input, axis=None, keepdim=False, unbiased=True, out=None, name=None): """ Computes the standard-deviation of the input Variable's elements along the specified axis. Args: input (Variable): The input Variable to be computed standard-deviation, with data type float32 and float64 supported. axis (list|int, optional): The axis along which the standard-deviation is computed. If `None`, compute the standard-deviation over all elements of :attr:`input` and return a Variable with a single element, otherwise it must be in the range :math:`[-rank(input), rank(input))`. If :math:`axis[i] < 0`, the axis to compute is :math:`rank(input) + axis[i]`. keepdim (bool, optional): Whether to reserve the reduced dimensions in the output Variable. The dimensions in :attr:`axis` will be squeezed and the result Variable will have :attr:`len(axis)` fewer dimensions than the :attr:`input` unless :attr:`keepdim` is true, default False. unbiased (bool, optional): Whether to compute standard-deviation via the unbiased estimator, in which the divisor used in the computation is :math:`N - 1`, where :math:`N` represents the number of elements along :attr:`axis`, otherwise the divisor is :math:`N`. Default True. out (Variable, optional): Alternate output Variable to store the result standard-deviation . Default None. name (str, optional): The name for this layer. Normally there is no need for user to set this property. For more information, please refer to :ref:`api_guide_Name`. Default None. Returns: Variable: The result standard-deviation with the same dtype as :attr:`input`. If :attr:`out = None`, returns a new Variable containing the standard-deviation , otherwise returns a reference to the output Variable. Examples: .. code-block:: python import paddle import paddle.fluid as fluid # x is a Tensor variable with following elements: # [[0.2, 0.3, 0.5, 0.9] # [0.1, 0.2, 0.6, 0.7]] # Each example is followed by the corresponding output tensor. x = fluid.data(name='x', shape=[2, 4], dtype='float32') paddle.std(x) # [0.28252685] paddle.std(x, axis=[0]) # [0.0707107, 0.07071075, 0.07071064, 0.1414217] paddle.std(x, axis=[-1]) # [0.30956957, 0.29439208] """ check_variable_and_dtype(input, 'input', ['float32', 'float64'], 'std') tmp = var(input, axis=axis, keepdim=keepdim, unbiased=unbiased, name=name) tmp = layers.sqrt(tmp) if out is not None: layers.assign(input=tmp, output=out) return out else: return tmp