Ejemplo de RNN mínimo en tensorflow
basic lstm cell tensorflow (1)
Tratando de implementar un ejemplo de RNN de juguete mínimo en tensorflow. El objetivo es aprender una asignación de los datos de entrada a los datos de destino, similar a este maravilloso ejemplo conciso en theanets .
Actualización : estamos llegando allí. La única parte restante es hacer que converja (y menos complicada). ¿Podría alguien ayudar a convertir lo siguiente en código de ejecución o proporcionar un ejemplo simple?
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!?
Creo que hay algunos problemas con su código, pero la idea es correcta.
El problema principal es que está usando un solo tensor para entradas y salidas, como en:
inputs = tf.placeholder(tf.int32, [batch_size, num_steps])
.
En TensorFlow, las funciones RNN toman una lista de tensores (porque num_steps puede variar en algunos modelos). Entonces deberías construir entradas como esta:
inputs = [tf.placeholder(tf.int32, [batch_size, 1]) for _ in xrange(num_steps)]
Luego debe tener en cuenta el hecho de que sus entradas son int32s, pero una celda RNN funciona en vectores flotantes, para eso es para lo que embedding_lookup.
Y finalmente deberá adaptar su alimentación para ponerla en la lista de entrada.
Creo que el tutorial de ptb es un lugar razonable para mirar, pero si quieres un ejemplo aún más mínimo de un RNN listo para usar, puedes echar un vistazo a algunas de las pruebas de unidades de rnn, por ejemplo, aquí. https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/kernel_tests/rnn_test.py#L164