以张量流中的间隔为条件对高斯进行采样
Sampling a Gaussian conditioned on an interval in tensorflow
假设 X 是高斯分布,N(0,1),我们想要对 X 进行采样,因为 x1 <= X <= x2
对于常量 x1,x2。如何在 tensorflow 中执行此操作?
这使用 special_math 函数 ndtr 和 ndtri,高斯分布和逆分布函数。由于目前无法找到这些功能
搜索 API,值得将其包含在此处。
import numpy as np
import tensorflow as tf
from tensorflow.python.ops.distributions import special_math as dsm
import matplotlib.pylab as pl
#assuming x1 < x2
def tf_conditioned_normal(x1,x2, dtype = tf.float32):
Fx1 = dsm.ndtr(x1)
Fx2 = dsm.ndtr(x2)
gamma = tf.random_uniform([1], dtype = dtype)
return dsm.ndtri(Fx1 + gamma*(Fx2 - Fx1))
if __name__ == '__main__':
graph = tf.Graph()
with graph.as_default():
t_x1ph = tf.placeholder(tf.float32,[])
t_x2ph = tf.placeholder(tf.float32,[])
t_cn = tf_conditioned_normal(t_x1ph,t_x2ph, dtype = tf.float32)
t_rn = tf.random_normal([1])
sess = tf.Session(graph = graph)
print 'Conditioned...'
x1 = -5.
x2 = -1.
N = 5000
res = np.zeros(N)
for i in xrange(N):
res[i] = sess.run(t_cn,
feed_dict = {
t_x1ph : x1 ,
t_x2ph : x2 ,
}
)
print 'Regular...'
Nn = 50000
nres = np.zeros(Nn)
for i in xrange(Nn):
nres[i] = sess.run(t_rn)
nres = nres[ (nres>=x1) & (nres <= x2) ]
pl.figure()
tmp = pl.hist(res, np.linspace(x1,x2,200), normed = True)
tmp = pl.hist(nres, np.linspace(x1,x2,200), normed = True, alpha = 0.7)
pl.show()
您可以简单地通过 -
import tensorflow as tf
x1 = tf.constant(0.)
x2 = tf.constant(1.)
N = tf.constant(10)
# Define a batch of one scalar valued Normals.
# The mean is 0. and standard deviation 1.
dist = tf.distributions.Normal(loc=[0.], scale=[1.])
# Get N samples, returning a N x 1 tensor.
sample = dist.sample([N])
# Put the filters and get boolean mask
filters = tf.logical_and(sample>x1, sample<x2)
# Put the filter in place
final_sample = tf.boolean_mask(sample, filters)
# Check output
sess = tf.InteractiveSession()
print(final_sample.eval())
输出
[0.11488124 0.38626793 0.3822059 0.3888869 ]
唯一的挑战是您必须不断采样和过滤,直到达到 N
。我将其作为微不足道的补充。
假设 X 是高斯分布,N(0,1),我们想要对 X 进行采样,因为 x1 <= X <= x2 对于常量 x1,x2。如何在 tensorflow 中执行此操作?
这使用 special_math 函数 ndtr 和 ndtri,高斯分布和逆分布函数。由于目前无法找到这些功能 搜索 API,值得将其包含在此处。
import numpy as np
import tensorflow as tf
from tensorflow.python.ops.distributions import special_math as dsm
import matplotlib.pylab as pl
#assuming x1 < x2
def tf_conditioned_normal(x1,x2, dtype = tf.float32):
Fx1 = dsm.ndtr(x1)
Fx2 = dsm.ndtr(x2)
gamma = tf.random_uniform([1], dtype = dtype)
return dsm.ndtri(Fx1 + gamma*(Fx2 - Fx1))
if __name__ == '__main__':
graph = tf.Graph()
with graph.as_default():
t_x1ph = tf.placeholder(tf.float32,[])
t_x2ph = tf.placeholder(tf.float32,[])
t_cn = tf_conditioned_normal(t_x1ph,t_x2ph, dtype = tf.float32)
t_rn = tf.random_normal([1])
sess = tf.Session(graph = graph)
print 'Conditioned...'
x1 = -5.
x2 = -1.
N = 5000
res = np.zeros(N)
for i in xrange(N):
res[i] = sess.run(t_cn,
feed_dict = {
t_x1ph : x1 ,
t_x2ph : x2 ,
}
)
print 'Regular...'
Nn = 50000
nres = np.zeros(Nn)
for i in xrange(Nn):
nres[i] = sess.run(t_rn)
nres = nres[ (nres>=x1) & (nres <= x2) ]
pl.figure()
tmp = pl.hist(res, np.linspace(x1,x2,200), normed = True)
tmp = pl.hist(nres, np.linspace(x1,x2,200), normed = True, alpha = 0.7)
pl.show()
您可以简单地通过 -
import tensorflow as tf
x1 = tf.constant(0.)
x2 = tf.constant(1.)
N = tf.constant(10)
# Define a batch of one scalar valued Normals.
# The mean is 0. and standard deviation 1.
dist = tf.distributions.Normal(loc=[0.], scale=[1.])
# Get N samples, returning a N x 1 tensor.
sample = dist.sample([N])
# Put the filters and get boolean mask
filters = tf.logical_and(sample>x1, sample<x2)
# Put the filter in place
final_sample = tf.boolean_mask(sample, filters)
# Check output
sess = tf.InteractiveSession()
print(final_sample.eval())
输出
[0.11488124 0.38626793 0.3822059 0.3888869 ]
唯一的挑战是您必须不断采样和过滤,直到达到 N
。我将其作为微不足道的补充。