Performance Tensorflow:有效的多项式采样(Theano x50更快?)

Performance Tensorflow:有效的多项式采样(Theano x50更快?),performance,tensorflow,sampling,multinomial,Performance,Tensorflow,Sampling,Multinomial,我希望能够有效地从多项式分布中取样,显然我的TensorFlow代码非常。。。非常慢 我的想法是: 向量:计数=[40,50,26,…,19]例如 概率矩阵:probs=[[0.1,…,0.5],…[0.3,…,0.02]这样np.sum(probs,axis=1)=1 假设len(counts)=N和len(probs)=(N,50)。我想做的是(在我们的示例中): 从矩阵的第一个概率向量中取样40次probs 从矩阵的第二个概率向量中取样50次probs 从矩阵的第n个概率向量中取样

我希望能够有效地从多项式分布中取样,显然我的TensorFlow代码非常。。。非常慢

我的想法是:

  • 向量:
    计数=[40,50,26,…,19]
    例如
  • 概率矩阵:
    probs=[[0.1,…,0.5],…[0.3,…,0.02]
    这样
    np.sum(probs,axis=1)=1
假设
len(counts)=N
len(probs)=(N,50)
。我想做的是(在我们的示例中):

  • 从矩阵的第一个概率向量中取样40次
    probs
  • 从矩阵的第二个概率向量中取样50次
    probs
  • 从矩阵的第n个概率向量中取样19次
    probs
这样我的最终矩阵看起来像(例如):
A=[[22,…13],…,[12,…,3]]
其中
np.sum(A,轴=1)=计数
(即每行上的总和=相应行中的
计数
向量)

以下是我的TensorFlow代码示例:

将numpy导入为np
导入tensorflow作为tf
将tensorflow.contrib.distributions导入为ds
导入时间
nb_分布=100#概率分布数
计数=np.random.randint(2000,3500,大小=nb#u分布)#定义计数数(大小为100的向量,2000,3500中的整数)
#print(u[:40])#应与tf.Session()中print(np.sum(res,1)[:40])的输出相同
#probsn是一个概率矩阵:
#probsn的每一行包含一个大小为30的向量,其总和为1
概率n=np.随机.均匀(大小=(nb_分布,30))
probsn/=np.sum(probsn,轴=1)[:,无]
counts=tf.Variable(counts,dtype=tf.float32)
probs=tf.Variable(tf.convert_to_tensor(probsn.astype(np.float32)))
#多项式样本
距离=ds.多项式(总计数=计数,概率=概率)
out=距离样本()
开始=时间。时间()
使用tf.Session()作为sess:
sess.run(tf.global\u variables\u initializer())
res=sess.运行(耗尽)
#打印(np.sum(res,1)[:40])
打印(time.time()-start)
经过的时间:0.12秒

我在中的等效代码编号

将numpy导入为np
进口茶
从编号张量导入\u共享
nb_分布=100#概率分布数
计数=np.random.randint(2000、3500,大小=nb_分布)
#print(u[:40])#应与print的输出相同(np.sum(v_sample(),1)[:40])
计数=_共享(计数)#定义计数的数量(大小为100的向量,在2000和3500中为int)
#probsn是一个概率矩阵:
#probsn的每一行包含一个和为1的向量
概率n=np.随机.均匀(大小=(nb_分布,30))
probsn/=np.sum(probsn,轴=1)[:,无]
probsn=_共享(probsn)
从ano.tensor.shared\u randomstreams导入randomstreams
np\u rng=np.random.RandomState(12345)
theano_rng=随机流(np_rng.randint(2**30))
v_sample=theano.函数(输入=[],输出=theano_rng.多项式(n=计数,pvals=probsn))
start\u t=time.time()
out=np.sum(v_sample(),1)[:40]
#打印(输出)
打印(time.time()-start\t)
经过的时间:0.0025秒


西亚诺快了100倍。。。我的TensorFlow代码有问题吗?如何在TensorFlow中有效地从多项式分布采样?

问题是TensorFlow多项式
sample()
方法实际上使用方法调用
\u sample\n()
。定义了此方法。正如我们在多项式采样代码中所看到的,该代码为每行生成一个1_hot的矩阵,然后通过对行求和将矩阵减少为向量:

math\u ops.reduce\u sum(数组\u ops.one\u hot(x,深度=k),轴=-2)

它的效率很低,因为它使用额外的内存。为了避免这种情况,我使用了
tf.scatter\u nd
功能。下面是一个完全可运行的示例:

将tensorflow导入为tf
将numpy作为np导入
将tensorflow.contrib.distributions导入为ds
导入时间
tf.reset_default_graph()
nb_分布=100#概率数分布
u=np.random.randint(2000,3500,size=nb#u分布)#定义计数数(大小为100的向量,2000,3500中的int)
#probsn是一个概率矩阵:
#probsn的每一行包含一个大小为30的向量,其总和为1
概率n=np.随机.均匀(大小=(nb_分布,30))
probsn/=np.sum(probsn,轴=1)[:,无]
counts=tf.Variable(u,dtype=tf.float32)
probs=tf.Variable(tf.convert_to_tensor(probsn.astype(np.float32)))
#多项式样本
距离=ds.多项式(总计数=计数,概率=概率)
out=距离样本()
使用tf.Session()作为sess:
sess.run(tf.global\u variables\u initializer())
res=sess.run(out)#如果删除这一行,代码会变慢。。。
开始=时间。时间()
res=sess.运行(耗尽)
打印(time.time()-start)
打印(np.all(u==np.sum(res,axis=1)))
这段代码花了0.05秒来计算

def V多项抽样(计数、PVAL、种子=无):
k=tf.形状(pvals)[1]
logits=tf.expand_dims(tf.log(pvals),1)
def样本_单个(参数):
logits,n\u draw=args[0],args[1]
x=tf.多项式(logits,n,draw,seed)
指数=tf.cast(tf.reformate(x,[-1,1]),tf.int32)
更新=tf.ones(n_draw_)#tf.shape(index)[0]
返回tf.scatter\n(索引、更新,[k])
x=tf.map\u fn(样本单,[logits,counts],dtype=tf.float32)
返回x
xx=V多项抽样(u,probsn)
#检查=tf.展开尺寸(计数,1)*问题
使用tf.Session()作为sess:
sess.run(tf.global\u variables\u initializer())
res=sess.run(xx)#如果删除这一行,代码会变慢。。。
start\u t=time.time()
res=sess.run(xx)
打印(time.time()-start\t)
#打印(np.总和(分辨率,轴=1))
打印(np.all(u==np.sum(res,axi