如何在PyTorch中获取范围[r1,r2]内的均匀分布?

56

我想在PyTorch中获得一个大小为[a,b]的二维torch.Tensor,其中填充了来自均匀分布(范围在[r1,r2]内)的值。


1
我不知道是不是只有我觉得,但我认为torch.rand的命名非常糟糕。如果没有查看文档(顺便说一下,在浏览器上加载文档需要很长时间),我就不知道它是高斯分布还是均匀分布。 - Charlie Parker
3
更正之前的评论。请使用以下代码:r2 = torch.torch.distributions.Uniform(low=lb, high=ub).sample((num_samples,Din)) - Charlie Parker
9个回答

90
如果U是在[0, 1]上均匀分布的随机变量,那么(r1 - r2) * U + r2就是在[r1, r2]上均匀分布的随机变量。

因此,您只需要:
(r1 - r2) * torch.rand(a, b) + r2

或者,您可以简单地使用:

torch.FloatTensor(a, b).uniform_(r1, r2)

为了充分解释这个公式,让我们看一些具体的数字:
r1 = 2 # Create uniform random numbers in half-open interval [2.0, 5.0)
r2 = 5

a = 1  # Create tensor shape 1 x 7
b = 7

我们可以将表达式(r1 - r2) * torch.rand(a, b) + r2分解如下:
  1. torch.rand(a, b)会生成一个大小为a x b(1x7)的张量,其中的数字在区间[0.0, 1.0)上均匀分布。
x = torch.rand(a, b)
print(x)
# tensor([[0.5671, 0.9814, 0.8324, 0.0241, 0.2072, 0.6192, 0.4704]])
  1. (r1 - r2) * torch.rand(a, b) 产生均匀分布在区间 [0.0, -3.0) 内的数字
print((r1 - r2) * x)
tensor([[-1.7014, -2.9441, -2.4972, -0.0722, -0.6216, -1.8577, -1.4112]])
  1. (r1 - r2) * torch.rand(a, b) + r2 生成在区间 [5.0, 2.0) 上均匀分布的随机数。
print((r1 - r2) * x + r2)
tensor([[3.2986, 2.0559, 2.5028, 4.9278, 4.3784, 3.1423, 3.5888]])

现在,让我们分解@Jonasson建议的答案:(r2 - r1) * torch.rand(a, b) + r1
  1. torch.rand(a, b)再次生成一个范围在[0.0, 1.0)之间的(1x7)数字序列。
x = torch.rand(a, b)
print(x)
# tensor([[0.5671, 0.9814, 0.8324, 0.0241, 0.2072, 0.6192, 0.4704]])
  1. (r2 - r1) * torch.rand(a, b) 产生的数字在区间 [0.0, 3.0) 均匀分布。
print((r2 - r1) * x)
# tensor([[1.7014, 2.9441, 2.4972, 0.0722, 0.6216, 1.8577, 1.4112]])
  1. (r2 - r1) * torch.rand(a, b) + r1 生成在区间 [2.0, 5.0) 均匀分布的随机数。
print((r2 - r1) * x + r1)
tensor([[3.7014, 4.9441, 4.4972, 2.0722, 2.6216, 3.8577, 3.4112]])

简而言之(r1 - r2) * torch.rand(a, b) + r2 生成的数字范围为[r2, r1),而(r2 - r1) * torch.rand(a, b) + r1 生成的数字范围为[r1, r2)。


9
是不是应该反过来呢?即 (r2-r1)*torch.rand(a,b) + r1。 - Jonasson
1
这不是一样的吗? - BiBi
1
@stackoverflowuser2010 任何连续分布中的单个值都有零概率,因此在闭区间、开区间或半开区间上定义的概率密度函数是等价的。参考链接 - iacob
2
@CharlieParker 这里有: torch.distributions.uniform.Uniform() - iacob
@iacob:看API,不要看数学。 - stackoverflowuser2010
显示剩余4条评论

33
torch.FloatTensor(a, b).uniform_(r1, r2)

1
虽然被接受的答案更详细地介绍了不同的方法及其工作原理,但这个答案是最简单的。 - Joseph Summerhays
1
我仍然不明白为什么像Numpy一样,没有类似于torch.uniform的东西。 - Charlie Parker
2
@CharlieParker 这里有: torch.distributions.uniform.Uniform() - iacob

9

使用torch.distributions包从不同的分布中生成样本。

例如,要从范围为range(low, high)的均匀分布中采样大小为[a,b]的2d PyTorch张量,请尝试以下示例代码:

import torch
a,b = 2,3   #dimension of the pytorch tensor to be generated
low,high = 0,1 #range of uniform distribution

x = torch.distributions.uniform.Uniform(low,high).sample([a,b]) 

4

请尝试类似于以下内容:

import torch as pt
pt.empty(2,3).uniform_(5,10).type(pt.FloatTensor)

3

PyTorch内置了许多分布函数。您可以使用以下代码从均匀分布中抽取元素,创建一个所需shape的张量:

from torch.distributions.uniform import Uniform

shape = 3,4
r1, r2 = 0,1

x = Uniform(r1, r2).sample(shape) 

2
为了获得均匀随机分布,您可以使用:
torch.distributions.uniform.Uniform()

example,

import torch
from torch.distributions import uniform

distribution = uniform.Uniform(torch.Tensor([0.0]),torch.Tensor([5.0]))
distribution.sample(torch.Size([2,3])

这将会输出一个大小为 [2, 3] 的张量。

2

这个答案使用NumPy先生成一个随机矩阵,然后将该矩阵转换为PyTorch张量。我发现NumPy API更容易理解。

import numpy as np

torch.from_numpy(np.random.uniform(low=r1, high=r2, size=(a, b)))

0

查看所有分布,请参见:https://pytorch.org/docs/stable/distributions.html#torch.distributions.uniform.Uniform

这是我发现可行的方法:

# generating uniform variables

import numpy as np

num_samples = 3
Din = 1
lb, ub = -1, 1

xn = np.random.uniform(low=lb, high=ub, size=(num_samples,Din))
print(xn)

import torch

sampler = torch.distributions.Uniform(low=lb, high=ub)
r = sampler.sample((num_samples,Din))

print(r)

r2 = torch.torch.distributions.Uniform(low=lb, high=ub).sample((num_samples,Din))

print(r2)

# process input
f = nn.Sequential(OrderedDict([
    ('f1', nn.Linear(Din,Dout)),
    ('out', nn.SELU())
]))
Y = f(r2)
print(Y)

但我必须承认,我不知道生成采样器的意义何在,为什么不能像我在单行代码中那样直接调用它。

评论:


参考资料:


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接