Theano重塑 - 索引超出界限

时间:2015-08-07 14:41:21

标签: python debugging reshape theano

我似乎无法让Theano按照自己的意愿重塑我的张量。下面的代码中的重新整形应该保持keep_dims维度,并将所有剩余的维度展平为单个数组。

如果我使用测试值运行代码,则代码会在IndexError: index out of bounds行上以reshape失败。否则,该函数似乎是编译的,但在使用ValueError: total size of new array must be unchanged的第一次实际输入时失败。

当我尝试使用numpy作为等效代码时,它正常工作。有什么我做错了吗?或者有没有简单的方法来查看用于重塑的结果维度(ipdb没有帮助,因为一切都是Theano变量)?

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

theano.config.compute_test_value = 'warn'
theano.config.optimizer = 'None'


class Layer(object):

    def __init__(self, name):
        self.name = name
        self.inputs = []
        self.outputs = []

    def get_init_weights(self, shape):
        rows, cols = shape
        w_init = np.reshape(np.asarray([rnd.uniform(-0.05, 0.05)
                                        for _ in xrange(rows * cols)]),
                            newshape=(rows, cols))
        return w_init

class Embedding(Layer):

    def __init__(self, name, dict_size, width, init='uniform_005'):
        super(Embedding, self).__init__(name)
        self.width = width
        self.dict_size = dict_size
        e_init = self.get_init_weights((dict_size, width))
        self.e = theano.shared(value=e_init, name=self.name)

    def connect(self, inputs):
        output = self.e[inputs]
        self.inputs.append(inputs)
        self.outputs.append(output)
        return output

class Flatten(Layer):

    def __init__(self, name, keep_dims=1):
        super(Flatten, self).__init__(name)
        self.params = []
        self.keep_dims = keep_dims

    def connect(self, inputs):
        keep_dims = self.keep_dims

        # this line fails
        output = inputs.reshape(inputs.shape[0:keep_dims] +
                                (T.prod(inputs.shape[keep_dims:]),),
                                ndim=(keep_dims + 1))
        return output


if __name__ == '__main__':

    x = T.itensor3('x')  # batch embedding * embedding size * number of different embeddings
    x.tag.test_value = np.random.randint(0, 50, (5, 20, 3)).astype('int32')

    emb_layer = Embedding('e', dict_size=50, width=10)
    y = emb_layer.connect(x)
    flat_layer = Flatten('f')
    y = flat_layer.connect(y)

    func = theano.function([x], y, allow_input_downcast=True) 

1 个答案:

答案 0 :(得分:0)

问题与你如何组合新形状的两个组成部分有关。 reshape command requires an lvector for the new shape

由于您正在使用测试值机制,因此您只需打印测试值的位数即可调试此问题。例如,我使用

print inputs.shape.tag.test_value
print inputs.shape[0:keep_dims].tag.test_value
print inputs.shape[keep_dims:].tag.test_value
print T.prod(inputs.shape[keep_dims:]).tag.test_value
print (inputs.shape[0:keep_dims] + (T.prod(inputs.shape[keep_dims:]),)).tag.test_value
print T.concatenate([inputs.shape[0:keep_dims], [T.prod(inputs.shape[keep_dims:])]]).tag.test_value

这显示了问题的解决方法:使用T.concatenate合并keep_dim s和其余dims的产品。