I want to get a 2-D torch.Tensor with size [a,b] filled with values from a uniform distribution (in range [r1,r2]) in PyTorch.

2

8 Answers

If U is a random variable uniformly distributed on [0, 1], then (r1 - r2) * U + r2 is uniformly distributed on [r1, r2].

Thus, you just need:

(r1 - r2) * torch.rand(a, b) + r2 

Alternatively, you can simply use:

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

To fully explain this formulation, let's look at some concrete numbers:

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 

We can break down the expression (r1 - r2) * torch.rand(a, b) + r2 as follows:

  1. torch.rand(a, b) produces an a x b (1x7) tensor with numbers uniformly distributed in the range [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) produces numbers distributed in the uniform range [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 produces numbers in the uniform range [5.0, 2.0)
print((r1 - r2) * x + r2) tensor([[3.2986, 2.0559, 2.5028, 4.9278, 4.3784, 3.1423, 3.5888]]) 

Now, let's break down the answer suggested by @Jonasson: (r2 - r1) * torch.rand(a, b) + r1

  1. Again, torch.rand(a, b) produces (1x7) numbers uniformly distributed in the range [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. (r2 - r1) * torch.rand(a, b) produces numbers uniformly distributed in the range [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 produces numbers uniformly distributed in the range [2.0, 5.0)
print((r2 - r1) * x + r1) tensor([[3.7014, 4.9441, 4.4972, 2.0722, 2.6216, 3.8577, 3.4112]]) 

In summary, (r1 - r2) * torch.rand(a, b) + r2 produces numbers in the range [r2, r1), while (r2 - r1) * torch.rand(a, b) + r1 produces numbers in the range [r1, r2).

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

Utilize the torch.distributions package to generate samples from different distributions.

For example to sample a 2d PyTorch tensor of size [a,b] from a uniform distribution of range(low, high) try the following sample code

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]) 

To get a uniform random distribution, you can use

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]) 

This will give the output, tensor of size [2, 3].

This answer uses NumPy to first produce a random matrix and then converts the matrix to a PyTorch tensor. I find the NumPy API to be easier to understand.

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

Please Can you try something like:

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

PyTorch has a number of distributions built in. You can build a tensor of the desired shape with elements drawn from a uniform distribution like so:

from torch.distributions.uniform import Uniform shape = 3,4 r1, r2 = 0,1 x = Uniform(r1, r2).sample(shape) 
0

See this for all distributions:

This is the way I found works:

# 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) 

but I have to admit I don't know what the point of generating sampler is and why not just call it directly as I do in the one liner (last line of code).

Comments:

  • sampler are good for it's so you can transform/compose/cache/etc distributions. see , and the top of the docs of and
  • you can feed in tensors to uniform to let it know the high dimensional interval (hypercube) to generate the uniform samples (that's why it receives tensors as input rather than simply numbers)

Reference:

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy