Я новичок в теано. Но я уже гуглил, читал официальную документацию 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)
Но тем не менее, я получаю «RuntimeError: максимальная глубина рекурсии превышена в сравнении» прямо в первый раз, когда выполняется sym_im2col_prev_layer_curr_batch = theano.clone.
Последний пример фрагмента кода правильно показывает то, что я собираюсь сделать. Но я понятия не имею, почему я получаю «превышение максимальной глубины рекурсии». Потому что каждый раз, когда я делаю theano.clone, предполагается, что theano заменяет sym_im2col_prev_layer_batch_idx (который уже используется в сканировании) своим точным символическим значением — im2col_prev_layer[batch_idx] и дает мне копию этого подграфа. Я мог что-то упустить...
Как такие (или похожие) задачи решаются в theano и как избежать слишком глубоких расчетных графиков при выполнении таких задач?
Также я пробовал такой подход:
Я пробовал такой подход:
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)
Но при попытке напечатать значение «свернуто» сразу после цикла «для» я получаю:
ipdb> theano.printing.debugprint(convolved)
...
*** RuntimeError: maximum recursion depth exceeded while calling a Python object
Итак, та же история.
Увеличение глубины рекурсии для python НЕ вариант.
Любые идеи, как сгладить график расчета для моего случая?