20

在一些(例如机器学习)库中,我们可以找到log_prob函数。它有什么作用,它与仅服用常规药物有何不同log

例如,这段代码的目的是什么:

dist = Normal(mean, std)
sample = dist.sample()
logprob = dist.log_prob(sample)

随后,我们为什么要先取一个日志,然后对结果值求幂,而不是直接评估它:

prob = torch.exp(dist.log_prob(sample))
4

4 回答 4

10

正如您自己的答案所提到的,log_prob返回密度或概率的对数。在这里,我将解决您问题中的其余要点:

  • 那和 有什么不同log?发行版没有方法log。如果他们这样做了,最接近的可能解释确实会是类似的东西,log_prob但它不会是一个非常精确的名称,因为 if 会引发“什么的日志”这个问题?一个分布具有多个数值属性(例如,它的均值、方差等),而概率或密度只是其中之一,因此名称会模棱两可。

这同样不适用于该Tensor.log()方法(这可能是您的想法),因为Tensor它本身就是一个我们可以记录的数学量。

  • 为什么取一个概率的对数只是为了以后取幂呢?您以后可能不需要对其取幂。例如,如果您有概率p和的对数q,那么您可以直接计算log(p * q)log(p) + log(q),避免中间取幂。这在数值上更稳定(避免下溢),因为概率可能变得非常接近于零,而它们的对数则不会。一般来说,加法也比乘法更有效,而且它的导数更简单。在https://en.wikipedia.org/wiki/Log_probability上有一篇关于这些主题的好文章。
于 2020-08-07T19:58:37.843 回答
5

部分答案是log_prob返回在给定样本值处评估的概率密度/质量函数的对数。

于 2019-02-11T18:00:13.150 回答
4

log_prob取(某些动作的)概率的对数。例子:

action_logits = torch.rand(5)
action_probs = F.softmax(action_logits, dim=-1)
action_probs

回报:

张量([0.1457, 0.2831, 0.1569, 0.2221, 0.1922])

然后:

dist = Categorical(action_probs)
action = dist.sample()
print(dist.log_prob(action), torch.log(action_probs[action]))

回报:

张量(-1.8519) 张量(-1.8519)

于 2020-11-12T02:02:44.603 回答
1

我们可以通过一个简单的例子来理解这个log_prob函数做了什么。

a首先,通过使用有界的统一函数生成概率[0, 1]

import torch.distributions as D
import torch

a = torch.empty(1).uniform_(0, 1)
a  # OUTPUT: tensor([0.3291])

然后,基于这个概率和 python 类torch.distributions.Bernoulli,我们可以实例化一个伯努利分布b(它在每个伯努利实验中以1概率生成,a=0.3291 同时以概率生成),01-a=0.6709

b = D.Bernoulli(a)
b  # OUTPUT: Bernoulli()

在这里,我们可以进行一次伯努利实验来获取样本c(保持我们有0.3291概率得到10.6709概率得到0),

c = b.sample()
c  # OUTPUT: tensor([0.])

使用伯努利分布b和一个特定样本c,我们可以得到在特定分布(伯努利分布实验cb结果 )c

b.log_prob(c)
b  # OUTPUT: tensor([-0.3991])

由于我们已经知道每个样本的概率为0(对于一个实验,概率可以简单地视为该实验的概率密度/质量函数)0.6709,因此我们可以验证log_prob结果,

torch.log(torch.tensor(0.6709))  # OUTPUT: tensor(-0.3991)

因此,这意味着它b.log_prob(c)是在值 ( )处评估的概率密度/质量函数的对数c

希望对你有效。

于 2021-09-08T07:07:32.827 回答