在一些(例如机器学习)库中,我们可以找到log_prob
函数。它有什么作用,它与仅服用常规药物有何不同log
?
例如,这段代码的目的是什么:
dist = Normal(mean, std)
sample = dist.sample()
logprob = dist.log_prob(sample)
随后,我们为什么要先取一个日志,然后对结果值求幂,而不是直接评估它:
prob = torch.exp(dist.log_prob(sample))
在一些(例如机器学习)库中,我们可以找到log_prob
函数。它有什么作用,它与仅服用常规药物有何不同log
?
例如,这段代码的目的是什么:
dist = Normal(mean, std)
sample = dist.sample()
logprob = dist.log_prob(sample)
随后,我们为什么要先取一个日志,然后对结果值求幂,而不是直接评估它:
prob = torch.exp(dist.log_prob(sample))
正如您自己的答案所提到的,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上有一篇关于这些主题的好文章。部分答案是log_prob
返回在给定样本值处评估的概率密度/质量函数的对数。
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)
我们可以通过一个简单的例子来理解这个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
同时以概率生成),0
1-a=0.6709
b = D.Bernoulli(a)
b # OUTPUT: Bernoulli()
在这里,我们可以进行一次伯努利实验来获取样本c
(保持我们有0.3291
概率得到1
而0.6709
概率得到0
),
c = b.sample()
c # OUTPUT: tensor([0.])
使用伯努利分布b
和一个特定样本c
,我们可以得到在特定分布(伯努利分布)下实验c
b
结果( )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
希望对你有效。