Я начал использовать RNN в тензорном потоке и получил общий принцип, но некоторые аспекты реализации не совсем ясны.
Что я понимаю: допустим, я тренируюсь в последовательности-последовательность сети, в которой размер входных данных совпадает с размером выходных данных (это может быть что-то вроде предсказания следующего символа в фрагменте текста на каждом временном шаге).Мой рекуррентный слой использует ячейку LSTM, и я хочу, чтобы впоследствии полностью подключенный слой добавил немного глубины в прогноз.
В статическом RNN, согласно соглашению TF, вы должны разложить свои входные данные по временному измерению и передать их в метод static_rnn
в виде списка, например:
import tensorflow as tf
num_input_features = 32
num_output_features = 32
lstm_size = 128
max_seq_len = 5
# input/output:
x = tf.placeholder(tf.float32, [None, max_seq_len, num_input_features])
x_series = tf.unstack(x, axis=1) # a list of length max_seq_len
# recurrent layer:
lstm_cell = tf.contrib.rnn.BasicLSTMCell(lstm_size)
rnn_outputs, final_state = tf.nn.static_rnn(lstm_cell, x_series, dtype=tf.float32)
Это дает вам список выходов, один для каждого временного шага.Затем, если вы хотите выполнить некоторые дополнительные вычисления на выходах RNN на каждом шаге, вы можете просто сделать это для каждого элемента списка вывода:
# output layer:
w = tf.Variable(tf.random_normal([lstm_size, num_output_features]))
b = tf.Variable(tf.random_normal([num_output_features]))
z_series = [tf.matmul(out, w) + b for out in rnn_outputs]
yhat_series = [tf.nn.tanh(z) for z in z_series]
И тогда я могу составить yhat_series
еще раз и сравните его с некоторыми метками y
для моей функции стоимости.
Вот что я не получаю: В динамическом RNN вход, который вы передаете методу dynamic_rnn
, вместо этого является тензором с егособственное измерение времени (по умолчанию ось 1):
# input/output:
x = tf.placeholder(tf.float32, [None, max_seq_len, num_input_features])
# x_series = tf.unstack(x, axis=1) # dynamic RNN does not need this
# recurrent layer:
lstm_cell = tf.contrib.rnn.BasicLSTMCell(lstm_size)
dyn_rnn_outputs, dyn_final_state = tf.nn.dynamic_rnn(lstm_cell, x, dtype=tf.float32)
Тогда dyn_rnn_output
- это не список, а тензор формы (?, max_seq_len, lstm_size).Какой лучший способ справиться с подачей этого тензора в последующий плотный слой?Я не могу умножить выходы RNN на свою матрицу весов, и разбор выводов RNN выглядит как неуклюжий взлом, которого был разработан API dynamic_rnn, чтобы его избежать.
Есть ли хороший подход, который мне не хватает?