Я не уверен, является ли это точным ответом на ваш вопрос, но это может быть хорошим началом, так как кажется, что вашей проблеме не уделяется много внимания (и, ну, я не удивлен этимколичество путаницы).
Кроме того, есть тонны вопросов (слишком много для комментариев), которые могут возникнуть и у других, поэтому я приведу их здесь (и постараюсь дать ответ на имеющуюся ситуацию).
Версия Tensorflow: 1.12
1.Нет градиентов
Эта проблема не существует ни для output
, ни для new_state
, когда batch_size
не указан .
Градиенты относительно new_state
, например, grads_new_state_wrt_vars = tf.gradients(new_state, tf.trainable_variables())
возврат:
** Tensor("gradients/layer_cell/conv1d/BiasAdd_grad/BiasAddGrad:0", shape=(100,), dtype=float32)
** Tensor("gradients/layer_cell/bn/batchnorm/mul_grad/Mul_1:0", shape=(100,), dtype=float32)
** Tensor("gradients/layer_cell/bn/batchnorm/add_1_grad/Reshape_1:0", shape=(100,), dtype=float32)
** Tensor("gradients/lstm_model/rnn/while/gru_cell/MatMul/Enter_grad/b_acc_3:0", shape=(164, 128), dtype=float32)
** Tensor("gradients/lstm_model/rnn/while/gru_cell/BiasAdd/Enter_grad/b_acc_3:0", shape=(128,), dtype=float32)
** Tensor("gradients/lstm_model/rnn/while/gru_cell/MatMul_1/Enter_grad/b_acc_3:0", shape=(164, 64), dtype=float32)
** Tensor("gradients/lstm_model/rnn/while/gru_cell/BiasAdd_1/Enter_grad/b_acc_3:0", shape=(64,), dtype=float32)
** None
** None
как ожидается (поскольку он не проходит через Dense
часть вашей сети).
Градиенты относительно output_state
, например, grads_new_state_wrt_vars = tf.gradients(output_state, tf.trainable_variables())
возврат:
** Tensor("gradients/layer_cell/conv1d/BiasAdd_grad/BiasAddGrad:0", shape=(100,), dtype=float32)
** Tensor("gradients/layer_cell/bn/batchnorm/mul_grad/Mul_1:0", shape=(100,), dtype=float32)
** Tensor("gradients/layer_cell/bn/batchnorm/add_1_grad/Reshape_1:0", shape=(100,), dtype=float32)
** Tensor("gradients/lstm_model/rnn/while/gru_cell/MatMul/Enter_grad/b_acc_3:0", shape=(164, 128), dtype=float32)
** Tensor("gradients/lstm_model/rnn/while/gru_cell/BiasAdd/Enter_grad/b_acc_3:0", shape=(128,), dtype=float32)
** Tensor("gradients/lstm_model/rnn/while/gru_cell/MatMul_1/Enter_grad/b_acc_3:0", shape=(164, 64), dtype=float32)
** Tensor("gradients/lstm_model/rnn/while/gru_cell/BiasAdd_1/Enter_grad/b_acc_3:0", shape=(64,), dtype=float32)
** Tensor("gradients/output/dense/MatMul_grad/MatMul_1:0", shape=(64, 2), dtype=float32)
** Tensor("gradients/output/dense/BiasAdd_grad/BiasAddGrad:0", shape=(2,), dtype=float32)
Еще раз, все в порядке.
2.Указание размера партии
Когда размер партии указан, как вы описали, например,
inputs_train_ph = tf.placeholder(dtype=m_dtype, shape=[34, 75, num_features], name="inputs_train_ph")
inputs_devel_ph = tf.placeholder(dtype=m_dtype, shape=[34, 75, num_features], name="inputs_devel_ph")
ваша сеть НЕ работает вообще, и это не страннотак как ваши фигуры не совпадают в выходном пространстве имен.
Кроме того, labels_devel_ph
и labels_train_ph
не имеют значения для рассматриваемого кода, зачем размещать их здесь, они просто загромождают вопрос еще дальше.См. Минимальный, полный и проверяемый пример , существует множество деталей, совершенно не необходимых для рассматриваемой задачи.
Далее, нет связи между партиямиформа inputs_train_ph
и inputs_devel_ph
, с чего бы это?Один не зависит от другого, и только один используется одновременно из-за tf.cond
(который должен быть указан как значение при запуске сеанса, но это выходит за рамки этого вопроса).
Проблемный выводчасть, именно это:
output = tf.reshape(output, shape=[5, -1, num_classes])
used = tf.expand_dims(used, 2)
output = output * used
Тензорные формы, используя ваш подход:
Output shape: (5, 480, 2)
Used initial shape: (32, 75)
Used after expand_dims: (32, 75, 1)
Очевидно, (5, 480, 2)
, умноженное на (32, 75, 1)
, не будет работать, я не вижу возможности этой работы когда-либо, даже с Tensorflow в пре-альфа-версии, что заставляет меня думать, что другие части вашего исходного кода заставляют его работать, и кто знает, что еще влияет на него, если честно.
Проблема с used
может быть решенанесколькими способами, но я думаю, что вы хотели, чтобы сложить used
в другое измерение и изменить его впоследствии ( это не будет работать без изменения ):
output = tf.reshape(output, shape=[5, -1, num_classes])
used = tf.stack((used, used), 2)
used = tf.reshape(used, shape=(5, -1, num_classes))
output = output * used
Используя этот подход, каждая форма партии проходит через сеть без проблем.
Кстати. Я не совсем уверен, чего вы пытаетесь достичь с помощью used
в начале eЕще, но, возможно, у вас есть вариант использования, IMO намерение полностью нечитаемо по сравнению с конечным результатом (столбцы, содержащие нули, когда все объекты в последовательности равны нулю, и один в противном случае).
3.Версии Tensorflow
Протестировано с версией 1.8 версии Tensorflow (ток 1.12 и 2.0 за углом) и Мне удалось воспроизвести вашу проблему.
Тем не менее, выходные формы сбои, как описано выше, хотя.
На самом деле, версия 1.9 уже имеет эту проблему решена.
Почему существует эта проблемав 1.8?
Я пытался определить возможную причину, но я все еще не знаю.Некоторые идеи:
Использование tf.layers
вместо tf.nn
.Так как планируется для версии 2.0 , этот модуль будет устаревшим, и из-за большого количества ошибок в фреймворке, я предположил, что что-то может быть не так и в этом случае.Я изменил conv1d
на tf.keras.layers
аналог и нормализацию партии на tf.nn.batch_normalization
, но безрезультатно, к сожалению, результаты все те же.
Согласно версии 1.9ноты Prevent tf.gradients() from backpropagating through integer tensors
.Может быть, это как-то связано с вашей проблемой?Может быть, график обратного распространения как-то застрял в v1.8.0?
Проблемы с областью действия tf.variable_scope
и tf.layers
- как и ожидалось, ничего не изменилось после удаления пространств имен.
В целом: обновите ваши зависимости до версии 1.9 или выше, это решит все ваши проблемы (хотя почему они возникают, довольно сложно понять, как и этот фреймворк).
На самом деле, мне кажется, что такие изменения происходят между второстепенными версиями и не описаны более подробно в журнале изменений, но, возможно, я упускаю что-то большое ...
Немного-topic
Может быть, вам следует рассмотреть возможность использования tf.Estimator
, tf.keras
или другого фреймворка, такого как PyTorch?Этот код крайне нечитабелен, труден для отладки и уродлив, существуют новые методы, и они должны помочь вам и нам (если у вас есть другая проблема с нейронными сетями и вы решите обратиться в StackOverflow)