Orden de sess.run () en Tensorflow

Me pregunto cuál es el orden de ejecución de la lista de operaciones en sess.run (ops_list, …). por ejemplo: para un escenario de clasificación típico: _, loss = sess.run([train_op, loss_op]) , si train_op ejecuta primero, la pérdida es la pérdida después del backprop actual. Pero si la loss ejecuta primero, entonces la pérdida es la pérdida antes del backprop actual. alguien me ayude? Gracias.

loss será el valor de la pérdida antes de la actualización causada por train_op . Tenga en cuenta que loss_op es una entrada para el optimizador, por lo que necesariamente va “antes” de train_op en el gráfico. loss_op se calcula con los valores de las variables al comienzo de la operación de run . Si quisiera calcular la pérdida después de train_op , podría hacerlo, por ejemplo, utilizando un bloque tf.control_dependencies con el optimizador y calculando la pérdida nuevamente, pero en ese caso estaría haciendo dos pasos hacia adelante de su modelo en cada paso, con El coste asociado. Por lo general, si solo desea trazar la pérdida para la monitorización o algo así, está bien usar el valor del paso anterior.

Para una explicación más detallada, en general, el orden en que se ejecutan las operaciones de TensorFlow solo se garantiza en la medida en que estas operaciones dependan unas de otras, y no se relaciona con el orden en que se pasan para run . En su caso, train_op depende de loss_op , por lo que loss_op tiene que ir primero. Sin embargo, en otros casos, las operaciones no dependen directamente unas de otras, y en ese caso el pedido no está garantizado. Muchas veces eso realmente no importa, pero en algunos casos lo hace. Considera el siguiente ejemplo:

 import tensorflow as tf v = tf.Variable(0) v2 = 2 * v v_update = v.assign(v + 1) init = tf.global_variables_initializer() with tf.Session() as sess: sess.run(init) for i in range(5): print(sess.run([v_update, v2])) 

Una carrera en mi computadora produjo esta salida:

 [1, 0] [2, 2] [3, 4] [4, 8] [5, 10] 

Como ve, v2 es a veces el doble del valor actualizado y, a veces, el doble del valor no actualizado. Si, por ejemplo, quisiéramos asegurarnos de que v2 siempre se ejecute antes de v_update , podríamos hacerlo:

 import tensorflow as tf v = tf.Variable(0) v2 = 2 * v with tf.control_dependencies([v2]): v_update = v.assign(v + 1) init = tf.global_variables_initializer() with tf.Session() as sess: sess.run(init) for i in range(5): print(sess.run([v_update, v2])) 

Que produce constantemente:

 [1, 0] [2, 2] [3, 4] [4, 6] [5, 8]