CNTK жалуется на динамическую ось в LSTM

Я пытаюсь реализовать LSTM в CNTK (используя Python) для классификации последовательности.

Ввод:

  • Объекты представляют собой последовательности чисел фиксированной длины (временные ряды).

  • Ярлыки - это векторы горячих значений.

Сеть:

input = input_variable(input_dim)
label = input_variable(num_output_classes)
h = Recurrence(LSTM(lstm_dim)) (input)
final_output = C.sequence.last(h)
z = Dense(num_output_classes) (final_output)
loss = C.cross_entropy_with_softmax(z, label)

Вывод: вероятность того, что последовательность соответствует ярлыку.

Все размеры фиксированы, поэтому я не думаю, что мне нужна какая-либо динамическая ось, и я ее не указывал.

Однако CNTK недовольна, и я получаю:

return cross_entropy_with_softmax(output_vector, target_vector, axis, name)
RuntimeError: Currently if an operand of a elementwise operation has any dynamic axes, those must match the dynamic axes of the other operands

Если (в соответствии с некоторыми примерами) я определяю метку с помощью динамической оси

label = input_variable(num_output_classes, dynamic_axes=[C.Axis.default_batch_axis()])

Он больше не жалуется на это и продолжает:

tf = np.split(training_features,num_minibatches)
tl = np.split(training_labels, num_minibatches)

for i in range(num_minibatches*num_passes): # multiply by the 
    features = np.ascontiguousarray(tf[i%num_minibatches])
    labels = np.ascontiguousarray(tl[i%num_minibatches])

    # Specify the mapping of input variables in the model to actual minibatch data to be trained with
    trainer.train_minibatch({input : features, label : labels})

Но умирает с этой ошибкой:

  File "C:\Users\Dev\Anaconda3\envs\cntk-py34\lib\site-packages\cntk\cntk_py.py", line 1745, in train_minibatch
    return _cntk_py.Trainer_train_minibatch(self, *args)
RuntimeError: Node '__v2libuid__Plus561__v2libname__Plus552' (Plus operation): DataFor: FrameRange's dynamic axis is inconsistent with matrix: {numTimeSteps:1, numParallelSequences:100, sequences:[{seqId:0, s:0, begin:0, end:1}, {seqId:1, s:1, begin:0, end:1}, {seqId:2, s:2, begin:0, end:1}, {seqId:3, s:3, begin:0, end:1}, {seq...

Что мне нужно сделать, чтобы это исправить?


person Tiny    schedule 17.12.2016    source источник


Ответы (1)


Если я правильно это понимаю, у вас есть последовательности одномерных входов. Если так, то ваши проблемы проистекают из этой строки

input =  input_variable(input_dim)

который объявляет последовательность размерных векторов input_dim. Если вы измените его на

input = input_variable(1)

то я считаю, что ваша первая попытка должна сработать.

Обновление. Вышеупомянутого недостаточно, потому что операция взятия последнего элемента последовательности создает результат, динамические оси которого отличаются от динамических осей по умолчанию, с которыми создается метка. Простое исправление - определить метку после того, как вы определили результат z следующим образом

label = input_variable(num_output_classes, dynamic_axes=z.dynamic_axes)

У меня это работает без нареканий. Затем я загрузил некоторые фиктивные данные, подобные этому (при условии, что минипакет из 4, длина последовательности из 5 и 3 классов)

x = np.arange(20.0, dtype=np.float32).reshape(4,5,1)
y = np.array([1,0,0,0,1,0,0,0,1,0,0,1], dtype=np.float32).reshape(4,1,3)
loss.eval({input: x, label:y })

и это сработало, как ожидалось.

person Nikos Karampatziakis    schedule 18.12.2016
comment
RuntimeError: в настоящее время, если операнд поэлементной операции имеет какие-либо динамические оси, они должны соответствовать динамическим осям других операндов. - person Tiny; 19.12.2016