Theano reshape——索引越界

Theano reshape – index out ouf bounds

我似乎无法让 Theano 按照需要重塑我的张量。下面代码中的重塑应该保持 keep_dims 维度并将所有剩余的维度展平到一个数组中。

如果我 运行 它带有测试值,则代码会在 reshape 行上以 IndexError: index out of bounds 失败。否则,该函数似乎可以编译,但在 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) 

问题与您如何组合新形状的两个组成部分有关。 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 和剩余 dims 的乘积。