Python Pytorch:快速创建分数张量方法

Python Pytorch:快速创建分数张量方法,python,pytorch,Python,Pytorch,我是Pytorch的新手,正在寻找一个快速获取分数的功能。给定一组样本和一个分布,输出一个张量,由每个样本的相应分数组成。例如,考虑下面的代码: norm = torch.distributions.multivariate_normal.MultivariateNormal(torch.zeros(2),torch.eye(2)) samples = norm.sample((1000,)) samples.requires_grad_(True) 使用样本我想创建一个分数张量[1000,2

我是Pytorch的新手,正在寻找一个快速获取分数的功能。给定一组样本和一个分布,输出一个张量,由每个样本的相应分数组成。例如,考虑下面的代码:

norm = torch.distributions.multivariate_normal.MultivariateNormal(torch.zeros(2),torch.eye(2))
samples = norm.sample((1000,))
samples.requires_grad_(True)
使用
样本
我想创建一个
分数
张量
[1000,2]
,其中第I个分量
分数[I]
对数p(样本[I])
的梯度,其中
p
是给定分布的密度。我提出的方法如下:

def get_score(samples,distribution):
    log_probs = distribution.log_prob(samples)
    for i in range(log_probs.size()[0]):
        log_probs[i].backward(retain_graph = True)
由此产生的
得分
张量即为
样本。梯度
。问题是,对于较大的样本,我的方法非常慢(例如,对于大小
[50000,2]
的样本,我的CPU大约需要25-30秒)。这是最快的速度吗

我能想到的唯一替代方法是为我将要使用的每个发行版硬编码score函数,这似乎不是一个好的解决方案


通过实验,对于50000个样本,以下速度大约快50%:

for i in range(50000):
    sample = norm.sample((1,))
    sample.requires_grad_(True)
    log_prob = norm.log_prob(a)
    log_prob.backward()

这表明应该有更好的方法

我假设log_probs存储为pytorch张量。 您可以利用微分的线性一次计算所有样本的导数:
log\u probs.sum().backward(retain\u graph=True)

至少有了GPU加速,速度会快得多


如果log_probs不是张量而是标量列表(表示为秩为0的pytorch张量),则可以首先使用
log_probs=torch.stack(log_probs)

Nice!它被存储为pytorch张量,现在基本上是瞬时的,谢谢