Минимальный пример RNN в тензорном потоке
Попытка реализовать минимальный пример RNN игрушек в тензорном потоке.
Цель состоит в том, чтобы изучить сопоставление от входных данных к целевым данным, подобно этому замечательному сжатому примеру в theanets.
Обновление: мы добираемся туда. Единственная оставшаяся часть - сделать ее сходимой (и менее запутанной). Может ли кто-нибудь помочь превратить следующее в запущенный код или предоставить простой пример?
import tensorflow as tf
from tensorflow.python.ops import rnn_cell
init_scale = 0.1
num_steps = 7
num_units = 7
input_data = [1, 2, 3, 4, 5, 6, 7]
target = [2, 3, 4, 5, 6, 7, 7]
#target = [1,1,1,1,1,1,1] #converges, but not what we want
batch_size = 1
with tf.Graph().as_default(), tf.Session() as session:
# Placeholder for the inputs and target of the net
# inputs = tf.placeholder(tf.int32, [batch_size, num_steps])
input1 = tf.placeholder(tf.float32, [batch_size, 1])
inputs = [input1 for _ in range(num_steps)]
outputs = tf.placeholder(tf.float32, [batch_size, num_steps])
gru = rnn_cell.GRUCell(num_units)
initial_state = state = tf.zeros([batch_size, num_units])
loss = tf.constant(0.0)
# setup model: unroll
for time_step in range(num_steps):
if time_step > 0: tf.get_variable_scope().reuse_variables()
step_ = inputs[time_step]
output, state = gru(step_, state)
loss += tf.reduce_sum(abs(output - target)) # all norms work equally well? NO!
final_state = state
optimizer = tf.train.AdamOptimizer(0.1) # CONVERGEs sooo much better
train = optimizer.minimize(loss) # let the optimizer train
numpy_state = initial_state.eval()
session.run(tf.initialize_all_variables())
for epoch in range(10): # now
for i in range(7): # feed fake 2D matrix of 1 byte at a time ;)
feed_dict = {initial_state: numpy_state, input1: [[input_data[i]]]} # no
numpy_state, current_loss,_ = session.run([final_state, loss,train], feed_dict=feed_dict)
print(current_loss) # hopefully going down, always stuck at 189, why!?
Ответы
Ответ 1
Я думаю, что есть несколько проблем с вашим кодом, но идея правильная.
Основная проблема заключается в том, что вы используете один тензор для входов и выходов, например:
inputs = tf.placeholder(tf.int32, [batch_size, num_steps])
.
В TensorFlow функции RNN принимают список тензоров (поскольку в некоторых моделях num_steps могут меняться). Итак, вы должны построить такие ресурсы, как это:
inputs = [tf.placeholder(tf.int32, [batch_size, 1]) for _ in xrange(num_steps)]
Затем вам нужно позаботиться о том, что ваши входы являются int32, но ячейка RNN работает с векторами float - для чего используется embedding_lookup.
И, наконец, вам нужно будет адаптировать фид для ввода списка входных данных.
Я думаю, что учебник ptb - это разумное место для поиска, но если вы хотите еще более минимальный пример готового RNN, вы можете взглянуть на некоторые из модульных тестов rnn, например здесь,
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/kernel_tests/rnn_test.py#L164