Python - Theano scan() 函数

10 投票
1 回答
5925 浏览
提问于 2025-05-01 08:37

我对theano.scan()的行为不是很理解。

这里有一个例子:

import numpy as np
import theano
import theano.tensor as T


def addf(a1,a2):
        return a1+a2

i = T.iscalar('i')
x0 = T.ivector('x0') 
step= T.iscalar('step')

results, updates = theano.scan(fn=addf,
                   outputs_info=[{'initial':x0, 'taps':[-2]}],
                   non_sequences=step,
                   n_steps=i)

f=theano.function([x0,i,step],results)

print f([1,1],10,2)

上面的代码片段打印出以下序列,这个结果是完全合理的:

[ 3  3  5  5  7  7  9  9 11 11]

但是如果我把tap索引从-2改成-1,也就是:

outputs_info=[{'initial':x0, 'taps':[-1]}]

结果变成了:

[[ 3  3]
 [ 5  5]
 [ 7  7]
 [ 9  9]
 [11 11]
 [13 13]
 [15 15]
 [17 17]
 [19 19]
 [21 21]]

而不是我认为合理的结果(只取向量的最后一个值然后加2):

[ 3  5  7  9 11 13 15 17 19 21]

任何帮助都非常感谢。

谢谢!

暂无标签

1 个回答

10

当你使用 taps=[-1] 时,scan 会认为输出的信息是直接使用的。这意味着 addf 函数会用一个向量和一个非序列的值作为输入。如果你把 x0 转换成一个标量(就是一个单一的数值),它就会像你预期的那样工作:

import numpy as np
import theano
import theano.tensor as T


def addf(a1,a2):
        print a1.type
        print a2.type
        return a1+a2

i = T.iscalar('i')
x0 = T.iscalar('x0') 
step= T.iscalar('step')

results, updates = theano.scan(fn=addf,
                   outputs_info=[{'initial':x0, 'taps':[-1]}],
                   non_sequences=step,
                   n_steps=i)

f=theano.function([x0,i,step],results)

print f(1,10,2)

这样会得到以下输出:

TensorType(int32, scalar)
TensorType(int32, scalar)
[ 3  5  7  9 11 13 15 17 19 21]

在你的情况下,因为它执行的是 addf(vector, scalar),所以它会逐个处理每个元素。

换句话说,如果 taps 是 [-1],那么 x0 会直接传递给内部函数。如果 taps 里有其他内容,那么传递给内部函数的值会比 x0 少一个维度,因为 x0 需要提供多个初始步骤的值(-2 和 -1)。

撰写回答