uruguay tren paso nivel ferroviario estacion binacional argentina tensorflow

tensorflow - nivel - ¿Cómo puedo mantener el estado del paso del tren al paso del tren?



tren a uruguay 2017 (2)

Aquí hay un ejemplo del uso de tensores persistentes para almacenar el historial de degradados. En el siguiente ciclo, gradient_history refiere a la concatenación de todos los degradados hasta el momento:

n = 2 x = tf.Variable(tf.zeros((n,))) x_target = 10*tf.ones((n,)) loss = tf.reduce_sum(tf.square(x - x_target)) optimizer = tf.train.GradientDescentOptimizer(0.1) gradient = tf.gradients(loss, [x])[0] train_op = optimizer.apply_gradients([[gradient, x]]) # initialize history with first gradient sess = tf.Session() sess.run(tf.global_variables_initializer()) gradient_history0 = sess.run(tf.get_session_handle(tf.stack([gradient]))) previous_gradients_in, previous_gradients = tf.get_session_tensor(gradient_history0, dtype=dtype) gradient_history = tf.concat(0, [previous_gradients, [gradient]]) gradient_history_out = tf.get_session_handle(gradient_history) sess.run(tf.global_variables_initializer()) for i in range(10): [gradient_history0, _, loss0, gradient0] = sess.run([gradient_history_out, train_op, loss, gradient], feed_dict={previous_gradients_in: gradient_history0.handle}) print(loss0, gradient0)

Cuando lo ejecutas, deberías ver algo como esto:

200.0 [-20. -20.] 128.0 [-16. -16.] 81.92 [-12.80000019 -12.80000019] 52.4288 [-10.23999977 -10.23999977] 33.5544 [-8.19199944 -8.19199944] 21.4748 [-6.55359936 -6.55359936] 13.7439 [-5.24287987 -5.24287987] 8.79609 [-4.19430351 -4.19430351] 5.6295 [-3.35544205 -3.35544205] 3.60288 [-2.68435287 -2.68435287]

Tenga en cuenta que en cada paso alimentado de su computación, gradient_history es un objeto Tensor que se refiere al historial del gradiente. Mientras tanto, gradient_history0 es un objeto TensorHandle que hace referencia al historial guardado que persiste entre llamadas session.run . Puede volver a alimentar ese valor en el gráfico usando feed_dict={...: gradient_history0.handle} , pero a diferencia de alimentar matrices numpy, está alimentando un "puntero" a los datos, y los datos nunca dejan el tiempo de ejecución de TensorFlow. Como el control persiste entre llamadas session.run , también puede evaluarlo directamente:

In [10]: gradient_history0.eval() Out[10]: array([[-20. , -20. ], [-20. , -20. ], [-16. , -16. ], [-12.80000019, -12.80000019], [-10.23999977, -10.23999977], [ -8.19199944, -8.19199944], [ -6.55359936, -6.55359936], [ -5.24287987, -5.24287987], [ -4.19430351, -4.19430351], [ -3.35544205, -3.35544205], [ -2.68435287, -2.68435287]], dtype=float32)

Tengo un tensor en mi gráfico de computación al que me gustaría agregar una fila después de cada paso del tren. ¿Cómo puedo lograr esto?

Más detalles: estoy obteniendo gradientes de optimizer.compute_gradients , y me gustaría modificar esos degradados en función del historial de gradientes. Aquí está el código que intento usar:

def process_gradient(gradient, optimizer, name): reshaped_gradient = flatten(gradient) if gradient.name in optimizer._slots: optimizer._slots[gradient.name] += [reshaped_gradient] else: optimizer._slots[gradient.name] = [reshaped_gradient] # each gradients_over_time = tf.stack(optimizer._slots[gradient.name]) print(''gradients_over_time.get_shape()'', gradients_over_time.get_shape()) return gradient ... grads_and_vars = optimizer.compute_gradients(cost_function) train_step = optimizer.apply_gradients([(process_gradient(grad, optimizer, str(i)), var) for i, (grad, var) in enumerate(grads_and_vars)])

También traté de mantener una variable alrededor de la que uso para hacer un seguimiento de las filas mediante la concatenación de nuevas filas, pero eso no funcionó.


Terminé usando tf.py_func para lograr esto. Sigo la pista del estado en una lista global a la que se accede en la función Python. Aquí los degradados se aplican:

# process each individual gradient before applying it train_step = optimizer.apply_gradients([(process_gradient(grad, str(i)), var) for i, (grad, var) in enumerate(grads_and_vars)])

Aquí es donde hago un seguimiento del estado a lo largo del tiempo y utilizaré el estado acumulado:

def construct_processor(name): global_gradients_over_time = {} def python_process_gradient(gradient): reshaped_gradient = gradient.flatten() if name in global_gradients_over_time: global_gradients_over_time[name].append(reshaped_gradient) else: global_gradients_over_time[name] = [reshaped_gradient] # process gradients somehow return gradient return python_process_gradient def process_gradient(gradient, name): return tf.py_func(construct_processor(name), [gradient], tf.float32)

construct_processor está ahí para permitirle procesar degradados uno a la vez, dando un nombre a cada conjunto de degradados para que pueda encontrarlos en el diccionario global. Este enfoque también mantiene la memoria fuera de la GPU, creo.