如何使用累加器(符号变量)展平循环的计算图?

时间:2015-05-31 09:45:10

标签: python theano

我是theano的新手。但是我已经用谷歌搜索了,阅读官方的theano文档& 我还没有找到解决问题的任何线索。

我试图重新发明轮子:我正在使用theano实现我自己的批量卷积。 (我这样做是为了学习这个图书馆)

所以,这就是我要做的事情:

# lr_all_w is a 3-tensor of <filter #, width, height>
lr_all_w = self._all_W.dimshuffle(('x', 0, 1)).repeat(self._prev_layer._processors_count, axis=0)

# element-wise to self._in_weight_masks
lr_all_w = lr_all_w * self._in_weight_masks
lr_all_w.name = 'lr_all_w'

#convolved = T.tensor3("convolved_batch")
# 'convolved' represents a dense convolved batches using im2col
convolved = T.zeros((self.batch_size, self._processors_count, self._processor_side**self._rec_f_dim))
convolved.name = "convolved_batches"

for batch_idx in range(self.batch_size):
    for i in range(self._prev_layer._processors_count):
        convolved = T.inc_subtensor(convolved[batch_idx], T.dot(lr_all_w[i], im2col_prev_layer[batch_idx, i]))

    # and adding bias
    convolved = T.inc_subtensor(convolved[batch_idx], self._all_B)

这导致了一个非常深的计算图,因为inc_subtensor被添加到每个先前的操作之上:

inc_subtensor_stepN(inc_subtensor_stepN-1(inc_subtensor_stepN-2 ...

所以我试图压扁它。由于所有变量都是象征性的,我意识到,我必须以某种方式将它们替换为图形。

我尝试了theano.clone,但结果与inc_subtensor相同。

然后我尝试使用theano.scan:

sym_im2col_prev_layer_batch_idx = T.tensor3("sym_im2col_prev_layer_batch_idx")
#TODO replace sym_im2col_prev_layer_batch_idx with concrete substitution afterwards
result, updates = theano.scan( fn=lambda lr_all_w_i, im2col_prev_layer_batch_idx_i: T.dot(lr_all_w_i, im2col_prev_layer_batch_idx_i),
 sequences=[lr_all_w, sym_im2col_prev_layer_batch_idx])

to_substitute = result.sum(0)
to_substitute.name = 'to_substitute'

for batch_idx in range(self.batch_size):
    for i in range(self._prev_layer._processors_count):
        sym_im2col_prev_layer_curr_batch = theano.clone(
            to_substitute, {sym_im2col_prev_layer_batch_idx: im2col_prev_layer[batch_idx]}
        )
        convolved = T.set_subtensor(convolved[batch_idx], sym_im2col_prev_layer_curr_batch)

    # and adding bias
    convolved = T.set_subtensor(convolved[batch_idx], convolved[batch_idx] + self._all_B)

但是,我仍然得到&#34; RuntimeError:比较超过了最大递归深度&#34; 正在执行sym_im2col_prev_layer_curr_batch = theano.clone时第一次正确。

后面的代码片段示例显示了我要做的事情。但我不知道为什么我的最大递归深度超过了#39; 因为每次我执行theano.clone时,theano应该替换为sym_im2col_prev_layer_batch_idx(已经在扫描中使用过) 它的确切符号值 - im2col_prev_layer [batch_idx],并给我一份这个子图。 我可能错过了一些东西......

如何在theano&amp;中解决此类(或类似)任务我怎样才能避免过深的计算图 做这样的任务?

我也试过这样的方法:

我尝试过这样的方法:

for batch_idx in range(self.batch_size):
    result, updates = theano.scan(fn=lambda lr_all_w_i, im2col_prev_layer_batch_idx_i: T.dot(lr_all_w_i, im2col_prev_layer_batch_idx_i),
                                  sequences=[lr_all_w, im2col_prev_layer[batch_idx]])

    result = result.sum(0)
    convolved = T.set_subtensor(convolved[batch_idx], result)


    # and adding bias
    convolved = T.inc_subtensor(convolved[batch_idx], self._all_B)

但是当试图打印出“卷入”的价值时。紧接着&#39; for&#39;周期,我得到了:

ipdb> theano.printing.debugprint(convolved)
...
*** RuntimeError: maximum recursion depth exceeded while calling a Python object

所以,同样的故事。

增加python的递归深度不是一种选择。

如何为我的案例展平计算图?

1 个答案:

答案 0 :(得分:2)

通常theano.scan是递归情况的解决方案。在像您这样的情况下,theano.scan应该用于替换 Python for循环,而不是for循环。

很难确切地看到你想要实现的目标,但set_subtensorinc_subtensor的广泛使用表明你正在以一种与Theano想要的方式不相符的方式来思考这个问题上班。 theano.scan可能允许您使用当前正在使用的方法实现您想要的效果,但在快速浏览您提供的代码后,甚至不需要theano.scan。如果一次迭代不依赖于前一次迭代的结果(如果是这样的话),那么你可以通过明智的方式完成这项任务(根本不是Python for循环或theano.scan)使用Theano张量操作。非循环方法几乎肯定比通过某种循环做事更有效和快速。不可否认,这些操作比连续的,一行一次的操作更难以解决。

如果你看不到你的计算如何通过没有循环的普通多维张量操作来实现,那么我建议你研究如何用尽可能少的for替换你的Python theano.scan循环你可以逃脱的行动。