应用theano的扫描功能时出现值错误

2024-09-27 21:32:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试使用ano的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.。错误的完整回溯如下:

Traceback (most recent call last):

File "", line 7, in sequences=[lower,upper,means,covs])

File "C:\Anaconda2\lib\site-packages\theano\scan_module\scan.py", line 745, in scan condition, outputs, updates = scan_utils.get_updates_and_outputs(fn(*args))

ValueError: setting an array element with a sequence.

我最初认为代码不起作用是因为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个输出值相同。你知道吗

那么回到主要问题上来:为什么在scan语句中使用mvnun函数时不能让它工作呢?为什么我会有这种奇怪的ValueError?你知道吗

任何建议都会很有帮助!!!你知道吗

谢谢!!!你知道吗


Tags: 函数scannprandomtheanocovupperlower

热门问题