说一个函数,它计算数组每个索引处的出现次数:
import theano
import theano.tensor as T
A = T.vector("A")
idx_range = T.arange(A.shape[0])
result, updates = theano.scan(fn=lambda idx: T.sum(A[:idx+1]), sequences=idx_range)
count_ones = theano.function(inputs=[A], outputs=result)
print count_ones([0,0,1,0,0,1,1,1])
# gives [ 0. 0. 1. 1. 1. 2. 3. 4.]
至于说在这里,使用扫描效率不高。另外,theano.scan总是在我的机器上生成“ RuntimeWarning:numpy.ndarray的大小已更改,可能表明scan_perform.scan_perform import *与二进制不兼容”。
所以我想知道Theano中是否有更好的映射函数的方法?
提前致谢。
编辑:
我刚刚意识到这是一个可怕的例子,显然有一种更有效的方法可以像这样循环遍历向量:
result, updates = theano.scan(fn=lambda prior_result, a: prior_result + a,
outputs_info=T.alloc(np.int32(0), 1),
sequences=A,
n_steps=A.shape[0])
但是根据@Daniel Renshaw的回答,因为
一步中的计算取决于某个较早步骤中的相同计算
所以实际上我无法避免在这方面使用扫描,对吗?
编辑:
我想到了一种将其陶瓷化的方法:
A = T.vector()
in_size = 8
# a matrix with ones at and below the given diagonal and zeros elsewhere
mask = theano.shared(numpy.tri(in_size))
result = T.dot(mask, A)
count_ones = theano.function(inputs=[A], outputs=result)
print count_ones(numpy.asarray([0,0,1,0,0,1,1,1]))
但是在这种情况下,我必须事先知道输入的大小(除非我可以像运行矩阵一样制作numpy.tri吗?)。
欢迎大家提出意见。:)
编辑:
我使用512D输入数组和10000次迭代对这三种方法进行了基准测试,并得到以下结果:
在最一般的情况下,如果不对该功能做任何假设,则必须使用扫描。但是,可以对许多(也许是大多数?)有用功能进行矢量化处理,从而无需扫描。正如问题编辑中指出的那样,示例功能当然可以在不使用扫描的情况下应用于输入。
决定是否需要扫描将取决于需要应用的功能。案例肯定会要求扫描是那些当在一个步骤的计算依赖于以下一些早期的步骤相同的计算。
PS关于二进制不兼容的警告可以安全地忽略。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句