#tensorflow
#tensorflow
Вопрос:
Я хочу сложить два LSTM без использования MultiRNN
оболочки. Однако следующий код приводит к ValueError: Shapes (3,) and (2,) are not compatible
появлению because of inputs=states_fw_1
во втором LSTM. Как я могу передать скрытое состояние первого LSTM в качестве входных данных второму?
LSTM 1
with tf.name_scope("BiLSTM_1"):
with tf.variable_scope('forward_1'):
cell_fw_1 = tf.nn.rnn_cell.LSTMCell(num_units=hidden_size, state_is_tuple=True)
with tf.variable_scope('backward_srl'):
cell_bw_srl = tf.nn.rnn_cell.LSTMCell(num_units=hidden_size, state_is_tuple=True)
outputs_1, states_1 = tf.nn.bidirectional_dynamic_rnn(
cell_fw=cell_fw_1,
cell_bw=cell_bw_1,
dtype=tf.float64,
sequence_length=self.input_seq_len,
inputs=self.embedded_input_layer,
scope='BiLSTM_1')
Состояние — это кортеж
states_fw_1, states_bw_1 = states
LSTM 2
with tf.name_scope("BiLSTM_2"):
with tf.variable_scope('forward'):
cell_fw = tf.nn.rnn_cell.LSTMCell(num_units=hidden_size, state_is_tuple=True)
with tf.variable_scope('backward'):
cell_bw = tf.nn.rnn_cell.LSTMCell(num_units=hidden_size, state_is_tuple=True)
outputs, states = tf.nn.bidirectional_dynamic_rnn(
cell_fw=cell_fw,
cell_bw=cell_bw,
dtype=tf.float64,
sequence_length=self.input_seq_len,
inputs=states_fw_1,
scope="BiLSTM_extraction")
Ответ №1:
Я изучаю TF 2 дня (так что я не профессионал), и мне было интересно решить эту проблему.
Вот мои выводы: вы хотите сделать то, что невозможно получить с помощью реализации ‘LSTMCell’. Вот почему:
-
Вы хотите передать «states_fw_1 в следующий BI-LSTM. Итак, первый вопрос должен быть: каковы размеры «states_fw_1»? Для любой реализации RNN вам понадобится [batch_size, seq_len, input_size] . Для «states_fw_1» это [batch_size, hidden_size] (я только что проверил размер «states_fw_1», выполняемый ниже кода). Итак, вы можете видеть, что ваш вывод не соответствует требованиям RNN. Это связано с тем, что модель выводит только одно последнее состояние ячейки LSTM, а не всю историю (см. Документацию). И вас не интересует последнее состояние, потому что вы хотите передать состояние [t-step] на слой выше.’state_fw_1′ полезен, когда вы хотите классифицировать последовательность (не каждый элемент в последовательности) Редактировать: ‘state_fw_1’ содержит последнее «hidden_state» и последнее «memory_cell». Я думаю, что для классификации будет полезно только «hidden_state».
-
Итак, вам просто нужно использовать объединенный вывод (из прямого и обратного прохода). И выходные данные ячейки ‘LSTMCell’ имеют размер [batch_size, seq_len, hidden_size * 2], (* 2 как вперед и назад), поэтому он подходит для следующего сложенного RNN (выходные данные поступают с каждого временного шага, а не с состояния).
Вот код, который я тестировал:
import tensorflow as tf
import numpy as np
hidden_size = 21
seq_len = tf.placeholder(tf.int32, [None])
inputs = tf.placeholder(tf.float32, [None, None, 32])
with tf.variable_scope('BiLSTM_1'):
with tf.variable_scope('forward_1'):
cell_fw_1 = tf.nn.rnn_cell.LSTMCell(num_units=hidden_size, state_is_tuple=True)
with tf.variable_scope('backward_srl'):
cell_bw_1 = tf.nn.rnn_cell.LSTMCell(num_units=hidden_size, state_is_tuple=True)
outputs_1, states_1 = tf.nn.bidirectional_dynamic_rnn(
cell_fw=cell_fw_1,
cell_bw=cell_bw_1,
dtype=tf.float32,
sequence_length=seq_len,
inputs=inputs,
scope='BiLSTM_1')
# Merge Output tensor from forward and backward pass. It size is [batch_size, seq_len, 2*hidden_size]
outputs_1 = tf.concat(outputs_1, 2)
with tf.name_scope("BiLSTM_2"):
with tf.variable_scope('forward'):
cell_fw = tf.nn.rnn_cell.LSTMCell(num_units=hidden_size, state_is_tuple=True)
with tf.variable_scope('backward'):
cell_bw = tf.nn.rnn_cell.LSTMCell(num_units=hidden_size, state_is_tuple=True)
outputs, states = tf.nn.bidirectional_dynamic_rnn(
cell_fw=cell_fw,
cell_bw=cell_bw,
dtype=tf.float32,
sequence_length=seq_len,
inputs=outputs_1,
scope="BiLSTM_2")
# Initializate the weights and biases
init = tf.initialize_all_variables()
batch_size = 5
seq_len_val = 10
train_inputs = np.zeros((batch_size, seq_len_val, 32))
train_seq_len = np.ones(batch_size) * seq_len_val
with tf.Session() as session:
session.run(init)
feed = {inputs: train_inputs, seq_len: train_seq_len}
out,state,state_1 = session.run([outputs,states, states_1],feed)
print ("State size: ", state_1[0].c.shape, " Out Size: ", out[0][0].shape)
print ("Batch_size: ", batch_size, " Sequence Len: ", seq_len_val, " Hidden Size: ", hidden_size)
Ответ №2:
‘outputs_1’, возвращаемый LSTM 1, представляет собой кортеж, содержащий ‘outputs_fw’ и ‘outputs_bw’.
‘outputs_fw’ и ‘outputs_bw’ будут иметь размерность: [batch_size, sequence_length, hidden_size] .
Вы должны объединить скрытые состояния ‘outputs_fw’ и ‘outputs_bw’ (us tf.concat с axis = 2) и передать их в качестве входных данных в LSTM 2 вместо передачи ‘states_fw_1’ в качестве входных данных в LSTM 2.