Reputation: 3743
If I have n sized mean vector, n sized variance vector, then how do I do this?
z ∼ N (μ, σ)
import torch
x = torch.randn(3, 3)
mu = x.mean()
sigma = x.var()
What do I do to get z?
Upvotes: 3
Views: 3536
Reputation: 1321
Simply using torch.normal(mean=mean_vector, std=std_vector)
would work.
The method described above is correct, but another good way of doing it is to use torch.normal()
.
Below is an example of sampling from a normal distribution with mean and variance of tensors.
An example is shown below.
import torch
a = torch.tensor([1, 2, 3, 4 * 2, 2])
b = torch.tensor([5, 6, 7, 8 * 2, 2])
c = torch.tensor([5, 6, 7, 8 * 2, 2])
d = torch.tensor([9, 10, 11, 12 * 2, 2])
stacked_vectors = torch.stack([a, b, c, d]).float() # 2d tensor
mean_vector = stacked_vectors.mean(dim=0)
std_vector = stacked_vectors.std(dim=0)
# --------------------------------------------------------------
# Sampling
# --------------------------------------------------------------
sampled1 = torch.normal(mean=mean_vector, std=std_vector) # <--
sampled2 = torch.normal(mean=mean_vector, std=std_vector)
# --------------------------------------------------------------
print("mean_vector:", mean_vector)
print("std_vector:", std_vector)
print(sampled1)
print(sampled2)
mean_vector: tensor([ 5., 6., 7., 16., 2.])
std_vector: tensor([3.2660, 3.2660, 3.2660, 6.5320, 0.0000])
tensor([ 3.5221, -0.0818, 5.1410, 13.2573, 2.0000])
tensor([ 6.2393, 6.0634, 2.4302, 20.4233, 2.0000])
Upvotes: 1
Reputation: 114966
If you want to sample from a normal distribution with mean mu
and std sigma
then you can simply
z = torch.randn_like(mu) * sigma + mu
If you sample many such z
their mean and std will converge to sigma
and mu
:
mu = torch.arange(10.)
Out[]: tensor([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
sigma = 5. - 0.5 * torch.arange(10.)
Out[]: tensor([5.0000, 4.5000, 4.0000, 3.5000, 3.0000, 2.5000, 2.0000, 1.5000, 1.0000, 0.5000])
z = torch.randn(10, 1000000) * sigma[:, None] + mu[:, None]
z.mean(dim=1)
Out[]:
tensor([-5.4823e-03, 1.0011e+00, 1.9982e+00, 2.9985e+00, 4.0017e+00,
4.9972e+00, 6.0010e+00, 7.0004e+00, 7.9996e+00, 9.0006e+00])
z.std(dim=1)
Out[]:
tensor([4.9930, 4.4945, 4.0021, 3.5013, 3.0005, 2.4986, 1.9997, 1.4998, 0.9990,
0.5001])
As you can see when you sample 1,000,000 elements from the distribution the sample mean and std are close to the original mu
and sigma
you started with.
Upvotes: 2