Проблема с функцией сканирования Theano - TypeError: невозможно преобразовать Type TensorType (float64, 3D)

У меня возникли проблемы с функцией сканирования Theano и следующим кодом:

def lstm_layer(tparams, options, trng, prefix='lstm'):

def _slice(_x, n, dim):
    if _x.ndim == 3:
        return _x[:, :, n * dim:(n + 1) * dim]
    return _x[:, n * dim:(n + 1) * dim]

def _step(sample_, h_, c_):
    theano.printing.debugprint(sample_,print_type=True)
    emb = tparams['Wemb'][sample_]
    x_ = tensor.dot(emb[None,:], tparams[_p(prefix, 'W')]) + tparams[_p(prefix, 'b')]
    preact = tensor.dot(h_, tparams[_p(prefix, 'U')])
    preact += x_

    i = tensor.nnet.sigmoid(_slice(preact, 0, options['dim_proj']))
    f = tensor.nnet.sigmoid(_slice(preact, 1, options['dim_proj']))
    o = tensor.nnet.sigmoid(_slice(preact, 2, options['dim_proj']))
    c = tensor.tanh(_slice(preact, 3, options['dim_proj']))

    c = f * c_ + i * c
    h = o * tensor.tanh(c)

    pred = tensor.nnet.softmax(tensor.dot(h, tparams['U']) + tparams['b'])
    rand = trng.multinomial(n=1, pvals=pred)
    sample = tensor.argmax(rand[0], axis=0)
    return sample, h, c

start = tensor.scalar('start', dtype='int64')
dim_proj = options['dim_proj']
nsteps = options['seq_length']
rval, updates = theano.scan(_step,
                            outputs_info=[start,
                                          tensor.alloc(numpy_floatX(0.),
                                                       1,
                                                       dim_proj),
                                          tensor.alloc(numpy_floatX(0.),
                                                       1,
                                                       dim_proj)],
                            name=_p(prefix, '_layers'),
                            n_steps=2)
return rval[0], start

Как видите, переменная start представляет собой целое число, которое получает новое значение после каждого вызова step_, и я хочу получить последовательности ее значений через произвольное количество шагов n_steps. Если я запускаю код с n_steps = 1, все работает. Однако для n_steps > 1 я получаю эту ошибку:

TypeError: невозможно преобразовать тип TensorType (float64, 3D) (из Variable IncSubtensor {Set;: int64:}.0) в тип TensorType (float64, (False, True, False)). Вы можете попытаться вручную преобразовать IncSubtensor{Set;:int64:}.0 в TensorType(float64, (False, True, False)).

Я не понимаю, откуда это взялось, поскольку ни одна из моих переменных не является трехмерным тензором (я проверил с помощью theano.printing.debugprinting, а h и c - это строки, как и ожидалось, и выборка скаляра).

У вас есть какие-нибудь подсказки?

Спасибо


person nisace    schedule 27.07.2015    source источник
comment
Вы четко указываете, что _x будет трехмерным, учитывая код внутри функции _slice. Можете ли вы предоставить какой-нибудь минимальный исполняемый код, который иллюстрирует проблему, потому что бывает сложно помочь с такого рода ошибками, просто читая код.   -  person Daniel Renshaw    schedule 28.07.2015


Ответы (1)


Собственно, я нашел решение своей проблемы. я изменил это

def _slice(_x, n, dim):
if _x.ndim == 3:
    return _x[:, :, n * dim:(n + 1) * dim]
return _x[:, n * dim:(n + 1) * dim]

этим

    def _slice(_x, n, dim):
    if _x.ndim == 3:
        return _x[:, :, n * dim:(n + 1) * dim]
    if _x.ndim == 2:
        return _x[:, n * dim:(n + 1) * dim]
    return _x[n * dim:(n + 1) * dim]

и это

x_ = tensor.dot(emb[None,:], tparams[_p(prefix, 'W')]) + tparams[_p(prefix, 'b')]

этим

    x_ = tensor.dot(emb, tparams[_p(prefix, 'W')]) + tparams[_p(prefix, 'b')]

Это создает вектор x_, h_ and c_ theano вместо строк, как раньше, и устраняет ошибку (хотя я не совсем уверен, почему).

Конечно, я также обновил вызов на scan

    rval, updates = theano.scan(_step,
                            outputs_info=[start, tensor.alloc(numpy_floatX(0.),
                                                       dim_proj),
                                          tensor.alloc(numpy_floatX(0.),
                                                       dim_proj)],
                            name=_p(prefix, '_layers'),
                            n_steps=2)
person nisace    schedule 28.07.2015