应用theano扫描函数时的ValueError

时间:2017-09-25 08:09:21

标签: python vectorization theano valueerror theano.scan

我尝试使用theano的scan函数多次评估多元正常CDF,但我得到了一个ValueError。

以下是我试图进行矢量化的原始函数示例:

from scipy.stats.mvn import mvnun # library that calculates MVN CDF

low  = [-1.96, 0   ] # lower bounds of integration
upp  = [0    , 1.96] # upper bounds of integration
mean = [0    , 0   ] # means of the jointly distributed random variables
covs = [[1,0.25],[0.25,1]] # covariance matrix

print(mvnun(low,upp,mean,cov))

这会产生以下输出:

(0.19620339269649473, 0)

简单明了,对吧?

我真正想做的是创建4个大型输入对象,每个对象包含1500个元素。这样,我就可以评估mvnun函数1500次。我们的想法是,在每次迭代时,所有输入都与上一次不同,并且不需要前一次迭代的信息。

这是我的设置:

import theano
import numpy as np

lower = theano.tensor.dmatrix("lower")      # lower bounds - dim: 1500 x 2
upper = theano.tensor.dmatrix("upper")      # upper bounds - dim: 1500 x 2
means = theano.tensor.dmatrix("means")      # means means -  dim: 1500 x 2
covs  = theano.tensor.dtensor3("covs")      # cov matrices - dim: 1500 x 2 x 2

results, updates = theano.scan(fn=mvnun,
                               sequences=[lower,upper,means,covs])

f = theano.function(inputs=[lower, upper, means, covs],
                    outputs=results,
                    updates=updates)

但是,当我尝试运行这段代码时,我在使用scan命令的行上收到错误。错误说明:ValueError: setting an array element with a sequence.。错误的完整回溯如下:

  

追踪(最近一次呼叫最后一次):

     

文件"",第7行,in       序列= [下限,上限,手段,COVS])

     

文件" C:\ Anaconda2 \ lib \ site-packages \ theano \ scan_module \ scan.py",   第745行,在扫描中       条件,输出,更新= scan_utils.get_updates_and_outputs(fn(* args))

     

ValueError:使用序列设置数组元素。

我原本认为代码不起作用,因为mvnun函数返回一个双元素元组而不是单个值。

然而,当我尝试向量化一个也返回了两元素元组的测试函数(我创建)时,事情就好了。以下是完整的示例:

# Some weird crazy function that takes in three Nx1 vectors 
# and an NxN matrix and spits out a tuple of scalars.
def test_func(low_i,upp_i,mean_i,cov_i):
    r1 = low_i.sum() + upp_i.sum()
    r2 = np.dot(mean_i,cov_i).sum()
    test_func_out = (r1,r2)
    return(test_func_out)

lower = theano.tensor.dmatrix("lower")      # lower
upper = theano.tensor.dmatrix("upper")      # upper
means = theano.tensor.dmatrix("means")      # means
covs  = theano.tensor.dtensor3("covs")      # covs

results, updates = theano.scan(fn=test_func,
                               sequences=[lower,upper,means,covs])

f = theano.function(inputs=[lower, upper, means, covs],
                    outputs=results,
                    updates=updates)

np.random.seed(666)

obs = 1500 # number of elements in the dataset
dim = 2 # dimension of multivariate normal distribution

# Generating random values for the lower bounds, upper bounds and means
lower_vals = np.random.rand(obs,dim)
upper_vals = lower_vals + np.random.rand(obs,dim)
means_vals = np.random.rand(obs,dim)

# Creates a symmetric matrix - used for the random covariance matrices
def make_sym_matrix(dim,vals):
    m = np.zeros([dim,dim])
    xs,ys = np.triu_indices(dim,k=1)
    m[xs,ys] = vals[:-dim]
    m[ys,xs] = vals[:-dim]
    m[ np.diag_indices(dim) ] = vals[-dim:]
    return m

# Generating the random covariance matrices
covs_vals = []
for i in range(obs):
    cov_vals = np.random.rand((dim^2 - dim)/2+dim)
    cov_mtx = make_sym_matrix(dim,cov_vals)
    covs_vals.append(cov_mtx)
covs_vals = np.array(covs_vals)

# Evaluating the test function on all 1500 elements
print(f(lower_vals,upper_vals,means_vals,covs_vals))

当我运行这段代码时,一切都运行正常,我得到的输出是一个包含2个数组的列表,每个数组包含1500个元素:

[array([ 4.24700864,  3.80830129,  2.60806493, ...,  3.12995381, 4.41907055,  4.12880839]), 
 array([ 0.87814314,  1.01768617,  0.45072405, ...,  1.15788282, 0.15766754,  1.32393402])] 

值得注意的是,矢量化函数从序列中获取元素的顺序是完美的。我对列表中的前3个数字进行了健全性检查:

for i in range(3):
    print(test_func(lower_vals[i],upper_vals[i],means_vals[i],covs_vals[i]))

结果是:

(4.2470086396797502, 0.87814313729162796)
(3.808301289302495, 1.017686166097616)
(2.6080649327828564, 0.45072405177076169)

这些值实际上与矢量化方法中的前3个输出值相同。

回到主要问题:当我在mvnun语句中使用scan函数时,为什么我无法使用ValueError函数?为什么我会得到这个奇怪的par

任何建议都会非常有用!!!

感谢!!!

0 个答案:

没有答案