No puedo encontrar la documentación adecuada sobre cómo usar TensorFlow v2 para la programación básica de flujo de datos. Puedo encontrar muchos recursos en línea sobre TensorFlow v1, pero gran parte del comportamiento que explican ahora está obsoleto. Por ejemplo, el siguiente código de Python funciona bien en TensorFlow v1:

import tensorflow as tf

# Define some helper functions
def func1(a, b):
    return a+b # Or any manipulation of the arguments

def func2(a, b):
    return a*b

def func3(a, b):
    return a-b

# Define a graph; (a,b)-->e, (c,d)-->f, (e,f)-->g
a = tf.placeholder(tf.float64)
b = tf.placeholder(tf.float64)
c = tf.placeholder(tf.float64)
d = tf.placeholder(tf.float64)
e = tf.py_func(func1, [a,b], tf.float64)
f = tf.py_func(func2, [c,d], tf.float64)
g = tf.py_func(func3, [e,f], tf.float64)

# Execute in a session
sess1 = tf.Session()
res = sess1.run([g], feed_dict={a:1, b:2, c:3, d:4})
print(res) # = [-9.0]

Aquí he convertido algunas funciones de Python en operaciones de tensorflow; He definido un gráfico en el que g depende de e y f que a su vez dependen de a,b,c,d; finalmente, he ejecutado una sesión y he proporcionado entradas para a,b,c,d.

También puedo evitar proporcionar todas las entradas y elegir nodos intermedios en su lugar:

sess2 = tf.Session()
res = sess2.run([g], feed_dict={a:1, b:2, f:12})
print(res) # = [-9.0]

Aquí, ya proporciono f, en lugar de sus dependencias c,d.

¿Cómo funcionaría algo como esto en TensorFlow v2 (además de importar tensorflow.compat.v1)? ¿Se pensó que TensorFlow v2 haría algo como esto o es solo aprendizaje automático?

Nota: Esto está relacionado de alguna manera con esta pregunta que trata de un problema mucho más complicado.

1
gfole 24 ago. 2020 a las 11:53

1 respuesta

La mejor respuesta

La principal motivación, según tengo entendido, de TF 2.0 fue alejarse de lo antiguo estilo de definir primero todo el flujo de datos y luego llamarlo al final. Querían cambiar a una forma más pitónica de hacer las cosas.

Una parte importante de esto es definir funciones de forma pitónica y luego decorarlas con @tf.function para que tensorflow genere un gráfico y mejore el rendimiento.

El método "fregadero de cocina" de poner todo en un gráfico grande y luego ejecutar una sesión por lo que necesita de él, se desaconseja en TF2.

En su ejemplo, esto se vería así

import tensorflow as tf

# Define some helper functions
def func1(a, b):
    return a+b # Or any manipulation of the arguments

def func2(a, b):
    return a*b

def func3(a, b):
    return a-b

Si solo necesita una función grande, esto debería ser suficiente:

# define combined tf function, the decorated ensures a graph is generated.
@tf.function
def tf2_function(a, b, c, d):
    e = func1(a, b)
    f = func2(c, d)
    g = func3(e, f)
    return g

e, f, g = tf2_function(1, 2, 3, 4) # -9

Pero si necesita la opción de obtener valores intermedios o proporcionar valores intermedios, la mejor opción sería dividir la función en dos funciones más pequeñas, como recomiendan los desarrolladores de TF.

@tf.function
def get_f(a,b,c,d):
    e = func1(a, b)
    f = func2(c, d)
    return f

@tf.function
def get_g_from_e_f(e,f):
    g = func3(e,f)
    return g

Tampoco es necesario decorar todas las funciones con @tf.function, por lo general es suficiente decorar las funciones más grandes y caras con él, y todas las funciones llamadas comprarlas también se convertirán en un gráfico.

Pero sí, no hay una forma real de hacer lo que podría hacer en TF1.x, alimentando diferentes valores y obteniendo diferentes salidas del gráfico, en TF2.

1
Johannes Ackermann 25 ago. 2020 a las 09:36