Я создаю модель кодера-декодера игрушек для машинного перевода с использованием Tensorflow.
Я использую версию Tensorflow 1.8.0 cpu. В слое внедрения используется предварительный предварительный вектор в формате FastText размера 300. Затем партия обучающих данных проходит через кодировщик и декодер с механизмом внимания. В обучающей стадии декодер использует TrainHelper и в стадии вывода используется GreedyEmbeddingHelper.
Я уже успешно использовал модель, используя двунаправленный кодер LSTM. Однако, когда я пытаюсь улучшить мою модель, используя многослойный LSTM, возникает ошибка. Код для создания модели этапа обучения приведен ниже:
def BuildTrainModel(train_iterator):
((source, source_lengths), (target, target_lengths)) = train_iterator.get_next()
encoder_inputs = tf.transpose(source, [1,0]) # to time major
decoder_inputs = tf.transpose(target, [1,0])
decoder_outputs = tf.pad(decoder_inputs[1:], tf.constant([[0,1],[0,0]]), constant_values=tar_eos_id)
embedding_encoder = tf.Variable(embedding_matrix_src, name='embedding_encoder')
embedding_decoder = tf.Variable(embedding_matrix_tar, name='embedding_decoder')
# Embedding layer
encoder_emb_inp = tf.nn.embedding_lookup(embedding_encoder, encoder_inputs)
decoder_emb_inp = tf.nn.embedding_lookup(embedding_decoder, decoder_inputs)
# Encoder
# Construct forward and backward cells
forward_cell = tf.nn.rnn_cell.BasicLSTMCell(num_units)
backward_cell = tf.nn.rnn_cell.BasicLSTMCell(num_units)
encoder_outputs, encoder_states_fw, encoder_states_bw = tf.contrib.rnn.stack_bidirectional_dynamic_rnn(
[forward_cell] * num_layers, [backward_cell] * num_layers, encoder_emb_inp, dtype=tf.float64,
sequence_length=source_lengths, time_major=True)
Здесь я просто покажу часть кодировщика. Полный код и гиперпараметр см. В моем github: https://github.com/nkjsy/Neural-Machine-Translation/blob/master/nmt3.ipynb
Сообщение об ошибке:
InvalidArgumentError: Dimensions must be equal, but are 96 and 332 for 'stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/basic_lstm_cell/MatMul_1' (op: 'MatMul') with input shapes: [?,96], [332,128].
Я попытался установить вход как [forward_cell] и [backward_cell] и без проблем, что означает только 1 уровень, как и раньше. Когда я добавляю больше слоев, проблема возникает.
Используйте следующий метод для определения списка экземпляров ячеек,
forward_cell = [tf.contrib.rnn.BasicLSTMCell(num_units),tf.contrib.rnn.BasicLSTMCell(num_units)]
Вы можете видеть разницу при печати двух списков,
num_units =128
num_layers =2
#Method1
forward_cell = [tf.contrib.rnn.BasicLSTMCell( num_units),tf.contrib.rnn.BasicLSTMCell(num_units)]
print(forward_cell)
#Method2
forward_cell = [tf.contrib.rnn.BasicLSTMCell(num_units)]*num_layers
print(forward_cell)
Над фрагментом кода печатается нечто похожее на следующее,
[<tensorflow.python.ops.rnn_cell_impl.BasicLSTMCell object at 0x00000087798E6EF0>, <tensorflow.python.ops.rnn_cell_impl.BasicLSTMCell object at 0x0000008709AE72E8>]
[<tensorflow.python.ops.rnn_cell_impl.BasicLSTMCell object at 0x0000008709AFDC50>, <tensorflow.python.ops.rnn_cell_impl.BasicLSTMCell object at 0x0000008709AFDC50>]
Как вы могли видеть, #Method2
выводит список одного и того же экземпляра ячейки, чего не ожидается.
Надеюсь это поможет.