Gráfico condicional en tensorflow y para bucle que accede al tamaño del tensor

Primero las preguntas generales:

  • ¿Es posible construir un gráfico condicional con tensorflow?
  • En caso afirmativo, ¿funcionan con él los cálculos automatizados de gradiente y los optimizadores implementados?
  • ¿Puedo acceder a la forma de un tensor y convertirlo en un entero para usarlo con una condición “if” y un bucle “for i in range ()”?

Mi caso de uso real es que quiero hacer una convolución 1D con longitud de tensor variable. Para esto primero necesito una sentencia if que solo ejecute la convolución si la longitud es mayor que una. Luego tengo un bucle for que atraviesa el tensor para la convolución. El problema es que este código:

for i in range(tf.shape(tensor)[0]): 

no funciona porque el operador de rango necesita un entero. ¿Puedo convertir esto de alguna manera en un entero?

Al final quiero entrenar este modelo con Adagrad, ya sea con la diferenciación automática o con el optimizador ya implementado.


Editar:

esta es la convolución 1D que luego será la primera de las dos capas en mi modelo. Los errores de tipo están detrás de cada versión del bucle for que activa una

 import tensorflow as tf import numpy as np def convolve(s, Tl, Tr, b): if (tf.shape(s)[0] == 1): return s sum = 0 # for i in range(tf.shape(s)[0] - 1): # error: TypeError: range() integer end argument expected, got Tensor # for i in range(s._shape._dims[0]._value - 1): # error: TypeError: unsupported operand type(s) for -: 'NoneType' and 'int' for i in range(s.get_shape().as_list()[0] - 1): # error: TypeError: unsupported operand type(s) for -: 'NoneType' and 'int' sum += tf.tanh(tf.matmul(Tl,s[i]) + tf.matmul(Tr, s[i+1]) + b) return sum ModelSize = 3 # tensor to be convolved s = tf.placeholder("float", shape = [None, ModelSize]) # initialise weights Tl = tf.Variable(tf.random_normal(shape=[ModelSize,ModelSize], stddev = 0.1 )) Tr = tf.Variable(tf.random_normal(shape=[ModelSize,ModelSize], stddev = 0.1 )) b = tf.Variable(tf.random_normal(shape=[ModelSize], stddev = 0.1 )) #convolution s_convolved = convolve(s, Tl, Tr, b) # initialise variables. init = tf.initialize_all_variables() # run graph sess = tf.Session() sess.run(init) # test data s_dataLong = np.random.random((2,5,ModelSize)) s_dataShort = np.random.random((2,1,ModelSize)) for s_dataPart in s_dataLong: print sess.run(s_convolved, feed_dict = {s : s_dataPart}) for s_dataPart in s_dataShort: print sess.run(s_convolved, feed_dict = {s : s_dataPart}) 

Te recomiendo que escribas cada pregunta de manera diferente. De lo contrario se cerrará como demasiado amplio.

Solo puedo responder a tu tercera pregunta. Cómo obtener una forma del tensor mediante progtwigción. Está utilizando correctamente la forma para obtener la forma del tensor , pero aún no puede obtener los resultados antes de ejecutar el gráfico (consulte mi explicación aquí ).

 a = tf.truncated_normal([2, 3], mean=0.0, stddev=0.02, dtype=tf.float32, seed=1) b = tf.shape(a) sess = tf.Session() print sess.run(b) # will give you [2 3] 

La forma fea que he encontrado para obtener la forma de las constantes, sin ejecutar el gráfico es hacer algo como (no sé realmente por qué lo necesitarías):

 print a._shape._dims[0]._value print a._shape._dims[1]._value 

Para obtener la forma de una variable, puede hacer esto:

 weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35)) print weights.get_shape().as_list() 

Otra forma de acceder a una forma de un Tensor antes de la evaluación es: tf.Tensor.get_shape ()