def log_prob(self, value): """Log probability density/mass function. Args: value (Tensor): The input tensor. Returns: Tensor: log probability.The data type is same with value. """ value = self._check_values_dtype_in_probs(self.low, value) if _non_static_mode(): # ensure value in [low, high] lb_bool = self.low < value ub_bool = value < self.high lb = _C_ops.cast(lb_bool, 'in_dtype', lb_bool.dtype, 'out_dtype', value.dtype) ub = _C_ops.cast(ub_bool, 'in_dtype', ub_bool.dtype, 'out_dtype', value.dtype) return nn.log(lb * ub) - nn.log(self.high - self.low) name = self.name + '_log_prob' lb_bool = self.low < value ub_bool = value < self.high lb = tensor.cast(lb_bool, dtype=value.dtype) ub = tensor.cast(ub_bool, dtype=value.dtype) return elementwise_sub(nn.log(lb * ub), nn.log(self.high - self.low), name=name)
def entropy(self): r"""Shannon entropy in nats. The entropy is .. math:: entropy(\sigma) = 0.5 \\log (2 \pi e \sigma^2) In the above equation: * :math:`scale = \sigma`: is the std. Returns: Tensor: Shannon entropy of normal distribution.The data type is float32. """ name = self.name + '_entropy' batch_shape = list((self.loc + self.scale).shape) zero_tmp = tensor.fill_constant_batch_size_like( self.loc + self.scale, batch_shape, self.dtype, 0.) return elementwise_add(0.5 + zero_tmp, 0.5 * math.log(2 * math.pi) + nn.log( (self.scale + zero_tmp)), name=name)
def entropy(self): """Shannon entropy in nats. Returns: Tensor: Shannon entropy of Categorical distribution. The data type is float32. Examples: .. code-block:: python import paddle from paddle.distribution import Categorical paddle.seed(100) # on CPU device x = paddle.rand([6]) print(x) # [0.5535528 0.20714243 0.01162981 # 0.51577556 0.36369765 0.2609165 ] cat = Categorical(x) cat.entropy() # [1.77528] """ name = self.name + '_entropy' logits = self.logits - nn.reduce_max( self.logits, dim=-1, keep_dim=True) e_logits = ops.exp(logits) z = nn.reduce_sum(e_logits, dim=-1, keep_dim=True) prob = e_logits / z neg_entropy = nn.reduce_sum(prob * (logits - nn.log(z)), dim=-1, keep_dim=True) entropy = nn.scale(neg_entropy, scale=-1.0, name=name) return entropy
def softmax_with_cross_entropy(self, shard_logit, shard_label): shard_max = nn.reduce_max(shard_logit, dim=1, keep_dim=True) global_max = collective._c_allreduce(shard_max, reduce_type='max', use_calc_stream=True) shard_logit_new = nn.elementwise_sub(shard_logit, global_max) shard_exp = ops.exp(shard_logit_new) shard_demon = nn.reduce_sum(shard_exp, dim=1, keep_dim=True) global_demon = collective._c_allreduce(shard_demon, reduce_type='sum', use_calc_stream=True) global_log_demon = nn.log(global_demon) shard_log_prob = shard_logit_new - global_log_demon shard_prob = ops.exp(shard_log_prob) shard_one_hot = nn.one_hot(shard_label, depth=self.shard_dim, allow_out_of_range=True) target_log_prob = nn.reduce_min(shard_log_prob * shard_one_hot, dim=1, keep_dim=True) shard_loss = nn.scale(target_log_prob, scale=-1.0) global_loss = collective._c_reducescatter(shard_loss, nranks=self.nranks, use_calc_stream=True) return global_loss, shard_prob
def kl_divergence(self, other): """The KL-divergence between two Categorical distributions. Args: other (Categorical): instance of Categorical. The data type is float32. Returns: Tensor: kl-divergence between two Categorical distributions. Examples: .. code-block:: python import paddle from paddle.distribution import Categorical paddle.seed(100) # on CPU device x = paddle.rand([6]) print(x) # [0.5535528 0.20714243 0.01162981 # 0.51577556 0.36369765 0.2609165 ] paddle.seed(200) # on CPU device y = paddle.rand([6]) print(y) # [0.77663314 0.90824795 0.15685187 # 0.04279523 0.34468332 0.7955718 ] cat = Categorical(x) cat2 = Categorical(y) cat.kl_divergence(cat2) # [0.071952] """ name = self.name + '_kl_divergence' if not in_dygraph_mode(): check_type(other, 'other', Categorical, 'kl_divergence') logits = self.logits - nn.reduce_max( self.logits, dim=-1, keep_dim=True) other_logits = other.logits - nn.reduce_max( other.logits, dim=-1, keep_dim=True) e_logits = ops.exp(logits) other_e_logits = ops.exp(other_logits) z = nn.reduce_sum(e_logits, dim=-1, keep_dim=True) other_z = nn.reduce_sum(other_e_logits, dim=-1, keep_dim=True) prob = e_logits / z kl = nn.reduce_sum( prob * (logits - nn.log(z) - other_logits + nn.log(other_z)), dim=-1, keep_dim=True, name=name) return kl
def entropy(self): r"""Shannon entropy in nats. The entropy is .. math:: entropy(low, high) = \\log (high - low) Returns: Tensor: Shannon entropy of uniform distribution.The data type is float32. """ name = self.name + '_entropy' return nn.log(self.high - self.low, name=name)
def kl_divergence(self, other): r"""The KL-divergence between two normal distributions. The probability density function (pdf) is .. math:: KL\_divergence(\mu_0, \sigma_0; \mu_1, \sigma_1) = 0.5 (ratio^2 + (\\frac{diff}{\sigma_1})^2 - 1 - 2 \\ln {ratio}) .. math:: ratio = \\frac{\sigma_0}{\sigma_1} .. math:: diff = \mu_1 - \mu_0 In the above equation: * :math:`loc = \mu_0`: is the mean of current Normal distribution. * :math:`scale = \sigma_0`: is the std of current Normal distribution. * :math:`loc = \mu_1`: is the mean of other Normal distribution. * :math:`scale = \sigma_1`: is the std of other Normal distribution. * :math:`ratio`: is the ratio of scales. * :math:`diff`: is the difference between means. Args: other (Normal): instance of Normal. Returns: Tensor: kl-divergence between two normal distributions.The data type is float32. """ if not _non_static_mode(): check_type(other, 'other', Normal, 'kl_divergence') name = self.name + '_kl_divergence' var_ratio = self.scale / other.scale var_ratio = (var_ratio * var_ratio) t1 = (self.loc - other.loc) / other.scale t1 = (t1 * t1) return elementwise_add(0.5 * var_ratio, 0.5 * (t1 - 1. - nn.log(var_ratio)), name=name)
def log_prob(self, value): """Log probability density/mass function. Args: value (Tensor): The input tensor. Returns: Tensor: log probability.The data type is same with value. """ name = self.name + '_log_prob' value = self._check_values_dtype_in_probs(self.loc, value) var = self.scale * self.scale log_scale = nn.log(self.scale) return elementwise_sub(-1. * ((value - self.loc) * (value - self.loc)) / (2. * var), log_scale + math.log(math.sqrt(2. * math.pi)), name=name)
def log_prob(self, value): """Log probabilities of the given category. Refer to ``probs`` method. Args: value (Tensor): The input tensor represents the selected category index. Returns: Tensor: Log probability. Examples: .. code-block:: python import paddle from paddle.distribution import Categorical paddle.seed(100) # on CPU device x = paddle.rand([6]) print(x) # [0.5535528 0.20714243 0.01162981 # 0.51577556 0.36369765 0.2609165 ] cat = Categorical(x) value = paddle.to_tensor([2,1,3]) cat.log_prob(value) # [-5.10271 -2.22287 -1.31061] """ name = self.name + '_log_prob' return nn.log(self.probs(value), name=name)