了解pytorch中正态分布的log_prob



我目前正试图从具有连续动作空间的openAi健身房环境中解决Pendulum-v0。因此,我需要使用正态分布来对我的操作进行采样。我不明白的是使用log_prob时的维度:

import torch
from torch.distributions import Normal 
means = torch.tensor([[0.0538],
[0.0651]])
stds = torch.tensor([[0.7865],
[0.7792]])
dist = Normal(means, stds)
a = torch.tensor([1.2,3.4])
d = dist.log_prob(a)
print(d.size())

我期望一个大小为2的张量(每个动作一个log_prob(,但它输出的是大小为(2,2(的张量。

然而,当对离散环境使用分类分布时,log_prob具有预期的大小:

logits = torch.tensor([[-0.0657, -0.0949],
[-0.0586, -0.1007]])
dist = Categorical(logits = logits)
a = torch.tensor([1, 1])
print(dist.log_prob(a).size())

给我一个大小为(2(的张量。

为什么正态分布的log_prob大小不同?

如果查看torch.distributions.Normal的源代码并找到log_prob(value(函数的定义,可以看到计算的主要部分是:

return -((value - self.loc) ** 2) / (2 * var) - some other part

其中,value是一个包含要计算对数概率的值的变量(在您的情况下,a(,1self。loc为分布的平均值(在您情况下,表示,而var则为方差,即标准差的平方(在您中,2stds**2(。可以看出,这确实是正态分布的概率密度函数的对数,减去一些常数和标准差的对数,我上面没有写。

在第一个示例中,您将的意思是stds定义为列向量,而则定义为行向量

means = torch.tensor([[0.0538],
[0.0651]])
stds = torch.tensor([[0.7865],
[0.7792]])
a = torch.tensor([1.2,3.4])

但是,代码在Python中的value-self.loc中所做的从列向量中减去行向量会得到一个矩阵(try!(,因此,对于两个定义的分布中的每个分布和a的每个变量,您获得的结果都是log_prob值。

如果你想获得一个没有交叉项的log_prob,那么就一致地定义变量,即

means = torch.tensor([[0.0538],
[0.0651]])
stds = torch.tensor([[0.7865],
[0.7792]])
a = torch.tensor([[1.2],[3.4]])

means = torch.tensor([0.0538,
0.0651])
stds = torch.tensor([0.7865,
0.7792])
a = torch.tensor([1.2,3.4])

这就是你在第二个例子中的做法,这就是你获得预期结果的原因。

最新更新