如何更改 theano.scan() 中给出的函数的输入?

How to change inputs of the function given in theano.scan()?

我对 theano.scan() 感到困惑。我已经阅读了官方文档,但我仍然觉得我的知识有限。我想更改 theano.scan 中给出的函数的输入。例如,我有以下代码。

def forward_prop_step(x_t, s_t1_prev, s_t2_prev):
    # i have my code here

[o, s, s2], updates = theano.scan(
            forward_prop_step,
            sequences=x,
            truncate_gradient=self.bptt_truncate,
            outputs_info=[None, 
                          dict(initial=T.zeros(self.hidden_dim)),
                          dict(initial=T.zeros(self.hidden_dim))])

所以,这里 theano.scan 运行 超过序列 x。据我所知,当 theano.scan 通过序列 xforward_prop_step 得到输入 x_t 但是 forward_prop_step 如何得到第二个和第三个参数? theano.scan 是否从 outputs_info 的第二个和第三个值中获取第二个和第三个参数?

如果我想修改上面的代码,想给theano.scan多一个参数x2作为一个序列,我该如何修改代码呢?我希望 theano.scan 到 运行 超过两个序列 xx2 并将它们的值作为前两个参数(xx2forward_prop_step 方法。例如,forward_prop_step 的原型将是:

def forward_prop_step(x_t, x_f, s_t1_prev, s_t2_prev):
    # i have my code here

我如何更改 theano.scan 上的上述代码以同时提供 xx2 作为序列?任何人都可以简单地解释一下我如何更改给定 theano.scan 的函数的参数以及 return 值的示例吗?

其他几个问题:

(1) 如果我将 n_steps 参数与 sequences 参数一起提供,theano.scan 将如何执行? theano.scan 是否像嵌套(两个)for 循环一样工作?

(2) non_sequencestheano.scan 函数参数中的 sequences 有何不同?

(3) theano.scan 是否为序列参数的每个元素调用提供的函数?如果是这样,那么当我在 forward_prop_step 函数中写一个 print 语句时, print 语句只执行一次,尽管函数内部的计算执行了几次(经历了整个序列). theano.scan如何重复调用提供给它的方法?

theano.scan 是否从 outputs_info 的第二个和第三个值中获取第二个和第三个参数?

-> 是的,如果 outputs_info 的元素不是 None,则表示它是循环输出,因此必须传递给 step 函数。

如果我想修改上面的代码,想多给一个参数x2作为一个序列给theano.scan,我应该如何修改代码?

-> 你只需要将 x2 添加到序列列表中

[o, s, s2], updates = theano.scan(
        forward_prop_step,
        sequences=[x, x2],
        truncate_gradient=self.bptt_truncate,
        outputs_info=[None, 
                      dict(initial=T.zeros(self.hidden_dim)),
                      dict(initial=T.zeros(self.hidden_dim))])

参数在 step 函数中出现的顺序是(元素):sequencesoutputs_infonon_sequences(仅当它们在scan).

(1) 如果我给出 n_steps 参数和序列参数,theano.scan 如何执行? theano.scan 是否像嵌套(两个)for 循环一样工作?

如果提供n_steps scan 将只迭代这些迭代次数。如果您正在迭代一个张量,其第一维具有 10 个元素并且 n_steps4,则扫描将仅迭代该张量的前 4 个 'elements'。它不会像嵌套循环那样工作。

(2) non_sequences 参数与 theano.scan 函数参数中的序列有何不同?

non_sequences 没有被 scan 迭代,它们只是为了代码的清晰而被提及,因为它们在 step 函数中使用,显然 scan 可以计算单独列出它们,因此它们只是可选的,而不是强制性的(尽管推荐)。相反,sequences 指定变量 scan 在循环时应该迭代。

(3) theano.scan 是否为序列参数的每个元素调用提供的函数?如果是这样,那么当我在 forward_prop_step 函数中写一个 print 语句时, print 语句只执行一次,尽管函数内部的计算执行了几次(经历了整个序列). theano.scan如何重复调用提供给它的方法?

theano.scan 一次迭代 sequences[] 中每个元素的第一个维度,并在每次迭代期间调用 step 函数。如果你想在 scan 中打印中间计算,你应该使用 theano.printing.Print(查看 this link 了解详细信息)。 print 语句只执行一次的原因是因为 Theano 的工作方式是它在扫描代码时构建一个计算图,然后只用相应的值执行这个计算图,python 的 print 不能成为 theano 计算图的一部分,因此你只能看到它一次。

我建议您更深入地了解 documentation, and this 教程。