Разница между MultiRNNCell и stack_bidirectional_dynamic_rnn в Tensorflow

Я строю динамическую сеть RNN со стеком нескольких LSTM. Я вижу, есть 2 варианта

# cells_fw and cells_bw are list of cells eg LSTM cells
stacked_cell_fw = tf.contrib.rnn.MultiRNNCell(cells_fw)
stacked_cell_bw = tf.contrib.rnn.MultiRNNCell(cells_bw)

output = tf.nn.bidirectional_dynamic_rnn(
          stacked_cell_fw, stacked_cell_bw, INPUT,
          sequence_length=LENGTHS, dtype=tf.float32)

против

output = tf.contrib.rnn.stack_bidirectional_dynamic_rnn(cells_fw, cells_bw, INPUT,
sequence_length=LENGTHS, dtype=tf.float32)

В чем разница между двумя подходами, и один из них лучше другого?

1 ответ

Решение

Если вы хотите иметь несколько слоев, которые передают информацию назад или вперед во времени, есть два способа, как спроектировать это. Предположим, что прямой уровень состоит из двух уровней F1, F2, а уровень заднего слова состоит из двух уровней B1, B2.

Если вы используете tf.nn.bidirectional_dynamic_rnn модель будет выглядеть так (время течет слева направо):

Если вы используете tf.contrib.rnn.stack_bidirectional_dynamic_rnn модель будет выглядеть так:

Здесь черная точка между первым и вторым слоем представляет собой конкатенацию. Т.е. выходы прямой и обратной сот объединяются вместе и подаются на обратный и прямой уровни следующего верхнего уровня. Это означает, что и F2, и B2 получают абсолютно одинаковые входные данные, и между обратным и прямым слоями существует явная связь. В "Распознавании речи с глубокими рекуррентными нейронными сетями" Graves et al. суммировать это следующим образом:

... каждый скрытый слой получает входные данные от прямого и обратного слоев на уровне ниже.

Это соединение происходит неявно только в непакетированном BiRNN (первое изображение), а именно при отображении на выход. Сложенный BiRNN обычно работал лучше для моих целей, но я думаю, это зависит от вашей проблемы. Но наверняка стоит попробовать!

РЕДАКТИРОВАТЬ

В ответ на ваш комментарий: я основываю свой ответ на документации функции tf.contrib.rnn.stack_bidirectional_dynamic_rnn который говорит:

Укладывает несколько двунаправленных рН-слоев. Объединенные выходные данные прямого и обратного уровней используются в качестве входных данных следующего уровня. tf.bidirectional_rnn не позволяет обмениваться прямой и обратной информацией между слоями.

Также я посмотрел на реализацию, доступную по этой ссылке.

Другие вопросы по тегам